public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-16 19:56 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-16 19:56 UTC (permalink / raw
  To: gentoo-commits

commit:     9367223686e9f04be347f8f929183e3bc40882ea
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Dec 16 19:56:24 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Dec 16 19:56:24 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=93672236

Update CPU Optimization patch

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

 5010_enable-cpu-optimizations-universal.patch | 217 +++++++++++++++++++-------
 1 file changed, 159 insertions(+), 58 deletions(-)

diff --git a/5010_enable-cpu-optimizations-universal.patch b/5010_enable-cpu-optimizations-universal.patch
index b9c03cb6..0841340b 100644
--- a/5010_enable-cpu-optimizations-universal.patch
+++ b/5010_enable-cpu-optimizations-universal.patch
@@ -1,10 +1,7 @@
-From b5892719c43f739343c628e3d357471a3bdaa368 Mon Sep 17 00:00:00 2001
-From: graysky <graysky@archlinux.us>
-Date: Tue, 15 Mar 2022 05:58:43 -0400
+From a0825feea3f100656d58446885b5f190284fd219
+From: graysky <therealgraysky@proton.me>
+Date: Fri, 4 Nov 2022 15:34:36 -0400
 Subject: [PATCH] more uarches for kernel 5.17+
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
 
 FEATURES
 This patch adds additional CPU options to the Linux kernel accessible under:
@@ -36,6 +33,7 @@ CPU-specific microarchitectures include:
 • AMD Family 17h (Zen)
 • AMD Family 17h (Zen 2)
 • AMD Family 19h (Zen 3)†
+• AMD Family 19h (Zen 4)§
 • Intel Silvermont low-power processors
 • Intel Goldmont low-power processors (Apollo Lake and Denverton)
 • Intel Goldmont Plus low-power processors (Gemini Lake)
@@ -55,11 +53,14 @@ CPU-specific microarchitectures include:
 • Intel 3rd Gen 10nm++ Xeon (Sapphire Rapids)‡
 • Intel 11th Gen i3/i5/i7/i9-family (Rocket Lake)‡
 • Intel 12th Gen i3/i5/i7/i9-family (Alder Lake)‡
+• Intel 13th Gen i3/i5/i7/i9-family (Raptor Lake)§
+• Intel 14th Gen i3/i5/i7/i9-family (Meteor Lake)§
 
 Notes: If not otherwise noted, gcc >=9.1 is required for support.
        *Requires gcc >=10.1 or clang >=10.0
        †Required gcc >=10.3 or clang >=12.0
        ‡Required gcc >=11.1 or clang >=12.0
+       §Required gcc >=13.0 or clang >=15.0.5
 
 It also offers to compile passing the 'native' option which, "selects the CPU
 to generate code for at compilation time by determining the processor type of
@@ -99,20 +100,19 @@ REFERENCES
 4.  https://github.com/graysky2/kernel_gcc_patch/issues/15
 5.  http://www.linuxforge.net/docs/linux/linux-gcc.php
 
-Signed-off-by: graysky <graysky@archlinux.us>
 ---
- arch/x86/Kconfig.cpu            | 332 ++++++++++++++++++++++++++++++--
- arch/x86/Makefile               |  40 +++-
- arch/x86/include/asm/vermagic.h |  66 +++++++
- 3 files changed, 424 insertions(+), 14 deletions(-)
+ arch/x86/Kconfig.cpu            | 416 ++++++++++++++++++++++++++++++--
+ arch/x86/Makefile               |  43 +++-
+ arch/x86/include/asm/vermagic.h |  72 ++++++
+ 3 files changed, 514 insertions(+), 17 deletions(-)
 
 diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
-index 542377cd419d..22b919cdb6d1 100644
+index 542377cd419d..08d887d1220d 100644
 --- a/arch/x86/Kconfig.cpu
 +++ b/arch/x86/Kconfig.cpu
 @@ -157,7 +157,7 @@ config MPENTIUM4
- 
- 
+
+
  config MK6
 -	bool "K6/K6-II/K6-III"
 +	bool "AMD K6/K6-II/K6-III"
@@ -121,16 +121,16 @@ index 542377cd419d..22b919cdb6d1 100644
  	  Select this for an AMD K6-family processor.  Enables use of
 @@ -165,7 +165,7 @@ config MK6
  	  flags to GCC.
- 
+
  config MK7
 -	bool "Athlon/Duron/K7"
 +	bool "AMD Athlon/Duron/K7"
  	depends on X86_32
  	help
  	  Select this for an AMD Athlon K7-family processor.  Enables use of
-@@ -173,12 +173,98 @@ config MK7
+@@ -173,12 +173,106 @@ config MK7
  	  flags to GCC.
- 
+
  config MK8
 -	bool "Opteron/Athlon64/Hammer/K8"
 +	bool "AMD Opteron/Athlon64/Hammer/K8"
@@ -138,7 +138,7 @@ index 542377cd419d..22b919cdb6d1 100644
  	  Select this for an AMD Opteron or Athlon64 Hammer-family processor.
  	  Enables use of some extended instructions, and passes appropriate
  	  optimization flags to GCC.
- 
+
 +config MK8SSE3
 +	bool "AMD Opteron/Athlon64/Hammer/K8 with SSE3"
 +	help
@@ -224,32 +224,40 @@ index 542377cd419d..22b919cdb6d1 100644
 +	  Select this for AMD Family 19h Zen 3 processors.
 +
 +	  Enables -march=znver3
++
++config MZEN4
++	bool "AMD Zen 4"
++	depends on (CC_IS_GCC && GCC_VERSION >= 130000) || (CC_IS_CLANG && CLANG_VERSION >= 150500)
++	help
++	  Select this for AMD Family 19h Zen 4 processors.
++
++	  Enables -march=znver4
 +
  config MCRUSOE
  	bool "Crusoe"
  	depends on X86_32
-@@ -270,7 +356,7 @@ config MPSC
+@@ -270,7 +364,7 @@ config MPSC
  	  in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one.
- 
+
  config MCORE2
 -	bool "Core 2/newer Xeon"
 +	bool "Intel Core 2"
  	help
- 
+
  	  Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and
-@@ -278,6 +364,8 @@ config MCORE2
+@@ -278,6 +372,8 @@ config MCORE2
  	  family in /proc/cpuinfo. Newer ones have 6 and older ones 15
  	  (not a typo)
- 
+
 +	  Enables -march=core2
 +
  config MATOM
  	bool "Intel Atom"
  	help
-@@ -287,6 +375,182 @@ config MATOM
+@@ -287,6 +383,202 @@ config MATOM
  	  accordingly optimized code. Use a recent GCC with specific Atom
  	  support in order to fully benefit from selecting this option.
- 
+
 +config MNEHALEM
 +	bool "Intel Nehalem"
 +	select X86_P6_NOP
@@ -425,14 +433,34 @@ index 542377cd419d..22b919cdb6d1 100644
 +	  Select this for twelfth-generation processors in the Alder Lake family.
 +
 +	  Enables -march=alderlake
++
++config MRAPTORLAKE
++	bool "Intel Raptor Lake"
++	depends on (CC_IS_GCC && GCC_VERSION >= 130000) || (CC_IS_CLANG && CLANG_VERSION >= 150500)
++	select X86_P6_NOP
++	help
++
++	  Select this for thirteenth-generation processors in the Raptor Lake family.
++
++	  Enables -march=raptorlake
++
++config MMETEORLAKE
++	bool "Intel Meteor Lake"
++	depends on (CC_IS_GCC && GCC_VERSION >= 130000) || (CC_IS_CLANG && CLANG_VERSION >= 150500)
++	select X86_P6_NOP
++	help
++
++	  Select this for fourteenth-generation processors in the Meteor Lake family.
++
++	  Enables -march=meteorlake
 +
  config GENERIC_CPU
  	bool "Generic-x86-64"
  	depends on X86_64
-@@ -294,6 +558,50 @@ config GENERIC_CPU
+@@ -294,6 +586,50 @@ config GENERIC_CPU
  	  Generic x86-64 CPU.
  	  Run equally well on all x86-64 CPUs.
- 
+
 +config GENERIC_CPU2
 +	bool "Generic-x86-64-v2"
 +	depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
@@ -478,68 +506,133 @@ index 542377cd419d..22b919cdb6d1 100644
 +	  Enables -march=native
 +
  endchoice
- 
+
  config X86_GENERIC
-@@ -318,7 +626,7 @@ config X86_INTERNODE_CACHE_SHIFT
+@@ -318,9 +654,17 @@ config X86_INTERNODE_CACHE_SHIFT
  config X86_L1_CACHE_SHIFT
  	int
  	default "7" if MPENTIUM4 || MPSC
 -	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
-+	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD || X86_GENERIC || GENERIC_CPU || GENERIC_CPU2 || GENERIC_CPU3 || GENERIC_CPU4
++	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || MK8SSE3 || MK10 \
++	|| MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER \
++	|| MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MZEN4 || MNEHALEM || MWESTMERE || MSILVERMONT \
++	|| MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL \
++	|| MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE \
++	|| MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE \
++	|| MNATIVE_INTEL || MNATIVE_AMD || X86_GENERIC || GENERIC_CPU || GENERIC_CPU2 || GENERIC_CPU3 \
++	|| GENERIC_CPU4
  	default "4" if MELAN || M486SX || M486 || MGEODEGX1
- 	default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
- 
-@@ -336,11 +644,11 @@ config X86_ALIGNMENT_16
- 
+-	default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
++	default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII \
++	|| MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
+
+ config X86_F00F_BUG
+ 	def_bool y
+@@ -332,15 +676,27 @@ config X86_INVD_BUG
+
+ config X86_ALIGNMENT_16
+ 	def_bool y
+-	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486SX || M486 || MVIAC3_2 || MGEODEGX1
++	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC \
++	|| M586 || M486SX || M486 || MVIAC3_2 || MGEODEGX1
+
  config X86_INTEL_USERCOPY
  	def_bool y
 -	depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2
-+	depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL
- 
++	depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC \
++	|| MK8 || MK7 || MEFFICEON || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT \
++	|| MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX \
++	|| MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS \
++	|| MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MNATIVE_INTEL
+
  config X86_USE_PPRO_CHECKSUM
  	def_bool y
 -	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM
-+	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD
- 
++	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM \
++	|| MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX \
++	|| MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER \
++	|| MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MZEN4 || MNEHALEM \
++	|| MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE \
++	|| MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE \
++	|| MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE \
++	|| MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MNATIVE_INTEL || MNATIVE_AMD
+
  #
  # P6_NOPs are a relatively minor optimization that require a family >=
-@@ -356,26 +664,26 @@ config X86_USE_PPRO_CHECKSUM
+@@ -356,32 +712,62 @@ config X86_USE_PPRO_CHECKSUM
  config X86_P6_NOP
  	def_bool y
  	depends on X86_64
 -	depends on (MCORE2 || MPENTIUM4 || MPSC)
-+	depends on (MCORE2 || MPENTIUM4 || MPSC || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL)
- 
++	depends on (MCORE2 || MPENTIUM4 || MPSC || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT \
++	|| MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE \
++	|| MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE \
++	|| MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MNATIVE_INTEL)
+
  config X86_TSC
  	def_bool y
 -	depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) || X86_64
-+	depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD) || X86_64
- 
++	depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM \
++	|| MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 \
++	|| MGEODE_LX || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER \
++	|| MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MZEN4 || MNEHALEM \
++	|| MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL \
++	|| MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE \
++	|| MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MNATIVE_INTEL \
++	|| MNATIVE_AMD) || X86_64
+
  config X86_CMPXCHG64
  	def_bool y
 -	depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586TSC || M586MMX || MATOM || MGEODE_LX || MGEODEGX1 || MK6 || MK7 || MK8
-+	depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586TSC || M586MMX || MATOM || MGEODE_LX || MGEODEGX1 || MK6 || MK7 || MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD
- 
++	depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 \
++	|| M586TSC || M586MMX || MATOM || MGEODE_LX || MGEODEGX1 || MK6 || MK7 || MK8 || MK8SSE3 || MK10 \
++	|| MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN \
++	|| MZEN2 || MZEN3 || MZEN4 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS \
++	|| MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE \
++	|| MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE \
++	|| MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MNATIVE_INTEL || MNATIVE_AMD
+
  # this should be set for all -march=.. options where the compiler
  # generates cmov.
  config X86_CMOV
  	def_bool y
 -	depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
-+	depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD)
- 
++	depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 \
++	|| MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX || MK8SSE3 || MK10 \
++	|| MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR \
++	|| MZEN || MZEN2 || MZEN3 || MZEN4 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT \
++	|| MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX \
++	|| MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS \
++	|| MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MMETEORLAKE || MNATIVE_INTEL || MNATIVE_AMD)
+
  config X86_MINIMUM_CPU_FAMILY
  	int
  	default "64" if X86_64
 -	default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8)
-+	default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8 ||  MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD)
++	default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 \
++	|| MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8 ||  MK8SSE3 \
++	|| MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER \
++	|| MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MZEN4 || MNEHALEM || MWESTMERE || MSILVERMONT \
++	|| MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL \
++	|| MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE \
++	|| MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MRAPTORLAKE || MRAPTORLAKE \
++	|| MNATIVE_INTEL || MNATIVE_AMD)
  	default "5" if X86_32 && X86_CMPXCHG64
  	default "4"
- 
+
+ config X86_DEBUGCTLMSR
+ 	def_bool y
+-	depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486SX || M486) && !UML
++	depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 \
++	|| M486SX || M486) && !UML
+
+ config IA32_FEAT_CTL
+ 	def_bool y
 diff --git a/arch/x86/Makefile b/arch/x86/Makefile
-index e84cdd409b64..7d3bbf060079 100644
+index bafbd905e6e7..7fae52788560 100644
 --- a/arch/x86/Makefile
 +++ b/arch/x86/Makefile
-@@ -131,8 +131,44 @@ else
+@@ -150,8 +150,47 @@ else
          # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu)
          cflags-$(CONFIG_MK8)		+= -march=k8
          cflags-$(CONFIG_MPSC)		+= -march=nocona
@@ -557,6 +650,7 @@ index e84cdd409b64..7d3bbf060079 100644
 +        cflags-$(CONFIG_MZEN) 		+= -march=znver1
 +        cflags-$(CONFIG_MZEN2) 	+= -march=znver2
 +        cflags-$(CONFIG_MZEN3) 	+= -march=znver3
++        cflags-$(CONFIG_MZEN4) 	+= -march=znver4
 +        cflags-$(CONFIG_MNATIVE_INTEL) += -march=native
 +        cflags-$(CONFIG_MNATIVE_AMD) 	+= -march=native
 +        cflags-$(CONFIG_MATOM) 	+= -march=bonnell
@@ -580,17 +674,19 @@ index e84cdd409b64..7d3bbf060079 100644
 +        cflags-$(CONFIG_MSAPPHIRERAPIDS) += -march=sapphirerapids
 +        cflags-$(CONFIG_MROCKETLAKE) 	+= -march=rocketlake
 +        cflags-$(CONFIG_MALDERLAKE) 	+= -march=alderlake
++        cflags-$(CONFIG_MRAPTORLAKE) 	+= -march=raptorlake
++        cflags-$(CONFIG_MMETEORLAKE) 	+= -march=meteorlake
 +        cflags-$(CONFIG_GENERIC_CPU2) 	+= -march=x86-64-v2
 +        cflags-$(CONFIG_GENERIC_CPU3) 	+= -march=x86-64-v3
 +        cflags-$(CONFIG_GENERIC_CPU4) 	+= -march=x86-64-v4
          cflags-$(CONFIG_GENERIC_CPU)	+= -mtune=generic
          KBUILD_CFLAGS += $(cflags-y)
- 
+
 diff --git a/arch/x86/include/asm/vermagic.h b/arch/x86/include/asm/vermagic.h
-index 75884d2cdec3..4e6a08d4c7e5 100644
+index 75884d2cdec3..18021e8c0c28 100644
 --- a/arch/x86/include/asm/vermagic.h
 +++ b/arch/x86/include/asm/vermagic.h
-@@ -17,6 +17,48 @@
+@@ -17,6 +17,52 @@
  #define MODULE_PROC_FAMILY "586MMX "
  #elif defined CONFIG_MCORE2
  #define MODULE_PROC_FAMILY "CORE2 "
@@ -636,10 +732,14 @@ index 75884d2cdec3..4e6a08d4c7e5 100644
 +#define MODULE_PROC_FAMILY "ROCKETLAKE "
 +#elif defined CONFIG_MALDERLAKE
 +#define MODULE_PROC_FAMILY "ALDERLAKE "
++#elif defined CONFIG_MRAPTORLAKE
++#define MODULE_PROC_FAMILY "RAPTORLAKE "
++#elif defined CONFIG_MMETEORLAKE
++#define MODULE_PROC_FAMILY "METEORLAKE "
  #elif defined CONFIG_MATOM
  #define MODULE_PROC_FAMILY "ATOM "
  #elif defined CONFIG_M686
-@@ -35,6 +77,30 @@
+@@ -35,6 +81,32 @@
  #define MODULE_PROC_FAMILY "K7 "
  #elif defined CONFIG_MK8
  #define MODULE_PROC_FAMILY "K8 "
@@ -667,9 +767,10 @@ index 75884d2cdec3..4e6a08d4c7e5 100644
 +#define MODULE_PROC_FAMILY "ZEN2 "
 +#elif defined CONFIG_MZEN3
 +#define MODULE_PROC_FAMILY "ZEN3 "
++#elif defined CONFIG_MZEN4
++#define MODULE_PROC_FAMILY "ZEN4 "
  #elif defined CONFIG_MELAN
  #define MODULE_PROC_FAMILY "ELAN "
  #elif defined CONFIG_MCRUSOE
--- 
-2.35.1
-
+--
+2.38.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2023-01-12 12:17 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2023-01-12 12:17 UTC (permalink / raw
  To: gentoo-commits

commit:     319bd1afecafadce35585a733a6919e656db8780
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Jan 12 12:17:29 2023 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Jan 12 12:17:29 2023 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=319bd1af

Linux patch 6.0.19

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

 0000_README             |    6 +-
 1018_linux-6.0.19.patch | 7559 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 7564 insertions(+), 1 deletion(-)

diff --git a/0000_README b/0000_README
index 569afe2e..ceb9effe 100644
--- a/0000_README
+++ b/0000_README
@@ -111,10 +111,14 @@ Patch:  1016_linux-6.0.17.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.17
 
-Patch:  1017_linux-6.0.19.patch
+Patch:  1017_linux-6.0.18.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.18
 
+Patch:  1018_linux-6.0.19.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.19
+
 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/1018_linux-6.0.19.patch b/1018_linux-6.0.19.patch
new file mode 100644
index 00000000..79b68f80
--- /dev/null
+++ b/1018_linux-6.0.19.patch
@@ -0,0 +1,7559 @@
+diff --git a/Makefile b/Makefile
+index 0104f69d30bbd..b978809a1c7cb 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 18
++SUBLEVEL = 19
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
+index aecc403b28804..7f092cb55a417 100644
+--- a/arch/arm/include/asm/thread_info.h
++++ b/arch/arm/include/asm/thread_info.h
+@@ -128,15 +128,16 @@ extern int vfp_restore_user_hwstate(struct user_vfp *,
+ #define TIF_NEED_RESCHED	1	/* rescheduling necessary */
+ #define TIF_NOTIFY_RESUME	2	/* callback before returning to user */
+ #define TIF_UPROBE		3	/* breakpointed or singlestepping */
+-#define TIF_SYSCALL_TRACE	4	/* syscall trace active */
+-#define TIF_SYSCALL_AUDIT	5	/* syscall auditing active */
+-#define TIF_SYSCALL_TRACEPOINT	6	/* syscall tracepoint instrumentation */
+-#define TIF_SECCOMP		7	/* seccomp syscall filtering active */
+-#define TIF_NOTIFY_SIGNAL	8	/* signal notifications exist */
++#define TIF_NOTIFY_SIGNAL	4	/* signal notifications exist */
+ 
+ #define TIF_USING_IWMMXT	17
+ #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
+-#define TIF_RESTORE_SIGMASK	20
++#define TIF_RESTORE_SIGMASK	19
++#define TIF_SYSCALL_TRACE	20	/* syscall trace active */
++#define TIF_SYSCALL_AUDIT	21	/* syscall auditing active */
++#define TIF_SYSCALL_TRACEPOINT	22	/* syscall tracepoint instrumentation */
++#define TIF_SECCOMP		23	/* seccomp syscall filtering active */
++
+ 
+ #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
+ #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
+diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
+index 01c132bc33d54..4d06de77d92a6 100644
+--- a/arch/mips/ralink/of.c
++++ b/arch/mips/ralink/of.c
+@@ -64,7 +64,7 @@ void __init plat_mem_setup(void)
+ 	dtb = get_fdt();
+ 	__dt_setup_arch(dtb);
+ 
+-	if (!early_init_dt_scan_memory())
++	if (early_init_dt_scan_memory())
+ 		return;
+ 
+ 	if (soc_info.mem_detect)
+diff --git a/arch/riscv/include/asm/uaccess.h b/arch/riscv/include/asm/uaccess.h
+index 855450bed9f52..ec0cab9fbddd0 100644
+--- a/arch/riscv/include/asm/uaccess.h
++++ b/arch/riscv/include/asm/uaccess.h
+@@ -165,7 +165,7 @@ do {								\
+ 	might_fault();						\
+ 	access_ok(__p, sizeof(*__p)) ?		\
+ 		__get_user((x), __p) :				\
+-		((x) = 0, -EFAULT);				\
++		((x) = (__force __typeof__(x))0, -EFAULT);	\
+ })
+ 
+ #define __put_user_asm(insn, x, ptr, err)			\
+diff --git a/arch/riscv/kernel/probes/simulate-insn.h b/arch/riscv/kernel/probes/simulate-insn.h
+index cb6ff7dccb92e..de8474146a9b6 100644
+--- a/arch/riscv/kernel/probes/simulate-insn.h
++++ b/arch/riscv/kernel/probes/simulate-insn.h
+@@ -31,9 +31,9 @@ __RISCV_INSN_FUNCS(fence,	0x7f, 0x0f);
+ 	} while (0)
+ 
+ __RISCV_INSN_FUNCS(c_j,		0xe003, 0xa001);
+-__RISCV_INSN_FUNCS(c_jr,	0xf007, 0x8002);
++__RISCV_INSN_FUNCS(c_jr,	0xf07f, 0x8002);
+ __RISCV_INSN_FUNCS(c_jal,	0xe003, 0x2001);
+-__RISCV_INSN_FUNCS(c_jalr,	0xf007, 0x9002);
++__RISCV_INSN_FUNCS(c_jalr,	0xf07f, 0x9002);
+ __RISCV_INSN_FUNCS(c_beqz,	0xe003, 0xc001);
+ __RISCV_INSN_FUNCS(c_bnez,	0xe003, 0xe001);
+ __RISCV_INSN_FUNCS(c_ebreak,	0xffff, 0x9002);
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index 06ad95ae78ceb..2d6915fe73856 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -1951,6 +1951,8 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
+ 		if (ctrl == PR_SPEC_FORCE_DISABLE)
+ 			task_set_spec_ib_force_disable(task);
+ 		task_update_spec_tif(task);
++		if (task == current)
++			indirect_branch_prediction_barrier();
+ 		break;
+ 	default:
+ 		return -ERANGE;
+diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
+index 9730c88530fc8..305514431f26e 100644
+--- a/arch/x86/kernel/crash.c
++++ b/arch/x86/kernel/crash.c
+@@ -401,10 +401,8 @@ int crash_load_segments(struct kimage *image)
+ 	kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
+ 	kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+ 	ret = kexec_add_buffer(&kbuf);
+-	if (ret) {
+-		vfree((void *)image->elf_headers);
++	if (ret)
+ 		return ret;
+-	}
+ 	image->elf_load_addr = kbuf.mem;
+ 	pr_debug("Loaded ELF headers at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
+ 		 image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
+diff --git a/block/blk-merge.c b/block/blk-merge.c
+index ff04e9290715a..f46c87ef951df 100644
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -300,6 +300,16 @@ static struct bio *bio_split_rw(struct bio *bio, struct queue_limits *lim,
+ 	*segs = nsegs;
+ 	return NULL;
+ split:
++	/*
++	 * We can't sanely support splitting for a REQ_NOWAIT bio. End it
++	 * with EAGAIN if splitting is required and return an error pointer.
++	 */
++	if (bio->bi_opf & REQ_NOWAIT) {
++		bio->bi_status = BLK_STS_AGAIN;
++		bio_endio(bio);
++		return ERR_PTR(-EAGAIN);
++	}
++
+ 	*segs = nsegs;
+ 
+ 	/*
+diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
+index 31a8715d3a4d3..ebb5c846d8260 100644
+--- a/drivers/block/ublk_drv.c
++++ b/drivers/block/ublk_drv.c
+@@ -1718,6 +1718,9 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd,
+ 	struct ublksrv_ctrl_cmd *header = (struct ublksrv_ctrl_cmd *)cmd->cmd;
+ 	int ret = -EINVAL;
+ 
++	if (issue_flags & IO_URING_F_NONBLOCK)
++		return -EAGAIN;
++
+ 	ublk_ctrl_cmd_dump(cmd);
+ 
+ 	if (!(issue_flags & IO_URING_F_SQE128))
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
+index dd9a05174726b..53931fcef0d58 100644
+--- a/drivers/block/virtio_blk.c
++++ b/drivers/block/virtio_blk.c
+@@ -311,22 +311,35 @@ static void virtio_commit_rqs(struct blk_mq_hw_ctx *hctx)
+ 		virtqueue_notify(vq->vq);
+ }
+ 
++static blk_status_t virtblk_fail_to_queue(struct request *req, int rc)
++{
++	virtblk_cleanup_cmd(req);
++	switch (rc) {
++	case -ENOSPC:
++		return BLK_STS_DEV_RESOURCE;
++	case -ENOMEM:
++		return BLK_STS_RESOURCE;
++	default:
++		return BLK_STS_IOERR;
++	}
++}
++
+ static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx,
+ 					struct virtio_blk *vblk,
+ 					struct request *req,
+ 					struct virtblk_req *vbr)
+ {
+ 	blk_status_t status;
++	int num;
+ 
+ 	status = virtblk_setup_cmd(vblk->vdev, req, vbr);
+ 	if (unlikely(status))
+ 		return status;
+ 
+-	vbr->sg_table.nents = virtblk_map_data(hctx, req, vbr);
+-	if (unlikely(vbr->sg_table.nents < 0)) {
+-		virtblk_cleanup_cmd(req);
+-		return BLK_STS_RESOURCE;
+-	}
++	num = virtblk_map_data(hctx, req, vbr);
++	if (unlikely(num < 0))
++		return virtblk_fail_to_queue(req, -ENOMEM);
++	vbr->sg_table.nents = num;
+ 
+ 	blk_mq_start_request(req);
+ 
+@@ -360,15 +373,7 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
+ 			blk_mq_stop_hw_queue(hctx);
+ 		spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags);
+ 		virtblk_unmap_data(req, vbr);
+-		virtblk_cleanup_cmd(req);
+-		switch (err) {
+-		case -ENOSPC:
+-			return BLK_STS_DEV_RESOURCE;
+-		case -ENOMEM:
+-			return BLK_STS_RESOURCE;
+-		default:
+-			return BLK_STS_IOERR;
+-		}
++		return virtblk_fail_to_queue(req, err);
+ 	}
+ 
+ 	if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq))
+diff --git a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c
+index e553ccadbcbc8..e5876286828b8 100644
+--- a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c
++++ b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c
+@@ -239,7 +239,8 @@ static int virtio_crypto_alg_skcipher_close_session(
+ 		pr_err("virtio_crypto: Close session failed status: %u, session_id: 0x%llx\n",
+ 			ctrl_status->status, destroy_session->session_id);
+ 
+-		return -EINVAL;
++		err = -EINVAL;
++		goto out;
+ 	}
+ 
+ 	err = 0;
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index a06decee51e06..a6e9968a2ddc0 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -608,7 +608,7 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
+ 
+ 		seed = early_memremap(efi_rng_seed, sizeof(*seed));
+ 		if (seed != NULL) {
+-			size = min(seed->size, EFI_RANDOM_SEED_SIZE);
++			size = min_t(u32, seed->size, SZ_1K); // sanity check
+ 			early_memunmap(seed, sizeof(*seed));
+ 		} else {
+ 			pr_err("Could not map UEFI random seed!\n");
+@@ -617,8 +617,8 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
+ 			seed = early_memremap(efi_rng_seed,
+ 					      sizeof(*seed) + size);
+ 			if (seed != NULL) {
+-				pr_notice("seeding entropy pool\n");
+ 				add_bootloader_randomness(seed->bits, size);
++				memzero_explicit(seed->bits, size);
+ 				early_memunmap(seed, sizeof(*seed) + size);
+ 			} else {
+ 				pr_err("Could not map UEFI random seed!\n");
+diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
+index b0ae0a454404b..0ce2bf4b8b581 100644
+--- a/drivers/firmware/efi/libstub/efistub.h
++++ b/drivers/firmware/efi/libstub/efistub.h
+@@ -873,6 +873,8 @@ efi_status_t efi_get_random_bytes(unsigned long size, u8 *out);
+ efi_status_t efi_random_alloc(unsigned long size, unsigned long align,
+ 			      unsigned long *addr, unsigned long random_seed);
+ 
++efi_status_t efi_random_get_seed(void);
++
+ efi_status_t check_platform_features(void);
+ 
+ void *get_efi_config_table(efi_guid_t guid);
+diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c
+index 33ab567695951..f85d2c0668777 100644
+--- a/drivers/firmware/efi/libstub/random.c
++++ b/drivers/firmware/efi/libstub/random.c
+@@ -67,27 +67,43 @@ efi_status_t efi_random_get_seed(void)
+ 	efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
+ 	efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
+ 	efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
++	struct linux_efi_random_seed *prev_seed, *seed = NULL;
++	int prev_seed_size = 0, seed_size = EFI_RANDOM_SEED_SIZE;
+ 	efi_rng_protocol_t *rng = NULL;
+-	struct linux_efi_random_seed *seed = NULL;
+ 	efi_status_t status;
+ 
+ 	status = efi_bs_call(locate_protocol, &rng_proto, NULL, (void **)&rng);
+ 	if (status != EFI_SUCCESS)
+ 		return status;
+ 
++	/*
++	 * Check whether a seed was provided by a prior boot stage. In that
++	 * case, instead of overwriting it, let's create a new buffer that can
++	 * hold both, and concatenate the existing and the new seeds.
++	 * Note that we should read the seed size with caution, in case the
++	 * table got corrupted in memory somehow.
++	 */
++	prev_seed = get_efi_config_table(LINUX_EFI_RANDOM_SEED_TABLE_GUID);
++	if (prev_seed && prev_seed->size <= 512U) {
++		prev_seed_size = prev_seed->size;
++		seed_size += prev_seed_size;
++	}
++
+ 	/*
+ 	 * Use EFI_ACPI_RECLAIM_MEMORY here so that it is guaranteed that the
+ 	 * allocation will survive a kexec reboot (although we refresh the seed
+ 	 * beforehand)
+ 	 */
+ 	status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
+-			     sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
++			     struct_size(seed, bits, seed_size),
+ 			     (void **)&seed);
+-	if (status != EFI_SUCCESS)
+-		return status;
++	if (status != EFI_SUCCESS) {
++		efi_warn("Failed to allocate memory for RNG seed.\n");
++		goto err_warn;
++	}
+ 
+ 	status = efi_call_proto(rng, get_rng, &rng_algo_raw,
+-				 EFI_RANDOM_SEED_SIZE, seed->bits);
++				EFI_RANDOM_SEED_SIZE, seed->bits);
+ 
+ 	if (status == EFI_UNSUPPORTED)
+ 		/*
+@@ -100,14 +116,28 @@ efi_status_t efi_random_get_seed(void)
+ 	if (status != EFI_SUCCESS)
+ 		goto err_freepool;
+ 
+-	seed->size = EFI_RANDOM_SEED_SIZE;
++	seed->size = seed_size;
++	if (prev_seed_size)
++		memcpy(seed->bits + EFI_RANDOM_SEED_SIZE, prev_seed->bits,
++		       prev_seed_size);
++
+ 	status = efi_bs_call(install_configuration_table, &rng_table_guid, seed);
+ 	if (status != EFI_SUCCESS)
+ 		goto err_freepool;
+ 
++	if (prev_seed_size) {
++		/* wipe and free the old seed if we managed to install the new one */
++		memzero_explicit(prev_seed->bits, prev_seed_size);
++		efi_bs_call(free_pool, prev_seed);
++	}
+ 	return EFI_SUCCESS;
+ 
+ err_freepool:
++	memzero_explicit(seed, struct_size(seed, bits, seed_size));
+ 	efi_bs_call(free_pool, seed);
++	efi_warn("Failed to obtain seed from EFI_RNG_PROTOCOL\n");
++err_warn:
++	if (prev_seed)
++		efi_warn("Retaining bootloader-supplied seed only");
+ 	return status;
+ }
+diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
+index 238f3210970cf..bc5660f61c570 100644
+--- a/drivers/gpio/gpio-sifive.c
++++ b/drivers/gpio/gpio-sifive.c
+@@ -215,6 +215,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
+ 		return -ENODEV;
+ 	}
+ 	parent = irq_find_host(irq_parent);
++	of_node_put(irq_parent);
+ 	if (!parent) {
+ 		dev_err(dev, "no IRQ parent domain\n");
+ 		return -ENODEV;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index d597e2656c475..2fb7bf47f41ac 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -196,6 +196,7 @@ extern int amdgpu_emu_mode;
+ extern uint amdgpu_smu_memory_pool_size;
+ extern int amdgpu_smu_pptable_id;
+ extern uint amdgpu_dc_feature_mask;
++extern uint amdgpu_freesync_vid_mode;
+ extern uint amdgpu_dc_debug_mask;
+ extern uint amdgpu_dc_visual_confirm;
+ extern uint amdgpu_dm_abm_level;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+index 647220a8762dc..30f145dc8724e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+@@ -265,8 +265,10 @@ int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_
+ 	(&((struct amdgpu_fpriv *)					\
+ 		((struct drm_file *)(drm_priv))->driver_priv)->vm)
+ 
++int amdgpu_amdkfd_gpuvm_set_vm_pasid(struct amdgpu_device *adev,
++				     struct file *filp, u32 pasid);
+ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
+-					struct file *filp, u32 pasid,
++					struct file *filp,
+ 					void **process_info,
+ 					struct dma_fence **ef);
+ void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 6659630303a38..ba5a09c2b3ce6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -1471,10 +1471,9 @@ static void amdgpu_amdkfd_gpuvm_unpin_bo(struct amdgpu_bo *bo)
+ 	amdgpu_bo_unreserve(bo);
+ }
+ 
+-int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
+-					   struct file *filp, u32 pasid,
+-					   void **process_info,
+-					   struct dma_fence **ef)
++int amdgpu_amdkfd_gpuvm_set_vm_pasid(struct amdgpu_device *adev,
++				     struct file *filp, u32 pasid)
++
+ {
+ 	struct amdgpu_fpriv *drv_priv;
+ 	struct amdgpu_vm *avm;
+@@ -1485,10 +1484,6 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
+ 		return ret;
+ 	avm = &drv_priv->vm;
+ 
+-	/* Already a compute VM? */
+-	if (avm->process_info)
+-		return -EINVAL;
+-
+ 	/* Free the original amdgpu allocated pasid,
+ 	 * will be replaced with kfd allocated pasid.
+ 	 */
+@@ -1497,14 +1492,36 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
+ 		amdgpu_vm_set_pasid(adev, avm, 0);
+ 	}
+ 
+-	/* Convert VM into a compute VM */
+-	ret = amdgpu_vm_make_compute(adev, avm);
++	ret = amdgpu_vm_set_pasid(adev, avm, pasid);
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = amdgpu_vm_set_pasid(adev, avm, pasid);
++	return 0;
++}
++
++int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
++					   struct file *filp,
++					   void **process_info,
++					   struct dma_fence **ef)
++{
++	struct amdgpu_fpriv *drv_priv;
++	struct amdgpu_vm *avm;
++	int ret;
++
++	ret = amdgpu_file_to_fpriv(filp, &drv_priv);
+ 	if (ret)
+ 		return ret;
++	avm = &drv_priv->vm;
++
++	/* Already a compute VM? */
++	if (avm->process_info)
++		return -EINVAL;
++
++	/* Convert VM into a compute VM */
++	ret = amdgpu_vm_make_compute(adev, avm);
++	if (ret)
++		return ret;
++
+ 	/* Initialize KFD part of the VM and process info */
+ 	ret = init_kfd_vm(avm, process_info, ef);
+ 	if (ret)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index 379e65ea8afb1..adb369bb7295f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -177,6 +177,7 @@ int amdgpu_mes_kiq;
+ int amdgpu_noretry = -1;
+ int amdgpu_force_asic_type = -1;
+ int amdgpu_tmz = -1; /* auto */
++uint amdgpu_freesync_vid_mode;
+ int amdgpu_reset_method = -1; /* auto */
+ int amdgpu_num_kcq = -1;
+ int amdgpu_smartshift_bias;
+@@ -862,6 +863,32 @@ module_param_named(backlight, amdgpu_backlight, bint, 0444);
+ MODULE_PARM_DESC(tmz, "Enable TMZ feature (-1 = auto (default), 0 = off, 1 = on)");
+ module_param_named(tmz, amdgpu_tmz, int, 0444);
+ 
++/**
++ * DOC: freesync_video (uint)
++ * Enable the optimization to adjust front porch timing to achieve seamless
++ * mode change experience when setting a freesync supported mode for which full
++ * modeset is not needed.
++ *
++ * The Display Core will add a set of modes derived from the base FreeSync
++ * video mode into the corresponding connector's mode list based on commonly
++ * used refresh rates and VRR range of the connected display, when users enable
++ * this feature. From the userspace perspective, they can see a seamless mode
++ * change experience when the change between different refresh rates under the
++ * same resolution. Additionally, userspace applications such as Video playback
++ * can read this modeset list and change the refresh rate based on the video
++ * frame rate. Finally, the userspace can also derive an appropriate mode for a
++ * particular refresh rate based on the FreeSync Mode and add it to the
++ * connector's mode list.
++ *
++ * Note: This is an experimental feature.
++ *
++ * The default value: 0 (off).
++ */
++MODULE_PARM_DESC(
++	freesync_video,
++	"Enable freesync modesetting optimization feature (0 = off (default), 1 = on)");
++module_param_named(freesync_video, amdgpu_freesync_vid_mode, uint, 0444);
++
+ /**
+  * DOC: reset_method (int)
+  * GPU reset method (-1 = auto (default), 0 = legacy, 1 = mode0, 2 = mode1, 3 = mode2, 4 = baco)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+index bfe0fc258fc14..60ab2d952d5c5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+@@ -446,27 +446,24 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
+ 
+ 	/*
+ 	 * If GTT is part of requested domains the check must succeed to
+-	 * allow fall back to GTT
++	 * allow fall back to GTT.
+ 	 */
+ 	if (domain & AMDGPU_GEM_DOMAIN_GTT) {
+ 		man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
+ 
+-		if (size < man->size)
++		if (man && size < man->size)
+ 			return true;
+-		else
+-			goto fail;
+-	}
+-
+-	if (domain & AMDGPU_GEM_DOMAIN_VRAM) {
++		else if (!man)
++			WARN_ON_ONCE("GTT domain requested but GTT mem manager uninitialized");
++		goto fail;
++	} else if (domain & AMDGPU_GEM_DOMAIN_VRAM) {
+ 		man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
+ 
+-		if (size < man->size)
++		if (man && size < man->size)
+ 			return true;
+-		else
+-			goto fail;
++		goto fail;
+ 	}
+ 
+-
+ 	/* TODO add more domains checks, such as AMDGPU_GEM_DOMAIN_CPU */
+ 	return true;
+ 
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+index 6c83a519b3a1b..febf0e9f7af14 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+@@ -689,13 +689,13 @@ void kfd_process_destroy_wq(void)
+ }
+ 
+ static void kfd_process_free_gpuvm(struct kgd_mem *mem,
+-			struct kfd_process_device *pdd, void *kptr)
++			struct kfd_process_device *pdd, void **kptr)
+ {
+ 	struct kfd_dev *dev = pdd->dev;
+ 
+-	if (kptr) {
++	if (kptr && *kptr) {
+ 		amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(mem);
+-		kptr = NULL;
++		*kptr = NULL;
+ 	}
+ 
+ 	amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(dev->adev, mem, pdd->drm_priv);
+@@ -795,7 +795,7 @@ static void kfd_process_device_destroy_ib_mem(struct kfd_process_device *pdd)
+ 	if (!qpd->ib_kaddr || !qpd->ib_base)
+ 		return;
+ 
+-	kfd_process_free_gpuvm(qpd->ib_mem, pdd, qpd->ib_kaddr);
++	kfd_process_free_gpuvm(qpd->ib_mem, pdd, &qpd->ib_kaddr);
+ }
+ 
+ struct kfd_process *kfd_create_process(struct file *filep)
+@@ -1277,7 +1277,7 @@ static void kfd_process_device_destroy_cwsr_dgpu(struct kfd_process_device *pdd)
+ 	if (!dev->cwsr_enabled || !qpd->cwsr_kaddr || !qpd->cwsr_base)
+ 		return;
+ 
+-	kfd_process_free_gpuvm(qpd->cwsr_mem, pdd, qpd->cwsr_kaddr);
++	kfd_process_free_gpuvm(qpd->cwsr_mem, pdd, &qpd->cwsr_kaddr);
+ }
+ 
+ void kfd_process_set_trap_handler(struct qcm_process_device *qpd,
+@@ -1581,9 +1581,9 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd,
+ 	p = pdd->process;
+ 	dev = pdd->dev;
+ 
+-	ret = amdgpu_amdkfd_gpuvm_acquire_process_vm(
+-		dev->adev, drm_file, p->pasid,
+-		&p->kgd_process_info, &p->ef);
++	ret = amdgpu_amdkfd_gpuvm_acquire_process_vm(dev->adev, drm_file,
++						     &p->kgd_process_info,
++						     &p->ef);
+ 	if (ret) {
+ 		pr_err("Failed to create process VM object\n");
+ 		return ret;
+@@ -1598,13 +1598,19 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd,
+ 	if (ret)
+ 		goto err_init_cwsr;
+ 
++	ret = amdgpu_amdkfd_gpuvm_set_vm_pasid(dev->adev, drm_file, p->pasid);
++	if (ret)
++		goto err_set_pasid;
++
+ 	pdd->drm_file = drm_file;
+ 
+ 	return 0;
+ 
++err_set_pasid:
++	kfd_process_device_destroy_cwsr_dgpu(pdd);
+ err_init_cwsr:
++	kfd_process_device_destroy_ib_mem(pdd);
+ err_reserve_ib_mem:
+-	kfd_process_device_free_bos(pdd);
+ 	pdd->drm_priv = NULL;
+ 
+ 	return ret;
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+index 3f0a4a415907d..35a9b702508af 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+@@ -801,7 +801,7 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev,
+ 
+ 		p2plink->attr.name = "properties";
+ 		p2plink->attr.mode = KFD_SYSFS_FILE_MODE;
+-		sysfs_attr_init(&iolink->attr);
++		sysfs_attr_init(&p2plink->attr);
+ 		ret = sysfs_create_file(p2plink->kobj, &p2plink->attr);
+ 		if (ret < 0)
+ 			return ret;
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 895bbd20dd07a..68f2eb215e81c 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -5821,7 +5821,8 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
+ 		 */
+ 		DRM_DEBUG_DRIVER("No preferred mode found\n");
+ 	} else {
+-		recalculate_timing = is_freesync_video_mode(&mode, aconnector);
++		recalculate_timing = amdgpu_freesync_vid_mode &&
++				 is_freesync_video_mode(&mode, aconnector);
+ 		if (recalculate_timing) {
+ 			freesync_mode = get_highest_refresh_rate_mode(aconnector, false);
+ 			drm_mode_copy(&saved_mode, &mode);
+@@ -6895,7 +6896,7 @@ static void amdgpu_dm_connector_add_freesync_modes(struct drm_connector *connect
+ 	struct amdgpu_dm_connector *amdgpu_dm_connector =
+ 		to_amdgpu_dm_connector(connector);
+ 
+-	if (!edid)
++	if (!(amdgpu_freesync_vid_mode && edid))
+ 		return;
+ 
+ 	if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10)
+@@ -8766,7 +8767,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
+ 		 * TODO: Refactor this function to allow this check to work
+ 		 * in all conditions.
+ 		 */
+-		if (dm_new_crtc_state->stream &&
++		if (amdgpu_freesync_vid_mode &&
++		    dm_new_crtc_state->stream &&
+ 		    is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state))
+ 			goto skip_modeset;
+ 
+@@ -8801,7 +8803,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
+ 		if (!dm_old_crtc_state->stream)
+ 			goto skip_modeset;
+ 
+-		if (dm_new_crtc_state->stream &&
++		if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream &&
+ 		    is_timing_unchanged_for_freesync(new_crtc_state,
+ 						     old_crtc_state)) {
+ 			new_crtc_state->mode_changed = false;
+@@ -8813,7 +8815,7 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
+ 			set_freesync_fixed_config(dm_new_crtc_state);
+ 
+ 			goto skip_modeset;
+-		} else if (aconnector &&
++		} else if (amdgpu_freesync_vid_mode && aconnector &&
+ 			   is_freesync_video_mode(&new_crtc_state->mode,
+ 						  aconnector)) {
+ 			struct drm_display_mode *high_mode;
+diff --git a/drivers/gpu/drm/i915/gvt/debugfs.c b/drivers/gpu/drm/i915/gvt/debugfs.c
+index 9f1c209d92511..e08ed0e9f1653 100644
+--- a/drivers/gpu/drm/i915/gvt/debugfs.c
++++ b/drivers/gpu/drm/i915/gvt/debugfs.c
+@@ -175,8 +175,13 @@ void intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu)
+  */
+ void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu)
+ {
+-	debugfs_remove_recursive(vgpu->debugfs);
+-	vgpu->debugfs = NULL;
++	struct intel_gvt *gvt = vgpu->gvt;
++	struct drm_minor *minor = gvt->gt->i915->drm.primary;
++
++	if (minor->debugfs_root && gvt->debugfs_root) {
++		debugfs_remove_recursive(vgpu->debugfs);
++		vgpu->debugfs = NULL;
++	}
+ }
+ 
+ /**
+@@ -199,6 +204,10 @@ void intel_gvt_debugfs_init(struct intel_gvt *gvt)
+  */
+ void intel_gvt_debugfs_clean(struct intel_gvt *gvt)
+ {
+-	debugfs_remove_recursive(gvt->debugfs_root);
+-	gvt->debugfs_root = NULL;
++	struct drm_minor *minor = gvt->gt->i915->drm.primary;
++
++	if (minor->debugfs_root) {
++		debugfs_remove_recursive(gvt->debugfs_root);
++		gvt->debugfs_root = NULL;
++	}
+ }
+diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
+index ce0eb03709c3f..80c60754a5c1c 100644
+--- a/drivers/gpu/drm/i915/gvt/gtt.c
++++ b/drivers/gpu/drm/i915/gvt/gtt.c
+@@ -1214,10 +1214,8 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
+ 	for_each_shadow_entry(sub_spt, &sub_se, sub_index) {
+ 		ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index,
+ 						   PAGE_SIZE, &dma_addr);
+-		if (ret) {
+-			ppgtt_invalidate_spt(spt);
+-			return ret;
+-		}
++		if (ret)
++			goto err;
+ 		sub_se.val64 = se->val64;
+ 
+ 		/* Copy the PAT field from PDE. */
+@@ -1236,6 +1234,17 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
+ 	ops->set_pfn(se, sub_spt->shadow_page.mfn);
+ 	ppgtt_set_shadow_entry(spt, se, index);
+ 	return 0;
++err:
++	/* Cancel the existing addess mappings of DMA addr. */
++	for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) {
++		gvt_vdbg_mm("invalidate 4K entry\n");
++		ppgtt_invalidate_pte(sub_spt, &sub_se);
++	}
++	/* Release the new allocated spt. */
++	trace_spt_change(sub_spt->vgpu->id, "release", sub_spt,
++		sub_spt->guest_page.gfn, sub_spt->shadow_page.type);
++	ppgtt_free_spt(sub_spt);
++	return ret;
+ }
+ 
+ static int split_64KB_gtt_entry(struct intel_vgpu *vgpu,
+diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
+index d6fe94cd0fdb6..8342d95f56cbc 100644
+--- a/drivers/gpu/drm/i915/gvt/scheduler.c
++++ b/drivers/gpu/drm/i915/gvt/scheduler.c
+@@ -696,6 +696,7 @@ intel_vgpu_shadow_mm_pin(struct intel_vgpu_workload *workload)
+ 
+ 	if (workload->shadow_mm->type != INTEL_GVT_MM_PPGTT ||
+ 	    !workload->shadow_mm->ppgtt_mm.shadowed) {
++		intel_vgpu_unpin_mm(workload->shadow_mm);
+ 		gvt_vgpu_err("workload shadow ppgtt isn't ready\n");
+ 		return -EINVAL;
+ 	}
+diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
+index ea5f594955dfe..4b05f310071c0 100644
+--- a/drivers/gpu/drm/imx/ipuv3-plane.c
++++ b/drivers/gpu/drm/imx/ipuv3-plane.c
+@@ -615,6 +615,11 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ 		break;
+ 	}
+ 
++	if (ipu_plane->dp_flow == IPU_DP_FLOW_SYNC_BG)
++		width = ipu_src_rect_width(new_state);
++	else
++		width = drm_rect_width(&new_state->src) >> 16;
++
+ 	eba = drm_plane_state_to_eba(new_state, 0);
+ 
+ 	/*
+@@ -623,8 +628,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ 	 */
+ 	if (ipu_state->use_pre) {
+ 		axi_id = ipu_chan_assign_axi_id(ipu_plane->dma);
+-		ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id,
+-					  ipu_src_rect_width(new_state),
++		ipu_prg_channel_configure(ipu_plane->ipu_ch, axi_id, width,
+ 					  drm_rect_height(&new_state->src) >> 16,
+ 					  fb->pitches[0], fb->format->format,
+ 					  fb->modifier, &eba);
+@@ -679,9 +683,8 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ 		break;
+ 	}
+ 
+-	ipu_dmfc_config_wait4eot(ipu_plane->dmfc, ALIGN(drm_rect_width(dst), 8));
++	ipu_dmfc_config_wait4eot(ipu_plane->dmfc, width);
+ 
+-	width = ipu_src_rect_width(new_state);
+ 	height = drm_rect_height(&new_state->src) >> 16;
+ 	info = drm_format_info(fb->format->format);
+ 	ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0],
+@@ -745,8 +748,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
+ 		ipu_cpmem_set_burstsize(ipu_plane->ipu_ch, 16);
+ 
+ 		ipu_cpmem_zero(ipu_plane->alpha_ch);
+-		ipu_cpmem_set_resolution(ipu_plane->alpha_ch,
+-					 ipu_src_rect_width(new_state),
++		ipu_cpmem_set_resolution(ipu_plane->alpha_ch, width,
+ 					 drm_rect_height(&new_state->src) >> 16);
+ 		ipu_cpmem_set_format_passthrough(ipu_plane->alpha_ch, 8);
+ 		ipu_cpmem_set_high_priority(ipu_plane->alpha_ch);
+diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
+index d4b907889a21d..cd399b0b71814 100644
+--- a/drivers/gpu/drm/meson/meson_viu.c
++++ b/drivers/gpu/drm/meson/meson_viu.c
+@@ -436,15 +436,14 @@ void meson_viu_init(struct meson_drm *priv)
+ 
+ 	/* Initialize OSD1 fifo control register */
+ 	reg = VIU_OSD_DDR_PRIORITY_URGENT |
+-		VIU_OSD_HOLD_FIFO_LINES(31) |
+ 		VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */
+ 		VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */
+ 		VIU_OSD_FIFO_LIMITS(2);      /* fifo_lim: 2*16=32 */
+ 
+ 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
+-		reg |= VIU_OSD_BURST_LENGTH_32;
++		reg |= (VIU_OSD_BURST_LENGTH_32 | VIU_OSD_HOLD_FIFO_LINES(31));
+ 	else
+-		reg |= VIU_OSD_BURST_LENGTH_64;
++		reg |= (VIU_OSD_BURST_LENGTH_64 | VIU_OSD_HOLD_FIFO_LINES(4));
+ 
+ 	writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
+ 	writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
+diff --git a/drivers/gpu/drm/mgag200/mgag200_pll.c b/drivers/gpu/drm/mgag200/mgag200_pll.c
+index 8065ca5d8de9a..4f55961848a84 100644
+--- a/drivers/gpu/drm/mgag200/mgag200_pll.c
++++ b/drivers/gpu/drm/mgag200/mgag200_pll.c
+@@ -269,7 +269,8 @@ static void mgag200_pixpll_update_g200se_04(struct mgag200_pll *pixpll,
+ 	pixpllcp = pixpllc->p - 1;
+ 	pixpllcs = pixpllc->s;
+ 
+-	xpixpllcm = pixpllcm | ((pixpllcn & BIT(8)) >> 1);
++	// For G200SE A, BIT(7) should be set unconditionally.
++	xpixpllcm = BIT(7) | pixpllcm;
+ 	xpixpllcn = pixpllcn;
+ 	xpixpllcp = (pixpllcs << 3) | pixpllcp;
+ 
+diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
+index 2fa5afe212889..919e6cc049828 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
++++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
+@@ -82,6 +82,7 @@ static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data,
+ 	struct panfrost_gem_object *bo;
+ 	struct drm_panfrost_create_bo *args = data;
+ 	struct panfrost_gem_mapping *mapping;
++	int ret;
+ 
+ 	if (!args->size || args->pad ||
+ 	    (args->flags & ~(PANFROST_BO_NOEXEC | PANFROST_BO_HEAP)))
+@@ -92,21 +93,29 @@ static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data,
+ 	    !(args->flags & PANFROST_BO_NOEXEC))
+ 		return -EINVAL;
+ 
+-	bo = panfrost_gem_create_with_handle(file, dev, args->size, args->flags,
+-					     &args->handle);
++	bo = panfrost_gem_create(dev, args->size, args->flags);
+ 	if (IS_ERR(bo))
+ 		return PTR_ERR(bo);
+ 
++	ret = drm_gem_handle_create(file, &bo->base.base, &args->handle);
++	if (ret)
++		goto out;
++
+ 	mapping = panfrost_gem_mapping_get(bo, priv);
+-	if (!mapping) {
+-		drm_gem_object_put(&bo->base.base);
+-		return -EINVAL;
++	if (mapping) {
++		args->offset = mapping->mmnode.start << PAGE_SHIFT;
++		panfrost_gem_mapping_put(mapping);
++	} else {
++		/* This can only happen if the handle from
++		 * drm_gem_handle_create() has already been guessed and freed
++		 * by user space
++		 */
++		ret = -EINVAL;
+ 	}
+ 
+-	args->offset = mapping->mmnode.start << PAGE_SHIFT;
+-	panfrost_gem_mapping_put(mapping);
+-
+-	return 0;
++out:
++	drm_gem_object_put(&bo->base.base);
++	return ret;
+ }
+ 
+ /**
+diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
+index 293e799e2fe81..3c812fbd126fd 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
++++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
+@@ -235,12 +235,8 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t
+ }
+ 
+ struct panfrost_gem_object *
+-panfrost_gem_create_with_handle(struct drm_file *file_priv,
+-				struct drm_device *dev, size_t size,
+-				u32 flags,
+-				uint32_t *handle)
++panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags)
+ {
+-	int ret;
+ 	struct drm_gem_shmem_object *shmem;
+ 	struct panfrost_gem_object *bo;
+ 
+@@ -256,16 +252,6 @@ panfrost_gem_create_with_handle(struct drm_file *file_priv,
+ 	bo->noexec = !!(flags & PANFROST_BO_NOEXEC);
+ 	bo->is_heap = !!(flags & PANFROST_BO_HEAP);
+ 
+-	/*
+-	 * Allocate an id of idr table where the obj is registered
+-	 * and handle has the id what user can see.
+-	 */
+-	ret = drm_gem_handle_create(file_priv, &shmem->base, handle);
+-	/* drop reference from allocate - handle holds it now. */
+-	drm_gem_object_put(&shmem->base);
+-	if (ret)
+-		return ERR_PTR(ret);
+-
+ 	return bo;
+ }
+ 
+diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h
+index 8088d5fd8480e..ad2877eeeccdf 100644
+--- a/drivers/gpu/drm/panfrost/panfrost_gem.h
++++ b/drivers/gpu/drm/panfrost/panfrost_gem.h
+@@ -69,10 +69,7 @@ panfrost_gem_prime_import_sg_table(struct drm_device *dev,
+ 				   struct sg_table *sgt);
+ 
+ struct panfrost_gem_object *
+-panfrost_gem_create_with_handle(struct drm_file *file_priv,
+-				struct drm_device *dev, size_t size,
+-				u32 flags,
+-				uint32_t *handle);
++panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags);
+ 
+ int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv);
+ void panfrost_gem_close(struct drm_gem_object *obj,
+diff --git a/drivers/infiniband/hw/mlx5/counters.c b/drivers/infiniband/hw/mlx5/counters.c
+index 945758f395236..3e1272695d993 100644
+--- a/drivers/infiniband/hw/mlx5/counters.c
++++ b/drivers/infiniband/hw/mlx5/counters.c
+@@ -278,7 +278,6 @@ static int do_get_hw_stats(struct ib_device *ibdev,
+ 	const struct mlx5_ib_counters *cnts = get_counters(dev, port_num - 1);
+ 	struct mlx5_core_dev *mdev;
+ 	int ret, num_counters;
+-	u32 mdev_port_num;
+ 
+ 	if (!stats)
+ 		return -EINVAL;
+@@ -299,8 +298,9 @@ static int do_get_hw_stats(struct ib_device *ibdev,
+ 	}
+ 
+ 	if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
+-		mdev = mlx5_ib_get_native_port_mdev(dev, port_num,
+-						    &mdev_port_num);
++		if (!port_num)
++			port_num = 1;
++		mdev = mlx5_ib_get_native_port_mdev(dev, port_num, NULL);
+ 		if (!mdev) {
+ 			/* If port is not affiliated yet, its in down state
+ 			 * which doesn't have any counters yet, so it would be
+diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
+index 40d9410ec3033..cf953d23d18da 100644
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -4502,6 +4502,40 @@ static bool mlx5_ib_modify_qp_allowed(struct mlx5_ib_dev *dev,
+ 	return false;
+ }
+ 
++static int validate_rd_atomic(struct mlx5_ib_dev *dev, struct ib_qp_attr *attr,
++			      int attr_mask, enum ib_qp_type qp_type)
++{
++	int log_max_ra_res;
++	int log_max_ra_req;
++
++	if (qp_type == MLX5_IB_QPT_DCI) {
++		log_max_ra_res = 1 << MLX5_CAP_GEN(dev->mdev,
++						   log_max_ra_res_dc);
++		log_max_ra_req = 1 << MLX5_CAP_GEN(dev->mdev,
++						   log_max_ra_req_dc);
++	} else {
++		log_max_ra_res = 1 << MLX5_CAP_GEN(dev->mdev,
++						   log_max_ra_res_qp);
++		log_max_ra_req = 1 << MLX5_CAP_GEN(dev->mdev,
++						   log_max_ra_req_qp);
++	}
++
++	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
++	    attr->max_rd_atomic > log_max_ra_res) {
++		mlx5_ib_dbg(dev, "invalid max_rd_atomic value %d\n",
++			    attr->max_rd_atomic);
++		return false;
++	}
++
++	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
++	    attr->max_dest_rd_atomic > log_max_ra_req) {
++		mlx5_ib_dbg(dev, "invalid max_dest_rd_atomic value %d\n",
++			    attr->max_dest_rd_atomic);
++		return false;
++	}
++	return true;
++}
++
+ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 		      int attr_mask, struct ib_udata *udata)
+ {
+@@ -4589,21 +4623,8 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 		goto out;
+ 	}
+ 
+-	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
+-	    attr->max_rd_atomic >
+-	    (1 << MLX5_CAP_GEN(dev->mdev, log_max_ra_res_qp))) {
+-		mlx5_ib_dbg(dev, "invalid max_rd_atomic value %d\n",
+-			    attr->max_rd_atomic);
+-		goto out;
+-	}
+-
+-	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
+-	    attr->max_dest_rd_atomic >
+-	    (1 << MLX5_CAP_GEN(dev->mdev, log_max_ra_req_qp))) {
+-		mlx5_ib_dbg(dev, "invalid max_dest_rd_atomic value %d\n",
+-			    attr->max_dest_rd_atomic);
++	if (!validate_rd_atomic(dev, attr, attr_mask, qp_type))
+ 		goto out;
+-	}
+ 
+ 	if (cur_state == new_state && cur_state == IB_QPS_RESET) {
+ 		err = 0;
+diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
+index e58a1e0cadd2e..9270977e6c7ff 100644
+--- a/drivers/net/bonding/bond_3ad.c
++++ b/drivers/net/bonding/bond_3ad.c
+@@ -1540,6 +1540,7 @@ static void ad_port_selection_logic(struct port *port, bool *update_slave_arr)
+ 			slave_err(bond->dev, port->slave->dev,
+ 				  "Port %d did not find a suitable aggregator\n",
+ 				  port->actor_port_number);
++			return;
+ 		}
+ 	}
+ 	/* if all aggregator's ports are READY_N == TRUE, set ready=TRUE
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 771f2a533d3f6..7807113e09100 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -2653,10 +2653,12 @@ static void bond_miimon_link_change(struct bonding *bond,
+ 
+ static void bond_miimon_commit(struct bonding *bond)
+ {
+-	struct slave *slave, *primary;
++	struct slave *slave, *primary, *active;
+ 	bool do_failover = false;
+ 	struct list_head *iter;
+ 
++	ASSERT_RTNL();
++
+ 	bond_for_each_slave(bond, slave, iter) {
+ 		switch (slave->link_new_state) {
+ 		case BOND_LINK_NOCHANGE:
+@@ -2699,8 +2701,8 @@ static void bond_miimon_commit(struct bonding *bond)
+ 
+ 			bond_miimon_link_change(bond, slave, BOND_LINK_UP);
+ 
+-			if (!rcu_access_pointer(bond->curr_active_slave) || slave == primary ||
+-			    slave->prio > rcu_dereference(bond->curr_active_slave)->prio)
++			active = rtnl_dereference(bond->curr_active_slave);
++			if (!active || slave == primary || slave->prio > active->prio)
+ 				do_failover = true;
+ 
+ 			continue;
+diff --git a/drivers/net/dsa/mv88e6xxx/Kconfig b/drivers/net/dsa/mv88e6xxx/Kconfig
+index 7a2445a34eb77..e3181d5471dfe 100644
+--- a/drivers/net/dsa/mv88e6xxx/Kconfig
++++ b/drivers/net/dsa/mv88e6xxx/Kconfig
+@@ -2,7 +2,6 @@
+ config NET_DSA_MV88E6XXX
+ 	tristate "Marvell 88E6xxx Ethernet switch fabric support"
+ 	depends on NET_DSA
+-	depends on PTP_1588_CLOCK_OPTIONAL
+ 	select IRQ_DOMAIN
+ 	select NET_DSA_TAG_EDSA
+ 	select NET_DSA_TAG_DSA
+@@ -13,7 +12,8 @@ config NET_DSA_MV88E6XXX
+ config NET_DSA_MV88E6XXX_PTP
+ 	bool "PTP support for Marvell 88E6xxx"
+ 	default n
+-	depends on NET_DSA_MV88E6XXX && PTP_1588_CLOCK
++	depends on (NET_DSA_MV88E6XXX = y && PTP_1588_CLOCK = y) || \
++	           (NET_DSA_MV88E6XXX = m && PTP_1588_CLOCK)
+ 	help
+ 	  Say Y to enable PTP hardware timestamping on Marvell 88E6xxx switch
+ 	  chips that support it.
+diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
+index 300c9345ee2be..3587f75807d0d 100644
+--- a/drivers/net/dsa/qca/qca8k-8xxx.c
++++ b/drivers/net/dsa/qca/qca8k-8xxx.c
+@@ -36,44 +36,6 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
+ 	*page = regaddr & 0x3ff;
+ }
+ 
+-static int
+-qca8k_set_lo(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 lo)
+-{
+-	u16 *cached_lo = &priv->mdio_cache.lo;
+-	struct mii_bus *bus = priv->bus;
+-	int ret;
+-
+-	if (lo == *cached_lo)
+-		return 0;
+-
+-	ret = bus->write(bus, phy_id, regnum, lo);
+-	if (ret < 0)
+-		dev_err_ratelimited(&bus->dev,
+-				    "failed to write qca8k 32bit lo register\n");
+-
+-	*cached_lo = lo;
+-	return 0;
+-}
+-
+-static int
+-qca8k_set_hi(struct qca8k_priv *priv, int phy_id, u32 regnum, u16 hi)
+-{
+-	u16 *cached_hi = &priv->mdio_cache.hi;
+-	struct mii_bus *bus = priv->bus;
+-	int ret;
+-
+-	if (hi == *cached_hi)
+-		return 0;
+-
+-	ret = bus->write(bus, phy_id, regnum, hi);
+-	if (ret < 0)
+-		dev_err_ratelimited(&bus->dev,
+-				    "failed to write qca8k 32bit hi register\n");
+-
+-	*cached_hi = hi;
+-	return 0;
+-}
+-
+ static int
+ qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
+ {
+@@ -97,7 +59,7 @@ qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
+ }
+ 
+ static void
+-qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val)
++qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
+ {
+ 	u16 lo, hi;
+ 	int ret;
+@@ -105,9 +67,12 @@ qca8k_mii_write32(struct qca8k_priv *priv, int phy_id, u32 regnum, u32 val)
+ 	lo = val & 0xffff;
+ 	hi = (u16)(val >> 16);
+ 
+-	ret = qca8k_set_lo(priv, phy_id, regnum, lo);
++	ret = bus->write(bus, phy_id, regnum, lo);
+ 	if (ret >= 0)
+-		ret = qca8k_set_hi(priv, phy_id, regnum + 1, hi);
++		ret = bus->write(bus, phy_id, regnum + 1, hi);
++	if (ret < 0)
++		dev_err_ratelimited(&bus->dev,
++				    "failed to write qca8k 32bit register\n");
+ }
+ 
+ static int
+@@ -146,7 +111,16 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
+ 
+ 	command = get_unaligned_le32(&mgmt_ethhdr->command);
+ 	cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command);
++
+ 	len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command);
++	/* Special case for len of 15 as this is the max value for len and needs to
++	 * be increased before converting it from word to dword.
++	 */
++	if (len == 15)
++		len++;
++
++	/* We can ignore odd value, we always round up them in the alloc function. */
++	len *= sizeof(u16);
+ 
+ 	/* Make sure the seq match the requested packet */
+ 	if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq)
+@@ -193,17 +167,33 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
+ 	if (!skb)
+ 		return NULL;
+ 
+-	/* Max value for len reg is 15 (0xf) but the switch actually return 16 byte
+-	 * Actually for some reason the steps are:
+-	 * 0: nothing
+-	 * 1-4: first 4 byte
+-	 * 5-6: first 12 byte
+-	 * 7-15: all 16 byte
++	/* Hdr mgmt length value is in step of word size.
++	 * As an example to process 4 byte of data the correct length to set is 2.
++	 * To process 8 byte 4, 12 byte 6, 16 byte 8...
++	 *
++	 * Odd values will always return the next size on the ack packet.
++	 * (length of 3 (6 byte) will always return 8 bytes of data)
++	 *
++	 * This means that a value of 15 (0xf) actually means reading/writing 32 bytes
++	 * of data.
++	 *
++	 * To correctly calculate the length we devide the requested len by word and
++	 * round up.
++	 * On the ack function we can skip the odd check as we already handle the
++	 * case here.
++	 */
++	real_len = DIV_ROUND_UP(len, sizeof(u16));
++
++	/* We check if the result len is odd and we round up another time to
++	 * the next size. (length of 3 will be increased to 4 as switch will always
++	 * return 8 bytes)
+ 	 */
+-	if (len == 16)
+-		real_len = 15;
+-	else
+-		real_len = len;
++	if (real_len % sizeof(u16) != 0)
++		real_len++;
++
++	/* Max reg value is 0xf(15) but switch will always return the next size (32 byte) */
++	if (real_len == 16)
++		real_len--;
+ 
+ 	skb_reset_mac_header(skb);
+ 	skb_set_network_header(skb, skb->len);
+@@ -417,7 +407,7 @@ qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
+ 	if (ret < 0)
+ 		goto exit;
+ 
+-	qca8k_mii_write32(priv, 0x10 | r2, r1, val);
++	qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+ 
+ exit:
+ 	mutex_unlock(&bus->mdio_lock);
+@@ -450,7 +440,7 @@ qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_
+ 
+ 	val &= ~mask;
+ 	val |= write_val;
+-	qca8k_mii_write32(priv, 0x10 | r2, r1, val);
++	qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+ 
+ exit:
+ 	mutex_unlock(&bus->mdio_lock);
+@@ -725,14 +715,14 @@ qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data)
+ 	if (ret)
+ 		goto exit;
+ 
+-	qca8k_mii_write32(priv, 0x10 | r2, r1, val);
++	qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+ 
+ 	ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
+ 				   QCA8K_MDIO_MASTER_BUSY);
+ 
+ exit:
+ 	/* even if the busy_wait timeouts try to clear the MASTER_EN */
+-	qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
++	qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
+ 
+ 	mutex_unlock(&bus->mdio_lock);
+ 
+@@ -762,7 +752,7 @@ qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)
+ 	if (ret)
+ 		goto exit;
+ 
+-	qca8k_mii_write32(priv, 0x10 | r2, r1, val);
++	qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+ 
+ 	ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
+ 				   QCA8K_MDIO_MASTER_BUSY);
+@@ -773,7 +763,7 @@ qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)
+ 
+ exit:
+ 	/* even if the busy_wait timeouts try to clear the MASTER_EN */
+-	qca8k_mii_write32(priv, 0x10 | r2, r1, 0);
++	qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
+ 
+ 	mutex_unlock(&bus->mdio_lock);
+ 
+@@ -1943,8 +1933,6 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
+ 	}
+ 
+ 	priv->mdio_cache.page = 0xffff;
+-	priv->mdio_cache.lo = 0xffff;
+-	priv->mdio_cache.hi = 0xffff;
+ 
+ 	/* Check the detected switch id */
+ 	ret = qca8k_read_switch_id(priv);
+diff --git a/drivers/net/dsa/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h
+index e36ecc9777f43..342e9d945dfbb 100644
+--- a/drivers/net/dsa/qca/qca8k.h
++++ b/drivers/net/dsa/qca/qca8k.h
+@@ -375,11 +375,6 @@ struct qca8k_mdio_cache {
+  * mdio writes
+  */
+ 	u16 page;
+-/* lo and hi can also be cached and from Documentation we can skip one
+- * extra mdio write if lo or hi is didn't change.
+- */
+-	u16 lo;
+-	u16 hi;
+ };
+ 
+ struct qca8k_pcs {
+diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c
+index 8c8b4c88c7dea..451c3a1b62553 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_com.c
++++ b/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -2400,29 +2400,18 @@ int ena_com_fill_hash_function(struct ena_com_dev *ena_dev,
+ 		return -EOPNOTSUPP;
+ 	}
+ 
+-	switch (func) {
+-	case ENA_ADMIN_TOEPLITZ:
+-		if (key) {
+-			if (key_len != sizeof(hash_key->key)) {
+-				netdev_err(ena_dev->net_device,
+-					   "key len (%u) doesn't equal the supported size (%zu)\n",
+-					   key_len, sizeof(hash_key->key));
+-				return -EINVAL;
+-			}
+-			memcpy(hash_key->key, key, key_len);
+-			rss->hash_init_val = init_val;
+-			hash_key->key_parts = key_len / sizeof(hash_key->key[0]);
++	if ((func == ENA_ADMIN_TOEPLITZ) && key) {
++		if (key_len != sizeof(hash_key->key)) {
++			netdev_err(ena_dev->net_device,
++				   "key len (%u) doesn't equal the supported size (%zu)\n",
++				   key_len, sizeof(hash_key->key));
++			return -EINVAL;
+ 		}
+-		break;
+-	case ENA_ADMIN_CRC32:
+-		rss->hash_init_val = init_val;
+-		break;
+-	default:
+-		netdev_err(ena_dev->net_device, "Invalid hash function (%d)\n",
+-			   func);
+-		return -EINVAL;
++		memcpy(hash_key->key, key, key_len);
++		hash_key->key_parts = key_len / sizeof(hash_key->key[0]);
+ 	}
+ 
++	rss->hash_init_val = init_val;
+ 	old_func = rss->hash_func;
+ 	rss->hash_func = func;
+ 	rc = ena_com_set_hash_function(ena_dev);
+diff --git a/drivers/net/ethernet/amazon/ena/ena_ethtool.c b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+index 39242c5a17290..108506721bcfd 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_ethtool.c
++++ b/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+@@ -887,11 +887,7 @@ static int ena_set_tunable(struct net_device *netdev,
+ 	switch (tuna->id) {
+ 	case ETHTOOL_RX_COPYBREAK:
+ 		len = *(u32 *)data;
+-		if (len > adapter->netdev->mtu) {
+-			ret = -EINVAL;
+-			break;
+-		}
+-		adapter->rx_copybreak = len;
++		ret = ena_set_rx_copybreak(adapter, len);
+ 		break;
+ 	default:
+ 		ret = -EINVAL;
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+index 41c8213484769..413714f373ffd 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -374,9 +374,9 @@ static int ena_xdp_xmit(struct net_device *dev, int n,
+ 
+ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+ {
++	u32 verdict = ENA_XDP_PASS;
+ 	struct bpf_prog *xdp_prog;
+ 	struct ena_ring *xdp_ring;
+-	u32 verdict = XDP_PASS;
+ 	struct xdp_frame *xdpf;
+ 	u64 *xdp_stat;
+ 
+@@ -393,7 +393,7 @@ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+ 		if (unlikely(!xdpf)) {
+ 			trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
+ 			xdp_stat = &rx_ring->rx_stats.xdp_aborted;
+-			verdict = XDP_ABORTED;
++			verdict = ENA_XDP_DROP;
+ 			break;
+ 		}
+ 
+@@ -409,29 +409,35 @@ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+ 
+ 		spin_unlock(&xdp_ring->xdp_tx_lock);
+ 		xdp_stat = &rx_ring->rx_stats.xdp_tx;
++		verdict = ENA_XDP_TX;
+ 		break;
+ 	case XDP_REDIRECT:
+ 		if (likely(!xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog))) {
+ 			xdp_stat = &rx_ring->rx_stats.xdp_redirect;
++			verdict = ENA_XDP_REDIRECT;
+ 			break;
+ 		}
+ 		trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
+ 		xdp_stat = &rx_ring->rx_stats.xdp_aborted;
+-		verdict = XDP_ABORTED;
++		verdict = ENA_XDP_DROP;
+ 		break;
+ 	case XDP_ABORTED:
+ 		trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict);
+ 		xdp_stat = &rx_ring->rx_stats.xdp_aborted;
++		verdict = ENA_XDP_DROP;
+ 		break;
+ 	case XDP_DROP:
+ 		xdp_stat = &rx_ring->rx_stats.xdp_drop;
++		verdict = ENA_XDP_DROP;
+ 		break;
+ 	case XDP_PASS:
+ 		xdp_stat = &rx_ring->rx_stats.xdp_pass;
++		verdict = ENA_XDP_PASS;
+ 		break;
+ 	default:
+ 		bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, verdict);
+ 		xdp_stat = &rx_ring->rx_stats.xdp_invalid;
++		verdict = ENA_XDP_DROP;
+ 	}
+ 
+ 	ena_increase_stat(xdp_stat, 1, &rx_ring->syncp);
+@@ -512,16 +518,18 @@ static void ena_xdp_exchange_program_rx_in_range(struct ena_adapter *adapter,
+ 						 struct bpf_prog *prog,
+ 						 int first, int count)
+ {
++	struct bpf_prog *old_bpf_prog;
+ 	struct ena_ring *rx_ring;
+ 	int i = 0;
+ 
+ 	for (i = first; i < count; i++) {
+ 		rx_ring = &adapter->rx_ring[i];
+-		xchg(&rx_ring->xdp_bpf_prog, prog);
+-		if (prog) {
++		old_bpf_prog = xchg(&rx_ring->xdp_bpf_prog, prog);
++
++		if (!old_bpf_prog && prog) {
+ 			ena_xdp_register_rxq_info(rx_ring);
+ 			rx_ring->rx_headroom = XDP_PACKET_HEADROOM;
+-		} else {
++		} else if (old_bpf_prog && !prog) {
+ 			ena_xdp_unregister_rxq_info(rx_ring);
+ 			rx_ring->rx_headroom = NET_SKB_PAD;
+ 		}
+@@ -672,6 +680,7 @@ static void ena_init_io_rings_common(struct ena_adapter *adapter,
+ 	ring->ena_dev = adapter->ena_dev;
+ 	ring->per_napi_packets = 0;
+ 	ring->cpu = 0;
++	ring->numa_node = 0;
+ 	ring->no_interrupt_event_cnt = 0;
+ 	u64_stats_init(&ring->syncp);
+ }
+@@ -775,6 +784,7 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid)
+ 	tx_ring->next_to_use = 0;
+ 	tx_ring->next_to_clean = 0;
+ 	tx_ring->cpu = ena_irq->cpu;
++	tx_ring->numa_node = node;
+ 	return 0;
+ 
+ err_push_buf_intermediate_buf:
+@@ -907,6 +917,7 @@ static int ena_setup_rx_resources(struct ena_adapter *adapter,
+ 	rx_ring->next_to_clean = 0;
+ 	rx_ring->next_to_use = 0;
+ 	rx_ring->cpu = ena_irq->cpu;
++	rx_ring->numa_node = node;
+ 
+ 	return 0;
+ }
+@@ -1619,12 +1630,12 @@ static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp)
+ 	 * we expect, then we simply drop it
+ 	 */
+ 	if (unlikely(rx_ring->ena_bufs[0].len > ENA_XDP_MAX_MTU))
+-		return XDP_DROP;
++		return ENA_XDP_DROP;
+ 
+ 	ret = ena_xdp_execute(rx_ring, xdp);
+ 
+ 	/* The xdp program might expand the headers */
+-	if (ret == XDP_PASS) {
++	if (ret == ENA_XDP_PASS) {
+ 		rx_info->page_offset = xdp->data - xdp->data_hard_start;
+ 		rx_ring->ena_bufs[0].len = xdp->data_end - xdp->data;
+ 	}
+@@ -1663,7 +1674,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ 	xdp_init_buff(&xdp, ENA_PAGE_SIZE, &rx_ring->xdp_rxq);
+ 
+ 	do {
+-		xdp_verdict = XDP_PASS;
++		xdp_verdict = ENA_XDP_PASS;
+ 		skb = NULL;
+ 		ena_rx_ctx.ena_bufs = rx_ring->ena_bufs;
+ 		ena_rx_ctx.max_bufs = rx_ring->sgl_size;
+@@ -1691,7 +1702,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ 			xdp_verdict = ena_xdp_handle_buff(rx_ring, &xdp);
+ 
+ 		/* allocate skb and fill it */
+-		if (xdp_verdict == XDP_PASS)
++		if (xdp_verdict == ENA_XDP_PASS)
+ 			skb = ena_rx_skb(rx_ring,
+ 					 rx_ring->ena_bufs,
+ 					 ena_rx_ctx.descs,
+@@ -1709,14 +1720,15 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ 				/* Packets was passed for transmission, unmap it
+ 				 * from RX side.
+ 				 */
+-				if (xdp_verdict == XDP_TX || xdp_verdict == XDP_REDIRECT) {
++				if (xdp_verdict & ENA_XDP_FORWARDED) {
+ 					ena_unmap_rx_buff(rx_ring,
+ 							  &rx_ring->rx_buffer_info[req_id]);
+ 					rx_ring->rx_buffer_info[req_id].page = NULL;
+ 				}
+ 			}
+-			if (xdp_verdict != XDP_PASS) {
++			if (xdp_verdict != ENA_XDP_PASS) {
+ 				xdp_flags |= xdp_verdict;
++				total_len += ena_rx_ctx.ena_bufs[0].len;
+ 				res_budget--;
+ 				continue;
+ 			}
+@@ -1760,7 +1772,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ 		ena_refill_rx_bufs(rx_ring, refill_required);
+ 	}
+ 
+-	if (xdp_flags & XDP_REDIRECT)
++	if (xdp_flags & ENA_XDP_REDIRECT)
+ 		xdp_do_flush_map();
+ 
+ 	return work_done;
+@@ -1814,8 +1826,9 @@ static void ena_adjust_adaptive_rx_intr_moderation(struct ena_napi *ena_napi)
+ static void ena_unmask_interrupt(struct ena_ring *tx_ring,
+ 					struct ena_ring *rx_ring)
+ {
++	u32 rx_interval = tx_ring->smoothed_interval;
+ 	struct ena_eth_io_intr_reg intr_reg;
+-	u32 rx_interval = 0;
++
+ 	/* Rx ring can be NULL when for XDP tx queues which don't have an
+ 	 * accompanying rx_ring pair.
+ 	 */
+@@ -1853,20 +1866,27 @@ static void ena_update_ring_numa_node(struct ena_ring *tx_ring,
+ 	if (likely(tx_ring->cpu == cpu))
+ 		goto out;
+ 
++	tx_ring->cpu = cpu;
++	if (rx_ring)
++		rx_ring->cpu = cpu;
++
+ 	numa_node = cpu_to_node(cpu);
++
++	if (likely(tx_ring->numa_node == numa_node))
++		goto out;
++
+ 	put_cpu();
+ 
+ 	if (numa_node != NUMA_NO_NODE) {
+ 		ena_com_update_numa_node(tx_ring->ena_com_io_cq, numa_node);
+-		if (rx_ring)
++		tx_ring->numa_node = numa_node;
++		if (rx_ring) {
++			rx_ring->numa_node = numa_node;
+ 			ena_com_update_numa_node(rx_ring->ena_com_io_cq,
+ 						 numa_node);
++		}
+ 	}
+ 
+-	tx_ring->cpu = cpu;
+-	if (rx_ring)
+-		rx_ring->cpu = cpu;
+-
+ 	return;
+ out:
+ 	put_cpu();
+@@ -1987,11 +2007,10 @@ static int ena_io_poll(struct napi_struct *napi, int budget)
+ 			if (ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev))
+ 				ena_adjust_adaptive_rx_intr_moderation(ena_napi);
+ 
++			ena_update_ring_numa_node(tx_ring, rx_ring);
+ 			ena_unmask_interrupt(tx_ring, rx_ring);
+ 		}
+ 
+-		ena_update_ring_numa_node(tx_ring, rx_ring);
+-
+ 		ret = rx_work_done;
+ 	} else {
+ 		ret = budget;
+@@ -2378,7 +2397,7 @@ static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid)
+ 	ctx.mem_queue_type = ena_dev->tx_mem_queue_type;
+ 	ctx.msix_vector = msix_vector;
+ 	ctx.queue_size = tx_ring->ring_size;
+-	ctx.numa_node = cpu_to_node(tx_ring->cpu);
++	ctx.numa_node = tx_ring->numa_node;
+ 
+ 	rc = ena_com_create_io_queue(ena_dev, &ctx);
+ 	if (rc) {
+@@ -2446,7 +2465,7 @@ static int ena_create_io_rx_queue(struct ena_adapter *adapter, int qid)
+ 	ctx.mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+ 	ctx.msix_vector = msix_vector;
+ 	ctx.queue_size = rx_ring->ring_size;
+-	ctx.numa_node = cpu_to_node(rx_ring->cpu);
++	ctx.numa_node = rx_ring->numa_node;
+ 
+ 	rc = ena_com_create_io_queue(ena_dev, &ctx);
+ 	if (rc) {
+@@ -2807,6 +2826,24 @@ int ena_update_queue_sizes(struct ena_adapter *adapter,
+ 	return dev_was_up ? ena_up(adapter) : 0;
+ }
+ 
++int ena_set_rx_copybreak(struct ena_adapter *adapter, u32 rx_copybreak)
++{
++	struct ena_ring *rx_ring;
++	int i;
++
++	if (rx_copybreak > min_t(u16, adapter->netdev->mtu, ENA_PAGE_SIZE))
++		return -EINVAL;
++
++	adapter->rx_copybreak = rx_copybreak;
++
++	for (i = 0; i < adapter->num_io_queues; i++) {
++		rx_ring = &adapter->rx_ring[i];
++		rx_ring->rx_copybreak = rx_copybreak;
++	}
++
++	return 0;
++}
++
+ int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count)
+ {
+ 	struct ena_com_dev *ena_dev = adapter->ena_dev;
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h
+index 1bdce99bf6888..2cb141079474c 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -262,9 +262,11 @@ struct ena_ring {
+ 	bool disable_meta_caching;
+ 	u16 no_interrupt_event_cnt;
+ 
+-	/* cpu for TPH */
++	/* cpu and NUMA for TPH */
+ 	int cpu;
+-	 /* number of tx/rx_buffer_info's entries */
++	int numa_node;
++
++	/* number of tx/rx_buffer_info's entries */
+ 	int ring_size;
+ 
+ 	enum ena_admin_placement_policy_type tx_mem_queue_type;
+@@ -392,6 +394,8 @@ int ena_update_queue_sizes(struct ena_adapter *adapter,
+ 
+ int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count);
+ 
++int ena_set_rx_copybreak(struct ena_adapter *adapter, u32 rx_copybreak);
++
+ int ena_get_sset_count(struct net_device *netdev, int sset);
+ 
+ static inline void ena_reset_device(struct ena_adapter *adapter,
+@@ -409,6 +413,15 @@ enum ena_xdp_errors_t {
+ 	ENA_XDP_NO_ENOUGH_QUEUES,
+ };
+ 
++enum ENA_XDP_ACTIONS {
++	ENA_XDP_PASS		= 0,
++	ENA_XDP_TX		= BIT(0),
++	ENA_XDP_REDIRECT	= BIT(1),
++	ENA_XDP_DROP		= BIT(2)
++};
++
++#define ENA_XDP_FORWARDED (ENA_XDP_TX | ENA_XDP_REDIRECT)
++
+ static inline bool ena_xdp_present(struct ena_adapter *adapter)
+ {
+ 	return !!adapter->xdp_bpf_prog;
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+index f342bb8531891..2ee2cd4a1e356 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+@@ -1064,6 +1064,9 @@ static void xgbe_free_irqs(struct xgbe_prv_data *pdata)
+ 
+ 	devm_free_irq(pdata->dev, pdata->dev_irq, pdata);
+ 
++	tasklet_kill(&pdata->tasklet_dev);
++	tasklet_kill(&pdata->tasklet_ecc);
++
+ 	if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq))
+ 		devm_free_irq(pdata->dev, pdata->ecc_irq, pdata);
+ 
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c b/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
+index 22d4fc547a0a3..a9ccc4258ee50 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c
+@@ -447,8 +447,10 @@ static void xgbe_i2c_stop(struct xgbe_prv_data *pdata)
+ 	xgbe_i2c_disable(pdata);
+ 	xgbe_i2c_clear_all_interrupts(pdata);
+ 
+-	if (pdata->dev_irq != pdata->i2c_irq)
++	if (pdata->dev_irq != pdata->i2c_irq) {
+ 		devm_free_irq(pdata->dev, pdata->i2c_irq, pdata);
++		tasklet_kill(&pdata->tasklet_i2c);
++	}
+ }
+ 
+ static int xgbe_i2c_start(struct xgbe_prv_data *pdata)
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+index 4e97b48695220..0c5c1b1556830 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+@@ -1390,8 +1390,10 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
+ 	/* Disable auto-negotiation */
+ 	xgbe_an_disable_all(pdata);
+ 
+-	if (pdata->dev_irq != pdata->an_irq)
++	if (pdata->dev_irq != pdata->an_irq) {
+ 		devm_free_irq(pdata->dev, pdata->an_irq, pdata);
++		tasklet_kill(&pdata->tasklet_an);
++	}
+ 
+ 	pdata->phy_if.phy_impl.stop(pdata);
+ 
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 57cabe20aa122..1b38295254e26 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -988,8 +988,7 @@ static struct sk_buff *bnxt_rx_multi_page_skb(struct bnxt *bp,
+ 	dma_addr -= bp->rx_dma_offset;
+ 	dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir,
+ 			     DMA_ATTR_WEAK_ORDERING);
+-	skb = build_skb(page_address(page), BNXT_PAGE_MODE_BUF_SIZE +
+-					    bp->rx_dma_offset);
++	skb = build_skb(page_address(page), PAGE_SIZE);
+ 	if (!skb) {
+ 		__free_page(page);
+ 		return NULL;
+@@ -1922,7 +1921,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+ 	dma_addr = rx_buf->mapping;
+ 
+ 	if (bnxt_xdp_attached(bp, rxr)) {
+-		bnxt_xdp_buff_init(bp, rxr, cons, &data_ptr, &len, &xdp);
++		bnxt_xdp_buff_init(bp, rxr, cons, data_ptr, len, &xdp);
+ 		if (agg_bufs) {
+ 			u32 frag_len = bnxt_rx_agg_pages_xdp(bp, cpr, &xdp,
+ 							     cp_cons, agg_bufs,
+@@ -1937,7 +1936,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+ 	}
+ 
+ 	if (xdp_active) {
+-		if (bnxt_rx_xdp(bp, rxr, cons, xdp, data, &len, event)) {
++		if (bnxt_rx_xdp(bp, rxr, cons, xdp, data, &data_ptr, &len, event)) {
+ 			rc = 1;
+ 			goto next_rx;
+ 		}
+@@ -3966,8 +3965,10 @@ void bnxt_set_ring_params(struct bnxt *bp)
+ 		bp->rx_agg_ring_mask = (bp->rx_agg_nr_pages * RX_DESC_CNT) - 1;
+ 
+ 		if (BNXT_RX_PAGE_MODE(bp)) {
+-			rx_space = BNXT_PAGE_MODE_BUF_SIZE;
+-			rx_size = BNXT_MAX_PAGE_MODE_MTU;
++			rx_space = PAGE_SIZE;
++			rx_size = PAGE_SIZE -
++				  ALIGN(max(NET_SKB_PAD, XDP_PACKET_HEADROOM), 8) -
++				  SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+ 		} else {
+ 			rx_size = SKB_DATA_ALIGN(BNXT_RX_COPY_THRESH + NET_IP_ALIGN);
+ 			rx_space = rx_size + NET_SKB_PAD +
+@@ -5370,15 +5371,16 @@ static int bnxt_hwrm_vnic_set_hds(struct bnxt *bp, u16 vnic_id)
+ 	req->flags = cpu_to_le32(VNIC_PLCMODES_CFG_REQ_FLAGS_JUMBO_PLACEMENT);
+ 	req->enables = cpu_to_le32(VNIC_PLCMODES_CFG_REQ_ENABLES_JUMBO_THRESH_VALID);
+ 
+-	if (BNXT_RX_PAGE_MODE(bp) && !BNXT_RX_JUMBO_MODE(bp)) {
++	if (BNXT_RX_PAGE_MODE(bp)) {
++		req->jumbo_thresh = cpu_to_le16(bp->rx_buf_use_size);
++	} else {
+ 		req->flags |= cpu_to_le32(VNIC_PLCMODES_CFG_REQ_FLAGS_HDS_IPV4 |
+ 					  VNIC_PLCMODES_CFG_REQ_FLAGS_HDS_IPV6);
+ 		req->enables |=
+ 			cpu_to_le32(VNIC_PLCMODES_CFG_REQ_ENABLES_HDS_THRESHOLD_VALID);
++		req->jumbo_thresh = cpu_to_le16(bp->rx_copy_thresh);
++		req->hds_threshold = cpu_to_le16(bp->rx_copy_thresh);
+ 	}
+-	/* thresholds not implemented in firmware yet */
+-	req->jumbo_thresh = cpu_to_le16(bp->rx_copy_thresh);
+-	req->hds_threshold = cpu_to_le16(bp->rx_copy_thresh);
+ 	req->vnic_id = cpu_to_le32(vnic->fw_vnic_id);
+ 	return hwrm_req_send(bp, req);
+ }
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+index d5fa43cfe5248..02741d499bf4a 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+@@ -591,12 +591,20 @@ struct nqe_cn {
+ #define BNXT_RX_PAGE_SIZE (1 << BNXT_RX_PAGE_SHIFT)
+ 
+ #define BNXT_MAX_MTU		9500
+-#define BNXT_PAGE_MODE_BUF_SIZE \
++
++/* First RX buffer page in XDP multi-buf mode
++ *
++ * +-------------------------------------------------------------------------+
++ * | XDP_PACKET_HEADROOM | bp->rx_buf_use_size              | skb_shared_info|
++ * | (bp->rx_dma_offset) |                                  |                |
++ * +-------------------------------------------------------------------------+
++ */
++#define BNXT_MAX_PAGE_MODE_MTU_SBUF \
+ 	((unsigned int)PAGE_SIZE - VLAN_ETH_HLEN - NET_IP_ALIGN -	\
+ 	 XDP_PACKET_HEADROOM)
+ #define BNXT_MAX_PAGE_MODE_MTU	\
+-	BNXT_PAGE_MODE_BUF_SIZE - \
+-	SKB_DATA_ALIGN((unsigned int)sizeof(struct skb_shared_info))
++	(BNXT_MAX_PAGE_MODE_MTU_SBUF - \
++	 SKB_DATA_ALIGN((unsigned int)sizeof(struct skb_shared_info)))
+ 
+ #define BNXT_MIN_PKT_SIZE	52
+ 
+@@ -2131,7 +2139,6 @@ struct bnxt {
+ #define BNXT_DUMP_CRASH		1
+ 
+ 	struct bpf_prog		*xdp_prog;
+-	u8			xdp_has_frags;
+ 
+ 	struct bnxt_ptp_cfg	*ptp_cfg;
+ 	u8			ptp_all_rx_tstamp;
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+index c3065ec0a4798..36d5202c0aeec 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+@@ -177,7 +177,7 @@ bool bnxt_xdp_attached(struct bnxt *bp, struct bnxt_rx_ring_info *rxr)
+ }
+ 
+ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
+-			u16 cons, u8 **data_ptr, unsigned int *len,
++			u16 cons, u8 *data_ptr, unsigned int len,
+ 			struct xdp_buff *xdp)
+ {
+ 	struct bnxt_sw_rx_bd *rx_buf;
+@@ -191,13 +191,10 @@ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
+ 	offset = bp->rx_offset;
+ 
+ 	mapping = rx_buf->mapping - bp->rx_dma_offset;
+-	dma_sync_single_for_cpu(&pdev->dev, mapping + offset, *len, bp->rx_dir);
+-
+-	if (bp->xdp_has_frags)
+-		buflen = BNXT_PAGE_MODE_BUF_SIZE + offset;
++	dma_sync_single_for_cpu(&pdev->dev, mapping + offset, len, bp->rx_dir);
+ 
+ 	xdp_init_buff(xdp, buflen, &rxr->xdp_rxq);
+-	xdp_prepare_buff(xdp, *data_ptr - offset, offset, *len, false);
++	xdp_prepare_buff(xdp, data_ptr - offset, offset, len, false);
+ }
+ 
+ void bnxt_xdp_buff_frags_free(struct bnxt_rx_ring_info *rxr,
+@@ -222,7 +219,8 @@ void bnxt_xdp_buff_frags_free(struct bnxt_rx_ring_info *rxr,
+  * false   - packet should be passed to the stack.
+  */
+ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
+-		 struct xdp_buff xdp, struct page *page, unsigned int *len, u8 *event)
++		 struct xdp_buff xdp, struct page *page, u8 **data_ptr,
++		 unsigned int *len, u8 *event)
+ {
+ 	struct bpf_prog *xdp_prog = READ_ONCE(rxr->xdp_prog);
+ 	struct bnxt_tx_ring_info *txr;
+@@ -255,8 +253,10 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
+ 		*event &= ~BNXT_RX_EVENT;
+ 
+ 	*len = xdp.data_end - xdp.data;
+-	if (orig_data != xdp.data)
++	if (orig_data != xdp.data) {
+ 		offset = xdp.data - xdp.data_hard_start;
++		*data_ptr = xdp.data_hard_start + offset;
++	}
+ 
+ 	switch (act) {
+ 	case XDP_PASS:
+@@ -401,10 +401,8 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
+ 		netdev_warn(dev, "ethtool rx/tx channels must be combined to support XDP.\n");
+ 		return -EOPNOTSUPP;
+ 	}
+-	if (prog) {
++	if (prog)
+ 		tx_xdp = bp->rx_nr_rings;
+-		bp->xdp_has_frags = prog->aux->xdp_has_frags;
+-	}
+ 
+ 	tc = netdev_get_num_tc(dev);
+ 	if (!tc)
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
+index 505911ae095d3..ea430d6961df3 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
+@@ -18,8 +18,8 @@ struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
+ 				   struct xdp_buff *xdp);
+ void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts);
+ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
+-		 struct xdp_buff xdp, struct page *page, unsigned int *len,
+-		 u8 *event);
++		 struct xdp_buff xdp, struct page *page, u8 **data_ptr,
++		 unsigned int *len, u8 *event);
+ int bnxt_xdp(struct net_device *dev, struct netdev_bpf *xdp);
+ int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
+ 		  struct xdp_frame **frames, u32 flags);
+@@ -27,7 +27,7 @@ int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
+ bool bnxt_xdp_attached(struct bnxt *bp, struct bnxt_rx_ring_info *rxr);
+ 
+ void bnxt_xdp_buff_init(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
+-			u16 cons, u8 **data_ptr, unsigned int *len,
++			u16 cons, u8 *data_ptr, unsigned int len,
+ 			struct xdp_buff *xdp);
+ void bnxt_xdp_buff_frags_free(struct bnxt_rx_ring_info *rxr,
+ 			      struct xdp_buff *xdp);
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
+index 7d4ae467f3ad4..abcd7877f7d2a 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
+@@ -233,6 +233,17 @@ struct hclgevf_mbx_arq_ring {
+ 	__le16 msg_q[HCLGE_MBX_MAX_ARQ_MSG_NUM][HCLGE_MBX_MAX_ARQ_MSG_SIZE];
+ };
+ 
++struct hclge_dev;
++
++#define HCLGE_MBX_OPCODE_MAX 256
++struct hclge_mbx_ops_param {
++	struct hclge_vport *vport;
++	struct hclge_mbx_vf_to_pf_cmd *req;
++	struct hclge_respond_to_vf_msg *resp_msg;
++};
++
++typedef int (*hclge_mbx_ops_fn)(struct hclge_mbx_ops_param *param);
++
+ #define hclge_mbx_ring_ptr_move_crq(crq) \
+ 	(crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num)
+ #define hclge_mbx_tail_ptr_move_arq(arq) \
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index 44d4265f109a8..d5d7fae354e7e 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -3813,18 +3813,16 @@ static int hns3_gro_complete(struct sk_buff *skb, u32 l234info)
+ 	return 0;
+ }
+ 
+-static bool hns3_checksum_complete(struct hns3_enet_ring *ring,
++static void hns3_checksum_complete(struct hns3_enet_ring *ring,
+ 				   struct sk_buff *skb, u32 ptype, u16 csum)
+ {
+ 	if (ptype == HNS3_INVALID_PTYPE ||
+ 	    hns3_rx_ptype_tbl[ptype].ip_summed != CHECKSUM_COMPLETE)
+-		return false;
++		return;
+ 
+ 	hns3_ring_stats_update(ring, csum_complete);
+ 	skb->ip_summed = CHECKSUM_COMPLETE;
+ 	skb->csum = csum_unfold((__force __sum16)csum);
+-
+-	return true;
+ }
+ 
+ static void hns3_rx_handle_csum(struct sk_buff *skb, u32 l234info,
+@@ -3884,8 +3882,7 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
+ 		ptype = hnae3_get_field(ol_info, HNS3_RXD_PTYPE_M,
+ 					HNS3_RXD_PTYPE_S);
+ 
+-	if (hns3_checksum_complete(ring, skb, ptype, csum))
+-		return;
++	hns3_checksum_complete(ring, skb, ptype, csum);
+ 
+ 	/* check if hardware has done checksum */
+ 	if (!(bd_base_info & BIT(HNS3_RXD_L3L4P_B)))
+@@ -3894,6 +3891,7 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
+ 	if (unlikely(l234info & (BIT(HNS3_RXD_L3E_B) | BIT(HNS3_RXD_L4E_B) |
+ 				 BIT(HNS3_RXD_OL3E_B) |
+ 				 BIT(HNS3_RXD_OL4E_B)))) {
++		skb->ip_summed = CHECKSUM_NONE;
+ 		hns3_ring_stats_update(ring, l3l4_csum_err);
+ 
+ 		return;
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index 7e8a60f2401c9..d2dde3f1fb884 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -3713,9 +3713,17 @@ static int hclge_set_all_vf_rst(struct hclge_dev *hdev, bool reset)
+ 			return ret;
+ 		}
+ 
+-		if (!reset || !test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
++		if (!reset ||
++		    !test_bit(HCLGE_VPORT_STATE_INITED, &vport->state))
+ 			continue;
+ 
++		if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state) &&
++		    hdev->reset_type == HNAE3_FUNC_RESET) {
++			set_bit(HCLGE_VPORT_NEED_NOTIFY_RESET,
++				&vport->need_notify);
++			continue;
++		}
++
+ 		/* Inform VF to process the reset.
+ 		 * hclge_inform_reset_assert_to_vf may fail if VF
+ 		 * driver is not loaded.
+@@ -4412,18 +4420,25 @@ static void hclge_reset_service_task(struct hclge_dev *hdev)
+ 
+ static void hclge_update_vport_alive(struct hclge_dev *hdev)
+ {
++#define HCLGE_ALIVE_SECONDS_NORMAL		8
++
++	unsigned long alive_time = HCLGE_ALIVE_SECONDS_NORMAL * HZ;
+ 	int i;
+ 
+ 	/* start from vport 1 for PF is always alive */
+ 	for (i = 1; i < hdev->num_alloc_vport; i++) {
+ 		struct hclge_vport *vport = &hdev->vport[i];
+ 
+-		if (time_after(jiffies, vport->last_active_jiffies + 8 * HZ))
++		if (!test_bit(HCLGE_VPORT_STATE_INITED, &vport->state) ||
++		    !test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
++			continue;
++		if (time_after(jiffies, vport->last_active_jiffies +
++			       alive_time)) {
+ 			clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
+-
+-		/* If vf is not alive, set to default value */
+-		if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
+-			vport->mps = HCLGE_MAC_DEFAULT_FRAME;
++			dev_warn(&hdev->pdev->dev,
++				 "VF %u heartbeat timeout\n",
++				 i - HCLGE_VF_VPORT_START_NUM);
++		}
+ 	}
+ }
+ 
+@@ -7853,9 +7868,11 @@ int hclge_vport_start(struct hclge_vport *vport)
+ {
+ 	struct hclge_dev *hdev = vport->back;
+ 
++	set_bit(HCLGE_VPORT_STATE_INITED, &vport->state);
+ 	set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
+ 	set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
+ 	vport->last_active_jiffies = jiffies;
++	vport->need_notify = 0;
+ 
+ 	if (test_bit(vport->vport_id, hdev->vport_config_block)) {
+ 		if (vport->vport_id) {
+@@ -7873,7 +7890,9 @@ int hclge_vport_start(struct hclge_vport *vport)
+ 
+ void hclge_vport_stop(struct hclge_vport *vport)
+ {
++	clear_bit(HCLGE_VPORT_STATE_INITED, &vport->state);
+ 	clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
++	vport->need_notify = 0;
+ }
+ 
+ static int hclge_client_start(struct hnae3_handle *handle)
+@@ -8997,7 +9016,8 @@ static int hclge_set_vf_mac(struct hnae3_handle *handle, int vf,
+ 		return 0;
+ 	}
+ 
+-	dev_info(&hdev->pdev->dev, "MAC of VF %d has been set to %s\n",
++	dev_info(&hdev->pdev->dev,
++		 "MAC of VF %d has been set to %s, will be active after VF reset\n",
+ 		 vf, format_mac_addr);
+ 	return 0;
+ }
+@@ -10254,12 +10274,16 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
+ 	 * for DEVICE_VERSION_V3, vf doesn't need to know about the port based
+ 	 * VLAN state.
+ 	 */
+-	if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3 &&
+-	    test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
+-		(void)hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
+-							vport->vport_id,
+-							state, &vlan_info);
+-
++	if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3) {
++		if (test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
++			(void)hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
++								vport->vport_id,
++								state,
++								&vlan_info);
++		else
++			set_bit(HCLGE_VPORT_NEED_NOTIFY_VF_VLAN,
++				&vport->need_notify);
++	}
+ 	return 0;
+ }
+ 
+@@ -11723,7 +11747,7 @@ static void hclge_reset_vport_state(struct hclge_dev *hdev)
+ 	int i;
+ 
+ 	for (i = 0; i < hdev->num_alloc_vport; i++) {
+-		hclge_vport_stop(vport);
++		clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
+ 		vport++;
+ 	}
+ }
+@@ -12536,60 +12560,71 @@ static int hclge_gro_en(struct hnae3_handle *handle, bool enable)
+ 	return ret;
+ }
+ 
+-static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
++static int hclge_sync_vport_promisc_mode(struct hclge_vport *vport)
+ {
+-	struct hclge_vport *vport = &hdev->vport[0];
+ 	struct hnae3_handle *handle = &vport->nic;
++	struct hclge_dev *hdev = vport->back;
++	bool uc_en = false;
++	bool mc_en = false;
+ 	u8 tmp_flags;
++	bool bc_en;
+ 	int ret;
+-	u16 i;
+ 
+ 	if (vport->last_promisc_flags != vport->overflow_promisc_flags) {
+ 		set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
+ 		vport->last_promisc_flags = vport->overflow_promisc_flags;
+ 	}
+ 
+-	if (test_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state)) {
++	if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
++				&vport->state))
++		return 0;
++
++	/* for PF */
++	if (!vport->vport_id) {
+ 		tmp_flags = handle->netdev_flags | vport->last_promisc_flags;
+ 		ret = hclge_set_promisc_mode(handle, tmp_flags & HNAE3_UPE,
+ 					     tmp_flags & HNAE3_MPE);
+-		if (!ret) {
+-			clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
+-				  &vport->state);
++		if (!ret)
+ 			set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
+ 				&vport->state);
+-		}
++		else
++			set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
++				&vport->state);
++		return ret;
+ 	}
+ 
+-	for (i = 1; i < hdev->num_alloc_vport; i++) {
+-		bool uc_en = false;
+-		bool mc_en = false;
+-		bool bc_en;
++	/* for VF */
++	if (vport->vf_info.trusted) {
++		uc_en = vport->vf_info.request_uc_en > 0 ||
++			vport->overflow_promisc_flags & HNAE3_OVERFLOW_UPE;
++		mc_en = vport->vf_info.request_mc_en > 0 ||
++			vport->overflow_promisc_flags & HNAE3_OVERFLOW_MPE;
++	}
++	bc_en = vport->vf_info.request_bc_en > 0;
+ 
+-		vport = &hdev->vport[i];
++	ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en,
++					 mc_en, bc_en);
++	if (ret) {
++		set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
++		return ret;
++	}
++	hclge_set_vport_vlan_fltr_change(vport);
+ 
+-		if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
+-					&vport->state))
+-			continue;
++	return 0;
++}
+ 
+-		if (vport->vf_info.trusted) {
+-			uc_en = vport->vf_info.request_uc_en > 0 ||
+-				vport->overflow_promisc_flags &
+-				HNAE3_OVERFLOW_UPE;
+-			mc_en = vport->vf_info.request_mc_en > 0 ||
+-				vport->overflow_promisc_flags &
+-				HNAE3_OVERFLOW_MPE;
+-		}
+-		bc_en = vport->vf_info.request_bc_en > 0;
++static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
++{
++	struct hclge_vport *vport;
++	int ret;
++	u16 i;
+ 
+-		ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en,
+-						 mc_en, bc_en);
+-		if (ret) {
+-			set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
+-				&vport->state);
++	for (i = 0; i < hdev->num_alloc_vport; i++) {
++		vport = &hdev->vport[i];
++
++		ret = hclge_sync_vport_promisc_mode(vport);
++		if (ret)
+ 			return;
+-		}
+-		hclge_set_vport_vlan_fltr_change(vport);
+ 	}
+ }
+ 
+@@ -12726,6 +12761,11 @@ static void hclge_clear_vport_vf_info(struct hclge_vport *vport, int vfid)
+ 	struct hclge_vlan_info vlan_info;
+ 	int ret;
+ 
++	clear_bit(HCLGE_VPORT_STATE_INITED, &vport->state);
++	clear_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
++	vport->need_notify = 0;
++	vport->mps = 0;
++
+ 	/* after disable sriov, clean VF rate configured by PF */
+ 	ret = hclge_tm_qs_shaper_cfg(vport, 0);
+ 	if (ret)
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+index 18caddd541f8a..14473e29fe034 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+@@ -972,9 +972,15 @@ enum HCLGE_VPORT_STATE {
+ 	HCLGE_VPORT_STATE_MAC_TBL_CHANGE,
+ 	HCLGE_VPORT_STATE_PROMISC_CHANGE,
+ 	HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
++	HCLGE_VPORT_STATE_INITED,
+ 	HCLGE_VPORT_STATE_MAX
+ };
+ 
++enum HCLGE_VPORT_NEED_NOTIFY {
++	HCLGE_VPORT_NEED_NOTIFY_RESET,
++	HCLGE_VPORT_NEED_NOTIFY_VF_VLAN,
++};
++
+ struct hclge_vlan_info {
+ 	u16 vlan_proto; /* so far support 802.1Q only */
+ 	u16 qos;
+@@ -1021,6 +1027,7 @@ struct hclge_vport {
+ 	struct hnae3_handle roce;
+ 
+ 	unsigned long state;
++	unsigned long need_notify;
+ 	unsigned long last_active_jiffies;
+ 	u32 mps; /* Max packet size */
+ 	struct hclge_vf_info vf_info;
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+index e1012f7f9b734..04ff9bf121853 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+@@ -124,17 +124,26 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len,
+ 	return status;
+ }
+ 
++static int hclge_inform_vf_reset(struct hclge_vport *vport, u16 reset_type)
++{
++	__le16 msg_data;
++	u8 dest_vfid;
++
++	dest_vfid = (u8)vport->vport_id;
++	msg_data = cpu_to_le16(reset_type);
++
++	/* send this requested info to VF */
++	return hclge_send_mbx_msg(vport, (u8 *)&msg_data, sizeof(msg_data),
++				  HCLGE_MBX_ASSERTING_RESET, dest_vfid);
++}
++
+ int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
+ {
+ 	struct hclge_dev *hdev = vport->back;
+-	__le16 msg_data;
+ 	u16 reset_type;
+-	u8 dest_vfid;
+ 
+ 	BUILD_BUG_ON(HNAE3_MAX_RESET > U16_MAX);
+ 
+-	dest_vfid = (u8)vport->vport_id;
+-
+ 	if (hdev->reset_type == HNAE3_FUNC_RESET)
+ 		reset_type = HNAE3_VF_PF_FUNC_RESET;
+ 	else if (hdev->reset_type == HNAE3_FLR_RESET)
+@@ -142,11 +151,7 @@ int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
+ 	else
+ 		reset_type = HNAE3_VF_FUNC_RESET;
+ 
+-	msg_data = cpu_to_le16(reset_type);
+-
+-	/* send this requested info to VF */
+-	return hclge_send_mbx_msg(vport, (u8 *)&msg_data, sizeof(msg_data),
+-				  HCLGE_MBX_ASSERTING_RESET, dest_vfid);
++	return hclge_inform_vf_reset(vport, reset_type);
+ }
+ 
+ static void hclge_free_vector_ring_chain(struct hnae3_ring_chain_node *head)
+@@ -652,9 +657,56 @@ static int hclge_reset_vf(struct hclge_vport *vport)
+ 	return hclge_func_reset_cmd(hdev, vport->vport_id);
+ }
+ 
++static void hclge_notify_vf_config(struct hclge_vport *vport)
++{
++	struct hclge_dev *hdev = vport->back;
++	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
++	struct hclge_port_base_vlan_config *vlan_cfg;
++	int ret;
++
++	hclge_push_vf_link_status(vport);
++	if (test_bit(HCLGE_VPORT_NEED_NOTIFY_RESET, &vport->need_notify)) {
++		ret = hclge_inform_vf_reset(vport, HNAE3_VF_PF_FUNC_RESET);
++		if (ret) {
++			dev_err(&hdev->pdev->dev,
++				"failed to inform VF %u reset!",
++				vport->vport_id - HCLGE_VF_VPORT_START_NUM);
++			return;
++		}
++		vport->need_notify = 0;
++		return;
++	}
++
++	if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3 &&
++	    test_bit(HCLGE_VPORT_NEED_NOTIFY_VF_VLAN, &vport->need_notify)) {
++		vlan_cfg = &vport->port_base_vlan_cfg;
++		ret = hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
++							vport->vport_id,
++							vlan_cfg->state,
++							&vlan_cfg->vlan_info);
++		if (ret) {
++			dev_err(&hdev->pdev->dev,
++				"failed to inform VF %u port base vlan!",
++				vport->vport_id - HCLGE_VF_VPORT_START_NUM);
++			return;
++		}
++		clear_bit(HCLGE_VPORT_NEED_NOTIFY_VF_VLAN, &vport->need_notify);
++	}
++}
++
+ static void hclge_vf_keep_alive(struct hclge_vport *vport)
+ {
++	struct hclge_dev *hdev = vport->back;
++
+ 	vport->last_active_jiffies = jiffies;
++
++	if (test_bit(HCLGE_VPORT_STATE_INITED, &vport->state) &&
++	    !test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) {
++		set_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state);
++		dev_info(&hdev->pdev->dev, "VF %u is alive!",
++			 vport->vport_id - HCLGE_VF_VPORT_START_NUM);
++		hclge_notify_vf_config(vport);
++	}
+ }
+ 
+ static int hclge_set_vf_mtu(struct hclge_vport *vport,
+@@ -779,17 +831,285 @@ static void hclge_handle_vf_tbl(struct hclge_vport *vport,
+ 	}
+ }
+ 
++static int
++hclge_mbx_map_ring_to_vector_handler(struct hclge_mbx_ops_param *param)
++{
++	return hclge_map_unmap_ring_to_vf_vector(param->vport, true,
++						 param->req);
++}
++
++static int
++hclge_mbx_unmap_ring_to_vector_handler(struct hclge_mbx_ops_param *param)
++{
++	return hclge_map_unmap_ring_to_vf_vector(param->vport, false,
++						 param->req);
++}
++
++static int
++hclge_mbx_get_ring_vector_map_handler(struct hclge_mbx_ops_param *param)
++{
++	int ret;
++
++	ret = hclge_get_vf_ring_vector_map(param->vport, param->req,
++					   param->resp_msg);
++	if (ret)
++		dev_err(&param->vport->back->pdev->dev,
++			"PF fail(%d) to get VF ring vector map\n",
++			ret);
++	return ret;
++}
++
++static int hclge_mbx_set_promisc_mode_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_set_vf_promisc_mode(param->vport, param->req);
++	return 0;
++}
++
++static int hclge_mbx_set_unicast_handler(struct hclge_mbx_ops_param *param)
++{
++	int ret;
++
++	ret = hclge_set_vf_uc_mac_addr(param->vport, param->req);
++	if (ret)
++		dev_err(&param->vport->back->pdev->dev,
++			"PF fail(%d) to set VF UC MAC Addr\n",
++			ret);
++	return ret;
++}
++
++static int hclge_mbx_set_multicast_handler(struct hclge_mbx_ops_param *param)
++{
++	int ret;
++
++	ret = hclge_set_vf_mc_mac_addr(param->vport, param->req);
++	if (ret)
++		dev_err(&param->vport->back->pdev->dev,
++			"PF fail(%d) to set VF MC MAC Addr\n",
++			ret);
++	return ret;
++}
++
++static int hclge_mbx_set_vlan_handler(struct hclge_mbx_ops_param *param)
++{
++	int ret;
++
++	ret = hclge_set_vf_vlan_cfg(param->vport, param->req, param->resp_msg);
++	if (ret)
++		dev_err(&param->vport->back->pdev->dev,
++			"PF failed(%d) to config VF's VLAN\n",
++			ret);
++	return ret;
++}
++
++static int hclge_mbx_set_alive_handler(struct hclge_mbx_ops_param *param)
++{
++	int ret;
++
++	ret = hclge_set_vf_alive(param->vport, param->req);
++	if (ret)
++		dev_err(&param->vport->back->pdev->dev,
++			"PF failed(%d) to set VF's ALIVE\n",
++			ret);
++	return ret;
++}
++
++static int hclge_mbx_get_qinfo_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_get_vf_queue_info(param->vport, param->resp_msg);
++	return 0;
++}
++
++static int hclge_mbx_get_qdepth_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_get_vf_queue_depth(param->vport, param->resp_msg);
++	return 0;
++}
++
++static int hclge_mbx_get_basic_info_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_get_basic_info(param->vport, param->resp_msg);
++	return 0;
++}
++
++static int hclge_mbx_get_link_status_handler(struct hclge_mbx_ops_param *param)
++{
++	int ret;
++
++	ret = hclge_push_vf_link_status(param->vport);
++	if (ret)
++		dev_err(&param->vport->back->pdev->dev,
++			"failed to inform link stat to VF, ret = %d\n",
++			ret);
++	return ret;
++}
++
++static int hclge_mbx_queue_reset_handler(struct hclge_mbx_ops_param *param)
++{
++	return hclge_mbx_reset_vf_queue(param->vport, param->req,
++					param->resp_msg);
++}
++
++static int hclge_mbx_reset_handler(struct hclge_mbx_ops_param *param)
++{
++	return hclge_reset_vf(param->vport);
++}
++
++static int hclge_mbx_keep_alive_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_vf_keep_alive(param->vport);
++	return 0;
++}
++
++static int hclge_mbx_set_mtu_handler(struct hclge_mbx_ops_param *param)
++{
++	int ret;
++
++	ret = hclge_set_vf_mtu(param->vport, param->req);
++	if (ret)
++		dev_err(&param->vport->back->pdev->dev,
++			"VF fail(%d) to set mtu\n", ret);
++	return ret;
++}
++
++static int hclge_mbx_get_qid_in_pf_handler(struct hclge_mbx_ops_param *param)
++{
++	return hclge_get_queue_id_in_pf(param->vport, param->req,
++					param->resp_msg);
++}
++
++static int hclge_mbx_get_rss_key_handler(struct hclge_mbx_ops_param *param)
++{
++	return hclge_get_rss_key(param->vport, param->req, param->resp_msg);
++}
++
++static int hclge_mbx_get_link_mode_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_get_link_mode(param->vport, param->req);
++	return 0;
++}
++
++static int
++hclge_mbx_get_vf_flr_status_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_rm_vport_all_mac_table(param->vport, false,
++				     HCLGE_MAC_ADDR_UC);
++	hclge_rm_vport_all_mac_table(param->vport, false,
++				     HCLGE_MAC_ADDR_MC);
++	hclge_rm_vport_all_vlan_table(param->vport, false);
++	return 0;
++}
++
++static int hclge_mbx_vf_uninit_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_rm_vport_all_mac_table(param->vport, true,
++				     HCLGE_MAC_ADDR_UC);
++	hclge_rm_vport_all_mac_table(param->vport, true,
++				     HCLGE_MAC_ADDR_MC);
++	hclge_rm_vport_all_vlan_table(param->vport, true);
++	param->vport->mps = 0;
++	return 0;
++}
++
++static int hclge_mbx_get_media_type_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_get_vf_media_type(param->vport, param->resp_msg);
++	return 0;
++}
++
++static int hclge_mbx_push_link_status_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_handle_link_change_event(param->vport->back, param->req);
++	return 0;
++}
++
++static int hclge_mbx_get_mac_addr_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_get_vf_mac_addr(param->vport, param->resp_msg);
++	return 0;
++}
++
++static int hclge_mbx_ncsi_error_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_handle_ncsi_error(param->vport->back);
++	return 0;
++}
++
++static int hclge_mbx_handle_vf_tbl_handler(struct hclge_mbx_ops_param *param)
++{
++	hclge_handle_vf_tbl(param->vport, param->req);
++	return 0;
++}
++
++static const hclge_mbx_ops_fn hclge_mbx_ops_list[HCLGE_MBX_OPCODE_MAX] = {
++	[HCLGE_MBX_RESET]   = hclge_mbx_reset_handler,
++	[HCLGE_MBX_SET_UNICAST] = hclge_mbx_set_unicast_handler,
++	[HCLGE_MBX_SET_MULTICAST] = hclge_mbx_set_multicast_handler,
++	[HCLGE_MBX_SET_VLAN] = hclge_mbx_set_vlan_handler,
++	[HCLGE_MBX_MAP_RING_TO_VECTOR] = hclge_mbx_map_ring_to_vector_handler,
++	[HCLGE_MBX_UNMAP_RING_TO_VECTOR] = hclge_mbx_unmap_ring_to_vector_handler,
++	[HCLGE_MBX_SET_PROMISC_MODE] = hclge_mbx_set_promisc_mode_handler,
++	[HCLGE_MBX_GET_QINFO] = hclge_mbx_get_qinfo_handler,
++	[HCLGE_MBX_GET_QDEPTH] = hclge_mbx_get_qdepth_handler,
++	[HCLGE_MBX_GET_BASIC_INFO] = hclge_mbx_get_basic_info_handler,
++	[HCLGE_MBX_GET_RSS_KEY] = hclge_mbx_get_rss_key_handler,
++	[HCLGE_MBX_GET_MAC_ADDR] = hclge_mbx_get_mac_addr_handler,
++	[HCLGE_MBX_GET_LINK_STATUS] = hclge_mbx_get_link_status_handler,
++	[HCLGE_MBX_QUEUE_RESET] = hclge_mbx_queue_reset_handler,
++	[HCLGE_MBX_KEEP_ALIVE] = hclge_mbx_keep_alive_handler,
++	[HCLGE_MBX_SET_ALIVE] = hclge_mbx_set_alive_handler,
++	[HCLGE_MBX_SET_MTU] = hclge_mbx_set_mtu_handler,
++	[HCLGE_MBX_GET_QID_IN_PF] = hclge_mbx_get_qid_in_pf_handler,
++	[HCLGE_MBX_GET_LINK_MODE] = hclge_mbx_get_link_mode_handler,
++	[HCLGE_MBX_GET_MEDIA_TYPE] = hclge_mbx_get_media_type_handler,
++	[HCLGE_MBX_VF_UNINIT] = hclge_mbx_vf_uninit_handler,
++	[HCLGE_MBX_HANDLE_VF_TBL] = hclge_mbx_handle_vf_tbl_handler,
++	[HCLGE_MBX_GET_RING_VECTOR_MAP] = hclge_mbx_get_ring_vector_map_handler,
++	[HCLGE_MBX_GET_VF_FLR_STATUS] = hclge_mbx_get_vf_flr_status_handler,
++	[HCLGE_MBX_PUSH_LINK_STATUS] = hclge_mbx_push_link_status_handler,
++	[HCLGE_MBX_NCSI_ERROR] = hclge_mbx_ncsi_error_handler,
++};
++
++static void hclge_mbx_request_handling(struct hclge_mbx_ops_param *param)
++{
++	hclge_mbx_ops_fn cmd_func = NULL;
++	struct hclge_dev *hdev;
++	int ret = 0;
++
++	hdev = param->vport->back;
++	cmd_func = hclge_mbx_ops_list[param->req->msg.code];
++	if (cmd_func)
++		ret = cmd_func(param);
++	else
++		dev_err(&hdev->pdev->dev,
++			"un-supported mailbox message, code = %u\n",
++			param->req->msg.code);
++
++	/* PF driver should not reply IMP */
++	if (hnae3_get_bit(param->req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B) &&
++	    param->req->msg.code < HCLGE_MBX_GET_VF_FLR_STATUS) {
++		param->resp_msg->status = ret;
++		if (time_is_before_jiffies(hdev->last_mbx_scheduled +
++					   HCLGE_MBX_SCHED_TIMEOUT))
++			dev_warn(&hdev->pdev->dev,
++				 "resp vport%u mbx(%u,%u) late\n",
++				 param->req->mbx_src_vfid,
++				 param->req->msg.code,
++				 param->req->msg.subcode);
++
++		hclge_gen_resp_to_vf(param->vport, param->req, param->resp_msg);
++	}
++}
++
+ void hclge_mbx_handler(struct hclge_dev *hdev)
+ {
+ 	struct hclge_comm_cmq_ring *crq = &hdev->hw.hw.cmq.crq;
+ 	struct hclge_respond_to_vf_msg resp_msg;
+ 	struct hclge_mbx_vf_to_pf_cmd *req;
+-	struct hclge_vport *vport;
++	struct hclge_mbx_ops_param param;
+ 	struct hclge_desc *desc;
+-	bool is_del = false;
+ 	unsigned int flag;
+-	int ret = 0;
+ 
++	param.resp_msg = &resp_msg;
+ 	/* handle all the mailbox requests in the queue */
+ 	while (!hclge_cmd_crq_empty(&hdev->hw)) {
+ 		if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE,
+@@ -814,152 +1134,16 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
+ 			continue;
+ 		}
+ 
+-		vport = &hdev->vport[req->mbx_src_vfid];
+-
+ 		trace_hclge_pf_mbx_get(hdev, req);
+ 
+ 		/* clear the resp_msg before processing every mailbox message */
+ 		memset(&resp_msg, 0, sizeof(resp_msg));
+-
+-		switch (req->msg.code) {
+-		case HCLGE_MBX_MAP_RING_TO_VECTOR:
+-			ret = hclge_map_unmap_ring_to_vf_vector(vport, true,
+-								req);
+-			break;
+-		case HCLGE_MBX_UNMAP_RING_TO_VECTOR:
+-			ret = hclge_map_unmap_ring_to_vf_vector(vport, false,
+-								req);
+-			break;
+-		case HCLGE_MBX_GET_RING_VECTOR_MAP:
+-			ret = hclge_get_vf_ring_vector_map(vport, req,
+-							   &resp_msg);
+-			if (ret)
+-				dev_err(&hdev->pdev->dev,
+-					"PF fail(%d) to get VF ring vector map\n",
+-					ret);
+-			break;
+-		case HCLGE_MBX_SET_PROMISC_MODE:
+-			hclge_set_vf_promisc_mode(vport, req);
+-			break;
+-		case HCLGE_MBX_SET_UNICAST:
+-			ret = hclge_set_vf_uc_mac_addr(vport, req);
+-			if (ret)
+-				dev_err(&hdev->pdev->dev,
+-					"PF fail(%d) to set VF UC MAC Addr\n",
+-					ret);
+-			break;
+-		case HCLGE_MBX_SET_MULTICAST:
+-			ret = hclge_set_vf_mc_mac_addr(vport, req);
+-			if (ret)
+-				dev_err(&hdev->pdev->dev,
+-					"PF fail(%d) to set VF MC MAC Addr\n",
+-					ret);
+-			break;
+-		case HCLGE_MBX_SET_VLAN:
+-			ret = hclge_set_vf_vlan_cfg(vport, req, &resp_msg);
+-			if (ret)
+-				dev_err(&hdev->pdev->dev,
+-					"PF failed(%d) to config VF's VLAN\n",
+-					ret);
+-			break;
+-		case HCLGE_MBX_SET_ALIVE:
+-			ret = hclge_set_vf_alive(vport, req);
+-			if (ret)
+-				dev_err(&hdev->pdev->dev,
+-					"PF failed(%d) to set VF's ALIVE\n",
+-					ret);
+-			break;
+-		case HCLGE_MBX_GET_QINFO:
+-			hclge_get_vf_queue_info(vport, &resp_msg);
+-			break;
+-		case HCLGE_MBX_GET_QDEPTH:
+-			hclge_get_vf_queue_depth(vport, &resp_msg);
+-			break;
+-		case HCLGE_MBX_GET_BASIC_INFO:
+-			hclge_get_basic_info(vport, &resp_msg);
+-			break;
+-		case HCLGE_MBX_GET_LINK_STATUS:
+-			ret = hclge_push_vf_link_status(vport);
+-			if (ret)
+-				dev_err(&hdev->pdev->dev,
+-					"failed to inform link stat to VF, ret = %d\n",
+-					ret);
+-			break;
+-		case HCLGE_MBX_QUEUE_RESET:
+-			ret = hclge_mbx_reset_vf_queue(vport, req, &resp_msg);
+-			break;
+-		case HCLGE_MBX_RESET:
+-			ret = hclge_reset_vf(vport);
+-			break;
+-		case HCLGE_MBX_KEEP_ALIVE:
+-			hclge_vf_keep_alive(vport);
+-			break;
+-		case HCLGE_MBX_SET_MTU:
+-			ret = hclge_set_vf_mtu(vport, req);
+-			if (ret)
+-				dev_err(&hdev->pdev->dev,
+-					"VF fail(%d) to set mtu\n", ret);
+-			break;
+-		case HCLGE_MBX_GET_QID_IN_PF:
+-			ret = hclge_get_queue_id_in_pf(vport, req, &resp_msg);
+-			break;
+-		case HCLGE_MBX_GET_RSS_KEY:
+-			ret = hclge_get_rss_key(vport, req, &resp_msg);
+-			break;
+-		case HCLGE_MBX_GET_LINK_MODE:
+-			hclge_get_link_mode(vport, req);
+-			break;
+-		case HCLGE_MBX_GET_VF_FLR_STATUS:
+-		case HCLGE_MBX_VF_UNINIT:
+-			is_del = req->msg.code == HCLGE_MBX_VF_UNINIT;
+-			hclge_rm_vport_all_mac_table(vport, is_del,
+-						     HCLGE_MAC_ADDR_UC);
+-			hclge_rm_vport_all_mac_table(vport, is_del,
+-						     HCLGE_MAC_ADDR_MC);
+-			hclge_rm_vport_all_vlan_table(vport, is_del);
+-			break;
+-		case HCLGE_MBX_GET_MEDIA_TYPE:
+-			hclge_get_vf_media_type(vport, &resp_msg);
+-			break;
+-		case HCLGE_MBX_PUSH_LINK_STATUS:
+-			hclge_handle_link_change_event(hdev, req);
+-			break;
+-		case HCLGE_MBX_GET_MAC_ADDR:
+-			hclge_get_vf_mac_addr(vport, &resp_msg);
+-			break;
+-		case HCLGE_MBX_NCSI_ERROR:
+-			hclge_handle_ncsi_error(hdev);
+-			break;
+-		case HCLGE_MBX_HANDLE_VF_TBL:
+-			hclge_handle_vf_tbl(vport, req);
+-			break;
+-		default:
+-			dev_err(&hdev->pdev->dev,
+-				"un-supported mailbox message, code = %u\n",
+-				req->msg.code);
+-			break;
+-		}
+-
+-		/* PF driver should not reply IMP */
+-		if (hnae3_get_bit(req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B) &&
+-		    req->msg.code < HCLGE_MBX_GET_VF_FLR_STATUS) {
+-			resp_msg.status = ret;
+-			if (time_is_before_jiffies(hdev->last_mbx_scheduled +
+-						   HCLGE_MBX_SCHED_TIMEOUT))
+-				dev_warn(&hdev->pdev->dev,
+-					 "resp vport%u mbx(%u,%u) late\n",
+-					 req->mbx_src_vfid,
+-					 req->msg.code,
+-					 req->msg.subcode);
+-
+-			hclge_gen_resp_to_vf(vport, req, &resp_msg);
+-		}
++		param.vport = &hdev->vport[req->mbx_src_vfid];
++		param.req = req;
++		hclge_mbx_request_handling(&param);
+ 
+ 		crq->desc[crq->next_to_use].flag = 0;
+ 		hclge_mbx_ring_ptr_move_crq(crq);
+-
+-		/* reinitialize ret after complete the mbx message processing */
+-		ret = 0;
+ 	}
+ 
+ 	/* Write back CMDQ_RQ header pointer, M7 need this pointer */
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+index 26f87330173eb..c551508e69325 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -2767,7 +2767,8 @@ static int hclgevf_pci_reset(struct hclgevf_dev *hdev)
+ 	struct pci_dev *pdev = hdev->pdev;
+ 	int ret = 0;
+ 
+-	if (hdev->reset_type == HNAE3_VF_FULL_RESET &&
++	if ((hdev->reset_type == HNAE3_VF_FULL_RESET ||
++	     hdev->reset_type == HNAE3_FLR_RESET) &&
+ 	    test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) {
+ 		hclgevf_misc_irq_uninit(hdev);
+ 		hclgevf_uninit_msi(hdev);
+diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c
+index 056c904b83ccb..79fa65d1cf201 100644
+--- a/drivers/net/ethernet/intel/ice/ice_xsk.c
++++ b/drivers/net/ethernet/intel/ice/ice_xsk.c
+@@ -772,7 +772,7 @@ construct_skb:
+ static void
+ ice_clean_xdp_tx_buf(struct ice_tx_ring *xdp_ring, struct ice_tx_buf *tx_buf)
+ {
+-	xdp_return_frame((struct xdp_frame *)tx_buf->raw_buf);
++	page_frag_free(tx_buf->raw_buf);
+ 	xdp_ring->xdp_tx_active--;
+ 	dma_unmap_single(xdp_ring->dev, dma_unmap_addr(tx_buf, dma),
+ 			 dma_unmap_len(tx_buf, len), DMA_TO_DEVICE);
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index 9c2baa437c231..2926d754ade8e 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -977,6 +977,7 @@ static void otx2_pool_refill_task(struct work_struct *work)
+ 	rbpool = cq->rbpool;
+ 	free_ptrs = cq->pool_ptrs;
+ 
++	get_cpu();
+ 	while (cq->pool_ptrs) {
+ 		if (otx2_alloc_rbuf(pfvf, rbpool, &bufptr)) {
+ 			/* Schedule a WQ if we fails to free atleast half of the
+@@ -996,6 +997,7 @@ static void otx2_pool_refill_task(struct work_struct *work)
+ 		pfvf->hw_ops->aura_freeptr(pfvf, qidx, bufptr + OTX2_HEAD_ROOM);
+ 		cq->pool_ptrs--;
+ 	}
++	put_cpu();
+ 	cq->refill_task_sched = false;
+ }
+ 
+@@ -1333,6 +1335,7 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf)
+ 	if (err)
+ 		goto fail;
+ 
++	get_cpu();
+ 	/* Allocate pointers and free them to aura/pool */
+ 	for (qidx = 0; qidx < hw->tot_tx_queues; qidx++) {
+ 		pool_id = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, qidx);
+@@ -1341,18 +1344,24 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf)
+ 		sq = &qset->sq[qidx];
+ 		sq->sqb_count = 0;
+ 		sq->sqb_ptrs = kcalloc(num_sqbs, sizeof(*sq->sqb_ptrs), GFP_KERNEL);
+-		if (!sq->sqb_ptrs)
+-			return -ENOMEM;
++		if (!sq->sqb_ptrs) {
++			err = -ENOMEM;
++			goto err_mem;
++		}
+ 
+ 		for (ptr = 0; ptr < num_sqbs; ptr++) {
+-			if (otx2_alloc_rbuf(pfvf, pool, &bufptr))
+-				return -ENOMEM;
++			err = otx2_alloc_rbuf(pfvf, pool, &bufptr);
++			if (err)
++				goto err_mem;
+ 			pfvf->hw_ops->aura_freeptr(pfvf, pool_id, bufptr);
+ 			sq->sqb_ptrs[sq->sqb_count++] = (u64)bufptr;
+ 		}
+ 	}
+ 
+-	return 0;
++err_mem:
++	put_cpu();
++	return err ? -ENOMEM : 0;
++
+ fail:
+ 	otx2_mbox_reset(&pfvf->mbox.mbox, 0);
+ 	otx2_aura_pool_free(pfvf);
+@@ -1391,18 +1400,21 @@ int otx2_rq_aura_pool_init(struct otx2_nic *pfvf)
+ 	if (err)
+ 		goto fail;
+ 
++	get_cpu();
+ 	/* Allocate pointers and free them to aura/pool */
+ 	for (pool_id = 0; pool_id < hw->rqpool_cnt; pool_id++) {
+ 		pool = &pfvf->qset.pool[pool_id];
+ 		for (ptr = 0; ptr < num_ptrs; ptr++) {
+-			if (otx2_alloc_rbuf(pfvf, pool, &bufptr))
+-				return -ENOMEM;
++			err = otx2_alloc_rbuf(pfvf, pool, &bufptr);
++			if (err)
++				goto err_mem;
+ 			pfvf->hw_ops->aura_freeptr(pfvf, pool_id,
+ 						   bufptr + OTX2_HEAD_ROOM);
+ 		}
+ 	}
+-
+-	return 0;
++err_mem:
++	put_cpu();
++	return err ? -ENOMEM : 0;
+ fail:
+ 	otx2_mbox_reset(&pfvf->mbox.mbox, 0);
+ 	otx2_aura_pool_free(pfvf);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+index 66c6a7017695d..97e9ec44a759b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+@@ -468,7 +468,7 @@ static int mlx5_devlink_enable_roce_validate(struct devlink *devlink, u32 id,
+ 	bool new_state = val.vbool;
+ 
+ 	if (new_state && !MLX5_CAP_GEN(dev, roce) &&
+-	    !MLX5_CAP_GEN(dev, roce_rw_supported)) {
++	    !(MLX5_CAP_GEN(dev, roce_rw_supported) && MLX5_CAP_GEN_MAX(dev, roce))) {
+ 		NL_SET_ERR_MSG_MOD(extack, "Device doesn't support RoCE");
+ 		return -EOPNOTSUPP;
+ 	}
+@@ -563,7 +563,7 @@ static int mlx5_devlink_eq_depth_validate(struct devlink *devlink, u32 id,
+ 					  union devlink_param_value val,
+ 					  struct netlink_ext_ack *extack)
+ {
+-	return (val.vu16 >= 64 && val.vu16 <= 4096) ? 0 : -EINVAL;
++	return (val.vu32 >= 64 && val.vu32 <= 4096) ? 0 : -EINVAL;
+ }
+ 
+ static const struct devlink_param mlx5_devlink_params[] = {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
+index 864ce0c393e61..f01f7dfdbcf88 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
+@@ -2080,14 +2080,9 @@ out_err:
+ static void
+ mlx5_ct_tc_create_dbgfs(struct mlx5_tc_ct_priv *ct_priv)
+ {
+-	bool is_fdb = ct_priv->ns_type == MLX5_FLOW_NAMESPACE_FDB;
+ 	struct mlx5_tc_ct_debugfs *ct_dbgfs = &ct_priv->debugfs;
+-	char dirname[16] = {};
+ 
+-	if (sscanf(dirname, "ct_%s", is_fdb ? "fdb" : "nic") < 0)
+-		return;
+-
+-	ct_dbgfs->root = debugfs_create_dir(dirname, mlx5_debugfs_get_dev_root(ct_priv->dev));
++	ct_dbgfs->root = debugfs_create_dir("ct", mlx5_debugfs_get_dev_root(ct_priv->dev));
+ 	debugfs_create_atomic_t("offloaded", 0400, ct_dbgfs->root,
+ 				&ct_dbgfs->stats.offloaded);
+ 	debugfs_create_atomic_t("rx_dropped", 0400, ct_dbgfs->root,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+index ff73d25bc6eb8..2aaf8ab857b8f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+@@ -222,7 +222,7 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
+ 	int err;
+ 
+ 	list_for_each_entry(flow, flow_list, tmp_list) {
+-		if (!mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, SLOW))
++		if (!mlx5e_is_offloaded_flow(flow))
+ 			continue;
+ 
+ 		attr = mlx5e_tc_get_encap_attr(flow);
+@@ -231,6 +231,13 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
+ 		esw_attr->dests[flow->tmp_entry_index].flags &= ~MLX5_ESW_DEST_ENCAP_VALID;
+ 		esw_attr->dests[flow->tmp_entry_index].pkt_reformat = NULL;
+ 
++		/* Clear pkt_reformat before checking slow path flag. Because
++		 * in next iteration, the same flow is already set slow path
++		 * flag, but still need to clear the pkt_reformat.
++		 */
++		if (flow_flag_test(flow, SLOW))
++			continue;
++
+ 		/* update from encap rule to slow path rule */
+ 		spec = &flow->attr->parse_attr->spec;
+ 		rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c
+index f5b26f5a7de46..054d80c4e65cf 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c
+@@ -273,6 +273,11 @@ static int mlx5e_tc_tun_parse_geneve_options(struct mlx5e_priv *priv,
+ 		 geneve_tlv_option_0_data, be32_to_cpu(opt_data_key));
+ 	MLX5_SET(fte_match_set_misc3, misc_3_c,
+ 		 geneve_tlv_option_0_data, be32_to_cpu(opt_data_mask));
++	if (MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev,
++				       ft_field_support.geneve_tlv_option_0_exist)) {
++		MLX5_SET_TO_ONES(fte_match_set_misc, misc_c, geneve_tlv_option_0_exist);
++		MLX5_SET_TO_ONES(fte_match_set_misc, misc_v, geneve_tlv_option_0_exist);
++	}
+ 
+ 	spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_3;
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 6cf6a81775a85..5c16efb8be81d 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -1146,7 +1146,7 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c,
+ 	sq->channel   = c;
+ 	sq->uar_map   = mdev->mlx5e_res.hw_objs.bfreg.map;
+ 	sq->min_inline_mode = params->tx_min_inline_mode;
+-	sq->hw_mtu    = MLX5E_SW2HW_MTU(params, params->sw_mtu);
++	sq->hw_mtu    = MLX5E_SW2HW_MTU(params, params->sw_mtu) - ETH_FCS_LEN;
+ 	sq->xsk_pool  = xsk_pool;
+ 
+ 	sq->stats = sq->xsk_pool ?
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
+index 60a73990017c2..6b4c9ffad95b2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
+@@ -67,6 +67,7 @@ static void esw_acl_egress_lgcy_groups_destroy(struct mlx5_vport *vport)
+ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
+ 			      struct mlx5_vport *vport)
+ {
++	bool vst_mode_steering = esw_vst_mode_is_steering(esw);
+ 	struct mlx5_flow_destination drop_ctr_dst = {};
+ 	struct mlx5_flow_destination *dst = NULL;
+ 	struct mlx5_fc *drop_counter = NULL;
+@@ -77,6 +78,7 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
+ 	 */
+ 	int table_size = 2;
+ 	int dest_num = 0;
++	int actions_flag;
+ 	int err = 0;
+ 
+ 	if (vport->egress.legacy.drop_counter) {
+@@ -119,8 +121,11 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw,
+ 		  vport->vport, vport->info.vlan, vport->info.qos);
+ 
+ 	/* Allowed vlan rule */
++	actions_flag = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
++	if (vst_mode_steering)
++		actions_flag |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
+ 	err = esw_egress_acl_vlan_create(esw, vport, NULL, vport->info.vlan,
+-					 MLX5_FLOW_CONTEXT_ACTION_ALLOW);
++					 actions_flag);
+ 	if (err)
+ 		goto out;
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
+index b1a5199260f69..093ed86a0acd8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c
+@@ -139,11 +139,14 @@ static void esw_acl_ingress_lgcy_groups_destroy(struct mlx5_vport *vport)
+ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ 			       struct mlx5_vport *vport)
+ {
++	bool vst_mode_steering = esw_vst_mode_is_steering(esw);
+ 	struct mlx5_flow_destination drop_ctr_dst = {};
+ 	struct mlx5_flow_destination *dst = NULL;
+ 	struct mlx5_flow_act flow_act = {};
+ 	struct mlx5_flow_spec *spec = NULL;
+ 	struct mlx5_fc *counter = NULL;
++	bool vst_check_cvlan = false;
++	bool vst_push_cvlan = false;
+ 	/* The ingress acl table contains 4 groups
+ 	 * (2 active rules at the same time -
+ 	 *      1 allow rule from one of the first 3 groups.
+@@ -203,7 +206,26 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ 		goto out;
+ 	}
+ 
+-	if (vport->info.vlan || vport->info.qos)
++	if ((vport->info.vlan || vport->info.qos)) {
++		if (vst_mode_steering)
++			vst_push_cvlan = true;
++		else if (!MLX5_CAP_ESW(esw->dev, vport_cvlan_insert_always))
++			vst_check_cvlan = true;
++	}
++
++	if (vst_check_cvlan || vport->info.spoofchk)
++		spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
++
++	/* Create ingress allow rule */
++	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
++	if (vst_push_cvlan) {
++		flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
++		flow_act.vlan[0].prio = vport->info.qos;
++		flow_act.vlan[0].vid = vport->info.vlan;
++		flow_act.vlan[0].ethtype = ETH_P_8021Q;
++	}
++
++	if (vst_check_cvlan)
+ 		MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
+ 				 outer_headers.cvlan_tag);
+ 
+@@ -218,9 +240,6 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ 		ether_addr_copy(smac_v, vport->info.mac);
+ 	}
+ 
+-	/* Create ingress allow rule */
+-	spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
+-	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
+ 	vport->ingress.allow_rule = mlx5_add_flow_rules(vport->ingress.acl, spec,
+ 							&flow_act, NULL, 0);
+ 	if (IS_ERR(vport->ingress.allow_rule)) {
+@@ -232,6 +251,9 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ 		goto out;
+ 	}
+ 
++	if (!vst_check_cvlan && !vport->info.spoofchk)
++		goto out;
++
+ 	memset(&flow_act, 0, sizeof(flow_act));
+ 	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
+ 	/* Attach drop flow counter */
+@@ -257,7 +279,8 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw,
+ 	return 0;
+ 
+ out:
+-	esw_acl_ingress_lgcy_cleanup(esw, vport);
++	if (err)
++		esw_acl_ingress_lgcy_cleanup(esw, vport);
+ 	kvfree(spec);
+ 	return err;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+index 59cffa49e4b58..940e893f3f097 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+@@ -161,10 +161,17 @@ static int modify_esw_vport_cvlan(struct mlx5_core_dev *dev, u16 vport,
+ 			 esw_vport_context.vport_cvlan_strip, 1);
+ 
+ 	if (set_flags & SET_VLAN_INSERT) {
+-		/* insert only if no vlan in packet */
+-		MLX5_SET(modify_esw_vport_context_in, in,
+-			 esw_vport_context.vport_cvlan_insert, 1);
+-
++		if (MLX5_CAP_ESW(dev, vport_cvlan_insert_always)) {
++			/* insert either if vlan exist in packet or not */
++			MLX5_SET(modify_esw_vport_context_in, in,
++				 esw_vport_context.vport_cvlan_insert,
++				 MLX5_VPORT_CVLAN_INSERT_ALWAYS);
++		} else {
++			/* insert only if no vlan in packet */
++			MLX5_SET(modify_esw_vport_context_in, in,
++				 esw_vport_context.vport_cvlan_insert,
++				 MLX5_VPORT_CVLAN_INSERT_WHEN_NO_CVLAN);
++		}
+ 		MLX5_SET(modify_esw_vport_context_in, in,
+ 			 esw_vport_context.cvlan_pcp, qos);
+ 		MLX5_SET(modify_esw_vport_context_in, in,
+@@ -774,6 +781,7 @@ static void esw_vport_cleanup_acl(struct mlx5_eswitch *esw,
+ 
+ static int esw_vport_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
+ {
++	bool vst_mode_steering = esw_vst_mode_is_steering(esw);
+ 	u16 vport_num = vport->vport;
+ 	int flags;
+ 	int err;
+@@ -800,8 +808,9 @@ static int esw_vport_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
+ 
+ 	flags = (vport->info.vlan || vport->info.qos) ?
+ 		SET_VLAN_STRIP | SET_VLAN_INSERT : 0;
+-	modify_esw_vport_cvlan(esw->dev, vport_num, vport->info.vlan,
+-			       vport->info.qos, flags);
++	if (esw->mode == MLX5_ESWITCH_OFFLOADS || !vst_mode_steering)
++		modify_esw_vport_cvlan(esw->dev, vport_num, vport->info.vlan,
++				       vport->info.qos, flags);
+ 
+ 	return 0;
+ }
+@@ -1806,6 +1815,7 @@ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
+ 				  u16 vport, u16 vlan, u8 qos, u8 set_flags)
+ {
+ 	struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport);
++	bool vst_mode_steering = esw_vst_mode_is_steering(esw);
+ 	int err = 0;
+ 
+ 	if (IS_ERR(evport))
+@@ -1813,9 +1823,11 @@ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
+ 	if (vlan > 4095 || qos > 7)
+ 		return -EINVAL;
+ 
+-	err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set_flags);
+-	if (err)
+-		return err;
++	if (esw->mode == MLX5_ESWITCH_OFFLOADS || !vst_mode_steering) {
++		err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set_flags);
++		if (err)
++			return err;
++	}
+ 
+ 	evport->info.vlan = vlan;
+ 	evport->info.qos = qos;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+index 5ceed4e6c6581..03080e8161cba 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+@@ -513,6 +513,12 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
+ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
+ 				  u16 vport, u16 vlan, u8 qos, u8 set_flags);
+ 
++static inline bool esw_vst_mode_is_steering(struct mlx5_eswitch *esw)
++{
++	return (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, pop_vlan) &&
++		MLX5_CAP_ESW_INGRESS_ACL(esw->dev, push_vlan));
++}
++
+ static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev *dev,
+ 						       u8 vlan_depth)
+ {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c
+index 2cf2c99484467..0ed239eadf394 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/health.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c
+@@ -674,6 +674,12 @@ static void mlx5_fw_fatal_reporter_err_work(struct work_struct *work)
+ 	dev = container_of(priv, struct mlx5_core_dev, priv);
+ 	devlink = priv_to_devlink(dev);
+ 
++	mutex_lock(&dev->intf_state_mutex);
++	if (test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags)) {
++		mlx5_core_err(dev, "health works are not permitted at this stage\n");
++		return;
++	}
++	mutex_unlock(&dev->intf_state_mutex);
+ 	enter_error_state(dev, false);
+ 	if (IS_ERR_OR_NULL(health->fw_fatal_reporter)) {
+ 		devl_lock(devlink);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+index c02b7b08fb4c1..2032d5c0ad86a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+@@ -70,6 +70,10 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
+ 	params->packet_merge.type = MLX5E_PACKET_MERGE_NONE;
+ 	params->hard_mtu = MLX5_IB_GRH_BYTES + MLX5_IPOIB_HARD_LEN;
+ 	params->tunneled_offload_en = false;
++
++	/* CQE compression is not supported for IPoIB */
++	params->rx_cqe_compress_def = false;
++	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS, params->rx_cqe_compress_def);
+ }
+ 
+ /* Called directly after IPoIB netdevice was created to initialize SW structs */
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+index bbe810f3b373a..c142011d20977 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+@@ -201,6 +201,7 @@ static void mlx5_ldev_free(struct kref *ref)
+ 	if (ldev->nb.notifier_call)
+ 		unregister_netdevice_notifier_net(&init_net, &ldev->nb);
+ 	mlx5_lag_mp_cleanup(ldev);
++	cancel_delayed_work_sync(&ldev->bond_work);
+ 	destroy_workqueue(ldev->wq);
+ 	mlx5_lag_mpesw_cleanup(ldev);
+ 	mutex_destroy(&ldev->lock);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index ac178796e484f..0a2f23a7082a8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -614,7 +614,7 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
+ 		MLX5_SET(cmd_hca_cap, set_hca_cap, num_total_dynamic_vf_msix,
+ 			 MLX5_CAP_GEN_MAX(dev, num_total_dynamic_vf_msix));
+ 
+-	if (MLX5_CAP_GEN(dev, roce_rw_supported))
++	if (MLX5_CAP_GEN(dev, roce_rw_supported) && MLX5_CAP_GEN_MAX(dev, roce))
+ 		MLX5_SET(cmd_hca_cap, set_hca_cap, roce,
+ 			 mlx5_is_roce_on(dev));
+ 
+@@ -1017,6 +1017,8 @@ err_rl_cleanup:
+ err_tables_cleanup:
+ 	mlx5_geneve_destroy(dev->geneve);
+ 	mlx5_vxlan_destroy(dev->vxlan);
++	mlx5_cleanup_clock(dev);
++	mlx5_cleanup_reserved_gids(dev);
+ 	mlx5_cq_debugfs_cleanup(dev);
+ 	mlx5_fw_reset_cleanup(dev);
+ err_events_cleanup:
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_port.c b/drivers/net/ethernet/microchip/lan966x/lan966x_port.c
+index f141644e4372f..26c5cdf373c4d 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_port.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_port.c
+@@ -369,7 +369,7 @@ int lan966x_port_pcs_set(struct lan966x_port *port,
+ 	}
+ 
+ 	/* Take PCS out of reset */
+-	lan_rmw(DEV_CLOCK_CFG_LINK_SPEED_SET(2) |
++	lan_rmw(DEV_CLOCK_CFG_LINK_SPEED_SET(LAN966X_SPEED_1000) |
+ 		DEV_CLOCK_CFG_PCS_RX_RST_SET(0) |
+ 		DEV_CLOCK_CFG_PCS_TX_RST_SET(0),
+ 		DEV_CLOCK_CFG_LINK_SPEED |
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+index e58de119186a6..a2d0631f7ac71 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+@@ -819,7 +819,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
+ 	if (err)
+ 		goto cleanup_config;
+ 
+-	if (!of_get_mac_address(np, sparx5->base_mac)) {
++	if (of_get_mac_address(np, sparx5->base_mac)) {
+ 		dev_info(sparx5->dev, "MAC addr was not set, use random MAC\n");
+ 		eth_random_addr(sparx5->base_mac);
+ 		sparx5->base_mac[5] = 0;
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+index 86ecb080b1536..cdcead614e9fa 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+@@ -1832,7 +1832,8 @@ static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
+ 					    struct qed_ptt *p_ptt,
+ 					    u32 image_type,
+ 					    u32 *nvram_offset_bytes,
+-					    u32 *nvram_size_bytes)
++					    u32 *nvram_size_bytes,
++					    bool b_can_sleep)
+ {
+ 	u32 ret_mcp_resp, ret_mcp_param, ret_txn_size;
+ 	struct mcp_file_att file_att;
+@@ -1846,7 +1847,8 @@ static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
+ 					&ret_mcp_resp,
+ 					&ret_mcp_param,
+ 					&ret_txn_size,
+-					(u32 *)&file_att, false);
++					(u32 *)&file_att,
++					b_can_sleep);
+ 
+ 	/* Check response */
+ 	if (nvm_result || (ret_mcp_resp & FW_MSG_CODE_MASK) !=
+@@ -1873,7 +1875,9 @@ static enum dbg_status qed_find_nvram_image(struct qed_hwfn *p_hwfn,
+ static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
+ 				      struct qed_ptt *p_ptt,
+ 				      u32 nvram_offset_bytes,
+-				      u32 nvram_size_bytes, u32 *ret_buf)
++				      u32 nvram_size_bytes,
++				      u32 *ret_buf,
++				      bool b_can_sleep)
+ {
+ 	u32 ret_mcp_resp, ret_mcp_param, ret_read_size, bytes_to_copy;
+ 	s32 bytes_left = nvram_size_bytes;
+@@ -1899,7 +1903,7 @@ static enum dbg_status qed_nvram_read(struct qed_hwfn *p_hwfn,
+ 				       &ret_mcp_resp,
+ 				       &ret_mcp_param, &ret_read_size,
+ 				       (u32 *)((u8 *)ret_buf + read_offset),
+-				       false))
++				       b_can_sleep))
+ 			return DBG_STATUS_NVRAM_READ_FAILED;
+ 
+ 		/* Check response */
+@@ -3380,7 +3384,8 @@ static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn,
+ 				      p_ptt,
+ 				      NVM_TYPE_HW_DUMP_OUT,
+ 				      &hw_dump_offset_bytes,
+-				      &hw_dump_size_bytes);
++				      &hw_dump_size_bytes,
++				      false);
+ 	if (status != DBG_STATUS_OK)
+ 		return 0;
+ 
+@@ -3397,7 +3402,9 @@ static u32 qed_grc_dump_mcp_hw_dump(struct qed_hwfn *p_hwfn,
+ 		status = qed_nvram_read(p_hwfn,
+ 					p_ptt,
+ 					hw_dump_offset_bytes,
+-					hw_dump_size_bytes, dump_buf + offset);
++					hw_dump_size_bytes,
++					dump_buf + offset,
++					false);
+ 		if (status != DBG_STATUS_OK) {
+ 			DP_NOTICE(p_hwfn,
+ 				  "Failed to read MCP HW Dump image from NVRAM\n");
+@@ -4123,7 +4130,9 @@ static enum dbg_status qed_mcp_trace_get_meta_info(struct qed_hwfn *p_hwfn,
+ 	return qed_find_nvram_image(p_hwfn,
+ 				    p_ptt,
+ 				    nvram_image_type,
+-				    trace_meta_offset, trace_meta_size);
++				    trace_meta_offset,
++				    trace_meta_size,
++				    true);
+ }
+ 
+ /* Reads the MCP Trace meta data from NVRAM into the specified buffer */
+@@ -4139,7 +4148,10 @@ static enum dbg_status qed_mcp_trace_read_meta(struct qed_hwfn *p_hwfn,
+ 	/* Read meta data from NVRAM */
+ 	status = qed_nvram_read(p_hwfn,
+ 				p_ptt,
+-				nvram_offset_in_bytes, size_in_bytes, buf);
++				nvram_offset_in_bytes,
++				size_in_bytes,
++				buf,
++				true);
+ 	if (status != DBG_STATUS_OK)
+ 		return status;
+ 
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+index dbb800769cb63..c95d56e56c59a 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+@@ -2505,7 +2505,13 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter)
+ 		goto disable_mbx_intr;
+ 
+ 	qlcnic_83xx_clear_function_resources(adapter);
+-	qlcnic_dcb_enable(adapter->dcb);
++
++	err = qlcnic_dcb_enable(adapter->dcb);
++	if (err) {
++		qlcnic_dcb_free(adapter->dcb);
++		goto disable_mbx_intr;
++	}
++
+ 	qlcnic_83xx_initialize_nic(adapter, 1);
+ 	qlcnic_dcb_get_info(adapter->dcb);
+ 
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
+index 7519773eaca6e..22afa2be85fdb 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h
+@@ -41,11 +41,6 @@ struct qlcnic_dcb {
+ 	unsigned long			state;
+ };
+ 
+-static inline void qlcnic_clear_dcb_ops(struct qlcnic_dcb *dcb)
+-{
+-	kfree(dcb);
+-}
+-
+ static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_dcb *dcb)
+ {
+ 	if (dcb && dcb->ops->get_hw_capability)
+@@ -112,9 +107,8 @@ static inline void qlcnic_dcb_init_dcbnl_ops(struct qlcnic_dcb *dcb)
+ 		dcb->ops->init_dcbnl_ops(dcb);
+ }
+ 
+-static inline void qlcnic_dcb_enable(struct qlcnic_dcb *dcb)
++static inline int qlcnic_dcb_enable(struct qlcnic_dcb *dcb)
+ {
+-	if (dcb && qlcnic_dcb_attach(dcb))
+-		qlcnic_clear_dcb_ops(dcb);
++	return dcb ? qlcnic_dcb_attach(dcb) : 0;
+ }
+ #endif
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+index 28476b982bab6..44dac3c0908eb 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+@@ -2599,7 +2599,13 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 			 "Device does not support MSI interrupts\n");
+ 
+ 	if (qlcnic_82xx_check(adapter)) {
+-		qlcnic_dcb_enable(adapter->dcb);
++		err = qlcnic_dcb_enable(adapter->dcb);
++		if (err) {
++			qlcnic_dcb_free(adapter->dcb);
++			dev_err(&pdev->dev, "Failed to enable DCB\n");
++			goto err_out_free_hw;
++		}
++
+ 		qlcnic_dcb_get_info(adapter->dcb);
+ 		err = qlcnic_setup_intr(adapter);
+ 
+diff --git a/drivers/net/phy/xilinx_gmii2rgmii.c b/drivers/net/phy/xilinx_gmii2rgmii.c
+index 8dcb49ed1f3d9..7fd9fe6a602bc 100644
+--- a/drivers/net/phy/xilinx_gmii2rgmii.c
++++ b/drivers/net/phy/xilinx_gmii2rgmii.c
+@@ -105,6 +105,7 @@ static int xgmiitorgmii_probe(struct mdio_device *mdiodev)
+ 
+ 	if (!priv->phy_dev->drv) {
+ 		dev_info(dev, "Attached phy not ready\n");
++		put_device(&priv->phy_dev->mdio.dev);
+ 		return -EPROBE_DEFER;
+ 	}
+ 
+diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
+index f79333fe17836..7b3739b29c8f7 100644
+--- a/drivers/net/usb/rndis_host.c
++++ b/drivers/net/usb/rndis_host.c
+@@ -255,7 +255,8 @@ static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
+ 
+ 	off = le32_to_cpu(u.get_c->offset);
+ 	len = le32_to_cpu(u.get_c->len);
+-	if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE))
++	if (unlikely((off > CONTROL_BUFFER_SIZE - 8) ||
++		     (len > CONTROL_BUFFER_SIZE - 8 - off)))
+ 		goto response_error;
+ 
+ 	if (*reply_len != -1 && len != *reply_len)
+diff --git a/drivers/net/veth.c b/drivers/net/veth.c
+index 466da01ba2e3e..909427d99a594 100644
+--- a/drivers/net/veth.c
++++ b/drivers/net/veth.c
+@@ -974,6 +974,9 @@ static int veth_poll(struct napi_struct *napi, int budget)
+ 	xdp_set_return_frame_no_direct();
+ 	done = veth_xdp_rcv(rq, budget, &bq, &stats);
+ 
++	if (stats.xdp_redirect > 0)
++		xdp_do_flush();
++
+ 	if (done < budget && napi_complete_done(napi, done)) {
+ 		/* Write rx_notify_masked before reading ptr_ring */
+ 		smp_store_mb(rq->rx_notify_masked, false);
+@@ -987,8 +990,6 @@ static int veth_poll(struct napi_struct *napi, int budget)
+ 
+ 	if (stats.xdp_tx > 0)
+ 		veth_xdp_flush(rq, &bq);
+-	if (stats.xdp_redirect > 0)
+-		xdp_do_flush();
+ 	xdp_clear_return_frame_no_direct();
+ 
+ 	return done;
+diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
+index c28c4a654615c..c312d16f580c9 100644
+--- a/drivers/net/vmxnet3/vmxnet3_drv.c
++++ b/drivers/net/vmxnet3/vmxnet3_drv.c
+@@ -1288,6 +1288,10 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
+ 		    (le32_to_cpu(gdesc->dword[3]) &
+ 		     VMXNET3_RCD_CSUM_OK) == VMXNET3_RCD_CSUM_OK) {
+ 			skb->ip_summed = CHECKSUM_UNNECESSARY;
++			if ((le32_to_cpu(gdesc->dword[0]) &
++				     (1UL << VMXNET3_RCD_HDR_INNER_SHIFT))) {
++				skb->csum_level = 1;
++			}
+ 			WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
+ 				     !(le32_to_cpu(gdesc->dword[0]) &
+ 				     (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
+@@ -1297,6 +1301,10 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
+ 		} else if (gdesc->rcd.v6 && (le32_to_cpu(gdesc->dword[3]) &
+ 					     (1 << VMXNET3_RCD_TUC_SHIFT))) {
+ 			skb->ip_summed = CHECKSUM_UNNECESSARY;
++			if ((le32_to_cpu(gdesc->dword[0]) &
++				     (1UL << VMXNET3_RCD_HDR_INNER_SHIFT))) {
++				skb->csum_level = 1;
++			}
+ 			WARN_ON_ONCE(!(gdesc->rcd.tcp || gdesc->rcd.udp) &&
+ 				     !(le32_to_cpu(gdesc->dword[0]) &
+ 				     (1UL << VMXNET3_RCD_HDR_INNER_SHIFT)));
+diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
+index 5df7a0abc39d5..f7f40e3fe9cce 100644
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -1385,8 +1385,8 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
+ 
+ 	/* loopback, multicast & non-ND link-local traffic; do not push through
+ 	 * packet taps again. Reset pkt_type for upper layers to process skb.
+-	 * For strict packets with a source LLA, determine the dst using the
+-	 * original ifindex.
++	 * For non-loopback strict packets, determine the dst using the original
++	 * ifindex.
+ 	 */
+ 	if (skb->pkt_type == PACKET_LOOPBACK || (need_strict && !is_ndisc)) {
+ 		skb->dev = vrf_dev;
+@@ -1395,7 +1395,7 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
+ 
+ 		if (skb->pkt_type == PACKET_LOOPBACK)
+ 			skb->pkt_type = PACKET_HOST;
+-		else if (ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)
++		else
+ 			vrf_ip6_input_dst(skb, vrf_dev, orig_iif);
+ 
+ 		goto out;
+diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
+index c3285242f74fb..a03752ef544f4 100644
+--- a/drivers/net/vxlan/vxlan_core.c
++++ b/drivers/net/vxlan/vxlan_core.c
+@@ -2920,16 +2920,23 @@ static int vxlan_init(struct net_device *dev)
+ 		vxlan_vnigroup_init(vxlan);
+ 
+ 	dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
+-	if (!dev->tstats)
+-		return -ENOMEM;
++	if (!dev->tstats) {
++		err = -ENOMEM;
++		goto err_vnigroup_uninit;
++	}
+ 
+ 	err = gro_cells_init(&vxlan->gro_cells, dev);
+-	if (err) {
+-		free_percpu(dev->tstats);
+-		return err;
+-	}
++	if (err)
++		goto err_free_percpu;
+ 
+ 	return 0;
++
++err_free_percpu:
++	free_percpu(dev->tstats);
++err_vnigroup_uninit:
++	if (vxlan->cfg.flags & VXLAN_F_VNIFILTER)
++		vxlan_vnigroup_uninit(vxlan);
++	return err;
+ }
+ 
+ static void vxlan_fdb_delete_default(struct vxlan_dev *vxlan, __be32 vni)
+diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
+index 30f0765fb9fd8..237f4ec2cffd7 100644
+--- a/drivers/net/wireless/ath/ath9k/htc.h
++++ b/drivers/net/wireless/ath/ath9k/htc.h
+@@ -327,9 +327,9 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
+ }
+ 
+ #ifdef CONFIG_ATH9K_HTC_DEBUGFS
+-#define __STAT_SAFE(hif_dev, expr)	((hif_dev)->htc_handle->drv_priv ? (expr) : 0)
+-#define CAB_STAT_INC(priv)		((priv)->debug.tx_stats.cab_queued++)
+-#define TX_QSTAT_INC(priv, q)		((priv)->debug.tx_stats.queue_stats[q]++)
++#define __STAT_SAFE(hif_dev, expr)	do { ((hif_dev)->htc_handle->drv_priv ? (expr) : 0); } while (0)
++#define CAB_STAT_INC(priv)		do { ((priv)->debug.tx_stats.cab_queued++); } while (0)
++#define TX_QSTAT_INC(priv, q)		do { ((priv)->debug.tx_stats.queue_stats[q]++); } while (0)
+ 
+ #define TX_STAT_INC(hif_dev, c) \
+ 		__STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c++)
+@@ -378,10 +378,10 @@ void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
+ 			    struct ethtool_stats *stats, u64 *data);
+ #else
+ 
+-#define TX_STAT_INC(hif_dev, c)
+-#define TX_STAT_ADD(hif_dev, c, a)
+-#define RX_STAT_INC(hif_dev, c)
+-#define RX_STAT_ADD(hif_dev, c, a)
++#define TX_STAT_INC(hif_dev, c)		do { } while (0)
++#define TX_STAT_ADD(hif_dev, c, a)	do { } while (0)
++#define RX_STAT_INC(hif_dev, c)		do { } while (0)
++#define RX_STAT_ADD(hif_dev, c, a)	do { } while (0)
+ 
+ #define CAB_STAT_INC(priv)
+ #define TX_QSTAT_INC(priv, c)
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 3582a28a1dcec..f06bae83e8ee0 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1069,6 +1069,18 @@ static u32 nvme_known_admin_effects(u8 opcode)
+ 	return 0;
+ }
+ 
++static u32 nvme_known_nvm_effects(u8 opcode)
++{
++	switch (opcode) {
++	case nvme_cmd_write:
++	case nvme_cmd_write_zeroes:
++	case nvme_cmd_write_uncor:
++		 return NVME_CMD_EFFECTS_LBCC;
++	default:
++		return 0;
++	}
++}
++
+ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
+ {
+ 	u32 effects = 0;
+@@ -1076,16 +1088,24 @@ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
+ 	if (ns) {
+ 		if (ns->head->effects)
+ 			effects = le32_to_cpu(ns->head->effects->iocs[opcode]);
++		if (ns->head->ids.csi == NVME_CAP_CSS_NVM)
++			effects |= nvme_known_nvm_effects(opcode);
+ 		if (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC))
+ 			dev_warn_once(ctrl->device,
+-				"IO command:%02x has unhandled effects:%08x\n",
++				"IO command:%02x has unusual effects:%08x\n",
+ 				opcode, effects);
+-		return 0;
+-	}
+ 
+-	if (ctrl->effects)
+-		effects = le32_to_cpu(ctrl->effects->acs[opcode]);
+-	effects |= nvme_known_admin_effects(opcode);
++		/*
++		 * NVME_CMD_EFFECTS_CSE_MASK causes a freeze all I/O queues,
++		 * which would deadlock when done on an I/O command.  Note that
++		 * We already warn about an unusual effect above.
++		 */
++		effects &= ~NVME_CMD_EFFECTS_CSE_MASK;
++	} else {
++		if (ctrl->effects)
++			effects = le32_to_cpu(ctrl->effects->acs[opcode]);
++		effects |= nvme_known_admin_effects(opcode);
++	}
+ 
+ 	return effects;
+ }
+diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
+index 70555022cb445..35352206b5dee 100644
+--- a/drivers/nvme/host/nvme.h
++++ b/drivers/nvme/host/nvme.h
+@@ -872,7 +872,7 @@ static inline void nvme_trace_bio_complete(struct request *req)
+ {
+ 	struct nvme_ns *ns = req->q->queuedata;
+ 
+-	if (req->cmd_flags & REQ_NVME_MPATH)
++	if ((req->cmd_flags & REQ_NVME_MPATH) && req->bio)
+ 		trace_block_bio_complete(ns->head->disk->queue, req->bio);
+ }
+ 
+diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
+index fc8a957fad0ac..4aaa27cc8d2bd 100644
+--- a/drivers/nvme/target/admin-cmd.c
++++ b/drivers/nvme/target/admin-cmd.c
+@@ -164,26 +164,29 @@ out:
+ 
+ static void nvmet_get_cmd_effects_nvm(struct nvme_effects_log *log)
+ {
+-	log->acs[nvme_admin_get_log_page]	= cpu_to_le32(1 << 0);
+-	log->acs[nvme_admin_identify]		= cpu_to_le32(1 << 0);
+-	log->acs[nvme_admin_abort_cmd]		= cpu_to_le32(1 << 0);
+-	log->acs[nvme_admin_set_features]	= cpu_to_le32(1 << 0);
+-	log->acs[nvme_admin_get_features]	= cpu_to_le32(1 << 0);
+-	log->acs[nvme_admin_async_event]	= cpu_to_le32(1 << 0);
+-	log->acs[nvme_admin_keep_alive]		= cpu_to_le32(1 << 0);
+-
+-	log->iocs[nvme_cmd_read]		= cpu_to_le32(1 << 0);
+-	log->iocs[nvme_cmd_write]		= cpu_to_le32(1 << 0);
+-	log->iocs[nvme_cmd_flush]		= cpu_to_le32(1 << 0);
+-	log->iocs[nvme_cmd_dsm]			= cpu_to_le32(1 << 0);
+-	log->iocs[nvme_cmd_write_zeroes]	= cpu_to_le32(1 << 0);
++	log->acs[nvme_admin_get_log_page] =
++	log->acs[nvme_admin_identify] =
++	log->acs[nvme_admin_abort_cmd] =
++	log->acs[nvme_admin_set_features] =
++	log->acs[nvme_admin_get_features] =
++	log->acs[nvme_admin_async_event] =
++	log->acs[nvme_admin_keep_alive] =
++		cpu_to_le32(NVME_CMD_EFFECTS_CSUPP);
++
++	log->iocs[nvme_cmd_read] =
++	log->iocs[nvme_cmd_write] =
++	log->iocs[nvme_cmd_flush] =
++	log->iocs[nvme_cmd_dsm]	=
++	log->iocs[nvme_cmd_write_zeroes] =
++		cpu_to_le32(NVME_CMD_EFFECTS_CSUPP);
+ }
+ 
+ static void nvmet_get_cmd_effects_zns(struct nvme_effects_log *log)
+ {
+-	log->iocs[nvme_cmd_zone_append]		= cpu_to_le32(1 << 0);
+-	log->iocs[nvme_cmd_zone_mgmt_send]	= cpu_to_le32(1 << 0);
+-	log->iocs[nvme_cmd_zone_mgmt_recv]	= cpu_to_le32(1 << 0);
++	log->iocs[nvme_cmd_zone_append] =
++	log->iocs[nvme_cmd_zone_mgmt_send] =
++	log->iocs[nvme_cmd_zone_mgmt_recv] =
++		cpu_to_le32(NVME_CMD_EFFECTS_CSUPP);
+ }
+ 
+ static void nvmet_execute_get_log_cmd_effects_ns(struct nvmet_req *req)
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
+index 1c573e7a60bc8..f4bfaf1669fb3 100644
+--- a/drivers/of/fdt.c
++++ b/drivers/of/fdt.c
+@@ -1106,7 +1106,7 @@ u64 __init dt_mem_next_cell(int s, const __be32 **cellp)
+  */
+ int __init early_init_dt_scan_memory(void)
+ {
+-	int node;
++	int node, found_memory = 0;
+ 	const void *fdt = initial_boot_params;
+ 
+ 	fdt_for_each_subnode(node, fdt, 0) {
+@@ -1146,6 +1146,8 @@ int __init early_init_dt_scan_memory(void)
+ 
+ 			early_init_dt_add_memory_arch(base, size);
+ 
++			found_memory = 1;
++
+ 			if (!hotpluggable)
+ 				continue;
+ 
+@@ -1154,7 +1156,7 @@ int __init early_init_dt_scan_memory(void)
+ 					base, base + size);
+ 		}
+ 	}
+-	return 0;
++	return found_memory;
+ }
+ 
+ int __init early_init_dt_scan_chosen(char *cmdline)
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+index 0feda8eb93b52..5e011520650de 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+@@ -767,6 +767,7 @@ struct qcom_qmp {
+ 	struct regulator_bulk_data *vregs;
+ 
+ 	struct qmp_phy **phys;
++	struct qmp_phy *usb_phy;
+ 
+ 	struct mutex phy_mutex;
+ 	int init_count;
+@@ -1607,7 +1608,7 @@ static int qcom_qmp_phy_combo_com_init(struct qmp_phy *qphy)
+ {
+ 	struct qcom_qmp *qmp = qphy->qmp;
+ 	const struct qmp_phy_cfg *cfg = qphy->cfg;
+-	void __iomem *pcs = qphy->pcs;
++	struct qmp_phy *usb_phy = qmp->usb_phy;
+ 	void __iomem *dp_com = qmp->dp_com;
+ 	int ret;
+ 
+@@ -1663,13 +1664,13 @@ static int qcom_qmp_phy_combo_com_init(struct qmp_phy *qphy)
+ 		qphy_clrbits(dp_com, QPHY_V3_DP_COM_SW_RESET, SW_RESET);
+ 	}
+ 
+-	if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
+-		qphy_setbits(pcs,
+-				cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
+-				cfg->pwrdn_ctrl);
++	if (usb_phy->cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
++		qphy_setbits(usb_phy->pcs,
++				usb_phy->cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
++				usb_phy->cfg->pwrdn_ctrl);
+ 	else
+-		qphy_setbits(pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL,
+-				cfg->pwrdn_ctrl);
++		qphy_setbits(usb_phy->pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL,
++				usb_phy->cfg->pwrdn_ctrl);
+ 
+ 	mutex_unlock(&qmp->phy_mutex);
+ 
+@@ -2576,6 +2577,8 @@ static int qcom_qmp_phy_combo_probe(struct platform_device *pdev)
+ 				goto err_node_put;
+ 			}
+ 
++			qmp->usb_phy = qmp->phys[id];
++
+ 			/*
+ 			 * Register the pipe clock provided by phy.
+ 			 * See function description to see details of this pipe clock.
+@@ -2591,6 +2594,9 @@ static int qcom_qmp_phy_combo_probe(struct platform_device *pdev)
+ 		id++;
+ 	}
+ 
++	if (!qmp->usb_phy)
++		return -EINVAL;
++
+ 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ 	if (!IS_ERR(phy_provider))
+ 		dev_info(dev, "Registered Qcom-QMP phy\n");
+diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c
+index 8c42e76620333..92ed1213fe379 100644
+--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c
++++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c
+@@ -172,6 +172,7 @@ static const struct attribute_group fivr_attribute_group = {
+ RFIM_SHOW(rfi_restriction_run_busy, 1)
+ RFIM_SHOW(rfi_restriction_err_code, 1)
+ RFIM_SHOW(rfi_restriction_data_rate, 1)
++RFIM_SHOW(rfi_restriction_data_rate_base, 1)
+ RFIM_SHOW(ddr_data_rate_point_0, 1)
+ RFIM_SHOW(ddr_data_rate_point_1, 1)
+ RFIM_SHOW(ddr_data_rate_point_2, 1)
+@@ -181,11 +182,13 @@ RFIM_SHOW(rfi_disable, 1)
+ RFIM_STORE(rfi_restriction_run_busy, 1)
+ RFIM_STORE(rfi_restriction_err_code, 1)
+ RFIM_STORE(rfi_restriction_data_rate, 1)
++RFIM_STORE(rfi_restriction_data_rate_base, 1)
+ RFIM_STORE(rfi_disable, 1)
+ 
+ static DEVICE_ATTR_RW(rfi_restriction_run_busy);
+ static DEVICE_ATTR_RW(rfi_restriction_err_code);
+ static DEVICE_ATTR_RW(rfi_restriction_data_rate);
++static DEVICE_ATTR_RW(rfi_restriction_data_rate_base);
+ static DEVICE_ATTR_RO(ddr_data_rate_point_0);
+ static DEVICE_ATTR_RO(ddr_data_rate_point_1);
+ static DEVICE_ATTR_RO(ddr_data_rate_point_2);
+@@ -248,6 +251,7 @@ static struct attribute *dvfs_attrs[] = {
+ 	&dev_attr_rfi_restriction_run_busy.attr,
+ 	&dev_attr_rfi_restriction_err_code.attr,
+ 	&dev_attr_rfi_restriction_data_rate.attr,
++	&dev_attr_rfi_restriction_data_rate_base.attr,
+ 	&dev_attr_ddr_data_rate_point_0.attr,
+ 	&dev_attr_ddr_data_rate_point_1.attr,
+ 	&dev_attr_ddr_data_rate_point_2.attr,
+diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c
+index 67b237c7a76a1..550ae64350df0 100644
+--- a/drivers/usb/dwc3/dwc3-xilinx.c
++++ b/drivers/usb/dwc3/dwc3-xilinx.c
+@@ -13,6 +13,7 @@
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/of_gpio.h>
+ #include <linux/of_platform.h>
+ #include <linux/pm_runtime.h>
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index c2075b90f3dfe..40f75ba53e80e 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1702,6 +1702,7 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int
+ 	else if (!ret)
+ 		dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
+ 
++	dep->flags &= ~DWC3_EP_DELAY_STOP;
+ 	return ret;
+ }
+ 
+@@ -3701,8 +3702,10 @@ void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
+ 	if (dep->number <= 1 && dwc->ep0state != EP0_DATA_PHASE)
+ 		return;
+ 
++	if (interrupt && (dep->flags & DWC3_EP_DELAY_STOP))
++		return;
++
+ 	if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) ||
+-	    (dep->flags & DWC3_EP_DELAY_STOP) ||
+ 	    (dep->flags & DWC3_EP_END_TRANSFER_PENDING))
+ 		return;
+ 
+diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
+index 90913365def43..444d6572b2d05 100644
+--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
+@@ -1468,11 +1468,13 @@ static int mlx5_vdpa_add_mac_vlan_rules(struct mlx5_vdpa_net *ndev, u8 *mac,
+ 	dmac_v = MLX5_ADDR_OF(fte_match_param, headers_v, outer_headers.dmac_47_16);
+ 	eth_broadcast_addr(dmac_c);
+ 	ether_addr_copy(dmac_v, mac);
+-	MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1);
++	if (ndev->mvdev.actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VLAN)) {
++		MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1);
++		MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, headers_c, first_vid);
++	}
+ 	if (tagged) {
+ 		MLX5_SET(fte_match_set_lyr_2_4, headers_v, cvlan_tag, 1);
+-		MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, headers_c, first_vid);
+-		MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_vid, vid);
++		MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_vid, vid);
+ 	}
+ 	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+ 	dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
+@@ -1684,7 +1686,7 @@ static virtio_net_ctrl_ack handle_ctrl_mac(struct mlx5_vdpa_dev *mvdev, u8 cmd)
+ 
+ 		/* Need recreate the flow table entry, so that the packet could forward back
+ 		 */
+-		mac_vlan_del(ndev, ndev->config.mac, 0, false);
++		mac_vlan_del(ndev, mac_back, 0, false);
+ 
+ 		if (mac_vlan_add(ndev, ndev->config.mac, 0, false)) {
+ 			mlx5_vdpa_warn(mvdev, "failed to insert forward rules, try to restore\n");
+diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c
+index 225b7f5d8be35..6489f44bca1af 100644
+--- a/drivers/vdpa/vdpa_sim/vdpa_sim.c
++++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c
+@@ -66,8 +66,7 @@ static void vdpasim_queue_ready(struct vdpasim *vdpasim, unsigned int idx)
+ {
+ 	struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx];
+ 
+-	vringh_init_iotlb(&vq->vring, vdpasim->dev_attr.supported_features,
+-			  VDPASIM_QUEUE_MAX, false,
++	vringh_init_iotlb(&vq->vring, vdpasim->features, vq->num, false,
+ 			  (struct vring_desc *)(uintptr_t)vq->desc_addr,
+ 			  (struct vring_avail *)
+ 			  (uintptr_t)vq->driver_addr,
+@@ -680,7 +679,9 @@ static void vdpasim_free(struct vdpa_device *vdpa)
+ 	}
+ 
+ 	kvfree(vdpasim->buffer);
+-	vhost_iotlb_free(vdpasim->iommu);
++	for (i = 0; i < vdpasim->dev_attr.nas; i++)
++		vhost_iotlb_reset(&vdpasim->iommu[i]);
++	kfree(vdpasim->iommu);
+ 	kfree(vdpasim->vqs);
+ 	kfree(vdpasim->config);
+ }
+diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
+index c8bfea3b7db23..cc0534f8ae934 100644
+--- a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
++++ b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
+@@ -427,8 +427,10 @@ static int __init vdpasim_blk_init(void)
+ 	int ret;
+ 
+ 	ret = device_register(&vdpasim_blk_mgmtdev);
+-	if (ret)
++	if (ret) {
++		put_device(&vdpasim_blk_mgmtdev);
+ 		return ret;
++	}
+ 
+ 	ret = vdpa_mgmtdev_register(&mgmt_dev);
+ 	if (ret)
+diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
+index 886449e885026..c2e19dd064198 100644
+--- a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
++++ b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
+@@ -304,8 +304,10 @@ static int __init vdpasim_net_init(void)
+ 	int ret;
+ 
+ 	ret = device_register(&vdpasim_net_mgmtdev);
+-	if (ret)
++	if (ret) {
++		put_device(&vdpasim_net_mgmtdev);
+ 		return ret;
++	}
+ 
+ 	ret = vdpa_mgmtdev_register(&mgmt_dev);
+ 	if (ret)
+diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c b/drivers/vdpa/virtio_pci/vp_vdpa.c
+index 04522077735b2..f4e375b1d903c 100644
+--- a/drivers/vdpa/virtio_pci/vp_vdpa.c
++++ b/drivers/vdpa/virtio_pci/vp_vdpa.c
+@@ -629,7 +629,7 @@ static void vp_vdpa_remove(struct pci_dev *pdev)
+ 	mdev = vp_vdpa_mgtdev->mdev;
+ 	vp_modern_remove(mdev);
+ 	vdpa_mgmtdev_unregister(&vp_vdpa_mgtdev->mgtdev);
+-	kfree(&vp_vdpa_mgtdev->mgtdev.id_table);
++	kfree(vp_vdpa_mgtdev->mgtdev.id_table);
+ 	kfree(mdev);
+ 	kfree(vp_vdpa_mgtdev);
+ }
+diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
+index 166044642fd5c..ec32f785dfdec 100644
+--- a/drivers/vhost/vdpa.c
++++ b/drivers/vhost/vdpa.c
+@@ -65,6 +65,10 @@ static DEFINE_IDA(vhost_vdpa_ida);
+ 
+ static dev_t vhost_vdpa_major;
+ 
++static void vhost_vdpa_iotlb_unmap(struct vhost_vdpa *v,
++				   struct vhost_iotlb *iotlb, u64 start,
++				   u64 last, u32 asid);
++
+ static inline u32 iotlb_to_asid(struct vhost_iotlb *iotlb)
+ {
+ 	struct vhost_vdpa_as *as = container_of(iotlb, struct
+@@ -135,7 +139,7 @@ static int vhost_vdpa_remove_as(struct vhost_vdpa *v, u32 asid)
+ 		return -EINVAL;
+ 
+ 	hlist_del(&as->hash_link);
+-	vhost_iotlb_reset(&as->iotlb);
++	vhost_vdpa_iotlb_unmap(v, &as->iotlb, 0ULL, 0ULL - 1, asid);
+ 	kfree(as);
+ 
+ 	return 0;
+@@ -683,10 +687,20 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
+ 	mutex_unlock(&d->mutex);
+ 	return r;
+ }
++static void vhost_vdpa_general_unmap(struct vhost_vdpa *v,
++				     struct vhost_iotlb_map *map, u32 asid)
++{
++	struct vdpa_device *vdpa = v->vdpa;
++	const struct vdpa_config_ops *ops = vdpa->config;
++	if (ops->dma_map) {
++		ops->dma_unmap(vdpa, asid, map->start, map->size);
++	} else if (ops->set_map == NULL) {
++		iommu_unmap(v->domain, map->start, map->size);
++	}
++}
+ 
+-static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v,
+-				struct vhost_iotlb *iotlb,
+-				u64 start, u64 last)
++static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, struct vhost_iotlb *iotlb,
++				u64 start, u64 last, u32 asid)
+ {
+ 	struct vhost_dev *dev = &v->vdev;
+ 	struct vhost_iotlb_map *map;
+@@ -703,13 +717,13 @@ static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v,
+ 			unpin_user_page(page);
+ 		}
+ 		atomic64_sub(PFN_DOWN(map->size), &dev->mm->pinned_vm);
++		vhost_vdpa_general_unmap(v, map, asid);
+ 		vhost_iotlb_map_free(iotlb, map);
+ 	}
+ }
+ 
+-static void vhost_vdpa_va_unmap(struct vhost_vdpa *v,
+-				struct vhost_iotlb *iotlb,
+-				u64 start, u64 last)
++static void vhost_vdpa_va_unmap(struct vhost_vdpa *v, struct vhost_iotlb *iotlb,
++				u64 start, u64 last, u32 asid)
+ {
+ 	struct vhost_iotlb_map *map;
+ 	struct vdpa_map_file *map_file;
+@@ -718,20 +732,21 @@ static void vhost_vdpa_va_unmap(struct vhost_vdpa *v,
+ 		map_file = (struct vdpa_map_file *)map->opaque;
+ 		fput(map_file->file);
+ 		kfree(map_file);
++		vhost_vdpa_general_unmap(v, map, asid);
+ 		vhost_iotlb_map_free(iotlb, map);
+ 	}
+ }
+ 
+ static void vhost_vdpa_iotlb_unmap(struct vhost_vdpa *v,
+-				   struct vhost_iotlb *iotlb,
+-				   u64 start, u64 last)
++				   struct vhost_iotlb *iotlb, u64 start,
++				   u64 last, u32 asid)
+ {
+ 	struct vdpa_device *vdpa = v->vdpa;
+ 
+ 	if (vdpa->use_va)
+-		return vhost_vdpa_va_unmap(v, iotlb, start, last);
++		return vhost_vdpa_va_unmap(v, iotlb, start, last, asid);
+ 
+-	return vhost_vdpa_pa_unmap(v, iotlb, start, last);
++	return vhost_vdpa_pa_unmap(v, iotlb, start, last, asid);
+ }
+ 
+ static int perm_to_iommu_flags(u32 perm)
+@@ -798,17 +813,12 @@ static void vhost_vdpa_unmap(struct vhost_vdpa *v,
+ 	const struct vdpa_config_ops *ops = vdpa->config;
+ 	u32 asid = iotlb_to_asid(iotlb);
+ 
+-	vhost_vdpa_iotlb_unmap(v, iotlb, iova, iova + size - 1);
++	vhost_vdpa_iotlb_unmap(v, iotlb, iova, iova + size - 1, asid);
+ 
+-	if (ops->dma_map) {
+-		ops->dma_unmap(vdpa, asid, iova, size);
+-	} else if (ops->set_map) {
++	if (ops->set_map) {
+ 		if (!v->in_batch)
+ 			ops->set_map(vdpa, asid, iotlb);
+-	} else {
+-		iommu_unmap(v->domain, iova, size);
+ 	}
+-
+ 	/* If we are in the middle of batch processing, delay the free
+ 	 * of AS until BATCH_END.
+ 	 */
+@@ -1162,14 +1172,14 @@ static void vhost_vdpa_cleanup(struct vhost_vdpa *v)
+ 	struct vhost_vdpa_as *as;
+ 	u32 asid;
+ 
+-	vhost_dev_cleanup(&v->vdev);
+-	kfree(v->vdev.vqs);
+-
+ 	for (asid = 0; asid < v->vdpa->nas; asid++) {
+ 		as = asid_to_as(v, asid);
+ 		if (as)
+ 			vhost_vdpa_remove_as(v, asid);
+ 	}
++
++	vhost_dev_cleanup(&v->vdev);
++	kfree(v->vdev.vqs);
+ }
+ 
+ static int vhost_vdpa_open(struct inode *inode, struct file *filep)
+diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
+index 40097826cff0b..3c2359570df9d 100644
+--- a/drivers/vhost/vhost.c
++++ b/drivers/vhost/vhost.c
+@@ -2053,7 +2053,7 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len,
+ 	struct vhost_dev *dev = vq->dev;
+ 	struct vhost_iotlb *umem = dev->iotlb ? dev->iotlb : dev->umem;
+ 	struct iovec *_iov;
+-	u64 s = 0;
++	u64 s = 0, last = addr + len - 1;
+ 	int ret = 0;
+ 
+ 	while ((u64)len > s) {
+@@ -2063,7 +2063,7 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len,
+ 			break;
+ 		}
+ 
+-		map = vhost_iotlb_itree_first(umem, addr, addr + len - 1);
++		map = vhost_iotlb_itree_first(umem, addr, last);
+ 		if (map == NULL || map->start > addr) {
+ 			if (umem != dev->iotlb) {
+ 				ret = -EFAULT;
+diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
+index 11f59dd06a74e..828c293065657 100644
+--- a/drivers/vhost/vringh.c
++++ b/drivers/vhost/vringh.c
+@@ -1102,7 +1102,7 @@ static int iotlb_translate(const struct vringh *vrh,
+ 	struct vhost_iotlb_map *map;
+ 	struct vhost_iotlb *iotlb = vrh->iotlb;
+ 	int ret = 0;
+-	u64 s = 0;
++	u64 s = 0, last = addr + len - 1;
+ 
+ 	spin_lock(vrh->iotlb_lock);
+ 
+@@ -1114,8 +1114,7 @@ static int iotlb_translate(const struct vringh *vrh,
+ 			break;
+ 		}
+ 
+-		map = vhost_iotlb_itree_first(iotlb, addr,
+-					      addr + len - 1);
++		map = vhost_iotlb_itree_first(iotlb, addr, last);
+ 		if (!map || map->start > addr) {
+ 			ret = -EINVAL;
+ 			break;
+diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
+index 5703775af1297..10a7d23731fef 100644
+--- a/drivers/vhost/vsock.c
++++ b/drivers/vhost/vsock.c
+@@ -959,7 +959,14 @@ static int __init vhost_vsock_init(void)
+ 				  VSOCK_TRANSPORT_F_H2G);
+ 	if (ret < 0)
+ 		return ret;
+-	return misc_register(&vhost_vsock_misc);
++
++	ret = misc_register(&vhost_vsock_misc);
++	if (ret) {
++		vsock_core_unregister(&vhost_transport.transport);
++		return ret;
++	}
++
++	return 0;
+ };
+ 
+ static void __exit vhost_vsock_exit(void)
+diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c
+index 68bba2688f4c1..3d1bca3bcd4fd 100644
+--- a/drivers/video/fbdev/matrox/matroxfb_base.c
++++ b/drivers/video/fbdev/matrox/matroxfb_base.c
+@@ -1377,8 +1377,8 @@ static struct video_board vbG200 = {
+ 	.lowlevel = &matrox_G100
+ };
+ static struct video_board vbG200eW = {
+-	.maxvram = 0x100000,
+-	.maxdisplayable = 0x800000,
++	.maxvram = 0x1000000,
++	.maxdisplayable = 0x0800000,
+ 	.accelID = FB_ACCEL_MATROX_MGAG200,
+ 	.lowlevel = &matrox_G100
+ };
+diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c
+index 06be0644dd376..6ce704d3bdd27 100644
+--- a/fs/btrfs/block-rsv.c
++++ b/fs/btrfs/block-rsv.c
+@@ -424,6 +424,7 @@ void btrfs_init_root_block_rsv(struct btrfs_root *root)
+ 	case BTRFS_CSUM_TREE_OBJECTID:
+ 	case BTRFS_EXTENT_TREE_OBJECTID:
+ 	case BTRFS_FREE_SPACE_TREE_OBJECTID:
++	case BTRFS_BLOCK_GROUP_TREE_OBJECTID:
+ 		root->block_rsv = &fs_info->delayed_refs_rsv;
+ 		break;
+ 	case BTRFS_ROOT_TREE_OBJECTID:
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index bad06add93d7e..8e77acdecd252 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -280,14 +280,9 @@ struct btrfs_super_block {
+ 	/* the UUID written into btree blocks */
+ 	u8 metadata_uuid[BTRFS_FSID_SIZE];
+ 
+-	/* Extent tree v2 */
+-	__le64 block_group_root;
+-	__le64 block_group_root_generation;
+-	u8 block_group_root_level;
+-
+ 	/* future expansion */
+-	u8 reserved8[7];
+-	__le64 reserved[25];
++	u8 reserved8[8];
++	__le64 reserved[27];
+ 	u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
+ 	struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS];
+ 
+@@ -307,7 +302,8 @@ static_assert(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
+ #define BTRFS_FEATURE_COMPAT_RO_SUPP			\
+ 	(BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE |	\
+ 	 BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID | \
+-	 BTRFS_FEATURE_COMPAT_RO_VERITY)
++	 BTRFS_FEATURE_COMPAT_RO_VERITY |		\
++	 BTRFS_FEATURE_COMPAT_RO_BLOCK_GROUP_TREE)
+ 
+ #define BTRFS_FEATURE_COMPAT_RO_SAFE_SET	0ULL
+ #define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR	0ULL
+@@ -2391,17 +2387,6 @@ BTRFS_SETGET_STACK_FUNCS(backup_bytes_used, struct btrfs_root_backup,
+ BTRFS_SETGET_STACK_FUNCS(backup_num_devices, struct btrfs_root_backup,
+ 		   num_devices, 64);
+ 
+-/*
+- * For extent tree v2 we overload the extent root with the block group root, as
+- * we will have multiple extent roots.
+- */
+-BTRFS_SETGET_STACK_FUNCS(backup_block_group_root, struct btrfs_root_backup,
+-			 extent_root, 64);
+-BTRFS_SETGET_STACK_FUNCS(backup_block_group_root_gen, struct btrfs_root_backup,
+-			 extent_root_gen, 64);
+-BTRFS_SETGET_STACK_FUNCS(backup_block_group_root_level,
+-			 struct btrfs_root_backup, extent_root_level, 8);
+-
+ /* struct btrfs_balance_item */
+ BTRFS_SETGET_FUNCS(balance_flags, struct btrfs_balance_item, flags, 64);
+ 
+@@ -2534,13 +2519,6 @@ BTRFS_SETGET_STACK_FUNCS(super_cache_generation, struct btrfs_super_block,
+ BTRFS_SETGET_STACK_FUNCS(super_magic, struct btrfs_super_block, magic, 64);
+ BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block,
+ 			 uuid_tree_generation, 64);
+-BTRFS_SETGET_STACK_FUNCS(super_block_group_root, struct btrfs_super_block,
+-			 block_group_root, 64);
+-BTRFS_SETGET_STACK_FUNCS(super_block_group_root_generation,
+-			 struct btrfs_super_block,
+-			 block_group_root_generation, 64);
+-BTRFS_SETGET_STACK_FUNCS(super_block_group_root_level, struct btrfs_super_block,
+-			 block_group_root_level, 8);
+ 
+ int btrfs_super_csum_size(const struct btrfs_super_block *s);
+ const char *btrfs_super_csum_name(u16 csum_type);
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index aa4bc213d301b..23bb51e46e596 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -167,11 +167,9 @@ static bool btrfs_supported_super_csum(u16 csum_type)
+  * Return 0 if the superblock checksum type matches the checksum value of that
+  * algorithm. Pass the raw disk superblock data.
+  */
+-static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
+-				  char *raw_disk_sb)
++int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
++			   const struct btrfs_super_block *disk_sb)
+ {
+-	struct btrfs_super_block *disk_sb =
+-		(struct btrfs_super_block *)raw_disk_sb;
+ 	char result[BTRFS_CSUM_SIZE];
+ 	SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
+ 
+@@ -182,7 +180,7 @@ static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
+ 	 * BTRFS_SUPER_INFO_SIZE range, we expect that the unused space is
+ 	 * filled with zeros and is included in the checksum.
+ 	 */
+-	crypto_shash_digest(shash, raw_disk_sb + BTRFS_CSUM_SIZE,
++	crypto_shash_digest(shash, (const u8 *)disk_sb + BTRFS_CSUM_SIZE,
+ 			    BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE, result);
+ 
+ 	if (memcmp(disk_sb->csum, result, fs_info->csum_size))
+@@ -1524,6 +1522,9 @@ static struct btrfs_root *btrfs_get_global_root(struct btrfs_fs_info *fs_info,
+ 	if (objectid == BTRFS_UUID_TREE_OBJECTID)
+ 		return btrfs_grab_root(fs_info->uuid_root) ?
+ 			fs_info->uuid_root : ERR_PTR(-ENOENT);
++	if (objectid == BTRFS_BLOCK_GROUP_TREE_OBJECTID)
++		return btrfs_grab_root(fs_info->block_group_root) ?
++			fs_info->block_group_root : ERR_PTR(-ENOENT);
+ 	if (objectid == BTRFS_FREE_SPACE_TREE_OBJECTID) {
+ 		struct btrfs_root *root = btrfs_global_root(fs_info, &key);
+ 
+@@ -1980,14 +1981,7 @@ static void backup_super_roots(struct btrfs_fs_info *info)
+ 	btrfs_set_backup_chunk_root_level(root_backup,
+ 			       btrfs_header_level(info->chunk_root->node));
+ 
+-	if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) {
+-		btrfs_set_backup_block_group_root(root_backup,
+-					info->block_group_root->node->start);
+-		btrfs_set_backup_block_group_root_gen(root_backup,
+-			btrfs_header_generation(info->block_group_root->node));
+-		btrfs_set_backup_block_group_root_level(root_backup,
+-			btrfs_header_level(info->block_group_root->node));
+-	} else {
++	if (!btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE)) {
+ 		struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
+ 		struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
+ 
+@@ -2529,10 +2523,24 @@ static int btrfs_read_roots(struct btrfs_fs_info *fs_info)
+ 	if (ret)
+ 		return ret;
+ 
+-	location.objectid = BTRFS_DEV_TREE_OBJECTID;
+ 	location.type = BTRFS_ROOT_ITEM_KEY;
+ 	location.offset = 0;
+ 
++	if (btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE)) {
++		location.objectid = BTRFS_BLOCK_GROUP_TREE_OBJECTID;
++		root = btrfs_read_tree_root(tree_root, &location);
++		if (IS_ERR(root)) {
++			if (!btrfs_test_opt(fs_info, IGNOREBADROOTS)) {
++				ret = PTR_ERR(root);
++				goto out;
++			}
++		} else {
++			set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
++			fs_info->block_group_root = root;
++		}
++	}
++
++	location.objectid = BTRFS_DEV_TREE_OBJECTID;
+ 	root = btrfs_read_tree_root(tree_root, &location);
+ 	if (IS_ERR(root)) {
+ 		if (!btrfs_test_opt(fs_info, IGNOREBADROOTS)) {
+@@ -2602,8 +2610,8 @@ out:
+  * 		1, 2	2nd and 3rd backup copy
+  * 	       -1	skip bytenr check
+  */
+-static int validate_super(struct btrfs_fs_info *fs_info,
+-			    struct btrfs_super_block *sb, int mirror_num)
++int btrfs_validate_super(struct btrfs_fs_info *fs_info,
++			 struct btrfs_super_block *sb, int mirror_num)
+ {
+ 	u64 nodesize = btrfs_super_nodesize(sb);
+ 	u64 sectorsize = btrfs_super_sectorsize(sb);
+@@ -2705,6 +2713,18 @@ static int validate_super(struct btrfs_fs_info *fs_info,
+ 		ret = -EINVAL;
+ 	}
+ 
++	/*
++	 * Artificial requirement for block-group-tree to force newer features
++	 * (free-space-tree, no-holes) so the test matrix is smaller.
++	 */
++	if (btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE) &&
++	    (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID) ||
++	     !btrfs_fs_incompat(fs_info, NO_HOLES))) {
++		btrfs_err(fs_info,
++		"block-group-tree feature requires fres-space-tree and no-holes");
++		ret = -EINVAL;
++	}
++
+ 	if (memcmp(fs_info->fs_devices->metadata_uuid, sb->dev_item.fsid,
+ 		   BTRFS_FSID_SIZE) != 0) {
+ 		btrfs_err(fs_info,
+@@ -2787,7 +2807,7 @@ static int validate_super(struct btrfs_fs_info *fs_info,
+  */
+ static int btrfs_validate_mount_super(struct btrfs_fs_info *fs_info)
+ {
+-	return validate_super(fs_info, fs_info->super_copy, 0);
++	return btrfs_validate_super(fs_info, fs_info->super_copy, 0);
+ }
+ 
+ /*
+@@ -2801,7 +2821,7 @@ static int btrfs_validate_write_super(struct btrfs_fs_info *fs_info,
+ {
+ 	int ret;
+ 
+-	ret = validate_super(fs_info, sb, -1);
++	ret = btrfs_validate_super(fs_info, sb, -1);
+ 	if (ret < 0)
+ 		goto out;
+ 	if (!btrfs_supported_super_csum(btrfs_super_csum_type(sb))) {
+@@ -2862,17 +2882,7 @@ static int load_important_roots(struct btrfs_fs_info *fs_info)
+ 		btrfs_warn(fs_info, "couldn't read tree root");
+ 		return ret;
+ 	}
+-
+-	if (!btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+-		return 0;
+-
+-	bytenr = btrfs_super_block_group_root(sb);
+-	gen = btrfs_super_block_group_root_generation(sb);
+-	level = btrfs_super_block_group_root_level(sb);
+-	ret = load_super_root(fs_info->block_group_root, bytenr, gen, level);
+-	if (ret)
+-		btrfs_warn(fs_info, "couldn't read block group root");
+-	return ret;
++	return 0;
+ }
+ 
+ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
+@@ -2884,16 +2894,6 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
+ 	int ret = 0;
+ 	int i;
+ 
+-	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+-		struct btrfs_root *root;
+-
+-		root = btrfs_alloc_root(fs_info, BTRFS_BLOCK_GROUP_TREE_OBJECTID,
+-					GFP_KERNEL);
+-		if (!root)
+-			return -ENOMEM;
+-		fs_info->block_group_root = root;
+-	}
+-
+ 	for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) {
+ 		if (handle_error) {
+ 			if (!IS_ERR(tree_root->node))
+@@ -3281,6 +3281,114 @@ out:
+ 	return ret;
+ }
+ 
++/*
++ * Do various sanity and dependency checks of different features.
++ *
++ * @is_rw_mount:	If the mount is read-write.
++ *
++ * This is the place for less strict checks (like for subpage or artificial
++ * feature dependencies).
++ *
++ * For strict checks or possible corruption detection, see
++ * btrfs_validate_super().
++ *
++ * This should be called after btrfs_parse_options(), as some mount options
++ * (space cache related) can modify on-disk format like free space tree and
++ * screw up certain feature dependencies.
++ */
++int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount)
++{
++	struct btrfs_super_block *disk_super = fs_info->super_copy;
++	u64 incompat = btrfs_super_incompat_flags(disk_super);
++	const u64 compat_ro = btrfs_super_compat_ro_flags(disk_super);
++	const u64 compat_ro_unsupp = (compat_ro & ~BTRFS_FEATURE_COMPAT_RO_SUPP);
++
++	if (incompat & ~BTRFS_FEATURE_INCOMPAT_SUPP) {
++		btrfs_err(fs_info,
++		"cannot mount because of unknown incompat features (0x%llx)",
++		    incompat);
++		return -EINVAL;
++	}
++
++	/* Runtime limitation for mixed block groups. */
++	if ((incompat & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) &&
++	    (fs_info->sectorsize != fs_info->nodesize)) {
++		btrfs_err(fs_info,
++"unequal nodesize/sectorsize (%u != %u) are not allowed for mixed block groups",
++			fs_info->nodesize, fs_info->sectorsize);
++		return -EINVAL;
++	}
++
++	/* Mixed backref is an always-enabled feature. */
++	incompat |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF;
++
++	/* Set compression related flags just in case. */
++	if (fs_info->compress_type == BTRFS_COMPRESS_LZO)
++		incompat |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
++	else if (fs_info->compress_type == BTRFS_COMPRESS_ZSTD)
++		incompat |= BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD;
++
++	/*
++	 * An ancient flag, which should really be marked deprecated.
++	 * Such runtime limitation doesn't really need a incompat flag.
++	 */
++	if (btrfs_super_nodesize(disk_super) > PAGE_SIZE)
++		incompat |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
++
++	if (compat_ro_unsupp && is_rw_mount) {
++		btrfs_err(fs_info,
++	"cannot mount read-write because of unknown compat_ro features (0x%llx)",
++		       compat_ro);
++		return -EINVAL;
++	}
++
++	/*
++	 * We have unsupported RO compat features, although RO mounted, we
++	 * should not cause any metadata writes, including log replay.
++	 * Or we could screw up whatever the new feature requires.
++	 */
++	if (compat_ro_unsupp && btrfs_super_log_root(disk_super) &&
++	    !btrfs_test_opt(fs_info, NOLOGREPLAY)) {
++		btrfs_err(fs_info,
++"cannot replay dirty log with unsupported compat_ro features (0x%llx), try rescue=nologreplay",
++			  compat_ro);
++		return -EINVAL;
++	}
++
++	/*
++	 * Artificial limitations for block group tree, to force
++	 * block-group-tree to rely on no-holes and free-space-tree.
++	 */
++	if (btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE) &&
++	    (!btrfs_fs_incompat(fs_info, NO_HOLES) ||
++	     !btrfs_test_opt(fs_info, FREE_SPACE_TREE))) {
++		btrfs_err(fs_info,
++"block-group-tree feature requires no-holes and free-space-tree features");
++		return -EINVAL;
++	}
++
++	/*
++	 * Subpage runtime limitation on v1 cache.
++	 *
++	 * V1 space cache still has some hard codeed PAGE_SIZE usage, while
++	 * we're already defaulting to v2 cache, no need to bother v1 as it's
++	 * going to be deprecated anyway.
++	 */
++	if (fs_info->sectorsize < PAGE_SIZE && btrfs_test_opt(fs_info, SPACE_CACHE)) {
++		btrfs_warn(fs_info,
++	"v1 space cache is not supported for page size %lu with sectorsize %u",
++			   PAGE_SIZE, fs_info->sectorsize);
++		return -EINVAL;
++	}
++
++	/* This can be called by remount, we need to protect the super block. */
++	spin_lock(&fs_info->super_lock);
++	btrfs_set_super_incompat_flags(disk_super, incompat);
++	spin_unlock(&fs_info->super_lock);
++
++	return 0;
++}
++
+ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_devices,
+ 		      char *options)
+ {
+@@ -3361,7 +3469,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
+ 	 * We want to check superblock checksum, the type is stored inside.
+ 	 * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
+ 	 */
+-	if (btrfs_check_super_csum(fs_info, (u8 *)disk_super)) {
++	if (btrfs_check_super_csum(fs_info, disk_super)) {
+ 		btrfs_err(fs_info, "superblock checksum mismatch");
+ 		err = -EINVAL;
+ 		btrfs_release_disk_super(disk_super);
+@@ -3430,72 +3538,12 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
+ 		goto fail_alloc;
+ 	}
+ 
+-	features = btrfs_super_incompat_flags(disk_super) &
+-		~BTRFS_FEATURE_INCOMPAT_SUPP;
+-	if (features) {
+-		btrfs_err(fs_info,
+-		    "cannot mount because of unsupported optional features (0x%llx)",
+-		    features);
+-		err = -EINVAL;
+-		goto fail_alloc;
+-	}
+-
+-	features = btrfs_super_incompat_flags(disk_super);
+-	features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF;
+-	if (fs_info->compress_type == BTRFS_COMPRESS_LZO)
+-		features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
+-	else if (fs_info->compress_type == BTRFS_COMPRESS_ZSTD)
+-		features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD;
+-
+-	/*
+-	 * Flag our filesystem as having big metadata blocks if they are bigger
+-	 * than the page size.
+-	 */
+-	if (btrfs_super_nodesize(disk_super) > PAGE_SIZE)
+-		features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
+-
+-	/*
+-	 * mixed block groups end up with duplicate but slightly offset
+-	 * extent buffers for the same range.  It leads to corruptions
+-	 */
+-	if ((features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) &&
+-	    (sectorsize != nodesize)) {
+-		btrfs_err(fs_info,
+-"unequal nodesize/sectorsize (%u != %u) are not allowed for mixed block groups",
+-			nodesize, sectorsize);
+-		goto fail_alloc;
+-	}
+-
+-	/*
+-	 * Needn't use the lock because there is no other task which will
+-	 * update the flag.
+-	 */
+-	btrfs_set_super_incompat_flags(disk_super, features);
+-
+-	features = btrfs_super_compat_ro_flags(disk_super) &
+-		~BTRFS_FEATURE_COMPAT_RO_SUPP;
+-	if (!sb_rdonly(sb) && features) {
+-		btrfs_err(fs_info,
+-	"cannot mount read-write because of unsupported optional features (0x%llx)",
+-		       features);
+-		err = -EINVAL;
+-		goto fail_alloc;
+-	}
+-	/*
+-	 * We have unsupported RO compat features, although RO mounted, we
+-	 * should not cause any metadata write, including log replay.
+-	 * Or we could screw up whatever the new feature requires.
+-	 */
+-	if (unlikely(features && btrfs_super_log_root(disk_super) &&
+-		     !btrfs_test_opt(fs_info, NOLOGREPLAY))) {
+-		btrfs_err(fs_info,
+-"cannot replay dirty log with unsupported compat_ro features (0x%llx), try rescue=nologreplay",
+-			  features);
+-		err = -EINVAL;
++	ret = btrfs_check_features(fs_info, !sb_rdonly(sb));
++	if (ret < 0) {
++		err = ret;
+ 		goto fail_alloc;
+ 	}
+ 
+-
+ 	if (sectorsize < PAGE_SIZE) {
+ 		struct btrfs_subpage_info *subpage_info;
+ 
+@@ -3835,7 +3883,7 @@ static void btrfs_end_super_write(struct bio *bio)
+ }
+ 
+ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
+-						   int copy_num)
++						   int copy_num, bool drop_cache)
+ {
+ 	struct btrfs_super_block *super;
+ 	struct page *page;
+@@ -3853,6 +3901,19 @@ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
+ 	if (bytenr + BTRFS_SUPER_INFO_SIZE >= bdev_nr_bytes(bdev))
+ 		return ERR_PTR(-EINVAL);
+ 
++	if (drop_cache) {
++		/* This should only be called with the primary sb. */
++		ASSERT(copy_num == 0);
++
++		/*
++		 * Drop the page of the primary superblock, so later read will
++		 * always read from the device.
++		 */
++		invalidate_inode_pages2_range(mapping,
++				bytenr >> PAGE_SHIFT,
++				(bytenr + BTRFS_SUPER_INFO_SIZE) >> PAGE_SHIFT);
++	}
++
+ 	page = read_cache_page_gfp(mapping, bytenr >> PAGE_SHIFT, GFP_NOFS);
+ 	if (IS_ERR(page))
+ 		return ERR_CAST(page);
+@@ -3884,7 +3945,7 @@ struct btrfs_super_block *btrfs_read_dev_super(struct block_device *bdev)
+ 	 * later supers, using BTRFS_SUPER_MIRROR_MAX instead
+ 	 */
+ 	for (i = 0; i < 1; i++) {
+-		super = btrfs_read_dev_one_super(bdev, i);
++		super = btrfs_read_dev_one_super(bdev, i, false);
+ 		if (IS_ERR(super))
+ 			continue;
+ 
+diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
+index 47ad8e0a2d33f..7322af63c0cc7 100644
+--- a/fs/btrfs/disk-io.h
++++ b/fs/btrfs/disk-io.h
+@@ -42,14 +42,19 @@ struct extent_buffer *btrfs_find_create_tree_block(
+ void btrfs_clean_tree_block(struct extent_buffer *buf);
+ void btrfs_clear_oneshot_options(struct btrfs_fs_info *fs_info);
+ int btrfs_start_pre_rw_mount(struct btrfs_fs_info *fs_info);
++int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
++			   const struct btrfs_super_block *disk_sb);
+ int __cold open_ctree(struct super_block *sb,
+ 	       struct btrfs_fs_devices *fs_devices,
+ 	       char *options);
+ void __cold close_ctree(struct btrfs_fs_info *fs_info);
++int btrfs_validate_super(struct btrfs_fs_info *fs_info,
++			 struct btrfs_super_block *sb, int mirror_num);
++int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount);
+ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors);
+ struct btrfs_super_block *btrfs_read_dev_super(struct block_device *bdev);
+ struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
+-						   int copy_num);
++						   int copy_num, bool drop_cache);
+ int btrfs_commit_super(struct btrfs_fs_info *fs_info);
+ struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
+ 					struct btrfs_key *key);
+@@ -103,7 +108,7 @@ static inline struct btrfs_root *btrfs_grab_root(struct btrfs_root *root)
+ 
+ static inline struct btrfs_root *btrfs_block_group_root(struct btrfs_fs_info *fs_info)
+ {
+-	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
++	if (btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE))
+ 		return fs_info->block_group_root;
+ 	return btrfs_extent_root(fs_info, 0);
+ }
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index cf4f19e80e2f7..0982995177a6d 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -2377,7 +2377,16 @@ static int repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,
+ 				      &map_length, &bioc, mirror_num);
+ 		if (ret)
+ 			goto out_counter_dec;
+-		BUG_ON(mirror_num != bioc->mirror_num);
++		/*
++		 * This happens when dev-replace is also running, and the
++		 * mirror_num indicates the dev-replace target.
++		 *
++		 * In this case, we don't need to do anything, as the read
++		 * error just means the replace progress hasn't reached our
++		 * read range, and later replace routine would handle it well.
++		 */
++		if (mirror_num != bioc->mirror_num)
++			goto out_counter_dec;
+ 	}
+ 
+ 	sector = bioc->stripes[bioc->mirror_num - 1].physical >> 9;
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index 4fff0067bd2a9..c498d5e164eb0 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3750,13 +3750,10 @@ static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info,
+ 	di_args->bytes_used = btrfs_device_get_bytes_used(dev);
+ 	di_args->total_bytes = btrfs_device_get_total_bytes(dev);
+ 	memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid));
+-	if (dev->name) {
+-		strncpy(di_args->path, rcu_str_deref(dev->name),
+-				sizeof(di_args->path) - 1);
+-		di_args->path[sizeof(di_args->path) - 1] = 0;
+-	} else {
++	if (dev->name)
++		strscpy(di_args->path, rcu_str_deref(dev->name), sizeof(di_args->path));
++	else
+ 		di_args->path[0] = '\0';
+-	}
+ 
+ out:
+ 	rcu_read_unlock();
+diff --git a/fs/btrfs/rcu-string.h b/fs/btrfs/rcu-string.h
+index 5c1a617eb25de..5c2b66d155ef7 100644
+--- a/fs/btrfs/rcu-string.h
++++ b/fs/btrfs/rcu-string.h
+@@ -18,7 +18,11 @@ static inline struct rcu_string *rcu_string_strdup(const char *src, gfp_t mask)
+ 					 (len * sizeof(char)), mask);
+ 	if (!ret)
+ 		return ret;
+-	strncpy(ret->str, src, len);
++	/* Warn if the source got unexpectedly truncated. */
++	if (WARN_ON(strscpy(ret->str, src, len) < 0)) {
++		kfree(ret);
++		return NULL;
++	}
+ 	return ret;
+ }
+ 
+diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
+index ad3ce9700eaf3..01c381e75cdbb 100644
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -2012,14 +2012,10 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
+ 	if (ret)
+ 		goto restore;
+ 
+-	/* V1 cache is not supported for subpage mount. */
+-	if (fs_info->sectorsize < PAGE_SIZE && btrfs_test_opt(fs_info, SPACE_CACHE)) {
+-		btrfs_warn(fs_info,
+-	"v1 space cache is not supported for page size %lu with sectorsize %u",
+-			   PAGE_SIZE, fs_info->sectorsize);
+-		ret = -EINVAL;
++	ret = btrfs_check_features(fs_info, !(*flags & SB_RDONLY));
++	if (ret < 0)
+ 		goto restore;
+-	}
++
+ 	btrfs_remount_begin(fs_info, old_opts, *flags);
+ 	btrfs_resize_thread_pool(fs_info,
+ 		fs_info->thread_pool_size, old_thread_pool_size);
+@@ -2115,15 +2111,6 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
+ 			ret = -EINVAL;
+ 			goto restore;
+ 		}
+-		if (btrfs_super_compat_ro_flags(fs_info->super_copy) &
+-		    ~BTRFS_FEATURE_COMPAT_RO_SUPP) {
+-			btrfs_err(fs_info,
+-		"can not remount read-write due to unsupported optional flags 0x%llx",
+-				btrfs_super_compat_ro_flags(fs_info->super_copy) &
+-				~BTRFS_FEATURE_COMPAT_RO_SUPP);
+-			ret = -EINVAL;
+-			goto restore;
+-		}
+ 		if (fs_info->fs_devices->rw_devices == 0) {
+ 			ret = -EACCES;
+ 			goto restore;
+@@ -2562,11 +2549,87 @@ static int btrfs_freeze(struct super_block *sb)
+ 	return btrfs_commit_transaction(trans);
+ }
+ 
++static int check_dev_super(struct btrfs_device *dev)
++{
++	struct btrfs_fs_info *fs_info = dev->fs_info;
++	struct btrfs_super_block *sb;
++	u16 csum_type;
++	int ret = 0;
++
++	/* This should be called with fs still frozen. */
++	ASSERT(test_bit(BTRFS_FS_FROZEN, &fs_info->flags));
++
++	/* Missing dev, no need to check. */
++	if (!dev->bdev)
++		return 0;
++
++	/* Only need to check the primary super block. */
++	sb = btrfs_read_dev_one_super(dev->bdev, 0, true);
++	if (IS_ERR(sb))
++		return PTR_ERR(sb);
++
++	/* Verify the checksum. */
++	csum_type = btrfs_super_csum_type(sb);
++	if (csum_type != btrfs_super_csum_type(fs_info->super_copy)) {
++		btrfs_err(fs_info, "csum type changed, has %u expect %u",
++			  csum_type, btrfs_super_csum_type(fs_info->super_copy));
++		ret = -EUCLEAN;
++		goto out;
++	}
++
++	if (btrfs_check_super_csum(fs_info, sb)) {
++		btrfs_err(fs_info, "csum for on-disk super block no longer matches");
++		ret = -EUCLEAN;
++		goto out;
++	}
++
++	/* Btrfs_validate_super() includes fsid check against super->fsid. */
++	ret = btrfs_validate_super(fs_info, sb, 0);
++	if (ret < 0)
++		goto out;
++
++	if (btrfs_super_generation(sb) != fs_info->last_trans_committed) {
++		btrfs_err(fs_info, "transid mismatch, has %llu expect %llu",
++			btrfs_super_generation(sb),
++			fs_info->last_trans_committed);
++		ret = -EUCLEAN;
++		goto out;
++	}
++out:
++	btrfs_release_disk_super(sb);
++	return ret;
++}
++
+ static int btrfs_unfreeze(struct super_block *sb)
+ {
+ 	struct btrfs_fs_info *fs_info = btrfs_sb(sb);
++	struct btrfs_device *device;
++	int ret = 0;
+ 
++	/*
++	 * Make sure the fs is not changed by accident (like hibernation then
++	 * modified by other OS).
++	 * If we found anything wrong, we mark the fs error immediately.
++	 *
++	 * And since the fs is frozen, no one can modify the fs yet, thus
++	 * we don't need to hold device_list_mutex.
++	 */
++	list_for_each_entry(device, &fs_info->fs_devices->devices, dev_list) {
++		ret = check_dev_super(device);
++		if (ret < 0) {
++			btrfs_handle_fs_error(fs_info, ret,
++				"super block on devid %llu got modified unexpectedly",
++				device->devid);
++			break;
++		}
++	}
+ 	clear_bit(BTRFS_FS_FROZEN, &fs_info->flags);
++
++	/*
++	 * We still return 0, to allow VFS layer to unfreeze the fs even the
++	 * above checks failed. Since the fs is either fine or read-only, we're
++	 * safe to continue, without causing further damage.
++	 */
+ 	return 0;
+ }
+ 
+diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
+index 00b97e6eb5078..897367ba68d2a 100644
+--- a/fs/btrfs/sysfs.c
++++ b/fs/btrfs/sysfs.c
+@@ -286,6 +286,7 @@ BTRFS_FEAT_ATTR_INCOMPAT(skinny_metadata, SKINNY_METADATA);
+ BTRFS_FEAT_ATTR_INCOMPAT(no_holes, NO_HOLES);
+ BTRFS_FEAT_ATTR_INCOMPAT(metadata_uuid, METADATA_UUID);
+ BTRFS_FEAT_ATTR_COMPAT_RO(free_space_tree, FREE_SPACE_TREE);
++BTRFS_FEAT_ATTR_COMPAT_RO(block_group_tree, BLOCK_GROUP_TREE);
+ BTRFS_FEAT_ATTR_INCOMPAT(raid1c34, RAID1C34);
+ #ifdef CONFIG_BLK_DEV_ZONED
+ BTRFS_FEAT_ATTR_INCOMPAT(zoned, ZONED);
+@@ -317,6 +318,7 @@ static struct attribute *btrfs_supported_feature_attrs[] = {
+ 	BTRFS_FEAT_ATTR_PTR(metadata_uuid),
+ 	BTRFS_FEAT_ATTR_PTR(free_space_tree),
+ 	BTRFS_FEAT_ATTR_PTR(raid1c34),
++	BTRFS_FEAT_ATTR_PTR(block_group_tree),
+ #ifdef CONFIG_BLK_DEV_ZONED
+ 	BTRFS_FEAT_ATTR_PTR(zoned),
+ #endif
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index 0bec10740ad39..8fab3b2749571 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -1912,14 +1912,6 @@ static void update_super_roots(struct btrfs_fs_info *fs_info)
+ 		super->cache_generation = 0;
+ 	if (test_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags))
+ 		super->uuid_tree_generation = root_item->generation;
+-
+-	if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+-		root_item = &fs_info->block_group_root->root_item;
+-
+-		super->block_group_root = root_item->bytenr;
+-		super->block_group_root_generation = root_item->generation;
+-		super->block_group_root_level = root_item->level;
+-	}
+ }
+ 
+ int btrfs_transaction_in_commit(struct btrfs_fs_info *info)
+diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c
+index b6cf39f4e7e48..072ab9a1374b5 100644
+--- a/fs/btrfs/tree-defrag.c
++++ b/fs/btrfs/tree-defrag.c
+@@ -31,8 +31,10 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
+ 		goto out;
+ 
+ 	path = btrfs_alloc_path();
+-	if (!path)
+-		return -ENOMEM;
++	if (!path) {
++		ret = -ENOMEM;
++		goto out;
++	}
+ 
+ 	level = btrfs_header_level(root->node);
+ 
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 6f006430115a3..55c8bf9a5c890 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -2029,7 +2029,7 @@ void btrfs_scratch_superblocks(struct btrfs_fs_info *fs_info,
+ 		struct page *page;
+ 		int ret;
+ 
+-		disk_super = btrfs_read_dev_one_super(bdev, copy_num);
++		disk_super = btrfs_read_dev_one_super(bdev, copy_num, false);
+ 		if (IS_ERR(disk_super))
+ 			continue;
+ 
+diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
+index 02b5c0ac56547..af8dbcf932ab1 100644
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -2910,7 +2910,7 @@ int ceph_get_caps(struct file *filp, int need, int want, loff_t endoff, int *got
+ 
+ 	while (true) {
+ 		flags &= CEPH_FILE_MODE_MASK;
+-		if (atomic_read(&fi->num_locks))
++		if (vfs_inode_has_locks(inode))
+ 			flags |= CHECK_FILELOCK;
+ 		_got = 0;
+ 		ret = try_get_cap_refs(inode, need, want, endoff,
+diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c
+index 3e2843e86e274..b191426bf880c 100644
+--- a/fs/ceph/locks.c
++++ b/fs/ceph/locks.c
+@@ -32,18 +32,14 @@ void __init ceph_flock_init(void)
+ 
+ static void ceph_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
+ {
+-	struct ceph_file_info *fi = dst->fl_file->private_data;
+ 	struct inode *inode = file_inode(dst->fl_file);
+ 	atomic_inc(&ceph_inode(inode)->i_filelock_ref);
+-	atomic_inc(&fi->num_locks);
+ }
+ 
+ static void ceph_fl_release_lock(struct file_lock *fl)
+ {
+-	struct ceph_file_info *fi = fl->fl_file->private_data;
+ 	struct inode *inode = file_inode(fl->fl_file);
+ 	struct ceph_inode_info *ci = ceph_inode(inode);
+-	atomic_dec(&fi->num_locks);
+ 	if (atomic_dec_and_test(&ci->i_filelock_ref)) {
+ 		/* clear error when all locks are released */
+ 		spin_lock(&ci->i_ceph_lock);
+diff --git a/fs/ceph/super.h b/fs/ceph/super.h
+index 40630e6f691c7..ae4126f634101 100644
+--- a/fs/ceph/super.h
++++ b/fs/ceph/super.h
+@@ -788,7 +788,6 @@ struct ceph_file_info {
+ 	struct list_head rw_contexts;
+ 
+ 	u32 filp_gen;
+-	atomic_t num_locks;
+ };
+ 
+ struct ceph_dir_file_info {
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index 5d93154572c01..4ef2d08de5b65 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -292,9 +292,10 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
+ 			continue;
+ 		}
+ 		kref_get(&iface->refcount);
++		break;
+ 	}
+ 
+-	if (!list_entry_is_head(iface, &ses->iface_list, iface_head)) {
++	if (list_entry_is_head(iface, &ses->iface_list, iface_head)) {
+ 		rc = 1;
+ 		iface = NULL;
+ 		cifs_dbg(FYI, "unable to find a suitable iface\n");
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 74052b51655ec..05c9c75360fab 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -530,7 +530,6 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ 	p = buf;
+ 
+ 	spin_lock(&ses->iface_lock);
+-	ses->iface_count = 0;
+ 	/*
+ 	 * Go through iface_list and do kref_put to remove
+ 	 * any unused ifaces. ifaces in use will be removed
+@@ -540,6 +539,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ 				 iface_head) {
+ 		iface->is_active = 0;
+ 		kref_put(&iface->refcount, release_iface);
++		ses->iface_count--;
+ 	}
+ 	spin_unlock(&ses->iface_lock);
+ 
+@@ -617,6 +617,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ 				/* just get a ref so that it doesn't get picked/freed */
+ 				iface->is_active = 1;
+ 				kref_get(&iface->refcount);
++				ses->iface_count++;
+ 				spin_unlock(&ses->iface_lock);
+ 				goto next_iface;
+ 			} else if (ret < 0) {
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 2eae6e038f38a..ac083526c1155 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -5063,30 +5063,31 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
+ 		   ext4_has_feature_journal_needs_recovery(sb)) {
+ 		ext4_msg(sb, KERN_ERR, "required journal recovery "
+ 		       "suppressed and not mounted read-only");
+-		goto failed_mount_wq;
++		goto failed_mount3a;
+ 	} else {
+ 		/* Nojournal mode, all journal mount options are illegal */
+-		if (test_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM)) {
+-			ext4_msg(sb, KERN_ERR, "can't mount with "
+-				 "journal_checksum, fs mounted w/o journal");
+-			goto failed_mount_wq;
+-		}
+ 		if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
+ 			ext4_msg(sb, KERN_ERR, "can't mount with "
+ 				 "journal_async_commit, fs mounted w/o journal");
+-			goto failed_mount_wq;
++			goto failed_mount3a;
++		}
++
++		if (test_opt2(sb, EXPLICIT_JOURNAL_CHECKSUM)) {
++			ext4_msg(sb, KERN_ERR, "can't mount with "
++				 "journal_checksum, fs mounted w/o journal");
++			goto failed_mount3a;
+ 		}
+ 		if (sbi->s_commit_interval != JBD2_DEFAULT_MAX_COMMIT_AGE*HZ) {
+ 			ext4_msg(sb, KERN_ERR, "can't mount with "
+ 				 "commit=%lu, fs mounted w/o journal",
+ 				 sbi->s_commit_interval / HZ);
+-			goto failed_mount_wq;
++			goto failed_mount3a;
+ 		}
+ 		if (EXT4_MOUNT_DATA_FLAGS &
+ 		    (sbi->s_mount_opt ^ sbi->s_def_mount_opt)) {
+ 			ext4_msg(sb, KERN_ERR, "can't mount with "
+ 				 "data=, fs mounted w/o journal");
+-			goto failed_mount_wq;
++			goto failed_mount3a;
+ 		}
+ 		sbi->s_def_mount_opt &= ~EXT4_MOUNT_JOURNAL_CHECKSUM;
+ 		clear_opt(sb, JOURNAL_CHECKSUM);
+diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
+index a0746be3c1de7..80d17c520d0ba 100644
+--- a/fs/hfs/inode.c
++++ b/fs/hfs/inode.c
+@@ -458,15 +458,16 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ 		/* panic? */
+ 		return -EIO;
+ 
++	res = -EIO;
+ 	if (HFS_I(main_inode)->cat_key.CName.len > HFS_NAMELEN)
+-		return -EIO;
++		goto out;
+ 	fd.search_key->cat = HFS_I(main_inode)->cat_key;
+ 	if (hfs_brec_find(&fd))
+-		/* panic? */
+ 		goto out;
+ 
+ 	if (S_ISDIR(main_inode->i_mode)) {
+-		WARN_ON(fd.entrylength < sizeof(struct hfs_cat_dir));
++		if (fd.entrylength < sizeof(struct hfs_cat_dir))
++			goto out;
+ 		hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
+ 			   sizeof(struct hfs_cat_dir));
+ 		if (rec.type != HFS_CDR_DIR ||
+@@ -479,6 +480,8 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ 		hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
+ 			    sizeof(struct hfs_cat_dir));
+ 	} else if (HFS_IS_RSRC(inode)) {
++		if (fd.entrylength < sizeof(struct hfs_cat_file))
++			goto out;
+ 		hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
+ 			       sizeof(struct hfs_cat_file));
+ 		hfs_inode_write_fork(inode, rec.file.RExtRec,
+@@ -486,7 +489,8 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ 		hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
+ 				sizeof(struct hfs_cat_file));
+ 	} else {
+-		WARN_ON(fd.entrylength < sizeof(struct hfs_cat_file));
++		if (fd.entrylength < sizeof(struct hfs_cat_file))
++			goto out;
+ 		hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
+ 			   sizeof(struct hfs_cat_file));
+ 		if (rec.type != HFS_CDR_FIL ||
+@@ -503,9 +507,10 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ 		hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
+ 			    sizeof(struct hfs_cat_file));
+ 	}
++	res = 0;
+ out:
+ 	hfs_find_exit(&fd);
+-	return 0;
++	return res;
+ }
+ 
+ static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry,
+diff --git a/fs/ksmbd/auth.c b/fs/ksmbd/auth.c
+index c5a5c7b90d727..93b2290addd59 100644
+--- a/fs/ksmbd/auth.c
++++ b/fs/ksmbd/auth.c
+@@ -322,7 +322,8 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob,
+ 	dn_off = le32_to_cpu(authblob->DomainName.BufferOffset);
+ 	dn_len = le16_to_cpu(authblob->DomainName.Length);
+ 
+-	if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len)
++	if (blob_len < (u64)dn_off + dn_len || blob_len < (u64)nt_off + nt_len ||
++	    nt_len < CIFS_ENCPWD_SIZE)
+ 		return -EINVAL;
+ 
+ 	/* TODO : use domain name that imported from configuration file */
+diff --git a/fs/ksmbd/connection.c b/fs/ksmbd/connection.c
+index 756ad631c019a..eab9950b5a683 100644
+--- a/fs/ksmbd/connection.c
++++ b/fs/ksmbd/connection.c
+@@ -310,9 +310,12 @@ int ksmbd_conn_handler_loop(void *p)
+ 
+ 		/* 4 for rfc1002 length field */
+ 		size = pdu_size + 4;
+-		conn->request_buf = kvmalloc(size, GFP_KERNEL);
++		conn->request_buf = kvmalloc(size,
++					     GFP_KERNEL |
++					     __GFP_NOWARN |
++					     __GFP_NORETRY);
+ 		if (!conn->request_buf)
+-			continue;
++			break;
+ 
+ 		memcpy(conn->request_buf, hdr_buf, sizeof(hdr_buf));
+ 		if (!ksmbd_smb_request(conn))
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
+index 7a9497a7b0a30..a71a7cc0e5762 100644
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -1926,13 +1926,13 @@ int smb2_tree_connect(struct ksmbd_work *work)
+ 	if (conn->posix_ext_supported)
+ 		status.tree_conn->posix_extensions = true;
+ 
+-out_err1:
+ 	rsp->StructureSize = cpu_to_le16(16);
++	inc_rfc1001_len(work->response_buf, 16);
++out_err1:
+ 	rsp->Capabilities = 0;
+ 	rsp->Reserved = 0;
+ 	/* default manual caching */
+ 	rsp->ShareFlags = SMB2_SHAREFLAG_MANUAL_CACHING;
+-	inc_rfc1001_len(work->response_buf, 16);
+ 
+ 	if (!IS_ERR(treename))
+ 		kfree(treename);
+@@ -1965,6 +1965,9 @@ out_err1:
+ 		rsp->hdr.Status = STATUS_ACCESS_DENIED;
+ 	}
+ 
++	if (status.ret != KSMBD_TREE_CONN_STATUS_OK)
++		smb2_set_err_rsp(work);
++
+ 	return rc;
+ }
+ 
+diff --git a/fs/ksmbd/transport_tcp.c b/fs/ksmbd/transport_tcp.c
+index 143bba4e4db81..434891db42a2c 100644
+--- a/fs/ksmbd/transport_tcp.c
++++ b/fs/ksmbd/transport_tcp.c
+@@ -295,6 +295,7 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
+ 	struct msghdr ksmbd_msg;
+ 	struct kvec *iov;
+ 	struct ksmbd_conn *conn = KSMBD_TRANS(t)->conn;
++	int max_retry = 2;
+ 
+ 	iov = get_conn_iovec(t, nr_segs);
+ 	if (!iov)
+@@ -321,9 +322,11 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
+ 		} else if (conn->status == KSMBD_SESS_NEED_RECONNECT) {
+ 			total_read = -EAGAIN;
+ 			break;
+-		} else if (length == -ERESTARTSYS || length == -EAGAIN) {
++		} else if ((length == -ERESTARTSYS || length == -EAGAIN) &&
++			   max_retry) {
+ 			usleep_range(1000, 2000);
+ 			length = 0;
++			max_retry--;
+ 			continue;
+ 		} else if (length <= 0) {
+ 			total_read = -EAGAIN;
+diff --git a/fs/locks.c b/fs/locks.c
+index 607f94a0e789f..7dc129cc1a267 100644
+--- a/fs/locks.c
++++ b/fs/locks.c
+@@ -2669,6 +2669,29 @@ int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
+ }
+ EXPORT_SYMBOL_GPL(vfs_cancel_lock);
+ 
++/**
++ * vfs_inode_has_locks - are any file locks held on @inode?
++ * @inode: inode to check for locks
++ *
++ * Return true if there are any FL_POSIX or FL_FLOCK locks currently
++ * set on @inode.
++ */
++bool vfs_inode_has_locks(struct inode *inode)
++{
++	struct file_lock_context *ctx;
++	bool ret;
++
++	ctx = smp_load_acquire(&inode->i_flctx);
++	if (!ctx)
++		return false;
++
++	spin_lock(&ctx->flc_lock);
++	ret = !list_empty(&ctx->flc_posix) || !list_empty(&ctx->flc_flock);
++	spin_unlock(&ctx->flc_lock);
++	return ret;
++}
++EXPORT_SYMBOL_GPL(vfs_inode_has_locks);
++
+ #ifdef CONFIG_PROC_FS
+ #include <linux/proc_fs.h>
+ #include <linux/seq_file.h>
+diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
+index 2960d0a8e8f9a..355164a527540 100644
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -3528,6 +3528,17 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
+ 	case nfserr_noent:
+ 		xdr_truncate_encode(xdr, start_offset);
+ 		goto skip_entry;
++	case nfserr_jukebox:
++		/*
++		 * The pseudoroot should only display dentries that lead to
++		 * exports. If we get EJUKEBOX here, then we can't tell whether
++		 * this entry should be included. Just fail the whole READDIR
++		 * with NFS4ERR_DELAY in that case, and hope that the situation
++		 * will resolve itself by the client's next attempt.
++		 */
++		if (cd->rd_fhp->fh_export->ex_flags & NFSEXP_V4ROOT)
++			goto fail;
++		fallthrough;
+ 	default:
+ 		/*
+ 		 * If the client requested the RDATTR_ERROR attribute,
+diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
+index 4bb5baa17040f..011c556caa1e7 100644
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -447,8 +447,8 @@ static void nfsd_shutdown_net(struct net *net)
+ {
+ 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+ 
+-	nfsd_file_cache_shutdown_net(net);
+ 	nfs4_state_shutdown_net(net);
++	nfsd_file_cache_shutdown_net(net);
+ 	if (nn->lockd_up) {
+ 		lockd_down(net);
+ 		nn->lockd_up = false;
+diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
+index 4f2ffc7ef296f..f31c0389a2e7d 100644
+--- a/fs/ntfs3/file.c
++++ b/fs/ntfs3/file.c
+@@ -486,10 +486,10 @@ static int ntfs_truncate(struct inode *inode, loff_t new_size)
+ 
+ 	new_valid = ntfs_up_block(sb, min_t(u64, ni->i_valid, new_size));
+ 
+-	ni_lock(ni);
+-
+ 	truncate_setsize(inode, new_size);
+ 
++	ni_lock(ni);
++
+ 	down_write(&ni->file.run_lock);
+ 	err = attr_set_size(ni, ATTR_DATA, NULL, 0, &ni->file.run, new_size,
+ 			    &new_valid, ni->mi.sbi->options->prealloc, NULL);
+diff --git a/fs/udf/inode.c b/fs/udf/inode.c
+index b9a83820e1adf..3c380140515da 100644
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -600,7 +600,7 @@ static void udf_do_extend_final_block(struct inode *inode,
+ 	 */
+ 	if (new_elen <= (last_ext->extLength & UDF_EXTENT_LENGTH_MASK))
+ 		return;
+-	added_bytes = (last_ext->extLength & UDF_EXTENT_LENGTH_MASK) - new_elen;
++	added_bytes = new_elen - (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+ 	last_ext->extLength += added_bytes;
+ 	UDF_I(inode)->i_lenExtents += added_bytes;
+ 
+diff --git a/include/linux/dsa/tag_qca.h b/include/linux/dsa/tag_qca.h
+index b1b5720d89a59..ee657452f122a 100644
+--- a/include/linux/dsa/tag_qca.h
++++ b/include/linux/dsa/tag_qca.h
+@@ -45,8 +45,8 @@ struct sk_buff;
+ 					QCA_HDR_MGMT_COMMAND_LEN + \
+ 					QCA_HDR_MGMT_DATA1_LEN)
+ 
+-#define QCA_HDR_MGMT_DATA2_LEN		12 /* Other 12 byte for the mdio data */
+-#define QCA_HDR_MGMT_PADDING_LEN	34 /* Padding to reach the min Ethernet packet */
++#define QCA_HDR_MGMT_DATA2_LEN		28 /* Other 28 byte for the mdio data */
++#define QCA_HDR_MGMT_PADDING_LEN	18 /* Padding to reach the min Ethernet packet */
+ 
+ #define QCA_HDR_MGMT_PKT_LEN		(QCA_HDR_MGMT_HEADER_LEN + \
+ 					QCA_HDR_LEN + \
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index f87b2f5db9f83..4f51616f01b21 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -1139,8 +1139,6 @@ void efi_check_for_embedded_firmwares(void);
+ static inline void efi_check_for_embedded_firmwares(void) { }
+ #endif
+ 
+-efi_status_t efi_random_get_seed(void);
+-
+ #define arch_efi_call_virt(p, f, args...)	((p)->f(args))
+ 
+ /*
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 8e79a761c56c5..17a1a57adbe00 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1170,6 +1170,7 @@ extern int locks_delete_block(struct file_lock *);
+ extern int vfs_test_lock(struct file *, struct file_lock *);
+ extern int vfs_lock_file(struct file *, unsigned int, struct file_lock *, struct file_lock *);
+ extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
++bool vfs_inode_has_locks(struct inode *inode);
+ extern int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl);
+ extern int __break_lease(struct inode *inode, unsigned int flags, unsigned int type);
+ extern void lease_get_mtime(struct inode *, struct timespec64 *time);
+@@ -1284,6 +1285,11 @@ static inline int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
+ 	return 0;
+ }
+ 
++static inline bool vfs_inode_has_locks(struct inode *inode)
++{
++	return false;
++}
++
+ static inline int locks_lock_inode_wait(struct inode *inode, struct file_lock *fl)
+ {
+ 	return -ENOLCK;
+diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
+index b5f58fd37a0f7..4b00221f57e26 100644
+--- a/include/linux/mlx5/device.h
++++ b/include/linux/mlx5/device.h
+@@ -1088,6 +1088,11 @@ enum {
+ 	MLX5_VPORT_ADMIN_STATE_AUTO  = 0x2,
+ };
+ 
++enum {
++	MLX5_VPORT_CVLAN_INSERT_WHEN_NO_CVLAN  = 0x1,
++	MLX5_VPORT_CVLAN_INSERT_ALWAYS         = 0x3,
++};
++
+ enum {
+ 	MLX5_L3_PROT_TYPE_IPV4		= 0,
+ 	MLX5_L3_PROT_TYPE_IPV6		= 1,
+diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
+index 4acd5610e96bc..e640c27b1b6df 100644
+--- a/include/linux/mlx5/mlx5_ifc.h
++++ b/include/linux/mlx5/mlx5_ifc.h
+@@ -877,7 +877,8 @@ struct mlx5_ifc_e_switch_cap_bits {
+ 	u8         vport_svlan_insert[0x1];
+ 	u8         vport_cvlan_insert_if_not_exist[0x1];
+ 	u8         vport_cvlan_insert_overwrite[0x1];
+-	u8         reserved_at_5[0x2];
++	u8         reserved_at_5[0x1];
++	u8         vport_cvlan_insert_always[0x1];
+ 	u8         esw_shared_ingress_acl[0x1];
+ 	u8         esw_uplink_ingress_acl[0x1];
+ 	u8         root_ft_on_other_esw[0x1];
+diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
+index ada1296c87d50..72f5ebc5c97a9 100644
+--- a/include/linux/netfilter/ipset/ip_set.h
++++ b/include/linux/netfilter/ipset/ip_set.h
+@@ -197,7 +197,7 @@ struct ip_set_region {
+ };
+ 
+ /* Max range where every element is added/deleted in one step */
+-#define IPSET_MAX_RANGE		(1<<20)
++#define IPSET_MAX_RANGE		(1<<14)
+ 
+ /* The max revision number supported by any set type + 1 */
+ #define IPSET_REVISION_MAX	9
+diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
+index cd188a527d169..3b35b6f6533aa 100644
+--- a/include/linux/sunrpc/rpc_pipe_fs.h
++++ b/include/linux/sunrpc/rpc_pipe_fs.h
+@@ -92,6 +92,11 @@ extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *,
+ 				       char __user *, size_t);
+ extern int rpc_queue_upcall(struct rpc_pipe *, struct rpc_pipe_msg *);
+ 
++/* returns true if the msg is in-flight, i.e., already eaten by the peer */
++static inline bool rpc_msg_is_inflight(const struct rpc_pipe_msg *msg) {
++	return (msg->copied != 0 && list_empty(&msg->list));
++}
++
+ struct rpc_clnt;
+ extern struct dentry *rpc_create_client_dir(struct dentry *, const char *, struct rpc_clnt *);
+ extern int rpc_remove_client_dir(struct rpc_clnt *);
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index cdb7db9b0e252..1daededfa75ed 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -311,17 +311,29 @@ struct nft_set_iter {
+ /**
+  *	struct nft_set_desc - description of set elements
+  *
++ *	@ktype: key type
+  *	@klen: key length
++ *	@dtype: data type
+  *	@dlen: data length
++ *	@objtype: object type
++ *	@flags: flags
+  *	@size: number of set elements
++ *	@policy: set policy
++ *	@gc_int: garbage collector interval
+  *	@field_len: length of each field in concatenation, bytes
+  *	@field_count: number of concatenated fields in element
+  *	@expr: set must support for expressions
+  */
+ struct nft_set_desc {
++	u32			ktype;
+ 	unsigned int		klen;
++	u32			dtype;
+ 	unsigned int		dlen;
++	u32			objtype;
+ 	unsigned int		size;
++	u32			policy;
++	u32			gc_int;
++	u64			timeout;
+ 	u8			field_len[NFT_REG32_COUNT];
+ 	u8			field_count;
+ 	bool			expr;
+@@ -580,7 +592,9 @@ void *nft_set_catchall_gc(const struct nft_set *set);
+ 
+ static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
+ {
+-	return set->gc_int ? msecs_to_jiffies(set->gc_int) : HZ;
++	u32 gc_int = READ_ONCE(set->gc_int);
++
++	return gc_int ? msecs_to_jiffies(gc_int) : HZ;
+ }
+ 
+ /**
+@@ -1551,6 +1565,9 @@ struct nft_trans_rule {
+ struct nft_trans_set {
+ 	struct nft_set			*set;
+ 	u32				set_id;
++	u32				gc_int;
++	u64				timeout;
++	bool				update;
+ 	bool				bound;
+ };
+ 
+@@ -1560,6 +1577,12 @@ struct nft_trans_set {
+ 	(((struct nft_trans_set *)trans->data)->set_id)
+ #define nft_trans_set_bound(trans)	\
+ 	(((struct nft_trans_set *)trans->data)->bound)
++#define nft_trans_set_update(trans)	\
++	(((struct nft_trans_set *)trans->data)->update)
++#define nft_trans_set_timeout(trans)	\
++	(((struct nft_trans_set *)trans->data)->timeout)
++#define nft_trans_set_gc_int(trans)	\
++	(((struct nft_trans_set *)trans->data)->gc_int)
+ 
+ struct nft_trans_chain {
+ 	bool				update;
+diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
+index 7ada84e4a3ed1..5655e89b962be 100644
+--- a/include/uapi/linux/btrfs.h
++++ b/include/uapi/linux/btrfs.h
+@@ -290,6 +290,12 @@ struct btrfs_ioctl_fs_info_args {
+ #define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID	(1ULL << 1)
+ #define BTRFS_FEATURE_COMPAT_RO_VERITY			(1ULL << 2)
+ 
++/*
++ * Put all block group items into a dedicated block group tree, greatly
++ * reducing mount time for large filesystem due to better locality.
++ */
++#define BTRFS_FEATURE_COMPAT_RO_BLOCK_GROUP_TREE	(1ULL << 3)
++
+ #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF	(1ULL << 0)
+ #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL	(1ULL << 1)
+ #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS	(1ULL << 2)
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index b8a39be3bcb4c..9c49a1a4cedaa 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -2206,7 +2206,7 @@ int io_run_task_work_sig(void)
+ /* when returns >0, the caller should retry */
+ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
+ 					  struct io_wait_queue *iowq,
+-					  ktime_t timeout)
++					  ktime_t *timeout)
+ {
+ 	int ret;
+ 	unsigned long check_cq;
+@@ -2224,7 +2224,7 @@ static inline int io_cqring_wait_schedule(struct io_ring_ctx *ctx,
+ 		if (check_cq & BIT(IO_CHECK_CQ_DROPPED_BIT))
+ 			return -EBADR;
+ 	}
+-	if (!schedule_hrtimeout(&timeout, HRTIMER_MODE_ABS))
++	if (!schedule_hrtimeout(timeout, HRTIMER_MODE_ABS))
+ 		return -ETIME;
+ 	return 1;
+ }
+@@ -2289,7 +2289,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
+ 		}
+ 		prepare_to_wait_exclusive(&ctx->cq_wait, &iowq.wq,
+ 						TASK_INTERRUPTIBLE);
+-		ret = io_cqring_wait_schedule(ctx, &iowq, timeout);
++		ret = io_cqring_wait_schedule(ctx, &iowq, &timeout);
+ 		cond_resched();
+ 	} while (ret > 0);
+ 
+@@ -3725,8 +3725,6 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
+ 		return -EEXIST;
+ 
+ 	if (ctx->restricted) {
+-		if (opcode >= IORING_REGISTER_LAST)
+-			return -EINVAL;
+ 		opcode = array_index_nospec(opcode, IORING_REGISTER_LAST);
+ 		if (!test_bit(opcode, ctx->restrictions.register_op))
+ 			return -EACCES;
+@@ -3882,6 +3880,9 @@ SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode,
+ 	long ret = -EBADF;
+ 	struct fd f;
+ 
++	if (opcode >= IORING_REGISTER_LAST)
++		return -EINVAL;
++
+ 	f = fdget(fd);
+ 	if (!f.file)
+ 		return -EBADF;
+diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
+index 41b67eb83ab3f..2fb6d8e196e69 100644
+--- a/kernel/bpf/trampoline.c
++++ b/kernel/bpf/trampoline.c
+@@ -501,6 +501,10 @@ again:
+ 		/* reset fops->func and fops->trampoline for re-register */
+ 		tr->fops->func = NULL;
+ 		tr->fops->trampoline = 0;
++
++		/* reset im->image memory attr for arch_prepare_bpf_trampoline */
++		set_memory_nx((long)im->image, 1);
++		set_memory_rw((long)im->image, 1);
+ 		goto again;
+ 	}
+ #endif
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 8464d95805d08..1f50dce8765d5 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -425,7 +425,7 @@ void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
+ 	 * the status change is visible to another thread
+ 	 */
+ 	smp_wmb();
+-	req->status = status;
++	WRITE_ONCE(req->status, status);
+ 
+ 	wake_up(&req->wq);
+ 	p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc.tag);
+@@ -587,7 +587,7 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
+ 	/* if we haven't received a response for oldreq,
+ 	 * remove it from the list
+ 	 */
+-	if (oldreq->status == REQ_STATUS_SENT) {
++	if (READ_ONCE(oldreq->status) == REQ_STATUS_SENT) {
+ 		if (c->trans_mod->cancelled)
+ 			c->trans_mod->cancelled(c, oldreq);
+ 	}
+@@ -672,7 +672,8 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
+ 	}
+ again:
+ 	/* Wait for the response */
+-	err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD);
++	err = wait_event_killable(req->wq,
++				  READ_ONCE(req->status) >= REQ_STATUS_RCVD);
+ 
+ 	/* Make sure our req is coherent with regard to updates in other
+ 	 * threads - echoes to wmb() in the callback
+@@ -686,7 +687,7 @@ again:
+ 		goto again;
+ 	}
+ 
+-	if (req->status == REQ_STATUS_ERROR) {
++	if (READ_ONCE(req->status) == REQ_STATUS_ERROR) {
+ 		p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
+ 		err = req->t_err;
+ 	}
+@@ -699,7 +700,7 @@ again:
+ 			p9_client_flush(c, req);
+ 
+ 		/* if we received the response anyway, don't signal error */
+-		if (req->status == REQ_STATUS_RCVD)
++		if (READ_ONCE(req->status) == REQ_STATUS_RCVD)
+ 			err = 0;
+ 	}
+ recalc_sigpending:
+@@ -768,7 +769,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
+ 		if (err != -ERESTARTSYS)
+ 			goto recalc_sigpending;
+ 	}
+-	if (req->status == REQ_STATUS_ERROR) {
++	if (READ_ONCE(req->status) == REQ_STATUS_ERROR) {
+ 		p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
+ 		err = req->t_err;
+ 	}
+@@ -781,7 +782,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
+ 			p9_client_flush(c, req);
+ 
+ 		/* if we received the response anyway, don't signal error */
+-		if (req->status == REQ_STATUS_RCVD)
++		if (READ_ONCE(req->status) == REQ_STATUS_RCVD)
+ 			err = 0;
+ 	}
+ recalc_sigpending:
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index 080b5de3e1ed8..a2eb1363d293b 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -202,11 +202,11 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
+ 
+ 	list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
+ 		list_move(&req->req_list, &cancel_list);
+-		req->status = REQ_STATUS_ERROR;
++		WRITE_ONCE(req->status, REQ_STATUS_ERROR);
+ 	}
+ 	list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
+ 		list_move(&req->req_list, &cancel_list);
+-		req->status = REQ_STATUS_ERROR;
++		WRITE_ONCE(req->status, REQ_STATUS_ERROR);
+ 	}
+ 
+ 	spin_unlock(&m->req_lock);
+@@ -467,7 +467,7 @@ static void p9_write_work(struct work_struct *work)
+ 
+ 		req = list_entry(m->unsent_req_list.next, struct p9_req_t,
+ 			       req_list);
+-		req->status = REQ_STATUS_SENT;
++		WRITE_ONCE(req->status, REQ_STATUS_SENT);
+ 		p9_debug(P9_DEBUG_TRANS, "move req %p\n", req);
+ 		list_move_tail(&req->req_list, &m->req_list);
+ 
+@@ -676,7 +676,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
+ 		return m->err;
+ 
+ 	spin_lock(&m->req_lock);
+-	req->status = REQ_STATUS_UNSENT;
++	WRITE_ONCE(req->status, REQ_STATUS_UNSENT);
+ 	list_add_tail(&req->req_list, &m->unsent_req_list);
+ 	spin_unlock(&m->req_lock);
+ 
+@@ -703,7 +703,7 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
+ 
+ 	if (req->status == REQ_STATUS_UNSENT) {
+ 		list_del(&req->req_list);
+-		req->status = REQ_STATUS_FLSHD;
++		WRITE_ONCE(req->status, REQ_STATUS_FLSHD);
+ 		p9_req_put(client, req);
+ 		ret = 0;
+ 	}
+@@ -732,7 +732,7 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
+ 	 * remove it from the list.
+ 	 */
+ 	list_del(&req->req_list);
+-	req->status = REQ_STATUS_FLSHD;
++	WRITE_ONCE(req->status, REQ_STATUS_FLSHD);
+ 	spin_unlock(&m->req_lock);
+ 
+ 	p9_req_put(client, req);
+diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
+index d817d3745238b..d8b0a6f3b15e5 100644
+--- a/net/9p/trans_rdma.c
++++ b/net/9p/trans_rdma.c
+@@ -507,7 +507,7 @@ dont_need_post_recv:
+ 	 * because doing if after could erase the REQ_STATUS_RCVD
+ 	 * status in case of a very fast reply.
+ 	 */
+-	req->status = REQ_STATUS_SENT;
++	WRITE_ONCE(req->status, REQ_STATUS_SENT);
+ 	err = ib_post_send(rdma->qp, &wr, NULL);
+ 	if (err)
+ 		goto send_error;
+@@ -517,7 +517,7 @@ dont_need_post_recv:
+ 
+  /* Handle errors that happened during or while preparing the send: */
+  send_error:
+-	req->status = REQ_STATUS_ERROR;
++	WRITE_ONCE(req->status, REQ_STATUS_ERROR);
+ 	kfree(c);
+ 	p9_debug(P9_DEBUG_ERROR, "Error %d in rdma_request()\n", err);
+ 
+diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
+index b84d35cf68994..947c038a0470c 100644
+--- a/net/9p/trans_virtio.c
++++ b/net/9p/trans_virtio.c
+@@ -263,7 +263,7 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
+ 
+ 	p9_debug(P9_DEBUG_TRANS, "9p debug: virtio request\n");
+ 
+-	req->status = REQ_STATUS_SENT;
++	WRITE_ONCE(req->status, REQ_STATUS_SENT);
+ req_retry:
+ 	spin_lock_irqsave(&chan->lock, flags);
+ 
+@@ -469,7 +469,7 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
+ 			inlen = n;
+ 		}
+ 	}
+-	req->status = REQ_STATUS_SENT;
++	WRITE_ONCE(req->status, REQ_STATUS_SENT);
+ req_retry_pinned:
+ 	spin_lock_irqsave(&chan->lock, flags);
+ 
+@@ -532,9 +532,10 @@ req_retry_pinned:
+ 	spin_unlock_irqrestore(&chan->lock, flags);
+ 	kicked = 1;
+ 	p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
+-	err = wait_event_killable(req->wq, req->status >= REQ_STATUS_RCVD);
++	err = wait_event_killable(req->wq,
++			          READ_ONCE(req->status) >= REQ_STATUS_RCVD);
+ 	// RERROR needs reply (== error string) in static data
+-	if (req->status == REQ_STATUS_RCVD &&
++	if (READ_ONCE(req->status) == REQ_STATUS_RCVD &&
+ 	    unlikely(req->rc.sdata[4] == P9_RERROR))
+ 		handle_rerror(req, in_hdr_len, offs, in_pages);
+ 
+diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
+index 0f862d5a59601..a103aed854658 100644
+--- a/net/9p/trans_xen.c
++++ b/net/9p/trans_xen.c
+@@ -157,7 +157,7 @@ again:
+ 			      &masked_prod, masked_cons,
+ 			      XEN_9PFS_RING_SIZE(ring));
+ 
+-	p9_req->status = REQ_STATUS_SENT;
++	WRITE_ONCE(p9_req->status, REQ_STATUS_SENT);
+ 	virt_wmb();			/* write ring before updating pointer */
+ 	prod += size;
+ 	ring->intf->out_prod = prod;
+@@ -212,7 +212,7 @@ static void p9_xen_response(struct work_struct *work)
+ 			dev_warn(&priv->dev->dev,
+ 				 "requested packet size too big: %d for tag %d with capacity %zd\n",
+ 				 h.size, h.tag, req->rc.capacity);
+-			req->status = REQ_STATUS_ERROR;
++			WRITE_ONCE(req->status, REQ_STATUS_ERROR);
+ 			goto recv_error;
+ 		}
+ 
+diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c
+index 2809cbd6b7f74..d8cb4b2a076b4 100644
+--- a/net/caif/cfctrl.c
++++ b/net/caif/cfctrl.c
+@@ -269,11 +269,15 @@ int cfctrl_linkup_request(struct cflayer *layer,
+ 	default:
+ 		pr_warn("Request setup of bad link type = %d\n",
+ 			param->linktype);
++		cfpkt_destroy(pkt);
+ 		return -EINVAL;
+ 	}
+ 	req = kzalloc(sizeof(*req), GFP_KERNEL);
+-	if (!req)
++	if (!req) {
++		cfpkt_destroy(pkt);
+ 		return -ENOMEM;
++	}
++
+ 	req->client_layer = user_layer;
+ 	req->cmd = CFCTRL_CMD_LINK_SETUP;
+ 	req->param = *param;
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 3aae1885b9702..50d685be517d5 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -3182,15 +3182,18 @@ static int bpf_skb_generic_push(struct sk_buff *skb, u32 off, u32 len)
+ 
+ static int bpf_skb_generic_pop(struct sk_buff *skb, u32 off, u32 len)
+ {
++	void *old_data;
++
+ 	/* skb_ensure_writable() is not needed here, as we're
+ 	 * already working on an uncloned skb.
+ 	 */
+ 	if (unlikely(!pskb_may_pull(skb, off + len)))
+ 		return -ENOMEM;
+ 
+-	skb_postpull_rcsum(skb, skb->data + off, len);
+-	memmove(skb->data + len, skb->data, off);
++	old_data = skb->data;
+ 	__skb_pull(skb, len);
++	skb_postpull_rcsum(skb, old_data + off, len);
++	memmove(skb->data, old_data, off);
+ 
+ 	return 0;
+ }
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index 971969cc7e17f..fb01211a255b0 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -1037,12 +1037,26 @@ void inet_csk_prepare_forced_close(struct sock *sk)
+ }
+ EXPORT_SYMBOL(inet_csk_prepare_forced_close);
+ 
++static int inet_ulp_can_listen(const struct sock *sk)
++{
++	const struct inet_connection_sock *icsk = inet_csk(sk);
++
++	if (icsk->icsk_ulp_ops && !icsk->icsk_ulp_ops->clone)
++		return -EINVAL;
++
++	return 0;
++}
++
+ int inet_csk_listen_start(struct sock *sk)
+ {
+ 	struct inet_connection_sock *icsk = inet_csk(sk);
+ 	struct inet_sock *inet = inet_sk(sk);
+ 	int err;
+ 
++	err = inet_ulp_can_listen(sk);
++	if (unlikely(err))
++		return err;
++
+ 	reqsk_queue_alloc(&icsk->icsk_accept_queue);
+ 
+ 	sk->sk_ack_backlog = 0;
+diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c
+index 9ae50b1bd8444..05b6077b9f2c3 100644
+--- a/net/ipv4/tcp_ulp.c
++++ b/net/ipv4/tcp_ulp.c
+@@ -139,6 +139,10 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
+ 	if (sk->sk_socket)
+ 		clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
+ 
++	err = -EINVAL;
++	if (!ulp_ops->clone && sk->sk_state == TCP_LISTEN)
++		goto out_err;
++
+ 	err = ulp_ops->init(sk);
+ 	if (err)
+ 		goto out_err;
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index 42d5e0a7952ae..a2cc25cca33e1 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2310,7 +2310,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+ 		/* otherwise tcp will dispose of the ssk and subflow ctx */
+ 		if (ssk->sk_state == TCP_LISTEN) {
+ 			tcp_set_state(ssk, TCP_CLOSE);
+-			mptcp_subflow_queue_clean(ssk);
++			mptcp_subflow_queue_clean(sk, ssk);
+ 			inet_csk_listen_stop(ssk);
+ 		}
+ 		__tcp_close(ssk, 0);
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index c1eaa16855921..df6937c8cf544 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -610,7 +610,7 @@ void mptcp_close_ssk(struct sock *sk, struct sock *ssk,
+ 		     struct mptcp_subflow_context *subflow);
+ void __mptcp_subflow_send_ack(struct sock *ssk);
+ void mptcp_subflow_reset(struct sock *ssk);
+-void mptcp_subflow_queue_clean(struct sock *ssk);
++void mptcp_subflow_queue_clean(struct sock *sk, struct sock *ssk);
+ void mptcp_sock_graft(struct sock *sk, struct socket *parent);
+ struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);
+ bool __mptcp_close(struct sock *sk, long timeout);
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 613f515fedf0a..9d3701fdb2937 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -1733,7 +1733,7 @@ static void subflow_state_change(struct sock *sk)
+ 	}
+ }
+ 
+-void mptcp_subflow_queue_clean(struct sock *listener_ssk)
++void mptcp_subflow_queue_clean(struct sock *listener_sk, struct sock *listener_ssk)
+ {
+ 	struct request_sock_queue *queue = &inet_csk(listener_ssk)->icsk_accept_queue;
+ 	struct mptcp_sock *msk, *next, *head = NULL;
+@@ -1782,8 +1782,23 @@ void mptcp_subflow_queue_clean(struct sock *listener_ssk)
+ 
+ 		do_cancel_work = __mptcp_close(sk, 0);
+ 		release_sock(sk);
+-		if (do_cancel_work)
++		if (do_cancel_work) {
++			/* lockdep will report a false positive ABBA deadlock
++			 * between cancel_work_sync and the listener socket.
++			 * The involved locks belong to different sockets WRT
++			 * the existing AB chain.
++			 * Using a per socket key is problematic as key
++			 * deregistration requires process context and must be
++			 * performed at socket disposal time, in atomic
++			 * context.
++			 * Just tell lockdep to consider the listener socket
++			 * released here.
++			 */
++			mutex_release(&listener_sk->sk_lock.dep_map, _RET_IP_);
+ 			mptcp_cancel_work(sk);
++			mutex_acquire(&listener_sk->sk_lock.dep_map,
++				      SINGLE_DEPTH_NESTING, 0, _RET_IP_);
++		}
+ 		sock_put(sk);
+ 	}
+ 
+diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
+index 6b31746f9be3b..751ac89b07a56 100644
+--- a/net/netfilter/ipset/ip_set_core.c
++++ b/net/netfilter/ipset/ip_set_core.c
+@@ -1698,9 +1698,10 @@ call_ad(struct net *net, struct sock *ctnl, struct sk_buff *skb,
+ 		ret = set->variant->uadt(set, tb, adt, &lineno, flags, retried);
+ 		ip_set_unlock(set);
+ 		retried = true;
+-	} while (ret == -EAGAIN &&
+-		 set->variant->resize &&
+-		 (ret = set->variant->resize(set, retried)) == 0);
++	} while (ret == -ERANGE ||
++		 (ret == -EAGAIN &&
++		  set->variant->resize &&
++		  (ret = set->variant->resize(set, retried)) == 0));
+ 
+ 	if (!ret || (ret == -IPSET_ERR_EXIST && eexist))
+ 		return 0;
+diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
+index 75d556d71652d..24adcdd7a0b16 100644
+--- a/net/netfilter/ipset/ip_set_hash_ip.c
++++ b/net/netfilter/ipset/ip_set_hash_ip.c
+@@ -98,11 +98,11 @@ static int
+ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 	      enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+-	const struct hash_ip4 *h = set->data;
++	struct hash_ip4 *h = set->data;
+ 	ipset_adtfn adtfn = set->variant->adt[adt];
+ 	struct hash_ip4_elem e = { 0 };
+ 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+-	u32 ip = 0, ip_to = 0, hosts;
++	u32 ip = 0, ip_to = 0, hosts, i = 0;
+ 	int ret = 0;
+ 
+ 	if (tb[IPSET_ATTR_LINENO])
+@@ -147,14 +147,14 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 
+ 	hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1);
+ 
+-	/* 64bit division is not allowed on 32bit */
+-	if (((u64)ip_to - ip + 1) >> (32 - h->netmask) > IPSET_MAX_RANGE)
+-		return -ERANGE;
+-
+ 	if (retried)
+ 		ip = ntohl(h->next.ip);
+-	for (; ip <= ip_to;) {
++	for (; ip <= ip_to; i++) {
+ 		e.ip = htonl(ip);
++		if (i > IPSET_MAX_RANGE) {
++			hash_ip4_data_next(&h->next, &e);
++			return -ERANGE;
++		}
+ 		ret = adtfn(set, &e, &ext, &ext, flags);
+ 		if (ret && !ip_set_eexist(ret, flags))
+ 			return ret;
+diff --git a/net/netfilter/ipset/ip_set_hash_ipmark.c b/net/netfilter/ipset/ip_set_hash_ipmark.c
+index 153de3457423e..a22ec1a6f6ec8 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipmark.c
++++ b/net/netfilter/ipset/ip_set_hash_ipmark.c
+@@ -97,11 +97,11 @@ static int
+ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 		  enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+-	const struct hash_ipmark4 *h = set->data;
++	struct hash_ipmark4 *h = set->data;
+ 	ipset_adtfn adtfn = set->variant->adt[adt];
+ 	struct hash_ipmark4_elem e = { };
+ 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+-	u32 ip, ip_to = 0;
++	u32 ip, ip_to = 0, i = 0;
+ 	int ret;
+ 
+ 	if (tb[IPSET_ATTR_LINENO])
+@@ -148,13 +148,14 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 		ip_set_mask_from_to(ip, ip_to, cidr);
+ 	}
+ 
+-	if (((u64)ip_to - ip + 1) > IPSET_MAX_RANGE)
+-		return -ERANGE;
+-
+ 	if (retried)
+ 		ip = ntohl(h->next.ip);
+-	for (; ip <= ip_to; ip++) {
++	for (; ip <= ip_to; ip++, i++) {
+ 		e.ip = htonl(ip);
++		if (i > IPSET_MAX_RANGE) {
++			hash_ipmark4_data_next(&h->next, &e);
++			return -ERANGE;
++		}
+ 		ret = adtfn(set, &e, &ext, &ext, flags);
+ 
+ 		if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
+index 7303138e46be1..10481760a9b25 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipport.c
++++ b/net/netfilter/ipset/ip_set_hash_ipport.c
+@@ -105,11 +105,11 @@ static int
+ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 		  enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+-	const struct hash_ipport4 *h = set->data;
++	struct hash_ipport4 *h = set->data;
+ 	ipset_adtfn adtfn = set->variant->adt[adt];
+ 	struct hash_ipport4_elem e = { .ip = 0 };
+ 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+-	u32 ip, ip_to = 0, p = 0, port, port_to;
++	u32 ip, ip_to = 0, p = 0, port, port_to, i = 0;
+ 	bool with_ports = false;
+ 	int ret;
+ 
+@@ -173,17 +173,18 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 			swap(port, port_to);
+ 	}
+ 
+-	if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
+-		return -ERANGE;
+-
+ 	if (retried)
+ 		ip = ntohl(h->next.ip);
+ 	for (; ip <= ip_to; ip++) {
+ 		p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
+ 						       : port;
+-		for (; p <= port_to; p++) {
++		for (; p <= port_to; p++, i++) {
+ 			e.ip = htonl(ip);
+ 			e.port = htons(p);
++			if (i > IPSET_MAX_RANGE) {
++				hash_ipport4_data_next(&h->next, &e);
++				return -ERANGE;
++			}
+ 			ret = adtfn(set, &e, &ext, &ext, flags);
+ 
+ 			if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
+index 334fb1ad0e86c..39a01934b1536 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
++++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
+@@ -108,11 +108,11 @@ static int
+ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 		    enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+-	const struct hash_ipportip4 *h = set->data;
++	struct hash_ipportip4 *h = set->data;
+ 	ipset_adtfn adtfn = set->variant->adt[adt];
+ 	struct hash_ipportip4_elem e = { .ip = 0 };
+ 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+-	u32 ip, ip_to = 0, p = 0, port, port_to;
++	u32 ip, ip_to = 0, p = 0, port, port_to, i = 0;
+ 	bool with_ports = false;
+ 	int ret;
+ 
+@@ -180,17 +180,18 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 			swap(port, port_to);
+ 	}
+ 
+-	if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
+-		return -ERANGE;
+-
+ 	if (retried)
+ 		ip = ntohl(h->next.ip);
+ 	for (; ip <= ip_to; ip++) {
+ 		p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
+ 						       : port;
+-		for (; p <= port_to; p++) {
++		for (; p <= port_to; p++, i++) {
+ 			e.ip = htonl(ip);
+ 			e.port = htons(p);
++			if (i > IPSET_MAX_RANGE) {
++				hash_ipportip4_data_next(&h->next, &e);
++				return -ERANGE;
++			}
+ 			ret = adtfn(set, &e, &ext, &ext, flags);
+ 
+ 			if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
+index 7df94f437f600..5c6de605a9fb7 100644
+--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
++++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
+@@ -160,12 +160,12 @@ static int
+ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 		     enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+-	const struct hash_ipportnet4 *h = set->data;
++	struct hash_ipportnet4 *h = set->data;
+ 	ipset_adtfn adtfn = set->variant->adt[adt];
+ 	struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 };
+ 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ 	u32 ip = 0, ip_to = 0, p = 0, port, port_to;
+-	u32 ip2_from = 0, ip2_to = 0, ip2;
++	u32 ip2_from = 0, ip2_to = 0, ip2, i = 0;
+ 	bool with_ports = false;
+ 	u8 cidr;
+ 	int ret;
+@@ -253,9 +253,6 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 			swap(port, port_to);
+ 	}
+ 
+-	if (((u64)ip_to - ip + 1)*(port_to - port + 1) > IPSET_MAX_RANGE)
+-		return -ERANGE;
+-
+ 	ip2_to = ip2_from;
+ 	if (tb[IPSET_ATTR_IP2_TO]) {
+ 		ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP2_TO], &ip2_to);
+@@ -282,9 +279,15 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 		for (; p <= port_to; p++) {
+ 			e.port = htons(p);
+ 			do {
++				i++;
+ 				e.ip2 = htonl(ip2);
+ 				ip2 = ip_set_range_to_cidr(ip2, ip2_to, &cidr);
+ 				e.cidr = cidr - 1;
++				if (i > IPSET_MAX_RANGE) {
++					hash_ipportnet4_data_next(&h->next,
++								  &e);
++					return -ERANGE;
++				}
+ 				ret = adtfn(set, &e, &ext, &ext, flags);
+ 
+ 				if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c
+index 1422739d9aa25..ce0a9ce5a91f1 100644
+--- a/net/netfilter/ipset/ip_set_hash_net.c
++++ b/net/netfilter/ipset/ip_set_hash_net.c
+@@ -136,11 +136,11 @@ static int
+ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 	       enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+-	const struct hash_net4 *h = set->data;
++	struct hash_net4 *h = set->data;
+ 	ipset_adtfn adtfn = set->variant->adt[adt];
+ 	struct hash_net4_elem e = { .cidr = HOST_MASK };
+ 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+-	u32 ip = 0, ip_to = 0, ipn, n = 0;
++	u32 ip = 0, ip_to = 0, i = 0;
+ 	int ret;
+ 
+ 	if (tb[IPSET_ATTR_LINENO])
+@@ -188,19 +188,16 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 		if (ip + UINT_MAX == ip_to)
+ 			return -IPSET_ERR_HASH_RANGE;
+ 	}
+-	ipn = ip;
+-	do {
+-		ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr);
+-		n++;
+-	} while (ipn++ < ip_to);
+-
+-	if (n > IPSET_MAX_RANGE)
+-		return -ERANGE;
+ 
+ 	if (retried)
+ 		ip = ntohl(h->next.ip);
+ 	do {
++		i++;
+ 		e.ip = htonl(ip);
++		if (i > IPSET_MAX_RANGE) {
++			hash_net4_data_next(&h->next, &e);
++			return -ERANGE;
++		}
+ 		ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
+ 		ret = adtfn(set, &e, &ext, &ext, flags);
+ 		if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
+index 9810f5bf63f5e..0310732862362 100644
+--- a/net/netfilter/ipset/ip_set_hash_netiface.c
++++ b/net/netfilter/ipset/ip_set_hash_netiface.c
+@@ -202,7 +202,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 	ipset_adtfn adtfn = set->variant->adt[adt];
+ 	struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 };
+ 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+-	u32 ip = 0, ip_to = 0, ipn, n = 0;
++	u32 ip = 0, ip_to = 0, i = 0;
+ 	int ret;
+ 
+ 	if (tb[IPSET_ATTR_LINENO])
+@@ -256,19 +256,16 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 	} else {
+ 		ip_set_mask_from_to(ip, ip_to, e.cidr);
+ 	}
+-	ipn = ip;
+-	do {
+-		ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr);
+-		n++;
+-	} while (ipn++ < ip_to);
+-
+-	if (n > IPSET_MAX_RANGE)
+-		return -ERANGE;
+ 
+ 	if (retried)
+ 		ip = ntohl(h->next.ip);
+ 	do {
++		i++;
+ 		e.ip = htonl(ip);
++		if (i > IPSET_MAX_RANGE) {
++			hash_netiface4_data_next(&h->next, &e);
++			return -ERANGE;
++		}
+ 		ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
+ 		ret = adtfn(set, &e, &ext, &ext, flags);
+ 
+diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
+index 3d09eefe998a7..c07b70bf32db4 100644
+--- a/net/netfilter/ipset/ip_set_hash_netnet.c
++++ b/net/netfilter/ipset/ip_set_hash_netnet.c
+@@ -163,13 +163,12 @@ static int
+ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 		  enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+-	const struct hash_netnet4 *h = set->data;
++	struct hash_netnet4 *h = set->data;
+ 	ipset_adtfn adtfn = set->variant->adt[adt];
+ 	struct hash_netnet4_elem e = { };
+ 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ 	u32 ip = 0, ip_to = 0;
+-	u32 ip2 = 0, ip2_from = 0, ip2_to = 0, ipn;
+-	u64 n = 0, m = 0;
++	u32 ip2 = 0, ip2_from = 0, ip2_to = 0, i = 0;
+ 	int ret;
+ 
+ 	if (tb[IPSET_ATTR_LINENO])
+@@ -245,19 +244,6 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 	} else {
+ 		ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
+ 	}
+-	ipn = ip;
+-	do {
+-		ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr[0]);
+-		n++;
+-	} while (ipn++ < ip_to);
+-	ipn = ip2_from;
+-	do {
+-		ipn = ip_set_range_to_cidr(ipn, ip2_to, &e.cidr[1]);
+-		m++;
+-	} while (ipn++ < ip2_to);
+-
+-	if (n*m > IPSET_MAX_RANGE)
+-		return -ERANGE;
+ 
+ 	if (retried) {
+ 		ip = ntohl(h->next.ip[0]);
+@@ -270,7 +256,12 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 		e.ip[0] = htonl(ip);
+ 		ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]);
+ 		do {
++			i++;
+ 			e.ip[1] = htonl(ip2);
++			if (i > IPSET_MAX_RANGE) {
++				hash_netnet4_data_next(&h->next, &e);
++				return -ERANGE;
++			}
+ 			ip2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]);
+ 			ret = adtfn(set, &e, &ext, &ext, flags);
+ 			if (ret && !ip_set_eexist(ret, flags))
+diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
+index 09cf72eb37f8d..d1a0628df4ef3 100644
+--- a/net/netfilter/ipset/ip_set_hash_netport.c
++++ b/net/netfilter/ipset/ip_set_hash_netport.c
+@@ -154,12 +154,11 @@ static int
+ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 		   enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+-	const struct hash_netport4 *h = set->data;
++	struct hash_netport4 *h = set->data;
+ 	ipset_adtfn adtfn = set->variant->adt[adt];
+ 	struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 };
+ 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+-	u32 port, port_to, p = 0, ip = 0, ip_to = 0, ipn;
+-	u64 n = 0;
++	u32 port, port_to, p = 0, ip = 0, ip_to = 0, i = 0;
+ 	bool with_ports = false;
+ 	u8 cidr;
+ 	int ret;
+@@ -236,14 +235,6 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 	} else {
+ 		ip_set_mask_from_to(ip, ip_to, e.cidr + 1);
+ 	}
+-	ipn = ip;
+-	do {
+-		ipn = ip_set_range_to_cidr(ipn, ip_to, &cidr);
+-		n++;
+-	} while (ipn++ < ip_to);
+-
+-	if (n*(port_to - port + 1) > IPSET_MAX_RANGE)
+-		return -ERANGE;
+ 
+ 	if (retried) {
+ 		ip = ntohl(h->next.ip);
+@@ -255,8 +246,12 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 		e.ip = htonl(ip);
+ 		ip = ip_set_range_to_cidr(ip, ip_to, &cidr);
+ 		e.cidr = cidr - 1;
+-		for (; p <= port_to; p++) {
++		for (; p <= port_to; p++, i++) {
+ 			e.port = htons(p);
++			if (i > IPSET_MAX_RANGE) {
++				hash_netport4_data_next(&h->next, &e);
++				return -ERANGE;
++			}
+ 			ret = adtfn(set, &e, &ext, &ext, flags);
+ 			if (ret && !ip_set_eexist(ret, flags))
+ 				return ret;
+diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
+index 19bcdb3141f6e..005a7ce87217e 100644
+--- a/net/netfilter/ipset/ip_set_hash_netportnet.c
++++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
+@@ -173,17 +173,26 @@ hash_netportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
+ 	return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
+ }
+ 
++static u32
++hash_netportnet4_range_to_cidr(u32 from, u32 to, u8 *cidr)
++{
++	if (from == 0 && to == UINT_MAX) {
++		*cidr = 0;
++		return to;
++	}
++	return ip_set_range_to_cidr(from, to, cidr);
++}
++
+ static int
+ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 		      enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+-	const struct hash_netportnet4 *h = set->data;
++	struct hash_netportnet4 *h = set->data;
+ 	ipset_adtfn adtfn = set->variant->adt[adt];
+ 	struct hash_netportnet4_elem e = { };
+ 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ 	u32 ip = 0, ip_to = 0, p = 0, port, port_to;
+-	u32 ip2_from = 0, ip2_to = 0, ip2, ipn;
+-	u64 n = 0, m = 0;
++	u32 ip2_from = 0, ip2_to = 0, ip2, i = 0;
+ 	bool with_ports = false;
+ 	int ret;
+ 
+@@ -285,19 +294,6 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 	} else {
+ 		ip_set_mask_from_to(ip2_from, ip2_to, e.cidr[1]);
+ 	}
+-	ipn = ip;
+-	do {
+-		ipn = ip_set_range_to_cidr(ipn, ip_to, &e.cidr[0]);
+-		n++;
+-	} while (ipn++ < ip_to);
+-	ipn = ip2_from;
+-	do {
+-		ipn = ip_set_range_to_cidr(ipn, ip2_to, &e.cidr[1]);
+-		m++;
+-	} while (ipn++ < ip2_to);
+-
+-	if (n*m*(port_to - port + 1) > IPSET_MAX_RANGE)
+-		return -ERANGE;
+ 
+ 	if (retried) {
+ 		ip = ntohl(h->next.ip[0]);
+@@ -310,13 +306,19 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 
+ 	do {
+ 		e.ip[0] = htonl(ip);
+-		ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]);
++		ip = hash_netportnet4_range_to_cidr(ip, ip_to, &e.cidr[0]);
+ 		for (; p <= port_to; p++) {
+ 			e.port = htons(p);
+ 			do {
++				i++;
+ 				e.ip[1] = htonl(ip2);
+-				ip2 = ip_set_range_to_cidr(ip2, ip2_to,
+-							   &e.cidr[1]);
++				if (i > IPSET_MAX_RANGE) {
++					hash_netportnet4_data_next(&h->next,
++								   &e);
++					return -ERANGE;
++				}
++				ip2 = hash_netportnet4_range_to_cidr(ip2,
++							ip2_to, &e.cidr[1]);
+ 				ret = adtfn(set, &e, &ext, &ext, flags);
+ 				if (ret && !ip_set_eexist(ret, flags))
+ 					return ret;
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 7977f0422ecf6..e0c156bb0b172 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -465,8 +465,9 @@ static int nft_delrule_by_chain(struct nft_ctx *ctx)
+ 	return 0;
+ }
+ 
+-static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
+-			     struct nft_set *set)
++static int __nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
++			       struct nft_set *set,
++			       const struct nft_set_desc *desc)
+ {
+ 	struct nft_trans *trans;
+ 
+@@ -474,17 +475,28 @@ static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
+ 	if (trans == NULL)
+ 		return -ENOMEM;
+ 
+-	if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
++	if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] && !desc) {
+ 		nft_trans_set_id(trans) =
+ 			ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
+ 		nft_activate_next(ctx->net, set);
+ 	}
+ 	nft_trans_set(trans) = set;
++	if (desc) {
++		nft_trans_set_update(trans) = true;
++		nft_trans_set_gc_int(trans) = desc->gc_int;
++		nft_trans_set_timeout(trans) = desc->timeout;
++	}
+ 	nft_trans_commit_list_add_tail(ctx->net, trans);
+ 
+ 	return 0;
+ }
+ 
++static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
++			     struct nft_set *set)
++{
++	return __nft_trans_set_add(ctx, msg_type, set, NULL);
++}
++
+ static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set)
+ {
+ 	int err;
+@@ -3732,8 +3744,7 @@ static bool nft_set_ops_candidate(const struct nft_set_type *type, u32 flags)
+ static const struct nft_set_ops *
+ nft_select_set_ops(const struct nft_ctx *ctx,
+ 		   const struct nlattr * const nla[],
+-		   const struct nft_set_desc *desc,
+-		   enum nft_set_policies policy)
++		   const struct nft_set_desc *desc)
+ {
+ 	struct nftables_pernet *nft_net = nft_pernet(ctx->net);
+ 	const struct nft_set_ops *ops, *bops;
+@@ -3762,7 +3773,7 @@ nft_select_set_ops(const struct nft_ctx *ctx,
+ 		if (!ops->estimate(desc, flags, &est))
+ 			continue;
+ 
+-		switch (policy) {
++		switch (desc->policy) {
+ 		case NFT_SET_POL_PERFORMANCE:
+ 			if (est.lookup < best.lookup)
+ 				break;
+@@ -3997,8 +4008,10 @@ static int nf_tables_fill_set_concat(struct sk_buff *skb,
+ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
+ 			      const struct nft_set *set, u16 event, u16 flags)
+ {
+-	struct nlmsghdr *nlh;
++	u64 timeout = READ_ONCE(set->timeout);
++	u32 gc_int = READ_ONCE(set->gc_int);
+ 	u32 portid = ctx->portid;
++	struct nlmsghdr *nlh;
+ 	struct nlattr *nest;
+ 	u32 seq = ctx->seq;
+ 	int i;
+@@ -4034,13 +4047,13 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
+ 	    nla_put_be32(skb, NFTA_SET_OBJ_TYPE, htonl(set->objtype)))
+ 		goto nla_put_failure;
+ 
+-	if (set->timeout &&
++	if (timeout &&
+ 	    nla_put_be64(skb, NFTA_SET_TIMEOUT,
+-			 nf_jiffies64_to_msecs(set->timeout),
++			 nf_jiffies64_to_msecs(timeout),
+ 			 NFTA_SET_PAD))
+ 		goto nla_put_failure;
+-	if (set->gc_int &&
+-	    nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(set->gc_int)))
++	if (gc_int &&
++	    nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(gc_int)))
+ 		goto nla_put_failure;
+ 
+ 	if (set->policy != NFT_SET_POL_PERFORMANCE) {
+@@ -4341,15 +4354,94 @@ static int nf_tables_set_desc_parse(struct nft_set_desc *desc,
+ 	return err;
+ }
+ 
++static int nft_set_expr_alloc(struct nft_ctx *ctx, struct nft_set *set,
++			      const struct nlattr * const *nla,
++			      struct nft_expr **exprs, int *num_exprs,
++			      u32 flags)
++{
++	struct nft_expr *expr;
++	int err, i;
++
++	if (nla[NFTA_SET_EXPR]) {
++		expr = nft_set_elem_expr_alloc(ctx, set, nla[NFTA_SET_EXPR]);
++		if (IS_ERR(expr)) {
++			err = PTR_ERR(expr);
++			goto err_set_expr_alloc;
++		}
++		exprs[0] = expr;
++		(*num_exprs)++;
++	} else if (nla[NFTA_SET_EXPRESSIONS]) {
++		struct nlattr *tmp;
++		int left;
++
++		if (!(flags & NFT_SET_EXPR)) {
++			err = -EINVAL;
++			goto err_set_expr_alloc;
++		}
++		i = 0;
++		nla_for_each_nested(tmp, nla[NFTA_SET_EXPRESSIONS], left) {
++			if (i == NFT_SET_EXPR_MAX) {
++				err = -E2BIG;
++				goto err_set_expr_alloc;
++			}
++			if (nla_type(tmp) != NFTA_LIST_ELEM) {
++				err = -EINVAL;
++				goto err_set_expr_alloc;
++			}
++			expr = nft_set_elem_expr_alloc(ctx, set, tmp);
++			if (IS_ERR(expr)) {
++				err = PTR_ERR(expr);
++				goto err_set_expr_alloc;
++			}
++			exprs[i++] = expr;
++			(*num_exprs)++;
++		}
++	}
++
++	return 0;
++
++err_set_expr_alloc:
++	for (i = 0; i < *num_exprs; i++)
++		nft_expr_destroy(ctx, exprs[i]);
++
++	return err;
++}
++
++static bool nft_set_is_same(const struct nft_set *set,
++			    const struct nft_set_desc *desc,
++			    struct nft_expr *exprs[], u32 num_exprs, u32 flags)
++{
++	int i;
++
++	if (set->ktype != desc->ktype ||
++	    set->dtype != desc->dtype ||
++	    set->flags != flags ||
++	    set->klen != desc->klen ||
++	    set->dlen != desc->dlen ||
++	    set->field_count != desc->field_count ||
++	    set->num_exprs != num_exprs)
++		return false;
++
++	for (i = 0; i < desc->field_count; i++) {
++		if (set->field_len[i] != desc->field_len[i])
++			return false;
++	}
++
++	for (i = 0; i < num_exprs; i++) {
++		if (set->exprs[i]->ops != exprs[i]->ops)
++			return false;
++	}
++
++	return true;
++}
++
+ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ 			    const struct nlattr * const nla[])
+ {
+-	u32 ktype, dtype, flags, policy, gc_int, objtype;
+ 	struct netlink_ext_ack *extack = info->extack;
+ 	u8 genmask = nft_genmask_next(info->net);
+ 	u8 family = info->nfmsg->nfgen_family;
+ 	const struct nft_set_ops *ops;
+-	struct nft_expr *expr = NULL;
+ 	struct net *net = info->net;
+ 	struct nft_set_desc desc;
+ 	struct nft_table *table;
+@@ -4357,10 +4449,11 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ 	struct nft_set *set;
+ 	struct nft_ctx ctx;
+ 	size_t alloc_size;
+-	u64 timeout;
++	int num_exprs = 0;
+ 	char *name;
+ 	int err, i;
+ 	u16 udlen;
++	u32 flags;
+ 	u64 size;
+ 
+ 	if (nla[NFTA_SET_TABLE] == NULL ||
+@@ -4371,10 +4464,10 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ 
+ 	memset(&desc, 0, sizeof(desc));
+ 
+-	ktype = NFT_DATA_VALUE;
++	desc.ktype = NFT_DATA_VALUE;
+ 	if (nla[NFTA_SET_KEY_TYPE] != NULL) {
+-		ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
+-		if ((ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
++		desc.ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
++		if ((desc.ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
+ 			return -EINVAL;
+ 	}
+ 
+@@ -4399,17 +4492,17 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ 			return -EOPNOTSUPP;
+ 	}
+ 
+-	dtype = 0;
++	desc.dtype = 0;
+ 	if (nla[NFTA_SET_DATA_TYPE] != NULL) {
+ 		if (!(flags & NFT_SET_MAP))
+ 			return -EINVAL;
+ 
+-		dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
+-		if ((dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
+-		    dtype != NFT_DATA_VERDICT)
++		desc.dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
++		if ((desc.dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
++		    desc.dtype != NFT_DATA_VERDICT)
+ 			return -EINVAL;
+ 
+-		if (dtype != NFT_DATA_VERDICT) {
++		if (desc.dtype != NFT_DATA_VERDICT) {
+ 			if (nla[NFTA_SET_DATA_LEN] == NULL)
+ 				return -EINVAL;
+ 			desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
+@@ -4424,34 +4517,34 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ 		if (!(flags & NFT_SET_OBJECT))
+ 			return -EINVAL;
+ 
+-		objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
+-		if (objtype == NFT_OBJECT_UNSPEC ||
+-		    objtype > NFT_OBJECT_MAX)
++		desc.objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
++		if (desc.objtype == NFT_OBJECT_UNSPEC ||
++		    desc.objtype > NFT_OBJECT_MAX)
+ 			return -EOPNOTSUPP;
+ 	} else if (flags & NFT_SET_OBJECT)
+ 		return -EINVAL;
+ 	else
+-		objtype = NFT_OBJECT_UNSPEC;
++		desc.objtype = NFT_OBJECT_UNSPEC;
+ 
+-	timeout = 0;
++	desc.timeout = 0;
+ 	if (nla[NFTA_SET_TIMEOUT] != NULL) {
+ 		if (!(flags & NFT_SET_TIMEOUT))
+ 			return -EINVAL;
+ 
+-		err = nf_msecs_to_jiffies64(nla[NFTA_SET_TIMEOUT], &timeout);
++		err = nf_msecs_to_jiffies64(nla[NFTA_SET_TIMEOUT], &desc.timeout);
+ 		if (err)
+ 			return err;
+ 	}
+-	gc_int = 0;
++	desc.gc_int = 0;
+ 	if (nla[NFTA_SET_GC_INTERVAL] != NULL) {
+ 		if (!(flags & NFT_SET_TIMEOUT))
+ 			return -EINVAL;
+-		gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
++		desc.gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
+ 	}
+ 
+-	policy = NFT_SET_POL_PERFORMANCE;
++	desc.policy = NFT_SET_POL_PERFORMANCE;
+ 	if (nla[NFTA_SET_POLICY] != NULL)
+-		policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
++		desc.policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
+ 
+ 	if (nla[NFTA_SET_DESC] != NULL) {
+ 		err = nf_tables_set_desc_parse(&desc, nla[NFTA_SET_DESC]);
+@@ -4483,6 +4576,8 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ 			return PTR_ERR(set);
+ 		}
+ 	} else {
++		struct nft_expr *exprs[NFT_SET_EXPR_MAX] = {};
++
+ 		if (info->nlh->nlmsg_flags & NLM_F_EXCL) {
+ 			NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]);
+ 			return -EEXIST;
+@@ -4490,13 +4585,29 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ 		if (info->nlh->nlmsg_flags & NLM_F_REPLACE)
+ 			return -EOPNOTSUPP;
+ 
+-		return 0;
++		err = nft_set_expr_alloc(&ctx, set, nla, exprs, &num_exprs, flags);
++		if (err < 0)
++			return err;
++
++		err = 0;
++		if (!nft_set_is_same(set, &desc, exprs, num_exprs, flags)) {
++			NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]);
++			err = -EEXIST;
++		}
++
++		for (i = 0; i < num_exprs; i++)
++			nft_expr_destroy(&ctx, exprs[i]);
++
++		if (err < 0)
++			return err;
++
++		return __nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set, &desc);
+ 	}
+ 
+ 	if (!(info->nlh->nlmsg_flags & NLM_F_CREATE))
+ 		return -ENOENT;
+ 
+-	ops = nft_select_set_ops(&ctx, nla, &desc, policy);
++	ops = nft_select_set_ops(&ctx, nla, &desc);
+ 	if (IS_ERR(ops))
+ 		return PTR_ERR(ops);
+ 
+@@ -4536,18 +4647,18 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ 	set->table = table;
+ 	write_pnet(&set->net, net);
+ 	set->ops = ops;
+-	set->ktype = ktype;
++	set->ktype = desc.ktype;
+ 	set->klen = desc.klen;
+-	set->dtype = dtype;
+-	set->objtype = objtype;
++	set->dtype = desc.dtype;
++	set->objtype = desc.objtype;
+ 	set->dlen = desc.dlen;
+ 	set->flags = flags;
+ 	set->size = desc.size;
+-	set->policy = policy;
++	set->policy = desc.policy;
+ 	set->udlen = udlen;
+ 	set->udata = udata;
+-	set->timeout = timeout;
+-	set->gc_int = gc_int;
++	set->timeout = desc.timeout;
++	set->gc_int = desc.gc_int;
+ 
+ 	set->field_count = desc.field_count;
+ 	for (i = 0; i < desc.field_count; i++)
+@@ -4557,43 +4668,11 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ 	if (err < 0)
+ 		goto err_set_init;
+ 
+-	if (nla[NFTA_SET_EXPR]) {
+-		expr = nft_set_elem_expr_alloc(&ctx, set, nla[NFTA_SET_EXPR]);
+-		if (IS_ERR(expr)) {
+-			err = PTR_ERR(expr);
+-			goto err_set_expr_alloc;
+-		}
+-		set->exprs[0] = expr;
+-		set->num_exprs++;
+-	} else if (nla[NFTA_SET_EXPRESSIONS]) {
+-		struct nft_expr *expr;
+-		struct nlattr *tmp;
+-		int left;
+-
+-		if (!(flags & NFT_SET_EXPR)) {
+-			err = -EINVAL;
+-			goto err_set_expr_alloc;
+-		}
+-		i = 0;
+-		nla_for_each_nested(tmp, nla[NFTA_SET_EXPRESSIONS], left) {
+-			if (i == NFT_SET_EXPR_MAX) {
+-				err = -E2BIG;
+-				goto err_set_expr_alloc;
+-			}
+-			if (nla_type(tmp) != NFTA_LIST_ELEM) {
+-				err = -EINVAL;
+-				goto err_set_expr_alloc;
+-			}
+-			expr = nft_set_elem_expr_alloc(&ctx, set, tmp);
+-			if (IS_ERR(expr)) {
+-				err = PTR_ERR(expr);
+-				goto err_set_expr_alloc;
+-			}
+-			set->exprs[i++] = expr;
+-			set->num_exprs++;
+-		}
+-	}
++	err = nft_set_expr_alloc(&ctx, set, nla, set->exprs, &num_exprs, flags);
++	if (err < 0)
++		goto err_set_destroy;
+ 
++	set->num_exprs = num_exprs;
+ 	set->handle = nf_tables_alloc_handle(table);
+ 
+ 	err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
+@@ -4607,7 +4686,7 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+ err_set_expr_alloc:
+ 	for (i = 0; i < set->num_exprs; i++)
+ 		nft_expr_destroy(&ctx, set->exprs[i]);
+-
++err_set_destroy:
+ 	ops->destroy(set);
+ err_set_init:
+ 	kfree(set->name);
+@@ -5960,7 +6039,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ 			return err;
+ 	} else if (set->flags & NFT_SET_TIMEOUT &&
+ 		   !(flags & NFT_SET_ELEM_INTERVAL_END)) {
+-		timeout = set->timeout;
++		timeout = READ_ONCE(set->timeout);
+ 	}
+ 
+ 	expiration = 0;
+@@ -6061,7 +6140,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ 		if (err < 0)
+ 			goto err_parse_key_end;
+ 
+-		if (timeout != set->timeout) {
++		if (timeout != READ_ONCE(set->timeout)) {
+ 			err = nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
+ 			if (err < 0)
+ 				goto err_parse_key_end;
+@@ -8977,14 +9056,20 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+ 				nft_flow_rule_destroy(nft_trans_flow_rule(trans));
+ 			break;
+ 		case NFT_MSG_NEWSET:
+-			nft_clear(net, nft_trans_set(trans));
+-			/* This avoids hitting -EBUSY when deleting the table
+-			 * from the transaction.
+-			 */
+-			if (nft_set_is_anonymous(nft_trans_set(trans)) &&
+-			    !list_empty(&nft_trans_set(trans)->bindings))
+-				trans->ctx.table->use--;
++			if (nft_trans_set_update(trans)) {
++				struct nft_set *set = nft_trans_set(trans);
+ 
++				WRITE_ONCE(set->timeout, nft_trans_set_timeout(trans));
++				WRITE_ONCE(set->gc_int, nft_trans_set_gc_int(trans));
++			} else {
++				nft_clear(net, nft_trans_set(trans));
++				/* This avoids hitting -EBUSY when deleting the table
++				 * from the transaction.
++				 */
++				if (nft_set_is_anonymous(nft_trans_set(trans)) &&
++				    !list_empty(&nft_trans_set(trans)->bindings))
++					trans->ctx.table->use--;
++			}
+ 			nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
+ 					     NFT_MSG_NEWSET, GFP_KERNEL);
+ 			nft_trans_destroy(trans);
+@@ -9206,6 +9291,10 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
+ 			nft_trans_destroy(trans);
+ 			break;
+ 		case NFT_MSG_NEWSET:
++			if (nft_trans_set_update(trans)) {
++				nft_trans_destroy(trans);
++				break;
++			}
+ 			trans->ctx.table->use--;
+ 			if (nft_trans_set_bound(trans)) {
+ 				nft_trans_destroy(trans);
+diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
+index 7c62417ccfd78..32a08ae9ad117 100644
+--- a/net/nfc/netlink.c
++++ b/net/nfc/netlink.c
+@@ -1497,6 +1497,7 @@ static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
+ 	u32 dev_idx, se_idx;
+ 	u8 *apdu;
+ 	size_t apdu_len;
++	int rc;
+ 
+ 	if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
+ 	    !info->attrs[NFC_ATTR_SE_INDEX] ||
+@@ -1510,25 +1511,37 @@ static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
+ 	if (!dev)
+ 		return -ENODEV;
+ 
+-	if (!dev->ops || !dev->ops->se_io)
+-		return -ENOTSUPP;
++	if (!dev->ops || !dev->ops->se_io) {
++		rc = -EOPNOTSUPP;
++		goto put_dev;
++	}
+ 
+ 	apdu_len = nla_len(info->attrs[NFC_ATTR_SE_APDU]);
+-	if (apdu_len == 0)
+-		return -EINVAL;
++	if (apdu_len == 0) {
++		rc = -EINVAL;
++		goto put_dev;
++	}
+ 
+ 	apdu = nla_data(info->attrs[NFC_ATTR_SE_APDU]);
+-	if (!apdu)
+-		return -EINVAL;
++	if (!apdu) {
++		rc = -EINVAL;
++		goto put_dev;
++	}
+ 
+ 	ctx = kzalloc(sizeof(struct se_io_ctx), GFP_KERNEL);
+-	if (!ctx)
+-		return -ENOMEM;
++	if (!ctx) {
++		rc = -ENOMEM;
++		goto put_dev;
++	}
+ 
+ 	ctx->dev_idx = dev_idx;
+ 	ctx->se_idx = se_idx;
+ 
+-	return nfc_se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
++	rc = nfc_se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
++
++put_dev:
++	nfc_put_device(dev);
++	return rc;
+ }
+ 
+ static int nfc_genl_vendor_cmd(struct sk_buff *skb,
+@@ -1551,14 +1564,21 @@ static int nfc_genl_vendor_cmd(struct sk_buff *skb,
+ 	subcmd = nla_get_u32(info->attrs[NFC_ATTR_VENDOR_SUBCMD]);
+ 
+ 	dev = nfc_get_device(dev_idx);
+-	if (!dev || !dev->vendor_cmds || !dev->n_vendor_cmds)
++	if (!dev)
+ 		return -ENODEV;
+ 
++	if (!dev->vendor_cmds || !dev->n_vendor_cmds) {
++		err = -ENODEV;
++		goto put_dev;
++	}
++
+ 	if (info->attrs[NFC_ATTR_VENDOR_DATA]) {
+ 		data = nla_data(info->attrs[NFC_ATTR_VENDOR_DATA]);
+ 		data_len = nla_len(info->attrs[NFC_ATTR_VENDOR_DATA]);
+-		if (data_len == 0)
+-			return -EINVAL;
++		if (data_len == 0) {
++			err = -EINVAL;
++			goto put_dev;
++		}
+ 	} else {
+ 		data = NULL;
+ 		data_len = 0;
+@@ -1573,10 +1593,14 @@ static int nfc_genl_vendor_cmd(struct sk_buff *skb,
+ 		dev->cur_cmd_info = info;
+ 		err = cmd->doit(dev, data, data_len);
+ 		dev->cur_cmd_info = NULL;
+-		return err;
++		goto put_dev;
+ 	}
+ 
+-	return -EOPNOTSUPP;
++	err = -EOPNOTSUPP;
++
++put_dev:
++	nfc_put_device(dev);
++	return err;
+ }
+ 
+ /* message building helper */
+diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
+index 742c7d49a9581..8d1ef858db87d 100644
+--- a/net/sched/cls_tcindex.c
++++ b/net/sched/cls_tcindex.c
+@@ -332,7 +332,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
+ 		  struct tcindex_filter_result *r, struct nlattr **tb,
+ 		  struct nlattr *est, u32 flags, struct netlink_ext_ack *extack)
+ {
+-	struct tcindex_filter_result new_filter_result, *old_r = r;
++	struct tcindex_filter_result new_filter_result;
+ 	struct tcindex_data *cp = NULL, *oldp;
+ 	struct tcindex_filter *f = NULL; /* make gcc behave */
+ 	struct tcf_result cr = {};
+@@ -401,7 +401,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
+ 	err = tcindex_filter_result_init(&new_filter_result, cp, net);
+ 	if (err < 0)
+ 		goto errout_alloc;
+-	if (old_r)
++	if (r)
+ 		cr = r->res;
+ 
+ 	err = -EBUSY;
+@@ -478,14 +478,6 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
+ 		tcf_bind_filter(tp, &cr, base);
+ 	}
+ 
+-	if (old_r && old_r != r) {
+-		err = tcindex_filter_result_init(old_r, cp, net);
+-		if (err < 0) {
+-			kfree(f);
+-			goto errout_alloc;
+-		}
+-	}
+-
+ 	oldp = p;
+ 	r->res = cr;
+ 	tcf_exts_change(&r->exts, &e);
+diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
+index 816fd0d7ba38a..28e1897e0da70 100644
+--- a/net/sched/sch_atm.c
++++ b/net/sched/sch_atm.c
+@@ -397,10 +397,13 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ 				result = tcf_classify(skb, NULL, fl, &res, true);
+ 				if (result < 0)
+ 					continue;
++				if (result == TC_ACT_SHOT)
++					goto done;
++
+ 				flow = (struct atm_flow_data *)res.class;
+ 				if (!flow)
+ 					flow = lookup_flow(sch, res.classid);
+-				goto done;
++				goto drop;
+ 			}
+ 		}
+ 		flow = NULL;
+diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
+index ba99ce05cd527..5d9f4f259d693 100644
+--- a/net/sched/sch_cbq.c
++++ b/net/sched/sch_cbq.c
+@@ -230,6 +230,8 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
+ 		result = tcf_classify(skb, NULL, fl, &res, true);
+ 		if (!fl || result < 0)
+ 			goto fallback;
++		if (result == TC_ACT_SHOT)
++			return NULL;
+ 
+ 		cl = (void *)res.class;
+ 		if (!cl) {
+@@ -250,8 +252,6 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
+ 		case TC_ACT_TRAP:
+ 			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
+ 			fallthrough;
+-		case TC_ACT_SHOT:
+-			return NULL;
+ 		case TC_ACT_RECLASSIFY:
+ 			return cbq_reclassify(skb, cl);
+ 		}
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index 7bb247c51e2f6..2d7b1e03110ae 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -302,7 +302,7 @@ __gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid, const struct gss_auth *auth
+ 	list_for_each_entry(pos, &pipe->in_downcall, list) {
+ 		if (!uid_eq(pos->uid, uid))
+ 			continue;
+-		if (auth && pos->auth->service != auth->service)
++		if (pos->auth->service != auth->service)
+ 			continue;
+ 		refcount_inc(&pos->count);
+ 		return pos;
+@@ -686,6 +686,21 @@ out:
+ 	return err;
+ }
+ 
++static struct gss_upcall_msg *
++gss_find_downcall(struct rpc_pipe *pipe, kuid_t uid)
++{
++	struct gss_upcall_msg *pos;
++	list_for_each_entry(pos, &pipe->in_downcall, list) {
++		if (!uid_eq(pos->uid, uid))
++			continue;
++		if (!rpc_msg_is_inflight(&pos->msg))
++			continue;
++		refcount_inc(&pos->count);
++		return pos;
++	}
++	return NULL;
++}
++
+ #define MSG_BUF_MAXSIZE 1024
+ 
+ static ssize_t
+@@ -732,7 +747,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
+ 	err = -ENOENT;
+ 	/* Find a matching upcall */
+ 	spin_lock(&pipe->lock);
+-	gss_msg = __gss_find_upcall(pipe, uid, NULL);
++	gss_msg = gss_find_downcall(pipe, uid);
+ 	if (gss_msg == NULL) {
+ 		spin_unlock(&pipe->lock);
+ 		goto err_put_ctx;
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c
+index fb9d9e271845d..ddd2625bed90d 100644
+--- a/sound/soc/intel/boards/bytcr_rt5640.c
++++ b/sound/soc/intel/boards/bytcr_rt5640.c
+@@ -570,6 +570,21 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
+ 					BYT_RT5640_SSP0_AIF1 |
+ 					BYT_RT5640_MCLK_EN),
+ 	},
++	{
++		/* Advantech MICA-071 */
++		.matches = {
++			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"),
++			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"),
++		},
++		/* OVCD Th = 1500uA to reliable detect head-phones vs -set */
++		.driver_data = (void *)(BYT_RT5640_IN3_MAP |
++					BYT_RT5640_JD_SRC_JD2_IN4N |
++					BYT_RT5640_OVCD_TH_1500UA |
++					BYT_RT5640_OVCD_SF_0P75 |
++					BYT_RT5640_MONO_SPEAKER |
++					BYT_RT5640_DIFF_MIC |
++					BYT_RT5640_MCLK_EN),
++	},
+ 	{
+ 		.matches = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
+diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c
+index c99b5e6c026c1..694a2d94a2228 100644
+--- a/sound/soc/sof/core.c
++++ b/sound/soc/sof/core.c
+@@ -472,19 +472,10 @@ EXPORT_SYMBOL(snd_sof_device_remove);
+ int snd_sof_device_shutdown(struct device *dev)
+ {
+ 	struct snd_sof_dev *sdev = dev_get_drvdata(dev);
+-	struct snd_sof_pdata *pdata = sdev->pdata;
+ 
+ 	if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
+ 		cancel_work_sync(&sdev->probe_work);
+ 
+-	/*
+-	 * make sure clients and machine driver(s) are unregistered to force
+-	 * all userspace devices to be closed prior to the DSP shutdown sequence
+-	 */
+-	sof_unregister_clients(sdev);
+-
+-	snd_sof_machine_unregister(sdev, pdata);
+-
+ 	if (sdev->fw_state == SOF_FW_BOOT_COMPLETE)
+ 		return snd_sof_shutdown(sdev);
+ 
+diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
+index eddfd77ad90f4..0ab111814f1c5 100644
+--- a/sound/soc/sof/intel/hda-dsp.c
++++ b/sound/soc/sof/intel/hda-dsp.c
+@@ -901,6 +901,78 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
+ 	return snd_sof_dsp_set_power_state(sdev, &target_dsp_state);
+ }
+ 
++static unsigned int hda_dsp_check_for_dma_streams(struct snd_sof_dev *sdev)
++{
++	struct hdac_bus *bus = sof_to_bus(sdev);
++	struct hdac_stream *s;
++	unsigned int active_streams = 0;
++	int sd_offset;
++	u32 val;
++
++	list_for_each_entry(s, &bus->stream_list, list) {
++		sd_offset = SOF_STREAM_SD_OFFSET(s);
++		val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
++				       sd_offset);
++		if (val & SOF_HDA_SD_CTL_DMA_START)
++			active_streams |= BIT(s->index);
++	}
++
++	return active_streams;
++}
++
++static int hda_dsp_s5_quirk(struct snd_sof_dev *sdev)
++{
++	int ret;
++
++	/*
++	 * Do not assume a certain timing between the prior
++	 * suspend flow, and running of this quirk function.
++	 * This is needed if the controller was just put
++	 * to reset before calling this function.
++	 */
++	usleep_range(500, 1000);
++
++	/*
++	 * Take controller out of reset to flush DMA
++	 * transactions.
++	 */
++	ret = hda_dsp_ctrl_link_reset(sdev, false);
++	if (ret < 0)
++		return ret;
++
++	usleep_range(500, 1000);
++
++	/* Restore state for shutdown, back to reset */
++	ret = hda_dsp_ctrl_link_reset(sdev, true);
++	if (ret < 0)
++		return ret;
++
++	return ret;
++}
++
++int hda_dsp_shutdown_dma_flush(struct snd_sof_dev *sdev)
++{
++	unsigned int active_streams;
++	int ret, ret2;
++
++	/* check if DMA cleanup has been successful */
++	active_streams = hda_dsp_check_for_dma_streams(sdev);
++
++	sdev->system_suspend_target = SOF_SUSPEND_S3;
++	ret = snd_sof_suspend(sdev->dev);
++
++	if (active_streams) {
++		dev_warn(sdev->dev,
++			 "There were active DSP streams (%#x) at shutdown, trying to recover\n",
++			 active_streams);
++		ret2 = hda_dsp_s5_quirk(sdev);
++		if (ret2 < 0)
++			dev_err(sdev->dev, "shutdown recovery failed (%d)\n", ret2);
++	}
++
++	return ret;
++}
++
+ int hda_dsp_shutdown(struct snd_sof_dev *sdev)
+ {
+ 	sdev->system_suspend_target = SOF_SUSPEND_S3;
+diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
+index 5ef3e8775e364..554891e78cca5 100644
+--- a/sound/soc/sof/intel/hda.h
++++ b/sound/soc/sof/intel/hda.h
+@@ -578,6 +578,7 @@ int hda_dsp_resume(struct snd_sof_dev *sdev);
+ int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev);
+ int hda_dsp_runtime_resume(struct snd_sof_dev *sdev);
+ int hda_dsp_runtime_idle(struct snd_sof_dev *sdev);
++int hda_dsp_shutdown_dma_flush(struct snd_sof_dev *sdev);
+ int hda_dsp_shutdown(struct snd_sof_dev *sdev);
+ int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev);
+ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags);
+diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c
+index 6dfb4786c7824..0173e5b255daa 100644
+--- a/sound/soc/sof/intel/tgl.c
++++ b/sound/soc/sof/intel/tgl.c
+@@ -60,7 +60,7 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev)
+ 	memcpy(&sof_tgl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops));
+ 
+ 	/* probe/remove/shutdown */
+-	sof_tgl_ops.shutdown	= hda_dsp_shutdown;
++	sof_tgl_ops.shutdown	= hda_dsp_shutdown_dma_flush;
+ 
+ 	if (sdev->pdata->ipc_type == SOF_IPC) {
+ 		/* doorbell */
+diff --git a/sound/soc/sof/mediatek/mtk-adsp-common.c b/sound/soc/sof/mediatek/mtk-adsp-common.c
+index 1e0769c668a7b..de8dbe27cd0de 100644
+--- a/sound/soc/sof/mediatek/mtk-adsp-common.c
++++ b/sound/soc/sof/mediatek/mtk-adsp-common.c
+@@ -60,7 +60,7 @@ void mtk_adsp_dump(struct snd_sof_dev *sdev, u32 flags)
+ {
+ 	char *level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR;
+ 	struct sof_ipc_dsp_oops_xtensa xoops;
+-	struct sof_ipc_panic_info panic_info;
++	struct sof_ipc_panic_info panic_info = {};
+ 	u32 stack[MTK_ADSP_STACK_DUMP_SIZE];
+ 	u32 status;
+ 
+diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
+index ea40ae52cd2c7..2bc9231d86b66 100644
+--- a/tools/perf/builtin-lock.c
++++ b/tools/perf/builtin-lock.c
+@@ -1539,6 +1539,7 @@ static int __cmd_report(bool display_info)
+ 
+ 	/* for lock function check */
+ 	symbol_conf.sort_by_name = true;
++	symbol_conf.allow_aliases = true;
+ 	symbol__init(&session->header.env);
+ 
+ 	if (!perf_session__has_traces(session, "lock record"))
+@@ -1613,6 +1614,7 @@ static int __cmd_contention(int argc, const char **argv)
+ 
+ 	/* for lock function check */
+ 	symbol_conf.sort_by_name = true;
++	symbol_conf.allow_aliases = true;
+ 	symbol__init(&session->header.env);
+ 
+ 	if (use_bpf) {
+diff --git a/tools/perf/util/bpf_counter_cgroup.c b/tools/perf/util/bpf_counter_cgroup.c
+index 3c2df7522f6fc..1c82377ed78b9 100644
+--- a/tools/perf/util/bpf_counter_cgroup.c
++++ b/tools/perf/util/bpf_counter_cgroup.c
+@@ -116,27 +116,19 @@ static int bperf_load_program(struct evlist *evlist)
+ 
+ 			/* open single copy of the events w/o cgroup */
+ 			err = evsel__open_per_cpu(evsel, evsel->core.cpus, -1);
+-			if (err) {
+-				pr_err("Failed to open first cgroup events\n");
+-				goto out;
+-			}
++			if (err == 0)
++				evsel->supported = true;
+ 
+ 			map_fd = bpf_map__fd(skel->maps.events);
+ 			perf_cpu_map__for_each_cpu(cpu, j, evsel->core.cpus) {
+ 				int fd = FD(evsel, j);
+ 				__u32 idx = evsel->core.idx * total_cpus + cpu.cpu;
+ 
+-				err = bpf_map_update_elem(map_fd, &idx, &fd,
+-							  BPF_ANY);
+-				if (err < 0) {
+-					pr_err("Failed to update perf_event fd\n");
+-					goto out;
+-				}
++				bpf_map_update_elem(map_fd, &idx, &fd, BPF_ANY);
+ 			}
+ 
+ 			evsel->cgrp = leader_cgrp;
+ 		}
+-		evsel->supported = true;
+ 
+ 		if (evsel->cgrp == cgrp)
+ 			continue;
+diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c
+index e99b41f9be45a..cd978c240e0dd 100644
+--- a/tools/perf/util/cgroup.c
++++ b/tools/perf/util/cgroup.c
+@@ -224,6 +224,19 @@ static int add_cgroup_name(const char *fpath, const struct stat *sb __maybe_unus
+ 	return 0;
+ }
+ 
++static int check_and_add_cgroup_name(const char *fpath)
++{
++	struct cgroup_name *cn;
++
++	list_for_each_entry(cn, &cgroup_list, list) {
++		if (!strcmp(cn->name, fpath))
++			return 0;
++	}
++
++	/* pretend if it's added by ftw() */
++	return add_cgroup_name(fpath, NULL, FTW_D, NULL);
++}
++
+ static void release_cgroup_list(void)
+ {
+ 	struct cgroup_name *cn;
+@@ -242,7 +255,7 @@ static int list_cgroups(const char *str)
+ 	struct cgroup_name *cn;
+ 	char *s;
+ 
+-	/* use given name as is - for testing purpose */
++	/* use given name as is when no regex is given */
+ 	for (;;) {
+ 		p = strchr(str, ',');
+ 		e = p ? p : eos;
+@@ -253,13 +266,13 @@ static int list_cgroups(const char *str)
+ 			s = strndup(str, e - str);
+ 			if (!s)
+ 				return -1;
+-			/* pretend if it's added by ftw() */
+-			ret = add_cgroup_name(s, NULL, FTW_D, NULL);
++
++			ret = check_and_add_cgroup_name(s);
+ 			free(s);
+-			if (ret)
++			if (ret < 0)
+ 				return -1;
+ 		} else {
+-			if (add_cgroup_name("", NULL, FTW_D, NULL) < 0)
++			if (check_and_add_cgroup_name("/") < 0)
+ 				return -1;
+ 		}
+ 
+diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
+index a7f68c309545d..fc16299c915f9 100644
+--- a/tools/perf/util/data.c
++++ b/tools/perf/util/data.c
+@@ -132,6 +132,7 @@ int perf_data__open_dir(struct perf_data *data)
+ 		file->size = st.st_size;
+ 	}
+ 
++	closedir(dir);
+ 	if (!files)
+ 		return -EINVAL;
+ 
+@@ -140,6 +141,7 @@ int perf_data__open_dir(struct perf_data *data)
+ 	return 0;
+ 
+ out_err:
++	closedir(dir);
+ 	close_dir(files, nr);
+ 	return ret;
+ }
+diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
+index 609ca16715018..623527edeac1e 100644
+--- a/tools/perf/util/dwarf-aux.c
++++ b/tools/perf/util/dwarf-aux.c
+@@ -308,26 +308,13 @@ static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
+ {
+ 	Dwarf_Attribute attr;
+ 
+-	if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
++	if (dwarf_attr_integrate(tp_die, attr_name, &attr) == NULL ||
+ 	    dwarf_formudata(&attr, result) != 0)
+ 		return -ENOENT;
+ 
+ 	return 0;
+ }
+ 
+-/* Get attribute and translate it as a sdata */
+-static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name,
+-			      Dwarf_Sword *result)
+-{
+-	Dwarf_Attribute attr;
+-
+-	if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
+-	    dwarf_formsdata(&attr, result) != 0)
+-		return -ENOENT;
+-
+-	return 0;
+-}
+-
+ /**
+  * die_is_signed_type - Check whether a type DIE is signed or not
+  * @tp_die: a DIE of a type
+@@ -467,9 +454,9 @@ int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
+ /* Get the call file index number in CU DIE */
+ static int die_get_call_fileno(Dwarf_Die *in_die)
+ {
+-	Dwarf_Sword idx;
++	Dwarf_Word idx;
+ 
+-	if (die_get_attr_sdata(in_die, DW_AT_call_file, &idx) == 0)
++	if (die_get_attr_udata(in_die, DW_AT_call_file, &idx) == 0)
+ 		return (int)idx;
+ 	else
+ 		return -ENOENT;
+@@ -478,9 +465,9 @@ static int die_get_call_fileno(Dwarf_Die *in_die)
+ /* Get the declared file index number in CU DIE */
+ static int die_get_decl_fileno(Dwarf_Die *pdie)
+ {
+-	Dwarf_Sword idx;
++	Dwarf_Word idx;
+ 
+-	if (die_get_attr_sdata(pdie, DW_AT_decl_file, &idx) == 0)
++	if (die_get_attr_udata(pdie, DW_AT_decl_file, &idx) == 0)
+ 		return (int)idx;
+ 	else
+ 		return -ENOENT;
+diff --git a/tools/testing/selftests/net/arp_ndisc_evict_nocarrier.sh b/tools/testing/selftests/net/arp_ndisc_evict_nocarrier.sh
+index b5af08af85595..4a110bb01e53e 100755
+--- a/tools/testing/selftests/net/arp_ndisc_evict_nocarrier.sh
++++ b/tools/testing/selftests/net/arp_ndisc_evict_nocarrier.sh
+@@ -18,14 +18,15 @@ readonly V4_ADDR1=10.0.10.2
+ readonly V6_ADDR0=2001:db8:91::1
+ readonly V6_ADDR1=2001:db8:91::2
+ nsid=100
++ret=0
+ 
+ cleanup_v6()
+ {
+     ip netns del me
+     ip netns del peer
+ 
+-    sysctl -w net.ipv4.conf.veth0.ndisc_evict_nocarrier=1 >/dev/null 2>&1
+-    sysctl -w net.ipv4.conf.all.ndisc_evict_nocarrier=1 >/dev/null 2>&1
++    sysctl -w net.ipv6.conf.veth1.ndisc_evict_nocarrier=1 >/dev/null 2>&1
++    sysctl -w net.ipv6.conf.all.ndisc_evict_nocarrier=1 >/dev/null 2>&1
+ }
+ 
+ create_ns()
+@@ -61,7 +62,7 @@ setup_v6() {
+     if [ $? -ne 0 ]; then
+         cleanup_v6
+         echo "failed"
+-        exit
++        exit 1
+     fi
+ 
+     # Set veth2 down, which will put veth1 in NOCARRIER state
+@@ -88,7 +89,7 @@ setup_v4() {
+     if [ $? -ne 0 ]; then
+         cleanup_v4
+         echo "failed"
+-        exit
++        exit 1
+     fi
+ 
+     # Set veth1 down, which will put veth0 in NOCARRIER state
+@@ -115,6 +116,7 @@ run_arp_evict_nocarrier_enabled() {
+ 
+     if [ $? -eq 0 ];then
+         echo "failed"
++        ret=1
+     else
+         echo "ok"
+     fi
+@@ -134,6 +136,7 @@ run_arp_evict_nocarrier_disabled() {
+         echo "ok"
+     else
+         echo "failed"
++        ret=1
+     fi
+ 
+     cleanup_v4
+@@ -164,6 +167,7 @@ run_ndisc_evict_nocarrier_enabled() {
+ 
+     if [ $? -eq 0 ];then
+         echo "failed"
++        ret=1
+     else
+         echo "ok"
+     fi
+@@ -182,6 +186,7 @@ run_ndisc_evict_nocarrier_disabled() {
+         echo "ok"
+     else
+         echo "failed"
++        ret=1
+     fi
+ 
+     cleanup_v6
+@@ -198,6 +203,7 @@ run_ndisc_evict_nocarrier_disabled_all() {
+         echo "ok"
+     else
+         echo "failed"
++        ret=1
+     fi
+ 
+     cleanup_v6
+@@ -218,3 +224,4 @@ if [ "$(id -u)" -ne 0 ];then
+ fi
+ 
+ run_all_tests
++exit $ret


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2023-01-07 11:11 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2023-01-07 11:11 UTC (permalink / raw
  To: gentoo-commits

commit:     8927b6ad937d813e8fb6f22e58847532153288b4
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Jan  7 11:11:26 2023 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Jan  7 11:11:26 2023 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=8927b6ad

Linux patch 6.0.18

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

 0000_README             |    4 +
 1017_linux-6.0.18.patch | 6477 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 6481 insertions(+)

diff --git a/0000_README b/0000_README
index b0d2c4b3..569afe2e 100644
--- a/0000_README
+++ b/0000_README
@@ -111,6 +111,10 @@ Patch:  1016_linux-6.0.17.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.17
 
+Patch:  1017_linux-6.0.19.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.18
+
 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/1017_linux-6.0.18.patch b/1017_linux-6.0.18.patch
new file mode 100644
index 00000000..f58d7b4f
--- /dev/null
+++ b/1017_linux-6.0.18.patch
@@ -0,0 +1,6477 @@
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index 2bc11a61c4d01..0fb8f99e59257 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -2294,7 +2294,13 @@
+ 			Provide an override to the IOAPIC-ID<->DEVICE-ID
+ 			mapping provided in the IVRS ACPI table.
+ 			By default, PCI segment is 0, and can be omitted.
+-			For example:
++
++			For example, to map IOAPIC-ID decimal 10 to
++			PCI segment 0x1 and PCI device 00:14.0,
++			write the parameter as:
++				ivrs_ioapic=10@0001:00:14.0
++
++			Deprecated formats:
+ 			* To map IOAPIC-ID decimal 10 to PCI device 00:14.0
+ 			  write the parameter as:
+ 				ivrs_ioapic[10]=00:14.0
+@@ -2306,7 +2312,13 @@
+ 			Provide an override to the HPET-ID<->DEVICE-ID
+ 			mapping provided in the IVRS ACPI table.
+ 			By default, PCI segment is 0, and can be omitted.
+-			For example:
++
++			For example, to map HPET-ID decimal 10 to
++			PCI segment 0x1 and PCI device 00:14.0,
++			write the parameter as:
++				ivrs_hpet=10@0001:00:14.0
++
++			Deprecated formats:
+ 			* To map HPET-ID decimal 0 to PCI device 00:14.0
+ 			  write the parameter as:
+ 				ivrs_hpet[0]=00:14.0
+@@ -2317,15 +2329,20 @@
+ 	ivrs_acpihid	[HW,X86-64]
+ 			Provide an override to the ACPI-HID:UID<->DEVICE-ID
+ 			mapping provided in the IVRS ACPI table.
++			By default, PCI segment is 0, and can be omitted.
+ 
+ 			For example, to map UART-HID:UID AMD0020:0 to
+ 			PCI segment 0x1 and PCI device ID 00:14.5,
+ 			write the parameter as:
+-				ivrs_acpihid[0001:00:14.5]=AMD0020:0
++				ivrs_acpihid=AMD0020:0@0001:00:14.5
+ 
+-			By default, PCI segment is 0, and can be omitted.
+-			For example, PCI device 00:14.5 write the parameter as:
++			Deprecated formats:
++			* To map UART-HID:UID AMD0020:0 to PCI segment is 0,
++			  PCI device ID 00:14.5, write the parameter as:
+ 				ivrs_acpihid[00:14.5]=AMD0020:0
++			* To map UART-HID:UID AMD0020:0 to PCI segment 0x1 and
++			  PCI device ID 00:14.5, write the parameter as:
++				ivrs_acpihid[0001:00:14.5]=AMD0020:0
+ 
+ 	js=		[HW,JOY] Analog joystick
+ 			See Documentation/input/joydev/joystick.rst.
+diff --git a/Documentation/filesystems/mount_api.rst b/Documentation/filesystems/mount_api.rst
+index eb358a00be279..1d16787a00e95 100644
+--- a/Documentation/filesystems/mount_api.rst
++++ b/Documentation/filesystems/mount_api.rst
+@@ -814,6 +814,7 @@ process the parameters it is given.
+        int fs_lookup_param(struct fs_context *fc,
+ 			   struct fs_parameter *value,
+ 			   bool want_bdev,
++			   unsigned int flags,
+ 			   struct path *_path);
+ 
+      This takes a parameter that carries a string or filename type and attempts
+diff --git a/Makefile b/Makefile
+index a0ddac5b7cafb..0104f69d30bbd 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 17
++SUBLEVEL = 18
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/arm/nwfpe/Makefile b/arch/arm/nwfpe/Makefile
+index 303400fa2cdf7..2aec85ab1e8b9 100644
+--- a/arch/arm/nwfpe/Makefile
++++ b/arch/arm/nwfpe/Makefile
+@@ -11,3 +11,9 @@ nwfpe-y				+= fpa11.o fpa11_cpdo.o fpa11_cpdt.o \
+ 				   entry.o
+ 
+ nwfpe-$(CONFIG_FPE_NWFPE_XP)	+= extended_cpdo.o
++
++# Try really hard to avoid generating calls to __aeabi_uldivmod() from
++# float64_rem() due to loop elision.
++ifdef CONFIG_CC_IS_CLANG
++CFLAGS_softfloat.o	+= -mllvm -replexitval=never
++endif
+diff --git a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
+index 4fbd99eb496a2..dec85d2548384 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
++++ b/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
+@@ -56,10 +56,10 @@
+ 		#size-cells = <2>;
+ 		ranges;
+ 
+-		/* 192 KiB reserved for ARM Trusted Firmware (BL31) */
++		/* 2 MiB reserved for ARM Trusted Firmware (BL31) */
+ 		bl31_secmon_reserved: secmon@54600000 {
+ 			no-map;
+-			reg = <0 0x54600000 0x0 0x30000>;
++			reg = <0 0x54600000 0x0 0x200000>;
+ 		};
+ 
+ 		/* 12 MiB reserved for OP-TEE (BL32)
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+index 6d82dea3675b1..40dfa70436002 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+@@ -855,12 +855,13 @@
+ 			required-opps = <&rpmhpd_opp_nom>;
+ 
+ 			iommus = <&apps_smmu 0xe0 0x0>;
++			dma-coherent;
+ 
+ 			clocks = <&gcc GCC_UFS_PHY_AXI_CLK>,
+ 				 <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+ 				 <&gcc GCC_UFS_PHY_AHB_CLK>,
+ 				 <&gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>,
+-				 <&rpmhcc RPMH_CXO_CLK>,
++				 <&gcc GCC_UFS_REF_CLKREF_CLK>,
+ 				 <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>,
+ 				 <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>,
+ 				 <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>;
+@@ -891,7 +892,7 @@
+ 			ranges;
+ 			clock-names = "ref",
+ 				      "ref_aux";
+-			clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>,
++			clocks = <&gcc GCC_UFS_CARD_CLKREF_CLK>,
+ 				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+ 
+ 			resets = <&ufs_mem_hc 0>;
+@@ -923,12 +924,13 @@
+ 			power-domains = <&gcc UFS_CARD_GDSC>;
+ 
+ 			iommus = <&apps_smmu 0x4a0 0x0>;
++			dma-coherent;
+ 
+ 			clocks = <&gcc GCC_UFS_CARD_AXI_CLK>,
+ 				 <&gcc GCC_AGGRE_UFS_CARD_AXI_CLK>,
+ 				 <&gcc GCC_UFS_CARD_AHB_CLK>,
+ 				 <&gcc GCC_UFS_CARD_UNIPRO_CORE_CLK>,
+-				 <&rpmhcc RPMH_CXO_CLK>,
++				 <&gcc GCC_UFS_REF_CLKREF_CLK>,
+ 				 <&gcc GCC_UFS_CARD_TX_SYMBOL_0_CLK>,
+ 				 <&gcc GCC_UFS_CARD_RX_SYMBOL_0_CLK>,
+ 				 <&gcc GCC_UFS_CARD_RX_SYMBOL_1_CLK>;
+@@ -959,7 +961,7 @@
+ 			ranges;
+ 			clock-names = "ref",
+ 				      "ref_aux";
+-			clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>,
++			clocks = <&gcc GCC_UFS_1_CARD_CLKREF_CLK>,
+ 				 <&gcc GCC_UFS_CARD_PHY_AUX_CLK>;
+ 
+ 			resets = <&ufs_card_hc 0>;
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+index b2eddcd875069..a2eda0f67cfb0 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+@@ -1123,7 +1123,10 @@
+ 
+ /* PINCTRL - additions to nodes defined in sdm845.dtsi */
+ &qup_spi2_default {
+-	drive-strength = <16>;
++	pinconf {
++		pins = "gpio27", "gpio28", "gpio29", "gpio30";
++		drive-strength = <16>;
++	};
+ };
+ 
+ &qup_uart3_default{
+diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+index be59a8ba9c1fe..74f43da51fa50 100644
+--- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
++++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+@@ -487,8 +487,10 @@
+ };
+ 
+ &qup_i2c12_default {
+-	drive-strength = <2>;
+-	bias-disable;
++	pinmux {
++		drive-strength = <2>;
++		bias-disable;
++	};
+ };
+ 
+ &qup_uart6_default {
+diff --git a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
+index f954fe5cb61ab..d028a7eb364a6 100644
+--- a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
++++ b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
+@@ -415,8 +415,10 @@
+ };
+ 
+ &qup_i2c12_default {
+-	drive-strength = <2>;
+-	bias-disable;
++	pinmux {
++		drive-strength = <2>;
++		bias-disable;
++	};
+ };
+ 
+ &qup_uart6_default {
+diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
+index ce190ee18a201..7e5140d894eaf 100644
+--- a/arch/arm64/kernel/stacktrace.c
++++ b/arch/arm64/kernel/stacktrace.c
+@@ -23,8 +23,8 @@
+  *
+  * The regs must be on a stack currently owned by the calling task.
+  */
+-static inline void unwind_init_from_regs(struct unwind_state *state,
+-					 struct pt_regs *regs)
++static __always_inline void unwind_init_from_regs(struct unwind_state *state,
++						  struct pt_regs *regs)
+ {
+ 	unwind_init_common(state, current);
+ 
+@@ -58,8 +58,8 @@ static __always_inline void unwind_init_from_caller(struct unwind_state *state)
+  * duration of the unwind, or the unwind will be bogus. It is never valid to
+  * call this for the current task.
+  */
+-static inline void unwind_init_from_task(struct unwind_state *state,
+-					 struct task_struct *task)
++static __always_inline void unwind_init_from_task(struct unwind_state *state,
++						  struct task_struct *task)
+ {
+ 	unwind_init_common(state, task);
+ 
+@@ -190,7 +190,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl)
+ 	barrier();
+ }
+ 
+-noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
++noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry,
+ 			      void *cookie, struct task_struct *task,
+ 			      struct pt_regs *regs)
+ {
+diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
+index ecd0288544698..68ae77069d23f 100644
+--- a/arch/parisc/include/asm/pgtable.h
++++ b/arch/parisc/include/asm/pgtable.h
+@@ -166,8 +166,8 @@ extern void __update_cache(pte_t pte);
+ 
+ /* This calculates the number of initial pages we need for the initial
+  * page tables */
+-#if (KERNEL_INITIAL_ORDER) >= (PMD_SHIFT)
+-# define PT_INITIAL	(1 << (KERNEL_INITIAL_ORDER - PMD_SHIFT))
++#if (KERNEL_INITIAL_ORDER) >= (PLD_SHIFT + BITS_PER_PTE)
++# define PT_INITIAL	(1 << (KERNEL_INITIAL_ORDER - PLD_SHIFT - BITS_PER_PTE))
+ #else
+ # define PT_INITIAL	(1)  /* all initial PTEs fit into one page */
+ #endif
+diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
+index 6a7e315bcc2e5..a115315d88e69 100644
+--- a/arch/parisc/kernel/firmware.c
++++ b/arch/parisc/kernel/firmware.c
+@@ -1288,9 +1288,8 @@ void pdc_io_reset_devices(void)
+ 
+ #endif /* defined(BOOTLOADER) */
+ 
+-/* locked by pdc_console_lock */
+-static int __attribute__((aligned(8)))   iodc_retbuf[32];
+-static char __attribute__((aligned(64))) iodc_dbuf[4096];
++/* locked by pdc_lock */
++static char iodc_dbuf[4096] __page_aligned_bss;
+ 
+ /**
+  * pdc_iodc_print - Console print using IODC.
+@@ -1307,6 +1306,9 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
+ 	unsigned int i;
+ 	unsigned long flags;
+ 
++	count = min_t(unsigned int, count, sizeof(iodc_dbuf));
++
++	spin_lock_irqsave(&pdc_lock, flags);
+ 	for (i = 0; i < count;) {
+ 		switch(str[i]) {
+ 		case '\n':
+@@ -1322,12 +1324,11 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
+ 	}
+ 
+ print:
+-        spin_lock_irqsave(&pdc_lock, flags);
+-        real32_call(PAGE0->mem_cons.iodc_io,
+-                    (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
+-                    PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
+-                    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), i, 0);
+-        spin_unlock_irqrestore(&pdc_lock, flags);
++	real32_call(PAGE0->mem_cons.iodc_io,
++		(unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
++		PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
++		__pa(pdc_result), 0, __pa(iodc_dbuf), i, 0);
++	spin_unlock_irqrestore(&pdc_lock, flags);
+ 
+ 	return i;
+ }
+@@ -1354,10 +1355,11 @@ int pdc_iodc_getc(void)
+ 	real32_call(PAGE0->mem_kbd.iodc_io,
+ 		    (unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
+ 		    PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers), 
+-		    __pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
++		    __pa(pdc_result), 0, __pa(iodc_dbuf), 1, 0);
+ 
+ 	ch = *iodc_dbuf;
+-	status = *iodc_retbuf;
++	/* like convert_to_wide() but for first return value only: */
++	status = *(int *)&pdc_result;
+ 	spin_unlock_irqrestore(&pdc_lock, flags);
+ 
+ 	if (status == 0)
+diff --git a/arch/parisc/kernel/vdso32/Makefile b/arch/parisc/kernel/vdso32/Makefile
+index 85b1c6d261d12..4459a48d23033 100644
+--- a/arch/parisc/kernel/vdso32/Makefile
++++ b/arch/parisc/kernel/vdso32/Makefile
+@@ -26,7 +26,7 @@ $(obj)/vdso32_wrapper.o : $(obj)/vdso32.so FORCE
+ 
+ # Force dependency (incbin is bad)
+ # link rule for the .so file, .lds has to be first
+-$(obj)/vdso32.so: $(src)/vdso32.lds $(obj-vdso32) $(obj-cvdso32) $(VDSO_LIBGCC)
++$(obj)/vdso32.so: $(src)/vdso32.lds $(obj-vdso32) $(obj-cvdso32) $(VDSO_LIBGCC) FORCE
+ 	$(call if_changed,vdso32ld)
+ 
+ # assembly rules for the .S files
+@@ -38,7 +38,7 @@ $(obj-cvdso32): %.o: %.c FORCE
+ 
+ # actual build commands
+ quiet_cmd_vdso32ld = VDSO32L $@
+-      cmd_vdso32ld = $(CROSS32CC) $(c_flags) -Wl,-T $^ -o $@
++      cmd_vdso32ld = $(CROSS32CC) $(c_flags) -Wl,-T $(filter-out FORCE, $^) -o $@
+ quiet_cmd_vdso32as = VDSO32A $@
+       cmd_vdso32as = $(CROSS32CC) $(a_flags) -c -o $@ $<
+ quiet_cmd_vdso32cc = VDSO32C $@
+diff --git a/arch/parisc/kernel/vdso64/Makefile b/arch/parisc/kernel/vdso64/Makefile
+index a30f5ec5eb4bf..f3d6045793f4c 100644
+--- a/arch/parisc/kernel/vdso64/Makefile
++++ b/arch/parisc/kernel/vdso64/Makefile
+@@ -26,7 +26,7 @@ $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so FORCE
+ 
+ # Force dependency (incbin is bad)
+ # link rule for the .so file, .lds has to be first
+-$(obj)/vdso64.so: $(src)/vdso64.lds $(obj-vdso64) $(VDSO_LIBGCC)
++$(obj)/vdso64.so: $(src)/vdso64.lds $(obj-vdso64) $(VDSO_LIBGCC) FORCE
+ 	$(call if_changed,vdso64ld)
+ 
+ # assembly rules for the .S files
+@@ -35,7 +35,7 @@ $(obj-vdso64): %.o: %.S FORCE
+ 
+ # actual build commands
+ quiet_cmd_vdso64ld = VDSO64L $@
+-      cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $^ -o $@
++      cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $(filter-out FORCE, $^) -o $@
+ quiet_cmd_vdso64as = VDSO64A $@
+       cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
+ 
+diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h
+index 3cee7115441b4..e3d1f377bc5b5 100644
+--- a/arch/powerpc/include/asm/ftrace.h
++++ b/arch/powerpc/include/asm/ftrace.h
+@@ -64,17 +64,6 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
+  * those.
+  */
+ #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
+-#ifdef CONFIG_PPC64_ELF_ABI_V1
+-static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
+-{
+-	/* We need to skip past the initial dot, and the __se_sys alias */
+-	return !strcmp(sym + 1, name) ||
+-		(!strncmp(sym, ".__se_sys", 9) && !strcmp(sym + 6, name)) ||
+-		(!strncmp(sym, ".ppc_", 5) && !strcmp(sym + 5, name + 4)) ||
+-		(!strncmp(sym, ".ppc32_", 7) && !strcmp(sym + 7, name + 4)) ||
+-		(!strncmp(sym, ".ppc64_", 7) && !strcmp(sym + 7, name + 4));
+-}
+-#else
+ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
+ {
+ 	return !strcmp(sym, name) ||
+@@ -83,7 +72,6 @@ static inline bool arch_syscall_match_sym_name(const char *sym, const char *name
+ 		(!strncmp(sym, "ppc32_", 6) && !strcmp(sym + 6, name + 4)) ||
+ 		(!strncmp(sym, "ppc64_", 6) && !strcmp(sym + 6, name + 4));
+ }
+-#endif /* CONFIG_PPC64_ELF_ABI_V1 */
+ #endif /* CONFIG_FTRACE_SYSCALLS */
+ 
+ #if defined(CONFIG_PPC64) && defined(CONFIG_FUNCTION_TRACER)
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index 9d5b7fa1b6225..76a3d8280e67e 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -493,7 +493,7 @@ config KEXEC_FILE
+ 	select KEXEC_CORE
+ 	select KEXEC_ELF
+ 	select HAVE_IMA_KEXEC if IMA
+-	depends on 64BIT
++	depends on 64BIT && MMU
+ 	help
+ 	  This is new version of kexec system call. This system call is
+ 	  file based and takes file descriptors as system call argument
+diff --git a/arch/riscv/include/asm/kexec.h b/arch/riscv/include/asm/kexec.h
+index eee260e8ab308..2b56769cb530c 100644
+--- a/arch/riscv/include/asm/kexec.h
++++ b/arch/riscv/include/asm/kexec.h
+@@ -39,6 +39,7 @@ crash_setup_regs(struct pt_regs *newregs,
+ #define ARCH_HAS_KIMAGE_ARCH
+ 
+ struct kimage_arch {
++	void *fdt; /* For CONFIG_KEXEC_FILE */
+ 	unsigned long fdt_addr;
+ };
+ 
+@@ -62,6 +63,10 @@ int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
+ 				     const Elf_Shdr *relsec,
+ 				     const Elf_Shdr *symtab);
+ #define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add
++
++struct kimage;
++int arch_kimage_file_post_load_cleanup(struct kimage *image);
++#define arch_kimage_file_post_load_cleanup arch_kimage_file_post_load_cleanup
+ #endif
+ 
+ #endif
+diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
+index 0099dc1161683..5ff1f19fd45c2 100644
+--- a/arch/riscv/include/asm/mmu.h
++++ b/arch/riscv/include/asm/mmu.h
+@@ -19,6 +19,8 @@ typedef struct {
+ #ifdef CONFIG_SMP
+ 	/* A local icache flush is needed before user execution can resume. */
+ 	cpumask_t icache_stale_mask;
++	/* A local tlb flush is needed before user execution can resume. */
++	cpumask_t tlb_stale_mask;
+ #endif
+ } mm_context_t;
+ 
+diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
+index 7ec936910a96e..330f75fe12787 100644
+--- a/arch/riscv/include/asm/pgtable.h
++++ b/arch/riscv/include/asm/pgtable.h
+@@ -415,7 +415,7 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
+ 	 * Relying on flush_tlb_fix_spurious_fault would suffice, but
+ 	 * the extra traps reduce performance.  So, eagerly SFENCE.VMA.
+ 	 */
+-	local_flush_tlb_page(address);
++	flush_tlb_page(vma, address);
+ }
+ 
+ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
+diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
+index 801019381dea3..907b9efd39a87 100644
+--- a/arch/riscv/include/asm/tlbflush.h
++++ b/arch/riscv/include/asm/tlbflush.h
+@@ -22,6 +22,24 @@ static inline void local_flush_tlb_page(unsigned long addr)
+ {
+ 	ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory"));
+ }
++
++static inline void local_flush_tlb_all_asid(unsigned long asid)
++{
++	__asm__ __volatile__ ("sfence.vma x0, %0"
++			:
++			: "r" (asid)
++			: "memory");
++}
++
++static inline void local_flush_tlb_page_asid(unsigned long addr,
++		unsigned long asid)
++{
++	__asm__ __volatile__ ("sfence.vma %0, %1"
++			:
++			: "r" (addr), "r" (asid)
++			: "memory");
++}
++
+ #else /* CONFIG_MMU */
+ #define local_flush_tlb_all()			do { } while (0)
+ #define local_flush_tlb_page(addr)		do { } while (0)
+diff --git a/arch/riscv/kernel/elf_kexec.c b/arch/riscv/kernel/elf_kexec.c
+index 0cb94992c15b3..5372b708fae21 100644
+--- a/arch/riscv/kernel/elf_kexec.c
++++ b/arch/riscv/kernel/elf_kexec.c
+@@ -21,6 +21,18 @@
+ #include <linux/memblock.h>
+ #include <asm/setup.h>
+ 
++int arch_kimage_file_post_load_cleanup(struct kimage *image)
++{
++	kvfree(image->arch.fdt);
++	image->arch.fdt = NULL;
++
++	vfree(image->elf_headers);
++	image->elf_headers = NULL;
++	image->elf_headers_sz = 0;
++
++	return kexec_image_post_load_cleanup_default(image);
++}
++
+ static int riscv_kexec_elf_load(struct kimage *image, struct elfhdr *ehdr,
+ 				struct kexec_elf_info *elf_info, unsigned long old_pbase,
+ 				unsigned long new_pbase)
+@@ -298,6 +310,8 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,
+ 		pr_err("Error add DTB kbuf ret=%d\n", ret);
+ 		goto out_free_fdt;
+ 	}
++	/* Cache the fdt buffer address for memory cleanup */
++	image->arch.fdt = fdt;
+ 	pr_notice("Loaded device tree at 0x%lx\n", kbuf.mem);
+ 	goto out;
+ 
+diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c
+index 08d11a53f39e7..bcfe9eb55f80f 100644
+--- a/arch/riscv/kernel/stacktrace.c
++++ b/arch/riscv/kernel/stacktrace.c
+@@ -58,7 +58,7 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
+ 		} else {
+ 			fp = frame->fp;
+ 			pc = ftrace_graph_ret_addr(current, NULL, frame->ra,
+-						   (unsigned long *)(fp - 8));
++						   &frame->ra);
+ 		}
+ 
+ 	}
+diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c
+index 7acbfbd14557e..80ce9caba8d22 100644
+--- a/arch/riscv/mm/context.c
++++ b/arch/riscv/mm/context.c
+@@ -196,6 +196,16 @@ switch_mm_fast:
+ 
+ 	if (need_flush_tlb)
+ 		local_flush_tlb_all();
++#ifdef CONFIG_SMP
++	else {
++		cpumask_t *mask = &mm->context.tlb_stale_mask;
++
++		if (cpumask_test_cpu(cpu, mask)) {
++			cpumask_clear_cpu(cpu, mask);
++			local_flush_tlb_all_asid(cntx & asid_mask);
++		}
++	}
++#endif
+ }
+ 
+ static void set_mm_noasid(struct mm_struct *mm)
+diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
+index 37ed760d007c3..ce7dfc81bb3fe 100644
+--- a/arch/riscv/mm/tlbflush.c
++++ b/arch/riscv/mm/tlbflush.c
+@@ -5,23 +5,7 @@
+ #include <linux/sched.h>
+ #include <asm/sbi.h>
+ #include <asm/mmu_context.h>
+-
+-static inline void local_flush_tlb_all_asid(unsigned long asid)
+-{
+-	__asm__ __volatile__ ("sfence.vma x0, %0"
+-			:
+-			: "r" (asid)
+-			: "memory");
+-}
+-
+-static inline void local_flush_tlb_page_asid(unsigned long addr,
+-		unsigned long asid)
+-{
+-	__asm__ __volatile__ ("sfence.vma %0, %1"
+-			:
+-			: "r" (addr), "r" (asid)
+-			: "memory");
+-}
++#include <asm/tlbflush.h>
+ 
+ void flush_tlb_all(void)
+ {
+@@ -31,6 +15,7 @@ void flush_tlb_all(void)
+ static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start,
+ 				  unsigned long size, unsigned long stride)
+ {
++	struct cpumask *pmask = &mm->context.tlb_stale_mask;
+ 	struct cpumask *cmask = mm_cpumask(mm);
+ 	unsigned int cpuid;
+ 	bool broadcast;
+@@ -44,6 +29,15 @@ static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start,
+ 	if (static_branch_unlikely(&use_asid_allocator)) {
+ 		unsigned long asid = atomic_long_read(&mm->context.id);
+ 
++		/*
++		 * TLB will be immediately flushed on harts concurrently
++		 * executing this MM context. TLB flush on other harts
++		 * is deferred until this MM context migrates there.
++		 */
++		cpumask_setall(pmask);
++		cpumask_clear_cpu(cpuid, pmask);
++		cpumask_andnot(pmask, pmask, cmask);
++
+ 		if (broadcast) {
+ 			sbi_remote_sfence_vma_asid(cmask, start, size, asid);
+ 		} else if (size <= stride) {
+diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
+index 2adeaf4de4df6..b363fddc2a89e 100644
+--- a/arch/x86/events/intel/uncore.h
++++ b/arch/x86/events/intel/uncore.h
+@@ -2,6 +2,7 @@
+ #include <linux/slab.h>
+ #include <linux/pci.h>
+ #include <asm/apicdef.h>
++#include <asm/intel-family.h>
+ #include <linux/io-64-nonatomic-lo-hi.h>
+ 
+ #include <linux/perf_event.h>
+diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
+index fcd95e93f479a..8f371f3cbbd24 100644
+--- a/arch/x86/events/intel/uncore_snbep.c
++++ b/arch/x86/events/intel/uncore_snbep.c
+@@ -3804,6 +3804,21 @@ static const struct attribute_group *skx_iio_attr_update[] = {
+ 	NULL,
+ };
+ 
++static void pmu_clear_mapping_attr(const struct attribute_group **groups,
++				   struct attribute_group *ag)
++{
++	int i;
++
++	for (i = 0; groups[i]; i++) {
++		if (groups[i] == ag) {
++			for (i++; groups[i]; i++)
++				groups[i - 1] = groups[i];
++			groups[i - 1] = NULL;
++			break;
++		}
++	}
++}
++
+ static int
+ pmu_iio_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
+ {
+@@ -3852,7 +3867,7 @@ clear_attrs:
+ clear_topology:
+ 	kfree(type->topology);
+ clear_attr_update:
+-	type->attr_update = NULL;
++	pmu_clear_mapping_attr(type->attr_update, ag);
+ 	return ret;
+ }
+ 
+@@ -5144,6 +5159,11 @@ static int icx_iio_get_topology(struct intel_uncore_type *type)
+ 
+ static int icx_iio_set_mapping(struct intel_uncore_type *type)
+ {
++	/* Detect ICX-D system. This case is not supported */
++	if (boot_cpu_data.x86_model == INTEL_FAM6_ICELAKE_D) {
++		pmu_clear_mapping_attr(type->attr_update, &icx_iio_mapping_group);
++		return -EPERM;
++	}
+ 	return pmu_iio_set_mapping(type, &icx_iio_mapping_group);
+ }
+ 
+diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c
+index 1c87501e0fa3d..10fb5b5c9efa4 100644
+--- a/arch/x86/kernel/cpu/mce/amd.c
++++ b/arch/x86/kernel/cpu/mce/amd.c
+@@ -788,6 +788,24 @@ _log_error_bank(unsigned int bank, u32 msr_stat, u32 msr_addr, u64 misc)
+ 	return status & MCI_STATUS_DEFERRED;
+ }
+ 
++static bool _log_error_deferred(unsigned int bank, u32 misc)
++{
++	if (!_log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS),
++			     mca_msr_reg(bank, MCA_ADDR), misc))
++		return false;
++
++	/*
++	 * Non-SMCA systems don't have MCA_DESTAT/MCA_DEADDR registers.
++	 * Return true here to avoid accessing these registers.
++	 */
++	if (!mce_flags.smca)
++		return true;
++
++	/* Clear MCA_DESTAT if the deferred error was logged from MCA_STATUS. */
++	wrmsrl(MSR_AMD64_SMCA_MCx_DESTAT(bank), 0);
++	return true;
++}
++
+ /*
+  * We have three scenarios for checking for Deferred errors:
+  *
+@@ -799,19 +817,8 @@ _log_error_bank(unsigned int bank, u32 msr_stat, u32 msr_addr, u64 misc)
+  */
+ static void log_error_deferred(unsigned int bank)
+ {
+-	bool defrd;
+-
+-	defrd = _log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS),
+-				mca_msr_reg(bank, MCA_ADDR), 0);
+-
+-	if (!mce_flags.smca)
+-		return;
+-
+-	/* Clear MCA_DESTAT if we logged the deferred error from MCA_STATUS. */
+-	if (defrd) {
+-		wrmsrl(MSR_AMD64_SMCA_MCx_DESTAT(bank), 0);
++	if (_log_error_deferred(bank, 0))
+ 		return;
+-	}
+ 
+ 	/*
+ 	 * Only deferred errors are logged in MCA_DE{STAT,ADDR} so just check
+@@ -832,7 +839,7 @@ static void amd_deferred_error_interrupt(void)
+ 
+ static void log_error_thresholding(unsigned int bank, u64 misc)
+ {
+-	_log_error_bank(bank, mca_msr_reg(bank, MCA_STATUS), mca_msr_reg(bank, MCA_ADDR), misc);
++	_log_error_deferred(bank, misc);
+ }
+ 
+ static void log_and_reset_block(struct threshold_block *block)
+diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c
+index 025c8f0cd948c..40e74a9bef07a 100644
+--- a/arch/x86/kernel/cpu/microcode/intel.c
++++ b/arch/x86/kernel/cpu/microcode/intel.c
+@@ -621,7 +621,6 @@ void load_ucode_intel_ap(void)
+ 	else
+ 		iup = &intel_ucode_patch;
+ 
+-reget:
+ 	if (!*iup) {
+ 		patch = __load_ucode_intel(&uci);
+ 		if (!patch)
+@@ -632,12 +631,7 @@ reget:
+ 
+ 	uci.mc = *iup;
+ 
+-	if (apply_microcode_early(&uci, true)) {
+-		/* Mixed-silicon system? Try to refetch the proper patch: */
+-		*iup = NULL;
+-
+-		goto reget;
+-	}
++	apply_microcode_early(&uci, true);
+ }
+ 
+ static struct microcode_intel *find_patch(struct ucode_cpu_info *uci)
+diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
+index 59e543b95a3c6..c2dde46a538e7 100644
+--- a/arch/x86/kernel/fpu/xstate.c
++++ b/arch/x86/kernel/fpu/xstate.c
+@@ -440,8 +440,8 @@ static void __init __xstate_dump_leaves(void)
+ 	}
+ }
+ 
+-#define XSTATE_WARN_ON(x) do {							\
+-	if (WARN_ONCE(x, "XSAVE consistency problem, dumping leaves")) {	\
++#define XSTATE_WARN_ON(x, fmt, ...) do {					\
++	if (WARN_ONCE(x, "XSAVE consistency problem: " fmt, ##__VA_ARGS__)) {	\
+ 		__xstate_dump_leaves();						\
+ 	}									\
+ } while (0)
+@@ -554,8 +554,7 @@ static bool __init check_xstate_against_struct(int nr)
+ 	    (nr >= XFEATURE_MAX) ||
+ 	    (nr == XFEATURE_PT_UNIMPLEMENTED_SO_FAR) ||
+ 	    ((nr >= XFEATURE_RSRVD_COMP_11) && (nr <= XFEATURE_RSRVD_COMP_16))) {
+-		WARN_ONCE(1, "no structure for xstate: %d\n", nr);
+-		XSTATE_WARN_ON(1);
++		XSTATE_WARN_ON(1, "No structure for xstate: %d\n", nr);
+ 		return false;
+ 	}
+ 	return true;
+@@ -598,12 +597,13 @@ static bool __init paranoid_xstate_size_valid(unsigned int kernel_size)
+ 		 * XSAVES.
+ 		 */
+ 		if (!xsaves && xfeature_is_supervisor(i)) {
+-			XSTATE_WARN_ON(1);
++			XSTATE_WARN_ON(1, "Got supervisor feature %d, but XSAVES not advertised\n", i);
+ 			return false;
+ 		}
+ 	}
+ 	size = xstate_calculate_size(fpu_kernel_cfg.max_features, compacted);
+-	XSTATE_WARN_ON(size != kernel_size);
++	XSTATE_WARN_ON(size != kernel_size,
++		       "size %u != kernel_size %u\n", size, kernel_size);
+ 	return size == kernel_size;
+ }
+ 
+diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
+index bd165004776d9..e07234ec7e237 100644
+--- a/arch/x86/kernel/ftrace.c
++++ b/arch/x86/kernel/ftrace.c
+@@ -217,7 +217,9 @@ void ftrace_replace_code(int enable)
+ 
+ 		ret = ftrace_verify_code(rec->ip, old);
+ 		if (ret) {
++			ftrace_expected = old;
+ 			ftrace_bug(ret, rec);
++			ftrace_expected = NULL;
+ 			return;
+ 		}
+ 	}
+diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
+index 4c3c27b6aea3b..c6dd7ae68c8fb 100644
+--- a/arch/x86/kernel/kprobes/core.c
++++ b/arch/x86/kernel/kprobes/core.c
+@@ -37,6 +37,7 @@
+ #include <linux/extable.h>
+ #include <linux/kdebug.h>
+ #include <linux/kallsyms.h>
++#include <linux/kgdb.h>
+ #include <linux/ftrace.h>
+ #include <linux/kasan.h>
+ #include <linux/moduleloader.h>
+@@ -283,12 +284,15 @@ static int can_probe(unsigned long paddr)
+ 		if (ret < 0)
+ 			return 0;
+ 
++#ifdef CONFIG_KGDB
+ 		/*
+-		 * Another debugging subsystem might insert this breakpoint.
+-		 * In that case, we can't recover it.
++		 * If there is a dynamically installed kgdb sw breakpoint,
++		 * this function should not be probed.
+ 		 */
+-		if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
++		if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
++		    kgdb_has_hit_break(addr))
+ 			return 0;
++#endif
+ 		addr += insn.length;
+ 	}
+ 
+diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
+index e6b8c5362b945..e57e07b0edb64 100644
+--- a/arch/x86/kernel/kprobes/opt.c
++++ b/arch/x86/kernel/kprobes/opt.c
+@@ -15,6 +15,7 @@
+ #include <linux/extable.h>
+ #include <linux/kdebug.h>
+ #include <linux/kallsyms.h>
++#include <linux/kgdb.h>
+ #include <linux/ftrace.h>
+ #include <linux/objtool.h>
+ #include <linux/pgtable.h>
+@@ -279,19 +280,6 @@ static int insn_is_indirect_jump(struct insn *insn)
+ 	return ret;
+ }
+ 
+-static bool is_padding_int3(unsigned long addr, unsigned long eaddr)
+-{
+-	unsigned char ops;
+-
+-	for (; addr < eaddr; addr++) {
+-		if (get_kernel_nofault(ops, (void *)addr) < 0 ||
+-		    ops != INT3_INSN_OPCODE)
+-			return false;
+-	}
+-
+-	return true;
+-}
+-
+ /* Decode whole function to ensure any instructions don't jump into target */
+ static int can_optimize(unsigned long paddr)
+ {
+@@ -334,15 +322,15 @@ static int can_optimize(unsigned long paddr)
+ 		ret = insn_decode_kernel(&insn, (void *)recovered_insn);
+ 		if (ret < 0)
+ 			return 0;
+-
++#ifdef CONFIG_KGDB
+ 		/*
+-		 * In the case of detecting unknown breakpoint, this could be
+-		 * a padding INT3 between functions. Let's check that all the
+-		 * rest of the bytes are also INT3.
++		 * If there is a dynamically installed kgdb sw breakpoint,
++		 * this function should not be probed.
+ 		 */
+-		if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
+-			return is_padding_int3(addr, paddr - offset + size) ? 1 : 0;
+-
++		if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
++		    kgdb_has_hit_break(addr))
++			return 0;
++#endif
+ 		/* Recover address */
+ 		insn.kaddr = (void *)addr;
+ 		insn.next_byte = (void *)(addr + insn.length);
+diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
+index 9dda989a1cf01..4064ce1941ea7 100644
+--- a/arch/x86/kvm/lapic.c
++++ b/arch/x86/kvm/lapic.c
+@@ -2722,8 +2722,6 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
+ 			icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR);
+ 			__kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32);
+ 		}
+-	} else {
+-		kvm_lapic_xapic_id_updated(vcpu->arch.apic);
+ 	}
+ 
+ 	return 0;
+@@ -2759,6 +2757,9 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s)
+ 	}
+ 	memcpy(vcpu->arch.apic->regs, s->regs, sizeof(*s));
+ 
++	if (!apic_x2apic_mode(apic))
++		kvm_lapic_xapic_id_updated(apic);
++
+ 	atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY);
+ 	kvm_recalculate_apic_map(vcpu->kvm);
+ 	kvm_apic_set_version(vcpu);
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index f56cc2382edf9..cf8fbbd74f9c3 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -4953,24 +4953,35 @@ static int handle_vmxon(struct kvm_vcpu *vcpu)
+ 		| FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;
+ 
+ 	/*
+-	 * Note, KVM cannot rely on hardware to perform the CR0/CR4 #UD checks
+-	 * that have higher priority than VM-Exit (see Intel SDM's pseudocode
+-	 * for VMXON), as KVM must load valid CR0/CR4 values into hardware while
+-	 * running the guest, i.e. KVM needs to check the _guest_ values.
++	 * Manually check CR4.VMXE checks, KVM must force CR4.VMXE=1 to enter
++	 * the guest and so cannot rely on hardware to perform the check,
++	 * which has higher priority than VM-Exit (see Intel SDM's pseudocode
++	 * for VMXON).
+ 	 *
+-	 * Rely on hardware for the other two pre-VM-Exit checks, !VM86 and
+-	 * !COMPATIBILITY modes.  KVM may run the guest in VM86 to emulate Real
+-	 * Mode, but KVM will never take the guest out of those modes.
++	 * Rely on hardware for the other pre-VM-Exit checks, CR0.PE=1, !VM86
++	 * and !COMPATIBILITY modes.  For an unrestricted guest, KVM doesn't
++	 * force any of the relevant guest state.  For a restricted guest, KVM
++	 * does force CR0.PE=1, but only to also force VM86 in order to emulate
++	 * Real Mode, and so there's no need to check CR0.PE manually.
+ 	 */
+-	if (!nested_host_cr0_valid(vcpu, kvm_read_cr0(vcpu)) ||
+-	    !nested_host_cr4_valid(vcpu, kvm_read_cr4(vcpu))) {
++	if (!kvm_read_cr4_bits(vcpu, X86_CR4_VMXE)) {
+ 		kvm_queue_exception(vcpu, UD_VECTOR);
+ 		return 1;
+ 	}
+ 
+ 	/*
+-	 * CPL=0 and all other checks that are lower priority than VM-Exit must
+-	 * be checked manually.
++	 * The CPL is checked for "not in VMX operation" and for "in VMX root",
++	 * and has higher priority than the VM-Fail due to being post-VMXON,
++	 * i.e. VMXON #GPs outside of VMX non-root if CPL!=0.  In VMX non-root,
++	 * VMXON causes VM-Exit and KVM unconditionally forwards VMXON VM-Exits
++	 * from L2 to L1, i.e. there's no need to check for the vCPU being in
++	 * VMX non-root.
++	 *
++	 * Forwarding the VM-Exit unconditionally, i.e. without performing the
++	 * #UD checks (see above), is functionally ok because KVM doesn't allow
++	 * L1 to run L2 without CR4.VMXE=0, and because KVM never modifies L2's
++	 * CR0 or CR4, i.e. it's L2's responsibility to emulate #UDs that are
++	 * missed by hardware due to shadowing CR0 and/or CR4.
+ 	 */
+ 	if (vmx_get_cpl(vcpu)) {
+ 		kvm_inject_gp(vcpu, 0);
+@@ -4980,6 +4991,17 @@ static int handle_vmxon(struct kvm_vcpu *vcpu)
+ 	if (vmx->nested.vmxon)
+ 		return nested_vmx_fail(vcpu, VMXERR_VMXON_IN_VMX_ROOT_OPERATION);
+ 
++	/*
++	 * Invalid CR0/CR4 generates #GP.  These checks are performed if and
++	 * only if the vCPU isn't already in VMX operation, i.e. effectively
++	 * have lower priority than the VM-Fail above.
++	 */
++	if (!nested_host_cr0_valid(vcpu, kvm_read_cr0(vcpu)) ||
++	    !nested_host_cr4_valid(vcpu, kvm_read_cr4(vcpu))) {
++		kvm_inject_gp(vcpu, 0);
++		return 1;
++	}
++
+ 	if ((vmx->msr_ia32_feature_control & VMXON_NEEDED_FEATURES)
+ 			!= VMXON_NEEDED_FEATURES) {
+ 		kvm_inject_gp(vcpu, 0);
+@@ -6663,7 +6685,8 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps)
+ 		SECONDARY_EXEC_ENABLE_INVPCID |
+ 		SECONDARY_EXEC_RDSEED_EXITING |
+ 		SECONDARY_EXEC_XSAVES |
+-		SECONDARY_EXEC_TSC_SCALING;
++		SECONDARY_EXEC_TSC_SCALING |
++		SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
+ 
+ 	/*
+ 	 * We can emulate "VMCS shadowing," even if the hardware
+diff --git a/arch/x86/kvm/vmx/sgx.c b/arch/x86/kvm/vmx/sgx.c
+index aba8cebdc587f..3ed7d35fe9658 100644
+--- a/arch/x86/kvm/vmx/sgx.c
++++ b/arch/x86/kvm/vmx/sgx.c
+@@ -182,8 +182,10 @@ static int __handle_encls_ecreate(struct kvm_vcpu *vcpu,
+ 	/* Enforce CPUID restriction on max enclave size. */
+ 	max_size_log2 = (attributes & SGX_ATTR_MODE64BIT) ? sgx_12_0->edx >> 8 :
+ 							    sgx_12_0->edx;
+-	if (size >= BIT_ULL(max_size_log2))
++	if (size >= BIT_ULL(max_size_log2)) {
+ 		kvm_inject_gp(vcpu, 0);
++		return 1;
++	}
+ 
+ 	/*
+ 	 * sgx_virt_ecreate() returns:
+diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
+index b0bc8897c924f..2a31b1ab0c9f2 100644
+--- a/arch/xtensa/kernel/xtensa_ksyms.c
++++ b/arch/xtensa/kernel/xtensa_ksyms.c
+@@ -62,6 +62,7 @@ extern int __modsi3(int, int);
+ extern int __mulsi3(int, int);
+ extern unsigned int __udivsi3(unsigned int, unsigned int);
+ extern unsigned int __umodsi3(unsigned int, unsigned int);
++extern unsigned long long __umulsidi3(unsigned int, unsigned int);
+ 
+ EXPORT_SYMBOL(__ashldi3);
+ EXPORT_SYMBOL(__ashrdi3);
+@@ -71,6 +72,7 @@ EXPORT_SYMBOL(__modsi3);
+ EXPORT_SYMBOL(__mulsi3);
+ EXPORT_SYMBOL(__udivsi3);
+ EXPORT_SYMBOL(__umodsi3);
++EXPORT_SYMBOL(__umulsidi3);
+ 
+ unsigned int __sync_fetch_and_and_4(volatile void *p, unsigned int v)
+ {
+diff --git a/arch/xtensa/lib/Makefile b/arch/xtensa/lib/Makefile
+index d4e9c397e3fde..7ecef0519a27c 100644
+--- a/arch/xtensa/lib/Makefile
++++ b/arch/xtensa/lib/Makefile
+@@ -5,7 +5,7 @@
+ 
+ lib-y	+= memcopy.o memset.o checksum.o \
+ 	   ashldi3.o ashrdi3.o lshrdi3.o \
+-	   divsi3.o udivsi3.o modsi3.o umodsi3.o mulsi3.o \
++	   divsi3.o udivsi3.o modsi3.o umodsi3.o mulsi3.o umulsidi3.o \
+ 	   usercopy.o strncpy_user.o strnlen_user.o
+ lib-$(CONFIG_PCI) += pci-auto.o
+ lib-$(CONFIG_KCSAN) += kcsan-stubs.o
+diff --git a/arch/xtensa/lib/umulsidi3.S b/arch/xtensa/lib/umulsidi3.S
+new file mode 100644
+index 0000000000000..1360816479427
+--- /dev/null
++++ b/arch/xtensa/lib/umulsidi3.S
+@@ -0,0 +1,230 @@
++/* SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0 */
++#include <linux/linkage.h>
++#include <asm/asmmacro.h>
++#include <asm/core.h>
++
++#if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16
++#define XCHAL_NO_MUL 1
++#endif
++
++ENTRY(__umulsidi3)
++
++#ifdef __XTENSA_CALL0_ABI__
++	abi_entry(32)
++	s32i	a12, sp, 16
++	s32i	a13, sp, 20
++	s32i	a14, sp, 24
++	s32i	a15, sp, 28
++#elif XCHAL_NO_MUL
++	/* This is not really a leaf function; allocate enough stack space
++	   to allow CALL12s to a helper function.  */
++	abi_entry(32)
++#else
++	abi_entry_default
++#endif
++
++#ifdef __XTENSA_EB__
++#define wh a2
++#define wl a3
++#else
++#define wh a3
++#define wl a2
++#endif /* __XTENSA_EB__ */
++
++	/* This code is taken from the mulsf3 routine in ieee754-sf.S.
++	   See more comments there.  */
++
++#if XCHAL_HAVE_MUL32_HIGH
++	mull	a6, a2, a3
++	muluh	wh, a2, a3
++	mov	wl, a6
++
++#else /* ! MUL32_HIGH */
++
++#if defined(__XTENSA_CALL0_ABI__) && XCHAL_NO_MUL
++	/* a0 and a8 will be clobbered by calling the multiply function
++	   but a8 is not used here and need not be saved.  */
++	s32i	a0, sp, 0
++#endif
++
++#if XCHAL_HAVE_MUL16 || XCHAL_HAVE_MUL32
++
++#define a2h a4
++#define a3h a5
++
++	/* Get the high halves of the inputs into registers.  */
++	srli	a2h, a2, 16
++	srli	a3h, a3, 16
++
++#define a2l a2
++#define a3l a3
++
++#if XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MUL16
++	/* Clear the high halves of the inputs.  This does not matter
++	   for MUL16 because the high bits are ignored.  */
++	extui	a2, a2, 0, 16
++	extui	a3, a3, 0, 16
++#endif
++#endif /* MUL16 || MUL32 */
++
++
++#if XCHAL_HAVE_MUL16
++
++#define do_mul(dst, xreg, xhalf, yreg, yhalf) \
++	mul16u	dst, xreg ## xhalf, yreg ## yhalf
++
++#elif XCHAL_HAVE_MUL32
++
++#define do_mul(dst, xreg, xhalf, yreg, yhalf) \
++	mull	dst, xreg ## xhalf, yreg ## yhalf
++
++#elif XCHAL_HAVE_MAC16
++
++/* The preprocessor insists on inserting a space when concatenating after
++   a period in the definition of do_mul below.  These macros are a workaround
++   using underscores instead of periods when doing the concatenation.  */
++#define umul_aa_ll umul.aa.ll
++#define umul_aa_lh umul.aa.lh
++#define umul_aa_hl umul.aa.hl
++#define umul_aa_hh umul.aa.hh
++
++#define do_mul(dst, xreg, xhalf, yreg, yhalf) \
++	umul_aa_ ## xhalf ## yhalf	xreg, yreg; \
++	rsr	dst, ACCLO
++
++#else /* no multiply hardware */
++
++#define set_arg_l(dst, src) \
++	extui	dst, src, 0, 16
++#define set_arg_h(dst, src) \
++	srli	dst, src, 16
++
++#ifdef __XTENSA_CALL0_ABI__
++#define do_mul(dst, xreg, xhalf, yreg, yhalf) \
++	set_arg_ ## xhalf (a13, xreg); \
++	set_arg_ ## yhalf (a14, yreg); \
++	call0	.Lmul_mulsi3; \
++	mov	dst, a12
++#else
++#define do_mul(dst, xreg, xhalf, yreg, yhalf) \
++	set_arg_ ## xhalf (a14, xreg); \
++	set_arg_ ## yhalf (a15, yreg); \
++	call12	.Lmul_mulsi3; \
++	mov	dst, a14
++#endif /* __XTENSA_CALL0_ABI__ */
++
++#endif /* no multiply hardware */
++
++	/* Add pp1 and pp2 into a6 with carry-out in a9.  */
++	do_mul(a6, a2, l, a3, h)	/* pp 1 */
++	do_mul(a11, a2, h, a3, l)	/* pp 2 */
++	movi	a9, 0
++	add	a6, a6, a11
++	bgeu	a6, a11, 1f
++	addi	a9, a9, 1
++1:
++	/* Shift the high half of a9/a6 into position in a9.  Note that
++	   this value can be safely incremented without any carry-outs.  */
++	ssai	16
++	src	a9, a9, a6
++
++	/* Compute the low word into a6.  */
++	do_mul(a11, a2, l, a3, l)	/* pp 0 */
++	sll	a6, a6
++	add	a6, a6, a11
++	bgeu	a6, a11, 1f
++	addi	a9, a9, 1
++1:
++	/* Compute the high word into wh.  */
++	do_mul(wh, a2, h, a3, h)	/* pp 3 */
++	add	wh, wh, a9
++	mov	wl, a6
++
++#endif /* !MUL32_HIGH */
++
++#if defined(__XTENSA_CALL0_ABI__) && XCHAL_NO_MUL
++	/* Restore the original return address.  */
++	l32i	a0, sp, 0
++#endif
++#ifdef __XTENSA_CALL0_ABI__
++	l32i	a12, sp, 16
++	l32i	a13, sp, 20
++	l32i	a14, sp, 24
++	l32i	a15, sp, 28
++	abi_ret(32)
++#else
++	abi_ret_default
++#endif
++
++#if XCHAL_NO_MUL
++
++	.macro	do_addx2 dst, as, at, tmp
++#if XCHAL_HAVE_ADDX
++	addx2	\dst, \as, \at
++#else
++	slli	\tmp, \as, 1
++	add	\dst, \tmp, \at
++#endif
++	.endm
++
++	.macro	do_addx4 dst, as, at, tmp
++#if XCHAL_HAVE_ADDX
++	addx4	\dst, \as, \at
++#else
++	slli	\tmp, \as, 2
++	add	\dst, \tmp, \at
++#endif
++	.endm
++
++	.macro	do_addx8 dst, as, at, tmp
++#if XCHAL_HAVE_ADDX
++	addx8	\dst, \as, \at
++#else
++	slli	\tmp, \as, 3
++	add	\dst, \tmp, \at
++#endif
++	.endm
++
++	/* For Xtensa processors with no multiply hardware, this simplified
++	   version of _mulsi3 is used for multiplying 16-bit chunks of
++	   the floating-point mantissas.  When using CALL0, this function
++	   uses a custom ABI: the inputs are passed in a13 and a14, the
++	   result is returned in a12, and a8 and a15 are clobbered.  */
++	.align	4
++.Lmul_mulsi3:
++	abi_entry_default
++
++	.macro mul_mulsi3_body dst, src1, src2, tmp1, tmp2
++	movi	\dst, 0
++1:	add	\tmp1, \src2, \dst
++	extui	\tmp2, \src1, 0, 1
++	movnez	\dst, \tmp1, \tmp2
++
++	do_addx2 \tmp1, \src2, \dst, \tmp1
++	extui	\tmp2, \src1, 1, 1
++	movnez	\dst, \tmp1, \tmp2
++
++	do_addx4 \tmp1, \src2, \dst, \tmp1
++	extui	\tmp2, \src1, 2, 1
++	movnez	\dst, \tmp1, \tmp2
++
++	do_addx8 \tmp1, \src2, \dst, \tmp1
++	extui	\tmp2, \src1, 3, 1
++	movnez	\dst, \tmp1, \tmp2
++
++	srli	\src1, \src1, 4
++	slli	\src2, \src2, 4
++	bnez	\src1, 1b
++	.endm
++
++#ifdef __XTENSA_CALL0_ABI__
++	mul_mulsi3_body a12, a13, a14, a15, a8
++#else
++	/* The result will be written into a2, so save that argument in a4.  */
++	mov	a4, a2
++	mul_mulsi3_body a2, a4, a3, a5, a6
++#endif
++	abi_ret_default
++#endif /* XCHAL_NO_MUL */
++
++ENDPROC(__umulsidi3)
+diff --git a/block/mq-deadline.c b/block/mq-deadline.c
+index 5639921dfa922..6672f1bce3795 100644
+--- a/block/mq-deadline.c
++++ b/block/mq-deadline.c
+@@ -130,6 +130,20 @@ static u8 dd_rq_ioclass(struct request *rq)
+ 	return IOPRIO_PRIO_CLASS(req_get_ioprio(rq));
+ }
+ 
++/*
++ * get the request before `rq' in sector-sorted order
++ */
++static inline struct request *
++deadline_earlier_request(struct request *rq)
++{
++	struct rb_node *node = rb_prev(&rq->rb_node);
++
++	if (node)
++		return rb_entry_rq(node);
++
++	return NULL;
++}
++
+ /*
+  * get the request after `rq' in sector-sorted order
+  */
+@@ -277,6 +291,39 @@ static inline int deadline_check_fifo(struct dd_per_prio *per_prio,
+ 	return 0;
+ }
+ 
++/*
++ * Check if rq has a sequential request preceding it.
++ */
++static bool deadline_is_seq_writes(struct deadline_data *dd, struct request *rq)
++{
++	struct request *prev = deadline_earlier_request(rq);
++
++	if (!prev)
++		return false;
++
++	return blk_rq_pos(prev) + blk_rq_sectors(prev) == blk_rq_pos(rq);
++}
++
++/*
++ * Skip all write requests that are sequential from @rq, even if we cross
++ * a zone boundary.
++ */
++static struct request *deadline_skip_seq_writes(struct deadline_data *dd,
++						struct request *rq)
++{
++	sector_t pos = blk_rq_pos(rq);
++	sector_t skipped_sectors = 0;
++
++	while (rq) {
++		if (blk_rq_pos(rq) != pos + skipped_sectors)
++			break;
++		skipped_sectors += blk_rq_sectors(rq);
++		rq = deadline_latter_request(rq);
++	}
++
++	return rq;
++}
++
+ /*
+  * For the specified data direction, return the next request to
+  * dispatch using arrival ordered lists.
+@@ -297,11 +344,16 @@ deadline_fifo_request(struct deadline_data *dd, struct dd_per_prio *per_prio,
+ 
+ 	/*
+ 	 * Look for a write request that can be dispatched, that is one with
+-	 * an unlocked target zone.
++	 * an unlocked target zone. For some HDDs, breaking a sequential
++	 * write stream can lead to lower throughput, so make sure to preserve
++	 * sequential write streams, even if that stream crosses into the next
++	 * zones and these zones are unlocked.
+ 	 */
+ 	spin_lock_irqsave(&dd->zone_lock, flags);
+ 	list_for_each_entry(rq, &per_prio->fifo_list[DD_WRITE], queuelist) {
+-		if (blk_req_can_dispatch_to_zone(rq))
++		if (blk_req_can_dispatch_to_zone(rq) &&
++		    (blk_queue_nonrot(rq->q) ||
++		     !deadline_is_seq_writes(dd, rq)))
+ 			goto out;
+ 	}
+ 	rq = NULL;
+@@ -331,13 +383,19 @@ deadline_next_request(struct deadline_data *dd, struct dd_per_prio *per_prio,
+ 
+ 	/*
+ 	 * Look for a write request that can be dispatched, that is one with
+-	 * an unlocked target zone.
++	 * an unlocked target zone. For some HDDs, breaking a sequential
++	 * write stream can lead to lower throughput, so make sure to preserve
++	 * sequential write streams, even if that stream crosses into the next
++	 * zones and these zones are unlocked.
+ 	 */
+ 	spin_lock_irqsave(&dd->zone_lock, flags);
+ 	while (rq) {
+ 		if (blk_req_can_dispatch_to_zone(rq))
+ 			break;
+-		rq = deadline_latter_request(rq);
++		if (blk_queue_nonrot(rq->q))
++			rq = deadline_latter_request(rq);
++		else
++			rq = deadline_skip_seq_writes(dd, rq);
+ 	}
+ 	spin_unlock_irqrestore(&dd->zone_lock, flags);
+ 
+@@ -789,6 +847,18 @@ static void dd_prepare_request(struct request *rq)
+ 	rq->elv.priv[0] = NULL;
+ }
+ 
++static bool dd_has_write_work(struct blk_mq_hw_ctx *hctx)
++{
++	struct deadline_data *dd = hctx->queue->elevator->elevator_data;
++	enum dd_prio p;
++
++	for (p = 0; p <= DD_PRIO_MAX; p++)
++		if (!list_empty_careful(&dd->per_prio[p].fifo_list[DD_WRITE]))
++			return true;
++
++	return false;
++}
++
+ /*
+  * Callback from inside blk_mq_free_request().
+  *
+@@ -828,9 +898,10 @@ static void dd_finish_request(struct request *rq)
+ 
+ 		spin_lock_irqsave(&dd->zone_lock, flags);
+ 		blk_req_zone_write_unlock(rq);
+-		if (!list_empty(&per_prio->fifo_list[DD_WRITE]))
+-			blk_mq_sched_mark_restart_hctx(rq->mq_hctx);
+ 		spin_unlock_irqrestore(&dd->zone_lock, flags);
++
++		if (dd_has_write_work(rq->mq_hctx))
++			blk_mq_sched_mark_restart_hctx(rq->mq_hctx);
+ 	}
+ }
+ 
+diff --git a/drivers/base/dd.c b/drivers/base/dd.c
+index ec69b43f926ae..6669daf1f31fe 100644
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -1162,7 +1162,11 @@ static int __driver_attach(struct device *dev, void *data)
+ 		return 0;
+ 	} else if (ret < 0) {
+ 		dev_dbg(dev, "Bus failed to match device: %d\n", ret);
+-		return ret;
++		/*
++		 * Driver could not match with device, but may match with
++		 * another device on the bus.
++		 */
++		return 0;
+ 	} /* ret > 0 means positive match */
+ 
+ 	if (driver_allows_async_probing(drv)) {
+diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c
+index 4a42186ff1112..083459028a4b8 100644
+--- a/drivers/bus/mhi/host/pm.c
++++ b/drivers/bus/mhi/host/pm.c
+@@ -301,7 +301,8 @@ int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl)
+ 		read_lock_irq(&mhi_chan->lock);
+ 
+ 		/* Only ring DB if ring is not empty */
+-		if (tre_ring->base && tre_ring->wp  != tre_ring->rp)
++		if (tre_ring->base && tre_ring->wp  != tre_ring->rp &&
++		    mhi_chan->ch_state == MHI_CH_STATE_ENABLED)
+ 			mhi_ring_chan_db(mhi_cntrl, mhi_chan);
+ 		read_unlock_irq(&mhi_chan->lock);
+ 	}
+diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
+index c9e32d100b7eb..b151cbfc3d9b9 100644
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -1336,6 +1336,7 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
+ 	unsigned long    flags;
+ 	struct cmd_rcvr  *rcvr;
+ 	struct cmd_rcvr  *rcvrs = NULL;
++	struct module    *owner;
+ 
+ 	if (!acquire_ipmi_user(user, &i)) {
+ 		/*
+@@ -1398,8 +1399,9 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
+ 		kfree(rcvr);
+ 	}
+ 
++	owner = intf->owner;
+ 	kref_put(&intf->refcount, intf_free);
+-	module_put(intf->owner);
++	module_put(owner);
+ }
+ 
+ int ipmi_destroy_user(struct ipmi_user *user)
+diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
+index 6e357ad76f2eb..abddd7e43a9a6 100644
+--- a/drivers/char/ipmi/ipmi_si_intf.c
++++ b/drivers/char/ipmi/ipmi_si_intf.c
+@@ -2153,6 +2153,20 @@ skip_fallback_noirq:
+ }
+ module_init(init_ipmi_si);
+ 
++static void wait_msg_processed(struct smi_info *smi_info)
++{
++	unsigned long jiffies_now;
++	long time_diff;
++
++	while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
++		jiffies_now = jiffies;
++		time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
++		     * SI_USEC_PER_JIFFY);
++		smi_event_handler(smi_info, time_diff);
++		schedule_timeout_uninterruptible(1);
++	}
++}
++
+ static void shutdown_smi(void *send_info)
+ {
+ 	struct smi_info *smi_info = send_info;
+@@ -2187,16 +2201,13 @@ static void shutdown_smi(void *send_info)
+ 	 * in the BMC.  Note that timers and CPU interrupts are off,
+ 	 * so no need for locks.
+ 	 */
+-	while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
+-		poll(smi_info);
+-		schedule_timeout_uninterruptible(1);
+-	}
++	wait_msg_processed(smi_info);
++
+ 	if (smi_info->handlers)
+ 		disable_si_irq(smi_info);
+-	while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
+-		poll(smi_info);
+-		schedule_timeout_uninterruptible(1);
+-	}
++
++	wait_msg_processed(smi_info);
++
+ 	if (smi_info->handlers)
+ 		smi_info->handlers->cleanup(smi_info->si_sm);
+ 
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index 69b3d61852ac6..7e56a42750ea5 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -1207,6 +1207,7 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
+ 	if (!zalloc_cpumask_var(&policy->real_cpus, GFP_KERNEL))
+ 		goto err_free_rcpumask;
+ 
++	init_completion(&policy->kobj_unregister);
+ 	ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
+ 				   cpufreq_global_kobject, "policy%u", cpu);
+ 	if (ret) {
+@@ -1245,7 +1246,6 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
+ 	init_rwsem(&policy->rwsem);
+ 	spin_lock_init(&policy->transition_lock);
+ 	init_waitqueue_head(&policy->transition_wait);
+-	init_completion(&policy->kobj_unregister);
+ 	INIT_WORK(&policy->update, handle_update);
+ 
+ 	policy->cpu = cpu;
+diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
+index 79d9e14b70c87..0d0b96a7f4c07 100644
+--- a/drivers/crypto/Kconfig
++++ b/drivers/crypto/Kconfig
+@@ -790,8 +790,8 @@ config CRYPTO_DEV_CCREE
+ 	select CRYPTO_ECB
+ 	select CRYPTO_CTR
+ 	select CRYPTO_XTS
+-	select CRYPTO_SM4
+-	select CRYPTO_SM3
++	select CRYPTO_SM4_GENERIC
++	select CRYPTO_SM3_GENERIC
+ 	help
+ 	  Say 'Y' to enable a driver for the REE interface of the Arm
+ 	  TrustZone CryptoCell family of processors. Currently the
+diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c
+index 792d6da7f0c07..084d052fddccb 100644
+--- a/drivers/crypto/ccp/sp-pci.c
++++ b/drivers/crypto/ccp/sp-pci.c
+@@ -381,6 +381,15 @@ static const struct psp_vdata pspv3 = {
+ 	.inten_reg		= 0x10690,
+ 	.intsts_reg		= 0x10694,
+ };
++
++static const struct psp_vdata pspv4 = {
++	.sev			= &sevv2,
++	.tee			= &teev1,
++	.feature_reg		= 0x109fc,
++	.inten_reg		= 0x10690,
++	.intsts_reg		= 0x10694,
++};
++
+ #endif
+ 
+ static const struct sp_dev_vdata dev_vdata[] = {
+@@ -426,7 +435,7 @@ static const struct sp_dev_vdata dev_vdata[] = {
+ 	{	/* 5 */
+ 		.bar = 2,
+ #ifdef CONFIG_CRYPTO_DEV_SP_PSP
+-		.psp_vdata = &pspv2,
++		.psp_vdata = &pspv4,
+ #endif
+ 	},
+ 	{	/* 6 */
+diff --git a/drivers/crypto/hisilicon/Kconfig b/drivers/crypto/hisilicon/Kconfig
+index 27e1fa9120639..743ce4fc3158c 100644
+--- a/drivers/crypto/hisilicon/Kconfig
++++ b/drivers/crypto/hisilicon/Kconfig
+@@ -26,7 +26,7 @@ config CRYPTO_DEV_HISI_SEC2
+ 	select CRYPTO_SHA1
+ 	select CRYPTO_SHA256
+ 	select CRYPTO_SHA512
+-	select CRYPTO_SM4
++	select CRYPTO_SM4_GENERIC
+ 	depends on PCI && PCI_MSI
+ 	depends on UACCE || UACCE=n
+ 	depends on ARM64 || (COMPILE_TEST && 64BIT)
+diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c
+index 3b0bf6fea491a..b4db560105a9e 100644
+--- a/drivers/crypto/n2_core.c
++++ b/drivers/crypto/n2_core.c
+@@ -1229,6 +1229,7 @@ struct n2_hash_tmpl {
+ 	const u8	*hash_init;
+ 	u8		hw_op_hashsz;
+ 	u8		digest_size;
++	u8		statesize;
+ 	u8		block_size;
+ 	u8		auth_type;
+ 	u8		hmac_type;
+@@ -1260,6 +1261,7 @@ static const struct n2_hash_tmpl hash_tmpls[] = {
+ 	  .hmac_type	= AUTH_TYPE_HMAC_MD5,
+ 	  .hw_op_hashsz	= MD5_DIGEST_SIZE,
+ 	  .digest_size	= MD5_DIGEST_SIZE,
++	  .statesize	= sizeof(struct md5_state),
+ 	  .block_size	= MD5_HMAC_BLOCK_SIZE },
+ 	{ .name		= "sha1",
+ 	  .hash_zero	= sha1_zero_message_hash,
+@@ -1268,6 +1270,7 @@ static const struct n2_hash_tmpl hash_tmpls[] = {
+ 	  .hmac_type	= AUTH_TYPE_HMAC_SHA1,
+ 	  .hw_op_hashsz	= SHA1_DIGEST_SIZE,
+ 	  .digest_size	= SHA1_DIGEST_SIZE,
++	  .statesize	= sizeof(struct sha1_state),
+ 	  .block_size	= SHA1_BLOCK_SIZE },
+ 	{ .name		= "sha256",
+ 	  .hash_zero	= sha256_zero_message_hash,
+@@ -1276,6 +1279,7 @@ static const struct n2_hash_tmpl hash_tmpls[] = {
+ 	  .hmac_type	= AUTH_TYPE_HMAC_SHA256,
+ 	  .hw_op_hashsz	= SHA256_DIGEST_SIZE,
+ 	  .digest_size	= SHA256_DIGEST_SIZE,
++	  .statesize	= sizeof(struct sha256_state),
+ 	  .block_size	= SHA256_BLOCK_SIZE },
+ 	{ .name		= "sha224",
+ 	  .hash_zero	= sha224_zero_message_hash,
+@@ -1284,6 +1288,7 @@ static const struct n2_hash_tmpl hash_tmpls[] = {
+ 	  .hmac_type	= AUTH_TYPE_RESERVED,
+ 	  .hw_op_hashsz	= SHA256_DIGEST_SIZE,
+ 	  .digest_size	= SHA224_DIGEST_SIZE,
++	  .statesize	= sizeof(struct sha256_state),
+ 	  .block_size	= SHA224_BLOCK_SIZE },
+ };
+ #define NUM_HASH_TMPLS ARRAY_SIZE(hash_tmpls)
+@@ -1424,6 +1429,7 @@ static int __n2_register_one_ahash(const struct n2_hash_tmpl *tmpl)
+ 
+ 	halg = &ahash->halg;
+ 	halg->digestsize = tmpl->digest_size;
++	halg->statesize = tmpl->statesize;
+ 
+ 	base = &halg->base;
+ 	snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name);
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index 78344e4d4215b..36ef236354557 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -1225,7 +1225,7 @@ static int cxl_region_attach(struct cxl_region *cxlr,
+ 		struct cxl_endpoint_decoder *cxled_target;
+ 		struct cxl_memdev *cxlmd_target;
+ 
+-		cxled_target = p->targets[pos];
++		cxled_target = p->targets[i];
+ 		if (!cxled_target)
+ 			continue;
+ 
+@@ -1922,6 +1922,9 @@ static int cxl_region_probe(struct device *dev)
+ 	 */
+ 	up_read(&cxl_region_rwsem);
+ 
++	if (rc)
++		return rc;
++
+ 	switch (cxlr->mode) {
+ 	case CXL_DECODER_PMEM:
+ 		return devm_cxl_add_pmem_region(cxlr);
+diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
+index 63347a5ae5999..8c5f6f7fca112 100644
+--- a/drivers/devfreq/devfreq.c
++++ b/drivers/devfreq/devfreq.c
+@@ -776,8 +776,7 @@ static void remove_sysfs_files(struct devfreq *devfreq,
+  * @dev:	the device to add devfreq feature.
+  * @profile:	device-specific profile to run devfreq.
+  * @governor_name:	name of the policy to choose frequency.
+- * @data:	private data for the governor. The devfreq framework does not
+- *		touch this value.
++ * @data:	devfreq driver pass to governors, governor should not change it.
+  */
+ struct devfreq *devfreq_add_device(struct device *dev,
+ 				   struct devfreq_dev_profile *profile,
+@@ -1011,8 +1010,7 @@ static void devm_devfreq_dev_release(struct device *dev, void *res)
+  * @dev:	the device to add devfreq feature.
+  * @profile:	device-specific profile to run devfreq.
+  * @governor_name:	name of the policy to choose frequency.
+- * @data:	private data for the governor. The devfreq framework does not
+- *		touch this value.
++ * @data:	 devfreq driver pass to governors, governor should not change it.
+  *
+  * This function manages automatically the memory of devfreq device using device
+  * resource management and simplify the free operation for memory of devfreq
+diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c
+index ab9db7adb3ade..d69672ccacc49 100644
+--- a/drivers/devfreq/governor_userspace.c
++++ b/drivers/devfreq/governor_userspace.c
+@@ -21,7 +21,7 @@ struct userspace_data {
+ 
+ static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq)
+ {
+-	struct userspace_data *data = df->data;
++	struct userspace_data *data = df->governor_data;
+ 
+ 	if (data->valid)
+ 		*freq = data->user_frequency;
+@@ -40,7 +40,7 @@ static ssize_t set_freq_store(struct device *dev, struct device_attribute *attr,
+ 	int err = 0;
+ 
+ 	mutex_lock(&devfreq->lock);
+-	data = devfreq->data;
++	data = devfreq->governor_data;
+ 
+ 	sscanf(buf, "%lu", &wanted);
+ 	data->user_frequency = wanted;
+@@ -60,7 +60,7 @@ static ssize_t set_freq_show(struct device *dev,
+ 	int err = 0;
+ 
+ 	mutex_lock(&devfreq->lock);
+-	data = devfreq->data;
++	data = devfreq->governor_data;
+ 
+ 	if (data->valid)
+ 		err = sprintf(buf, "%lu\n", data->user_frequency);
+@@ -91,7 +91,7 @@ static int userspace_init(struct devfreq *devfreq)
+ 		goto out;
+ 	}
+ 	data->valid = false;
+-	devfreq->data = data;
++	devfreq->governor_data = data;
+ 
+ 	err = sysfs_create_group(&devfreq->dev.kobj, &dev_attr_group);
+ out:
+@@ -107,8 +107,8 @@ static void userspace_exit(struct devfreq *devfreq)
+ 	if (devfreq->dev.kobj.sd)
+ 		sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group);
+ 
+-	kfree(devfreq->data);
+-	devfreq->data = NULL;
++	kfree(devfreq->governor_data);
++	devfreq->governor_data = NULL;
+ }
+ 
+ static int devfreq_userspace_handler(struct devfreq *devfreq,
+diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
+index 0a638c97702a5..15f63452a9bec 100644
+--- a/drivers/edac/edac_mc_sysfs.c
++++ b/drivers/edac/edac_mc_sysfs.c
+@@ -298,6 +298,14 @@ DEVICE_CHANNEL(ch6_dimm_label, S_IRUGO | S_IWUSR,
+ 	channel_dimm_label_show, channel_dimm_label_store, 6);
+ DEVICE_CHANNEL(ch7_dimm_label, S_IRUGO | S_IWUSR,
+ 	channel_dimm_label_show, channel_dimm_label_store, 7);
++DEVICE_CHANNEL(ch8_dimm_label, S_IRUGO | S_IWUSR,
++	channel_dimm_label_show, channel_dimm_label_store, 8);
++DEVICE_CHANNEL(ch9_dimm_label, S_IRUGO | S_IWUSR,
++	channel_dimm_label_show, channel_dimm_label_store, 9);
++DEVICE_CHANNEL(ch10_dimm_label, S_IRUGO | S_IWUSR,
++	channel_dimm_label_show, channel_dimm_label_store, 10);
++DEVICE_CHANNEL(ch11_dimm_label, S_IRUGO | S_IWUSR,
++	channel_dimm_label_show, channel_dimm_label_store, 11);
+ 
+ /* Total possible dynamic DIMM Label attribute file table */
+ static struct attribute *dynamic_csrow_dimm_attr[] = {
+@@ -309,6 +317,10 @@ static struct attribute *dynamic_csrow_dimm_attr[] = {
+ 	&dev_attr_legacy_ch5_dimm_label.attr.attr,
+ 	&dev_attr_legacy_ch6_dimm_label.attr.attr,
+ 	&dev_attr_legacy_ch7_dimm_label.attr.attr,
++	&dev_attr_legacy_ch8_dimm_label.attr.attr,
++	&dev_attr_legacy_ch9_dimm_label.attr.attr,
++	&dev_attr_legacy_ch10_dimm_label.attr.attr,
++	&dev_attr_legacy_ch11_dimm_label.attr.attr,
+ 	NULL
+ };
+ 
+@@ -329,6 +341,14 @@ DEVICE_CHANNEL(ch6_ce_count, S_IRUGO,
+ 		   channel_ce_count_show, NULL, 6);
+ DEVICE_CHANNEL(ch7_ce_count, S_IRUGO,
+ 		   channel_ce_count_show, NULL, 7);
++DEVICE_CHANNEL(ch8_ce_count, S_IRUGO,
++		   channel_ce_count_show, NULL, 8);
++DEVICE_CHANNEL(ch9_ce_count, S_IRUGO,
++		   channel_ce_count_show, NULL, 9);
++DEVICE_CHANNEL(ch10_ce_count, S_IRUGO,
++		   channel_ce_count_show, NULL, 10);
++DEVICE_CHANNEL(ch11_ce_count, S_IRUGO,
++		   channel_ce_count_show, NULL, 11);
+ 
+ /* Total possible dynamic ce_count attribute file table */
+ static struct attribute *dynamic_csrow_ce_count_attr[] = {
+@@ -340,6 +360,10 @@ static struct attribute *dynamic_csrow_ce_count_attr[] = {
+ 	&dev_attr_legacy_ch5_ce_count.attr.attr,
+ 	&dev_attr_legacy_ch6_ce_count.attr.attr,
+ 	&dev_attr_legacy_ch7_ce_count.attr.attr,
++	&dev_attr_legacy_ch8_ce_count.attr.attr,
++	&dev_attr_legacy_ch9_ce_count.attr.attr,
++	&dev_attr_legacy_ch10_ce_count.attr.attr,
++	&dev_attr_legacy_ch11_ce_count.attr.attr,
+ 	NULL
+ };
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index f04e698e631c5..04c6c804ef65f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -2998,14 +2998,15 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
+ 			continue;
+ 		}
+ 
+-		/* skip suspend of gfx and psp for S0ix
++		/* skip suspend of gfx/mes and psp for S0ix
+ 		 * gfx is in gfxoff state, so on resume it will exit gfxoff just
+ 		 * like at runtime. PSP is also part of the always on hardware
+ 		 * so no need to suspend it.
+ 		 */
+ 		if (adev->in_s0ix &&
+ 		    (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP ||
+-		     adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX))
++		     adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
++		     adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_MES))
+ 			continue;
+ 
+ 		/* XXX handle errors */
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index de7144b06e933..379e65ea8afb1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -2025,6 +2025,15 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
+ 			 "See modparam exp_hw_support\n");
+ 		return -ENODEV;
+ 	}
++	/* differentiate between P10 and P11 asics with the same DID */
++	if (pdev->device == 0x67FF &&
++	    (pdev->revision == 0xE3 ||
++	     pdev->revision == 0xE7 ||
++	     pdev->revision == 0xF3 ||
++	     pdev->revision == 0xF7)) {
++		flags &= ~AMD_ASIC_MASK;
++		flags |= CHIP_POLARIS10;
++	}
+ 
+ 	/* Due to hardware bugs, S/G Display on raven requires a 1:1 IOMMU mapping,
+ 	 * however, SME requires an indirect IOMMU mapping because the encryption
+@@ -2094,12 +2103,12 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
+ 
+ 	pci_set_drvdata(pdev, ddev);
+ 
+-	ret = amdgpu_driver_load_kms(adev, ent->driver_data);
++	ret = amdgpu_driver_load_kms(adev, flags);
+ 	if (ret)
+ 		goto err_pci;
+ 
+ retry_init:
+-	ret = drm_dev_register(ddev, ent->driver_data);
++	ret = drm_dev_register(ddev, flags);
+ 	if (ret == -EAGAIN && ++retry <= 3) {
+ 		DRM_INFO("retry init %d\n", retry);
+ 		/* Don't request EX mode too frequently which is attacking */
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+index 4570ad4493905..bfe0fc258fc14 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+@@ -1506,7 +1506,8 @@ u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo)
+ uint32_t amdgpu_bo_get_preferred_domain(struct amdgpu_device *adev,
+ 					    uint32_t domain)
+ {
+-	if (domain == (AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT)) {
++	if ((domain == (AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT)) &&
++	    ((adev->asic_type == CHIP_CARRIZO) || (adev->asic_type == CHIP_STONEY))) {
+ 		domain = AMDGPU_GEM_DOMAIN_VRAM;
+ 		if (adev->gmc.real_vram_size <= AMDGPU_SG_THRESHOLD)
+ 			domain = AMDGPU_GEM_DOMAIN_GTT;
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
+index 998b5d17b271b..0e664d0cc8d51 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
+@@ -319,7 +319,7 @@ static void mmhub_v2_0_init_cache_regs(struct amdgpu_device *adev)
+ 
+ 	tmp = mmMMVM_L2_CNTL5_DEFAULT;
+ 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
+-	WREG32_SOC15(GC, 0, mmMMVM_L2_CNTL5, tmp);
++	WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL5, tmp);
+ }
+ 
+ static void mmhub_v2_0_enable_system_domain(struct amdgpu_device *adev)
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c
+index 1b027d069ab40..4638ea7c2eec5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c
+@@ -243,7 +243,7 @@ static void mmhub_v2_3_init_cache_regs(struct amdgpu_device *adev)
+ 
+ 	tmp = mmMMVM_L2_CNTL5_DEFAULT;
+ 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
+-	WREG32_SOC15(GC, 0, mmMMVM_L2_CNTL5, tmp);
++	WREG32_SOC15(MMHUB, 0, mmMMVM_L2_CNTL5, tmp);
+ }
+ 
+ static void mmhub_v2_3_enable_system_domain(struct amdgpu_device *adev)
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c
+index a1d26c4d80b8c..16cc82215e2e1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c
+@@ -275,7 +275,7 @@ static void mmhub_v3_0_init_cache_regs(struct amdgpu_device *adev)
+ 
+ 	tmp = regMMVM_L2_CNTL5_DEFAULT;
+ 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
+-	WREG32_SOC15(GC, 0, regMMVM_L2_CNTL5, tmp);
++	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL5, tmp);
+ }
+ 
+ static void mmhub_v3_0_enable_system_domain(struct amdgpu_device *adev)
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c
+index e8058edc1d108..6bdf2ef0298d6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_1.c
+@@ -269,7 +269,7 @@ static void mmhub_v3_0_1_init_cache_regs(struct amdgpu_device *adev)
+ 
+ 	tmp = regMMVM_L2_CNTL5_DEFAULT;
+ 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
+-	WREG32_SOC15(GC, 0, regMMVM_L2_CNTL5, tmp);
++	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL5, tmp);
+ }
+ 
+ static void mmhub_v3_0_1_enable_system_domain(struct amdgpu_device *adev)
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c
+index 770be0a8f7ce7..45465acaa943a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0_2.c
+@@ -268,7 +268,7 @@ static void mmhub_v3_0_2_init_cache_regs(struct amdgpu_device *adev)
+ 
+ 	tmp = regMMVM_L2_CNTL5_DEFAULT;
+ 	tmp = REG_SET_FIELD(tmp, MMVM_L2_CNTL5, L2_CACHE_SMALLK_FRAGMENT_SIZE, 0);
+-	WREG32_SOC15(GC, 0, regMMVM_L2_CNTL5, tmp);
++	WREG32_SOC15(MMHUB, 0, regMMVM_L2_CNTL5, tmp);
+ }
+ 
+ static void mmhub_v3_0_2_enable_system_domain(struct amdgpu_device *adev)
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 4b16d9d1e058c..895bbd20dd07a 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1511,6 +1511,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
+ 		case IP_VERSION(3, 0, 1):
+ 		case IP_VERSION(3, 1, 2):
+ 		case IP_VERSION(3, 1, 3):
++		case IP_VERSION(3, 1, 4):
+ 		case IP_VERSION(3, 1, 5):
+ 		case IP_VERSION(3, 1, 6):
+ 			init_data.flags.gpu_vm_support = true;
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
+index b76f0f7e42998..d6b964cf73bd1 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_0.h
+@@ -522,9 +522,9 @@ typedef enum  {
+   TEMP_HOTSPOT_M,
+   TEMP_MEM,
+   TEMP_VR_GFX,
++  TEMP_VR_SOC,
+   TEMP_VR_MEM0,
+   TEMP_VR_MEM1,
+-  TEMP_VR_SOC,
+   TEMP_VR_U,
+   TEMP_LIQUID0,
+   TEMP_LIQUID1,
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+index 865d6358918d2..a9122b3b15322 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+@@ -28,6 +28,7 @@
+ #define SMU13_DRIVER_IF_VERSION_INV 0xFFFFFFFF
+ #define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x04
+ #define SMU13_DRIVER_IF_VERSION_ALDE 0x08
++#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_0 0x34
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+index 1983e0d29e9db..c01c6952f31b3 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+@@ -288,6 +288,8 @@ int smu_v13_0_check_fw_version(struct smu_context *smu)
+ 		smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_ALDE;
+ 		break;
+ 	case IP_VERSION(13, 0, 0):
++		smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_0;
++		break;
+ 	case IP_VERSION(13, 0, 10):
+ 		smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10;
+ 		break;
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+index f0121d1716301..b8430601304f0 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+@@ -187,6 +187,8 @@ static struct cmn2asic_mapping smu_v13_0_0_feature_mask_map[SMU_FEATURE_COUNT] =
+ 	FEA_MAP(MEM_TEMP_READ),
+ 	FEA_MAP(ATHUB_MMHUB_PG),
+ 	FEA_MAP(SOC_PCC),
++	[SMU_FEATURE_DPM_VCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
++	[SMU_FEATURE_DPM_DCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
+ };
+ 
+ static struct cmn2asic_mapping smu_v13_0_0_table_map[SMU_TABLE_COUNT] = {
+@@ -517,6 +519,23 @@ static int smu_v13_0_0_set_default_dpm_table(struct smu_context *smu)
+ 						     dpm_table);
+ 		if (ret)
+ 			return ret;
++
++		/*
++		 * Update the reported maximum shader clock to the value
++		 * which can be guarded to be achieved on all cards. This
++		 * is aligned with Window setting. And considering that value
++		 * might be not the peak frequency the card can achieve, it
++		 * is normal some real-time clock frequency can overtake this
++		 * labelled maximum clock frequency(for example in pp_dpm_sclk
++		 * sysfs output).
++		 */
++		if (skutable->DriverReportedClocks.GameClockAc &&
++		    (dpm_table->dpm_levels[dpm_table->count - 1].value >
++		    skutable->DriverReportedClocks.GameClockAc)) {
++			dpm_table->dpm_levels[dpm_table->count - 1].value =
++				skutable->DriverReportedClocks.GameClockAc;
++			dpm_table->max = skutable->DriverReportedClocks.GameClockAc;
++		}
+ 	} else {
+ 		dpm_table->count = 1;
+ 		dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
+@@ -779,6 +798,57 @@ static int smu_v13_0_0_get_smu_metrics_data(struct smu_context *smu,
+ 	return ret;
+ }
+ 
++static int smu_v13_0_0_get_dpm_ultimate_freq(struct smu_context *smu,
++					     enum smu_clk_type clk_type,
++					     uint32_t *min,
++					     uint32_t *max)
++{
++	struct smu_13_0_dpm_context *dpm_context =
++		smu->smu_dpm.dpm_context;
++	struct smu_13_0_dpm_table *dpm_table;
++
++	switch (clk_type) {
++	case SMU_MCLK:
++	case SMU_UCLK:
++		/* uclk dpm table */
++		dpm_table = &dpm_context->dpm_tables.uclk_table;
++		break;
++	case SMU_GFXCLK:
++	case SMU_SCLK:
++		/* gfxclk dpm table */
++		dpm_table = &dpm_context->dpm_tables.gfx_table;
++		break;
++	case SMU_SOCCLK:
++		/* socclk dpm table */
++		dpm_table = &dpm_context->dpm_tables.soc_table;
++		break;
++	case SMU_FCLK:
++		/* fclk dpm table */
++		dpm_table = &dpm_context->dpm_tables.fclk_table;
++		break;
++	case SMU_VCLK:
++	case SMU_VCLK1:
++		/* vclk dpm table */
++		dpm_table = &dpm_context->dpm_tables.vclk_table;
++		break;
++	case SMU_DCLK:
++	case SMU_DCLK1:
++		/* dclk dpm table */
++		dpm_table = &dpm_context->dpm_tables.dclk_table;
++		break;
++	default:
++		dev_err(smu->adev->dev, "Unsupported clock type!\n");
++		return -EINVAL;
++	}
++
++	if (min)
++		*min = dpm_table->min;
++	if (max)
++		*max = dpm_table->max;
++
++	return 0;
++}
++
+ static int smu_v13_0_0_read_sensor(struct smu_context *smu,
+ 				   enum amd_pp_sensors sensor,
+ 				   void *data,
+@@ -1281,9 +1351,17 @@ static int smu_v13_0_0_populate_umd_state_clk(struct smu_context *smu)
+ 				&dpm_context->dpm_tables.fclk_table;
+ 	struct smu_umd_pstate_table *pstate_table =
+ 				&smu->pstate_table;
++	struct smu_table_context *table_context = &smu->smu_table;
++	PPTable_t *pptable = table_context->driver_pptable;
++	DriverReportedClocks_t driver_clocks =
++			pptable->SkuTable.DriverReportedClocks;
+ 
+ 	pstate_table->gfxclk_pstate.min = gfx_table->min;
+-	pstate_table->gfxclk_pstate.peak = gfx_table->max;
++	if (driver_clocks.GameClockAc &&
++	    (driver_clocks.GameClockAc < gfx_table->max))
++		pstate_table->gfxclk_pstate.peak = driver_clocks.GameClockAc;
++	else
++		pstate_table->gfxclk_pstate.peak = gfx_table->max;
+ 
+ 	pstate_table->uclk_pstate.min = mem_table->min;
+ 	pstate_table->uclk_pstate.peak = mem_table->max;
+@@ -1300,12 +1378,12 @@ static int smu_v13_0_0_populate_umd_state_clk(struct smu_context *smu)
+ 	pstate_table->fclk_pstate.min = fclk_table->min;
+ 	pstate_table->fclk_pstate.peak = fclk_table->max;
+ 
+-	/*
+-	 * For now, just use the mininum clock frequency.
+-	 * TODO: update them when the real pstate settings available
+-	 */
+-	pstate_table->gfxclk_pstate.standard = gfx_table->min;
+-	pstate_table->uclk_pstate.standard = mem_table->min;
++	if (driver_clocks.BaseClockAc &&
++	    driver_clocks.BaseClockAc < gfx_table->max)
++		pstate_table->gfxclk_pstate.standard = driver_clocks.BaseClockAc;
++	else
++		pstate_table->gfxclk_pstate.standard = gfx_table->max;
++	pstate_table->uclk_pstate.standard = mem_table->max;
+ 	pstate_table->socclk_pstate.standard = soc_table->min;
+ 	pstate_table->vclk_pstate.standard = vclk_table->min;
+ 	pstate_table->dclk_pstate.standard = dclk_table->min;
+@@ -1339,12 +1417,23 @@ out:
+ static int smu_v13_0_0_get_fan_speed_pwm(struct smu_context *smu,
+ 					 uint32_t *speed)
+ {
++	int ret;
++
+ 	if (!speed)
+ 		return -EINVAL;
+ 
+-	return smu_v13_0_0_get_smu_metrics_data(smu,
+-						METRICS_CURR_FANPWM,
+-						speed);
++	ret = smu_v13_0_0_get_smu_metrics_data(smu,
++					       METRICS_CURR_FANPWM,
++					       speed);
++	if (ret) {
++		dev_err(smu->adev->dev, "Failed to get fan speed(PWM)!");
++		return ret;
++	}
++
++	/* Convert the PMFW output which is in percent to pwm(255) based */
++	*speed = MIN(*speed * 255 / 100, 255);
++
++	return 0;
+ }
+ 
+ static int smu_v13_0_0_get_fan_speed_rpm(struct smu_context *smu,
+@@ -1813,7 +1902,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
+ 	.get_enabled_mask = smu_cmn_get_enabled_mask,
+ 	.dpm_set_vcn_enable = smu_v13_0_set_vcn_enable,
+ 	.dpm_set_jpeg_enable = smu_v13_0_set_jpeg_enable,
+-	.get_dpm_ultimate_freq = smu_v13_0_get_dpm_ultimate_freq,
++	.get_dpm_ultimate_freq = smu_v13_0_0_get_dpm_ultimate_freq,
+ 	.get_vbios_bootup_values = smu_v13_0_get_vbios_bootup_values,
+ 	.read_sensor = smu_v13_0_0_read_sensor,
+ 	.feature_is_enabled = smu_cmn_feature_is_enabled,
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+index 39deb06a86ba3..222924363a681 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+@@ -189,6 +189,8 @@ static struct cmn2asic_mapping smu_v13_0_7_feature_mask_map[SMU_FEATURE_COUNT] =
+ 	FEA_MAP(MEM_TEMP_READ),
+ 	FEA_MAP(ATHUB_MMHUB_PG),
+ 	FEA_MAP(SOC_PCC),
++	[SMU_FEATURE_DPM_VCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
++	[SMU_FEATURE_DPM_DCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
+ };
+ 
+ static struct cmn2asic_mapping smu_v13_0_7_table_map[SMU_TABLE_COUNT] = {
+@@ -1359,12 +1361,23 @@ static int smu_v13_0_7_populate_umd_state_clk(struct smu_context *smu)
+ static int smu_v13_0_7_get_fan_speed_pwm(struct smu_context *smu,
+ 					 uint32_t *speed)
+ {
++	int ret;
++
+ 	if (!speed)
+ 		return -EINVAL;
+ 
+-	return smu_v13_0_7_get_smu_metrics_data(smu,
+-						METRICS_CURR_FANPWM,
+-						speed);
++	ret = smu_v13_0_7_get_smu_metrics_data(smu,
++					       METRICS_CURR_FANPWM,
++					       speed);
++	if (ret) {
++		dev_err(smu->adev->dev, "Failed to get fan speed(PWM)!");
++		return ret;
++	}
++
++	/* Convert the PMFW output which is in percent to pwm(255) based */
++	*speed = MIN(*speed * 255 / 100, 255);
++
++	return 0;
+ }
+ 
+ static int smu_v13_0_7_get_fan_speed_rpm(struct smu_context *smu,
+diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
+index 1ab083b35e3b9..17eada72bd925 100644
+--- a/drivers/gpu/drm/drm_connector.c
++++ b/drivers/gpu/drm/drm_connector.c
+@@ -505,6 +505,9 @@ void drm_connector_cleanup(struct drm_connector *connector)
+ 	mutex_destroy(&connector->mutex);
+ 
+ 	memset(connector, 0, sizeof(*connector));
++
++	if (dev->registered)
++		drm_sysfs_hotplug_event(dev);
+ }
+ EXPORT_SYMBOL(drm_connector_cleanup);
+ 
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+index cc386f8a7116e..5cf13e52f7c94 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+@@ -258,7 +258,12 @@ struct etnaviv_vram_mapping *etnaviv_gem_mapping_get(
+ 		if (mapping->use == 0) {
+ 			mutex_lock(&mmu_context->lock);
+ 			if (mapping->context == mmu_context)
+-				mapping->use += 1;
++				if (va && mapping->iova != va) {
++					etnaviv_iommu_reap_mapping(mapping);
++					mapping = NULL;
++				} else {
++					mapping->use += 1;
++				}
+ 			else
+ 				mapping = NULL;
+ 			mutex_unlock(&mmu_context->lock);
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
+index dc1aa738c4f18..55479cb8b1ac3 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c
+@@ -135,6 +135,19 @@ static void etnaviv_iommu_remove_mapping(struct etnaviv_iommu_context *context,
+ 	drm_mm_remove_node(&mapping->vram_node);
+ }
+ 
++void etnaviv_iommu_reap_mapping(struct etnaviv_vram_mapping *mapping)
++{
++	struct etnaviv_iommu_context *context = mapping->context;
++
++	lockdep_assert_held(&context->lock);
++	WARN_ON(mapping->use);
++
++	etnaviv_iommu_remove_mapping(context, mapping);
++	etnaviv_iommu_context_put(mapping->context);
++	mapping->context = NULL;
++	list_del_init(&mapping->mmu_node);
++}
++
+ static int etnaviv_iommu_find_iova(struct etnaviv_iommu_context *context,
+ 				   struct drm_mm_node *node, size_t size)
+ {
+@@ -202,10 +215,7 @@ static int etnaviv_iommu_find_iova(struct etnaviv_iommu_context *context,
+ 		 * this mapping.
+ 		 */
+ 		list_for_each_entry_safe(m, n, &list, scan_node) {
+-			etnaviv_iommu_remove_mapping(context, m);
+-			etnaviv_iommu_context_put(m->context);
+-			m->context = NULL;
+-			list_del_init(&m->mmu_node);
++			etnaviv_iommu_reap_mapping(m);
+ 			list_del_init(&m->scan_node);
+ 		}
+ 
+@@ -257,10 +267,7 @@ static int etnaviv_iommu_insert_exact(struct etnaviv_iommu_context *context,
+ 	}
+ 
+ 	list_for_each_entry_safe(m, n, &scan_list, scan_node) {
+-		etnaviv_iommu_remove_mapping(context, m);
+-		etnaviv_iommu_context_put(m->context);
+-		m->context = NULL;
+-		list_del_init(&m->mmu_node);
++		etnaviv_iommu_reap_mapping(m);
+ 		list_del_init(&m->scan_node);
+ 	}
+ 
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
+index e4a0b7d09c2ea..c01a147f0dfdd 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
++++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.h
+@@ -91,6 +91,7 @@ int etnaviv_iommu_map_gem(struct etnaviv_iommu_context *context,
+ 	struct etnaviv_vram_mapping *mapping, u64 va);
+ void etnaviv_iommu_unmap_gem(struct etnaviv_iommu_context *context,
+ 	struct etnaviv_vram_mapping *mapping);
++void etnaviv_iommu_reap_mapping(struct etnaviv_vram_mapping *mapping);
+ 
+ int etnaviv_iommu_get_suballoc_va(struct etnaviv_iommu_context *ctx,
+ 				  struct etnaviv_vram_mapping *mapping,
+diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+index 75e8cc4337c93..fce69fa446d58 100644
+--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
++++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+@@ -137,9 +137,9 @@ static enum port intel_dsi_seq_port_to_port(struct intel_dsi *intel_dsi,
+ 		return ffs(intel_dsi->ports) - 1;
+ 
+ 	if (seq_port) {
+-		if (intel_dsi->ports & PORT_B)
++		if (intel_dsi->ports & BIT(PORT_B))
+ 			return PORT_B;
+-		else if (intel_dsi->ports & PORT_C)
++		else if (intel_dsi->ports & BIT(PORT_C))
+ 			return PORT_C;
+ 	}
+ 
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+index cd75b0ca2555f..c607d1019e80b 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+@@ -729,32 +729,69 @@ static int eb_reserve(struct i915_execbuffer *eb)
+ 	bool unpinned;
+ 
+ 	/*
+-	 * Attempt to pin all of the buffers into the GTT.
+-	 * This is done in 2 phases:
++	 * We have one more buffers that we couldn't bind, which could be due to
++	 * various reasons. To resolve this we have 4 passes, with every next
++	 * level turning the screws tighter:
+ 	 *
+-	 * 1. Unbind all objects that do not match the GTT constraints for
+-	 *    the execbuffer (fenceable, mappable, alignment etc).
+-	 * 2. Bind new objects.
++	 * 0. Unbind all objects that do not match the GTT constraints for the
++	 * execbuffer (fenceable, mappable, alignment etc). Bind all new
++	 * objects.  This avoids unnecessary unbinding of later objects in order
++	 * to make room for the earlier objects *unless* we need to defragment.
+ 	 *
+-	 * This avoid unnecessary unbinding of later objects in order to make
+-	 * room for the earlier objects *unless* we need to defragment.
++	 * 1. Reorder the buffers, where objects with the most restrictive
++	 * placement requirements go first (ignoring fixed location buffers for
++	 * now).  For example, objects needing the mappable aperture (the first
++	 * 256M of GTT), should go first vs objects that can be placed just
++	 * about anywhere. Repeat the previous pass.
+ 	 *
+-	 * Defragmenting is skipped if all objects are pinned at a fixed location.
++	 * 2. Consider buffers that are pinned at a fixed location. Also try to
++	 * evict the entire VM this time, leaving only objects that we were
++	 * unable to lock. Try again to bind the buffers. (still using the new
++	 * buffer order).
++	 *
++	 * 3. We likely have object lock contention for one or more stubborn
++	 * objects in the VM, for which we need to evict to make forward
++	 * progress (perhaps we are fighting the shrinker?). When evicting the
++	 * VM this time around, anything that we can't lock we now track using
++	 * the busy_bo, using the full lock (after dropping the vm->mutex to
++	 * prevent deadlocks), instead of trylock. We then continue to evict the
++	 * VM, this time with the stubborn object locked, which we can now
++	 * hopefully unbind (if still bound in the VM). Repeat until the VM is
++	 * evicted. Finally we should be able bind everything.
+ 	 */
+-	for (pass = 0; pass <= 2; pass++) {
++	for (pass = 0; pass <= 3; pass++) {
+ 		int pin_flags = PIN_USER | PIN_VALIDATE;
+ 
+ 		if (pass == 0)
+ 			pin_flags |= PIN_NONBLOCK;
+ 
+ 		if (pass >= 1)
+-			unpinned = eb_unbind(eb, pass == 2);
++			unpinned = eb_unbind(eb, pass >= 2);
+ 
+ 		if (pass == 2) {
+ 			err = mutex_lock_interruptible(&eb->context->vm->mutex);
+ 			if (!err) {
+-				err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
++				err = i915_gem_evict_vm(eb->context->vm, &eb->ww, NULL);
++				mutex_unlock(&eb->context->vm->mutex);
++			}
++			if (err)
++				return err;
++		}
++
++		if (pass == 3) {
++retry:
++			err = mutex_lock_interruptible(&eb->context->vm->mutex);
++			if (!err) {
++				struct drm_i915_gem_object *busy_bo = NULL;
++
++				err = i915_gem_evict_vm(eb->context->vm, &eb->ww, &busy_bo);
+ 				mutex_unlock(&eb->context->vm->mutex);
++				if (err && busy_bo) {
++					err = i915_gem_object_lock(busy_bo, &eb->ww);
++					i915_gem_object_put(busy_bo);
++					if (!err)
++						goto retry;
++				}
+ 			}
+ 			if (err)
+ 				return err;
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+index 0c5c43852e24d..6f579cb8f2ff6 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+@@ -369,7 +369,7 @@ retry:
+ 		if (vma == ERR_PTR(-ENOSPC)) {
+ 			ret = mutex_lock_interruptible(&ggtt->vm.mutex);
+ 			if (!ret) {
+-				ret = i915_gem_evict_vm(&ggtt->vm, &ww);
++				ret = i915_gem_evict_vm(&ggtt->vm, &ww, NULL);
+ 				mutex_unlock(&ggtt->vm.mutex);
+ 			}
+ 			if (ret)
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
+index 85482a04d1584..c3d1726d16b61 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
+@@ -726,6 +726,9 @@ bool i915_gem_object_needs_ccs_pages(struct drm_i915_gem_object *obj)
+ 	if (!HAS_FLAT_CCS(to_i915(obj->base.dev)))
+ 		return false;
+ 
++	if (obj->flags & I915_BO_ALLOC_CCS_AUX)
++		return true;
++
+ 	for (i = 0; i < obj->mm.n_placements; i++) {
+ 		/* Compression is not allowed for the objects with smem placement */
+ 		if (obj->mm.placements[i]->type == INTEL_MEMORY_SYSTEM)
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+index 9f6b14ec189a2..1c3d074b44c34 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
++++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+@@ -325,16 +325,18 @@ struct drm_i915_gem_object {
+  * dealing with userspace objects the CPU fault handler is free to ignore this.
+  */
+ #define I915_BO_ALLOC_GPU_ONLY	  BIT(6)
++#define I915_BO_ALLOC_CCS_AUX	  BIT(7)
+ #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
+ 			     I915_BO_ALLOC_VOLATILE | \
+ 			     I915_BO_ALLOC_CPU_CLEAR | \
+ 			     I915_BO_ALLOC_USER | \
+ 			     I915_BO_ALLOC_PM_VOLATILE | \
+ 			     I915_BO_ALLOC_PM_EARLY | \
+-			     I915_BO_ALLOC_GPU_ONLY)
+-#define I915_BO_READONLY          BIT(7)
+-#define I915_TILING_QUIRK_BIT     8 /* unknown swizzling; do not release! */
+-#define I915_BO_PROTECTED         BIT(9)
++			     I915_BO_ALLOC_GPU_ONLY | \
++			     I915_BO_ALLOC_CCS_AUX)
++#define I915_BO_READONLY          BIT(8)
++#define I915_TILING_QUIRK_BIT     9 /* unknown swizzling; do not release! */
++#define I915_BO_PROTECTED         BIT(10)
+ 	/**
+ 	 * @mem_flags - Mutable placement-related flags
+ 	 *
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
+index 9aad84059d568..aa0ef0c45554b 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_pm.c
+@@ -50,6 +50,7 @@ static int i915_ttm_backup(struct i915_gem_apply_to_region *apply,
+ 		container_of(bo->bdev, typeof(*i915), bdev);
+ 	struct drm_i915_gem_object *backup;
+ 	struct ttm_operation_ctx ctx = {};
++	unsigned int flags;
+ 	int err = 0;
+ 
+ 	if (bo->resource->mem_type == I915_PL_SYSTEM || obj->ttm.backup)
+@@ -65,7 +66,22 @@ static int i915_ttm_backup(struct i915_gem_apply_to_region *apply,
+ 	if (obj->flags & I915_BO_ALLOC_PM_VOLATILE)
+ 		return 0;
+ 
+-	backup = i915_gem_object_create_shmem(i915, obj->base.size);
++	/*
++	 * It seems that we might have some framebuffers still pinned at this
++	 * stage, but for such objects we might also need to deal with the CCS
++	 * aux state. Make sure we force the save/restore of the CCS state,
++	 * otherwise we might observe display corruption, when returning from
++	 * suspend.
++	 */
++	flags = 0;
++	if (i915_gem_object_needs_ccs_pages(obj)) {
++		WARN_ON_ONCE(!i915_gem_object_is_framebuffer(obj));
++		WARN_ON_ONCE(!pm_apply->allow_gpu);
++
++		flags = I915_BO_ALLOC_CCS_AUX;
++	}
++	backup = i915_gem_object_create_region(i915->mm.regions[INTEL_REGION_SMEM],
++					       obj->base.size, 0, flags);
+ 	if (IS_ERR(backup))
+ 		return PTR_ERR(backup);
+ 
+diff --git a/drivers/gpu/drm/i915/gt/intel_migrate.c b/drivers/gpu/drm/i915/gt/intel_migrate.c
+index 933648cc90ff9..50b6533a35b23 100644
+--- a/drivers/gpu/drm/i915/gt/intel_migrate.c
++++ b/drivers/gpu/drm/i915/gt/intel_migrate.c
+@@ -341,6 +341,16 @@ static int emit_no_arbitration(struct i915_request *rq)
+ 	return 0;
+ }
+ 
++static int max_pte_pkt_size(struct i915_request *rq, int pkt)
++{
++	struct intel_ring *ring = rq->ring;
++
++	pkt = min_t(int, pkt, (ring->space - rq->reserved_space) / sizeof(u32) + 5);
++	pkt = min_t(int, pkt, (ring->size - ring->emit) / sizeof(u32) + 5);
++
++	return pkt;
++}
++
+ static int emit_pte(struct i915_request *rq,
+ 		    struct sgt_dma *it,
+ 		    enum i915_cache_level cache_level,
+@@ -387,8 +397,7 @@ static int emit_pte(struct i915_request *rq,
+ 		return PTR_ERR(cs);
+ 
+ 	/* Pack as many PTE updates as possible into a single MI command */
+-	pkt = min_t(int, dword_length, ring->space / sizeof(u32) + 5);
+-	pkt = min_t(int, pkt, (ring->size - ring->emit) / sizeof(u32) + 5);
++	pkt = max_pte_pkt_size(rq, dword_length);
+ 
+ 	hdr = cs;
+ 	*cs++ = MI_STORE_DATA_IMM | REG_BIT(21); /* as qword elements */
+@@ -421,8 +430,7 @@ static int emit_pte(struct i915_request *rq,
+ 				}
+ 			}
+ 
+-			pkt = min_t(int, dword_rem, ring->space / sizeof(u32) + 5);
+-			pkt = min_t(int, pkt, (ring->size - ring->emit) / sizeof(u32) + 5);
++			pkt = max_pte_pkt_size(rq, dword_rem);
+ 
+ 			hdr = cs;
+ 			*cs++ = MI_STORE_DATA_IMM | REG_BIT(21);
+diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c
+index f025ee4fa5261..a4b4d9b7d26c7 100644
+--- a/drivers/gpu/drm/i915/i915_gem_evict.c
++++ b/drivers/gpu/drm/i915/i915_gem_evict.c
+@@ -416,6 +416,11 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
+  * @vm: Address space to cleanse
+  * @ww: An optional struct i915_gem_ww_ctx. If not NULL, i915_gem_evict_vm
+  * will be able to evict vma's locked by the ww as well.
++ * @busy_bo: Optional pointer to struct drm_i915_gem_object. If not NULL, then
++ * in the event i915_gem_evict_vm() is unable to trylock an object for eviction,
++ * then @busy_bo will point to it. -EBUSY is also returned. The caller must drop
++ * the vm->mutex, before trying again to acquire the contended lock. The caller
++ * also owns a reference to the object.
+  *
+  * This function evicts all vmas from a vm.
+  *
+@@ -425,7 +430,8 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
+  * To clarify: This is for freeing up virtual address space, not for freeing
+  * memory in e.g. the shrinker.
+  */
+-int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
++int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww,
++		      struct drm_i915_gem_object **busy_bo)
+ {
+ 	int ret = 0;
+ 
+@@ -457,15 +463,22 @@ int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
+ 			 * the resv is shared among multiple objects, we still
+ 			 * need the object ref.
+ 			 */
+-			if (dying_vma(vma) ||
++			if (!i915_gem_object_get_rcu(vma->obj) ||
+ 			    (ww && (dma_resv_locking_ctx(vma->obj->base.resv) == &ww->ctx))) {
+ 				__i915_vma_pin(vma);
+ 				list_add(&vma->evict_link, &locked_eviction_list);
+ 				continue;
+ 			}
+ 
+-			if (!i915_gem_object_trylock(vma->obj, ww))
++			if (!i915_gem_object_trylock(vma->obj, ww)) {
++				if (busy_bo) {
++					*busy_bo = vma->obj; /* holds ref */
++					ret = -EBUSY;
++					break;
++				}
++				i915_gem_object_put(vma->obj);
+ 				continue;
++			}
+ 
+ 			__i915_vma_pin(vma);
+ 			list_add(&vma->evict_link, &eviction_list);
+@@ -473,25 +486,29 @@ int i915_gem_evict_vm(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww)
+ 		if (list_empty(&eviction_list) && list_empty(&locked_eviction_list))
+ 			break;
+ 
+-		ret = 0;
+ 		/* Unbind locked objects first, before unlocking the eviction_list */
+ 		list_for_each_entry_safe(vma, vn, &locked_eviction_list, evict_link) {
+ 			__i915_vma_unpin(vma);
+ 
+-			if (ret == 0)
++			if (ret == 0) {
+ 				ret = __i915_vma_unbind(vma);
+-			if (ret != -EINTR) /* "Get me out of here!" */
+-				ret = 0;
++				if (ret != -EINTR) /* "Get me out of here!" */
++					ret = 0;
++			}
++			if (!dying_vma(vma))
++				i915_gem_object_put(vma->obj);
+ 		}
+ 
+ 		list_for_each_entry_safe(vma, vn, &eviction_list, evict_link) {
+ 			__i915_vma_unpin(vma);
+-			if (ret == 0)
++			if (ret == 0) {
+ 				ret = __i915_vma_unbind(vma);
+-			if (ret != -EINTR) /* "Get me out of here!" */
+-				ret = 0;
++				if (ret != -EINTR) /* "Get me out of here!" */
++					ret = 0;
++			}
+ 
+ 			i915_gem_object_unlock(vma->obj);
++			i915_gem_object_put(vma->obj);
+ 		}
+ 	} while (ret == 0);
+ 
+diff --git a/drivers/gpu/drm/i915/i915_gem_evict.h b/drivers/gpu/drm/i915/i915_gem_evict.h
+index e593c530f9bd7..bf0ee0e4fe608 100644
+--- a/drivers/gpu/drm/i915/i915_gem_evict.h
++++ b/drivers/gpu/drm/i915/i915_gem_evict.h
+@@ -11,6 +11,7 @@
+ struct drm_mm_node;
+ struct i915_address_space;
+ struct i915_gem_ww_ctx;
++struct drm_i915_gem_object;
+ 
+ int __must_check i915_gem_evict_something(struct i915_address_space *vm,
+ 					  struct i915_gem_ww_ctx *ww,
+@@ -23,6 +24,7 @@ int __must_check i915_gem_evict_for_node(struct i915_address_space *vm,
+ 					 struct drm_mm_node *node,
+ 					 unsigned int flags);
+ int i915_gem_evict_vm(struct i915_address_space *vm,
+-		      struct i915_gem_ww_ctx *ww);
++		      struct i915_gem_ww_ctx *ww,
++		      struct drm_i915_gem_object **busy_bo);
+ 
+ #endif /* __I915_GEM_EVICT_H__ */
+diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
+index 373582cfd8f31..240b7b8ed281d 100644
+--- a/drivers/gpu/drm/i915/i915_vma.c
++++ b/drivers/gpu/drm/i915/i915_vma.c
+@@ -1569,7 +1569,7 @@ static int __i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
+ 			 * locked objects when called from execbuf when pinning
+ 			 * is removed. This would probably regress badly.
+ 			 */
+-			i915_gem_evict_vm(vm, NULL);
++			i915_gem_evict_vm(vm, NULL, NULL);
+ 			mutex_unlock(&vm->mutex);
+ 		}
+ 	} while (1);
+diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
+index 8c6517d29b8e0..37068542aafe7 100644
+--- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
++++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c
+@@ -344,7 +344,7 @@ static int igt_evict_vm(void *arg)
+ 
+ 	/* Everything is pinned, nothing should happen */
+ 	mutex_lock(&ggtt->vm.mutex);
+-	err = i915_gem_evict_vm(&ggtt->vm, NULL);
++	err = i915_gem_evict_vm(&ggtt->vm, NULL, NULL);
+ 	mutex_unlock(&ggtt->vm.mutex);
+ 	if (err) {
+ 		pr_err("i915_gem_evict_vm on a full GGTT returned err=%d]\n",
+@@ -356,7 +356,7 @@ static int igt_evict_vm(void *arg)
+ 
+ 	for_i915_gem_ww(&ww, err, false) {
+ 		mutex_lock(&ggtt->vm.mutex);
+-		err = i915_gem_evict_vm(&ggtt->vm, &ww);
++		err = i915_gem_evict_vm(&ggtt->vm, &ww, NULL);
+ 		mutex_unlock(&ggtt->vm.mutex);
+ 	}
+ 
+diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+index eb8208bfe5ab3..98370b25a4b61 100644
+--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
++++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+@@ -1601,7 +1601,11 @@ static int ingenic_drm_init(void)
+ 			return err;
+ 	}
+ 
+-	return platform_driver_register(&ingenic_drm_driver);
++	err = platform_driver_register(&ingenic_drm_driver);
++	if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && err)
++		platform_driver_unregister(ingenic_ipu_driver_ptr);
++
++	return err;
+ }
+ module_init(ingenic_drm_init);
+ 
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+index ff2f735bbe7a0..5c7dc411b1804 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -309,7 +309,8 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
+ 	if (cmd->dma.guest.ptr.offset % PAGE_SIZE ||
+ 	    box->x != 0    || box->y != 0    || box->z != 0    ||
+ 	    box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
+-	    box->d != 1    || box_count != 1) {
++	    box->d != 1    || box_count != 1 ||
++	    box->w > 64 || box->h > 64) {
+ 		/* TODO handle none page aligned offsets */
+ 		/* TODO handle more dst & src != 0 */
+ 		/* TODO handle more then one copy */
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
+index fdc642362c140..6601b677c2502 100644
+--- a/drivers/iommu/amd/init.c
++++ b/drivers/iommu/amd/init.c
+@@ -3385,18 +3385,24 @@ static int __init parse_amd_iommu_options(char *str)
+ static int __init parse_ivrs_ioapic(char *str)
+ {
+ 	u32 seg = 0, bus, dev, fn;
+-	int ret, id, i;
++	int id, i;
+ 	u32 devid;
+ 
+-	ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
+-	if (ret != 4) {
+-		ret = sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn);
+-		if (ret != 5) {
+-			pr_err("Invalid command line: ivrs_ioapic%s\n", str);
+-			return 1;
+-		}
++	if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
++	    sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5)
++		goto found;
++
++	if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
++	    sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) {
++		pr_warn("ivrs_ioapic%s option format deprecated; use ivrs_ioapic=%d@%04x:%02x:%02x.%d instead\n",
++			str, id, seg, bus, dev, fn);
++		goto found;
+ 	}
+ 
++	pr_err("Invalid command line: ivrs_ioapic%s\n", str);
++	return 1;
++
++found:
+ 	if (early_ioapic_map_size == EARLY_MAP_SIZE) {
+ 		pr_err("Early IOAPIC map overflow - ignoring ivrs_ioapic%s\n",
+ 			str);
+@@ -3417,18 +3423,24 @@ static int __init parse_ivrs_ioapic(char *str)
+ static int __init parse_ivrs_hpet(char *str)
+ {
+ 	u32 seg = 0, bus, dev, fn;
+-	int ret, id, i;
++	int id, i;
+ 	u32 devid;
+ 
+-	ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn);
+-	if (ret != 4) {
+-		ret = sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn);
+-		if (ret != 5) {
+-			pr_err("Invalid command line: ivrs_hpet%s\n", str);
+-			return 1;
+-		}
++	if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
++	    sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5)
++		goto found;
++
++	if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 ||
++	    sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) {
++		pr_warn("ivrs_hpet%s option format deprecated; use ivrs_hpet=%d@%04x:%02x:%02x.%d instead\n",
++			str, id, seg, bus, dev, fn);
++		goto found;
+ 	}
+ 
++	pr_err("Invalid command line: ivrs_hpet%s\n", str);
++	return 1;
++
++found:
+ 	if (early_hpet_map_size == EARLY_MAP_SIZE) {
+ 		pr_err("Early HPET map overflow - ignoring ivrs_hpet%s\n",
+ 			str);
+@@ -3449,19 +3461,36 @@ static int __init parse_ivrs_hpet(char *str)
+ static int __init parse_ivrs_acpihid(char *str)
+ {
+ 	u32 seg = 0, bus, dev, fn;
+-	char *hid, *uid, *p;
++	char *hid, *uid, *p, *addr;
+ 	char acpiid[ACPIHID_UID_LEN + ACPIHID_HID_LEN] = {0};
+-	int ret, i;
+-
+-	ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid);
+-	if (ret != 4) {
+-		ret = sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid);
+-		if (ret != 5) {
+-			pr_err("Invalid command line: ivrs_acpihid(%s)\n", str);
+-			return 1;
++	int i;
++
++	addr = strchr(str, '@');
++	if (!addr) {
++		if (sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid) == 4 ||
++		    sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid) == 5) {
++			pr_warn("ivrs_acpihid%s option format deprecated; use ivrs_acpihid=%s@%04x:%02x:%02x.%d instead\n",
++				str, acpiid, seg, bus, dev, fn);
++			goto found;
+ 		}
++		goto not_found;
+ 	}
+ 
++	/* We have the '@', make it the terminator to get just the acpiid */
++	*addr++ = 0;
++
++	if (sscanf(str, "=%s", acpiid) != 1)
++		goto not_found;
++
++	if (sscanf(addr, "%x:%x.%x", &bus, &dev, &fn) == 3 ||
++	    sscanf(addr, "%x:%x:%x.%x", &seg, &bus, &dev, &fn) == 4)
++		goto found;
++
++not_found:
++	pr_err("Invalid command line: ivrs_acpihid%s\n", str);
++	return 1;
++
++found:
+ 	p = acpiid;
+ 	hid = strsep(&p, ":");
+ 	uid = p;
+@@ -3471,6 +3500,13 @@ static int __init parse_ivrs_acpihid(char *str)
+ 		return 1;
+ 	}
+ 
++	/*
++	 * Ignore leading zeroes after ':', so e.g., AMDI0095:00
++	 * will match AMDI0095:0 in the second strcmp in acpi_dev_hid_uid_match
++	 */
++	while (*uid == '0' && *(uid + 1))
++		uid++;
++
+ 	i = early_acpihid_map_size++;
+ 	memcpy(early_acpihid_map[i].hid, hid, strlen(hid));
+ 	memcpy(early_acpihid_map[i].uid, uid, strlen(uid));
+diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c
+index ab13b73802650..83a5975bcc729 100644
+--- a/drivers/md/dm-cache-metadata.c
++++ b/drivers/md/dm-cache-metadata.c
+@@ -551,11 +551,13 @@ static int __create_persistent_data_objects(struct dm_cache_metadata *cmd,
+ 	return r;
+ }
+ 
+-static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd)
++static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd,
++					      bool destroy_bm)
+ {
+ 	dm_sm_destroy(cmd->metadata_sm);
+ 	dm_tm_destroy(cmd->tm);
+-	dm_block_manager_destroy(cmd->bm);
++	if (destroy_bm)
++		dm_block_manager_destroy(cmd->bm);
+ }
+ 
+ typedef unsigned long (*flags_mutator)(unsigned long);
+@@ -826,7 +828,7 @@ static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev,
+ 		cmd2 = lookup(bdev);
+ 		if (cmd2) {
+ 			mutex_unlock(&table_lock);
+-			__destroy_persistent_data_objects(cmd);
++			__destroy_persistent_data_objects(cmd, true);
+ 			kfree(cmd);
+ 			return cmd2;
+ 		}
+@@ -874,7 +876,7 @@ void dm_cache_metadata_close(struct dm_cache_metadata *cmd)
+ 		mutex_unlock(&table_lock);
+ 
+ 		if (!cmd->fail_io)
+-			__destroy_persistent_data_objects(cmd);
++			__destroy_persistent_data_objects(cmd, true);
+ 		kfree(cmd);
+ 	}
+ }
+@@ -1807,14 +1809,52 @@ int dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd, bool *result)
+ 
+ int dm_cache_metadata_abort(struct dm_cache_metadata *cmd)
+ {
+-	int r;
++	int r = -EINVAL;
++	struct dm_block_manager *old_bm = NULL, *new_bm = NULL;
++
++	/* fail_io is double-checked with cmd->root_lock held below */
++	if (unlikely(cmd->fail_io))
++		return r;
++
++	/*
++	 * Replacement block manager (new_bm) is created and old_bm destroyed outside of
++	 * cmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of
++	 * shrinker associated with the block manager's bufio client vs cmd root_lock).
++	 * - must take shrinker_rwsem without holding cmd->root_lock
++	 */
++	new_bm = dm_block_manager_create(cmd->bdev, DM_CACHE_METADATA_BLOCK_SIZE << SECTOR_SHIFT,
++					 CACHE_MAX_CONCURRENT_LOCKS);
+ 
+ 	WRITE_LOCK(cmd);
+-	__destroy_persistent_data_objects(cmd);
+-	r = __create_persistent_data_objects(cmd, false);
++	if (cmd->fail_io) {
++		WRITE_UNLOCK(cmd);
++		goto out;
++	}
++
++	__destroy_persistent_data_objects(cmd, false);
++	old_bm = cmd->bm;
++	if (IS_ERR(new_bm)) {
++		DMERR("could not create block manager during abort");
++		cmd->bm = NULL;
++		r = PTR_ERR(new_bm);
++		goto out_unlock;
++	}
++
++	cmd->bm = new_bm;
++	r = __open_or_format_metadata(cmd, false);
++	if (r) {
++		cmd->bm = NULL;
++		goto out_unlock;
++	}
++	new_bm = NULL;
++out_unlock:
+ 	if (r)
+ 		cmd->fail_io = true;
+ 	WRITE_UNLOCK(cmd);
++	dm_block_manager_destroy(old_bm);
++out:
++	if (new_bm && !IS_ERR(new_bm))
++		dm_block_manager_destroy(new_bm);
+ 
+ 	return r;
+ }
+diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
+index 54a8d5c9a44ea..5e92fac90b675 100644
+--- a/drivers/md/dm-cache-target.c
++++ b/drivers/md/dm-cache-target.c
+@@ -907,16 +907,16 @@ static void abort_transaction(struct cache *cache)
+ 	if (get_cache_mode(cache) >= CM_READ_ONLY)
+ 		return;
+ 
+-	if (dm_cache_metadata_set_needs_check(cache->cmd)) {
+-		DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name);
+-		set_cache_mode(cache, CM_FAIL);
+-	}
+-
+ 	DMERR_LIMIT("%s: aborting current metadata transaction", dev_name);
+ 	if (dm_cache_metadata_abort(cache->cmd)) {
+ 		DMERR("%s: failed to abort metadata transaction", dev_name);
+ 		set_cache_mode(cache, CM_FAIL);
+ 	}
++
++	if (dm_cache_metadata_set_needs_check(cache->cmd)) {
++		DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name);
++		set_cache_mode(cache, CM_FAIL);
++	}
+ }
+ 
+ static void metadata_operation_failed(struct cache *cache, const char *op, int r)
+@@ -1887,6 +1887,7 @@ static void destroy(struct cache *cache)
+ 	if (cache->prison)
+ 		dm_bio_prison_destroy_v2(cache->prison);
+ 
++	cancel_delayed_work_sync(&cache->waker);
+ 	if (cache->wq)
+ 		destroy_workqueue(cache->wq);
+ 
+diff --git a/drivers/md/dm-clone-target.c b/drivers/md/dm-clone-target.c
+index 2f1cc66d26412..29e0b85eeaf09 100644
+--- a/drivers/md/dm-clone-target.c
++++ b/drivers/md/dm-clone-target.c
+@@ -1958,6 +1958,7 @@ static void clone_dtr(struct dm_target *ti)
+ 
+ 	mempool_exit(&clone->hydration_pool);
+ 	dm_kcopyd_client_destroy(clone->kcopyd_client);
++	cancel_delayed_work_sync(&clone->waker);
+ 	destroy_workqueue(clone->wq);
+ 	hash_table_exit(clone);
+ 	dm_clone_metadata_close(clone->cmd);
+diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
+index e97e9f97456d4..1388ee35571e0 100644
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -4558,6 +4558,8 @@ static void dm_integrity_dtr(struct dm_target *ti)
+ 	BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress));
+ 	BUG_ON(!list_empty(&ic->wait_list));
+ 
++	if (ic->mode == 'B')
++		cancel_delayed_work_sync(&ic->bitmap_flush_work);
+ 	if (ic->metadata_wq)
+ 		destroy_workqueue(ic->metadata_wq);
+ 	if (ic->wait_wq)
+diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c
+index a27395c8621ff..6bcc4c4786d89 100644
+--- a/drivers/md/dm-thin-metadata.c
++++ b/drivers/md/dm-thin-metadata.c
+@@ -724,6 +724,15 @@ static int __open_metadata(struct dm_pool_metadata *pmd)
+ 		goto bad_cleanup_data_sm;
+ 	}
+ 
++	/*
++	 * For pool metadata opening process, root setting is redundant
++	 * because it will be set again in __begin_transaction(). But dm
++	 * pool aborting process really needs to get last transaction's
++	 * root to avoid accessing broken btree.
++	 */
++	pmd->root = le64_to_cpu(disk_super->data_mapping_root);
++	pmd->details_root = le64_to_cpu(disk_super->device_details_root);
++
+ 	__setup_btree_details(pmd);
+ 	dm_bm_unlock(sblock);
+ 
+@@ -776,13 +785,15 @@ static int __create_persistent_data_objects(struct dm_pool_metadata *pmd, bool f
+ 	return r;
+ }
+ 
+-static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd)
++static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd,
++					      bool destroy_bm)
+ {
+ 	dm_sm_destroy(pmd->data_sm);
+ 	dm_sm_destroy(pmd->metadata_sm);
+ 	dm_tm_destroy(pmd->nb_tm);
+ 	dm_tm_destroy(pmd->tm);
+-	dm_block_manager_destroy(pmd->bm);
++	if (destroy_bm)
++		dm_block_manager_destroy(pmd->bm);
+ }
+ 
+ static int __begin_transaction(struct dm_pool_metadata *pmd)
+@@ -989,7 +1000,7 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
+ 	}
+ 	pmd_write_unlock(pmd);
+ 	if (!pmd->fail_io)
+-		__destroy_persistent_data_objects(pmd);
++		__destroy_persistent_data_objects(pmd, true);
+ 
+ 	kfree(pmd);
+ 	return 0;
+@@ -1860,19 +1871,52 @@ static void __set_abort_with_changes_flags(struct dm_pool_metadata *pmd)
+ int dm_pool_abort_metadata(struct dm_pool_metadata *pmd)
+ {
+ 	int r = -EINVAL;
++	struct dm_block_manager *old_bm = NULL, *new_bm = NULL;
++
++	/* fail_io is double-checked with pmd->root_lock held below */
++	if (unlikely(pmd->fail_io))
++		return r;
++
++	/*
++	 * Replacement block manager (new_bm) is created and old_bm destroyed outside of
++	 * pmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of
++	 * shrinker associated with the block manager's bufio client vs pmd root_lock).
++	 * - must take shrinker_rwsem without holding pmd->root_lock
++	 */
++	new_bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE << SECTOR_SHIFT,
++					 THIN_MAX_CONCURRENT_LOCKS);
+ 
+ 	pmd_write_lock(pmd);
+-	if (pmd->fail_io)
++	if (pmd->fail_io) {
++		pmd_write_unlock(pmd);
+ 		goto out;
++	}
+ 
+ 	__set_abort_with_changes_flags(pmd);
+-	__destroy_persistent_data_objects(pmd);
+-	r = __create_persistent_data_objects(pmd, false);
++	__destroy_persistent_data_objects(pmd, false);
++	old_bm = pmd->bm;
++	if (IS_ERR(new_bm)) {
++		DMERR("could not create block manager during abort");
++		pmd->bm = NULL;
++		r = PTR_ERR(new_bm);
++		goto out_unlock;
++	}
++
++	pmd->bm = new_bm;
++	r = __open_or_format_metadata(pmd, false);
++	if (r) {
++		pmd->bm = NULL;
++		goto out_unlock;
++	}
++	new_bm = NULL;
++out_unlock:
+ 	if (r)
+ 		pmd->fail_io = true;
+-
+-out:
+ 	pmd_write_unlock(pmd);
++	dm_block_manager_destroy(old_bm);
++out:
++	if (new_bm && !IS_ERR(new_bm))
++		dm_block_manager_destroy(new_bm);
+ 
+ 	return r;
+ }
+diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
+index e76c96c760a9b..196f82559ad6b 100644
+--- a/drivers/md/dm-thin.c
++++ b/drivers/md/dm-thin.c
+@@ -2889,6 +2889,8 @@ static void __pool_destroy(struct pool *pool)
+ 	dm_bio_prison_destroy(pool->prison);
+ 	dm_kcopyd_client_destroy(pool->copier);
+ 
++	cancel_delayed_work_sync(&pool->waker);
++	cancel_delayed_work_sync(&pool->no_space_timeout);
+ 	if (pool->wq)
+ 		destroy_workqueue(pool->wq);
+ 
+@@ -3540,20 +3542,28 @@ static int pool_preresume(struct dm_target *ti)
+ 	 */
+ 	r = bind_control_target(pool, ti);
+ 	if (r)
+-		return r;
++		goto out;
+ 
+ 	r = maybe_resize_data_dev(ti, &need_commit1);
+ 	if (r)
+-		return r;
++		goto out;
+ 
+ 	r = maybe_resize_metadata_dev(ti, &need_commit2);
+ 	if (r)
+-		return r;
++		goto out;
+ 
+ 	if (need_commit1 || need_commit2)
+ 		(void) commit(pool);
++out:
++	/*
++	 * When a thin-pool is PM_FAIL, it cannot be rebuilt if
++	 * bio is in deferred list. Therefore need to return 0
++	 * to allow pool_resume() to flush IO.
++	 */
++	if (r && get_pool_mode(pool) == PM_FAIL)
++		r = 0;
+ 
+-	return 0;
++	return r;
+ }
+ 
+ static void pool_suspend_active_thins(struct pool *pool)
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index 63ece30114e53..e7cc6ba1b657f 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -486,7 +486,7 @@ void md_bitmap_print_sb(struct bitmap *bitmap)
+ 	sb = kmap_atomic(bitmap->storage.sb_page);
+ 	pr_debug("%s: bitmap file superblock:\n", bmname(bitmap));
+ 	pr_debug("         magic: %08x\n", le32_to_cpu(sb->magic));
+-	pr_debug("       version: %d\n", le32_to_cpu(sb->version));
++	pr_debug("       version: %u\n", le32_to_cpu(sb->version));
+ 	pr_debug("          uuid: %08x.%08x.%08x.%08x\n",
+ 		 le32_to_cpu(*(__le32 *)(sb->uuid+0)),
+ 		 le32_to_cpu(*(__le32 *)(sb->uuid+4)),
+@@ -497,11 +497,11 @@ void md_bitmap_print_sb(struct bitmap *bitmap)
+ 	pr_debug("events cleared: %llu\n",
+ 		 (unsigned long long) le64_to_cpu(sb->events_cleared));
+ 	pr_debug("         state: %08x\n", le32_to_cpu(sb->state));
+-	pr_debug("     chunksize: %d B\n", le32_to_cpu(sb->chunksize));
+-	pr_debug("  daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep));
++	pr_debug("     chunksize: %u B\n", le32_to_cpu(sb->chunksize));
++	pr_debug("  daemon sleep: %us\n", le32_to_cpu(sb->daemon_sleep));
+ 	pr_debug("     sync size: %llu KB\n",
+ 		 (unsigned long long)le64_to_cpu(sb->sync_size)/2);
+-	pr_debug("max write behind: %d\n", le32_to_cpu(sb->write_behind));
++	pr_debug("max write behind: %u\n", le32_to_cpu(sb->write_behind));
+ 	kunmap_atomic(sb);
+ }
+ 
+@@ -2105,7 +2105,8 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+ 			bytes = DIV_ROUND_UP(chunks, 8);
+ 			if (!bitmap->mddev->bitmap_info.external)
+ 				bytes += sizeof(bitmap_super_t);
+-		} while (bytes > (space << 9));
++		} while (bytes > (space << 9) && (chunkshift + BITMAP_BLOCK_SHIFT) <
++			(BITS_PER_BYTE * sizeof(((bitmap_super_t *)0)->chunksize) - 1));
+ 	} else
+ 		chunkshift = ffz(~chunksize) - BITMAP_BLOCK_SHIFT;
+ 
+@@ -2150,7 +2151,7 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+ 	bitmap->counts.missing_pages = pages;
+ 	bitmap->counts.chunkshift = chunkshift;
+ 	bitmap->counts.chunks = chunks;
+-	bitmap->mddev->bitmap_info.chunksize = 1 << (chunkshift +
++	bitmap->mddev->bitmap_info.chunksize = 1UL << (chunkshift +
+ 						     BITMAP_BLOCK_SHIFT);
+ 
+ 	blocks = min(old_counts.chunks << old_counts.chunkshift,
+@@ -2176,8 +2177,8 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+ 				bitmap->counts.missing_pages = old_counts.pages;
+ 				bitmap->counts.chunkshift = old_counts.chunkshift;
+ 				bitmap->counts.chunks = old_counts.chunks;
+-				bitmap->mddev->bitmap_info.chunksize = 1 << (old_counts.chunkshift +
+-									     BITMAP_BLOCK_SHIFT);
++				bitmap->mddev->bitmap_info.chunksize =
++					1UL << (old_counts.chunkshift + BITMAP_BLOCK_SHIFT);
+ 				blocks = old_counts.chunks << old_counts.chunkshift;
+ 				pr_warn("Could not pre-allocate in-memory bitmap for cluster raid\n");
+ 				break;
+@@ -2537,6 +2538,9 @@ chunksize_store(struct mddev *mddev, const char *buf, size_t len)
+ 	if (csize < 512 ||
+ 	    !is_power_of_2(csize))
+ 		return -EINVAL;
++	if (BITS_PER_LONG > 32 && csize >= (1ULL << (BITS_PER_BYTE *
++		sizeof(((bitmap_super_t *)0)->chunksize))))
++		return -EOVERFLOW;
+ 	mddev->bitmap_info.chunksize = csize;
+ 	return len;
+ }
+diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
+index f6ee678107d37..9ce5f010de3f8 100644
+--- a/drivers/media/dvb-core/dmxdev.c
++++ b/drivers/media/dvb-core/dmxdev.c
+@@ -790,6 +790,11 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
+ 	if (mutex_lock_interruptible(&dmxdev->mutex))
+ 		return -ERESTARTSYS;
+ 
++	if (dmxdev->exit) {
++		mutex_unlock(&dmxdev->mutex);
++		return -ENODEV;
++	}
++
+ 	for (i = 0; i < dmxdev->filternum; i++)
+ 		if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
+ 			break;
+@@ -1448,7 +1453,10 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
+ 
+ void dvb_dmxdev_release(struct dmxdev *dmxdev)
+ {
++	mutex_lock(&dmxdev->mutex);
+ 	dmxdev->exit = 1;
++	mutex_unlock(&dmxdev->mutex);
++
+ 	if (dmxdev->dvbdev->users > 1) {
+ 		wait_event(dmxdev->dvbdev->wait_queue,
+ 				dmxdev->dvbdev->users == 1);
+diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
+index 9934728734af9..a31d52cb6d62c 100644
+--- a/drivers/media/dvb-core/dvbdev.c
++++ b/drivers/media/dvb-core/dvbdev.c
+@@ -335,6 +335,7 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
+ 				       GFP_KERNEL);
+ 		if (!dvbdev->pads) {
+ 			kfree(dvbdev->entity);
++			dvbdev->entity = NULL;
+ 			return -ENOMEM;
+ 		}
+ 	}
+diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c
+index 3d54a0ec86afd..3ae1f3a2f1420 100644
+--- a/drivers/media/dvb-frontends/stv0288.c
++++ b/drivers/media/dvb-frontends/stv0288.c
+@@ -440,9 +440,8 @@ static int stv0288_set_frontend(struct dvb_frontend *fe)
+ 	struct stv0288_state *state = fe->demodulator_priv;
+ 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ 
+-	char tm;
+-	unsigned char tda[3];
+-	u8 reg, time_out = 0;
++	u8 tda[3], reg, time_out = 0;
++	s8 tm;
+ 
+ 	dprintk("%s : FE_SET_FRONTEND\n", __func__);
+ 
+diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
+index 72d70984e99a6..6d3c92045c05f 100644
+--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
++++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_ctrl.c
+@@ -468,8 +468,10 @@ void s5p_mfc_close_mfc_inst(struct s5p_mfc_dev *dev, struct s5p_mfc_ctx *ctx)
+ 	s5p_mfc_hw_call(dev->mfc_ops, try_run, dev);
+ 	/* Wait until instance is returned or timeout occurred */
+ 	if (s5p_mfc_wait_for_done_ctx(ctx,
+-				S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0))
++				S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)){
++		clear_work_bit_irqsave(ctx);
+ 		mfc_err("Err returning instance\n");
++	}
+ 
+ 	/* Free resources */
+ 	s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx);
+diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+index b65e506665af7..f62703cebb77c 100644
+--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
++++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_enc.c
+@@ -1218,6 +1218,7 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
+ 	unsigned long mb_y_addr, mb_c_addr;
+ 	int slice_type;
+ 	unsigned int strm_size;
++	bool src_ready;
+ 
+ 	slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev);
+ 	strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev);
+@@ -1257,7 +1258,8 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
+ 			}
+ 		}
+ 	}
+-	if ((ctx->src_queue_cnt > 0) && (ctx->state == MFCINST_RUNNING)) {
++	if (ctx->src_queue_cnt > 0 && (ctx->state == MFCINST_RUNNING ||
++				       ctx->state == MFCINST_FINISHING)) {
+ 		mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
+ 									list);
+ 		if (mb_entry->flags & MFC_BUF_FLAG_USED) {
+@@ -1288,7 +1290,13 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
+ 		vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, strm_size);
+ 		vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE);
+ 	}
+-	if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0))
++
++	src_ready = true;
++	if (ctx->state == MFCINST_RUNNING && ctx->src_queue_cnt == 0)
++		src_ready = false;
++	if (ctx->state == MFCINST_FINISHING && ctx->ref_queue_cnt == 0)
++		src_ready = false;
++	if (!src_ready || ctx->dst_queue_cnt == 0)
+ 		clear_work_bit(ctx);
+ 
+ 	return 0;
+diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+index 8227004f67469..c0df5ac9fcff2 100644
+--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
++++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_opr_v6.c
+@@ -1060,7 +1060,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ 	}
+ 
+ 	/* aspect ratio VUI */
+-	readl(mfc_regs->e_h264_options);
++	reg = readl(mfc_regs->e_h264_options);
+ 	reg &= ~(0x1 << 5);
+ 	reg |= ((p_h264->vui_sar & 0x1) << 5);
+ 	writel(reg, mfc_regs->e_h264_options);
+@@ -1083,7 +1083,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ 
+ 	/* intra picture period for H.264 open GOP */
+ 	/* control */
+-	readl(mfc_regs->e_h264_options);
++	reg = readl(mfc_regs->e_h264_options);
+ 	reg &= ~(0x1 << 4);
+ 	reg |= ((p_h264->open_gop & 0x1) << 4);
+ 	writel(reg, mfc_regs->e_h264_options);
+@@ -1097,23 +1097,23 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ 	}
+ 
+ 	/* 'WEIGHTED_BI_PREDICTION' for B is disable */
+-	readl(mfc_regs->e_h264_options);
++	reg = readl(mfc_regs->e_h264_options);
+ 	reg &= ~(0x3 << 9);
+ 	writel(reg, mfc_regs->e_h264_options);
+ 
+ 	/* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */
+-	readl(mfc_regs->e_h264_options);
++	reg = readl(mfc_regs->e_h264_options);
+ 	reg &= ~(0x1 << 14);
+ 	writel(reg, mfc_regs->e_h264_options);
+ 
+ 	/* ASO */
+-	readl(mfc_regs->e_h264_options);
++	reg = readl(mfc_regs->e_h264_options);
+ 	reg &= ~(0x1 << 6);
+ 	reg |= ((p_h264->aso & 0x1) << 6);
+ 	writel(reg, mfc_regs->e_h264_options);
+ 
+ 	/* hier qp enable */
+-	readl(mfc_regs->e_h264_options);
++	reg = readl(mfc_regs->e_h264_options);
+ 	reg &= ~(0x1 << 8);
+ 	reg |= ((p_h264->open_gop & 0x1) << 8);
+ 	writel(reg, mfc_regs->e_h264_options);
+@@ -1134,7 +1134,7 @@ static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
+ 	writel(reg, mfc_regs->e_h264_num_t_layer);
+ 
+ 	/* frame packing SEI generation */
+-	readl(mfc_regs->e_h264_options);
++	reg = readl(mfc_regs->e_h264_options);
+ 	reg &= ~(0x1 << 25);
+ 	reg |= ((p_h264->sei_frame_packing & 0x1) << 25);
+ 	writel(reg, mfc_regs->e_h264_options);
+diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c
+index 51cb8cfce3236..d83800803cf1e 100644
+--- a/drivers/mmc/host/sdhci-sprd.c
++++ b/drivers/mmc/host/sdhci-sprd.c
+@@ -228,13 +228,15 @@ static inline void _sdhci_sprd_set_clock(struct sdhci_host *host,
+ 	div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8);
+ 	sdhci_enable_clk(host, div);
+ 
+-	/* enable auto gate sdhc_enable_auto_gate */
+-	val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
+-	mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN |
+-	       SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN;
+-	if (mask != (val & mask)) {
+-		val |= mask;
+-		sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI);
++	/* Enable CLK_AUTO when the clock is greater than 400K. */
++	if (clk > 400000) {
++		val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
++		mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN |
++			SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN;
++		if (mask != (val & mask)) {
++			val |= mask;
++			sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI);
++		}
+ 	}
+ }
+ 
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index 0cf1a1797ea32..2e0655c0b606f 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -1184,6 +1184,8 @@ spi_nor_find_best_erase_type(const struct spi_nor_erase_map *map,
+ 			continue;
+ 
+ 		erase = &map->erase_type[i];
++		if (!erase->size)
++			continue;
+ 
+ 		/* Alignment is not mandatory for overlaid regions */
+ 		if (region->offset & SNOR_OVERLAID_REGION &&
+diff --git a/drivers/mtd/spi-nor/gigadevice.c b/drivers/mtd/spi-nor/gigadevice.c
+index 119b38e6fc2a3..d57ddaf1525b3 100644
+--- a/drivers/mtd/spi-nor/gigadevice.c
++++ b/drivers/mtd/spi-nor/gigadevice.c
+@@ -8,19 +8,29 @@
+ 
+ #include "core.h"
+ 
+-static void gd25q256_default_init(struct spi_nor *nor)
++static int
++gd25q256_post_bfpt(struct spi_nor *nor,
++		   const struct sfdp_parameter_header *bfpt_header,
++		   const struct sfdp_bfpt *bfpt)
+ {
+ 	/*
+-	 * Some manufacturer like GigaDevice may use different
+-	 * bit to set QE on different memories, so the MFR can't
+-	 * indicate the quad_enable method for this case, we need
+-	 * to set it in the default_init fixup hook.
++	 * GD25Q256C supports the first version of JESD216 which does not define
++	 * the Quad Enable methods. Overwrite the default Quad Enable method.
++	 *
++	 * GD25Q256 GENERATION | SFDP MAJOR VERSION | SFDP MINOR VERSION
++	 *      GD25Q256C      | SFDP_JESD216_MAJOR | SFDP_JESD216_MINOR
++	 *      GD25Q256D      | SFDP_JESD216_MAJOR | SFDP_JESD216B_MINOR
++	 *      GD25Q256E      | SFDP_JESD216_MAJOR | SFDP_JESD216B_MINOR
+ 	 */
+-	nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
++	if (bfpt_header->major == SFDP_JESD216_MAJOR &&
++	    bfpt_header->minor == SFDP_JESD216_MINOR)
++		nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
++
++	return 0;
+ }
+ 
+ static const struct spi_nor_fixups gd25q256_fixups = {
+-	.default_init = gd25q256_default_init,
++	.post_bfpt = gd25q256_post_bfpt,
+ };
+ 
+ static const struct flash_info gigadevice_nor_parts[] = {
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 77d4f3eab9715..d52e598fd652b 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -2896,12 +2896,12 @@ static int ravb_remove(struct platform_device *pdev)
+ 			  priv->desc_bat_dma);
+ 	/* Set reset mode */
+ 	ravb_write(ndev, CCC_OPC_RESET, CCC);
+-	pm_runtime_put_sync(&pdev->dev);
+ 	unregister_netdev(ndev);
+ 	if (info->nc_queues)
+ 		netif_napi_del(&priv->napi[RAVB_NC]);
+ 	netif_napi_del(&priv->napi[RAVB_BE]);
+ 	ravb_mdio_release(priv);
++	pm_runtime_put_sync(&pdev->dev);
+ 	pm_runtime_disable(&pdev->dev);
+ 	reset_control_assert(priv->rstc);
+ 	free_netdev(ndev);
+diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c
+index 7390f94cd4ca2..a05bda7b9a3ba 100644
+--- a/drivers/net/wireless/microchip/wilc1000/sdio.c
++++ b/drivers/net/wireless/microchip/wilc1000/sdio.c
+@@ -20,6 +20,7 @@ static const struct sdio_device_id wilc_sdio_ids[] = {
+ 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MICROCHIP_WILC, SDIO_DEVICE_ID_MICROCHIP_WILC1000) },
+ 	{ },
+ };
++MODULE_DEVICE_TABLE(sdio, wilc_sdio_ids);
+ 
+ #define WILC_SDIO_BLOCK_SIZE 512
+ 
+diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c
+index e6c01db393f95..f26d2ba8a3715 100644
+--- a/drivers/of/kexec.c
++++ b/drivers/of/kexec.c
+@@ -281,7 +281,7 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image,
+ 				   const char *cmdline, size_t extra_fdt_size)
+ {
+ 	void *fdt;
+-	int ret, chosen_node;
++	int ret, chosen_node, len;
+ 	const void *prop;
+ 	size_t fdt_size;
+ 
+@@ -324,19 +324,19 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image,
+ 		goto out;
+ 
+ 	/* Did we boot using an initrd? */
+-	prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", NULL);
++	prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", &len);
+ 	if (prop) {
+ 		u64 tmp_start, tmp_end, tmp_size;
+ 
+-		tmp_start = fdt64_to_cpu(*((const fdt64_t *) prop));
++		tmp_start = of_read_number(prop, len / 4);
+ 
+-		prop = fdt_getprop(fdt, chosen_node, "linux,initrd-end", NULL);
++		prop = fdt_getprop(fdt, chosen_node, "linux,initrd-end", &len);
+ 		if (!prop) {
+ 			ret = -EINVAL;
+ 			goto out;
+ 		}
+ 
+-		tmp_end = fdt64_to_cpu(*((const fdt64_t *) prop));
++		tmp_end = of_read_number(prop, len / 4);
+ 
+ 		/*
+ 		 * kexec reserves exact initrd size, while firmware may
+diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
+index d4be9d2ee74d9..8bdc5e043831c 100644
+--- a/drivers/parisc/led.c
++++ b/drivers/parisc/led.c
+@@ -137,6 +137,9 @@ static int start_task(void)
+ 
+ 	/* Create the work queue and queue the LED task */
+ 	led_wq = create_singlethread_workqueue("led_wq");	
++	if (!led_wq)
++		return -ENOMEM;
++
+ 	queue_delayed_work(led_wq, &led_task, 0);
+ 
+ 	return 0;
+diff --git a/drivers/pci/doe.c b/drivers/pci/doe.c
+index e402f05068a53..66d9ab2886468 100644
+--- a/drivers/pci/doe.c
++++ b/drivers/pci/doe.c
+@@ -29,6 +29,9 @@
+ #define PCI_DOE_FLAG_CANCEL	0
+ #define PCI_DOE_FLAG_DEAD	1
+ 
++/* Max data object length is 2^18 dwords */
++#define PCI_DOE_MAX_LENGTH	(1 << 18)
++
+ /**
+  * struct pci_doe_mb - State for a single DOE mailbox
+  *
+@@ -107,6 +110,7 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
+ {
+ 	struct pci_dev *pdev = doe_mb->pdev;
+ 	int offset = doe_mb->cap_offset;
++	size_t length;
+ 	u32 val;
+ 	int i;
+ 
+@@ -123,15 +127,20 @@ static int pci_doe_send_req(struct pci_doe_mb *doe_mb,
+ 	if (FIELD_GET(PCI_DOE_STATUS_ERROR, val))
+ 		return -EIO;
+ 
++	/* Length is 2 DW of header + length of payload in DW */
++	length = 2 + task->request_pl_sz / sizeof(u32);
++	if (length > PCI_DOE_MAX_LENGTH)
++		return -EIO;
++	if (length == PCI_DOE_MAX_LENGTH)
++		length = 0;
++
+ 	/* Write DOE Header */
+ 	val = FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_1_VID, task->prot.vid) |
+ 		FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_1_TYPE, task->prot.type);
+ 	pci_write_config_dword(pdev, offset + PCI_DOE_WRITE, val);
+-	/* Length is 2 DW of header + length of payload in DW */
+ 	pci_write_config_dword(pdev, offset + PCI_DOE_WRITE,
+ 			       FIELD_PREP(PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH,
+-					  2 + task->request_pl_sz /
+-						sizeof(u32)));
++					  length));
+ 	for (i = 0; i < task->request_pl_sz / sizeof(u32); i++)
+ 		pci_write_config_dword(pdev, offset + PCI_DOE_WRITE,
+ 				       task->request_pl[i]);
+@@ -178,7 +187,10 @@ static int pci_doe_recv_resp(struct pci_doe_mb *doe_mb, struct pci_doe_task *tas
+ 	pci_write_config_dword(pdev, offset + PCI_DOE_READ, 0);
+ 
+ 	length = FIELD_GET(PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH, val);
+-	if (length > SZ_1M || length < 2)
++	/* A value of 0x0 indicates max data object length */
++	if (!length)
++		length = PCI_DOE_MAX_LENGTH;
++	if (length < 2)
+ 		return -EIO;
+ 
+ 	/* First 2 dwords have already been read */
+diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
+index fc804e08e3cb5..6dd4050c9f2ed 100644
+--- a/drivers/pci/pci-sysfs.c
++++ b/drivers/pci/pci-sysfs.c
+@@ -1174,11 +1174,9 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
+ 
+ 	sysfs_bin_attr_init(res_attr);
+ 	if (write_combine) {
+-		pdev->res_attr_wc[num] = res_attr;
+ 		sprintf(res_attr_name, "resource%d_wc", num);
+ 		res_attr->mmap = pci_mmap_resource_wc;
+ 	} else {
+-		pdev->res_attr[num] = res_attr;
+ 		sprintf(res_attr_name, "resource%d", num);
+ 		if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
+ 			res_attr->read = pci_read_resource_io;
+@@ -1196,10 +1194,17 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
+ 	res_attr->size = pci_resource_len(pdev, num);
+ 	res_attr->private = (void *)(unsigned long)num;
+ 	retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
+-	if (retval)
++	if (retval) {
+ 		kfree(res_attr);
++		return retval;
++	}
++
++	if (write_combine)
++		pdev->res_attr_wc[num] = res_attr;
++	else
++		pdev->res_attr[num] = res_attr;
+ 
+-	return retval;
++	return 0;
+ }
+ 
+ /**
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index 95bc329e74c0e..a484da1a9c66d 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -6462,6 +6462,8 @@ bool pci_device_is_present(struct pci_dev *pdev)
+ {
+ 	u32 v;
+ 
++	/* Check PF if pdev is a VF, since VF Vendor/Device IDs are 0xffff */
++	pdev = pci_physfn(pdev);
+ 	if (pci_dev_is_disconnected(pdev))
+ 		return false;
+ 	return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0);
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+index 3e730c05ac3fb..0feda8eb93b52 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+@@ -959,8 +959,8 @@ static const struct qmp_phy_cfg sc8180x_dpphy_cfg = {
+ 
+ 	.clk_list		= qmp_v3_phy_clk_l,
+ 	.num_clks		= ARRAY_SIZE(qmp_v3_phy_clk_l),
+-	.reset_list		= sc7180_usb3phy_reset_l,
+-	.num_resets		= ARRAY_SIZE(sc7180_usb3phy_reset_l),
++	.reset_list		= msm8996_usb3phy_reset_l,
++	.num_resets		= ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ 	.vreg_list		= qmp_phy_vreg_l,
+ 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
+ 	.regs			= qmp_v3_usb3phy_regs_layout,
+@@ -1032,8 +1032,8 @@ static const struct qmp_phy_cfg sm8250_dpphy_cfg = {
+ 	.serdes_tbl_hbr3	= qmp_v4_dp_serdes_tbl_hbr3,
+ 	.serdes_tbl_hbr3_num	= ARRAY_SIZE(qmp_v4_dp_serdes_tbl_hbr3),
+ 
+-	.clk_list		= qmp_v4_phy_clk_l,
+-	.num_clks		= ARRAY_SIZE(qmp_v4_phy_clk_l),
++	.clk_list		= qmp_v4_sm8250_usbphy_clk_l,
++	.num_clks		= ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l),
+ 	.reset_list		= msm8996_usb3phy_reset_l,
+ 	.num_resets		= ARRAY_SIZE(msm8996_usb3phy_reset_l),
+ 	.vreg_list		= qmp_phy_vreg_l,
+diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
+index ca0817f8e41e9..24ce0c0ee8463 100644
+--- a/drivers/remoteproc/imx_dsp_rproc.c
++++ b/drivers/remoteproc/imx_dsp_rproc.c
+@@ -347,9 +347,6 @@ static int imx_dsp_rproc_stop(struct rproc *rproc)
+ 	struct device *dev = rproc->dev.parent;
+ 	int ret = 0;
+ 
+-	/* Make sure work is finished */
+-	flush_work(&priv->rproc_work);
+-
+ 	if (rproc->state == RPROC_CRASHED) {
+ 		priv->flags &= ~REMOTE_IS_READY;
+ 		return 0;
+@@ -432,9 +429,18 @@ static void imx_dsp_rproc_vq_work(struct work_struct *work)
+ {
+ 	struct imx_dsp_rproc *priv = container_of(work, struct imx_dsp_rproc,
+ 						  rproc_work);
++	struct rproc *rproc = priv->rproc;
++
++	mutex_lock(&rproc->lock);
++
++	if (rproc->state != RPROC_RUNNING)
++		goto unlock_mutex;
+ 
+ 	rproc_vq_interrupt(priv->rproc, 0);
+ 	rproc_vq_interrupt(priv->rproc, 1);
++
++unlock_mutex:
++	mutex_unlock(&rproc->lock);
+ }
+ 
+ /**
+diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
+index 38383e7de3c1e..80592ccd10199 100644
+--- a/drivers/remoteproc/imx_rproc.c
++++ b/drivers/remoteproc/imx_rproc.c
+@@ -113,8 +113,8 @@ static const struct imx_rproc_att imx_rproc_att_imx93[] = {
+ 	{ 0x80000000, 0x80000000, 0x10000000, 0 },
+ 	{ 0x90000000, 0x80000000, 0x10000000, 0 },
+ 
+-	{ 0xC0000000, 0xa0000000, 0x10000000, 0 },
+-	{ 0xD0000000, 0xa0000000, 0x10000000, 0 },
++	{ 0xC0000000, 0xC0000000, 0x10000000, 0 },
++	{ 0xD0000000, 0xC0000000, 0x10000000, 0 },
+ };
+ 
+ static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
+diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
+index 4fc5ce2187ac8..3f5458372b783 100644
+--- a/drivers/remoteproc/remoteproc_core.c
++++ b/drivers/remoteproc/remoteproc_core.c
+@@ -1954,12 +1954,18 @@ static void rproc_crash_handler_work(struct work_struct *work)
+ 
+ 	mutex_lock(&rproc->lock);
+ 
+-	if (rproc->state == RPROC_CRASHED || rproc->state == RPROC_OFFLINE) {
++	if (rproc->state == RPROC_CRASHED) {
+ 		/* handle only the first crash detected */
+ 		mutex_unlock(&rproc->lock);
+ 		return;
+ 	}
+ 
++	if (rproc->state == RPROC_OFFLINE) {
++		/* Don't recover if the remote processor was stopped */
++		mutex_unlock(&rproc->lock);
++		goto out;
++	}
++
+ 	rproc->state = RPROC_CRASHED;
+ 	dev_err(dev, "handling crash #%u in %s\n", ++rproc->crash_cnt,
+ 		rproc->name);
+@@ -1969,6 +1975,7 @@ static void rproc_crash_handler_work(struct work_struct *work)
+ 	if (!rproc->recovery_disabled)
+ 		rproc_trigger_recovery(rproc);
+ 
++out:
+ 	pm_relax(rproc->dev.parent);
+ }
+ 
+diff --git a/drivers/rtc/rtc-ds1347.c b/drivers/rtc/rtc-ds1347.c
+index 157bf5209ac40..a40c1a52df659 100644
+--- a/drivers/rtc/rtc-ds1347.c
++++ b/drivers/rtc/rtc-ds1347.c
+@@ -112,7 +112,7 @@ static int ds1347_set_time(struct device *dev, struct rtc_time *dt)
+ 		return err;
+ 
+ 	century = (dt->tm_year / 100) + 19;
+-	err = regmap_write(map, DS1347_CENTURY_REG, century);
++	err = regmap_write(map, DS1347_CENTURY_REG, bin2bcd(century));
+ 	if (err)
+ 		return err;
+ 
+diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
+index e0d7a54595627..795a80a4faa8c 100644
+--- a/drivers/soc/qcom/Kconfig
++++ b/drivers/soc/qcom/Kconfig
+@@ -63,6 +63,7 @@ config QCOM_GSBI
+ config QCOM_LLCC
+ 	tristate "Qualcomm Technologies, Inc. LLCC driver"
+ 	depends on ARCH_QCOM || COMPILE_TEST
++	select REGMAP_MMIO
+ 	help
+ 	  Qualcomm Technologies, Inc. platform specific
+ 	  Last Level Cache Controller(LLCC) driver for platforms such as,
+@@ -236,6 +237,7 @@ config QCOM_ICC_BWMON
+ 	tristate "QCOM Interconnect Bandwidth Monitor driver"
+ 	depends on ARCH_QCOM || COMPILE_TEST
+ 	select PM_OPP
++	select REGMAP_MMIO
+ 	help
+ 	  Sets up driver monitoring bandwidth on various interconnects and
+ 	  based on that voting for interconnect bandwidth, adjusting their
+diff --git a/drivers/soc/ux500/ux500-soc-id.c b/drivers/soc/ux500/ux500-soc-id.c
+index a9472e0e5d61c..27d6e25a01153 100644
+--- a/drivers/soc/ux500/ux500-soc-id.c
++++ b/drivers/soc/ux500/ux500-soc-id.c
+@@ -167,20 +167,18 @@ ATTRIBUTE_GROUPS(ux500_soc);
+ static const char *db8500_read_soc_id(struct device_node *backupram)
+ {
+ 	void __iomem *base;
+-	void __iomem *uid;
+ 	const char *retstr;
++	u32 uid[5];
+ 
+ 	base = of_iomap(backupram, 0);
+ 	if (!base)
+ 		return NULL;
+-	uid = base + 0x1fc0;
++	memcpy_fromio(uid, base + 0x1fc0, sizeof(uid));
+ 
+ 	/* Throw these device-specific numbers into the entropy pool */
+-	add_device_randomness(uid, 0x14);
++	add_device_randomness(uid, sizeof(uid));
+ 	retstr = kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x",
+-			 readl((u32 *)uid+0),
+-			 readl((u32 *)uid+1), readl((u32 *)uid+2),
+-			 readl((u32 *)uid+3), readl((u32 *)uid+4));
++			   uid[0], uid[1], uid[2], uid[3], uid[4]);
+ 	iounmap(base);
+ 	return retstr;
+ }
+diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
+index 2234bb8d48b34..490ba0eb249b3 100644
+--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
+@@ -188,6 +188,28 @@ static int imgu_subdev_set_fmt(struct v4l2_subdev *sd,
+ 	return 0;
+ }
+ 
++static struct v4l2_rect *
++imgu_subdev_get_crop(struct imgu_v4l2_subdev *sd,
++		     struct v4l2_subdev_state *sd_state, unsigned int pad,
++		     enum v4l2_subdev_format_whence which)
++{
++	if (which == V4L2_SUBDEV_FORMAT_TRY)
++		return v4l2_subdev_get_try_crop(&sd->subdev, sd_state, pad);
++	else
++		return &sd->rect.eff;
++}
++
++static struct v4l2_rect *
++imgu_subdev_get_compose(struct imgu_v4l2_subdev *sd,
++			struct v4l2_subdev_state *sd_state, unsigned int pad,
++			enum v4l2_subdev_format_whence which)
++{
++	if (which == V4L2_SUBDEV_FORMAT_TRY)
++		return v4l2_subdev_get_try_compose(&sd->subdev, sd_state, pad);
++	else
++		return &sd->rect.bds;
++}
++
+ static int imgu_subdev_get_selection(struct v4l2_subdev *sd,
+ 				     struct v4l2_subdev_state *sd_state,
+ 				     struct v4l2_subdev_selection *sel)
+@@ -200,18 +222,12 @@ static int imgu_subdev_get_selection(struct v4l2_subdev *sd,
+ 
+ 	switch (sel->target) {
+ 	case V4L2_SEL_TGT_CROP:
+-		if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
+-			sel->r = *v4l2_subdev_get_try_crop(sd, sd_state,
+-							   sel->pad);
+-		else
+-			sel->r = imgu_sd->rect.eff;
++		sel->r = *imgu_subdev_get_crop(imgu_sd, sd_state, sel->pad,
++					       sel->which);
+ 		return 0;
+ 	case V4L2_SEL_TGT_COMPOSE:
+-		if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
+-			sel->r = *v4l2_subdev_get_try_compose(sd, sd_state,
+-							      sel->pad);
+-		else
+-			sel->r = imgu_sd->rect.bds;
++		sel->r = *imgu_subdev_get_compose(imgu_sd, sd_state, sel->pad,
++						  sel->which);
+ 		return 0;
+ 	default:
+ 		return -EINVAL;
+@@ -223,10 +239,9 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd,
+ 				     struct v4l2_subdev_selection *sel)
+ {
+ 	struct imgu_device *imgu = v4l2_get_subdevdata(sd);
+-	struct imgu_v4l2_subdev *imgu_sd = container_of(sd,
+-							struct imgu_v4l2_subdev,
+-							subdev);
+-	struct v4l2_rect *rect, *try_sel;
++	struct imgu_v4l2_subdev *imgu_sd =
++		container_of(sd, struct imgu_v4l2_subdev, subdev);
++	struct v4l2_rect *rect;
+ 
+ 	dev_dbg(&imgu->pci_dev->dev,
+ 		 "set subdev %u sel which %u target 0x%4x rect [%ux%u]",
+@@ -238,22 +253,18 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd,
+ 
+ 	switch (sel->target) {
+ 	case V4L2_SEL_TGT_CROP:
+-		try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad);
+-		rect = &imgu_sd->rect.eff;
++		rect = imgu_subdev_get_crop(imgu_sd, sd_state, sel->pad,
++					    sel->which);
+ 		break;
+ 	case V4L2_SEL_TGT_COMPOSE:
+-		try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad);
+-		rect = &imgu_sd->rect.bds;
++		rect = imgu_subdev_get_compose(imgu_sd, sd_state, sel->pad,
++					       sel->which);
+ 		break;
+ 	default:
+ 		return -EINVAL;
+ 	}
+ 
+-	if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
+-		*try_sel = sel->r;
+-	else
+-		*rect = sel->r;
+-
++	*rect = sel->r;
+ 	return 0;
+ }
+ 
+diff --git a/drivers/staging/media/tegra-video/csi.c b/drivers/staging/media/tegra-video/csi.c
+index b26e44adb2be7..426e653bd55d5 100644
+--- a/drivers/staging/media/tegra-video/csi.c
++++ b/drivers/staging/media/tegra-video/csi.c
+@@ -433,7 +433,7 @@ static int tegra_csi_channel_alloc(struct tegra_csi *csi,
+ 	for (i = 0; i < chan->numgangports; i++)
+ 		chan->csi_port_nums[i] = port_num + i * CSI_PORTS_PER_BRICK;
+ 
+-	chan->of_node = node;
++	chan->of_node = of_node_get(node);
+ 	chan->numpads = num_pads;
+ 	if (num_pads & 0x2) {
+ 		chan->pads[0].flags = MEDIA_PAD_FL_SINK;
+@@ -448,6 +448,7 @@ static int tegra_csi_channel_alloc(struct tegra_csi *csi,
+ 	chan->mipi = tegra_mipi_request(csi->dev, node);
+ 	if (IS_ERR(chan->mipi)) {
+ 		ret = PTR_ERR(chan->mipi);
++		chan->mipi = NULL;
+ 		dev_err(csi->dev, "failed to get mipi device: %d\n", ret);
+ 	}
+ 
+@@ -640,6 +641,7 @@ static void tegra_csi_channels_cleanup(struct tegra_csi *csi)
+ 			media_entity_cleanup(&subdev->entity);
+ 		}
+ 
++		of_node_put(chan->of_node);
+ 		list_del(&chan->list);
+ 		kfree(chan);
+ 	}
+diff --git a/drivers/staging/media/tegra-video/csi.h b/drivers/staging/media/tegra-video/csi.h
+index 4ee05a1785cfa..6960ea2e3d360 100644
+--- a/drivers/staging/media/tegra-video/csi.h
++++ b/drivers/staging/media/tegra-video/csi.h
+@@ -56,7 +56,7 @@ struct tegra_csi;
+  * @framerate: active framerate for TPG
+  * @h_blank: horizontal blanking for TPG active format
+  * @v_blank: vertical blanking for TPG active format
+- * @mipi: mipi device for corresponding csi channel pads
++ * @mipi: mipi device for corresponding csi channel pads, or NULL if not applicable (TPG, error)
+  * @pixel_rate: active pixel rate from the sensor on this channel
+  */
+ struct tegra_csi_channel {
+diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
+index 21c478df6aef4..ed53c0208f407 100644
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -433,6 +433,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
+ 	u64 wanted_disk_byte = ref->wanted_disk_byte;
+ 	u64 count = 0;
+ 	u64 data_offset;
++	u8 type;
+ 
+ 	if (level != 0) {
+ 		eb = path->nodes[level];
+@@ -487,6 +488,9 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
+ 			continue;
+ 		}
+ 		fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
++		type = btrfs_file_extent_type(eb, fi);
++		if (type == BTRFS_FILE_EXTENT_INLINE)
++			goto next;
+ 		disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
+ 		data_offset = btrfs_file_extent_offset(eb, fi);
+ 
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 7aa220742c61d..6f006430115a3 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -7128,8 +7128,9 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ 			map->stripes[i].dev = handle_missing_device(fs_info,
+ 								    devid, uuid);
+ 			if (IS_ERR(map->stripes[i].dev)) {
++				ret = PTR_ERR(map->stripes[i].dev);
+ 				free_extent_map(em);
+-				return PTR_ERR(map->stripes[i].dev);
++				return ret;
+ 			}
+ 		}
+ 
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index 712a431614480..6094cb2ff099b 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -678,9 +678,15 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
+ 	seq_printf(s, ",echo_interval=%lu",
+ 			tcon->ses->server->echo_interval / HZ);
+ 
+-	/* Only display max_credits if it was overridden on mount */
++	/* Only display the following if overridden on mount */
+ 	if (tcon->ses->server->max_credits != SMB2_MAX_CREDITS_AVAILABLE)
+ 		seq_printf(s, ",max_credits=%u", tcon->ses->server->max_credits);
++	if (tcon->ses->server->tcp_nodelay)
++		seq_puts(s, ",tcpnodelay");
++	if (tcon->ses->server->noautotune)
++		seq_puts(s, ",noautotune");
++	if (tcon->ses->server->noblocksnd)
++		seq_puts(s, ",noblocksend");
+ 
+ 	if (tcon->snapshot_time)
+ 		seq_printf(s, ",snapshot=%llu", tcon->snapshot_time);
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 816161f51b29d..4e4810339d763 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -279,8 +279,10 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
+ 			tcon->need_reconnect = true;
+ 			tcon->status = TID_NEED_RECON;
+ 		}
+-		if (ses->tcon_ipc)
++		if (ses->tcon_ipc) {
+ 			ses->tcon_ipc->need_reconnect = true;
++			ses->tcon_ipc->status = TID_NEED_RECON;
++		}
+ 
+ next_session:
+ 		spin_unlock(&ses->chan_lock);
+@@ -1870,6 +1872,9 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)
+ 
+ 	cifs_dbg(FYI, "IPC tcon rc=%d ipc tid=0x%x\n", rc, tcon->tid);
+ 
++	spin_lock(&tcon->tc_lock);
++	tcon->status = TID_GOOD;
++	spin_unlock(&tcon->tc_lock);
+ 	ses->tcon_ipc = tcon;
+ out:
+ 	return rc;
+@@ -2155,7 +2160,7 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx __attribute__((unused)),
+ struct cifs_ses *
+ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ {
+-	int rc = -ENOMEM;
++	int rc = 0;
+ 	unsigned int xid;
+ 	struct cifs_ses *ses;
+ 	struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
+@@ -2204,6 +2209,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ 		return ses;
+ 	}
+ 
++	rc = -ENOMEM;
++
+ 	cifs_dbg(FYI, "Existing smb sess not found\n");
+ 	ses = sesInfoAlloc();
+ 	if (ses == NULL)
+@@ -2276,10 +2283,10 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
+ 	list_add(&ses->smb_ses_list, &server->smb_ses_list);
+ 	spin_unlock(&cifs_tcp_ses_lock);
+ 
+-	free_xid(xid);
+-
+ 	cifs_setup_ipc(ses, ctx);
+ 
++	free_xid(xid);
++
+ 	return ses;
+ 
+ get_ses_fail:
+@@ -2598,6 +2605,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
+ 	tcon->nodelete = ctx->nodelete;
+ 	tcon->local_lease = ctx->local_lease;
+ 	INIT_LIST_HEAD(&tcon->pending_opens);
++	tcon->status = TID_GOOD;
+ 
+ 	/* schedule query interfaces poll */
+ 	INIT_DELAYED_WORK(&tcon->query_interfaces,
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index aa0245268d40e..6a12279671978 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -3481,7 +3481,7 @@ smb2_validate_and_copy_iov(unsigned int offset, unsigned int buffer_length,
+ 	if (rc)
+ 		return rc;
+ 
+-	memcpy(data, begin_of_buf, buffer_length);
++	memcpy(data, begin_of_buf, minbufsize);
+ 
+ 	return 0;
+ }
+@@ -3605,7 +3605,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
+ 
+ 	rc = smb2_validate_and_copy_iov(le16_to_cpu(rsp->OutputBufferOffset),
+ 					le32_to_cpu(rsp->OutputBufferLength),
+-					&rsp_iov, min_len, *data);
++					&rsp_iov, dlen ? *dlen : min_len, *data);
+ 	if (rc && allocated) {
+ 		kfree(*data);
+ 		*data = NULL;
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index 59f64c596233b..871d4e9f49fb6 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -1543,7 +1543,11 @@ static void process_recv_sockets(struct work_struct *work)
+ 
+ static void process_listen_recv_socket(struct work_struct *work)
+ {
+-	accept_from_sock(&listen_con);
++	int ret;
++
++	do {
++		ret = accept_from_sock(&listen_con);
++	} while (!ret);
+ }
+ 
+ static void dlm_connect(struct connection *con)
+@@ -1820,7 +1824,7 @@ static int dlm_listen_for_all(void)
+ 	result = sock->ops->listen(sock, 5);
+ 	if (result < 0) {
+ 		dlm_close_sock(&listen_con.sock);
+-		goto out;
++		return result;
+ 	}
+ 
+ 	return 0;
+@@ -2023,7 +2027,6 @@ fail_listen:
+ 	dlm_proto_ops = NULL;
+ fail_proto_ops:
+ 	dlm_allow_conn = 0;
+-	dlm_close_sock(&listen_con.sock);
+ 	work_stop();
+ fail_local:
+ 	deinit_local();
+diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
+index 8f597753ac129..5202eddfc3c0a 100644
+--- a/fs/ext2/dir.c
++++ b/fs/ext2/dir.c
+@@ -679,7 +679,7 @@ int ext2_empty_dir (struct inode * inode)
+ 		page = ext2_get_page(inode, i, 0, &page_addr);
+ 
+ 		if (IS_ERR(page))
+-			goto not_empty;
++			return 0;
+ 
+ 		kaddr = page_addr;
+ 		de = (ext2_dirent *)kaddr;
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 3bf9a6926798f..c3c52826212e7 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -558,7 +558,7 @@ enum {
+  *
+  * It's not paranoia if the Murphy's Law really *is* out to get you.  :-)
+  */
+-#define TEST_FLAG_VALUE(FLAG) (EXT4_##FLAG##_FL == (1 << EXT4_INODE_##FLAG))
++#define TEST_FLAG_VALUE(FLAG) (EXT4_##FLAG##_FL == (1U << EXT4_INODE_##FLAG))
+ #define CHECK_FLAG_VALUE(FLAG) BUILD_BUG_ON(!TEST_FLAG_VALUE(FLAG))
+ 
+ static inline void ext4_check_flag_values(void)
+@@ -2964,7 +2964,8 @@ int do_journal_get_write_access(handle_t *handle, struct inode *inode,
+ typedef enum {
+ 	EXT4_IGET_NORMAL =	0,
+ 	EXT4_IGET_SPECIAL =	0x0001, /* OK to iget a system inode */
+-	EXT4_IGET_HANDLE = 	0x0002	/* Inode # is from a handle */
++	EXT4_IGET_HANDLE = 	0x0002,	/* Inode # is from a handle */
++	EXT4_IGET_BAD =		0x0004  /* Allow to iget a bad inode */
+ } ext4_iget_flags;
+ 
+ extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
+@@ -3621,8 +3622,8 @@ extern void ext4_initialize_dirent_tail(struct buffer_head *bh,
+ 					unsigned int blocksize);
+ extern int ext4_handle_dirty_dirblock(handle_t *handle, struct inode *inode,
+ 				      struct buffer_head *bh);
+-extern int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name,
+-			 struct inode *inode);
++extern int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
++			 struct inode *inode, struct dentry *dentry);
+ extern int __ext4_link(struct inode *dir, struct inode *inode,
+ 		       struct dentry *dentry);
+ 
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 8378b86c1b496..eee73abc21f65 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5803,6 +5803,14 @@ int ext4_clu_mapped(struct inode *inode, ext4_lblk_t lclu)
+ 	struct ext4_extent *extent;
+ 	ext4_lblk_t first_lblk, first_lclu, last_lclu;
+ 
++	/*
++	 * if data can be stored inline, the logical cluster isn't
++	 * mapped - no physical clusters have been allocated, and the
++	 * file has no extents
++	 */
++	if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
++		return 0;
++
+ 	/* search for the extent closest to the first block in the cluster */
+ 	path = ext4_find_extent(inode, EXT4_C2B(sbi, lclu), NULL, 0);
+ 	if (IS_ERR(path)) {
+diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
+index 23167efda95ee..9c2459ddedb45 100644
+--- a/fs/ext4/extents_status.c
++++ b/fs/ext4/extents_status.c
+@@ -1372,7 +1372,7 @@ retry:
+ 		if (count_reserved)
+ 			count_rsvd(inode, lblk, orig_es.es_len - len1 - len2,
+ 				   &orig_es, &rc);
+-		goto out;
++		goto out_get_reserved;
+ 	}
+ 
+ 	if (len1 > 0) {
+@@ -1414,6 +1414,7 @@ retry:
+ 		}
+ 	}
+ 
++out_get_reserved:
+ 	if (count_reserved)
+ 		*reserved = get_rsvd(inode, end, es, &rc);
+ out:
+diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
+index e5d20da585287..8ceedc14928af 100644
+--- a/fs/ext4/fast_commit.c
++++ b/fs/ext4/fast_commit.c
+@@ -418,25 +418,34 @@ static int __track_dentry_update(struct inode *inode, void *arg, bool update)
+ 	struct __track_dentry_update_args *dentry_update =
+ 		(struct __track_dentry_update_args *)arg;
+ 	struct dentry *dentry = dentry_update->dentry;
+-	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
++	struct inode *dir = dentry->d_parent->d_inode;
++	struct super_block *sb = inode->i_sb;
++	struct ext4_sb_info *sbi = EXT4_SB(sb);
+ 
+ 	mutex_unlock(&ei->i_fc_lock);
++
++	if (IS_ENCRYPTED(dir)) {
++		ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_ENCRYPTED_FILENAME,
++					NULL);
++		mutex_lock(&ei->i_fc_lock);
++		return -EOPNOTSUPP;
++	}
++
+ 	node = kmem_cache_alloc(ext4_fc_dentry_cachep, GFP_NOFS);
+ 	if (!node) {
+-		ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_NOMEM, NULL);
++		ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, NULL);
+ 		mutex_lock(&ei->i_fc_lock);
+ 		return -ENOMEM;
+ 	}
+ 
+ 	node->fcd_op = dentry_update->op;
+-	node->fcd_parent = dentry->d_parent->d_inode->i_ino;
++	node->fcd_parent = dir->i_ino;
+ 	node->fcd_ino = inode->i_ino;
+ 	if (dentry->d_name.len > DNAME_INLINE_LEN) {
+ 		node->fcd_name.name = kmalloc(dentry->d_name.len, GFP_NOFS);
+ 		if (!node->fcd_name.name) {
+ 			kmem_cache_free(ext4_fc_dentry_cachep, node);
+-			ext4_fc_mark_ineligible(inode->i_sb,
+-				EXT4_FC_REASON_NOMEM, NULL);
++			ext4_fc_mark_ineligible(sb, EXT4_FC_REASON_NOMEM, NULL);
+ 			mutex_lock(&ei->i_fc_lock);
+ 			return -ENOMEM;
+ 		}
+@@ -674,6 +683,15 @@ static void ext4_fc_submit_bh(struct super_block *sb, bool is_tail)
+ 
+ /* Ext4 commit path routines */
+ 
++/* memcpy to fc reserved space and update CRC */
++static void *ext4_fc_memcpy(struct super_block *sb, void *dst, const void *src,
++				int len, u32 *crc)
++{
++	if (crc)
++		*crc = ext4_chksum(EXT4_SB(sb), *crc, src, len);
++	return memcpy(dst, src, len);
++}
++
+ /* memzero and update CRC */
+ static void *ext4_fc_memzero(struct super_block *sb, void *dst, int len,
+ 				u32 *crc)
+@@ -699,62 +717,59 @@ static void *ext4_fc_memzero(struct super_block *sb, void *dst, int len,
+  */
+ static u8 *ext4_fc_reserve_space(struct super_block *sb, int len, u32 *crc)
+ {
+-	struct ext4_fc_tl *tl;
++	struct ext4_fc_tl tl;
+ 	struct ext4_sb_info *sbi = EXT4_SB(sb);
+ 	struct buffer_head *bh;
+ 	int bsize = sbi->s_journal->j_blocksize;
+ 	int ret, off = sbi->s_fc_bytes % bsize;
+-	int pad_len;
++	int remaining;
++	u8 *dst;
+ 
+ 	/*
+-	 * After allocating len, we should have space at least for a 0 byte
+-	 * padding.
++	 * If 'len' is too long to fit in any block alongside a PAD tlv, then we
++	 * cannot fulfill the request.
+ 	 */
+-	if (len + EXT4_FC_TAG_BASE_LEN > bsize)
++	if (len > bsize - EXT4_FC_TAG_BASE_LEN)
+ 		return NULL;
+ 
+-	if (bsize - off - 1 > len + EXT4_FC_TAG_BASE_LEN) {
+-		/*
+-		 * Only allocate from current buffer if we have enough space for
+-		 * this request AND we have space to add a zero byte padding.
+-		 */
+-		if (!sbi->s_fc_bh) {
+-			ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh);
+-			if (ret)
+-				return NULL;
+-			sbi->s_fc_bh = bh;
+-		}
++	if (!sbi->s_fc_bh) {
++		ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh);
++		if (ret)
++			return NULL;
++		sbi->s_fc_bh = bh;
++	}
++	dst = sbi->s_fc_bh->b_data + off;
++
++	/*
++	 * Allocate the bytes in the current block if we can do so while still
++	 * leaving enough space for a PAD tlv.
++	 */
++	remaining = bsize - EXT4_FC_TAG_BASE_LEN - off;
++	if (len <= remaining) {
+ 		sbi->s_fc_bytes += len;
+-		return sbi->s_fc_bh->b_data + off;
++		return dst;
+ 	}
+-	/* Need to add PAD tag */
+-	tl = (struct ext4_fc_tl *)(sbi->s_fc_bh->b_data + off);
+-	tl->fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD);
+-	pad_len = bsize - off - 1 - EXT4_FC_TAG_BASE_LEN;
+-	tl->fc_len = cpu_to_le16(pad_len);
+-	if (crc)
+-		*crc = ext4_chksum(sbi, *crc, tl, EXT4_FC_TAG_BASE_LEN);
+-	if (pad_len > 0)
+-		ext4_fc_memzero(sb, tl + 1, pad_len, crc);
++
++	/*
++	 * Else, terminate the current block with a PAD tlv, then allocate a new
++	 * block and allocate the bytes at the start of that new block.
++	 */
++
++	tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD);
++	tl.fc_len = cpu_to_le16(remaining);
++	ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc);
++	ext4_fc_memzero(sb, dst + EXT4_FC_TAG_BASE_LEN, remaining, crc);
++
+ 	ext4_fc_submit_bh(sb, false);
+ 
+ 	ret = jbd2_fc_get_buf(EXT4_SB(sb)->s_journal, &bh);
+ 	if (ret)
+ 		return NULL;
+ 	sbi->s_fc_bh = bh;
+-	sbi->s_fc_bytes = (sbi->s_fc_bytes / bsize + 1) * bsize + len;
++	sbi->s_fc_bytes += bsize - off + len;
+ 	return sbi->s_fc_bh->b_data;
+ }
+ 
+-/* memcpy to fc reserved space and update CRC */
+-static void *ext4_fc_memcpy(struct super_block *sb, void *dst, const void *src,
+-				int len, u32 *crc)
+-{
+-	if (crc)
+-		*crc = ext4_chksum(EXT4_SB(sb), *crc, src, len);
+-	return memcpy(dst, src, len);
+-}
+-
+ /*
+  * Complete a fast commit by writing tail tag.
+  *
+@@ -782,7 +797,7 @@ static int ext4_fc_write_tail(struct super_block *sb, u32 crc)
+ 	off = sbi->s_fc_bytes % bsize;
+ 
+ 	tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_TAIL);
+-	tl.fc_len = cpu_to_le16(bsize - off - 1 + sizeof(struct ext4_fc_tail));
++	tl.fc_len = cpu_to_le16(bsize - off + sizeof(struct ext4_fc_tail));
+ 	sbi->s_fc_bytes = round_up(sbi->s_fc_bytes, bsize);
+ 
+ 	ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, &crc);
+@@ -792,6 +807,8 @@ static int ext4_fc_write_tail(struct super_block *sb, u32 crc)
+ 	dst += sizeof(tail.fc_tid);
+ 	tail.fc_crc = cpu_to_le32(crc);
+ 	ext4_fc_memcpy(sb, dst, &tail.fc_crc, sizeof(tail.fc_crc), NULL);
++	dst += sizeof(tail.fc_crc);
++	memset(dst, 0, bsize - off); /* Don't leak uninitialized memory. */
+ 
+ 	ext4_fc_submit_bh(sb, true);
+ 
+@@ -1396,7 +1413,7 @@ static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl,
+ 		return 0;
+ 	}
+ 
+-	ret = __ext4_unlink(NULL, old_parent, &entry, inode);
++	ret = __ext4_unlink(old_parent, &entry, inode, NULL);
+ 	/* -ENOENT ok coz it might not exist anymore. */
+ 	if (ret == -ENOENT)
+ 		ret = 0;
+@@ -1986,32 +2003,31 @@ void ext4_fc_replay_cleanup(struct super_block *sb)
+ 	kfree(sbi->s_fc_replay_state.fc_modified_inodes);
+ }
+ 
+-static inline bool ext4_fc_tag_len_isvalid(struct ext4_fc_tl *tl,
+-					   u8 *val, u8 *end)
++static bool ext4_fc_value_len_isvalid(struct ext4_sb_info *sbi,
++				      int tag, int len)
+ {
+-	if (val + tl->fc_len > end)
+-		return false;
+-
+-	/* Here only check ADD_RANGE/TAIL/HEAD which will read data when do
+-	 * journal rescan before do CRC check. Other tags length check will
+-	 * rely on CRC check.
+-	 */
+-	switch (tl->fc_tag) {
++	switch (tag) {
+ 	case EXT4_FC_TAG_ADD_RANGE:
+-		return (sizeof(struct ext4_fc_add_range) == tl->fc_len);
+-	case EXT4_FC_TAG_TAIL:
+-		return (sizeof(struct ext4_fc_tail) <= tl->fc_len);
+-	case EXT4_FC_TAG_HEAD:
+-		return (sizeof(struct ext4_fc_head) == tl->fc_len);
++		return len == sizeof(struct ext4_fc_add_range);
+ 	case EXT4_FC_TAG_DEL_RANGE:
++		return len == sizeof(struct ext4_fc_del_range);
++	case EXT4_FC_TAG_CREAT:
+ 	case EXT4_FC_TAG_LINK:
+ 	case EXT4_FC_TAG_UNLINK:
+-	case EXT4_FC_TAG_CREAT:
++		len -= sizeof(struct ext4_fc_dentry_info);
++		return len >= 1 && len <= EXT4_NAME_LEN;
+ 	case EXT4_FC_TAG_INODE:
++		len -= sizeof(struct ext4_fc_inode);
++		return len >= EXT4_GOOD_OLD_INODE_SIZE &&
++			len <= sbi->s_inode_size;
+ 	case EXT4_FC_TAG_PAD:
+-	default:
+-		return true;
++		return true; /* padding can have any length */
++	case EXT4_FC_TAG_TAIL:
++		return len >= sizeof(struct ext4_fc_tail);
++	case EXT4_FC_TAG_HEAD:
++		return len == sizeof(struct ext4_fc_head);
+ 	}
++	return false;
+ }
+ 
+ /*
+@@ -2049,7 +2065,7 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ 	state = &sbi->s_fc_replay_state;
+ 
+ 	start = (u8 *)bh->b_data;
+-	end = (__u8 *)bh->b_data + journal->j_blocksize - 1;
++	end = start + journal->j_blocksize;
+ 
+ 	if (state->fc_replay_expected_off == 0) {
+ 		state->fc_cur_tag = 0;
+@@ -2070,11 +2086,12 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ 	}
+ 
+ 	state->fc_replay_expected_off++;
+-	for (cur = start; cur < end - EXT4_FC_TAG_BASE_LEN;
++	for (cur = start; cur <= end - EXT4_FC_TAG_BASE_LEN;
+ 	     cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) {
+ 		ext4_fc_get_tl(&tl, cur);
+ 		val = cur + EXT4_FC_TAG_BASE_LEN;
+-		if (!ext4_fc_tag_len_isvalid(&tl, val, end)) {
++		if (tl.fc_len > end - val ||
++		    !ext4_fc_value_len_isvalid(sbi, tl.fc_tag, tl.fc_len)) {
+ 			ret = state->fc_replay_num_tags ?
+ 				JBD2_FC_REPLAY_STOP : -ECANCELED;
+ 			goto out_err;
+@@ -2187,9 +2204,9 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
+ #endif
+ 
+ 	start = (u8 *)bh->b_data;
+-	end = (__u8 *)bh->b_data + journal->j_blocksize - 1;
++	end = start + journal->j_blocksize;
+ 
+-	for (cur = start; cur < end - EXT4_FC_TAG_BASE_LEN;
++	for (cur = start; cur <= end - EXT4_FC_TAG_BASE_LEN;
+ 	     cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) {
+ 		ext4_fc_get_tl(&tl, cur);
+ 		val = cur + EXT4_FC_TAG_BASE_LEN;
+@@ -2258,17 +2275,17 @@ void ext4_fc_init(struct super_block *sb, journal_t *journal)
+ 	journal->j_fc_cleanup_callback = ext4_fc_cleanup;
+ }
+ 
+-static const char *fc_ineligible_reasons[] = {
+-	"Extended attributes changed",
+-	"Cross rename",
+-	"Journal flag changed",
+-	"Insufficient memory",
+-	"Swap boot",
+-	"Resize",
+-	"Dir renamed",
+-	"Falloc range op",
+-	"Data journalling",
+-	"FC Commit Failed"
++static const char * const fc_ineligible_reasons[] = {
++	[EXT4_FC_REASON_XATTR] = "Extended attributes changed",
++	[EXT4_FC_REASON_CROSS_RENAME] = "Cross rename",
++	[EXT4_FC_REASON_JOURNAL_FLAG_CHANGE] = "Journal flag changed",
++	[EXT4_FC_REASON_NOMEM] = "Insufficient memory",
++	[EXT4_FC_REASON_SWAP_BOOT] = "Swap boot",
++	[EXT4_FC_REASON_RESIZE] = "Resize",
++	[EXT4_FC_REASON_RENAME_DIR] = "Dir renamed",
++	[EXT4_FC_REASON_FALLOC_RANGE] = "Falloc range op",
++	[EXT4_FC_REASON_INODE_JOURNAL_DATA] = "Data journalling",
++	[EXT4_FC_REASON_ENCRYPTED_FILENAME] = "Encrypted filename",
+ };
+ 
+ int ext4_fc_info_show(struct seq_file *seq, void *v)
+diff --git a/fs/ext4/fast_commit.h b/fs/ext4/fast_commit.h
+index a6154c3ed1357..2fadb2c4780c8 100644
+--- a/fs/ext4/fast_commit.h
++++ b/fs/ext4/fast_commit.h
+@@ -58,7 +58,7 @@ struct ext4_fc_dentry_info {
+ 	__u8 fc_dname[];
+ };
+ 
+-/* Value structure for EXT4_FC_TAG_INODE and EXT4_FC_TAG_INODE_PARTIAL. */
++/* Value structure for EXT4_FC_TAG_INODE. */
+ struct ext4_fc_inode {
+ 	__le32 fc_ino;
+ 	__u8 fc_raw_inode[];
+@@ -96,6 +96,7 @@ enum {
+ 	EXT4_FC_REASON_RENAME_DIR,
+ 	EXT4_FC_REASON_FALLOC_RANGE,
+ 	EXT4_FC_REASON_INODE_JOURNAL_DATA,
++	EXT4_FC_REASON_ENCRYPTED_FILENAME,
+ 	EXT4_FC_REASON_MAX
+ };
+ 
+diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
+index 860fc51190098..c68bebe7ff4b6 100644
+--- a/fs/ext4/indirect.c
++++ b/fs/ext4/indirect.c
+@@ -148,6 +148,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth,
+ 	struct super_block *sb = inode->i_sb;
+ 	Indirect *p = chain;
+ 	struct buffer_head *bh;
++	unsigned int key;
+ 	int ret = -EIO;
+ 
+ 	*err = 0;
+@@ -156,7 +157,13 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth,
+ 	if (!p->key)
+ 		goto no_block;
+ 	while (--depth) {
+-		bh = sb_getblk(sb, le32_to_cpu(p->key));
++		key = le32_to_cpu(p->key);
++		if (key > ext4_blocks_count(EXT4_SB(sb)->s_es)) {
++			/* the block was out of range */
++			ret = -EFSCORRUPTED;
++			goto failure;
++		}
++		bh = sb_getblk(sb, key);
+ 		if (unlikely(!bh)) {
+ 			ret = -ENOMEM;
+ 			goto failure;
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 6da73be32bff3..8cfbcfcb67b9a 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -222,13 +222,13 @@ void ext4_evict_inode(struct inode *inode)
+ 
+ 	/*
+ 	 * For inodes with journalled data, transaction commit could have
+-	 * dirtied the inode. Flush worker is ignoring it because of I_FREEING
+-	 * flag but we still need to remove the inode from the writeback lists.
++	 * dirtied the inode. And for inodes with dioread_nolock, unwritten
++	 * extents converting worker could merge extents and also have dirtied
++	 * the inode. Flush worker is ignoring it because of I_FREEING flag but
++	 * we still need to remove the inode from the writeback lists.
+ 	 */
+-	if (!list_empty_careful(&inode->i_io_list)) {
+-		WARN_ON_ONCE(!ext4_should_journal_data(inode));
++	if (!list_empty_careful(&inode->i_io_list))
+ 		inode_io_list_del(inode);
+-	}
+ 
+ 	/*
+ 	 * Protect us against freezing - iput() caller didn't have to have any
+@@ -335,6 +335,12 @@ stop_handle:
+ 	ext4_xattr_inode_array_free(ea_inode_array);
+ 	return;
+ no_delete:
++	/*
++	 * Check out some where else accidentally dirty the evicting inode,
++	 * which may probably cause inode use-after-free issues later.
++	 */
++	WARN_ON_ONCE(!list_empty_careful(&inode->i_io_list));
++
+ 	if (!list_empty(&EXT4_I(inode)->i_fc_list))
+ 		ext4_fc_mark_ineligible(inode->i_sb, EXT4_FC_REASON_NOMEM, NULL);
+ 	ext4_clear_inode(inode);	/* We must guarantee clearing of inode... */
+@@ -1309,7 +1315,8 @@ static int ext4_write_end(struct file *file,
+ 
+ 	trace_ext4_write_end(inode, pos, len, copied);
+ 
+-	if (ext4_has_inline_data(inode))
++	if (ext4_has_inline_data(inode) &&
++	    ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
+ 		return ext4_write_inline_data_end(inode, pos, len, copied, page);
+ 
+ 	copied = block_write_end(file, mapping, pos, len, copied, page, fsdata);
+@@ -4225,7 +4232,8 @@ int ext4_truncate(struct inode *inode)
+ 
+ 	/* If we zero-out tail of the page, we have to create jinode for jbd2 */
+ 	if (inode->i_size & (inode->i_sb->s_blocksize - 1)) {
+-		if (ext4_inode_attach_jinode(inode) < 0)
++		err = ext4_inode_attach_jinode(inode);
++		if (err)
+ 			goto out_trace;
+ 	}
+ 
+@@ -4473,9 +4481,17 @@ static int __ext4_get_inode_loc(struct super_block *sb, unsigned long ino,
+ 	inodes_per_block = EXT4_SB(sb)->s_inodes_per_block;
+ 	inode_offset = ((ino - 1) %
+ 			EXT4_INODES_PER_GROUP(sb));
+-	block = ext4_inode_table(sb, gdp) + (inode_offset / inodes_per_block);
+ 	iloc->offset = (inode_offset % inodes_per_block) * EXT4_INODE_SIZE(sb);
+ 
++	block = ext4_inode_table(sb, gdp);
++	if ((block <= le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) ||
++	    (block >= ext4_blocks_count(EXT4_SB(sb)->s_es))) {
++		ext4_error(sb, "Invalid inode table block %llu in "
++			   "block_group %u", block, iloc->block_group);
++		return -EFSCORRUPTED;
++	}
++	block += (inode_offset / inodes_per_block);
++
+ 	bh = sb_getblk(sb, block);
+ 	if (unlikely(!bh))
+ 		return -ENOMEM;
+@@ -5044,8 +5060,14 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
+ 	if (IS_CASEFOLDED(inode) && !ext4_has_feature_casefold(inode->i_sb))
+ 		ext4_error_inode(inode, function, line, 0,
+ 				 "casefold flag without casefold feature");
+-	brelse(iloc.bh);
++	if (is_bad_inode(inode) && !(flags & EXT4_IGET_BAD)) {
++		ext4_error_inode(inode, function, line, 0,
++				 "bad inode without EXT4_IGET_BAD flag");
++		ret = -EUCLEAN;
++		goto bad_inode;
++	}
+ 
++	brelse(iloc.bh);
+ 	unlock_new_inode(inode);
+ 	return inode;
+ 
+@@ -5816,6 +5838,14 @@ static int __ext4_expand_extra_isize(struct inode *inode,
+ 		return 0;
+ 	}
+ 
++	/*
++	 * We may need to allocate external xattr block so we need quotas
++	 * initialized. Here we can be called with various locks held so we
++	 * cannot affort to initialize quotas ourselves. So just bail.
++	 */
++	if (dquot_initialize_needed(inode))
++		return -EAGAIN;
++
+ 	/* try to expand with EAs present */
+ 	error = ext4_expand_extra_isize_ea(inode, new_extra_isize,
+ 					   raw_inode, handle);
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index eed8bd7812d58..62a68d9cee1cb 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -374,7 +374,8 @@ static long swap_inode_boot_loader(struct super_block *sb,
+ 	blkcnt_t blocks;
+ 	unsigned short bytes;
+ 
+-	inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO, EXT4_IGET_SPECIAL);
++	inode_bl = ext4_iget(sb, EXT4_BOOT_LOADER_INO,
++			EXT4_IGET_SPECIAL | EXT4_IGET_BAD);
+ 	if (IS_ERR(inode_bl))
+ 		return PTR_ERR(inode_bl);
+ 	ei_bl = EXT4_I(inode_bl);
+@@ -424,7 +425,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
+ 	/* Protect extent tree against block allocations via delalloc */
+ 	ext4_double_down_write_data_sem(inode, inode_bl);
+ 
+-	if (inode_bl->i_nlink == 0) {
++	if (is_bad_inode(inode_bl) || !S_ISREG(inode_bl->i_mode)) {
+ 		/* this inode has never been used as a BOOT_LOADER */
+ 		set_nlink(inode_bl, 1);
+ 		i_uid_write(inode_bl, 0);
+@@ -731,6 +732,10 @@ static int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ 	if (ext4_is_quota_file(inode))
+ 		return err;
+ 
++	err = dquot_initialize(inode);
++	if (err)
++		return err;
++
+ 	err = ext4_get_inode_loc(inode, &iloc);
+ 	if (err)
+ 		return err;
+@@ -746,10 +751,6 @@ static int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ 		brelse(iloc.bh);
+ 	}
+ 
+-	err = dquot_initialize(inode);
+-	if (err)
+-		return err;
+-
+ 	handle = ext4_journal_start(inode, EXT4_HT_QUOTA,
+ 		EXT4_QUOTA_INIT_BLOCKS(sb) +
+ 		EXT4_QUOTA_DEL_BLOCKS(sb) + 3);
+@@ -1156,19 +1157,22 @@ static int ext4_ioctl_getuuid(struct ext4_sb_info *sbi,
+ 
+ 	if (fsuuid.fsu_len == 0) {
+ 		fsuuid.fsu_len = UUID_SIZE;
+-		if (copy_to_user(ufsuuid, &fsuuid, sizeof(fsuuid.fsu_len)))
++		if (copy_to_user(&ufsuuid->fsu_len, &fsuuid.fsu_len,
++					sizeof(fsuuid.fsu_len)))
+ 			return -EFAULT;
+-		return -EINVAL;
++		return 0;
+ 	}
+ 
+-	if (fsuuid.fsu_len != UUID_SIZE || fsuuid.fsu_flags != 0)
++	if (fsuuid.fsu_len < UUID_SIZE || fsuuid.fsu_flags != 0)
+ 		return -EINVAL;
+ 
+ 	lock_buffer(sbi->s_sbh);
+ 	memcpy(uuid, sbi->s_es->s_uuid, UUID_SIZE);
+ 	unlock_buffer(sbi->s_sbh);
+ 
+-	if (copy_to_user(&ufsuuid->fsu_uuid[0], uuid, UUID_SIZE))
++	fsuuid.fsu_len = UUID_SIZE;
++	if (copy_to_user(ufsuuid, &fsuuid, sizeof(fsuuid)) ||
++	    copy_to_user(&ufsuuid->fsu_uuid[0], uuid, UUID_SIZE))
+ 		return -EFAULT;
+ 	return 0;
+ }
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index be8136aafa22c..1e1a421333e8d 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -3204,14 +3204,20 @@ end_rmdir:
+ 	return retval;
+ }
+ 
+-int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name,
+-		  struct inode *inode)
++int __ext4_unlink(struct inode *dir, const struct qstr *d_name,
++		  struct inode *inode,
++		  struct dentry *dentry /* NULL during fast_commit recovery */)
+ {
+ 	int retval = -ENOENT;
+ 	struct buffer_head *bh;
+ 	struct ext4_dir_entry_2 *de;
++	handle_t *handle;
+ 	int skip_remove_dentry = 0;
+ 
++	/*
++	 * Keep this outside the transaction; it may have to set up the
++	 * directory's encryption key, which isn't GFP_NOFS-safe.
++	 */
+ 	bh = ext4_find_entry(dir, d_name, &de, NULL);
+ 	if (IS_ERR(bh))
+ 		return PTR_ERR(bh);
+@@ -3228,7 +3234,14 @@ int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name
+ 		if (EXT4_SB(inode->i_sb)->s_mount_state & EXT4_FC_REPLAY)
+ 			skip_remove_dentry = 1;
+ 		else
+-			goto out;
++			goto out_bh;
++	}
++
++	handle = ext4_journal_start(dir, EXT4_HT_DIR,
++				    EXT4_DATA_TRANS_BLOCKS(dir->i_sb));
++	if (IS_ERR(handle)) {
++		retval = PTR_ERR(handle);
++		goto out_bh;
+ 	}
+ 
+ 	if (IS_DIRSYNC(dir))
+@@ -3237,12 +3250,12 @@ int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name
+ 	if (!skip_remove_dentry) {
+ 		retval = ext4_delete_entry(handle, dir, de, bh);
+ 		if (retval)
+-			goto out;
++			goto out_handle;
+ 		dir->i_ctime = dir->i_mtime = current_time(dir);
+ 		ext4_update_dx_flag(dir);
+ 		retval = ext4_mark_inode_dirty(handle, dir);
+ 		if (retval)
+-			goto out;
++			goto out_handle;
+ 	} else {
+ 		retval = 0;
+ 	}
+@@ -3255,15 +3268,17 @@ int __ext4_unlink(handle_t *handle, struct inode *dir, const struct qstr *d_name
+ 		ext4_orphan_add(handle, inode);
+ 	inode->i_ctime = current_time(inode);
+ 	retval = ext4_mark_inode_dirty(handle, inode);
+-
+-out:
++	if (dentry && !retval)
++		ext4_fc_track_unlink(handle, dentry);
++out_handle:
++	ext4_journal_stop(handle);
++out_bh:
+ 	brelse(bh);
+ 	return retval;
+ }
+ 
+ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
+ {
+-	handle_t *handle;
+ 	int retval;
+ 
+ 	if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb))))
+@@ -3281,16 +3296,7 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
+ 	if (retval)
+ 		goto out_trace;
+ 
+-	handle = ext4_journal_start(dir, EXT4_HT_DIR,
+-				    EXT4_DATA_TRANS_BLOCKS(dir->i_sb));
+-	if (IS_ERR(handle)) {
+-		retval = PTR_ERR(handle);
+-		goto out_trace;
+-	}
+-
+-	retval = __ext4_unlink(handle, dir, &dentry->d_name, d_inode(dentry));
+-	if (!retval)
+-		ext4_fc_track_unlink(handle, dentry);
++	retval = __ext4_unlink(dir, &dentry->d_name, d_inode(dentry), dentry);
+ #if IS_ENABLED(CONFIG_UNICODE)
+ 	/* VFS negative dentries are incompatible with Encoding and
+ 	 * Case-insensitiveness. Eventually we'll want avoid
+@@ -3301,8 +3307,6 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
+ 	if (IS_CASEFOLDED(dir))
+ 		d_invalidate(dentry);
+ #endif
+-	if (handle)
+-		ext4_journal_stop(handle);
+ 
+ out_trace:
+ 	trace_ext4_unlink_exit(dentry, retval);
+@@ -3792,6 +3796,9 @@ static int ext4_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
+ 		return -EXDEV;
+ 
+ 	retval = dquot_initialize(old.dir);
++	if (retval)
++		return retval;
++	retval = dquot_initialize(old.inode);
+ 	if (retval)
+ 		return retval;
+ 	retval = dquot_initialize(new.dir);
+diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c
+index 69a9cf9137a61..e5b47dda33175 100644
+--- a/fs/ext4/orphan.c
++++ b/fs/ext4/orphan.c
+@@ -412,7 +412,7 @@ void ext4_orphan_cleanup(struct super_block *sb, struct ext4_super_block *es)
+ 		/* don't clear list on RO mount w/ errors */
+ 		if (es->s_last_orphan && !(s_flags & SB_RDONLY)) {
+ 			ext4_msg(sb, KERN_INFO, "Errors on filesystem, "
+-				  "clearing orphan list.\n");
++				  "clearing orphan list.");
+ 			es->s_last_orphan = 0;
+ 		}
+ 		ext4_debug("Skipping orphan recovery on fs with errors.\n");
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index 46b87ffeb3045..b493233750ab2 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1110,6 +1110,16 @@ exit_free:
+ 	return err;
+ }
+ 
++static inline void ext4_set_block_group_nr(struct super_block *sb, char *data,
++					   ext4_group_t group)
++{
++	struct ext4_super_block *es = (struct ext4_super_block *) data;
++
++	es->s_block_group_nr = cpu_to_le16(group);
++	if (ext4_has_metadata_csum(sb))
++		es->s_checksum = ext4_superblock_csum(sb, es);
++}
++
+ /*
+  * Update the backup copies of the ext4 metadata.  These don't need to be part
+  * of the main resize transaction, because e2fsck will re-write them if there
+@@ -1158,7 +1168,8 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
+ 	while (group < sbi->s_groups_count) {
+ 		struct buffer_head *bh;
+ 		ext4_fsblk_t backup_block;
+-		struct ext4_super_block *es;
++		int has_super = ext4_bg_has_super(sb, group);
++		ext4_fsblk_t first_block = ext4_group_first_block_no(sb, group);
+ 
+ 		/* Out of journal space, and can't get more - abort - so sad */
+ 		err = ext4_resize_ensure_credits_batch(handle, 1);
+@@ -1168,8 +1179,7 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
+ 		if (meta_bg == 0)
+ 			backup_block = ((ext4_fsblk_t)group) * bpg + blk_off;
+ 		else
+-			backup_block = (ext4_group_first_block_no(sb, group) +
+-					ext4_bg_has_super(sb, group));
++			backup_block = first_block + has_super;
+ 
+ 		bh = sb_getblk(sb, backup_block);
+ 		if (unlikely(!bh)) {
+@@ -1187,10 +1197,8 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
+ 		memcpy(bh->b_data, data, size);
+ 		if (rest)
+ 			memset(bh->b_data + size, 0, rest);
+-		es = (struct ext4_super_block *) bh->b_data;
+-		es->s_block_group_nr = cpu_to_le16(group);
+-		if (ext4_has_metadata_csum(sb))
+-			es->s_checksum = ext4_superblock_csum(sb, es);
++		if (has_super && (backup_block == first_block))
++			ext4_set_block_group_nr(sb, bh->b_data, group);
+ 		set_buffer_uptodate(bh);
+ 		unlock_buffer(bh);
+ 		err = ext4_handle_dirty_metadata(handle, NULL, bh);
+@@ -1476,8 +1484,6 @@ static void ext4_update_super(struct super_block *sb,
+ 	 * active. */
+ 	ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) +
+ 				reserved_blocks);
+-	ext4_superblock_csum_set(sb);
+-	unlock_buffer(sbi->s_sbh);
+ 
+ 	/* Update the free space counts */
+ 	percpu_counter_add(&sbi->s_freeclusters_counter,
+@@ -1513,6 +1519,8 @@ static void ext4_update_super(struct super_block *sb,
+ 		ext4_calculate_overhead(sb);
+ 	es->s_overhead_clusters = cpu_to_le32(sbi->s_overhead);
+ 
++	ext4_superblock_csum_set(sb);
++	unlock_buffer(sbi->s_sbh);
+ 	if (test_opt(sb, DEBUG))
+ 		printk(KERN_DEBUG "EXT4-fs: added group %u:"
+ 		       "%llu blocks(%llu free %llu reserved)\n", flex_gd->count,
+@@ -1596,8 +1604,8 @@ exit_journal:
+ 		int meta_bg = ext4_has_feature_meta_bg(sb);
+ 		sector_t old_gdb = 0;
+ 
+-		update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
+-			       sizeof(struct ext4_super_block), 0);
++		update_backups(sb, ext4_group_first_block_no(sb, 0),
++			       (char *)es, sizeof(struct ext4_super_block), 0);
+ 		for (; gdb_num <= gdb_num_end; gdb_num++) {
+ 			struct buffer_head *gdb_bh;
+ 
+@@ -1808,7 +1816,7 @@ errout:
+ 		if (test_opt(sb, DEBUG))
+ 			printk(KERN_DEBUG "EXT4-fs: extended group to %llu "
+ 			       "blocks\n", ext4_blocks_count(es));
+-		update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr,
++		update_backups(sb, ext4_group_first_block_no(sb, 0),
+ 			       (char *)es, sizeof(struct ext4_super_block), 0);
+ 	}
+ 	return err;
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 091db733834ee..2eae6e038f38a 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1323,6 +1323,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
+ 		return NULL;
+ 
+ 	inode_set_iversion(&ei->vfs_inode, 1);
++	ei->i_flags = 0;
+ 	spin_lock_init(&ei->i_raw_lock);
+ 	INIT_LIST_HEAD(&ei->i_prealloc_list);
+ 	atomic_set(&ei->i_prealloc_active, 0);
+@@ -2260,7 +2261,7 @@ static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param)
+ 			return -EINVAL;
+ 		}
+ 
+-		error = fs_lookup_param(fc, param, 1, &path);
++		error = fs_lookup_param(fc, param, 1, LOOKUP_FOLLOW, &path);
+ 		if (error) {
+ 			ext4_msg(NULL, KERN_ERR, "error: could not find "
+ 				 "journal device path");
+@@ -5580,7 +5581,7 @@ static struct inode *ext4_get_journal_inode(struct super_block *sb,
+ 
+ 	ext4_debug("Journal inode found at %p: %lld bytes\n",
+ 		  journal_inode, journal_inode->i_size);
+-	if (!S_ISREG(journal_inode->i_mode)) {
++	if (!S_ISREG(journal_inode->i_mode) || IS_ENCRYPTED(journal_inode)) {
+ 		ext4_msg(sb, KERN_ERR, "invalid journal inode");
+ 		iput(journal_inode);
+ 		return NULL;
+@@ -6743,6 +6744,20 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
+ 	return err;
+ }
+ 
++static inline bool ext4_check_quota_inum(int type, unsigned long qf_inum)
++{
++	switch (type) {
++	case USRQUOTA:
++		return qf_inum == EXT4_USR_QUOTA_INO;
++	case GRPQUOTA:
++		return qf_inum == EXT4_GRP_QUOTA_INO;
++	case PRJQUOTA:
++		return qf_inum >= EXT4_GOOD_OLD_FIRST_INO;
++	default:
++		BUG();
++	}
++}
++
+ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
+ 			     unsigned int flags)
+ {
+@@ -6759,9 +6774,16 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
+ 	if (!qf_inums[type])
+ 		return -EPERM;
+ 
++	if (!ext4_check_quota_inum(type, qf_inums[type])) {
++		ext4_error(sb, "Bad quota inum: %lu, type: %d",
++				qf_inums[type], type);
++		return -EUCLEAN;
++	}
++
+ 	qf_inode = ext4_iget(sb, qf_inums[type], EXT4_IGET_SPECIAL);
+ 	if (IS_ERR(qf_inode)) {
+-		ext4_error(sb, "Bad quota inode # %lu", qf_inums[type]);
++		ext4_error(sb, "Bad quota inode: %lu, type: %d",
++				qf_inums[type], type);
+ 		return PTR_ERR(qf_inode);
+ 	}
+ 
+@@ -6800,8 +6822,9 @@ int ext4_enable_quotas(struct super_block *sb)
+ 			if (err) {
+ 				ext4_warning(sb,
+ 					"Failed to enable quota tracking "
+-					"(type=%d, err=%d). Please run "
+-					"e2fsck to fix.", type, err);
++					"(type=%d, err=%d, ino=%lu). "
++					"Please run e2fsck to fix.", type,
++					err, qf_inums[type]);
+ 				for (type--; type >= 0; type--) {
+ 					struct inode *inode;
+ 
+diff --git a/fs/ext4/verity.c b/fs/ext4/verity.c
+index 94442c690ca7d..47a132170f306 100644
+--- a/fs/ext4/verity.c
++++ b/fs/ext4/verity.c
+@@ -79,7 +79,7 @@ static int pagecache_write(struct inode *inode, const void *buf, size_t count,
+ 		size_t n = min_t(size_t, count,
+ 				 PAGE_SIZE - offset_in_page(pos));
+ 		struct page *page;
+-		void *fsdata;
++		void *fsdata = NULL;
+ 		int res;
+ 
+ 		res = aops->write_begin(NULL, mapping, pos, n, &page, &fsdata);
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 36d6ba7190b6d..866772a2e068f 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1281,7 +1281,7 @@ retry_ref:
+ 				ce = mb_cache_entry_get(ea_block_cache, hash,
+ 							bh->b_blocknr);
+ 				if (ce) {
+-					ce->e_reusable = 1;
++					set_bit(MBE_REUSABLE_B, &ce->e_flags);
+ 					mb_cache_entry_put(ea_block_cache, ce);
+ 				}
+ 			}
+@@ -1441,6 +1441,9 @@ static struct inode *ext4_xattr_inode_create(handle_t *handle,
+ 		if (!err)
+ 			err = ext4_inode_attach_jinode(ea_inode);
+ 		if (err) {
++			if (ext4_xattr_inode_dec_ref(handle, ea_inode))
++				ext4_warning_inode(ea_inode,
++					"cleanup dec ref error %d", err);
+ 			iput(ea_inode);
+ 			return ERR_PTR(err);
+ 		}
+@@ -2042,7 +2045,7 @@ inserted:
+ 				}
+ 				BHDR(new_bh)->h_refcount = cpu_to_le32(ref);
+ 				if (ref == EXT4_XATTR_REFCOUNT_MAX)
+-					ce->e_reusable = 0;
++					clear_bit(MBE_REUSABLE_B, &ce->e_flags);
+ 				ea_bdebug(new_bh, "reusing; refcount now=%d",
+ 					  ref);
+ 				ext4_xattr_block_csum_set(inode, new_bh);
+@@ -2070,19 +2073,11 @@ inserted:
+ 
+ 			goal = ext4_group_first_block_no(sb,
+ 						EXT4_I(inode)->i_block_group);
+-
+-			/* non-extent files can't have physical blocks past 2^32 */
+-			if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
+-				goal = goal & EXT4_MAX_BLOCK_FILE_PHYS;
+-
+ 			block = ext4_new_meta_blocks(handle, inode, goal, 0,
+ 						     NULL, &error);
+ 			if (error)
+ 				goto cleanup;
+ 
+-			if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
+-				BUG_ON(block > EXT4_MAX_BLOCK_FILE_PHYS);
+-
+ 			ea_idebug(inode, "creating block %llu",
+ 				  (unsigned long long)block);
+ 
+@@ -2555,7 +2550,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
+ 
+ 	is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS);
+ 	bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS);
+-	buffer = kmalloc(value_size, GFP_NOFS);
++	buffer = kvmalloc(value_size, GFP_NOFS);
+ 	b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS);
+ 	if (!is || !bs || !buffer || !b_entry_name) {
+ 		error = -ENOMEM;
+@@ -2607,7 +2602,7 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode,
+ 	error = 0;
+ out:
+ 	kfree(b_entry_name);
+-	kfree(buffer);
++	kvfree(buffer);
+ 	if (is)
+ 		brelse(is->iloc.bh);
+ 	if (bs)
+diff --git a/fs/fs_parser.c b/fs/fs_parser.c
+index ed40ce5742fda..edb3712dcfa58 100644
+--- a/fs/fs_parser.c
++++ b/fs/fs_parser.c
+@@ -138,15 +138,16 @@ EXPORT_SYMBOL(__fs_parse);
+  * @fc: The filesystem context to log errors through.
+  * @param: The parameter.
+  * @want_bdev: T if want a blockdev
++ * @flags: Pathwalk flags passed to filename_lookup()
+  * @_path: The result of the lookup
+  */
+ int fs_lookup_param(struct fs_context *fc,
+ 		    struct fs_parameter *param,
+ 		    bool want_bdev,
++		    unsigned int flags,
+ 		    struct path *_path)
+ {
+ 	struct filename *f;
+-	unsigned int flags = 0;
+ 	bool put_f;
+ 	int ret;
+ 
+diff --git a/fs/mbcache.c b/fs/mbcache.c
+index e272ad738faff..2a4b8b549e934 100644
+--- a/fs/mbcache.c
++++ b/fs/mbcache.c
+@@ -100,8 +100,9 @@ int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
+ 	atomic_set(&entry->e_refcnt, 2);
+ 	entry->e_key = key;
+ 	entry->e_value = value;
+-	entry->e_reusable = reusable;
+-	entry->e_referenced = 0;
++	entry->e_flags = 0;
++	if (reusable)
++		set_bit(MBE_REUSABLE_B, &entry->e_flags);
+ 	head = mb_cache_entry_head(cache, key);
+ 	hlist_bl_lock(head);
+ 	hlist_bl_for_each_entry(dup, dup_node, head, e_hash_list) {
+@@ -165,7 +166,8 @@ static struct mb_cache_entry *__entry_find(struct mb_cache *cache,
+ 	while (node) {
+ 		entry = hlist_bl_entry(node, struct mb_cache_entry,
+ 				       e_hash_list);
+-		if (entry->e_key == key && entry->e_reusable &&
++		if (entry->e_key == key &&
++		    test_bit(MBE_REUSABLE_B, &entry->e_flags) &&
+ 		    atomic_inc_not_zero(&entry->e_refcnt))
+ 			goto out;
+ 		node = node->next;
+@@ -284,7 +286,7 @@ EXPORT_SYMBOL(mb_cache_entry_delete_or_get);
+ void mb_cache_entry_touch(struct mb_cache *cache,
+ 			  struct mb_cache_entry *entry)
+ {
+-	entry->e_referenced = 1;
++	set_bit(MBE_REFERENCED_B, &entry->e_flags);
+ }
+ EXPORT_SYMBOL(mb_cache_entry_touch);
+ 
+@@ -309,9 +311,9 @@ static unsigned long mb_cache_shrink(struct mb_cache *cache,
+ 		entry = list_first_entry(&cache->c_list,
+ 					 struct mb_cache_entry, e_list);
+ 		/* Drop initial hash reference if there is no user */
+-		if (entry->e_referenced ||
++		if (test_bit(MBE_REFERENCED_B, &entry->e_flags) ||
+ 		    atomic_cmpxchg(&entry->e_refcnt, 1, 0) != 1) {
+-			entry->e_referenced = 0;
++			clear_bit(MBE_REFERENCED_B, &entry->e_flags);
+ 			list_move_tail(&entry->e_list, &cache->c_list);
+ 			continue;
+ 		}
+diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
+index 0427b44bfee54..f27faf5db5544 100644
+--- a/fs/quota/dquot.c
++++ b/fs/quota/dquot.c
+@@ -2324,6 +2324,8 @@ static int vfs_setup_quota_inode(struct inode *inode, int type)
+ 	struct super_block *sb = inode->i_sb;
+ 	struct quota_info *dqopt = sb_dqopt(sb);
+ 
++	if (is_bad_inode(inode))
++		return -EUCLEAN;
+ 	if (!S_ISREG(inode->i_mode))
+ 		return -EACCES;
+ 	if (IS_RDONLY(inode))
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
+index 184b957e28ada..1eac74cacc963 100644
+--- a/include/linux/bpf_verifier.h
++++ b/include/linux/bpf_verifier.h
+@@ -634,7 +634,7 @@ static inline u32 type_flag(u32 type)
+ }
+ 
+ /* only use after check_attach_btf_id() */
+-static inline enum bpf_prog_type resolve_prog_type(struct bpf_prog *prog)
++static inline enum bpf_prog_type resolve_prog_type(const struct bpf_prog *prog)
+ {
+ 	return prog->type == BPF_PROG_TYPE_EXT ?
+ 		prog->aux->dst_prog->type : prog->type;
+diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
+index 34aab4dd336c8..4dc7cda4fd469 100644
+--- a/include/linux/devfreq.h
++++ b/include/linux/devfreq.h
+@@ -152,8 +152,8 @@ struct devfreq_stats {
+  * @max_state:		count of entry present in the frequency table.
+  * @previous_freq:	previously configured frequency value.
+  * @last_status:	devfreq user device info, performance statistics
+- * @data:	Private data of the governor. The devfreq framework does not
+- *		touch this.
++ * @data:	devfreq driver pass to governors, governor should not change it.
++ * @governor_data:	private data for governors, devfreq core doesn't touch it.
+  * @user_min_freq_req:	PM QoS minimum frequency request from user (via sysfs)
+  * @user_max_freq_req:	PM QoS maximum frequency request from user (via sysfs)
+  * @scaling_min_freq:	Limit minimum frequency requested by OPP interface
+@@ -193,7 +193,8 @@ struct devfreq {
+ 	unsigned long previous_freq;
+ 	struct devfreq_dev_status last_status;
+ 
+-	void *data; /* private data for governors */
++	void *data;
++	void *governor_data;
+ 
+ 	struct dev_pm_qos_request user_min_freq_req;
+ 	struct dev_pm_qos_request user_max_freq_req;
+diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h
+index f103c91139d4a..01542c4b87a2b 100644
+--- a/include/linux/fs_parser.h
++++ b/include/linux/fs_parser.h
+@@ -76,6 +76,7 @@ static inline int fs_parse(struct fs_context *fc,
+ extern int fs_lookup_param(struct fs_context *fc,
+ 			   struct fs_parameter *param,
+ 			   bool want_bdev,
++			   unsigned int flags,
+ 			   struct path *_path);
+ 
+ extern int lookup_constant(const struct constant_table tbl[], const char *name, int not_found);
+diff --git a/include/linux/mbcache.h b/include/linux/mbcache.h
+index 2da63fd7b98f4..97e64184767de 100644
+--- a/include/linux/mbcache.h
++++ b/include/linux/mbcache.h
+@@ -10,6 +10,12 @@
+ 
+ struct mb_cache;
+ 
++/* Cache entry flags */
++enum {
++	MBE_REFERENCED_B = 0,
++	MBE_REUSABLE_B
++};
++
+ struct mb_cache_entry {
+ 	/* List of entries in cache - protected by cache->c_list_lock */
+ 	struct list_head	e_list;
+@@ -26,8 +32,7 @@ struct mb_cache_entry {
+ 	atomic_t		e_refcnt;
+ 	/* Key in hash - stable during lifetime of the entry */
+ 	u32			e_key;
+-	u32			e_referenced:1;
+-	u32			e_reusable:1;
++	unsigned long		e_flags;
+ 	/* User provided value - stable during lifetime of the entry */
+ 	u64			e_value;
+ };
+diff --git a/include/net/mptcp.h b/include/net/mptcp.h
+index 412479ebf5ad3..3c5c68618fcc5 100644
+--- a/include/net/mptcp.h
++++ b/include/net/mptcp.h
+@@ -97,8 +97,6 @@ struct mptcp_out_options {
+ };
+ 
+ #ifdef CONFIG_MPTCP
+-extern struct request_sock_ops mptcp_subflow_request_sock_ops;
+-
+ void mptcp_init(void);
+ 
+ static inline bool sk_is_mptcp(const struct sock *sk)
+@@ -188,6 +186,9 @@ void mptcp_seq_show(struct seq_file *seq);
+ int mptcp_subflow_init_cookie_req(struct request_sock *req,
+ 				  const struct sock *sk_listener,
+ 				  struct sk_buff *skb);
++struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
++					       struct sock *sk_listener,
++					       bool attach_listener);
+ 
+ __be32 mptcp_get_reset_option(const struct sk_buff *skb);
+ 
+@@ -274,6 +275,13 @@ static inline int mptcp_subflow_init_cookie_req(struct request_sock *req,
+ 	return 0; /* TCP fallback */
+ }
+ 
++static inline struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
++							     struct sock *sk_listener,
++							     bool attach_listener)
++{
++	return NULL;
++}
++
+ static inline __be32 mptcp_reset_option(const struct sk_buff *skb)  { return htonl(0u); }
+ #endif /* CONFIG_MPTCP */
+ 
+diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
+index 229e8fae66a34..ced95fec3367d 100644
+--- a/include/trace/events/ext4.h
++++ b/include/trace/events/ext4.h
+@@ -104,6 +104,7 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_RESIZE);
+ TRACE_DEFINE_ENUM(EXT4_FC_REASON_RENAME_DIR);
+ TRACE_DEFINE_ENUM(EXT4_FC_REASON_FALLOC_RANGE);
+ TRACE_DEFINE_ENUM(EXT4_FC_REASON_INODE_JOURNAL_DATA);
++TRACE_DEFINE_ENUM(EXT4_FC_REASON_ENCRYPTED_FILENAME);
+ TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
+ 
+ #define show_fc_reason(reason)						\
+@@ -116,7 +117,8 @@ TRACE_DEFINE_ENUM(EXT4_FC_REASON_MAX);
+ 		{ EXT4_FC_REASON_RESIZE,	"RESIZE"},		\
+ 		{ EXT4_FC_REASON_RENAME_DIR,	"RENAME_DIR"},		\
+ 		{ EXT4_FC_REASON_FALLOC_RANGE,	"FALLOC_RANGE"},	\
+-		{ EXT4_FC_REASON_INODE_JOURNAL_DATA,	"INODE_JOURNAL_DATA"})
++		{ EXT4_FC_REASON_INODE_JOURNAL_DATA,	"INODE_JOURNAL_DATA"}, \
++		{ EXT4_FC_REASON_ENCRYPTED_FILENAME,	"ENCRYPTED_FILENAME"})
+ 
+ TRACE_EVENT(ext4_other_inode_update_time,
+ 	TP_PROTO(struct inode *inode, ino_t orig_ino),
+@@ -2764,7 +2766,7 @@ TRACE_EVENT(ext4_fc_stats,
+ 	),
+ 
+ 	TP_printk("dev %d,%d fc ineligible reasons:\n"
+-		  "%s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u "
++		  "%s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u, %s:%u"
+ 		  "num_commits:%lu, ineligible: %lu, numblks: %lu",
+ 		  MAJOR(__entry->dev), MINOR(__entry->dev),
+ 		  FC_REASON_NAME_STAT(EXT4_FC_REASON_XATTR),
+@@ -2776,6 +2778,7 @@ TRACE_EVENT(ext4_fc_stats,
+ 		  FC_REASON_NAME_STAT(EXT4_FC_REASON_RENAME_DIR),
+ 		  FC_REASON_NAME_STAT(EXT4_FC_REASON_FALLOC_RANGE),
+ 		  FC_REASON_NAME_STAT(EXT4_FC_REASON_INODE_JOURNAL_DATA),
++		  FC_REASON_NAME_STAT(EXT4_FC_REASON_ENCRYPTED_FILENAME),
+ 		  __entry->fc_commits, __entry->fc_ineligible_commits,
+ 		  __entry->fc_numblks)
+ );
+diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h
+index 99f783c384bb4..8f5ee380d3093 100644
+--- a/include/trace/events/jbd2.h
++++ b/include/trace/events/jbd2.h
+@@ -40,7 +40,7 @@ DECLARE_EVENT_CLASS(jbd2_commit,
+ 	TP_STRUCT__entry(
+ 		__field(	dev_t,	dev			)
+ 		__field(	char,	sync_commit		  )
+-		__field(	int,	transaction		  )
++		__field(	tid_t,	transaction		  )
+ 	),
+ 
+ 	TP_fast_assign(
+@@ -49,7 +49,7 @@ DECLARE_EVENT_CLASS(jbd2_commit,
+ 		__entry->transaction	= commit_transaction->t_tid;
+ 	),
+ 
+-	TP_printk("dev %d,%d transaction %d sync %d",
++	TP_printk("dev %d,%d transaction %u sync %d",
+ 		  MAJOR(__entry->dev), MINOR(__entry->dev),
+ 		  __entry->transaction, __entry->sync_commit)
+ );
+@@ -97,8 +97,8 @@ TRACE_EVENT(jbd2_end_commit,
+ 	TP_STRUCT__entry(
+ 		__field(	dev_t,	dev			)
+ 		__field(	char,	sync_commit		  )
+-		__field(	int,	transaction		  )
+-		__field(	int,	head		  	  )
++		__field(	tid_t,	transaction		  )
++		__field(	tid_t,	head		  	  )
+ 	),
+ 
+ 	TP_fast_assign(
+@@ -108,7 +108,7 @@ TRACE_EVENT(jbd2_end_commit,
+ 		__entry->head		= journal->j_tail_sequence;
+ 	),
+ 
+-	TP_printk("dev %d,%d transaction %d sync %d head %d",
++	TP_printk("dev %d,%d transaction %u sync %d head %u",
+ 		  MAJOR(__entry->dev), MINOR(__entry->dev),
+ 		  __entry->transaction, __entry->sync_commit, __entry->head)
+ );
+@@ -134,14 +134,14 @@ TRACE_EVENT(jbd2_submit_inode_data,
+ );
+ 
+ DECLARE_EVENT_CLASS(jbd2_handle_start_class,
+-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ 		 unsigned int line_no, int requested_blocks),
+ 
+ 	TP_ARGS(dev, tid, type, line_no, requested_blocks),
+ 
+ 	TP_STRUCT__entry(
+ 		__field(		dev_t,	dev		)
+-		__field(	unsigned long,	tid		)
++		__field(		tid_t,	tid		)
+ 		__field(	 unsigned int,	type		)
+ 		__field(	 unsigned int,	line_no		)
+ 		__field(		  int,	requested_blocks)
+@@ -155,28 +155,28 @@ DECLARE_EVENT_CLASS(jbd2_handle_start_class,
+ 		__entry->requested_blocks = requested_blocks;
+ 	),
+ 
+-	TP_printk("dev %d,%d tid %lu type %u line_no %u "
++	TP_printk("dev %d,%d tid %u type %u line_no %u "
+ 		  "requested_blocks %d",
+ 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+ 		  __entry->type, __entry->line_no, __entry->requested_blocks)
+ );
+ 
+ DEFINE_EVENT(jbd2_handle_start_class, jbd2_handle_start,
+-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ 		 unsigned int line_no, int requested_blocks),
+ 
+ 	TP_ARGS(dev, tid, type, line_no, requested_blocks)
+ );
+ 
+ DEFINE_EVENT(jbd2_handle_start_class, jbd2_handle_restart,
+-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ 		 unsigned int line_no, int requested_blocks),
+ 
+ 	TP_ARGS(dev, tid, type, line_no, requested_blocks)
+ );
+ 
+ TRACE_EVENT(jbd2_handle_extend,
+-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ 		 unsigned int line_no, int buffer_credits,
+ 		 int requested_blocks),
+ 
+@@ -184,7 +184,7 @@ TRACE_EVENT(jbd2_handle_extend,
+ 
+ 	TP_STRUCT__entry(
+ 		__field(		dev_t,	dev		)
+-		__field(	unsigned long,	tid		)
++		__field(		tid_t,	tid		)
+ 		__field(	 unsigned int,	type		)
+ 		__field(	 unsigned int,	line_no		)
+ 		__field(		  int,	buffer_credits  )
+@@ -200,7 +200,7 @@ TRACE_EVENT(jbd2_handle_extend,
+ 		__entry->requested_blocks = requested_blocks;
+ 	),
+ 
+-	TP_printk("dev %d,%d tid %lu type %u line_no %u "
++	TP_printk("dev %d,%d tid %u type %u line_no %u "
+ 		  "buffer_credits %d requested_blocks %d",
+ 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+ 		  __entry->type, __entry->line_no, __entry->buffer_credits,
+@@ -208,7 +208,7 @@ TRACE_EVENT(jbd2_handle_extend,
+ );
+ 
+ TRACE_EVENT(jbd2_handle_stats,
+-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
++	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
+ 		 unsigned int line_no, int interval, int sync,
+ 		 int requested_blocks, int dirtied_blocks),
+ 
+@@ -217,7 +217,7 @@ TRACE_EVENT(jbd2_handle_stats,
+ 
+ 	TP_STRUCT__entry(
+ 		__field(		dev_t,	dev		)
+-		__field(	unsigned long,	tid		)
++		__field(		tid_t,	tid		)
+ 		__field(	 unsigned int,	type		)
+ 		__field(	 unsigned int,	line_no		)
+ 		__field(		  int,	interval	)
+@@ -237,7 +237,7 @@ TRACE_EVENT(jbd2_handle_stats,
+ 		__entry->dirtied_blocks	  = dirtied_blocks;
+ 	),
+ 
+-	TP_printk("dev %d,%d tid %lu type %u line_no %u interval %d "
++	TP_printk("dev %d,%d tid %u type %u line_no %u interval %d "
+ 		  "sync %d requested_blocks %d dirtied_blocks %d",
+ 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+ 		  __entry->type, __entry->line_no, __entry->interval,
+@@ -246,14 +246,14 @@ TRACE_EVENT(jbd2_handle_stats,
+ );
+ 
+ TRACE_EVENT(jbd2_run_stats,
+-	TP_PROTO(dev_t dev, unsigned long tid,
++	TP_PROTO(dev_t dev, tid_t tid,
+ 		 struct transaction_run_stats_s *stats),
+ 
+ 	TP_ARGS(dev, tid, stats),
+ 
+ 	TP_STRUCT__entry(
+ 		__field(		dev_t,	dev		)
+-		__field(	unsigned long,	tid		)
++		__field(		tid_t,	tid		)
+ 		__field(	unsigned long,	wait		)
+ 		__field(	unsigned long,	request_delay	)
+ 		__field(	unsigned long,	running		)
+@@ -279,7 +279,7 @@ TRACE_EVENT(jbd2_run_stats,
+ 		__entry->blocks_logged	= stats->rs_blocks_logged;
+ 	),
+ 
+-	TP_printk("dev %d,%d tid %lu wait %u request_delay %u running %u "
++	TP_printk("dev %d,%d tid %u wait %u request_delay %u running %u "
+ 		  "locked %u flushing %u logging %u handle_count %u "
+ 		  "blocks %u blocks_logged %u",
+ 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+@@ -294,14 +294,14 @@ TRACE_EVENT(jbd2_run_stats,
+ );
+ 
+ TRACE_EVENT(jbd2_checkpoint_stats,
+-	TP_PROTO(dev_t dev, unsigned long tid,
++	TP_PROTO(dev_t dev, tid_t tid,
+ 		 struct transaction_chp_stats_s *stats),
+ 
+ 	TP_ARGS(dev, tid, stats),
+ 
+ 	TP_STRUCT__entry(
+ 		__field(		dev_t,	dev		)
+-		__field(	unsigned long,	tid		)
++		__field(		tid_t,	tid		)
+ 		__field(	unsigned long,	chp_time	)
+ 		__field(		__u32,	forced_to_close	)
+ 		__field(		__u32,	written		)
+@@ -317,7 +317,7 @@ TRACE_EVENT(jbd2_checkpoint_stats,
+ 		__entry->dropped	= stats->cs_dropped;
+ 	),
+ 
+-	TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u "
++	TP_printk("dev %d,%d tid %u chp_time %u forced_to_close %u "
+ 		  "written %u dropped %u",
+ 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
+ 		  jiffies_to_msecs(__entry->chp_time),
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index c4600a5781de1..7d315c94b80af 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -2088,6 +2088,7 @@ static unsigned int __bpf_prog_ret0_warn(const void *ctx,
+ bool bpf_prog_map_compatible(struct bpf_map *map,
+ 			     const struct bpf_prog *fp)
+ {
++	enum bpf_prog_type prog_type = resolve_prog_type(fp);
+ 	bool ret;
+ 
+ 	if (fp->kprobe_override)
+@@ -2098,12 +2099,12 @@ bool bpf_prog_map_compatible(struct bpf_map *map,
+ 		/* There's no owner yet where we could check for
+ 		 * compatibility.
+ 		 */
+-		map->owner.type  = fp->type;
++		map->owner.type  = prog_type;
+ 		map->owner.jited = fp->jited;
+ 		map->owner.xdp_has_frags = fp->aux->xdp_has_frags;
+ 		ret = true;
+ 	} else {
+-		ret = map->owner.type  == fp->type &&
++		ret = map->owner.type  == prog_type &&
+ 		      map->owner.jited == fp->jited &&
+ 		      map->owner.xdp_has_frags == fp->aux->xdp_has_frags;
+ 	}
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index a636fab5e381a..6914f328f7d7d 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -12176,12 +12176,12 @@ SYSCALL_DEFINE5(perf_event_open,
+ 	if (flags & ~PERF_FLAG_ALL)
+ 		return -EINVAL;
+ 
+-	/* Do we allow access to perf_event_open(2) ? */
+-	err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
++	err = perf_copy_attr(attr_uptr, &attr);
+ 	if (err)
+ 		return err;
+ 
+-	err = perf_copy_attr(attr_uptr, &attr);
++	/* Do we allow access to perf_event_open(2) ? */
++	err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
+ 	if (err)
+ 		return err;
+ 
+diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
+index 1052126bdca22..0977defe98205 100644
+--- a/kernel/trace/Kconfig
++++ b/kernel/trace/Kconfig
+@@ -369,6 +369,7 @@ config SCHED_TRACER
+ config HWLAT_TRACER
+ 	bool "Tracer to detect hardware latencies (like SMIs)"
+ 	select GENERIC_TRACER
++	select TRACER_MAX_TRACE
+ 	help
+ 	 This tracer, when enabled will create one or more kernel threads,
+ 	 depending on what the cpumask file is set to, which each thread
+@@ -404,6 +405,7 @@ config HWLAT_TRACER
+ config OSNOISE_TRACER
+ 	bool "OS Noise tracer"
+ 	select GENERIC_TRACER
++	select TRACER_MAX_TRACE
+ 	help
+ 	  In the context of high-performance computing (HPC), the Operating
+ 	  System Noise (osnoise) refers to the interference experienced by an
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index 7132e21e90d6d..0bfd805ec63fa 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1421,6 +1421,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr)
+ 	return false;
+ }
+ EXPORT_SYMBOL_GPL(tracing_snapshot_cond_disable);
++#define free_snapshot(tr)	do { } while (0)
+ #endif /* CONFIG_TRACER_SNAPSHOT */
+ 
+ void tracer_tracing_off(struct trace_array *tr)
+@@ -1692,6 +1693,8 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)
+ }
+ 
+ unsigned long __read_mostly	tracing_thresh;
++
++#ifdef CONFIG_TRACER_MAX_TRACE
+ static const struct file_operations tracing_max_lat_fops;
+ 
+ #ifdef LATENCY_FS_NOTIFY
+@@ -1748,18 +1751,14 @@ void latency_fsnotify(struct trace_array *tr)
+ 	irq_work_queue(&tr->fsnotify_irqwork);
+ }
+ 
+-#elif defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)	\
+-	|| defined(CONFIG_OSNOISE_TRACER)
++#else /* !LATENCY_FS_NOTIFY */
+ 
+ #define trace_create_maxlat_file(tr, d_tracer)				\
+ 	trace_create_file("tracing_max_latency", TRACE_MODE_WRITE,	\
+ 			  d_tracer, &tr->max_latency, &tracing_max_lat_fops)
+ 
+-#else
+-#define trace_create_maxlat_file(tr, d_tracer)	 do { } while (0)
+ #endif
+ 
+-#ifdef CONFIG_TRACER_MAX_TRACE
+ /*
+  * Copy the new maximum trace into the separate maximum-trace
+  * structure. (this way the maximum trace is permanently saved,
+@@ -1834,14 +1833,15 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
+ 		ring_buffer_record_off(tr->max_buffer.buffer);
+ 
+ #ifdef CONFIG_TRACER_SNAPSHOT
+-	if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data))
+-		goto out_unlock;
++	if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data)) {
++		arch_spin_unlock(&tr->max_lock);
++		return;
++	}
+ #endif
+ 	swap(tr->array_buffer.buffer, tr->max_buffer.buffer);
+ 
+ 	__update_max_tr(tr, tsk, cpu);
+ 
+- out_unlock:
+ 	arch_spin_unlock(&tr->max_lock);
+ }
+ 
+@@ -1888,6 +1888,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
+ 	__update_max_tr(tr, tsk, cpu);
+ 	arch_spin_unlock(&tr->max_lock);
+ }
++
+ #endif /* CONFIG_TRACER_MAX_TRACE */
+ 
+ static int wait_on_pipe(struct trace_iterator *iter, int full)
+@@ -6563,7 +6564,7 @@ out:
+ 	return ret;
+ }
+ 
+-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
++#ifdef CONFIG_TRACER_MAX_TRACE
+ 
+ static ssize_t
+ tracing_max_lat_read(struct file *filp, char __user *ubuf,
+@@ -6787,7 +6788,20 @@ waitagain:
+ 
+ 		ret = print_trace_line(iter);
+ 		if (ret == TRACE_TYPE_PARTIAL_LINE) {
+-			/* don't print partial lines */
++			/*
++			 * If one print_trace_line() fills entire trace_seq in one shot,
++			 * trace_seq_to_user() will returns -EBUSY because save_len == 0,
++			 * In this case, we need to consume it, otherwise, loop will peek
++			 * this event next time, resulting in an infinite loop.
++			 */
++			if (save_len == 0) {
++				iter->seq.full = 0;
++				trace_seq_puts(&iter->seq, "[LINE TOO BIG]\n");
++				trace_consume(iter);
++				break;
++			}
++
++			/* In other cases, don't print partial lines */
+ 			iter->seq.seq.len = save_len;
+ 			break;
+ 		}
+@@ -7578,7 +7592,7 @@ static const struct file_operations tracing_thresh_fops = {
+ 	.llseek		= generic_file_llseek,
+ };
+ 
+-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
++#ifdef CONFIG_TRACER_MAX_TRACE
+ static const struct file_operations tracing_max_lat_fops = {
+ 	.open		= tracing_open_generic,
+ 	.read		= tracing_max_lat_read,
+@@ -9592,7 +9606,9 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
+ 
+ 	create_trace_options_dir(tr);
+ 
++#ifdef CONFIG_TRACER_MAX_TRACE
+ 	trace_create_maxlat_file(tr, d_tracer);
++#endif
+ 
+ 	if (ftrace_create_function_files(tr, d_tracer))
+ 		MEM_FAIL(1, "Could not allocate function filter files");
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index 900e75d96c846..e5558d41d36ca 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -308,8 +308,7 @@ struct trace_array {
+ 	struct array_buffer	max_buffer;
+ 	bool			allocated_snapshot;
+ #endif
+-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
+-	|| defined(CONFIG_OSNOISE_TRACER)
++#ifdef CONFIG_TRACER_MAX_TRACE
+ 	unsigned long		max_latency;
+ #ifdef CONFIG_FSNOTIFY
+ 	struct dentry		*d_max_latency;
+@@ -687,12 +686,11 @@ void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
+ 		   void *cond_data);
+ void update_max_tr_single(struct trace_array *tr,
+ 			  struct task_struct *tsk, int cpu);
+-#endif /* CONFIG_TRACER_MAX_TRACE */
+ 
+-#if (defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
+-	|| defined(CONFIG_OSNOISE_TRACER)) && defined(CONFIG_FSNOTIFY)
++#ifdef CONFIG_FSNOTIFY
+ #define LATENCY_FS_NOTIFY
+ #endif
++#endif /* CONFIG_TRACER_MAX_TRACE */
+ 
+ #ifdef LATENCY_FS_NOTIFY
+ void latency_fsnotify(struct trace_array *tr);
+@@ -1968,17 +1966,30 @@ static __always_inline void trace_iterator_reset(struct trace_iterator *iter)
+ }
+ 
+ /* Check the name is good for event/group/fields */
+-static inline bool is_good_name(const char *name)
++static inline bool __is_good_name(const char *name, bool hash_ok)
+ {
+-	if (!isalpha(*name) && *name != '_')
++	if (!isalpha(*name) && *name != '_' && (!hash_ok || *name != '-'))
+ 		return false;
+ 	while (*++name != '\0') {
+-		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
++		if (!isalpha(*name) && !isdigit(*name) && *name != '_' &&
++		    (!hash_ok || *name != '-'))
+ 			return false;
+ 	}
+ 	return true;
+ }
+ 
++/* Check the name is good for event/group/fields */
++static inline bool is_good_name(const char *name)
++{
++	return __is_good_name(name, false);
++}
++
++/* Check the name is good for system */
++static inline bool is_good_system_name(const char *name)
++{
++	return __is_good_name(name, true);
++}
++
+ /* Convert certain expected symbols into '_' when generating event names */
+ static inline void sanitize_event_name(char *name)
+ {
+diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
+index 3b055aaee89a9..cae987f5a6524 100644
+--- a/kernel/trace/trace_eprobe.c
++++ b/kernel/trace/trace_eprobe.c
+@@ -560,6 +560,9 @@ static void eprobe_trigger_func(struct event_trigger_data *data,
+ {
+ 	struct eprobe_data *edata = data->private_data;
+ 
++	if (unlikely(!rec))
++		return;
++
+ 	if (unlikely(!rec))
+ 		return;
+ 
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index d8406f6f5d399..3fb4da6ee8ef0 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -588,7 +588,7 @@ struct action_data {
+ 	 * event param, and is passed to the synthetic event
+ 	 * invocation.
+ 	 */
+-	unsigned int		var_ref_idx[TRACING_MAP_VARS_MAX];
++	unsigned int		var_ref_idx[SYNTH_FIELDS_MAX];
+ 	struct synth_event	*synth_event;
+ 	bool			use_trace_keyword;
+ 	char			*synth_event_name;
+@@ -2150,7 +2150,9 @@ static struct hist_field *create_var_ref(struct hist_trigger_data *hist_data,
+ 			return ref_field;
+ 		}
+ 	}
+-
++	/* Sanity check to avoid out-of-bound write on 'hist_data->var_refs' */
++	if (hist_data->n_var_refs >= TRACING_MAP_VARS_MAX)
++		return NULL;
+ 	ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL);
+ 	if (ref_field) {
+ 		if (init_var_ref(ref_field, var_field, system, event_name)) {
+@@ -3562,6 +3564,7 @@ static int parse_action_params(struct trace_array *tr, char *params,
+ 	while (params) {
+ 		if (data->n_params >= SYNTH_FIELDS_MAX) {
+ 			hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0);
++			ret = -EINVAL;
+ 			goto out;
+ 		}
+ 
+@@ -3898,6 +3901,10 @@ static int trace_action_create(struct hist_trigger_data *hist_data,
+ 
+ 	lockdep_assert_held(&event_mutex);
+ 
++	/* Sanity check to avoid out-of-bound write on 'data->var_ref_idx' */
++	if (data->n_params > SYNTH_FIELDS_MAX)
++		return -EINVAL;
++
+ 	if (data->use_trace_keyword)
+ 		synth_event_name = data->synth_event_name;
+ 	else
+diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
+index 29fbfb27c2b2c..b16673926a415 100644
+--- a/kernel/trace/trace_events_synth.c
++++ b/kernel/trace/trace_events_synth.c
+@@ -1282,12 +1282,12 @@ static int __create_synth_event(const char *name, const char *raw_fields)
+ 				goto err_free_arg;
+ 			}
+ 
+-			fields[n_fields++] = field;
+ 			if (n_fields == SYNTH_FIELDS_MAX) {
+ 				synth_err(SYNTH_ERR_TOO_MANY_FIELDS, 0);
+ 				ret = -EINVAL;
+ 				goto err_free_arg;
+ 			}
++			fields[n_fields++] = field;
+ 
+ 			n_fields_this_loop++;
+ 		}
+diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
+index 36dff277de464..bb2f95d7175c2 100644
+--- a/kernel/trace/trace_probe.c
++++ b/kernel/trace/trace_probe.c
+@@ -246,7 +246,7 @@ int traceprobe_parse_event_name(const char **pevent, const char **pgroup,
+ 			return -EINVAL;
+ 		}
+ 		strlcpy(buf, event, slash - event + 1);
+-		if (!is_good_name(buf)) {
++		if (!is_good_system_name(buf)) {
+ 			trace_probe_log_err(offset, BAD_GROUP_NAME);
+ 			return -EINVAL;
+ 		}
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 88f34cdeef023..dd1d02c9e0d08 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -2080,6 +2080,7 @@ config TEST_MIN_HEAP
+ config TEST_SORT
+ 	tristate "Array-based sort test" if !KUNIT_ALL_TESTS
+ 	depends on KUNIT
++	select STACKTRACE if ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
+ 	default KUNIT_ALL_TESTS
+ 	help
+ 	  This option enables the self-test function of 'sort()' at boot,
+diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
+index 942d2dfa11151..26fb97d1d4d9a 100644
+--- a/net/ipv4/syncookies.c
++++ b/net/ipv4/syncookies.c
+@@ -288,12 +288,11 @@ struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops,
+ 	struct tcp_request_sock *treq;
+ 	struct request_sock *req;
+ 
+-#ifdef CONFIG_MPTCP
+ 	if (sk_is_mptcp(sk))
+-		ops = &mptcp_subflow_request_sock_ops;
+-#endif
++		req = mptcp_subflow_reqsk_alloc(ops, sk, false);
++	else
++		req = inet_reqsk_alloc(ops, sk, false);
+ 
+-	req = inet_reqsk_alloc(ops, sk, false);
+ 	if (!req)
+ 		return NULL;
+ 
+diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
+index 9e82250cbb703..0430415357ba3 100644
+--- a/net/mptcp/pm_userspace.c
++++ b/net/mptcp/pm_userspace.c
+@@ -156,6 +156,7 @@ int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info)
+ 
+ 	if (addr_val.addr.id == 0 || !(addr_val.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) {
+ 		GENL_SET_ERR_MSG(info, "invalid addr id or flags");
++		err = -EINVAL;
+ 		goto announce_err;
+ 	}
+ 
+@@ -282,6 +283,7 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info)
+ 
+ 	if (addr_l.id == 0) {
+ 		NL_SET_ERR_MSG_ATTR(info->extack, laddr, "missing local addr id");
++		err = -EINVAL;
+ 		goto create_err;
+ 	}
+ 
+@@ -395,11 +397,13 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info)
+ 
+ 	if (addr_l.family != addr_r.family) {
+ 		GENL_SET_ERR_MSG(info, "address families do not match");
++		err = -EINVAL;
+ 		goto destroy_err;
+ 	}
+ 
+ 	if (!addr_l.port || !addr_r.port) {
+ 		GENL_SET_ERR_MSG(info, "missing local or remote port");
++		err = -EINVAL;
+ 		goto destroy_err;
+ 	}
+ 
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 2159b5f9988f8..613f515fedf0a 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -45,7 +45,6 @@ static void subflow_req_destructor(struct request_sock *req)
+ 		sock_put((struct sock *)subflow_req->msk);
+ 
+ 	mptcp_token_destroy_request(req);
+-	tcp_request_sock_ops.destructor(req);
+ }
+ 
+ static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
+@@ -529,7 +528,7 @@ static int subflow_v6_rebuild_header(struct sock *sk)
+ }
+ #endif
+ 
+-struct request_sock_ops mptcp_subflow_request_sock_ops;
++static struct request_sock_ops mptcp_subflow_v4_request_sock_ops __ro_after_init;
+ static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops __ro_after_init;
+ 
+ static int subflow_v4_conn_request(struct sock *sk, struct sk_buff *skb)
+@@ -542,7 +541,7 @@ static int subflow_v4_conn_request(struct sock *sk, struct sk_buff *skb)
+ 	if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
+ 		goto drop;
+ 
+-	return tcp_conn_request(&mptcp_subflow_request_sock_ops,
++	return tcp_conn_request(&mptcp_subflow_v4_request_sock_ops,
+ 				&subflow_request_sock_ipv4_ops,
+ 				sk, skb);
+ drop:
+@@ -550,7 +549,14 @@ drop:
+ 	return 0;
+ }
+ 
++static void subflow_v4_req_destructor(struct request_sock *req)
++{
++	subflow_req_destructor(req);
++	tcp_request_sock_ops.destructor(req);
++}
++
+ #if IS_ENABLED(CONFIG_MPTCP_IPV6)
++static struct request_sock_ops mptcp_subflow_v6_request_sock_ops __ro_after_init;
+ static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops __ro_after_init;
+ static struct inet_connection_sock_af_ops subflow_v6_specific __ro_after_init;
+ static struct inet_connection_sock_af_ops subflow_v6m_specific __ro_after_init;
+@@ -573,15 +579,36 @@ static int subflow_v6_conn_request(struct sock *sk, struct sk_buff *skb)
+ 		return 0;
+ 	}
+ 
+-	return tcp_conn_request(&mptcp_subflow_request_sock_ops,
++	return tcp_conn_request(&mptcp_subflow_v6_request_sock_ops,
+ 				&subflow_request_sock_ipv6_ops, sk, skb);
+ 
+ drop:
+ 	tcp_listendrop(sk);
+ 	return 0; /* don't send reset */
+ }
++
++static void subflow_v6_req_destructor(struct request_sock *req)
++{
++	subflow_req_destructor(req);
++	tcp6_request_sock_ops.destructor(req);
++}
++#endif
++
++struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
++					       struct sock *sk_listener,
++					       bool attach_listener)
++{
++	if (ops->family == AF_INET)
++		ops = &mptcp_subflow_v4_request_sock_ops;
++#if IS_ENABLED(CONFIG_MPTCP_IPV6)
++	else if (ops->family == AF_INET6)
++		ops = &mptcp_subflow_v6_request_sock_ops;
+ #endif
+ 
++	return inet_reqsk_alloc(ops, sk_listener, attach_listener);
++}
++EXPORT_SYMBOL(mptcp_subflow_reqsk_alloc);
++
+ /* validate hmac received in third ACK */
+ static bool subflow_hmac_valid(const struct request_sock *req,
+ 			       const struct mptcp_options_received *mp_opt)
+@@ -1904,7 +1931,6 @@ static struct tcp_ulp_ops subflow_ulp_ops __read_mostly = {
+ static int subflow_ops_init(struct request_sock_ops *subflow_ops)
+ {
+ 	subflow_ops->obj_size = sizeof(struct mptcp_subflow_request_sock);
+-	subflow_ops->slab_name = "request_sock_subflow";
+ 
+ 	subflow_ops->slab = kmem_cache_create(subflow_ops->slab_name,
+ 					      subflow_ops->obj_size, 0,
+@@ -1914,16 +1940,17 @@ static int subflow_ops_init(struct request_sock_ops *subflow_ops)
+ 	if (!subflow_ops->slab)
+ 		return -ENOMEM;
+ 
+-	subflow_ops->destructor = subflow_req_destructor;
+-
+ 	return 0;
+ }
+ 
+ void __init mptcp_subflow_init(void)
+ {
+-	mptcp_subflow_request_sock_ops = tcp_request_sock_ops;
+-	if (subflow_ops_init(&mptcp_subflow_request_sock_ops) != 0)
+-		panic("MPTCP: failed to init subflow request sock ops\n");
++	mptcp_subflow_v4_request_sock_ops = tcp_request_sock_ops;
++	mptcp_subflow_v4_request_sock_ops.slab_name = "request_sock_subflow_v4";
++	mptcp_subflow_v4_request_sock_ops.destructor = subflow_v4_req_destructor;
++
++	if (subflow_ops_init(&mptcp_subflow_v4_request_sock_ops) != 0)
++		panic("MPTCP: failed to init subflow v4 request sock ops\n");
+ 
+ 	subflow_request_sock_ipv4_ops = tcp_request_sock_ipv4_ops;
+ 	subflow_request_sock_ipv4_ops.route_req = subflow_v4_route_req;
+@@ -1938,6 +1965,20 @@ void __init mptcp_subflow_init(void)
+ 	tcp_prot_override.release_cb = tcp_release_cb_override;
+ 
+ #if IS_ENABLED(CONFIG_MPTCP_IPV6)
++	/* In struct mptcp_subflow_request_sock, we assume the TCP request sock
++	 * structures for v4 and v6 have the same size. It should not changed in
++	 * the future but better to make sure to be warned if it is no longer
++	 * the case.
++	 */
++	BUILD_BUG_ON(sizeof(struct tcp_request_sock) != sizeof(struct tcp6_request_sock));
++
++	mptcp_subflow_v6_request_sock_ops = tcp6_request_sock_ops;
++	mptcp_subflow_v6_request_sock_ops.slab_name = "request_sock_subflow_v6";
++	mptcp_subflow_v6_request_sock_ops.destructor = subflow_v6_req_destructor;
++
++	if (subflow_ops_init(&mptcp_subflow_v6_request_sock_ops) != 0)
++		panic("MPTCP: failed to init subflow v6 request sock ops\n");
++
+ 	subflow_request_sock_ipv6_ops = tcp_request_sock_ipv6_ops;
+ 	subflow_request_sock_ipv6_ops.route_req = subflow_v6_route_req;
+ 
+diff --git a/security/device_cgroup.c b/security/device_cgroup.c
+index a9f8c63a96d1a..bef2b9285fb34 100644
+--- a/security/device_cgroup.c
++++ b/security/device_cgroup.c
+@@ -82,6 +82,17 @@ free_and_exit:
+ 	return -ENOMEM;
+ }
+ 
++static void dev_exceptions_move(struct list_head *dest, struct list_head *orig)
++{
++	struct dev_exception_item *ex, *tmp;
++
++	lockdep_assert_held(&devcgroup_mutex);
++
++	list_for_each_entry_safe(ex, tmp, orig, list) {
++		list_move_tail(&ex->list, dest);
++	}
++}
++
+ /*
+  * called under devcgroup_mutex
+  */
+@@ -604,11 +615,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
+ 	int count, rc = 0;
+ 	struct dev_exception_item ex;
+ 	struct dev_cgroup *parent = css_to_devcgroup(devcgroup->css.parent);
++	struct dev_cgroup tmp_devcgrp;
+ 
+ 	if (!capable(CAP_SYS_ADMIN))
+ 		return -EPERM;
+ 
+ 	memset(&ex, 0, sizeof(ex));
++	memset(&tmp_devcgrp, 0, sizeof(tmp_devcgrp));
+ 	b = buffer;
+ 
+ 	switch (*b) {
+@@ -620,15 +633,27 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
+ 
+ 			if (!may_allow_all(parent))
+ 				return -EPERM;
+-			dev_exception_clean(devcgroup);
+-			devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
+-			if (!parent)
++			if (!parent) {
++				devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
++				dev_exception_clean(devcgroup);
+ 				break;
++			}
+ 
++			INIT_LIST_HEAD(&tmp_devcgrp.exceptions);
++			rc = dev_exceptions_copy(&tmp_devcgrp.exceptions,
++						 &devcgroup->exceptions);
++			if (rc)
++				return rc;
++			dev_exception_clean(devcgroup);
+ 			rc = dev_exceptions_copy(&devcgroup->exceptions,
+ 						 &parent->exceptions);
+-			if (rc)
++			if (rc) {
++				dev_exceptions_move(&devcgroup->exceptions,
++						    &tmp_devcgrp.exceptions);
+ 				return rc;
++			}
++			devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
++			dev_exception_clean(&tmp_devcgrp);
+ 			break;
+ 		case DEVCG_DENY:
+ 			if (css_has_online_children(&devcgroup->css))
+diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
+index 7249f16257c72..39caeca474449 100644
+--- a/security/integrity/ima/Kconfig
++++ b/security/integrity/ima/Kconfig
+@@ -112,7 +112,7 @@ choice
+ 
+ 	config IMA_DEFAULT_HASH_SM3
+ 		bool "SM3"
+-		depends on CRYPTO_SM3=y
++		depends on CRYPTO_SM3_GENERIC=y
+ endchoice
+ 
+ config IMA_DEFAULT_HASH
+diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
+index 040b03ddc1c77..4a207a3ef7ef3 100644
+--- a/security/integrity/ima/ima_main.c
++++ b/security/integrity/ima/ima_main.c
+@@ -542,8 +542,13 @@ static int __ima_inode_hash(struct inode *inode, struct file *file, char *buf,
+ 
+ 		rc = ima_collect_measurement(&tmp_iint, file, NULL, 0,
+ 					     ima_hash_algo, NULL);
+-		if (rc < 0)
++		if (rc < 0) {
++			/* ima_hash could be allocated in case of failure. */
++			if (rc != -ENOMEM)
++				kfree(tmp_iint.ima_hash);
++
+ 			return -EOPNOTSUPP;
++		}
+ 
+ 		iint = &tmp_iint;
+ 		mutex_lock(&iint->mutex);
+diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
+index 195ac18f09275..04c49f05cb74f 100644
+--- a/security/integrity/ima/ima_template.c
++++ b/security/integrity/ima/ima_template.c
+@@ -340,8 +340,11 @@ static struct ima_template_desc *restore_template_fmt(char *template_name)
+ 
+ 	template_desc->name = "";
+ 	template_desc->fmt = kstrdup(template_name, GFP_KERNEL);
+-	if (!template_desc->fmt)
++	if (!template_desc->fmt) {
++		kfree(template_desc);
++		template_desc = NULL;
+ 		goto out;
++	}
+ 
+ 	spin_lock(&template_list);
+ 	list_add_tail_rcu(&template_desc->list, &defined_templates);
+diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c
+index b78753d27d8ea..d1fdd113450a6 100644
+--- a/security/integrity/platform_certs/load_uefi.c
++++ b/security/integrity/platform_certs/load_uefi.c
+@@ -35,6 +35,7 @@ static const struct dmi_system_id uefi_skip_cert[] = {
+ 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") },
+ 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") },
+ 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") },
++	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMacPro1,1") },
+ 	{ }
+ };
+ 
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 94fe842178947..cca6e8fdec5ff 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6925,6 +6925,34 @@ static void alc287_fixup_yoga9_14iap7_bass_spk_pin(struct hda_codec *codec,
+ 	}
+ }
+ 
++static void alc295_fixup_dell_inspiron_top_speakers(struct hda_codec *codec,
++					  const struct hda_fixup *fix, int action)
++{
++	static const struct hda_pintbl pincfgs[] = {
++		{ 0x14, 0x90170151 },
++		{ 0x17, 0x90170150 },
++		{ }
++	};
++	static const hda_nid_t conn[] = { 0x02, 0x03 };
++	static const hda_nid_t preferred_pairs[] = {
++		0x14, 0x02,
++		0x17, 0x03,
++		0x21, 0x02,
++		0
++	};
++	struct alc_spec *spec = codec->spec;
++
++	alc_fixup_no_shutup(codec, fix, action);
++
++	switch (action) {
++	case HDA_FIXUP_ACT_PRE_PROBE:
++		snd_hda_apply_pincfgs(codec, pincfgs);
++		snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
++		spec->gen.preferred_dacs = preferred_pairs;
++		break;
++	}
++}
++
+ enum {
+ 	ALC269_FIXUP_GPIO2,
+ 	ALC269_FIXUP_SONY_VAIO,
+@@ -7168,6 +7196,8 @@ enum {
+ 	ALC287_FIXUP_LEGION_16ITHG6,
+ 	ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK,
+ 	ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN,
++	ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS,
++	ALC236_FIXUP_DELL_DUAL_CODECS,
+ };
+ 
+ /* A special fixup for Lenovo C940 and Yoga Duet 7;
+@@ -9117,6 +9147,18 @@ static const struct hda_fixup alc269_fixups[] = {
+ 		.chained = true,
+ 		.chain_id = ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK,
+ 	},
++	[ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS] = {
++		.type = HDA_FIXUP_FUNC,
++		.v.func = alc295_fixup_dell_inspiron_top_speakers,
++		.chained = true,
++		.chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
++	},
++	[ALC236_FIXUP_DELL_DUAL_CODECS] = {
++		.type = HDA_FIXUP_PINS,
++		.v.func = alc1220_fixup_gb_dual_codecs,
++		.chained = true,
++		.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++	},
+ };
+ 
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -9217,6 +9259,14 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK),
+ 	SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
++	SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
++	SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
++	SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
++	SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
++	SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
++	SND_PCI_QUIRK(0x1028, 0x0c1c, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
++	SND_PCI_QUIRK(0x1028, 0x0c1d, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
++	SND_PCI_QUIRK(0x1028, 0x0c1e, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
+ 	SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
+diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
+index c4c1e89b47c1b..83cb81999c6fc 100644
+--- a/sound/soc/jz4740/jz4740-i2s.c
++++ b/sound/soc/jz4740/jz4740-i2s.c
+@@ -55,7 +55,8 @@
+ #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
+ #define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
+ #define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
+-#define JZ_AIC_CTRL_FLUSH		BIT(8)
++#define JZ_AIC_CTRL_TFLUSH		BIT(8)
++#define JZ_AIC_CTRL_RFLUSH		BIT(7)
+ #define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
+ #define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
+ #define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
+@@ -90,6 +91,8 @@ enum jz47xx_i2s_version {
+ struct i2s_soc_info {
+ 	enum jz47xx_i2s_version version;
+ 	struct snd_soc_dai_driver *dai;
++
++	bool shared_fifo_flush;
+ };
+ 
+ struct jz4740_i2s {
+@@ -116,19 +119,44 @@ static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
+ 	writel(value, i2s->base + reg);
+ }
+ 
++static inline void jz4740_i2s_set_bits(const struct jz4740_i2s *i2s,
++	unsigned int reg, uint32_t bits)
++{
++	uint32_t value = jz4740_i2s_read(i2s, reg);
++	value |= bits;
++	jz4740_i2s_write(i2s, reg, value);
++}
++
+ static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
+ 	struct snd_soc_dai *dai)
+ {
+ 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+-	uint32_t conf, ctrl;
++	uint32_t conf;
+ 	int ret;
+ 
++	/*
++	 * When we can flush FIFOs independently, only flush the FIFO
++	 * that is starting up. We can do this when the DAI is active
++	 * because it does not disturb other active substreams.
++	 */
++	if (!i2s->soc_info->shared_fifo_flush) {
++		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
++			jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH);
++		else
++			jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_RFLUSH);
++	}
++
+ 	if (snd_soc_dai_active(dai))
+ 		return 0;
+ 
+-	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
+-	ctrl |= JZ_AIC_CTRL_FLUSH;
+-	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
++	/*
++	 * When there is a shared flush bit for both FIFOs, the TFLUSH
++	 * bit flushes both FIFOs. Flushing while the DAI is active would
++	 * cause FIFO underruns in other active substreams so we have to
++	 * guard this behind the snd_soc_dai_active() check.
++	 */
++	if (i2s->soc_info->shared_fifo_flush)
++		jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH);
+ 
+ 	ret = clk_prepare_enable(i2s->clk_i2s);
+ 	if (ret)
+@@ -443,6 +471,7 @@ static struct snd_soc_dai_driver jz4740_i2s_dai = {
+ static const struct i2s_soc_info jz4740_i2s_soc_info = {
+ 	.version = JZ_I2S_JZ4740,
+ 	.dai = &jz4740_i2s_dai,
++	.shared_fifo_flush = true,
+ };
+ 
+ static const struct i2s_soc_info jz4760_i2s_soc_info = {
+diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
+index 09d1578f9d66f..1737c59e4ff67 100755
+--- a/tools/testing/ktest/ktest.pl
++++ b/tools/testing/ktest/ktest.pl
+@@ -1963,7 +1963,7 @@ sub run_scp_mod {
+ 
+ sub _get_grub_index {
+ 
+-    my ($command, $target, $skip) = @_;
++    my ($command, $target, $skip, $submenu) = @_;
+ 
+     return if (defined($grub_number) && defined($last_grub_menu) &&
+ 	$last_grub_menu eq $grub_menu && defined($last_machine) &&
+@@ -1980,11 +1980,16 @@ sub _get_grub_index {
+ 
+     my $found = 0;
+ 
++    my $submenu_number = 0;
++
+     while (<IN>) {
+ 	if (/$target/) {
+ 	    $grub_number++;
+ 	    $found = 1;
+ 	    last;
++	} elsif (defined($submenu) && /$submenu/) {
++		$submenu_number++;
++		$grub_number = -1;
+ 	} elsif (/$skip/) {
+ 	    $grub_number++;
+ 	}
+@@ -1993,6 +1998,9 @@ sub _get_grub_index {
+ 
+     dodie "Could not find '$grub_menu' through $command on $machine"
+ 	if (!$found);
++    if ($submenu_number > 0) {
++	$grub_number = "$submenu_number>$grub_number";
++    }
+     doprint "$grub_number\n";
+     $last_grub_menu = $grub_menu;
+     $last_machine = $machine;
+@@ -2003,6 +2011,7 @@ sub get_grub_index {
+     my $command;
+     my $target;
+     my $skip;
++    my $submenu;
+     my $grub_menu_qt;
+ 
+     if ($reboot_type !~ /^grub/) {
+@@ -2017,8 +2026,9 @@ sub get_grub_index {
+ 	$skip = '^\s*title\s';
+     } elsif ($reboot_type eq "grub2") {
+ 	$command = "cat $grub_file";
+-	$target = '^menuentry.*' . $grub_menu_qt;
+-	$skip = '^menuentry\s|^submenu\s';
++	$target = '^\s*menuentry.*' . $grub_menu_qt;
++	$skip = '^\s*menuentry';
++	$submenu = '^\s*submenu\s';
+     } elsif ($reboot_type eq "grub2bls") {
+ 	$command = $grub_bls_get;
+ 	$target = '^title=.*' . $grub_menu_qt;
+@@ -2027,7 +2037,7 @@ sub get_grub_index {
+ 	return;
+     }
+ 
+-    _get_grub_index($command, $target, $skip);
++    _get_grub_index($command, $target, $skip, $submenu);
+ }
+ 
+ sub wait_for_input {
+@@ -2090,7 +2100,7 @@ sub reboot_to {
+     if ($reboot_type eq "grub") {
+ 	run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
+     } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
+-	run_ssh "$grub_reboot $grub_number";
++	run_ssh "$grub_reboot \"'$grub_number'\"";
+     } elsif ($reboot_type eq "syslinux") {
+ 	run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
+     } elsif (defined $reboot_script) {
+@@ -3768,9 +3778,10 @@ sub test_this_config {
+     # .config to make sure it is missing the config that
+     # we had before
+     my %configs = %min_configs;
+-    delete $configs{$config};
++    $configs{$config} = "# $config is not set";
+     make_new_config ((values %configs), (values %keep_configs));
+     make_oldconfig;
++    delete $configs{$config};
+     undef %configs;
+     assign_configs \%configs, $output_config;
+ 
+diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk
+index a3ea3d4a206d0..291144c284fbc 100644
+--- a/tools/testing/selftests/lib.mk
++++ b/tools/testing/selftests/lib.mk
+@@ -123,6 +123,11 @@ endef
+ clean:
+ 	$(CLEAN)
+ 
++# Enables to extend CFLAGS and LDFLAGS from command line, e.g.
++# make USERCFLAGS=-Werror USERLDFLAGS=-static
++CFLAGS += $(USERCFLAGS)
++LDFLAGS += $(USERLDFLAGS)
++
+ # When make O= with kselftest target from main level
+ # the following aren't defined.
+ #


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2023-01-04 11:38 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2023-01-04 11:38 UTC (permalink / raw
  To: gentoo-commits

commit:     fef50508c3386cf852a065b4ef6d4f5b723cc859
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Jan  4 11:38:19 2023 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Jan  4 11:38:19 2023 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=fef50508

Linux patch 6.0.17

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

 0000_README             |    4 +
 1016_linux-6.0.17.patch | 2726 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2730 insertions(+)

diff --git a/0000_README b/0000_README
index 44fc4c7e..b0d2c4b3 100644
--- a/0000_README
+++ b/0000_README
@@ -107,6 +107,10 @@ Patch:  1015_linux-6.0.16.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.16
 
+Patch:  1016_linux-6.0.17.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.17
+
 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/1016_linux-6.0.17.patch b/1016_linux-6.0.17.patch
new file mode 100644
index 00000000..c6bffa77
--- /dev/null
+++ b/1016_linux-6.0.17.patch
@@ -0,0 +1,2726 @@
+diff --git a/Documentation/trace/kprobes.rst b/Documentation/trace/kprobes.rst
+index f318bceda1e67..97d086b23ce85 100644
+--- a/Documentation/trace/kprobes.rst
++++ b/Documentation/trace/kprobes.rst
+@@ -131,8 +131,7 @@ For example, if the function is non-recursive and is called with a
+ spinlock held, maxactive = 1 should be enough.  If the function is
+ non-recursive and can never relinquish the CPU (e.g., via a semaphore
+ or preemption), NR_CPUS should be enough.  If maxactive <= 0, it is
+-set to a default value.  If CONFIG_PREEMPT is enabled, the default
+-is max(10, 2*NR_CPUS).  Otherwise, the default is NR_CPUS.
++set to a default value: max(10, 2*NR_CPUS).
+ 
+ It's not a disaster if you set maxactive too low; you'll just miss
+ some probes.  In the kretprobe struct, the nmissed field is set to
+diff --git a/Makefile b/Makefile
+index ff8d88b113919..a0ddac5b7cafb 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 16
++SUBLEVEL = 17
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
+index 0b8a858aa8479..5a873d4fbd7b9 100644
+--- a/arch/powerpc/kernel/rtas.c
++++ b/arch/powerpc/kernel/rtas.c
+@@ -875,6 +875,7 @@ void __noreturn rtas_halt(void)
+ 
+ /* Must be in the RMO region, so we place it here */
+ static char rtas_os_term_buf[2048];
++static s32 ibm_os_term_token = RTAS_UNKNOWN_SERVICE;
+ 
+ void rtas_os_term(char *str)
+ {
+@@ -886,16 +887,20 @@ void rtas_os_term(char *str)
+ 	 * this property may terminate the partition which we want to avoid
+ 	 * since it interferes with panic_timeout.
+ 	 */
+-	if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term") ||
+-	    RTAS_UNKNOWN_SERVICE == rtas_token("ibm,extended-os-term"))
++	if (ibm_os_term_token == RTAS_UNKNOWN_SERVICE)
+ 		return;
+ 
+ 	snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str);
+ 
++	/*
++	 * Keep calling as long as RTAS returns a "try again" status,
++	 * but don't use rtas_busy_delay(), which potentially
++	 * schedules.
++	 */
+ 	do {
+-		status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
++		status = rtas_call(ibm_os_term_token, 1, 1, NULL,
+ 				   __pa(rtas_os_term_buf));
+-	} while (rtas_busy_delay(status));
++	} while (rtas_busy_delay_time(status));
+ 
+ 	if (status != 0)
+ 		printk(KERN_EMERG "ibm,os-term call failed %d\n", status);
+@@ -1255,6 +1260,13 @@ void __init rtas_initialize(void)
+ 	no_entry = of_property_read_u32(rtas.dev, "linux,rtas-entry", &entry);
+ 	rtas.entry = no_entry ? rtas.base : entry;
+ 
++	/*
++	 * Discover these now to avoid device tree lookups in the
++	 * panic path.
++	 */
++	if (of_property_read_bool(rtas.dev, "ibm,extended-os-term"))
++		ibm_os_term_token = rtas_token("ibm,os-term");
++
+ 	/* If RTAS was found, allocate the RMO buffer for it and look for
+ 	 * the stop-self token if any
+ 	 */
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index 528ca21044a57..7d2ca122362fa 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -5385,8 +5385,8 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync)
+ 		unsigned long flags;
+ 
+ 		spin_lock_irqsave(&bfqd->lock, flags);
+-		bfq_exit_bfqq(bfqd, bfqq);
+ 		bic_set_bfqq(bic, NULL, is_sync);
++		bfq_exit_bfqq(bfqd, bfqq);
+ 		spin_unlock_irqrestore(&bfqd->lock, flags);
+ 	}
+ }
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index c8f0c865bf4ed..ee517fb06aa6f 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -33,6 +33,7 @@
+ #include "blk-cgroup.h"
+ #include "blk-ioprio.h"
+ #include "blk-throttle.h"
++#include "blk-rq-qos.h"
+ 
+ /*
+  * blkcg_pol_mutex protects blkcg_policy[] and policy [de]activation.
+@@ -263,29 +264,13 @@ err_free:
+ 	return NULL;
+ }
+ 
+-struct blkcg_gq *blkg_lookup_slowpath(struct blkcg *blkcg,
+-				      struct request_queue *q, bool update_hint)
++static void blkg_update_hint(struct blkcg *blkcg, struct blkcg_gq *blkg)
+ {
+-	struct blkcg_gq *blkg;
+-
+-	/*
+-	 * Hint didn't match.  Look up from the radix tree.  Note that the
+-	 * hint can only be updated under queue_lock as otherwise @blkg
+-	 * could have already been removed from blkg_tree.  The caller is
+-	 * responsible for grabbing queue_lock if @update_hint.
+-	 */
+-	blkg = radix_tree_lookup(&blkcg->blkg_tree, q->id);
+-	if (blkg && blkg->q == q) {
+-		if (update_hint) {
+-			lockdep_assert_held(&q->queue_lock);
+-			rcu_assign_pointer(blkcg->blkg_hint, blkg);
+-		}
+-		return blkg;
+-	}
++	lockdep_assert_held(&blkg->q->queue_lock);
+ 
+-	return NULL;
++	if (blkcg != &blkcg_root && blkg != rcu_dereference(blkcg->blkg_hint))
++		rcu_assign_pointer(blkcg->blkg_hint, blkg);
+ }
+-EXPORT_SYMBOL_GPL(blkg_lookup_slowpath);
+ 
+ /*
+  * If @new_blkg is %NULL, this function tries to allocate a new one as
+@@ -324,7 +309,7 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg,
+ 
+ 	/* link parent */
+ 	if (blkcg_parent(blkcg)) {
+-		blkg->parent = __blkg_lookup(blkcg_parent(blkcg), q, false);
++		blkg->parent = blkg_lookup(blkcg_parent(blkcg), q);
+ 		if (WARN_ON_ONCE(!blkg->parent)) {
+ 			ret = -ENODEV;
+ 			goto err_put_css;
+@@ -397,9 +382,11 @@ static struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
+ 		return blkg;
+ 
+ 	spin_lock_irqsave(&q->queue_lock, flags);
+-	blkg = __blkg_lookup(blkcg, q, true);
+-	if (blkg)
++	blkg = blkg_lookup(blkcg, q);
++	if (blkg) {
++		blkg_update_hint(blkcg, blkg);
+ 		goto found;
++	}
+ 
+ 	/*
+ 	 * Create blkgs walking down from blkcg_root to @blkcg, so that all
+@@ -412,7 +399,7 @@ static struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,
+ 		struct blkcg_gq *ret_blkg = q->root_blkg;
+ 
+ 		while (parent) {
+-			blkg = __blkg_lookup(parent, q, false);
++			blkg = blkg_lookup(parent, q);
+ 			if (blkg) {
+ 				/* remember closest blkg */
+ 				ret_blkg = blkg;
+@@ -476,14 +463,9 @@ static void blkg_destroy(struct blkcg_gq *blkg)
+ 	percpu_ref_kill(&blkg->refcnt);
+ }
+ 
+-/**
+- * blkg_destroy_all - destroy all blkgs associated with a request_queue
+- * @q: request_queue of interest
+- *
+- * Destroy all blkgs associated with @q.
+- */
+-static void blkg_destroy_all(struct request_queue *q)
++static void blkg_destroy_all(struct gendisk *disk)
+ {
++	struct request_queue *q = disk->queue;
+ 	struct blkcg_gq *blkg, *n;
+ 	int count = BLKG_DESTROY_BATCH_SIZE;
+ 
+@@ -621,12 +603,18 @@ static struct blkcg_gq *blkg_lookup_check(struct blkcg *blkcg,
+ 					  const struct blkcg_policy *pol,
+ 					  struct request_queue *q)
+ {
++	struct blkcg_gq *blkg;
++
+ 	WARN_ON_ONCE(!rcu_read_lock_held());
+ 	lockdep_assert_held(&q->queue_lock);
+ 
+ 	if (!blkcg_policy_enabled(q, pol))
+ 		return ERR_PTR(-EOPNOTSUPP);
+-	return __blkg_lookup(blkcg, q, true /* update_hint */);
++
++	blkg = blkg_lookup(blkcg, q);
++	if (blkg)
++		blkg_update_hint(blkcg, blkg);
++	return blkg;
+ }
+ 
+ /**
+@@ -724,7 +712,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
+ 		struct blkcg_gq *new_blkg;
+ 
+ 		parent = blkcg_parent(blkcg);
+-		while (parent && !__blkg_lookup(parent, q, false)) {
++		while (parent && !blkg_lookup(parent, q)) {
+ 			pos = parent;
+ 			parent = blkcg_parent(parent);
+ 		}
+@@ -915,8 +903,7 @@ static void blkcg_fill_root_iostats(void)
+ 	class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
+ 	while ((dev = class_dev_iter_next(&iter))) {
+ 		struct block_device *bdev = dev_to_bdev(dev);
+-		struct blkcg_gq *blkg =
+-			blk_queue_root_blkg(bdev_get_queue(bdev));
++		struct blkcg_gq *blkg = bdev->bd_disk->queue->root_blkg;
+ 		struct blkg_iostat tmp;
+ 		int cpu;
+ 		unsigned long flags;
+@@ -1255,18 +1242,9 @@ static int blkcg_css_online(struct cgroup_subsys_state *css)
+ 	return 0;
+ }
+ 
+-/**
+- * blkcg_init_queue - initialize blkcg part of request queue
+- * @q: request_queue to initialize
+- *
+- * Called from blk_alloc_queue(). Responsible for initializing blkcg
+- * part of new request_queue @q.
+- *
+- * RETURNS:
+- * 0 on success, -errno on failure.
+- */
+-int blkcg_init_queue(struct request_queue *q)
++int blkcg_init_disk(struct gendisk *disk)
+ {
++	struct request_queue *q = disk->queue;
+ 	struct blkcg_gq *new_blkg, *blkg;
+ 	bool preloaded;
+ 	int ret;
+@@ -1295,21 +1273,22 @@ int blkcg_init_queue(struct request_queue *q)
+ 	if (ret)
+ 		goto err_destroy_all;
+ 
+-	ret = blk_throtl_init(q);
++	ret = blk_throtl_init(disk);
+ 	if (ret)
+-		goto err_destroy_all;
++		goto err_ioprio_exit;
+ 
+ 	ret = blk_iolatency_init(q);
+-	if (ret) {
+-		blk_throtl_exit(q);
+-		blk_ioprio_exit(q);
+-		goto err_destroy_all;
+-	}
++	if (ret)
++		goto err_throtl_exit;
+ 
+ 	return 0;
+ 
++err_throtl_exit:
++	blk_throtl_exit(disk);
++err_ioprio_exit:
++	blk_ioprio_exit(q);
+ err_destroy_all:
+-	blkg_destroy_all(q);
++	blkg_destroy_all(disk);
+ 	return ret;
+ err_unlock:
+ 	spin_unlock_irq(&q->queue_lock);
+@@ -1318,16 +1297,11 @@ err_unlock:
+ 	return PTR_ERR(blkg);
+ }
+ 
+-/**
+- * blkcg_exit_queue - exit and release blkcg part of request_queue
+- * @q: request_queue being released
+- *
+- * Called from blk_exit_queue().  Responsible for exiting blkcg part.
+- */
+-void blkcg_exit_queue(struct request_queue *q)
++void blkcg_exit_disk(struct gendisk *disk)
+ {
+-	blkg_destroy_all(q);
+-	blk_throtl_exit(q);
++	blkg_destroy_all(disk);
++	rq_qos_exit(disk->queue);
++	blk_throtl_exit(disk);
+ }
+ 
+ static void blkcg_bind(struct cgroup_subsys_state *root_css)
+diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h
+index d2724d1dd7c9b..aa2b286bc825f 100644
+--- a/block/blk-cgroup.h
++++ b/block/blk-cgroup.h
+@@ -178,10 +178,8 @@ struct blkcg_policy {
+ extern struct blkcg blkcg_root;
+ extern bool blkcg_debug_stats;
+ 
+-struct blkcg_gq *blkg_lookup_slowpath(struct blkcg *blkcg,
+-				      struct request_queue *q, bool update_hint);
+-int blkcg_init_queue(struct request_queue *q);
+-void blkcg_exit_queue(struct request_queue *q);
++int blkcg_init_disk(struct gendisk *disk);
++void blkcg_exit_disk(struct gendisk *disk);
+ 
+ /* Blkio controller policy registration */
+ int blkcg_policy_register(struct blkcg_policy *pol);
+@@ -227,22 +225,21 @@ static inline bool bio_issue_as_root_blkg(struct bio *bio)
+ }
+ 
+ /**
+- * __blkg_lookup - internal version of blkg_lookup()
++ * blkg_lookup - lookup blkg for the specified blkcg - q pair
+  * @blkcg: blkcg of interest
+  * @q: request_queue of interest
+- * @update_hint: whether to update lookup hint with the result or not
+  *
+- * This is internal version and shouldn't be used by policy
+- * implementations.  Looks up blkgs for the @blkcg - @q pair regardless of
+- * @q's bypass state.  If @update_hint is %true, the caller should be
+- * holding @q->queue_lock and lookup hint is updated on success.
++ * Lookup blkg for the @blkcg - @q pair.
++
++ * Must be called in a RCU critical section.
+  */
+-static inline struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg,
+-					     struct request_queue *q,
+-					     bool update_hint)
++static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg,
++					   struct request_queue *q)
+ {
+ 	struct blkcg_gq *blkg;
+ 
++	WARN_ON_ONCE(!rcu_read_lock_held());
++
+ 	if (blkcg == &blkcg_root)
+ 		return q->root_blkg;
+ 
+@@ -250,33 +247,10 @@ static inline struct blkcg_gq *__blkg_lookup(struct blkcg *blkcg,
+ 	if (blkg && blkg->q == q)
+ 		return blkg;
+ 
+-	return blkg_lookup_slowpath(blkcg, q, update_hint);
+-}
+-
+-/**
+- * blkg_lookup - lookup blkg for the specified blkcg - q pair
+- * @blkcg: blkcg of interest
+- * @q: request_queue of interest
+- *
+- * Lookup blkg for the @blkcg - @q pair.  This function should be called
+- * under RCU read lock.
+- */
+-static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg,
+-					   struct request_queue *q)
+-{
+-	WARN_ON_ONCE(!rcu_read_lock_held());
+-	return __blkg_lookup(blkcg, q, false);
+-}
+-
+-/**
+- * blk_queue_root_blkg - return blkg for the (blkcg_root, @q) pair
+- * @q: request_queue of interest
+- *
+- * Lookup blkg for @q at the root level. See also blkg_lookup().
+- */
+-static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
+-{
+-	return q->root_blkg;
++	blkg = radix_tree_lookup(&blkcg->blkg_tree, q->id);
++	if (blkg && blkg->q != q)
++		blkg = NULL;
++	return blkg;
+ }
+ 
+ /**
+@@ -373,8 +347,8 @@ static inline void blkg_put(struct blkcg_gq *blkg)
+  */
+ #define blkg_for_each_descendant_pre(d_blkg, pos_css, p_blkg)		\
+ 	css_for_each_descendant_pre((pos_css), &(p_blkg)->blkcg->css)	\
+-		if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css),	\
+-					      (p_blkg)->q, false)))
++		if (((d_blkg) = blkg_lookup(css_to_blkcg(pos_css),	\
++					    (p_blkg)->q)))
+ 
+ /**
+  * blkg_for_each_descendant_post - post-order walk of a blkg's descendants
+@@ -388,8 +362,8 @@ static inline void blkg_put(struct blkcg_gq *blkg)
+  */
+ #define blkg_for_each_descendant_post(d_blkg, pos_css, p_blkg)		\
+ 	css_for_each_descendant_post((pos_css), &(p_blkg)->blkcg->css)	\
+-		if (((d_blkg) = __blkg_lookup(css_to_blkcg(pos_css),	\
+-					      (p_blkg)->q, false)))
++		if (((d_blkg) = blkg_lookup(css_to_blkcg(pos_css),	\
++					    (p_blkg)->q)))
+ 
+ bool __blkcg_punt_bio_submit(struct bio *bio);
+ 
+@@ -507,10 +481,8 @@ struct blkcg {
+ };
+ 
+ static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; }
+-static inline struct blkcg_gq *blk_queue_root_blkg(struct request_queue *q)
+-{ return NULL; }
+-static inline int blkcg_init_queue(struct request_queue *q) { return 0; }
+-static inline void blkcg_exit_queue(struct request_queue *q) { }
++static inline int blkcg_init_disk(struct gendisk *disk) { return 0; }
++static inline void blkcg_exit_disk(struct gendisk *disk) { }
+ static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; }
+ static inline void blkcg_policy_unregister(struct blkcg_policy *pol) { }
+ static inline int blkcg_activate_policy(struct request_queue *q,
+diff --git a/block/blk-throttle.c b/block/blk-throttle.c
+index 35cf744ea9d11..f84a6ed440c93 100644
+--- a/block/blk-throttle.c
++++ b/block/blk-throttle.c
+@@ -2276,8 +2276,9 @@ void blk_throtl_bio_endio(struct bio *bio)
+ }
+ #endif
+ 
+-int blk_throtl_init(struct request_queue *q)
++int blk_throtl_init(struct gendisk *disk)
+ {
++	struct request_queue *q = disk->queue;
+ 	struct throtl_data *td;
+ 	int ret;
+ 
+@@ -2319,8 +2320,10 @@ int blk_throtl_init(struct request_queue *q)
+ 	return ret;
+ }
+ 
+-void blk_throtl_exit(struct request_queue *q)
++void blk_throtl_exit(struct gendisk *disk)
+ {
++	struct request_queue *q = disk->queue;
++
+ 	BUG_ON(!q->td);
+ 	del_timer_sync(&q->td->service_queue.pending_timer);
+ 	throtl_shutdown_wq(q);
+diff --git a/block/blk-throttle.h b/block/blk-throttle.h
+index ee7299e6dea91..e8c2b3d4a18b8 100644
+--- a/block/blk-throttle.h
++++ b/block/blk-throttle.h
+@@ -159,14 +159,14 @@ static inline struct throtl_grp *blkg_to_tg(struct blkcg_gq *blkg)
+  * Internal throttling interface
+  */
+ #ifndef CONFIG_BLK_DEV_THROTTLING
+-static inline int blk_throtl_init(struct request_queue *q) { return 0; }
+-static inline void blk_throtl_exit(struct request_queue *q) { }
++static inline int blk_throtl_init(struct gendisk *disk) { return 0; }
++static inline void blk_throtl_exit(struct gendisk *disk) { }
+ static inline void blk_throtl_register_queue(struct request_queue *q) { }
+ static inline bool blk_throtl_bio(struct bio *bio) { return false; }
+ static inline void blk_throtl_cancel_bios(struct request_queue *q) { }
+ #else /* CONFIG_BLK_DEV_THROTTLING */
+-int blk_throtl_init(struct request_queue *q);
+-void blk_throtl_exit(struct request_queue *q);
++int blk_throtl_init(struct gendisk *disk);
++void blk_throtl_exit(struct gendisk *disk);
+ void blk_throtl_register_queue(struct request_queue *q);
+ bool __blk_throtl_bio(struct bio *bio);
+ void blk_throtl_cancel_bios(struct request_queue *q);
+diff --git a/block/blk.h b/block/blk.h
+index ff0bec16f0fa0..c24afffc36780 100644
+--- a/block/blk.h
++++ b/block/blk.h
+@@ -429,7 +429,7 @@ static inline struct kmem_cache *blk_get_queue_kmem_cache(bool srcu)
+ }
+ struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu);
+ 
+-int disk_scan_partitions(struct gendisk *disk, fmode_t mode);
++int disk_scan_partitions(struct gendisk *disk, fmode_t mode, void *owner);
+ 
+ int disk_alloc_events(struct gendisk *disk);
+ void disk_add_events(struct gendisk *disk);
+diff --git a/block/genhd.c b/block/genhd.c
+index 28654723bc2b2..a7b9623031957 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -356,7 +356,7 @@ void disk_uevent(struct gendisk *disk, enum kobject_action action)
+ }
+ EXPORT_SYMBOL_GPL(disk_uevent);
+ 
+-int disk_scan_partitions(struct gendisk *disk, fmode_t mode)
++int disk_scan_partitions(struct gendisk *disk, fmode_t mode, void *owner)
+ {
+ 	struct block_device *bdev;
+ 
+@@ -366,6 +366,9 @@ int disk_scan_partitions(struct gendisk *disk, fmode_t mode)
+ 		return -EINVAL;
+ 	if (disk->open_partitions)
+ 		return -EBUSY;
++	/* Someone else has bdev exclusively open? */
++	if (disk->part0->bd_holder && disk->part0->bd_holder != owner)
++		return -EBUSY;
+ 
+ 	set_bit(GD_NEED_PART_SCAN, &disk->state);
+ 	bdev = blkdev_get_by_dev(disk_devt(disk), mode, NULL);
+@@ -499,7 +502,7 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
+ 
+ 		bdev_add(disk->part0, ddev->devt);
+ 		if (get_capacity(disk))
+-			disk_scan_partitions(disk, FMODE_READ);
++			disk_scan_partitions(disk, FMODE_READ, NULL);
+ 
+ 		/*
+ 		 * Announce the disk and partitions after all partitions are
+@@ -1154,7 +1157,8 @@ static void disk_release(struct device *dev)
+ 	    !test_bit(GD_ADDED, &disk->state))
+ 		blk_mq_exit_queue(disk->queue);
+ 
+-	blkcg_exit_queue(disk->queue);
++	blkcg_exit_disk(disk);
++
+ 	bioset_exit(&disk->bio_split);
+ 
+ 	disk_release_events(disk);
+@@ -1367,7 +1371,7 @@ struct gendisk *__alloc_disk_node(struct request_queue *q, int node_id,
+ 	if (xa_insert(&disk->part_tbl, 0, disk->part0, GFP_KERNEL))
+ 		goto out_destroy_part_tbl;
+ 
+-	if (blkcg_init_queue(q))
++	if (blkcg_init_disk(disk))
+ 		goto out_erase_part0;
+ 
+ 	rand_initialize_disk(disk);
+diff --git a/block/ioctl.c b/block/ioctl.c
+index 60121e89052bc..96617512982e5 100644
+--- a/block/ioctl.c
++++ b/block/ioctl.c
+@@ -467,9 +467,10 @@ static int blkdev_bszset(struct block_device *bdev, fmode_t mode,
+  * user space. Note the separate arg/argp parameters that are needed
+  * to deal with the compat_ptr() conversion.
+  */
+-static int blkdev_common_ioctl(struct block_device *bdev, fmode_t mode,
+-				unsigned cmd, unsigned long arg, void __user *argp)
++static int blkdev_common_ioctl(struct file *file, fmode_t mode, unsigned cmd,
++			       unsigned long arg, void __user *argp)
+ {
++	struct block_device *bdev = I_BDEV(file->f_mapping->host);
+ 	unsigned int max_sectors;
+ 
+ 	switch (cmd) {
+@@ -527,7 +528,8 @@ static int blkdev_common_ioctl(struct block_device *bdev, fmode_t mode,
+ 			return -EACCES;
+ 		if (bdev_is_partition(bdev))
+ 			return -EINVAL;
+-		return disk_scan_partitions(bdev->bd_disk, mode & ~FMODE_EXCL);
++		return disk_scan_partitions(bdev->bd_disk, mode & ~FMODE_EXCL,
++					    file);
+ 	case BLKTRACESTART:
+ 	case BLKTRACESTOP:
+ 	case BLKTRACETEARDOWN:
+@@ -605,7 +607,7 @@ long blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+ 		break;
+ 	}
+ 
+-	ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
++	ret = blkdev_common_ioctl(file, mode, cmd, arg, argp);
+ 	if (ret != -ENOIOCTLCMD)
+ 		return ret;
+ 
+@@ -674,7 +676,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+ 		break;
+ 	}
+ 
+-	ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
++	ret = blkdev_common_ioctl(file, mode, cmd, arg, argp);
+ 	if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl)
+ 		ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
+ 
+diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
+index 510cdec375c4d..98daea0db9798 100644
+--- a/drivers/acpi/resource.c
++++ b/drivers/acpi/resource.c
+@@ -399,16 +399,68 @@ static const struct dmi_system_id medion_laptop[] = {
+ 	{ }
+ };
+ 
++static const struct dmi_system_id asus_laptop[] = {
++	{
++		.ident = "Asus Vivobook K3402ZA",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_BOARD_NAME, "K3402ZA"),
++		},
++	},
++	{
++		.ident = "Asus Vivobook K3502ZA",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_BOARD_NAME, "K3502ZA"),
++		},
++	},
++	{ }
++};
++
++static const struct dmi_system_id lenovo_laptop[] = {
++	{
++		.ident = "LENOVO IdeaPad Flex 5 14ALC7",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "82R9"),
++		},
++	},
++	{
++		.ident = "LENOVO IdeaPad Flex 5 16ALC7",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "82RA"),
++		},
++	},
++	{ }
++};
++
++static const struct dmi_system_id schenker_gm_rg[] = {
++	{
++		.ident = "XMG CORE 15 (M22)",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
++			DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
++		},
++	},
++	{ }
++};
++
+ struct irq_override_cmp {
+ 	const struct dmi_system_id *system;
+ 	unsigned char irq;
+ 	unsigned char triggering;
+ 	unsigned char polarity;
+ 	unsigned char shareable;
++	bool override;
+ };
+ 
+-static const struct irq_override_cmp skip_override_table[] = {
+-	{ medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 },
++static const struct irq_override_cmp override_table[] = {
++	{ medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
++	{ asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
++	{ lenovo_laptop, 6, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
++	{ lenovo_laptop, 10, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
++	{ schenker_gm_rg, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true },
+ };
+ 
+ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
+@@ -416,6 +468,17 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
+ {
+ 	int i;
+ 
++	for (i = 0; i < ARRAY_SIZE(override_table); i++) {
++		const struct irq_override_cmp *entry = &override_table[i];
++
++		if (dmi_check_system(entry->system) &&
++		    entry->irq == gsi &&
++		    entry->triggering == triggering &&
++		    entry->polarity == polarity &&
++		    entry->shareable == shareable)
++			return entry->override;
++	}
++
+ #ifdef CONFIG_X86
+ 	/*
+ 	 * IRQ override isn't needed on modern AMD Zen systems and
+@@ -426,17 +489,6 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
+ 		return false;
+ #endif
+ 
+-	for (i = 0; i < ARRAY_SIZE(skip_override_table); i++) {
+-		const struct irq_override_cmp *entry = &skip_override_table[i];
+-
+-		if (dmi_check_system(entry->system) &&
+-		    entry->irq == gsi &&
+-		    entry->triggering == triggering &&
+-		    entry->polarity == polarity &&
+-		    entry->shareable == shareable)
+-			return false;
+-	}
+-
+ 	return true;
+ }
+ 
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index c1eca72b4575d..28d8c56cb4ddf 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -84,6 +84,7 @@ enum board_ids {
+ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+ static void ahci_remove_one(struct pci_dev *dev);
+ static void ahci_shutdown_one(struct pci_dev *dev);
++static void ahci_intel_pcs_quirk(struct pci_dev *pdev, struct ahci_host_priv *hpriv);
+ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
+ 				 unsigned long deadline);
+ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
+@@ -677,6 +678,25 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
+ 	ahci_save_initial_config(&pdev->dev, hpriv);
+ }
+ 
++static int ahci_pci_reset_controller(struct ata_host *host)
++{
++	struct pci_dev *pdev = to_pci_dev(host->dev);
++	struct ahci_host_priv *hpriv = host->private_data;
++	int rc;
++
++	rc = ahci_reset_controller(host);
++	if (rc)
++		return rc;
++
++	/*
++	 * If platform firmware failed to enable ports, try to enable
++	 * them here.
++	 */
++	ahci_intel_pcs_quirk(pdev, hpriv);
++
++	return 0;
++}
++
+ static void ahci_pci_init_controller(struct ata_host *host)
+ {
+ 	struct ahci_host_priv *hpriv = host->private_data;
+@@ -871,7 +891,7 @@ static int ahci_pci_device_runtime_resume(struct device *dev)
+ 	struct ata_host *host = pci_get_drvdata(pdev);
+ 	int rc;
+ 
+-	rc = ahci_reset_controller(host);
++	rc = ahci_pci_reset_controller(host);
+ 	if (rc)
+ 		return rc;
+ 	ahci_pci_init_controller(host);
+@@ -907,7 +927,7 @@ static int ahci_pci_device_resume(struct device *dev)
+ 		ahci_mcp89_apple_enable(pdev);
+ 
+ 	if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
+-		rc = ahci_reset_controller(host);
++		rc = ahci_pci_reset_controller(host);
+ 		if (rc)
+ 			return rc;
+ 
+@@ -1788,12 +1808,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	/* save initial config */
+ 	ahci_pci_save_initial_config(pdev, hpriv);
+ 
+-	/*
+-	 * If platform firmware failed to enable ports, try to enable
+-	 * them here.
+-	 */
+-	ahci_intel_pcs_quirk(pdev, hpriv);
+-
+ 	/* prepare host */
+ 	if (hpriv->cap & HOST_CAP_NCQ) {
+ 		pi.flags |= ATA_FLAG_NCQ;
+@@ -1903,7 +1917,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	if (rc)
+ 		return rc;
+ 
+-	rc = ahci_reset_controller(host);
++	rc = ahci_pci_reset_controller(host);
+ 	if (rc)
+ 		return rc;
+ 
+diff --git a/drivers/char/tpm/eventlog/acpi.c b/drivers/char/tpm/eventlog/acpi.c
+index 1b18ce5ebab1e..0913d3eb8d518 100644
+--- a/drivers/char/tpm/eventlog/acpi.c
++++ b/drivers/char/tpm/eventlog/acpi.c
+@@ -90,16 +90,21 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
+ 			return -ENODEV;
+ 
+ 		if (tbl->header.length <
+-				sizeof(*tbl) + sizeof(struct acpi_tpm2_phy))
++				sizeof(*tbl) + sizeof(struct acpi_tpm2_phy)) {
++			acpi_put_table((struct acpi_table_header *)tbl);
+ 			return -ENODEV;
++		}
+ 
+ 		tpm2_phy = (void *)tbl + sizeof(*tbl);
+ 		len = tpm2_phy->log_area_minimum_length;
+ 
+ 		start = tpm2_phy->log_area_start_address;
+-		if (!start || !len)
++		if (!start || !len) {
++			acpi_put_table((struct acpi_table_header *)tbl);
+ 			return -ENODEV;
++		}
+ 
++		acpi_put_table((struct acpi_table_header *)tbl);
+ 		format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
+ 	} else {
+ 		/* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
+@@ -120,8 +125,10 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
+ 			break;
+ 		}
+ 
++		acpi_put_table((struct acpi_table_header *)buff);
+ 		format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
+ 	}
++
+ 	if (!len) {
+ 		dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__);
+ 		return -EIO;
+@@ -156,5 +163,4 @@ err:
+ 	kfree(log->bios_event_log);
+ 	log->bios_event_log = NULL;
+ 	return ret;
+-
+ }
+diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
+index 65f8f179a27f0..16fc481d60950 100644
+--- a/drivers/char/tpm/tpm_crb.c
++++ b/drivers/char/tpm/tpm_crb.c
+@@ -676,12 +676,16 @@ static int crb_acpi_add(struct acpi_device *device)
+ 
+ 	/* Should the FIFO driver handle this? */
+ 	sm = buf->start_method;
+-	if (sm == ACPI_TPM2_MEMORY_MAPPED)
+-		return -ENODEV;
++	if (sm == ACPI_TPM2_MEMORY_MAPPED) {
++		rc = -ENODEV;
++		goto out;
++	}
+ 
+ 	priv = devm_kzalloc(dev, sizeof(struct crb_priv), GFP_KERNEL);
+-	if (!priv)
+-		return -ENOMEM;
++	if (!priv) {
++		rc = -ENOMEM;
++		goto out;
++	}
+ 
+ 	if (sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) {
+ 		if (buf->header.length < (sizeof(*buf) + sizeof(*crb_smc))) {
+@@ -689,7 +693,8 @@ static int crb_acpi_add(struct acpi_device *device)
+ 				FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n",
+ 				buf->header.length,
+ 				ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC);
+-			return -EINVAL;
++			rc = -EINVAL;
++			goto out;
+ 		}
+ 		crb_smc = ACPI_ADD_PTR(struct tpm2_crb_smc, buf, sizeof(*buf));
+ 		priv->smc_func_id = crb_smc->smc_func_id;
+@@ -700,17 +705,23 @@ static int crb_acpi_add(struct acpi_device *device)
+ 
+ 	rc = crb_map_io(device, priv, buf);
+ 	if (rc)
+-		return rc;
++		goto out;
+ 
+ 	chip = tpmm_chip_alloc(dev, &tpm_crb);
+-	if (IS_ERR(chip))
+-		return PTR_ERR(chip);
++	if (IS_ERR(chip)) {
++		rc = PTR_ERR(chip);
++		goto out;
++	}
+ 
+ 	dev_set_drvdata(&chip->dev, priv);
+ 	chip->acpi_dev_handle = device->handle;
+ 	chip->flags = TPM_CHIP_FLAG_TPM2;
+ 
+-	return tpm_chip_register(chip);
++	rc = tpm_chip_register(chip);
++
++out:
++	acpi_put_table((struct acpi_table_header *)buf);
++	return rc;
+ }
+ 
+ static int crb_acpi_remove(struct acpi_device *device)
+diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
+index bcff6429e0b4f..ed5dabd3c72d6 100644
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -125,6 +125,7 @@ static int check_acpi_tpm2(struct device *dev)
+ 	const struct acpi_device_id *aid = acpi_match_device(tpm_acpi_tbl, dev);
+ 	struct acpi_table_tpm2 *tbl;
+ 	acpi_status st;
++	int ret = 0;
+ 
+ 	if (!aid || aid->driver_data != DEVICE_IS_TPM2)
+ 		return 0;
+@@ -132,8 +133,7 @@ static int check_acpi_tpm2(struct device *dev)
+ 	/* If the ACPI TPM2 signature is matched then a global ACPI_SIG_TPM2
+ 	 * table is mandatory
+ 	 */
+-	st =
+-	    acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl);
++	st = acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl);
+ 	if (ACPI_FAILURE(st) || tbl->header.length < sizeof(*tbl)) {
+ 		dev_err(dev, FW_BUG "failed to get TPM2 ACPI table\n");
+ 		return -EINVAL;
+@@ -141,9 +141,10 @@ static int check_acpi_tpm2(struct device *dev)
+ 
+ 	/* The tpm2_crb driver handles this device */
+ 	if (tbl->start_method != ACPI_TPM2_MEMORY_MAPPED)
+-		return -ENODEV;
++		ret = -ENODEV;
+ 
+-	return 0;
++	acpi_put_table((struct acpi_table_header *)tbl);
++	return ret;
+ }
+ #else
+ static int check_acpi_tpm2(struct device *dev)
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 86e754b9400ff..5680543e97fdc 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -995,7 +995,10 @@
+ #define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S	0x8003
+ 
+ #define USB_VENDOR_ID_PLANTRONICS	0x047f
++#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES	0xc055
+ #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES	0xc056
++#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES	0xc057
++#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES	0xc058
+ 
+ #define USB_VENDOR_ID_PANASONIC		0x04da
+ #define USB_DEVICE_ID_PANABOARD_UBT780	0x1044
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index 91a4d3fc30e08..372cbdd223e09 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -1967,6 +1967,10 @@ static const struct hid_device_id mt_devices[] = {
+ 		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+ 			USB_VENDOR_ID_ELAN, 0x313a) },
+ 
++	{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
++		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
++			USB_VENDOR_ID_ELAN, 0x3148) },
++
+ 	/* Elitegroup panel */
+ 	{ .driver_data = MT_CLS_SERIAL,
+ 		MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
+diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c
+index e81b7cec2d124..3d414ae194acb 100644
+--- a/drivers/hid/hid-plantronics.c
++++ b/drivers/hid/hid-plantronics.c
+@@ -198,9 +198,18 @@ err:
+ }
+ 
+ static const struct hid_device_id plantronics_devices[] = {
++	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
++					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES),
++		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+ 					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES),
+ 		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
++	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
++					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES),
++		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
++	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
++					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
++		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
+ 	{ }
+ };
+diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
+index ec73720e239b2..15fa380b1f84b 100644
+--- a/drivers/iommu/mtk_iommu.c
++++ b/drivers/iommu/mtk_iommu.c
+@@ -452,7 +452,7 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
+ 		fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm];
+ 	}
+ 
+-	if (report_iommu_fault(&dom->domain, bank->parent_dev, fault_iova,
++	if (!dom || report_iommu_fault(&dom->domain, bank->parent_dev, fault_iova,
+ 			       write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
+ 		dev_err_ratelimited(
+ 			bank->parent_dev,
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 470a975e4be9b..cd7f8e6cfc717 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -509,13 +509,14 @@ static void md_end_flush(struct bio *bio)
+ 	struct md_rdev *rdev = bio->bi_private;
+ 	struct mddev *mddev = rdev->mddev;
+ 
++	bio_put(bio);
++
+ 	rdev_dec_pending(rdev, mddev);
+ 
+ 	if (atomic_dec_and_test(&mddev->flush_pending)) {
+ 		/* The pre-request flush has finished */
+ 		queue_work(md_wq, &mddev->flush_work);
+ 	}
+-	bio_put(bio);
+ }
+ 
+ static void md_submit_flush_data(struct work_struct *ws);
+@@ -913,10 +914,12 @@ static void super_written(struct bio *bio)
+ 	} else
+ 		clear_bit(LastDev, &rdev->flags);
+ 
++	bio_put(bio);
++
++	rdev_dec_pending(rdev, mddev);
++
+ 	if (atomic_dec_and_test(&mddev->pending_writes))
+ 		wake_up(&mddev->sb_wait);
+-	rdev_dec_pending(rdev, mddev);
+-	bio_put(bio);
+ }
+ 
+ void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
+diff --git a/drivers/mfd/mt6360-core.c b/drivers/mfd/mt6360-core.c
+index 6eaa6775b8885..d3b32eb798377 100644
+--- a/drivers/mfd/mt6360-core.c
++++ b/drivers/mfd/mt6360-core.c
+@@ -402,7 +402,7 @@ static int mt6360_regmap_read(void *context, const void *reg, size_t reg_size,
+ 	struct mt6360_ddata *ddata = context;
+ 	u8 bank = *(u8 *)reg;
+ 	u8 reg_addr = *(u8 *)(reg + 1);
+-	struct i2c_client *i2c = ddata->i2c[bank];
++	struct i2c_client *i2c;
+ 	bool crc_needed = false;
+ 	u8 *buf;
+ 	int buf_len = MT6360_ALLOC_READ_SIZE(val_size);
+@@ -410,6 +410,11 @@ static int mt6360_regmap_read(void *context, const void *reg, size_t reg_size,
+ 	u8 crc;
+ 	int ret;
+ 
++	if (bank >= MT6360_SLAVE_MAX)
++		return -EINVAL;
++
++	i2c = ddata->i2c[bank];
++
+ 	if (bank == MT6360_SLAVE_PMIC || bank == MT6360_SLAVE_LDO) {
+ 		crc_needed = true;
+ 		ret = mt6360_xlate_pmicldo_addr(&reg_addr, val_size);
+@@ -453,13 +458,18 @@ static int mt6360_regmap_write(void *context, const void *val, size_t val_size)
+ 	struct mt6360_ddata *ddata = context;
+ 	u8 bank = *(u8 *)val;
+ 	u8 reg_addr = *(u8 *)(val + 1);
+-	struct i2c_client *i2c = ddata->i2c[bank];
++	struct i2c_client *i2c;
+ 	bool crc_needed = false;
+ 	u8 *buf;
+ 	int buf_len = MT6360_ALLOC_WRITE_SIZE(val_size);
+ 	int write_size = val_size - MT6360_REGMAP_REG_BYTE_SIZE;
+ 	int ret;
+ 
++	if (bank >= MT6360_SLAVE_MAX)
++		return -EINVAL;
++
++	i2c = ddata->i2c[bank];
++
+ 	if (bank == MT6360_SLAVE_PMIC || bank == MT6360_SLAVE_LDO) {
+ 		crc_needed = true;
+ 		ret = mt6360_xlate_pmicldo_addr(&reg_addr, val_size - MT6360_REGMAP_REG_BYTE_SIZE);
+diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
+index ab36ec4797478..72f65f32abbc7 100644
+--- a/drivers/mmc/host/vub300.c
++++ b/drivers/mmc/host/vub300.c
+@@ -2049,6 +2049,7 @@ static void vub300_enable_sdio_irq(struct mmc_host *mmc, int enable)
+ 		return;
+ 	kref_get(&vub300->kref);
+ 	if (enable) {
++		set_current_state(TASK_RUNNING);
+ 		mutex_lock(&vub300->irq_mutex);
+ 		if (vub300->irqs_queued) {
+ 			vub300->irqs_queued -= 1;
+@@ -2064,6 +2065,7 @@ static void vub300_enable_sdio_irq(struct mmc_host *mmc, int enable)
+ 			vub300_queue_poll_work(vub300, 0);
+ 		}
+ 		mutex_unlock(&vub300->irq_mutex);
++		set_current_state(TASK_INTERRUPTIBLE);
+ 	} else {
+ 		vub300->irq_enabled = 0;
+ 	}
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 6867620bcc986..529b424ef9b26 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -35,7 +35,7 @@
+ #define SQ_SIZE(q)	((q)->q_depth << (q)->sqes)
+ #define CQ_SIZE(q)	((q)->q_depth * sizeof(struct nvme_completion))
+ 
+-#define SGES_PER_PAGE	(PAGE_SIZE / sizeof(struct nvme_sgl_desc))
++#define SGES_PER_PAGE	(NVME_CTRL_PAGE_SIZE / sizeof(struct nvme_sgl_desc))
+ 
+ /*
+  * These can be higher, but we need to ensure that any command doesn't
+@@ -144,9 +144,9 @@ struct nvme_dev {
+ 	mempool_t *iod_mempool;
+ 
+ 	/* shadow doorbell buffer support: */
+-	u32 *dbbuf_dbs;
++	__le32 *dbbuf_dbs;
+ 	dma_addr_t dbbuf_dbs_dma_addr;
+-	u32 *dbbuf_eis;
++	__le32 *dbbuf_eis;
+ 	dma_addr_t dbbuf_eis_dma_addr;
+ 
+ 	/* host memory buffer support: */
+@@ -210,10 +210,10 @@ struct nvme_queue {
+ #define NVMEQ_SQ_CMB		1
+ #define NVMEQ_DELETE_ERROR	2
+ #define NVMEQ_POLLED		3
+-	u32 *dbbuf_sq_db;
+-	u32 *dbbuf_cq_db;
+-	u32 *dbbuf_sq_ei;
+-	u32 *dbbuf_cq_ei;
++	__le32 *dbbuf_sq_db;
++	__le32 *dbbuf_cq_db;
++	__le32 *dbbuf_sq_ei;
++	__le32 *dbbuf_cq_ei;
+ 	struct completion delete_done;
+ };
+ 
+@@ -340,11 +340,11 @@ static inline int nvme_dbbuf_need_event(u16 event_idx, u16 new_idx, u16 old)
+ }
+ 
+ /* Update dbbuf and return true if an MMIO is required */
+-static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
+-					      volatile u32 *dbbuf_ei)
++static bool nvme_dbbuf_update_and_check_event(u16 value, __le32 *dbbuf_db,
++					      volatile __le32 *dbbuf_ei)
+ {
+ 	if (dbbuf_db) {
+-		u16 old_value;
++		u16 old_value, event_idx;
+ 
+ 		/*
+ 		 * Ensure that the queue is written before updating
+@@ -352,8 +352,8 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
+ 		 */
+ 		wmb();
+ 
+-		old_value = *dbbuf_db;
+-		*dbbuf_db = value;
++		old_value = le32_to_cpu(*dbbuf_db);
++		*dbbuf_db = cpu_to_le32(value);
+ 
+ 		/*
+ 		 * Ensure that the doorbell is updated before reading the event
+@@ -363,7 +363,8 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
+ 		 */
+ 		mb();
+ 
+-		if (!nvme_dbbuf_need_event(*dbbuf_ei, value, old_value))
++		event_idx = le32_to_cpu(*dbbuf_ei);
++		if (!nvme_dbbuf_need_event(event_idx, value, old_value))
+ 			return false;
+ 	}
+ 
+@@ -377,9 +378,9 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
+  */
+ static int nvme_pci_npages_prp(void)
+ {
+-	unsigned nprps = DIV_ROUND_UP(NVME_MAX_KB_SZ + NVME_CTRL_PAGE_SIZE,
+-				      NVME_CTRL_PAGE_SIZE);
+-	return DIV_ROUND_UP(8 * nprps, PAGE_SIZE - 8);
++	unsigned max_bytes = (NVME_MAX_KB_SZ * 1024) + NVME_CTRL_PAGE_SIZE;
++	unsigned nprps = DIV_ROUND_UP(max_bytes, NVME_CTRL_PAGE_SIZE);
++	return DIV_ROUND_UP(8 * nprps, NVME_CTRL_PAGE_SIZE - 8);
+ }
+ 
+ /*
+@@ -389,7 +390,7 @@ static int nvme_pci_npages_prp(void)
+ static int nvme_pci_npages_sgl(void)
+ {
+ 	return DIV_ROUND_UP(NVME_MAX_SEGS * sizeof(struct nvme_sgl_desc),
+-			PAGE_SIZE);
++			NVME_CTRL_PAGE_SIZE);
+ }
+ 
+ static size_t nvme_pci_iod_alloc_size(void)
+@@ -720,7 +721,7 @@ static void nvme_pci_sgl_set_seg(struct nvme_sgl_desc *sge,
+ 		sge->length = cpu_to_le32(entries * sizeof(*sge));
+ 		sge->type = NVME_SGL_FMT_LAST_SEG_DESC << 4;
+ 	} else {
+-		sge->length = cpu_to_le32(PAGE_SIZE);
++		sge->length = cpu_to_le32(NVME_CTRL_PAGE_SIZE);
+ 		sge->type = NVME_SGL_FMT_SEG_DESC << 4;
+ 	}
+ }
+diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c
+index 94d3153bae54d..09537000d817d 100644
+--- a/drivers/nvme/target/passthru.c
++++ b/drivers/nvme/target/passthru.c
+@@ -333,14 +333,13 @@ static void nvmet_passthru_execute_cmd(struct nvmet_req *req)
+ 	}
+ 
+ 	/*
+-	 * If there are effects for the command we are about to execute, or
+-	 * an end_req function we need to use nvme_execute_passthru_rq()
+-	 * synchronously in a work item seeing the end_req function and
+-	 * nvme_passthru_end() can't be called in the request done callback
+-	 * which is typically in interrupt context.
++	 * If a command needs post-execution fixups, or there are any
++	 * non-trivial effects, make sure to execute the command synchronously
++	 * in a workqueue so that nvme_passthru_end gets called.
+ 	 */
+ 	effects = nvme_command_effects(ctrl, ns, req->cmd->common.opcode);
+-	if (req->p.use_workqueue || effects) {
++	if (req->p.use_workqueue ||
++	    (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC))) {
+ 		INIT_WORK(&req->p.work, nvmet_passthru_execute_cmd_work);
+ 		req->p.rq = rq;
+ 		queue_work(nvmet_wq, &req->p.work);
+diff --git a/drivers/rtc/rtc-msc313.c b/drivers/rtc/rtc-msc313.c
+index f3fde013c4b8b..8d7737e0e2e02 100644
+--- a/drivers/rtc/rtc-msc313.c
++++ b/drivers/rtc/rtc-msc313.c
+@@ -212,22 +212,12 @@ static int msc313_rtc_probe(struct platform_device *pdev)
+ 		return ret;
+ 	}
+ 
+-	clk = devm_clk_get(dev, NULL);
++	clk = devm_clk_get_enabled(dev, NULL);
+ 	if (IS_ERR(clk)) {
+ 		dev_err(dev, "No input reference clock\n");
+ 		return PTR_ERR(clk);
+ 	}
+ 
+-	ret = clk_prepare_enable(clk);
+-	if (ret) {
+-		dev_err(dev, "Failed to enable the reference clock, %d\n", ret);
+-		return ret;
+-	}
+-
+-	ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, clk);
+-	if (ret)
+-		return ret;
+-
+ 	rate = clk_get_rate(clk);
+ 	writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
+ 	writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
+diff --git a/drivers/soundwire/dmi-quirks.c b/drivers/soundwire/dmi-quirks.c
+index f81cdd83ec26e..7969881f126dc 100644
+--- a/drivers/soundwire/dmi-quirks.c
++++ b/drivers/soundwire/dmi-quirks.c
+@@ -90,6 +90,14 @@ static const struct dmi_system_id adr_remap_quirk_table[] = {
+ 		},
+ 		.driver_data = (void *)intel_tgl_bios,
+ 	},
++	{
++		/* quirk used for NUC15 LAPBC710 skew */
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
++			DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"),
++		},
++		.driver_data = (void *)intel_tgl_bios,
++	},
+ 	{
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c
+index d3f3937d70052..e7d37b6000ad9 100644
+--- a/drivers/usb/dwc3/dwc3-qcom.c
++++ b/drivers/usb/dwc3/dwc3-qcom.c
+@@ -260,7 +260,8 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
+ 	if (IS_ERR(qcom->icc_path_apps)) {
+ 		dev_err(dev, "failed to get apps-usb path: %ld\n",
+ 				PTR_ERR(qcom->icc_path_apps));
+-		return PTR_ERR(qcom->icc_path_apps);
++		ret = PTR_ERR(qcom->icc_path_apps);
++		goto put_path_ddr;
+ 	}
+ 
+ 	if (usb_get_maximum_speed(&qcom->dwc3->dev) >= USB_SPEED_SUPER ||
+@@ -273,17 +274,23 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
+ 
+ 	if (ret) {
+ 		dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret);
+-		return ret;
++		goto put_path_apps;
+ 	}
+ 
+ 	ret = icc_set_bw(qcom->icc_path_apps,
+ 		APPS_USB_AVG_BW, APPS_USB_PEAK_BW);
+ 	if (ret) {
+ 		dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret);
+-		return ret;
++		goto put_path_apps;
+ 	}
+ 
+ 	return 0;
++
++put_path_apps:
++	icc_put(qcom->icc_path_apps);
++put_path_ddr:
++	icc_put(qcom->icc_path_ddr);
++	return ret;
+ }
+ 
+ /**
+diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
+index 08d0c8797828c..9ce5e1f41c26f 100644
+--- a/fs/binfmt_elf_fdpic.c
++++ b/fs/binfmt_elf_fdpic.c
+@@ -434,8 +434,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
+ 	current->mm->start_stack = current->mm->start_brk + stack_size;
+ #endif
+ 
+-	if (create_elf_fdpic_tables(bprm, current->mm,
+-				    &exec_params, &interp_params) < 0)
++	retval = create_elf_fdpic_tables(bprm, current->mm, &exec_params,
++					 &interp_params);
++	if (retval < 0)
+ 		goto error;
+ 
+ 	kdebug("- start_code  %lx", current->mm->start_code);
+diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
+index 4992b43616a7a..ba6cc50af390f 100644
+--- a/fs/cifs/smb2file.c
++++ b/fs/cifs/smb2file.c
+@@ -122,8 +122,8 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32
+ 		struct smb2_hdr *hdr = err_iov.iov_base;
+ 
+ 		if (unlikely(!err_iov.iov_base || err_buftype == CIFS_NO_BUFFER))
+-			rc = -ENOMEM;
+-		else if (hdr->Status == STATUS_STOPPED_ON_SYMLINK && oparms->cifs_sb) {
++			goto out;
++		if (hdr->Status == STATUS_STOPPED_ON_SYMLINK) {
+ 			rc = smb2_parse_symlink_response(oparms->cifs_sb, &err_iov,
+ 							 &data->symlink_target);
+ 			if (!rc) {
+diff --git a/fs/eventfd.c b/fs/eventfd.c
+index c0ffee99ad238..249ca6c0b7843 100644
+--- a/fs/eventfd.c
++++ b/fs/eventfd.c
+@@ -43,21 +43,7 @@ struct eventfd_ctx {
+ 	int id;
+ };
+ 
+-/**
+- * eventfd_signal - Adds @n to the eventfd counter.
+- * @ctx: [in] Pointer to the eventfd context.
+- * @n: [in] Value of the counter to be added to the eventfd internal counter.
+- *          The value cannot be negative.
+- *
+- * This function is supposed to be called by the kernel in paths that do not
+- * allow sleeping. In this function we allow the counter to reach the ULLONG_MAX
+- * value, and we signal this as overflow condition by returning a EPOLLERR
+- * to poll(2).
+- *
+- * Returns the amount by which the counter was incremented.  This will be less
+- * than @n if the counter has overflowed.
+- */
+-__u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
++__u64 eventfd_signal_mask(struct eventfd_ctx *ctx, __u64 n, unsigned mask)
+ {
+ 	unsigned long flags;
+ 
+@@ -78,12 +64,31 @@ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
+ 		n = ULLONG_MAX - ctx->count;
+ 	ctx->count += n;
+ 	if (waitqueue_active(&ctx->wqh))
+-		wake_up_locked_poll(&ctx->wqh, EPOLLIN);
++		wake_up_locked_poll(&ctx->wqh, EPOLLIN | mask);
+ 	current->in_eventfd = 0;
+ 	spin_unlock_irqrestore(&ctx->wqh.lock, flags);
+ 
+ 	return n;
+ }
++
++/**
++ * eventfd_signal - Adds @n to the eventfd counter.
++ * @ctx: [in] Pointer to the eventfd context.
++ * @n: [in] Value of the counter to be added to the eventfd internal counter.
++ *          The value cannot be negative.
++ *
++ * This function is supposed to be called by the kernel in paths that do not
++ * allow sleeping. In this function we allow the counter to reach the ULLONG_MAX
++ * value, and we signal this as overflow condition by returning a EPOLLERR
++ * to poll(2).
++ *
++ * Returns the amount by which the counter was incremented.  This will be less
++ * than @n if the counter has overflowed.
++ */
++__u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
++{
++	return eventfd_signal_mask(ctx, n, 0);
++}
+ EXPORT_SYMBOL_GPL(eventfd_signal);
+ 
+ static void eventfd_free_ctx(struct eventfd_ctx *ctx)
+diff --git a/fs/eventpoll.c b/fs/eventpoll.c
+index 8b56b94e2f56f..1b23cc16f957f 100644
+--- a/fs/eventpoll.c
++++ b/fs/eventpoll.c
+@@ -491,7 +491,8 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
+  */
+ #ifdef CONFIG_DEBUG_LOCK_ALLOC
+ 
+-static void ep_poll_safewake(struct eventpoll *ep, struct epitem *epi)
++static void ep_poll_safewake(struct eventpoll *ep, struct epitem *epi,
++			     unsigned pollflags)
+ {
+ 	struct eventpoll *ep_src;
+ 	unsigned long flags;
+@@ -522,16 +523,17 @@ static void ep_poll_safewake(struct eventpoll *ep, struct epitem *epi)
+ 	}
+ 	spin_lock_irqsave_nested(&ep->poll_wait.lock, flags, nests);
+ 	ep->nests = nests + 1;
+-	wake_up_locked_poll(&ep->poll_wait, EPOLLIN);
++	wake_up_locked_poll(&ep->poll_wait, EPOLLIN | pollflags);
+ 	ep->nests = 0;
+ 	spin_unlock_irqrestore(&ep->poll_wait.lock, flags);
+ }
+ 
+ #else
+ 
+-static void ep_poll_safewake(struct eventpoll *ep, struct epitem *epi)
++static void ep_poll_safewake(struct eventpoll *ep, struct epitem *epi,
++			     unsigned pollflags)
+ {
+-	wake_up_poll(&ep->poll_wait, EPOLLIN);
++	wake_up_poll(&ep->poll_wait, EPOLLIN | pollflags);
+ }
+ 
+ #endif
+@@ -742,7 +744,7 @@ static void ep_free(struct eventpoll *ep)
+ 
+ 	/* We need to release all tasks waiting for these file */
+ 	if (waitqueue_active(&ep->poll_wait))
+-		ep_poll_safewake(ep, NULL);
++		ep_poll_safewake(ep, NULL, 0);
+ 
+ 	/*
+ 	 * We need to lock this because we could be hit by
+@@ -1208,7 +1210,7 @@ out_unlock:
+ 
+ 	/* We have to call this outside the lock */
+ 	if (pwake)
+-		ep_poll_safewake(ep, epi);
++		ep_poll_safewake(ep, epi, pollflags & EPOLL_URING_WAKE);
+ 
+ 	if (!(epi->event.events & EPOLLEXCLUSIVE))
+ 		ewake = 1;
+@@ -1553,7 +1555,7 @@ static int ep_insert(struct eventpoll *ep, const struct epoll_event *event,
+ 
+ 	/* We have to call this outside the lock */
+ 	if (pwake)
+-		ep_poll_safewake(ep, NULL);
++		ep_poll_safewake(ep, NULL, 0);
+ 
+ 	return 0;
+ }
+@@ -1629,7 +1631,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi,
+ 
+ 	/* We have to call this outside the lock */
+ 	if (pwake)
+-		ep_poll_safewake(ep, NULL);
++		ep_poll_safewake(ep, NULL, 0);
+ 
+ 	return 0;
+ }
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 68eb1d33128be..d58100dc6e898 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1109,6 +1109,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+ 	if (ofs_in_node >= max_addrs) {
+ 		f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u",
+ 			ofs_in_node, dni->ino, dni->nid, max_addrs);
++		f2fs_put_page(node_page, 1);
+ 		return false;
+ 	}
+ 
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index e06a0c478b39a..f168dce9b5861 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -1358,8 +1358,7 @@ static int read_node_page(struct page *page, blk_opf_t op_flags)
+ 		return err;
+ 
+ 	/* NEW_ADDR can be seen, after cp_error drops some dirty node pages */
+-	if (unlikely(ni.blk_addr == NULL_ADDR || ni.blk_addr == NEW_ADDR) ||
+-			is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN)) {
++	if (unlikely(ni.blk_addr == NULL_ADDR || ni.blk_addr == NEW_ADDR)) {
+ 		ClearPageUptodate(page);
+ 		return -ENOENT;
+ 	}
+diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
+index a5db2e3b29801..6aa919e594834 100644
+--- a/fs/hfsplus/hfsplus_fs.h
++++ b/fs/hfsplus/hfsplus_fs.h
+@@ -198,6 +198,8 @@ struct hfsplus_sb_info {
+ #define HFSPLUS_SB_HFSX		3
+ #define HFSPLUS_SB_CASEFOLD	4
+ #define HFSPLUS_SB_NOBARRIER	5
++#define HFSPLUS_SB_UID		6
++#define HFSPLUS_SB_GID		7
+ 
+ static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb)
+ {
+diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
+index aeab83ed1c9c6..b675581aa9d0f 100644
+--- a/fs/hfsplus/inode.c
++++ b/fs/hfsplus/inode.c
+@@ -192,11 +192,11 @@ static void hfsplus_get_perms(struct inode *inode,
+ 	mode = be16_to_cpu(perms->mode);
+ 
+ 	i_uid_write(inode, be32_to_cpu(perms->owner));
+-	if (!i_uid_read(inode) && !mode)
++	if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode))
+ 		inode->i_uid = sbi->uid;
+ 
+ 	i_gid_write(inode, be32_to_cpu(perms->group));
+-	if (!i_gid_read(inode) && !mode)
++	if ((test_bit(HFSPLUS_SB_GID, &sbi->flags)) || (!i_gid_read(inode) && !mode))
+ 		inode->i_gid = sbi->gid;
+ 
+ 	if (dir) {
+diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c
+index 047e05c575601..c94a58762ad6d 100644
+--- a/fs/hfsplus/options.c
++++ b/fs/hfsplus/options.c
+@@ -140,6 +140,8 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
+ 			if (!uid_valid(sbi->uid)) {
+ 				pr_err("invalid uid specified\n");
+ 				return 0;
++			} else {
++				set_bit(HFSPLUS_SB_UID, &sbi->flags);
+ 			}
+ 			break;
+ 		case opt_gid:
+@@ -151,6 +153,8 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
+ 			if (!gid_valid(sbi->gid)) {
+ 				pr_err("invalid gid specified\n");
+ 				return 0;
++			} else {
++				set_bit(HFSPLUS_SB_GID, &sbi->flags);
+ 			}
+ 			break;
+ 		case opt_part:
+diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
+index 71f870d497aed..578c2bcfb1d93 100644
+--- a/fs/ntfs3/attrib.c
++++ b/fs/ntfs3/attrib.c
+@@ -101,6 +101,10 @@ static int attr_load_runs(struct ATTRIB *attr, struct ntfs_inode *ni,
+ 
+ 	asize = le32_to_cpu(attr->size);
+ 	run_off = le16_to_cpu(attr->nres.run_off);
++
++	if (run_off > asize)
++		return -EINVAL;
++
+ 	err = run_unpack_ex(run, ni->mi.sbi, ni->mi.rno, svcn, evcn,
+ 			    vcn ? *vcn : svcn, Add2Ptr(attr, run_off),
+ 			    asize - run_off);
+@@ -1217,6 +1221,11 @@ int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
+ 	CLST svcn, evcn;
+ 	u16 ro;
+ 
++	if (!ni) {
++		/* Is record corrupted? */
++		return -ENOENT;
++	}
++
+ 	attr = ni_find_attr(ni, NULL, NULL, type, name, name_len, &vcn, NULL);
+ 	if (!attr) {
+ 		/* Is record corrupted? */
+@@ -1232,6 +1241,10 @@ int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
+ 	}
+ 
+ 	ro = le16_to_cpu(attr->nres.run_off);
++
++	if (ro > le32_to_cpu(attr->size))
++		return -EINVAL;
++
+ 	err = run_unpack_ex(run, ni->mi.sbi, ni->mi.rno, svcn, evcn, svcn,
+ 			    Add2Ptr(attr, ro), le32_to_cpu(attr->size) - ro);
+ 	if (err < 0)
+@@ -1901,6 +1914,11 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
+ 			u16 le_sz;
+ 			u16 roff = le16_to_cpu(attr->nres.run_off);
+ 
++			if (roff > le32_to_cpu(attr->size)) {
++				err = -EINVAL;
++				goto out;
++			}
++
+ 			run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn,
+ 				      evcn1 - 1, svcn, Add2Ptr(attr, roff),
+ 				      le32_to_cpu(attr->size) - roff);
+diff --git a/fs/ntfs3/attrlist.c b/fs/ntfs3/attrlist.c
+index bad6d8a849a24..c0c6bcbc8c05c 100644
+--- a/fs/ntfs3/attrlist.c
++++ b/fs/ntfs3/attrlist.c
+@@ -68,6 +68,11 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr)
+ 
+ 		run_init(&ni->attr_list.run);
+ 
++		if (run_off > le32_to_cpu(attr->size)) {
++			err = -EINVAL;
++			goto out;
++		}
++
+ 		err = run_unpack_ex(&ni->attr_list.run, ni->mi.sbi, ni->mi.rno,
+ 				    0, le64_to_cpu(attr->nres.evcn), 0,
+ 				    Add2Ptr(attr, run_off),
+diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c
+index 087282cb130b7..bb29bc1782fb2 100644
+--- a/fs/ntfs3/bitmap.c
++++ b/fs/ntfs3/bitmap.c
+@@ -661,7 +661,7 @@ int wnd_init(struct wnd_bitmap *wnd, struct super_block *sb, size_t nbits)
+ 	if (!wnd->bits_last)
+ 		wnd->bits_last = wbits;
+ 
+-	wnd->free_bits = kcalloc(wnd->nwnd, sizeof(u16), GFP_NOFS);
++	wnd->free_bits = kcalloc(wnd->nwnd, sizeof(u16), GFP_NOFS | __GFP_NOWARN);
+ 	if (!wnd->free_bits)
+ 		return -ENOMEM;
+ 
+diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
+index 381a38a06ec22..b1b476fb7229b 100644
+--- a/fs/ntfs3/frecord.c
++++ b/fs/ntfs3/frecord.c
+@@ -568,6 +568,12 @@ static int ni_repack(struct ntfs_inode *ni)
+ 		}
+ 
+ 		roff = le16_to_cpu(attr->nres.run_off);
++
++		if (roff > le32_to_cpu(attr->size)) {
++			err = -EINVAL;
++			break;
++		}
++
+ 		err = run_unpack(&run, sbi, ni->mi.rno, svcn, evcn, svcn,
+ 				 Add2Ptr(attr, roff),
+ 				 le32_to_cpu(attr->size) - roff);
+@@ -1589,6 +1595,9 @@ int ni_delete_all(struct ntfs_inode *ni)
+ 		asize = le32_to_cpu(attr->size);
+ 		roff = le16_to_cpu(attr->nres.run_off);
+ 
++		if (roff > asize)
++			return -EINVAL;
++
+ 		/* run==1 means unpack and deallocate. */
+ 		run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
+ 			      Add2Ptr(attr, roff), asize - roff);
+@@ -2291,6 +2300,11 @@ remove_wof:
+ 		asize = le32_to_cpu(attr->size);
+ 		roff = le16_to_cpu(attr->nres.run_off);
+ 
++		if (roff > asize) {
++			err = -EINVAL;
++			goto out;
++		}
++
+ 		/*run==1  Means unpack and deallocate. */
+ 		run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
+ 			      Add2Ptr(attr, roff), asize - roff);
+diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
+index e7c494005122c..4236194af35ee 100644
+--- a/fs/ntfs3/fslog.c
++++ b/fs/ntfs3/fslog.c
+@@ -1132,7 +1132,7 @@ static int read_log_page(struct ntfs_log *log, u32 vbo,
+ 		return -EINVAL;
+ 
+ 	if (!*buffer) {
+-		to_free = kmalloc(bytes, GFP_NOFS);
++		to_free = kmalloc(log->page_size, GFP_NOFS);
+ 		if (!to_free)
+ 			return -ENOMEM;
+ 		*buffer = to_free;
+@@ -1180,10 +1180,7 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
+ 			struct restart_info *info)
+ {
+ 	u32 skip, vbo;
+-	struct RESTART_HDR *r_page = kmalloc(DefaultLogPageSize, GFP_NOFS);
+-
+-	if (!r_page)
+-		return -ENOMEM;
++	struct RESTART_HDR *r_page = NULL;
+ 
+ 	/* Determine which restart area we are looking for. */
+ 	if (first) {
+@@ -1197,7 +1194,6 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
+ 	/* Loop continuously until we succeed. */
+ 	for (; vbo < l_size; vbo = 2 * vbo + skip, skip = 0) {
+ 		bool usa_error;
+-		u32 sys_page_size;
+ 		bool brst, bchk;
+ 		struct RESTART_AREA *ra;
+ 
+@@ -1251,24 +1247,6 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
+ 			goto check_result;
+ 		}
+ 
+-		/* Read the entire restart area. */
+-		sys_page_size = le32_to_cpu(r_page->sys_page_size);
+-		if (DefaultLogPageSize != sys_page_size) {
+-			kfree(r_page);
+-			r_page = kzalloc(sys_page_size, GFP_NOFS);
+-			if (!r_page)
+-				return -ENOMEM;
+-
+-			if (read_log_page(log, vbo,
+-					  (struct RECORD_PAGE_HDR **)&r_page,
+-					  &usa_error)) {
+-				/* Ignore any errors. */
+-				kfree(r_page);
+-				r_page = NULL;
+-				continue;
+-			}
+-		}
+-
+ 		if (is_client_area_valid(r_page, usa_error)) {
+ 			info->valid_page = true;
+ 			ra = Add2Ptr(r_page, le16_to_cpu(r_page->ra_off));
+@@ -2727,6 +2705,9 @@ static inline bool check_attr(const struct MFT_REC *rec,
+ 			return false;
+ 		}
+ 
++		if (run_off > asize)
++			return false;
++
+ 		if (run_unpack(NULL, sbi, 0, svcn, evcn, svcn,
+ 			       Add2Ptr(attr, run_off), asize - run_off) < 0) {
+ 			return false;
+@@ -4771,6 +4752,12 @@ fake_attr:
+ 		u16 roff = le16_to_cpu(attr->nres.run_off);
+ 		CLST svcn = le64_to_cpu(attr->nres.svcn);
+ 
++		if (roff > t32) {
++			kfree(oa->attr);
++			oa->attr = NULL;
++			goto fake_attr;
++		}
++
+ 		err = run_unpack(&oa->run0, sbi, inode->i_ino, svcn,
+ 				 le64_to_cpu(attr->nres.evcn), svcn,
+ 				 Add2Ptr(attr, roff), t32 - roff);
+diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c
+index 4ed15f64b17f6..b6e22bcb929ba 100644
+--- a/fs/ntfs3/fsntfs.c
++++ b/fs/ntfs3/fsntfs.c
+@@ -1849,9 +1849,10 @@ int ntfs_security_init(struct ntfs_sb_info *sbi)
+ 		goto out;
+ 	}
+ 
+-	root_sdh = resident_data(attr);
++	root_sdh = resident_data_ex(attr, sizeof(struct INDEX_ROOT));
+ 	if (root_sdh->type != ATTR_ZERO ||
+-	    root_sdh->rule != NTFS_COLLATION_TYPE_SECURITY_HASH) {
++	    root_sdh->rule != NTFS_COLLATION_TYPE_SECURITY_HASH ||
++	    offsetof(struct INDEX_ROOT, ihdr) + root_sdh->ihdr.used > attr->res.data_size) {
+ 		err = -EINVAL;
+ 		goto out;
+ 	}
+@@ -1867,9 +1868,10 @@ int ntfs_security_init(struct ntfs_sb_info *sbi)
+ 		goto out;
+ 	}
+ 
+-	root_sii = resident_data(attr);
++	root_sii = resident_data_ex(attr, sizeof(struct INDEX_ROOT));
+ 	if (root_sii->type != ATTR_ZERO ||
+-	    root_sii->rule != NTFS_COLLATION_TYPE_UINT) {
++	    root_sii->rule != NTFS_COLLATION_TYPE_UINT ||
++	    offsetof(struct INDEX_ROOT, ihdr) + root_sii->ihdr.used > attr->res.data_size) {
+ 		err = -EINVAL;
+ 		goto out;
+ 	}
+diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c
+index 440328147e7e3..c27b4fe575136 100644
+--- a/fs/ntfs3/index.c
++++ b/fs/ntfs3/index.c
+@@ -1017,6 +1017,12 @@ ok:
+ 		err = 0;
+ 	}
+ 
++	/* check for index header length */
++	if (offsetof(struct INDEX_BUFFER, ihdr) + ib->ihdr.used > bytes) {
++		err = -EINVAL;
++		goto out;
++	}
++
+ 	in->index = ib;
+ 	*node = in;
+ 
+diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
+index 26a76ebfe58fc..471ea4d813ad8 100644
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -129,6 +129,9 @@ next_attr:
+ 	rsize = attr->non_res ? 0 : le32_to_cpu(attr->res.data_size);
+ 	asize = le32_to_cpu(attr->size);
+ 
++	if (le16_to_cpu(attr->name_off) + attr->name_len > asize)
++		goto out;
++
+ 	switch (attr->type) {
+ 	case ATTR_STD:
+ 		if (attr->non_res ||
+@@ -364,7 +367,13 @@ next_attr:
+ attr_unpack_run:
+ 	roff = le16_to_cpu(attr->nres.run_off);
+ 
++	if (roff > asize) {
++		err = -EINVAL;
++		goto out;
++	}
++
+ 	t64 = le64_to_cpu(attr->nres.svcn);
++
+ 	err = run_unpack_ex(run, sbi, ino, t64, le64_to_cpu(attr->nres.evcn),
+ 			    t64, Add2Ptr(attr, roff), asize - roff);
+ 	if (err < 0)
+diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c
+index 7d2fac5ee2156..af1e4b364ea8e 100644
+--- a/fs/ntfs3/record.c
++++ b/fs/ntfs3/record.c
+@@ -220,6 +220,11 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
+ 			return NULL;
+ 		}
+ 
++		if (off + asize < off) {
++			/* overflow check */
++			return NULL;
++		}
++
+ 		attr = Add2Ptr(attr, asize);
+ 		off += asize;
+ 	}
+@@ -260,6 +265,11 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
+ 		if (t16 + t32 > asize)
+ 			return NULL;
+ 
++		if (attr->name_len &&
++		    le16_to_cpu(attr->name_off) + sizeof(short) * attr->name_len > t16) {
++			return NULL;
++		}
++
+ 		return attr;
+ 	}
+ 
+diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
+index adc4f73722b7c..8e2fe0f69203b 100644
+--- a/fs/ntfs3/super.c
++++ b/fs/ntfs3/super.c
+@@ -789,7 +789,7 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
+ 						 : (u32)boot->record_size
+ 							   << sbi->cluster_bits;
+ 
+-	if (record_size > MAXIMUM_BYTES_PER_MFT)
++	if (record_size > MAXIMUM_BYTES_PER_MFT || record_size < SECTOR_SIZE)
+ 		goto out;
+ 
+ 	sbi->record_bits = blksize_bits(record_size);
+@@ -1141,7 +1141,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
+ 		goto put_inode_out;
+ 	}
+ 	bytes = inode->i_size;
+-	sbi->def_table = t = kmalloc(bytes, GFP_NOFS);
++	sbi->def_table = t = kmalloc(bytes, GFP_NOFS | __GFP_NOWARN);
+ 	if (!t) {
+ 		err = -ENOMEM;
+ 		goto put_inode_out;
+@@ -1260,9 +1260,9 @@ load_root:
+ 	ref.low = cpu_to_le32(MFT_REC_ROOT);
+ 	ref.seq = cpu_to_le16(MFT_REC_ROOT);
+ 	inode = ntfs_iget5(sb, &ref, &NAME_ROOT);
+-	if (IS_ERR(inode)) {
++	if (IS_ERR(inode) || !inode->i_op) {
+ 		ntfs_err(sb, "Failed to load root.");
+-		err = PTR_ERR(inode);
++		err = IS_ERR(inode) ? PTR_ERR(inode) : -EINVAL;
+ 		goto out;
+ 	}
+ 
+@@ -1281,6 +1281,7 @@ out:
+ 	 * Free resources here.
+ 	 * ntfs_fs_free will be called with fc->s_fs_info = NULL
+ 	 */
++	put_mount_options(sbi->options);
+ 	put_ntfs(sbi);
+ 	sb->s_fs_info = NULL;
+ 
+diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
+index 6b03457f72bb1..c3032cef391ef 100644
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -592,28 +592,42 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
+ 			goto out_revert_creds;
+ 	}
+ 
+-	err = -ENOMEM;
+-	override_cred = prepare_creds();
+-	if (override_cred) {
++	if (!attr->hardlink) {
++		err = -ENOMEM;
++		override_cred = prepare_creds();
++		if (!override_cred)
++			goto out_revert_creds;
++		/*
++		 * In the creation cases(create, mkdir, mknod, symlink),
++		 * ovl should transfer current's fs{u,g}id to underlying
++		 * fs. Because underlying fs want to initialize its new
++		 * inode owner using current's fs{u,g}id. And in this
++		 * case, the @inode is a new inode that is initialized
++		 * in inode_init_owner() to current's fs{u,g}id. So use
++		 * the inode's i_{u,g}id to override the cred's fs{u,g}id.
++		 *
++		 * But in the other hardlink case, ovl_link() does not
++		 * create a new inode, so just use the ovl mounter's
++		 * fs{u,g}id.
++		 */
+ 		override_cred->fsuid = inode->i_uid;
+ 		override_cred->fsgid = inode->i_gid;
+-		if (!attr->hardlink) {
+-			err = security_dentry_create_files_as(dentry,
+-					attr->mode, &dentry->d_name, old_cred,
+-					override_cred);
+-			if (err) {
+-				put_cred(override_cred);
+-				goto out_revert_creds;
+-			}
++		err = security_dentry_create_files_as(dentry,
++				attr->mode, &dentry->d_name, old_cred,
++				override_cred);
++		if (err) {
++			put_cred(override_cred);
++			goto out_revert_creds;
+ 		}
+ 		put_cred(override_creds(override_cred));
+ 		put_cred(override_cred);
+-
+-		if (!ovl_dentry_is_whiteout(dentry))
+-			err = ovl_create_upper(dentry, inode, attr);
+-		else
+-			err = ovl_create_over_whiteout(dentry, inode, attr);
+ 	}
++
++	if (!ovl_dentry_is_whiteout(dentry))
++		err = ovl_create_upper(dentry, inode, attr);
++	else
++		err = ovl_create_over_whiteout(dentry, inode, attr);
++
+ out_revert_creds:
+ 	revert_creds(old_cred);
+ 	return err;
+diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
+index a34f8042724ce..172cde9d2e569 100644
+--- a/fs/overlayfs/file.c
++++ b/fs/overlayfs/file.c
+@@ -96,6 +96,7 @@ static int ovl_change_flags(struct file *file, unsigned int flags)
+ 
+ 	spin_lock(&file->f_lock);
+ 	file->f_flags = (file->f_flags & ~OVL_SETFL_MASK) | flags;
++	file->f_iocb_flags = iocb_flags(file);
+ 	spin_unlock(&file->f_lock);
+ 
+ 	return 0;
+diff --git a/fs/pnode.c b/fs/pnode.c
+index 1106137c747a3..468e4e65a615d 100644
+--- a/fs/pnode.c
++++ b/fs/pnode.c
+@@ -244,7 +244,7 @@ static int propagate_one(struct mount *m)
+ 		}
+ 		do {
+ 			struct mount *parent = last_source->mnt_parent;
+-			if (last_source == first_source)
++			if (peers(last_source, first_source))
+ 				break;
+ 			done = parent->mnt_master == p;
+ 			if (done && peers(n, parent))
+diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
+index 74e4d93f3e08d..f3fa3625d772c 100644
+--- a/fs/pstore/ram.c
++++ b/fs/pstore/ram.c
+@@ -670,7 +670,7 @@ static int ramoops_parse_dt(struct platform_device *pdev,
+ 		field = value;						\
+ 	}
+ 
+-	parse_u32("mem-type", pdata->record_size, pdata->mem_type);
++	parse_u32("mem-type", pdata->mem_type, pdata->mem_type);
+ 	parse_u32("record-size", pdata->record_size, 0);
+ 	parse_u32("console-size", pdata->console_size, 0);
+ 	parse_u32("ftrace-size", pdata->ftrace_size, 0);
+diff --git a/fs/pstore/zone.c b/fs/pstore/zone.c
+index 017d0d4ad3295..2770746bb7aa1 100644
+--- a/fs/pstore/zone.c
++++ b/fs/pstore/zone.c
+@@ -761,7 +761,7 @@ static inline int notrace psz_kmsg_write_record(struct psz_context *cxt,
+ 		/* avoid destroying old data, allocate a new one */
+ 		len = zone->buffer_size + sizeof(*zone->buffer);
+ 		zone->oldbuf = zone->buffer;
+-		zone->buffer = kzalloc(len, GFP_KERNEL);
++		zone->buffer = kzalloc(len, GFP_ATOMIC);
+ 		if (!zone->buffer) {
+ 			zone->buffer = zone->oldbuf;
+ 			return -ENOMEM;
+diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h
+index 3cd202d3eefb3..36a486505b081 100644
+--- a/include/linux/eventfd.h
++++ b/include/linux/eventfd.h
+@@ -40,6 +40,7 @@ struct file *eventfd_fget(int fd);
+ struct eventfd_ctx *eventfd_ctx_fdget(int fd);
+ struct eventfd_ctx *eventfd_ctx_fileget(struct file *file);
+ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n);
++__u64 eventfd_signal_mask(struct eventfd_ctx *ctx, __u64 n, unsigned mask);
+ int eventfd_ctx_remove_wait_queue(struct eventfd_ctx *ctx, wait_queue_entry_t *wait,
+ 				  __u64 *cnt);
+ void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt);
+@@ -66,6 +67,12 @@ static inline int eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
+ 	return -ENOSYS;
+ }
+ 
++static inline int eventfd_signal_mask(struct eventfd_ctx *ctx, __u64 n,
++				      unsigned mask)
++{
++	return -ENOSYS;
++}
++
+ static inline void eventfd_ctx_put(struct eventfd_ctx *ctx)
+ {
+ 
+diff --git a/include/linux/nvme.h b/include/linux/nvme.h
+index ae53d74f3696a..e2dbb9755ccac 100644
+--- a/include/linux/nvme.h
++++ b/include/linux/nvme.h
+@@ -7,6 +7,7 @@
+ #ifndef _LINUX_NVME_H
+ #define _LINUX_NVME_H
+ 
++#include <linux/bits.h>
+ #include <linux/types.h>
+ #include <linux/uuid.h>
+ 
+@@ -639,7 +640,7 @@ enum {
+ 	NVME_CMD_EFFECTS_NCC		= 1 << 2,
+ 	NVME_CMD_EFFECTS_NIC		= 1 << 3,
+ 	NVME_CMD_EFFECTS_CCC		= 1 << 4,
+-	NVME_CMD_EFFECTS_CSE_MASK	= 3 << 16,
++	NVME_CMD_EFFECTS_CSE_MASK	= GENMASK(18, 16),
+ 	NVME_CMD_EFFECTS_UUID_SEL	= 1 << 19,
+ };
+ 
+diff --git a/include/uapi/linux/eventpoll.h b/include/uapi/linux/eventpoll.h
+index 8a3432d0f0dcb..e687658843b1c 100644
+--- a/include/uapi/linux/eventpoll.h
++++ b/include/uapi/linux/eventpoll.h
+@@ -41,6 +41,12 @@
+ #define EPOLLMSG	(__force __poll_t)0x00000400
+ #define EPOLLRDHUP	(__force __poll_t)0x00002000
+ 
++/*
++ * Internal flag - wakeup generated by io_uring, used to detect recursion back
++ * into the io_uring poll handler.
++ */
++#define EPOLL_URING_WAKE	((__force __poll_t)(1U << 27))
++
+ /* Set exclusive wakeup mode for the target file descriptor */
+ #define EPOLLEXCLUSIVE	((__force __poll_t)(1U << 28))
+ 
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index 1b6c25dc3f0c5..b8a39be3bcb4c 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -1607,7 +1607,7 @@ static int io_issue_sqe(struct io_kiocb *req, unsigned int issue_flags)
+ 		return ret;
+ 
+ 	/* If the op doesn't have a file, we're not polling for it */
+-	if ((req->ctx->flags & IORING_SETUP_IOPOLL) && req->file)
++	if ((req->ctx->flags & IORING_SETUP_IOPOLL) && def->iopoll_queue)
+ 		io_iopoll_req_issued(req, issue_flags);
+ 
+ 	return 0;
+diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c
+index 080867143f287..a49ccab262d53 100644
+--- a/io_uring/msg_ring.c
++++ b/io_uring/msg_ring.c
+@@ -169,9 +169,5 @@ done:
+ 	if (ret < 0)
+ 		req_set_fail(req);
+ 	io_req_set_res(req, ret, 0);
+-	/* put file to avoid an attempt to IOPOLL the req */
+-	if (!(req->flags & REQ_F_FIXED_FILE))
+-		io_put_file(req->file);
+-	req->file = NULL;
+ 	return IOU_OK;
+ }
+diff --git a/io_uring/opdef.c b/io_uring/opdef.c
+index 3b15cdb6dbbc5..b3746458741b8 100644
+--- a/io_uring/opdef.c
++++ b/io_uring/opdef.c
+@@ -63,6 +63,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.audit_skip		= 1,
+ 		.ioprio			= 1,
+ 		.iopoll			= 1,
++		.iopoll_queue		= 1,
+ 		.async_size		= sizeof(struct io_async_rw),
+ 		.name			= "READV",
+ 		.prep			= io_prep_rw,
+@@ -80,6 +81,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.audit_skip		= 1,
+ 		.ioprio			= 1,
+ 		.iopoll			= 1,
++		.iopoll_queue		= 1,
+ 		.async_size		= sizeof(struct io_async_rw),
+ 		.name			= "WRITEV",
+ 		.prep			= io_prep_rw,
+@@ -103,6 +105,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.audit_skip		= 1,
+ 		.ioprio			= 1,
+ 		.iopoll			= 1,
++		.iopoll_queue		= 1,
+ 		.async_size		= sizeof(struct io_async_rw),
+ 		.name			= "READ_FIXED",
+ 		.prep			= io_prep_rw,
+@@ -118,6 +121,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.audit_skip		= 1,
+ 		.ioprio			= 1,
+ 		.iopoll			= 1,
++		.iopoll_queue		= 1,
+ 		.async_size		= sizeof(struct io_async_rw),
+ 		.name			= "WRITE_FIXED",
+ 		.prep			= io_prep_rw,
+@@ -275,6 +279,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.audit_skip		= 1,
+ 		.ioprio			= 1,
+ 		.iopoll			= 1,
++		.iopoll_queue		= 1,
+ 		.async_size		= sizeof(struct io_async_rw),
+ 		.name			= "READ",
+ 		.prep			= io_prep_rw,
+@@ -290,6 +295,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.audit_skip		= 1,
+ 		.ioprio			= 1,
+ 		.iopoll			= 1,
++		.iopoll_queue		= 1,
+ 		.async_size		= sizeof(struct io_async_rw),
+ 		.name			= "WRITE",
+ 		.prep			= io_prep_rw,
+@@ -475,6 +481,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.needs_file		= 1,
+ 		.plug			= 1,
+ 		.name			= "URING_CMD",
++		.iopoll_queue		= 1,
+ 		.async_size		= uring_cmd_pdu_size(1),
+ 		.prep			= io_uring_cmd_prep,
+ 		.issue			= io_uring_cmd,
+diff --git a/io_uring/opdef.h b/io_uring/opdef.h
+index 3efe06d25473a..df7e13d9bfba7 100644
+--- a/io_uring/opdef.h
++++ b/io_uring/opdef.h
+@@ -25,6 +25,8 @@ struct io_op_def {
+ 	unsigned		ioprio : 1;
+ 	/* supports iopoll */
+ 	unsigned		iopoll : 1;
++	/* have to be put into the iopoll list */
++	unsigned		iopoll_queue : 1;
+ 	/* opcode specific path will handle ->async_data allocation if needed */
+ 	unsigned		manual_alloc : 1;
+ 	/* size of async data needed, if any */
+diff --git a/kernel/futex/syscalls.c b/kernel/futex/syscalls.c
+index 086a22d1adb78..a8074079b09e8 100644
+--- a/kernel/futex/syscalls.c
++++ b/kernel/futex/syscalls.c
+@@ -286,19 +286,22 @@ SYSCALL_DEFINE5(futex_waitv, struct futex_waitv __user *, waiters,
+ 	}
+ 
+ 	futexv = kcalloc(nr_futexes, sizeof(*futexv), GFP_KERNEL);
+-	if (!futexv)
+-		return -ENOMEM;
++	if (!futexv) {
++		ret = -ENOMEM;
++		goto destroy_timer;
++	}
+ 
+ 	ret = futex_parse_waitv(futexv, waiters, nr_futexes);
+ 	if (!ret)
+ 		ret = futex_wait_multiple(futexv, nr_futexes, timeout ? &to : NULL);
+ 
++	kfree(futexv);
++
++destroy_timer:
+ 	if (timeout) {
+ 		hrtimer_cancel(&to.timer);
+ 		destroy_hrtimer_on_stack(&to.timer);
+ 	}
+-
+-	kfree(futexv);
+ 	return ret;
+ }
+ 
+diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c
+index fe12dfe254ecf..54d077e1a2dc7 100644
+--- a/kernel/kcsan/core.c
++++ b/kernel/kcsan/core.c
+@@ -14,10 +14,12 @@
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/list.h>
++#include <linux/minmax.h>
+ #include <linux/moduleparam.h>
+ #include <linux/percpu.h>
+ #include <linux/preempt.h>
+ #include <linux/sched.h>
++#include <linux/string.h>
+ #include <linux/uaccess.h>
+ 
+ #include "encoding.h"
+@@ -1308,3 +1310,51 @@ noinline void __tsan_atomic_signal_fence(int memorder)
+ 	}
+ }
+ EXPORT_SYMBOL(__tsan_atomic_signal_fence);
++
++#ifdef __HAVE_ARCH_MEMSET
++void *__tsan_memset(void *s, int c, size_t count);
++noinline void *__tsan_memset(void *s, int c, size_t count)
++{
++	/*
++	 * Instead of not setting up watchpoints where accessed size is greater
++	 * than MAX_ENCODABLE_SIZE, truncate checked size to MAX_ENCODABLE_SIZE.
++	 */
++	size_t check_len = min_t(size_t, count, MAX_ENCODABLE_SIZE);
++
++	check_access(s, check_len, KCSAN_ACCESS_WRITE, _RET_IP_);
++	return memset(s, c, count);
++}
++#else
++void *__tsan_memset(void *s, int c, size_t count) __alias(memset);
++#endif
++EXPORT_SYMBOL(__tsan_memset);
++
++#ifdef __HAVE_ARCH_MEMMOVE
++void *__tsan_memmove(void *dst, const void *src, size_t len);
++noinline void *__tsan_memmove(void *dst, const void *src, size_t len)
++{
++	size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE);
++
++	check_access(dst, check_len, KCSAN_ACCESS_WRITE, _RET_IP_);
++	check_access(src, check_len, 0, _RET_IP_);
++	return memmove(dst, src, len);
++}
++#else
++void *__tsan_memmove(void *dst, const void *src, size_t len) __alias(memmove);
++#endif
++EXPORT_SYMBOL(__tsan_memmove);
++
++#ifdef __HAVE_ARCH_MEMCPY
++void *__tsan_memcpy(void *dst, const void *src, size_t len);
++noinline void *__tsan_memcpy(void *dst, const void *src, size_t len)
++{
++	size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE);
++
++	check_access(dst, check_len, KCSAN_ACCESS_WRITE, _RET_IP_);
++	check_access(src, check_len, 0, _RET_IP_);
++	return memcpy(dst, src, len);
++}
++#else
++void *__tsan_memcpy(void *dst, const void *src, size_t len) __alias(memcpy);
++#endif
++EXPORT_SYMBOL(__tsan_memcpy);
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index 771fcce54fac0..fb88278978fe7 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -2209,13 +2209,9 @@ int register_kretprobe(struct kretprobe *rp)
+ 	rp->kp.post_handler = NULL;
+ 
+ 	/* Pre-allocate memory for max kretprobe instances */
+-	if (rp->maxactive <= 0) {
+-#ifdef CONFIG_PREEMPTION
++	if (rp->maxactive <= 0)
+ 		rp->maxactive = max_t(unsigned int, 10, 2*num_possible_cpus());
+-#else
+-		rp->maxactive = num_possible_cpus();
+-#endif
+-	}
++
+ #ifdef CONFIG_KRETPROBE_ON_RETHOOK
+ 	rp->rh = rethook_alloc((void *)rp, kretprobe_rethook_handler);
+ 	if (!rp->rh)
+diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
+index 7779ee8abc2a0..010cf4e6d0b8f 100644
+--- a/kernel/locking/rtmutex.c
++++ b/kernel/locking/rtmutex.c
+@@ -89,15 +89,31 @@ static inline int __ww_mutex_check_kill(struct rt_mutex *lock,
+  * set this bit before looking at the lock.
+  */
+ 
+-static __always_inline void
+-rt_mutex_set_owner(struct rt_mutex_base *lock, struct task_struct *owner)
++static __always_inline struct task_struct *
++rt_mutex_owner_encode(struct rt_mutex_base *lock, struct task_struct *owner)
+ {
+ 	unsigned long val = (unsigned long)owner;
+ 
+ 	if (rt_mutex_has_waiters(lock))
+ 		val |= RT_MUTEX_HAS_WAITERS;
+ 
+-	WRITE_ONCE(lock->owner, (struct task_struct *)val);
++	return (struct task_struct *)val;
++}
++
++static __always_inline void
++rt_mutex_set_owner(struct rt_mutex_base *lock, struct task_struct *owner)
++{
++	/*
++	 * lock->wait_lock is held but explicit acquire semantics are needed
++	 * for a new lock owner so WRITE_ONCE is insufficient.
++	 */
++	xchg_acquire(&lock->owner, rt_mutex_owner_encode(lock, owner));
++}
++
++static __always_inline void rt_mutex_clear_owner(struct rt_mutex_base *lock)
++{
++	/* lock->wait_lock is held so the unlock provides release semantics. */
++	WRITE_ONCE(lock->owner, rt_mutex_owner_encode(lock, NULL));
+ }
+ 
+ static __always_inline void clear_rt_mutex_waiters(struct rt_mutex_base *lock)
+@@ -106,7 +122,8 @@ static __always_inline void clear_rt_mutex_waiters(struct rt_mutex_base *lock)
+ 			((unsigned long)lock->owner & ~RT_MUTEX_HAS_WAITERS);
+ }
+ 
+-static __always_inline void fixup_rt_mutex_waiters(struct rt_mutex_base *lock)
++static __always_inline void
++fixup_rt_mutex_waiters(struct rt_mutex_base *lock, bool acquire_lock)
+ {
+ 	unsigned long owner, *p = (unsigned long *) &lock->owner;
+ 
+@@ -172,8 +189,21 @@ static __always_inline void fixup_rt_mutex_waiters(struct rt_mutex_base *lock)
+ 	 * still set.
+ 	 */
+ 	owner = READ_ONCE(*p);
+-	if (owner & RT_MUTEX_HAS_WAITERS)
+-		WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS);
++	if (owner & RT_MUTEX_HAS_WAITERS) {
++		/*
++		 * See rt_mutex_set_owner() and rt_mutex_clear_owner() on
++		 * why xchg_acquire() is used for updating owner for
++		 * locking and WRITE_ONCE() for unlocking.
++		 *
++		 * WRITE_ONCE() would work for the acquire case too, but
++		 * in case that the lock acquisition failed it might
++		 * force other lockers into the slow path unnecessarily.
++		 */
++		if (acquire_lock)
++			xchg_acquire(p, owner & ~RT_MUTEX_HAS_WAITERS);
++		else
++			WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS);
++	}
+ }
+ 
+ /*
+@@ -208,6 +238,13 @@ static __always_inline void mark_rt_mutex_waiters(struct rt_mutex_base *lock)
+ 		owner = *p;
+ 	} while (cmpxchg_relaxed(p, owner,
+ 				 owner | RT_MUTEX_HAS_WAITERS) != owner);
++
++	/*
++	 * The cmpxchg loop above is relaxed to avoid back-to-back ACQUIRE
++	 * operations in the event of contention. Ensure the successful
++	 * cmpxchg is visible.
++	 */
++	smp_mb__after_atomic();
+ }
+ 
+ /*
+@@ -1243,7 +1280,7 @@ static int __sched __rt_mutex_slowtrylock(struct rt_mutex_base *lock)
+ 	 * try_to_take_rt_mutex() sets the lock waiters bit
+ 	 * unconditionally. Clean this up.
+ 	 */
+-	fixup_rt_mutex_waiters(lock);
++	fixup_rt_mutex_waiters(lock, true);
+ 
+ 	return ret;
+ }
+@@ -1604,7 +1641,7 @@ static int __sched __rt_mutex_slowlock(struct rt_mutex_base *lock,
+ 	 * try_to_take_rt_mutex() sets the waiter bit
+ 	 * unconditionally. We might have to fix that up.
+ 	 */
+-	fixup_rt_mutex_waiters(lock);
++	fixup_rt_mutex_waiters(lock, true);
+ 
+ 	trace_contention_end(lock, ret);
+ 
+@@ -1719,7 +1756,7 @@ static void __sched rtlock_slowlock_locked(struct rt_mutex_base *lock)
+ 	 * try_to_take_rt_mutex() sets the waiter bit unconditionally.
+ 	 * We might have to fix that up:
+ 	 */
+-	fixup_rt_mutex_waiters(lock);
++	fixup_rt_mutex_waiters(lock, true);
+ 	debug_rt_mutex_free_waiter(&waiter);
+ 
+ 	trace_contention_end(lock, 0);
+diff --git a/kernel/locking/rtmutex_api.c b/kernel/locking/rtmutex_api.c
+index 900220941caac..cb9fdff76a8a3 100644
+--- a/kernel/locking/rtmutex_api.c
++++ b/kernel/locking/rtmutex_api.c
+@@ -267,7 +267,7 @@ void __sched rt_mutex_init_proxy_locked(struct rt_mutex_base *lock,
+ void __sched rt_mutex_proxy_unlock(struct rt_mutex_base *lock)
+ {
+ 	debug_rt_mutex_proxy_unlock(lock);
+-	rt_mutex_set_owner(lock, NULL);
++	rt_mutex_clear_owner(lock);
+ }
+ 
+ /**
+@@ -382,7 +382,7 @@ int __sched rt_mutex_wait_proxy_lock(struct rt_mutex_base *lock,
+ 	 * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might
+ 	 * have to fix that up.
+ 	 */
+-	fixup_rt_mutex_waiters(lock);
++	fixup_rt_mutex_waiters(lock, true);
+ 	raw_spin_unlock_irq(&lock->wait_lock);
+ 
+ 	return ret;
+@@ -438,7 +438,7 @@ bool __sched rt_mutex_cleanup_proxy_lock(struct rt_mutex_base *lock,
+ 	 * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might
+ 	 * have to fix that up.
+ 	 */
+-	fixup_rt_mutex_waiters(lock);
++	fixup_rt_mutex_waiters(lock, false);
+ 
+ 	raw_spin_unlock_irq(&lock->wait_lock);
+ 
+diff --git a/mm/compaction.c b/mm/compaction.c
+index 88fea74c3a86b..8552f5ea358de 100644
+--- a/mm/compaction.c
++++ b/mm/compaction.c
+@@ -1346,7 +1346,7 @@ move_freelist_tail(struct list_head *freelist, struct page *freepage)
+ }
+ 
+ static void
+-fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsigned long nr_isolated)
++fast_isolate_around(struct compact_control *cc, unsigned long pfn)
+ {
+ 	unsigned long start_pfn, end_pfn;
+ 	struct page *page;
+@@ -1367,21 +1367,13 @@ fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsigned long
+ 	if (!page)
+ 		return;
+ 
+-	/* Scan before */
+-	if (start_pfn != pfn) {
+-		isolate_freepages_block(cc, &start_pfn, pfn, &cc->freepages, 1, false);
+-		if (cc->nr_freepages >= cc->nr_migratepages)
+-			return;
+-	}
+-
+-	/* Scan after */
+-	start_pfn = pfn + nr_isolated;
+-	if (start_pfn < end_pfn)
+-		isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
++	isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
+ 
+ 	/* Skip this pageblock in the future as it's full or nearly full */
+ 	if (cc->nr_freepages < cc->nr_migratepages)
+ 		set_pageblock_skip(page);
++
++	return;
+ }
+ 
+ /* Search orders in round-robin fashion */
+@@ -1558,7 +1550,7 @@ fast_isolate_freepages(struct compact_control *cc)
+ 		return cc->free_pfn;
+ 
+ 	low_pfn = page_to_pfn(page);
+-	fast_isolate_around(cc, low_pfn, nr_isolated);
++	fast_isolate_around(cc, low_pfn);
+ 	return low_pfn;
+ }
+ 
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index b73d3248d976a..dd385d7749470 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -1525,6 +1525,7 @@ SYSCALL_DEFINE4(set_mempolicy_home_node, unsigned long, start, unsigned long, le
+ 		 * the home node for vmas we already updated before.
+ 		 */
+ 		if (new->mode != MPOL_BIND && new->mode != MPOL_PREFERRED_MANY) {
++			mpol_put(new);
+ 			err = -EOPNOTSUPP;
+ 			break;
+ 		}
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
+index bcd74dddbe2db..9a5db285d4ae5 100644
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -1162,18 +1162,23 @@ static int gss_read_proxy_verf(struct svc_rqst *rqstp,
+ 		return res;
+ 
+ 	inlen = svc_getnl(argv);
+-	if (inlen > (argv->iov_len + rqstp->rq_arg.page_len))
++	if (inlen > (argv->iov_len + rqstp->rq_arg.page_len)) {
++		kfree(in_handle->data);
+ 		return SVC_DENIED;
++	}
+ 
+ 	pages = DIV_ROUND_UP(inlen, PAGE_SIZE);
+ 	in_token->pages = kcalloc(pages, sizeof(struct page *), GFP_KERNEL);
+-	if (!in_token->pages)
++	if (!in_token->pages) {
++		kfree(in_handle->data);
+ 		return SVC_DENIED;
++	}
+ 	in_token->page_base = 0;
+ 	in_token->page_len = inlen;
+ 	for (i = 0; i < pages; i++) {
+ 		in_token->pages[i] = alloc_page(GFP_KERNEL);
+ 		if (!in_token->pages[i]) {
++			kfree(in_handle->data);
+ 			gss_free_in_token_pages(in_token);
+ 			return SVC_DENIED;
+ 		}
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index 913509b29f938..8c0668304cbb8 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -167,6 +167,7 @@ struct hdmi_spec {
+ 	struct hdmi_ops ops;
+ 
+ 	bool dyn_pin_out;
++	bool static_pcm_mapping;
+ 	/* hdmi interrupt trigger control flag for Nvidia codec */
+ 	bool hdmi_intr_trig_ctrl;
+ 	bool nv_dp_workaround; /* workaround DP audio infoframe for Nvidia */
+@@ -1525,13 +1526,16 @@ static void update_eld(struct hda_codec *codec,
+ 	 */
+ 	pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
+ 
+-	if (eld->eld_valid) {
+-		hdmi_attach_hda_pcm(spec, per_pin);
+-		hdmi_pcm_setup_pin(spec, per_pin);
+-	} else {
+-		hdmi_pcm_reset_pin(spec, per_pin);
+-		hdmi_detach_hda_pcm(spec, per_pin);
++	if (!spec->static_pcm_mapping) {
++		if (eld->eld_valid) {
++			hdmi_attach_hda_pcm(spec, per_pin);
++			hdmi_pcm_setup_pin(spec, per_pin);
++		} else {
++			hdmi_pcm_reset_pin(spec, per_pin);
++			hdmi_detach_hda_pcm(spec, per_pin);
++		}
+ 	}
++
+ 	/* if pcm_idx == -1, it means this is in monitor connection event
+ 	 * we can get the correct pcm_idx now.
+ 	 */
+@@ -2281,8 +2285,8 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
+ 	struct hdmi_spec *spec = codec->spec;
+ 	int idx, pcm_num;
+ 
+-	/* limit the PCM devices to the codec converters */
+-	pcm_num = spec->num_cvts;
++	/* limit the PCM devices to the codec converters or available PINs */
++	pcm_num = min(spec->num_cvts, spec->num_pins);
+ 	codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num);
+ 
+ 	for (idx = 0; idx < pcm_num; idx++) {
+@@ -2379,6 +2383,11 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
+ 		struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
+ 		struct hdmi_eld *pin_eld = &per_pin->sink_eld;
+ 
++		if (spec->static_pcm_mapping) {
++			hdmi_attach_hda_pcm(spec, per_pin);
++			hdmi_pcm_setup_pin(spec, per_pin);
++		}
++
+ 		pin_eld->eld_valid = false;
+ 		hdmi_present_sense(per_pin, 0);
+ 	}
+@@ -4419,6 +4428,8 @@ static int patch_atihdmi(struct hda_codec *codec)
+ 
+ 	spec = codec->spec;
+ 
++	spec->static_pcm_mapping = true;
++
+ 	spec->ops.pin_get_eld = atihdmi_pin_get_eld;
+ 	spec->ops.pin_setup_infoframe = atihdmi_pin_setup_infoframe;
+ 	spec->ops.pin_hbr_setup = atihdmi_pin_hbr_setup;
+diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
+index 59faa5a9a7141..b67617b68e509 100644
+--- a/sound/usb/line6/driver.c
++++ b/sound/usb/line6/driver.c
+@@ -304,7 +304,8 @@ static void line6_data_received(struct urb *urb)
+ 		for (;;) {
+ 			done =
+ 				line6_midibuf_read(mb, line6->buffer_message,
+-						LINE6_MIDI_MESSAGE_MAXLEN);
++						   LINE6_MIDI_MESSAGE_MAXLEN,
++						   LINE6_MIDIBUF_READ_RX);
+ 
+ 			if (done <= 0)
+ 				break;
+diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c
+index ba0e2b7e8fe19..0838632c788e4 100644
+--- a/sound/usb/line6/midi.c
++++ b/sound/usb/line6/midi.c
+@@ -44,7 +44,8 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
+ 	int req, done;
+ 
+ 	for (;;) {
+-		req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size);
++		req = min3(line6_midibuf_bytes_free(mb), line6->max_packet_size,
++			   LINE6_FALLBACK_MAXPACKETSIZE);
+ 		done = snd_rawmidi_transmit_peek(substream, chunk, req);
+ 
+ 		if (done == 0)
+@@ -56,7 +57,8 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
+ 
+ 	for (;;) {
+ 		done = line6_midibuf_read(mb, chunk,
+-					  LINE6_FALLBACK_MAXPACKETSIZE);
++					  LINE6_FALLBACK_MAXPACKETSIZE,
++					  LINE6_MIDIBUF_READ_TX);
+ 
+ 		if (done == 0)
+ 			break;
+diff --git a/sound/usb/line6/midibuf.c b/sound/usb/line6/midibuf.c
+index 6a70463f82c4e..e7f830f7526c9 100644
+--- a/sound/usb/line6/midibuf.c
++++ b/sound/usb/line6/midibuf.c
+@@ -9,6 +9,7 @@
+ 
+ #include "midibuf.h"
+ 
++
+ static int midibuf_message_length(unsigned char code)
+ {
+ 	int message_length;
+@@ -20,12 +21,7 @@ static int midibuf_message_length(unsigned char code)
+ 
+ 		message_length = length[(code >> 4) - 8];
+ 	} else {
+-		/*
+-		   Note that according to the MIDI specification 0xf2 is
+-		   the "Song Position Pointer", but this is used by Line 6
+-		   to send sysex messages to the host.
+-		 */
+-		static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
++		static const int length[] = { -1, 2, 2, 2, -1, -1, 1, 1, 1, -1,
+ 			1, 1, 1, -1, 1, 1
+ 		};
+ 		message_length = length[code & 0x0f];
+@@ -125,7 +121,7 @@ int line6_midibuf_write(struct midi_buffer *this, unsigned char *data,
+ }
+ 
+ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
+-		       int length)
++		       int length, int read_type)
+ {
+ 	int bytes_used;
+ 	int length1, length2;
+@@ -148,9 +144,22 @@ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
+ 
+ 	length1 = this->size - this->pos_read;
+ 
+-	/* check MIDI command length */
+ 	command = this->buf[this->pos_read];
++	/*
++	   PODxt always has status byte lower nibble set to 0010,
++	   when it means to send 0000, so we correct if here so
++	   that control/program changes come on channel 1 and
++	   sysex message status byte is correct
++	 */
++	if (read_type == LINE6_MIDIBUF_READ_RX) {
++		if (command == 0xb2 || command == 0xc2 || command == 0xf2) {
++			unsigned char fixed = command & 0xf0;
++			this->buf[this->pos_read] = fixed;
++			command = fixed;
++		}
++	}
+ 
++	/* check MIDI command length */
+ 	if (command & 0x80) {
+ 		midi_length = midibuf_message_length(command);
+ 		this->command_prev = command;
+diff --git a/sound/usb/line6/midibuf.h b/sound/usb/line6/midibuf.h
+index 124a8f9f7e96c..542e8d836f87d 100644
+--- a/sound/usb/line6/midibuf.h
++++ b/sound/usb/line6/midibuf.h
+@@ -8,6 +8,9 @@
+ #ifndef MIDIBUF_H
+ #define MIDIBUF_H
+ 
++#define LINE6_MIDIBUF_READ_TX 0
++#define LINE6_MIDIBUF_READ_RX 1
++
+ struct midi_buffer {
+ 	unsigned char *buf;
+ 	int size;
+@@ -23,7 +26,7 @@ extern void line6_midibuf_destroy(struct midi_buffer *mb);
+ extern int line6_midibuf_ignore(struct midi_buffer *mb, int length);
+ extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split);
+ extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,
+-			      int length);
++			      int length, int read_type);
+ extern void line6_midibuf_reset(struct midi_buffer *mb);
+ extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,
+ 			       int length);
+diff --git a/sound/usb/line6/pod.c b/sound/usb/line6/pod.c
+index cd41aa7f03851..d173971e5f029 100644
+--- a/sound/usb/line6/pod.c
++++ b/sound/usb/line6/pod.c
+@@ -159,8 +159,9 @@ static struct line6_pcm_properties pod_pcm_properties = {
+ 	.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
+ };
+ 
++
+ static const char pod_version_header[] = {
+-	0xf2, 0x7e, 0x7f, 0x06, 0x02
++	0xf0, 0x7e, 0x7f, 0x06, 0x02
+ };
+ 
+ static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index 67afdce3421f5..274bc3d4bc3f8 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -207,7 +207,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
+ 		return false;
+ 
+ 	insn = find_insn(file, func->sec, func->offset);
+-	if (!insn->func)
++	if (!insn || !insn->func)
+ 		return false;
+ 
+ 	func_for_each_insn(file, func, insn) {


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-31 15:29 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-31 15:29 UTC (permalink / raw
  To: gentoo-commits

commit:     47bebee42dd8af1585608157960c0bcf25816035
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Dec 31 15:29:16 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Dec 31 15:29:16 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=47bebee4

Linux patch 6.0.16

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

 0000_README             |     4 +
 1015_linux-6.0.16.patch | 45617 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 45621 insertions(+)

diff --git a/0000_README b/0000_README
index 302d8339..44fc4c7e 100644
--- a/0000_README
+++ b/0000_README
@@ -103,6 +103,10 @@ Patch:  1014_linux-6.0.15.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.15
 
+Patch:  1015_linux-6.0.16.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.16
+
 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/1015_linux-6.0.16.patch b/1015_linux-6.0.16.patch
new file mode 100644
index 00000000..e72ee462
--- /dev/null
+++ b/1015_linux-6.0.16.patch
@@ -0,0 +1,45617 @@
+diff --git a/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor b/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor
+index d76cd3946434d..e9ef69aef20b1 100644
+--- a/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor
++++ b/Documentation/ABI/testing/sysfs-bus-spi-devices-spi-nor
+@@ -5,6 +5,9 @@ Contact:	linux-mtd@lists.infradead.org
+ Description:	(RO) The JEDEC ID of the SPI NOR flash as reported by the
+ 		flash device.
+ 
++		The attribute is not present if the flash doesn't support
++		the "Read JEDEC ID" command (9Fh). This is the case for
++		non-JEDEC compliant flashes.
+ 
+ What:		/sys/bus/spi/devices/.../spi-nor/manufacturer
+ Date:		April 2021
+diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
+index ee6572b1edada..66d1b23ca64fe 100644
+--- a/Documentation/admin-guide/sysctl/kernel.rst
++++ b/Documentation/admin-guide/sysctl/kernel.rst
+@@ -1298,6 +1298,29 @@ watchdog work to be queued by the watchdog timer function, otherwise the NMI
+ watchdog — if enabled — can detect a hard lockup condition.
+ 
+ 
++split_lock_mitigate (x86 only)
++==============================
++
++On x86, each "split lock" imposes a system-wide performance penalty. On larger
++systems, large numbers of split locks from unprivileged users can result in
++denials of service to well-behaved and potentially more important users.
++
++The kernel mitigates these bad users by detecting split locks and imposing
++penalties: forcing them to wait and only allowing one core to execute split
++locks at a time.
++
++These mitigations can make those bad applications unbearably slow. Setting
++split_lock_mitigate=0 may restore some application performance, but will also
++increase system exposure to denial of service attacks from split lock users.
++
++= ===================================================================
++0 Disable the mitigation mode - just warns the split lock on kernel log
++  and exposes the system to denials of service from the split lockers.
++1 Enable the mitigation mode (this is the default) - penalizes the split
++  lockers with intentional performance degradation.
++= ===================================================================
++
++
+ stack_erasing
+ =============
+ 
+diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml
+index bad9135489de5..1d20cdcc69ff8 100644
+--- a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml
++++ b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml
+@@ -22,6 +22,8 @@ properties:
+ 
+   clock-names: true
+ 
++  reg: true
++
+   compatible:
+     enum:
+       - qcom,sc7280-lpassaoncc
+@@ -38,8 +40,8 @@ properties:
+   '#power-domain-cells':
+     const: 1
+ 
+-  reg:
+-    maxItems: 1
++  '#reset-cells':
++    const: 1
+ 
+ required:
+   - compatible
+@@ -69,6 +71,11 @@ allOf:
+           items:
+             - const: bi_tcxo
+             - const: lpass_aon_cc_main_rcg_clk_src
++
++        reg:
++          items:
++            - description: lpass core cc register
++            - description: lpass audio csr register
+   - if:
+       properties:
+         compatible:
+@@ -90,6 +97,8 @@ allOf:
+             - const: bi_tcxo_ao
+             - const: iface
+ 
++        reg:
++          maxItems: 1
+   - if:
+       properties:
+         compatible:
+@@ -108,6 +117,8 @@ allOf:
+           items:
+             - const: bi_tcxo
+ 
++        reg:
++          maxItems: 1
+ examples:
+   - |
+     #include <dt-bindings/clock/qcom,rpmh.h>
+@@ -116,13 +127,15 @@ examples:
+     #include <dt-bindings/clock/qcom,lpasscorecc-sc7280.h>
+     lpass_audiocc: clock-controller@3300000 {
+       compatible = "qcom,sc7280-lpassaudiocc";
+-      reg = <0x3300000 0x30000>;
++      reg = <0x3300000 0x30000>,
++            <0x32a9000 0x1000>;
+       clocks = <&rpmhcc RPMH_CXO_CLK>,
+                <&lpass_aon LPASS_AON_CC_MAIN_RCG_CLK_SRC>;
+       clock-names = "bi_tcxo", "lpass_aon_cc_main_rcg_clk_src";
+       power-domains = <&lpass_aon LPASS_AON_CC_LPASS_AUDIO_HM_GDSC>;
+       #clock-cells = <1>;
+       #power-domain-cells = <1>;
++      #reset-cells = <1>;
+     };
+ 
+   - |
+diff --git a/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml b/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
+index 02e605fac408d..9ddba7f2e7aa6 100644
+--- a/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
++++ b/Documentation/devicetree/bindings/input/azoteq,iqs7222.yaml
+@@ -473,9 +473,6 @@ patternProperties:
+               Specifies whether the event is to be interpreted as a key (1)
+               or a switch (5).
+ 
+-        required:
+-          - linux,code
+-
+         additionalProperties: false
+ 
+     dependencies:
+@@ -501,7 +498,7 @@ patternProperties:
+ 
+       azoteq,slider-size:
+         $ref: /schemas/types.yaml#/definitions/uint32
+-        minimum: 0
++        minimum: 1
+         maximum: 65535
+         description:
+           Specifies the slider's one-dimensional resolution, equal to the
+@@ -575,9 +572,9 @@ patternProperties:
+           linux,code: true
+ 
+           azoteq,gesture-max-ms:
+-            multipleOf: 4
++            multipleOf: 16
+             minimum: 0
+-            maximum: 1020
++            maximum: 4080
+             description:
+               Specifies the length of time (in ms) within which a tap, swipe
+               or flick gesture must be completed in order to be acknowledged
+@@ -585,9 +582,9 @@ patternProperties:
+               gesture applies to all remaining swipe or flick gestures.
+ 
+           azoteq,gesture-min-ms:
+-            multipleOf: 4
++            multipleOf: 16
+             minimum: 0
+-            maximum: 124
++            maximum: 496
+             description:
+               Specifies the length of time (in ms) for which a tap gesture must
+               be held in order to be acknowledged by the device.
+@@ -620,9 +617,6 @@ patternProperties:
+               GPIO, they must all be of the same type (proximity, touch or
+               slider gesture).
+ 
+-        required:
+-          - linux,code
+-
+         additionalProperties: false
+ 
+     required:
+@@ -693,6 +687,7 @@ allOf:
+           properties:
+             azoteq,slider-size:
+               multipleOf: 16
++              minimum: 16
+               maximum: 4080
+ 
+             azoteq,top-speed:
+@@ -935,14 +930,14 @@ examples:
+ 
+                             event-tap {
+                                     linux,code = <KEY_PLAYPAUSE>;
+-                                    azoteq,gesture-max-ms = <600>;
+-                                    azoteq,gesture-min-ms = <24>;
++                                    azoteq,gesture-max-ms = <400>;
++                                    azoteq,gesture-min-ms = <32>;
+                             };
+ 
+                             event-flick-pos {
+                                     linux,code = <KEY_NEXTSONG>;
+-                                    azoteq,gesture-max-ms = <600>;
+-                                    azoteq,gesture-dist = <816>;
++                                    azoteq,gesture-max-ms = <800>;
++                                    azoteq,gesture-dist = <800>;
+                             };
+ 
+                             event-flick-neg {
+diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
+index 65cbc6dee545e..2a5bafe0660a0 100644
+--- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
++++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
+@@ -92,6 +92,10 @@ properties:
+     type: object
+     $ref: /schemas/regulator/regulator.yaml#
+ 
++  pwm:
++    type: object
++    $ref: /schemas/leds/leds-qcom-lpg.yaml#
++
+ patternProperties:
+   "^adc@[0-9a-f]+$":
+     type: object
+@@ -117,10 +121,6 @@ patternProperties:
+     type: object
+     $ref: /schemas/power/reset/qcom,pon.yaml#
+ 
+-  "pwm@[0-9a-f]+$":
+-    type: object
+-    $ref: /schemas/leds/leds-qcom-lpg.yaml#
+-
+   "^rtc@[0-9a-f]+$":
+     type: object
+     $ref: /schemas/rtc/qcom-pm8xxx-rtc.yaml#
+diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+index 376e739bcad40..49b4f7a32e71e 100644
+--- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
++++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml
+@@ -14,9 +14,6 @@ description: |+
+   This PCIe host controller is based on the Synopsys DesignWare PCIe IP
+   and thus inherits all the common properties defined in snps,dw-pcie.yaml.
+ 
+-allOf:
+-  - $ref: /schemas/pci/snps,dw-pcie.yaml#
+-
+ properties:
+   compatible:
+     enum:
+@@ -61,7 +58,7 @@ properties:
+       - const: pcie
+       - const: pcie_bus
+       - const: pcie_phy
+-      - const: pcie_inbound_axi for imx6sx-pcie, pcie_aux for imx8mq-pcie
++      - enum: [ pcie_inbound_axi, pcie_aux ]
+ 
+   num-lanes:
+     const: 1
+@@ -175,6 +172,47 @@ required:
+   - clocks
+   - clock-names
+ 
++allOf:
++  - $ref: /schemas/pci/snps,dw-pcie.yaml#
++  - if:
++      properties:
++        compatible:
++          contains:
++            const: fsl,imx6sx-pcie
++    then:
++      properties:
++        clock-names:
++          items:
++            - {}
++            - {}
++            - {}
++            - const: pcie_inbound_axi
++  - if:
++      properties:
++        compatible:
++          contains:
++            const: fsl,imx8mq-pcie
++    then:
++      properties:
++        clock-names:
++          items:
++            - {}
++            - {}
++            - {}
++            - const: pcie_aux
++  - if:
++      properties:
++        compatible:
++          not:
++            contains:
++              enum:
++                - fsl,imx6sx-pcie
++                - fsl,imx8mq-pcie
++    then:
++      properties:
++        clock-names:
++          maxItems: 3
++
+ unevaluatedProperties: false
+ 
+ examples:
+diff --git a/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml b/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
+index 30b6396d83c83..aea0e2bcdd778 100644
+--- a/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
++++ b/Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml
+@@ -36,7 +36,7 @@ properties:
+       - const: mpu
+ 
+   interrupts:
+-    maxItems: 1
++    maxItems: 2
+ 
+   clocks:
+     items:
+@@ -94,8 +94,9 @@ examples:
+             #interrupt-cells = <1>;
+             ranges = <0x81000000 0 0x40000000 0 0x40000000 0 0x00010000>,
+                      <0x82000000 0 0x50000000 0 0x50000000 0 0x20000000>;
+-            interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
+-            interrupt-names = "intr";
++            interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
++                         <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>;
++            interrupt-names = "msi", "intr";
+             interrupt-map-mask = <0 0 0 7>;
+             interrupt-map =
+                 <0 0 0 1 &gic GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH
+diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml
+index 4eadea55df10f..41abfa94877fb 100644
+--- a/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml
++++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt7986-pinctrl.yaml
+@@ -87,6 +87,8 @@ patternProperties:
+           "wifi_led"        "led"       1, 2
+           "i2c"             "i2c"       3, 4
+           "uart1_0"         "uart"      7, 8, 9, 10
++          "uart1_rx_tx"     "uart"      42, 43
++          "uart1_cts_rts"   "uart"      44, 45
+           "pcie_clk"        "pcie"      9
+           "pcie_wake"       "pcie"      10
+           "spi1_0"          "spi"       11, 12, 13, 14
+@@ -98,9 +100,11 @@ patternProperties:
+           "emmc_45"         "emmc"      22, 23, 24, 25, 26, 27, 28, 29, 30,
+                                         31, 32
+           "spi1_1"          "spi"       23, 24, 25, 26
+-          "uart1_2"         "uart"      29, 30, 31, 32
++          "uart1_2_rx_tx"   "uart"      29, 30
++          "uart1_2_cts_rts" "uart"      31, 32
+           "uart1_1"         "uart"      23, 24, 25, 26
+-          "uart2_0"         "uart"      29, 30, 31, 32
++          "uart2_0_rx_tx"   "uart"      29, 30
++          "uart2_0_cts_rts" "uart"      31, 32
+           "spi0"            "spi"       33, 34, 35, 36
+           "spi0_wp_hold"    "spi"       37, 38
+           "uart1_3_rx_tx"   "uart"      35, 36
+@@ -153,7 +157,7 @@ patternProperties:
+             then:
+               properties:
+                 groups:
+-                  enum: [emmc, emmc_rst]
++                  enum: [emmc_45, emmc_51]
+           - if:
+               properties:
+                 function:
+@@ -217,8 +221,12 @@ patternProperties:
+             then:
+               properties:
+                 groups:
+-                  enum: [uart1_0, uart1_1, uart1_2, uart1_3_rx_tx,
+-                         uart1_3_cts_rts, uart2_0, uart2_1, uart0, uart1, uart2]
++                  items:
++                    enum: [uart1_0, uart1_rx_tx, uart1_cts_rts, uart1_1,
++                           uart1_2_rx_tx, uart1_2_cts_rts, uart1_3_rx_tx,
++                           uart1_3_cts_rts, uart2_0_rx_tx, uart2_0_cts_rts,
++                           uart2_1, uart0, uart1, uart2]
++                  maxItems: 2
+           - if:
+               properties:
+                 function:
+@@ -348,6 +356,27 @@ examples:
+         interrupt-parent = <&gic>;
+         #interrupt-cells = <2>;
+ 
++        pcie_pins: pcie-pins {
++          mux {
++            function = "pcie";
++            groups = "pcie_clk", "pcie_wake", "pcie_pereset";
++          };
++        };
++
++        pwm_pins: pwm-pins {
++          mux {
++            function = "pwm";
++            groups = "pwm0", "pwm1_0";
++          };
++        };
++
++        spi0_pins: spi0-pins {
++          mux {
++            function = "spi";
++            groups = "spi0", "spi0_wp_hold";
++          };
++        };
++
+         uart1_pins: uart1-pins {
+           mux {
+             function = "uart";
+@@ -355,6 +384,13 @@ examples:
+           };
+         };
+ 
++        uart1_3_pins: uart1-3-pins {
++          mux {
++            function = "uart";
++            groups = "uart1_3_rx_tx", "uart1_3_cts_rts";
++          };
++        };
++
+         uart2_pins: uart2-pins {
+           mux {
+             function = "uart";
+diff --git a/Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml b/Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml
+index a7fae1772a81b..cd8e9a8907f84 100644
+--- a/Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml
++++ b/Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml
+@@ -30,7 +30,9 @@ properties:
+     maxItems: 1
+ 
+   "#pwm-cells":
+-    const: 2
++    enum: [2, 3]
++    description:
++      The only flag supported by the controller is PWM_POLARITY_INVERTED.
+ 
+   microchip,sync-update-mask:
+     description: |
+diff --git a/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt b/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
+index 5d6ea66a863fe..1f75feec3dec6 100644
+--- a/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
++++ b/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt
+@@ -109,7 +109,7 @@ audio-codec@1{
+ 	reg  = <1 0>;
+ 	interrupts = <&msmgpio 54 IRQ_TYPE_LEVEL_HIGH>;
+ 	interrupt-names = "intr2"
+-	reset-gpios = <&msmgpio 64 0>;
++	reset-gpios = <&msmgpio 64 GPIO_ACTIVE_LOW>;
+ 	slim-ifc-dev  = <&wc9335_ifd>;
+ 	clock-names = "mclk", "native";
+ 	clocks = <&rpmcc RPM_SMD_DIV_CLK1>,
+diff --git a/Documentation/devicetree/bindings/sound/rt5682.txt b/Documentation/devicetree/bindings/sound/rt5682.txt
+index c5f2b8febceec..6b87db68337c2 100644
+--- a/Documentation/devicetree/bindings/sound/rt5682.txt
++++ b/Documentation/devicetree/bindings/sound/rt5682.txt
+@@ -46,7 +46,7 @@ Optional properties:
+ 
+ - realtek,dmic-clk-driving-high : Set the high driving of the DMIC clock out.
+ 
+-- #sound-dai-cells: Should be set to '<0>'.
++- #sound-dai-cells: Should be set to '<1>'.
+ 
+ Pins on the device (for linking into audio routes) for RT5682:
+ 
+diff --git a/Documentation/driver-api/spi.rst b/Documentation/driver-api/spi.rst
+index f64cb666498aa..f28887045049d 100644
+--- a/Documentation/driver-api/spi.rst
++++ b/Documentation/driver-api/spi.rst
+@@ -25,8 +25,8 @@ hardware, which may be as simple as a set of GPIO pins or as complex as
+ a pair of FIFOs connected to dual DMA engines on the other side of the
+ SPI shift register (maximizing throughput). Such drivers bridge between
+ whatever bus they sit on (often the platform bus) and SPI, and expose
+-the SPI side of their device as a :c:type:`struct spi_master
+-<spi_master>`. SPI devices are children of that master,
++the SPI side of their device as a :c:type:`struct spi_controller
++<spi_controller>`. SPI devices are children of that master,
+ represented as a :c:type:`struct spi_device <spi_device>` and
+ manufactured from :c:type:`struct spi_board_info
+ <spi_board_info>` descriptors which are usually provided by
+diff --git a/Documentation/fault-injection/fault-injection.rst b/Documentation/fault-injection/fault-injection.rst
+index 17779a2772e51..5f6454b9dbd4d 100644
+--- a/Documentation/fault-injection/fault-injection.rst
++++ b/Documentation/fault-injection/fault-injection.rst
+@@ -83,9 +83,7 @@ configuration of fault-injection capabilities.
+ - /sys/kernel/debug/fail*/times:
+ 
+ 	specifies how many times failures may happen at most. A value of -1
+-	means "no limit". Note, though, that this file only accepts unsigned
+-	values. So, if you want to specify -1, you better use 'printf' instead
+-	of 'echo', e.g.: $ printf %#x -1 > times
++	means "no limit".
+ 
+ - /sys/kernel/debug/fail*/space:
+ 
+@@ -284,7 +282,7 @@ Application Examples
+     echo Y > /sys/kernel/debug/$FAILTYPE/task-filter
+     echo 10 > /sys/kernel/debug/$FAILTYPE/probability
+     echo 100 > /sys/kernel/debug/$FAILTYPE/interval
+-    printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times
++    echo -1 > /sys/kernel/debug/$FAILTYPE/times
+     echo 0 > /sys/kernel/debug/$FAILTYPE/space
+     echo 2 > /sys/kernel/debug/$FAILTYPE/verbose
+     echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait
+@@ -338,7 +336,7 @@ Application Examples
+     echo N > /sys/kernel/debug/$FAILTYPE/task-filter
+     echo 10 > /sys/kernel/debug/$FAILTYPE/probability
+     echo 100 > /sys/kernel/debug/$FAILTYPE/interval
+-    printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times
++    echo -1 > /sys/kernel/debug/$FAILTYPE/times
+     echo 0 > /sys/kernel/debug/$FAILTYPE/space
+     echo 2 > /sys/kernel/debug/$FAILTYPE/verbose
+     echo Y > /sys/kernel/debug/$FAILTYPE/ignore-gfp-wait
+@@ -369,7 +367,7 @@ Application Examples
+     echo N > /sys/kernel/debug/$FAILTYPE/task-filter
+     echo 100 > /sys/kernel/debug/$FAILTYPE/probability
+     echo 0 > /sys/kernel/debug/$FAILTYPE/interval
+-    printf %#x -1 > /sys/kernel/debug/$FAILTYPE/times
++    echo -1 > /sys/kernel/debug/$FAILTYPE/times
+     echo 0 > /sys/kernel/debug/$FAILTYPE/space
+     echo 1 > /sys/kernel/debug/$FAILTYPE/verbose
+ 
+diff --git a/Makefile b/Makefile
+index 0c7ae314ad3d5..ff8d88b113919 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 15
++SUBLEVEL = 16
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/Kconfig b/arch/Kconfig
+index 8b311e400ec14..732a4680e733e 100644
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -629,7 +629,7 @@ config ARCH_SUPPORTS_SHADOW_CALL_STACK
+ config SHADOW_CALL_STACK
+ 	bool "Shadow Call Stack"
+ 	depends on ARCH_SUPPORTS_SHADOW_CALL_STACK
+-	depends on DYNAMIC_FTRACE_WITH_REGS || !FUNCTION_GRAPH_TRACER
++	depends on DYNAMIC_FTRACE_WITH_ARGS || DYNAMIC_FTRACE_WITH_REGS || !FUNCTION_GRAPH_TRACER
+ 	help
+ 	  This option enables the compiler's Shadow Call Stack, which
+ 	  uses a shadow stack to protect function return addresses from
+diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h
+index fdc485d7787a6..084c27cb0c707 100644
+--- a/arch/alpha/include/asm/thread_info.h
++++ b/arch/alpha/include/asm/thread_info.h
+@@ -75,7 +75,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
+ 
+ /* Work to do on interrupt/exception return.  */
+ #define _TIF_WORK_MASK		(_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+-				 _TIF_NOTIFY_RESUME)
++				 _TIF_NOTIFY_RESUME | _TIF_NOTIFY_SIGNAL)
+ 
+ /* Work to do on any return to userspace.  */
+ #define _TIF_ALLWORK_MASK	(_TIF_WORK_MASK		\
+diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
+index e227f3a29a43c..c41a5a9c3b9f2 100644
+--- a/arch/alpha/kernel/entry.S
++++ b/arch/alpha/kernel/entry.S
+@@ -469,8 +469,10 @@ entSys:
+ #ifdef CONFIG_AUDITSYSCALL
+ 	lda     $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ 	and     $3, $6, $3
+-#endif
+ 	bne     $3, strace
++#else
++	blbs    $3, strace		/* check for SYSCALL_TRACE in disguise */
++#endif
+ 	beq	$4, 1f
+ 	ldq	$27, 0($5)
+ 1:	jsr	$26, ($27), sys_ni_syscall
+diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
+index 46e6d3ed8f35a..c042c416a94a3 100644
+--- a/arch/arm/boot/dts/armada-370.dtsi
++++ b/arch/arm/boot/dts/armada-370.dtsi
+@@ -74,7 +74,7 @@
+ 
+ 			pcie2: pcie@2,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
++				assigned-addresses = <0x82001000 0 0x80000 0 0x2000>;
+ 				reg = <0x1000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi
+index 7f2f24a29e6c1..352a2f7ba3114 100644
+--- a/arch/arm/boot/dts/armada-375.dtsi
++++ b/arch/arm/boot/dts/armada-375.dtsi
+@@ -582,7 +582,7 @@
+ 
+ 			pcie1: pcie@2,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++				assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
+ 				reg = <0x1000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-380.dtsi b/arch/arm/boot/dts/armada-380.dtsi
+index cff1269f3fbfd..7146cc8f082af 100644
+--- a/arch/arm/boot/dts/armada-380.dtsi
++++ b/arch/arm/boot/dts/armada-380.dtsi
+@@ -79,7 +79,7 @@
+ 			/* x1 port */
+ 			pcie@2,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
++				assigned-addresses = <0x82001000 0 0x40000 0 0x2000>;
+ 				reg = <0x1000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -98,7 +98,7 @@
+ 			/* x1 port */
+ 			pcie@3,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++				assigned-addresses = <0x82001800 0 0x44000 0 0x2000>;
+ 				reg = <0x1800 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+index a41902e3815cd..0b64d7505dca0 100644
+--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts
++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+@@ -23,6 +23,12 @@
+ 		stdout-path = &uart0;
+ 	};
+ 
++	aliases {
++		ethernet0 = &eth0;
++		ethernet1 = &eth1;
++		ethernet2 = &eth2;
++	};
++
+ 	memory {
+ 		device_type = "memory";
+ 		reg = <0x00000000 0x40000000>; /* 1024 MB */
+@@ -455,7 +461,17 @@
+ 				};
+ 			};
+ 
+-			/* port 6 is connected to eth0 */
++			ports@6 {
++				reg = <6>;
++				label = "cpu";
++				ethernet = <&eth0>;
++				phy-mode = "rgmii-id";
++
++				fixed-link {
++					speed = <1000>;
++					full-duplex;
++				};
++			};
+ 		};
+ 	};
+ };
+diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi
+index 83392b92dae28..be8d607c59b21 100644
+--- a/arch/arm/boot/dts/armada-385.dtsi
++++ b/arch/arm/boot/dts/armada-385.dtsi
+@@ -93,7 +93,7 @@
+ 			/* x1 port */
+ 			pcie2: pcie@2,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
++				assigned-addresses = <0x82001000 0 0x40000 0 0x2000>;
+ 				reg = <0x1000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -121,7 +121,7 @@
+ 			/* x1 port */
+ 			pcie3: pcie@3,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++				assigned-addresses = <0x82001800 0 0x44000 0 0x2000>;
+ 				reg = <0x1800 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -152,7 +152,7 @@
+ 			 */
+ 			pcie4: pcie@4,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
++				assigned-addresses = <0x82002000 0 0x48000 0 0x2000>;
+ 				reg = <0x2000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi
+index e0b7c20998312..9525e7b7f4360 100644
+--- a/arch/arm/boot/dts/armada-39x.dtsi
++++ b/arch/arm/boot/dts/armada-39x.dtsi
+@@ -453,7 +453,7 @@
+ 			/* x1 port */
+ 			pcie@2,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x40000 0 0x2000>;
++				assigned-addresses = <0x82001000 0 0x40000 0 0x2000>;
+ 				reg = <0x1000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -472,7 +472,7 @@
+ 			/* x1 port */
+ 			pcie@3,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++				assigned-addresses = <0x82001800 0 0x44000 0 0x2000>;
+ 				reg = <0x1800 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -494,7 +494,7 @@
+ 			 */
+ 			pcie@4,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
++				assigned-addresses = <0x82002000 0 0x48000 0 0x2000>;
+ 				reg = <0x2000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+index 8558bf6bb54c6..d55fe162fc7f0 100644
+--- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi
++++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi
+@@ -97,7 +97,7 @@
+ 
+ 			pcie2: pcie@2,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++				assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
+ 				reg = <0x1000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -115,7 +115,7 @@
+ 
+ 			pcie3: pcie@3,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
++				assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
+ 				reg = <0x1800 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -133,7 +133,7 @@
+ 
+ 			pcie4: pcie@4,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
++				assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
+ 				reg = <0x2000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -151,7 +151,7 @@
+ 
+ 			pcie5: pcie@5,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
++				assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
+ 				reg = <0x2800 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+index 2d85fe8ac3272..fdcc818199401 100644
+--- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi
++++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi
+@@ -112,7 +112,7 @@
+ 
+ 			pcie2: pcie@2,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x44000 0 0x2000>;
++				assigned-addresses = <0x82001000 0 0x44000 0 0x2000>;
+ 				reg = <0x1000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -130,7 +130,7 @@
+ 
+ 			pcie3: pcie@3,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x48000 0 0x2000>;
++				assigned-addresses = <0x82001800 0 0x48000 0 0x2000>;
+ 				reg = <0x1800 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -148,7 +148,7 @@
+ 
+ 			pcie4: pcie@4,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>;
++				assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>;
+ 				reg = <0x2000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -166,7 +166,7 @@
+ 
+ 			pcie5: pcie@5,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
++				assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
+ 				reg = <0x2800 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -184,7 +184,7 @@
+ 
+ 			pcie6: pcie@6,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x84000 0 0x2000>;
++				assigned-addresses = <0x82003000 0 0x84000 0 0x2000>;
+ 				reg = <0x3000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -202,7 +202,7 @@
+ 
+ 			pcie7: pcie@7,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x88000 0 0x2000>;
++				assigned-addresses = <0x82003800 0 0x88000 0 0x2000>;
+ 				reg = <0x3800 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -220,7 +220,7 @@
+ 
+ 			pcie8: pcie@8,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>;
++				assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>;
+ 				reg = <0x4000 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+@@ -238,7 +238,7 @@
+ 
+ 			pcie9: pcie@9,0 {
+ 				device_type = "pci";
+-				assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
++				assigned-addresses = <0x82004800 0 0x42000 0 0x2000>;
+ 				reg = <0x4800 0 0 0 0>;
+ 				#address-cells = <3>;
+ 				#size-cells = <2>;
+diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
+index a6a2bc3b855c2..fcc890e3ad735 100644
+--- a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
++++ b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
+@@ -162,16 +162,9 @@
+ 		#size-cells = <1>;
+ 		ranges;
+ 
+-		/* LPC FW cycle bridge region requires natural alignment */
+-		flash_memory: region@b8000000 {
+-			no-map;
+-			reg = <0xb8000000 0x04000000>; /* 64M */
+-		};
+-
+-		/* 48MB region from the end of flash to start of vga memory */
+-		ramoops@bc000000 {
++		ramoops@b3e00000 {
+ 			compatible = "ramoops";
+-			reg = <0xbc000000 0x200000>; /* 16 * (4 * 0x8000) */
++			reg = <0xb3e00000 0x200000>; /* 16 * (4 * 0x8000) */
+ 			record-size = <0x8000>;
+ 			console-size = <0x8000>;
+ 			ftrace-size = <0x8000>;
+@@ -179,6 +172,12 @@
+ 			max-reason = <3>; /* KMSG_DUMP_EMERG */
+ 		};
+ 
++		/* LPC FW cycle bridge region requires natural alignment */
++		flash_memory: region@b4000000 {
++			no-map;
++			reg = <0xb4000000 0x04000000>; /* 64M */
++		};
++
+ 		/* VGA region is dictated by hardware strapping */
+ 		vga_memory: region@bf000000 {
+ 			no-map;
+diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
+index bf59a9962379d..4879da4cdbd25 100644
+--- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
++++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
+@@ -95,14 +95,9 @@
+ 		#size-cells = <1>;
+ 		ranges;
+ 
+-		flash_memory: region@b8000000 {
+-			no-map;
+-			reg = <0xb8000000 0x04000000>; /* 64M */
+-		};
+-
+-		ramoops@bc000000 {
++		ramoops@b3e00000 {
+ 			compatible = "ramoops";
+-			reg = <0xbc000000 0x200000>; /* 16 * (4 * 0x8000) */
++			reg = <0xb3e00000 0x200000>; /* 16 * (4 * 0x8000) */
+ 			record-size = <0x8000>;
+ 			console-size = <0x8000>;
+ 			ftrace-size = <0x8000>;
+@@ -110,6 +105,13 @@
+ 			max-reason = <3>; /* KMSG_DUMP_EMERG */
+ 		};
+ 
++		/* LPC FW cycle bridge region requires natural alignment */
++		flash_memory: region@b4000000 {
++			no-map;
++			reg = <0xb4000000 0x04000000>; /* 64M */
++		};
++
++		/* VGA region is dictated by hardware strapping */
+ 		vga_memory: region@bf000000 {
+ 			no-map;
+ 			compatible = "shared-dma-pool";
+diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
+index 89e0bdaf3a85f..726d353eda686 100644
+--- a/arch/arm/boot/dts/dove.dtsi
++++ b/arch/arm/boot/dts/dove.dtsi
+@@ -129,7 +129,7 @@
+ 			pcie1: pcie@2 {
+ 				device_type = "pci";
+ 				status = "disabled";
+-				assigned-addresses = <0x82002800 0 0x80000 0 0x2000>;
++				assigned-addresses = <0x82001000 0 0x80000 0 0x2000>;
+ 				reg = <0x1000 0 0 0 0>;
+ 				clocks = <&gate_clk 5>;
+ 				marvell,pcie-port = <1>;
+diff --git a/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts b/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts
+index d10669fcd527d..9e9eba8bad5e4 100644
+--- a/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts
++++ b/arch/arm/boot/dts/nuvoton-npcm730-gbs.dts
+@@ -366,7 +366,7 @@
+ 		spi-max-frequency = <20000000>;
+ 		spi-rx-bus-width = <2>;
+ 		label = "bmc";
+-		partitions@80000000 {
++		partitions {
+ 			compatible = "fixed-partitions";
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+diff --git a/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts b/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts
+index 491606c4f044d..2a394cc15284c 100644
+--- a/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts
++++ b/arch/arm/boot/dts/nuvoton-npcm730-gsj.dts
+@@ -142,7 +142,7 @@
+ 		reg = <0>;
+ 		spi-rx-bus-width = <2>;
+ 
+-		partitions@80000000 {
++		partitions {
+ 			compatible = "fixed-partitions";
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+diff --git a/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts b/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts
+index a0c2d76526258..f7b38bee039bc 100644
+--- a/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts
++++ b/arch/arm/boot/dts/nuvoton-npcm730-kudo.dts
+@@ -388,7 +388,7 @@
+ 		spi-max-frequency = <5000000>;
+ 		spi-rx-bus-width = <2>;
+ 		label = "bmc";
+-		partitions@80000000 {
++		partitions {
+ 			compatible = "fixed-partitions";
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+@@ -422,7 +422,7 @@
+ 		reg = <1>;
+ 		spi-max-frequency = <5000000>;
+ 		spi-rx-bus-width = <2>;
+-		partitions@88000000 {
++		partitions {
+ 			compatible = "fixed-partitions";
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+@@ -447,7 +447,7 @@
+ 		reg = <0>;
+ 		spi-max-frequency = <5000000>;
+ 		spi-rx-bus-width = <2>;
+-		partitions@A0000000 {
++		partitions {
+ 			compatible = "fixed-partitions";
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+diff --git a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
+index 3dad32834e5ea..f53d45fa1de87 100644
+--- a/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
++++ b/arch/arm/boot/dts/nuvoton-npcm750-evb.dts
+@@ -74,7 +74,7 @@
+ 		spi-rx-bus-width = <2>;
+ 		reg = <0>;
+ 		spi-max-frequency = <5000000>;
+-		partitions@80000000 {
++		partitions {
+ 			compatible = "fixed-partitions";
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+@@ -135,7 +135,7 @@
+ 		spi-rx-bus-width = <2>;
+ 		reg = <0>;
+ 		spi-max-frequency = <5000000>;
+-		partitions@A0000000 {
++		partitions {
+ 			compatible = "fixed-partitions";
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+diff --git a/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts
+index 132e702281fc5..87359ab05db3e 100644
+--- a/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts
++++ b/arch/arm/boot/dts/nuvoton-npcm750-runbmc-olympus.dts
+@@ -107,7 +107,7 @@
+ 		reg = <0>;
+ 		spi-rx-bus-width = <2>;
+ 
+-		partitions@80000000 {
++		partitions {
+ 			compatible = "fixed-partitions";
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+@@ -146,7 +146,7 @@
+ 		reg = <1>;
+ 		npcm,fiu-rx-bus-width = <2>;
+ 
+-		partitions@88000000 {
++		partitions {
+ 			compatible = "fixed-partitions";
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+@@ -173,7 +173,7 @@
+ 		reg = <0>;
+ 		spi-rx-bus-width = <2>;
+ 
+-		partitions@A0000000 {
++		partitions {
+ 			compatible = "fixed-partitions";
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
+index ada4c828bf2f4..095849423de1d 100644
+--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
+@@ -1580,7 +1580,7 @@
+ 		};
+ 
+ 		etb@1a01000 {
+-			compatible = "coresight-etb10", "arm,primecell";
++			compatible = "arm,coresight-etb10", "arm,primecell";
+ 			reg = <0x1a01000 0x1000>;
+ 
+ 			clocks = <&rpmcc RPM_QDSS_CLK>;
+diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi
+index fd41243a0b2c0..9d5a04a46b14e 100644
+--- a/arch/arm/boot/dts/spear600.dtsi
++++ b/arch/arm/boot/dts/spear600.dtsi
+@@ -47,7 +47,7 @@
+ 			compatible = "arm,pl110", "arm,primecell";
+ 			reg = <0xfc200000 0x1000>;
+ 			interrupt-parent = <&vic1>;
+-			interrupts = <12>;
++			interrupts = <13>;
+ 			status = "disabled";
+ 		};
+ 
+diff --git a/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts b/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts
+index 2e3c9fbb4eb36..275167f26fd9d 100644
+--- a/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts
++++ b/arch/arm/boot/dts/stm32mp157a-dhcor-avenger96.dts
+@@ -13,7 +13,6 @@
+ /dts-v1/;
+ 
+ #include "stm32mp157.dtsi"
+-#include "stm32mp15xc.dtsi"
+ #include "stm32mp15xx-dhcor-som.dtsi"
+ #include "stm32mp15xx-dhcor-avenger96.dtsi"
+ 
+diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+index 90933077d66de..b6957cbdeff5f 100644
+--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
++++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi
+@@ -100,7 +100,7 @@
+ 		regulator-min-microvolt = <3300000>;
+ 		regulator-max-microvolt = <3300000>;
+ 
+-		gpios = <&gpioz 3 GPIO_ACTIVE_HIGH>;
++		gpio = <&gpioz 3 GPIO_ACTIVE_HIGH>;
+ 		enable-active-high;
+ 	};
+ };
+diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
+index 41b2e8abc9e69..708816caf859c 100644
+--- a/arch/arm/mach-mmp/time.c
++++ b/arch/arm/mach-mmp/time.c
+@@ -43,18 +43,21 @@
+ static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE;
+ 
+ /*
+- * FIXME: the timer needs some delay to stablize the counter capture
++ * Read the timer through the CVWR register. Delay is required after requesting
++ * a read. The CR register cannot be directly read due to metastability issues
++ * documented in the PXA168 software manual.
+  */
+ static inline uint32_t timer_read(void)
+ {
+-	int delay = 100;
++	uint32_t val;
++	int delay = 3;
+ 
+ 	__raw_writel(1, mmp_timer_base + TMR_CVWR(1));
+ 
+ 	while (delay--)
+-		cpu_relax();
++		val = __raw_readl(mmp_timer_base + TMR_CVWR(1));
+ 
+-	return __raw_readl(mmp_timer_base + TMR_CVWR(1));
++	return val;
+ }
+ 
+ static u64 notrace mmp_read_sched_clock(void)
+diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
+index 51a63b29d4045..a4d195e9eb8c8 100644
+--- a/arch/arm64/boot/dts/apple/t8103.dtsi
++++ b/arch/arm64/boot/dts/apple/t8103.dtsi
+@@ -412,7 +412,7 @@
+ 			resets = <&ps_ans2>;
+ 		};
+ 
+-		pcie0_dart_0: dart@681008000 {
++		pcie0_dart_0: iommu@681008000 {
+ 			compatible = "apple,t8103-dart";
+ 			reg = <0x6 0x81008000 0x0 0x4000>;
+ 			#iommu-cells = <1>;
+@@ -421,7 +421,7 @@
+ 			power-domains = <&ps_apcie_gp>;
+ 		};
+ 
+-		pcie0_dart_1: dart@682008000 {
++		pcie0_dart_1: iommu@682008000 {
+ 			compatible = "apple,t8103-dart";
+ 			reg = <0x6 0x82008000 0x0 0x4000>;
+ 			#iommu-cells = <1>;
+@@ -430,7 +430,7 @@
+ 			power-domains = <&ps_apcie_gp>;
+ 		};
+ 
+-		pcie0_dart_2: dart@683008000 {
++		pcie0_dart_2: iommu@683008000 {
+ 			compatible = "apple,t8103-dart";
+ 			reg = <0x6 0x83008000 0x0 0x4000>;
+ 			#iommu-cells = <1>;
+diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+index ada164d423f3d..200f97e1c4c9c 100644
+--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
++++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+@@ -125,9 +125,12 @@
+ 	/delete-property/ mrvl,i2c-fast-mode;
+ 	status = "okay";
+ 
++	/* MCP7940MT-I/MNY RTC */
+ 	rtc@6f {
+ 		compatible = "microchip,mcp7940x";
+ 		reg = <0x6f>;
++		interrupt-parent = <&gpiosb>;
++		interrupts = <5 0>; /* GPIO2_5 */
+ 	};
+ };
+ 
+diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+index 9b1af9c801308..d31a194124c91 100644
+--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
++++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+@@ -26,14 +26,14 @@
+ 		stdout-path = "serial0:921600n8";
+ 	};
+ 
+-	cpus_fixed_vproc0: fixedregulator@0 {
++	cpus_fixed_vproc0: regulator-vproc-buck0 {
+ 		compatible = "regulator-fixed";
+ 		regulator-name = "vproc_buck0";
+ 		regulator-min-microvolt = <1000000>;
+ 		regulator-max-microvolt = <1000000>;
+ 	};
+ 
+-	cpus_fixed_vproc1: fixedregulator@1 {
++	cpus_fixed_vproc1: regulator-vproc-buck1 {
+ 		compatible = "regulator-fixed";
+ 		regulator-name = "vproc_buck1";
+ 		regulator-min-microvolt = <1000000>;
+@@ -50,7 +50,7 @@
+ 		id-gpio = <&pio 14 GPIO_ACTIVE_HIGH>;
+ 	};
+ 
+-	usb_p0_vbus: regulator@2 {
++	usb_p0_vbus: regulator-usb-p0-vbus {
+ 		compatible = "regulator-fixed";
+ 		regulator-name = "p0_vbus";
+ 		regulator-min-microvolt = <5000000>;
+@@ -59,7 +59,7 @@
+ 		enable-active-high;
+ 	};
+ 
+-	usb_p1_vbus: regulator@3 {
++	usb_p1_vbus: regulator-usb-p1-vbus {
+ 		compatible = "regulator-fixed";
+ 		regulator-name = "p1_vbus";
+ 		regulator-min-microvolt = <5000000>;
+@@ -68,7 +68,7 @@
+ 		enable-active-high;
+ 	};
+ 
+-	usb_p2_vbus: regulator@4 {
++	usb_p2_vbus: regulator-usb-p2-vbus {
+ 		compatible = "regulator-fixed";
+ 		regulator-name = "p2_vbus";
+ 		regulator-min-microvolt = <5000000>;
+@@ -77,7 +77,7 @@
+ 		enable-active-high;
+ 	};
+ 
+-	usb_p3_vbus: regulator@5 {
++	usb_p3_vbus: regulator-usb-p3-vbus {
+ 		compatible = "regulator-fixed";
+ 		regulator-name = "p3_vbus";
+ 		regulator-min-microvolt = <5000000>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+index 4797537cb3683..2ebefd144d6f5 100644
+--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+@@ -160,70 +160,70 @@
+ 		#clock-cells = <0>;
+ 	};
+ 
+-	clk26m: oscillator@0 {
++	clk26m: oscillator-26m {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <26000000>;
+ 		clock-output-names = "clk26m";
+ 	};
+ 
+-	clk32k: oscillator@1 {
++	clk32k: oscillator-32k {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <32768>;
+ 		clock-output-names = "clk32k";
+ 	};
+ 
+-	clkfpc: oscillator@2 {
++	clkfpc: oscillator-50m {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <50000000>;
+ 		clock-output-names = "clkfpc";
+ 	};
+ 
+-	clkaud_ext_i_0: oscillator@3 {
++	clkaud_ext_i_0: oscillator-aud0 {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <6500000>;
+ 		clock-output-names = "clkaud_ext_i_0";
+ 	};
+ 
+-	clkaud_ext_i_1: oscillator@4 {
++	clkaud_ext_i_1: oscillator-aud1 {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <196608000>;
+ 		clock-output-names = "clkaud_ext_i_1";
+ 	};
+ 
+-	clkaud_ext_i_2: oscillator@5 {
++	clkaud_ext_i_2: oscillator-aud2 {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <180633600>;
+ 		clock-output-names = "clkaud_ext_i_2";
+ 	};
+ 
+-	clki2si0_mck_i: oscillator@6 {
++	clki2si0_mck_i: oscillator-i2s0 {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <30000000>;
+ 		clock-output-names = "clki2si0_mck_i";
+ 	};
+ 
+-	clki2si1_mck_i: oscillator@7 {
++	clki2si1_mck_i: oscillator-i2s1 {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <30000000>;
+ 		clock-output-names = "clki2si1_mck_i";
+ 	};
+ 
+-	clki2si2_mck_i: oscillator@8 {
++	clki2si2_mck_i: oscillator-i2s2 {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <30000000>;
+ 		clock-output-names = "clki2si2_mck_i";
+ 	};
+ 
+-	clktdmin_mclk_i: oscillator@9 {
++	clktdmin_mclk_i: oscillator-mclk {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <30000000>;
+@@ -266,7 +266,7 @@
+ 		reg = <0 0x10005000 0 0x1000>;
+ 	};
+ 
+-	pio: pinctrl@10005000 {
++	pio: pinctrl@1000b000 {
+ 		compatible = "mediatek,mt2712-pinctrl";
+ 		reg = <0 0x1000b000 0 0x1000>;
+ 		mediatek,pctl-regmap = <&syscfg_pctl_a>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt6779.dtsi b/arch/arm64/boot/dts/mediatek/mt6779.dtsi
+index 9bdf5145966c5..dde9ce137b4f1 100644
+--- a/arch/arm64/boot/dts/mediatek/mt6779.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt6779.dtsi
+@@ -88,14 +88,14 @@
+ 		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW 0>;
+ 	};
+ 
+-	clk26m: oscillator@0 {
++	clk26m: oscillator-26m {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <26000000>;
+ 		clock-output-names = "clk26m";
+ 	};
+ 
+-	clk32k: oscillator@1 {
++	clk32k: oscillator-32k {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <32768>;
+@@ -117,7 +117,7 @@
+ 		compatible = "simple-bus";
+ 		ranges;
+ 
+-		gic: interrupt-controller@0c000000 {
++		gic: interrupt-controller@c000000 {
+ 			compatible = "arm,gic-v3";
+ 			#interrupt-cells = <4>;
+ 			interrupt-parent = <&gic>;
+@@ -138,7 +138,7 @@
+ 
+ 		};
+ 
+-		sysirq: intpol-controller@0c53a650 {
++		sysirq: intpol-controller@c53a650 {
+ 			compatible = "mediatek,mt6779-sysirq",
+ 				     "mediatek,mt6577-sysirq";
+ 			interrupt-controller;
+diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
+index 15616231022a2..c3677d77e0a45 100644
+--- a/arch/arm64/boot/dts/mediatek/mt6797.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi
+@@ -95,7 +95,7 @@
+ 		};
+ 	};
+ 
+-	clk26m: oscillator@0 {
++	clk26m: oscillator-26m {
+ 		compatible = "fixed-clock";
+ 		#clock-cells = <0>;
+ 		clock-frequency = <26000000>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+index e3a407d03551f..25b297bbb1b02 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+@@ -13,7 +13,7 @@
+ 	#address-cells = <2>;
+ 	#size-cells = <2>;
+ 
+-	clk40m: oscillator@0 {
++	clk40m: oscillator-40m {
+ 		compatible = "fixed-clock";
+ 		clock-frequency = <40000000>;
+ 		#clock-cells = <0>;
+@@ -162,7 +162,7 @@
+ 			#clock-cells = <1>;
+ 		};
+ 
+-		trng: trng@1020f000 {
++		trng: rng@1020f000 {
+ 			compatible = "mediatek,mt7986-rng",
+ 				     "mediatek,mt7623-rng";
+ 			reg = <0 0x1020f000 0 0x100>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+index 9d32871973a29..85fb61324be8d 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+@@ -1670,7 +1670,7 @@
+ 				<GIC_SPI 278 IRQ_TYPE_LEVEL_LOW>;
+ 			interrupt-names = "job", "mmu", "gpu";
+ 
+-			clocks = <&topckgen CLK_TOP_MFGPLL_CK>;
++			clocks = <&mfgcfg CLK_MFG_BG3D>;
+ 
+ 			power-domains =
+ 				<&spm MT8183_POWER_DOMAIN_MFG_CORE0>,
+diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+index 066c14989708a..e694ddb74f7d5 100644
+--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+@@ -27,7 +27,7 @@
+ 			reg = <0x000>;
+ 			enable-method = "psci";
+ 			clock-frequency = <1701000000>;
+-			capacity-dmips-mhz = <578>;
++			capacity-dmips-mhz = <308>;
+ 			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+ 			next-level-cache = <&l2_0>;
+ 			#cooling-cells = <2>;
+@@ -39,7 +39,7 @@
+ 			reg = <0x100>;
+ 			enable-method = "psci";
+ 			clock-frequency = <1701000000>;
+-			capacity-dmips-mhz = <578>;
++			capacity-dmips-mhz = <308>;
+ 			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+ 			next-level-cache = <&l2_0>;
+ 			#cooling-cells = <2>;
+@@ -51,7 +51,7 @@
+ 			reg = <0x200>;
+ 			enable-method = "psci";
+ 			clock-frequency = <1701000000>;
+-			capacity-dmips-mhz = <578>;
++			capacity-dmips-mhz = <308>;
+ 			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+ 			next-level-cache = <&l2_0>;
+ 			#cooling-cells = <2>;
+@@ -63,7 +63,7 @@
+ 			reg = <0x300>;
+ 			enable-method = "psci";
+ 			clock-frequency = <1701000000>;
+-			capacity-dmips-mhz = <578>;
++			capacity-dmips-mhz = <308>;
+ 			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+ 			next-level-cache = <&l2_0>;
+ 			#cooling-cells = <2>;
+diff --git a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
+index 8ee1529683a34..ec8dfb3d1c6d6 100644
+--- a/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
++++ b/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
+@@ -17,7 +17,7 @@
+ 	};
+ 
+ 	firmware {
+-		optee: optee@4fd00000 {
++		optee: optee {
+ 			compatible = "linaro,optee-tz";
+ 			method = "smc";
+ 		};
+@@ -209,7 +209,7 @@
+ 		};
+ 	};
+ 
+-	i2c0_pins_a: i2c0@0 {
++	i2c0_pins_a: i2c0 {
+ 		pins1 {
+ 			pinmux = <MT8516_PIN_58_SDA0__FUNC_SDA0_0>,
+ 				 <MT8516_PIN_59_SCL0__FUNC_SCL0_0>;
+@@ -217,7 +217,7 @@
+ 		};
+ 	};
+ 
+-	i2c2_pins_a: i2c2@0 {
++	i2c2_pins_a: i2c2 {
+ 		pins1 {
+ 			pinmux = <MT8516_PIN_60_SDA2__FUNC_SDA2_0>,
+ 				 <MT8516_PIN_61_SCL2__FUNC_SCL2_0>;
+diff --git a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
+index 567b331065560..92f264891d84b 100644
+--- a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
++++ b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
+@@ -368,7 +368,7 @@
+ 
+ 	bus-width = <4>;
+ 
+-	cd-gpios = <&tlmm 38 0x1>;
++	cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+ 
+ 	vmmc-supply = <&vreg_l21a_2p95>;
+ 	vqmmc-supply = <&vreg_l13a_2p95>;
+diff --git a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts
+index 1ba2eca33c7b6..6a716c83e5f1d 100644
+--- a/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts
++++ b/arch/arm64/boot/dts/qcom/ipq6018-cp01-c1.dts
+@@ -37,6 +37,8 @@
+ 
+ &blsp1_spi1 {
+ 	cs-select = <0>;
++	pinctrl-0 = <&spi_0_pins>;
++	pinctrl-names = "default";
+ 	status = "okay";
+ 
+ 	flash@0 {
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+index 48bc2e09128d9..863a60b636416 100644
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
+@@ -1331,7 +1331,7 @@
+ 		};
+ 
+ 		mpss: remoteproc@4080000 {
+-			compatible = "qcom,msm8916-mss-pil", "qcom,q6v5-pil";
++			compatible = "qcom,msm8916-mss-pil";
+ 			reg = <0x04080000 0x100>,
+ 			      <0x04020000 0x040>;
+ 
+diff --git a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
+index f430d797196f5..ff60b7004d260 100644
+--- a/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
+@@ -471,7 +471,7 @@
+ &sdhc2 {
+ 	status = "okay";
+ 
+-	cd-gpios = <&tlmm 100 0>;
++	cd-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>;
+ 	vmmc-supply = <&pm8994_l21>;
+ 	vqmmc-supply = <&pm8994_l13>;
+ };
+diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi
+index 8bc6c070e3066..86ef0091cafff 100644
+--- a/arch/arm64/boot/dts/qcom/msm8994.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi
+@@ -6,6 +6,7 @@
+ #include <dt-bindings/clock/qcom,gcc-msm8994.h>
+ #include <dt-bindings/clock/qcom,mmcc-msm8994.h>
+ #include <dt-bindings/clock/qcom,rpmcc.h>
++#include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/power/qcom-rpmpd.h>
+ 
+ / {
+@@ -502,7 +503,7 @@
+ 			pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>;
+ 			pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>;
+ 
+-			cd-gpios = <&tlmm 100 0>;
++			cd-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>;
+ 			bus-width = <4>;
+ 			status = "disabled";
+ 		};
+diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+index 742eac4ce9b35..5cf04c350a62c 100644
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
+@@ -7,6 +7,7 @@
+ #include <dt-bindings/clock/qcom,mmcc-msm8996.h>
+ #include <dt-bindings/clock/qcom,rpmcc.h>
+ #include <dt-bindings/interconnect/qcom,msm8996.h>
++#include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/power/qcom-rpmpd.h>
+ #include <dt-bindings/soc/qcom,apr.h>
+ #include <dt-bindings/thermal/thermal.h>
+@@ -143,82 +144,92 @@
+ 		/* Nominal fmax for now */
+ 		opp-307200000 {
+ 			opp-hz = /bits/ 64 <307200000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-422400000 {
+ 			opp-hz = /bits/ 64 <422400000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-480000000 {
+ 			opp-hz = /bits/ 64 <480000000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-556800000 {
+ 			opp-hz = /bits/ 64 <556800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-652800000 {
+ 			opp-hz = /bits/ 64 <652800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-729600000 {
+ 			opp-hz = /bits/ 64 <729600000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-844800000 {
+ 			opp-hz = /bits/ 64 <844800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-960000000 {
+ 			opp-hz = /bits/ 64 <960000000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1036800000 {
+ 			opp-hz = /bits/ 64 <1036800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1113600000 {
+ 			opp-hz = /bits/ 64 <1113600000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1190400000 {
+ 			opp-hz = /bits/ 64 <1190400000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1228800000 {
+ 			opp-hz = /bits/ 64 <1228800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1324800000 {
+ 			opp-hz = /bits/ 64 <1324800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x5>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1363200000 {
++			opp-hz = /bits/ 64 <1363200000>;
++			opp-supported-hw = <0x2>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1401600000 {
+ 			opp-hz = /bits/ 64 <1401600000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x5>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1478400000 {
+ 			opp-hz = /bits/ 64 <1478400000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x1>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1497600000 {
++			opp-hz = /bits/ 64 <1497600000>;
++			opp-supported-hw = <0x04>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1593600000 {
+ 			opp-hz = /bits/ 64 <1593600000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x1>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 	};
+@@ -231,127 +242,137 @@
+ 		/* Nominal fmax for now */
+ 		opp-307200000 {
+ 			opp-hz = /bits/ 64 <307200000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-403200000 {
+ 			opp-hz = /bits/ 64 <403200000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-480000000 {
+ 			opp-hz = /bits/ 64 <480000000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-556800000 {
+ 			opp-hz = /bits/ 64 <556800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-652800000 {
+ 			opp-hz = /bits/ 64 <652800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-729600000 {
+ 			opp-hz = /bits/ 64 <729600000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-806400000 {
+ 			opp-hz = /bits/ 64 <806400000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-883200000 {
+ 			opp-hz = /bits/ 64 <883200000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-940800000 {
+ 			opp-hz = /bits/ 64 <940800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1036800000 {
+ 			opp-hz = /bits/ 64 <1036800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1113600000 {
+ 			opp-hz = /bits/ 64 <1113600000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1190400000 {
+ 			opp-hz = /bits/ 64 <1190400000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1248000000 {
+ 			opp-hz = /bits/ 64 <1248000000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1324800000 {
+ 			opp-hz = /bits/ 64 <1324800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1401600000 {
+ 			opp-hz = /bits/ 64 <1401600000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1478400000 {
+ 			opp-hz = /bits/ 64 <1478400000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1555200000 {
+ 			opp-hz = /bits/ 64 <1555200000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1632000000 {
+ 			opp-hz = /bits/ 64 <1632000000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1708800000 {
+ 			opp-hz = /bits/ 64 <1708800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1785600000 {
+ 			opp-hz = /bits/ 64 <1785600000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x7>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1804800000 {
++			opp-hz = /bits/ 64 <1804800000>;
++			opp-supported-hw = <0x6>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1824000000 {
+ 			opp-hz = /bits/ 64 <1824000000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x1>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1900800000 {
++			opp-hz = /bits/ 64 <1900800000>;
++			opp-supported-hw = <0x4>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1920000000 {
+ 			opp-hz = /bits/ 64 <1920000000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x1>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-1996800000 {
+ 			opp-hz = /bits/ 64 <1996800000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x1>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-2073600000 {
+ 			opp-hz = /bits/ 64 <2073600000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x1>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 		opp-2150400000 {
+ 			opp-hz = /bits/ 64 <2150400000>;
+-			opp-supported-hw = <0x77>;
++			opp-supported-hw = <0x1>;
+ 			clock-latency-ns = <200000>;
+ 		};
+ 	};
+@@ -1208,17 +1229,17 @@
+ 				compatible = "operating-points-v2";
+ 
+ 				/*
+-				 * 624Mhz and 560Mhz are only available on speed
+-				 * bin (1 << 0). All the rest are available on
+-				 * all bins of the hardware
++				 * 624Mhz is only available on speed bins 0 and 3.
++				 * 560Mhz is only available on speed bins 0, 2 and 3.
++				 * All the rest are available on all bins of the hardware.
+ 				 */
+ 				opp-624000000 {
+ 					opp-hz = /bits/ 64 <624000000>;
+-					opp-supported-hw = <0x01>;
++					opp-supported-hw = <0x09>;
+ 				};
+ 				opp-560000000 {
+ 					opp-hz = /bits/ 64 <560000000>;
+-					opp-supported-hw = <0x01>;
++					opp-supported-hw = <0x0d>;
+ 				};
+ 				opp-510000000 {
+ 					opp-hz = /bits/ 64 <510000000>;
+@@ -3337,7 +3358,7 @@
+ 					interrupt-names = "intr1", "intr2";
+ 					interrupt-controller;
+ 					#interrupt-cells = <1>;
+-					reset-gpios = <&tlmm 64 0>;
++					reset-gpios = <&tlmm 64 GPIO_ACTIVE_LOW>;
+ 
+ 					slim-ifc-dev = <&tasha_ifd>;
+ 
+diff --git a/arch/arm64/boot/dts/qcom/msm8996pro.dtsi b/arch/arm64/boot/dts/qcom/msm8996pro.dtsi
+new file mode 100644
+index 0000000000000..63e1b4ec7a360
+--- /dev/null
++++ b/arch/arm64/boot/dts/qcom/msm8996pro.dtsi
+@@ -0,0 +1,266 @@
++// SPDX-License-Identifier: BSD-3-Clause
++/*
++ * Copyright (c) 2022, Linaro Limited
++ */
++
++#include "msm8996.dtsi"
++
++/ {
++	/delete-node/ opp-table-cluster0;
++	/delete-node/ opp-table-cluster1;
++
++	/*
++	 * On MSM8996 Pro the cpufreq driver shifts speed bins into the high
++	 * nibble of supported hw, so speed bin 0 becomes 0x10, speed bin 1
++	 * becomes 0x20, speed 2 becomes 0x40.
++	 */
++
++	cluster0_opp: opp-table-cluster0 {
++		compatible = "operating-points-v2-kryo-cpu";
++		nvmem-cells = <&speedbin_efuse>;
++		opp-shared;
++
++		opp-307200000 {
++			opp-hz = /bits/ 64 <307200000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-384000000 {
++			opp-hz = /bits/ 64 <384000000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-460800000 {
++			opp-hz = /bits/ 64 <460800000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-537600000 {
++			opp-hz = /bits/ 64 <537600000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-614400000 {
++			opp-hz = /bits/ 64 <614400000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-691200000 {
++			opp-hz = /bits/ 64 <691200000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-768000000 {
++			opp-hz = /bits/ 64 <768000000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-844800000 {
++			opp-hz = /bits/ 64 <844800000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-902400000 {
++			opp-hz = /bits/ 64 <902400000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-979200000 {
++			opp-hz = /bits/ 64 <979200000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1056000000 {
++			opp-hz = /bits/ 64 <1056000000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1132800000 {
++			opp-hz = /bits/ 64 <1132800000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1209600000 {
++			opp-hz = /bits/ 64 <1209600000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1286400000 {
++			opp-hz = /bits/ 64 <1286400000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1363200000 {
++			opp-hz = /bits/ 64 <1363200000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1440000000 {
++			opp-hz = /bits/ 64 <1440000000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1516800000 {
++			opp-hz = /bits/ 64 <1516800000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1593600000 {
++			opp-hz = /bits/ 64 <1593600000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1996800000 {
++			opp-hz = /bits/ 64 <1996800000>;
++			opp-supported-hw = <0x20>;
++			clock-latency-ns = <200000>;
++		};
++		opp-2188800000 {
++			opp-hz = /bits/ 64 <2188800000>;
++			opp-supported-hw = <0x10>;
++			clock-latency-ns = <200000>;
++		};
++	};
++
++	cluster1_opp: opp-table-cluster1 {
++		compatible = "operating-points-v2-kryo-cpu";
++		nvmem-cells = <&speedbin_efuse>;
++		opp-shared;
++
++		opp-307200000 {
++			opp-hz = /bits/ 64 <307200000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-384000000 {
++			opp-hz = /bits/ 64 <384000000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-460800000 {
++			opp-hz = /bits/ 64 <460800000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-537600000 {
++			opp-hz = /bits/ 64 <537600000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-614400000 {
++			opp-hz = /bits/ 64 <614400000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-691200000 {
++			opp-hz = /bits/ 64 <691200000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-748800000 {
++			opp-hz = /bits/ 64 <748800000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-825600000 {
++			opp-hz = /bits/ 64 <825600000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-902400000 {
++			opp-hz = /bits/ 64 <902400000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-979200000 {
++			opp-hz = /bits/ 64 <979200000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1056000000 {
++			opp-hz = /bits/ 64 <1056000000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1132800000 {
++			opp-hz = /bits/ 64 <1132800000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1209600000 {
++			opp-hz = /bits/ 64 <1209600000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1286400000 {
++			opp-hz = /bits/ 64 <1286400000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1363200000 {
++			opp-hz = /bits/ 64 <1363200000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1440000000 {
++			opp-hz = /bits/ 64 <1440000000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1516800000 {
++			opp-hz = /bits/ 64 <1516800000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1593600000 {
++			opp-hz = /bits/ 64 <1593600000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1670400000 {
++			opp-hz = /bits/ 64 <1670400000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1747200000 {
++			opp-hz = /bits/ 64 <1747200000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1824000000 {
++			opp-hz = /bits/ 64 <1824000000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1900800000 {
++			opp-hz = /bits/ 64 <1900800000>;
++			opp-supported-hw = <0x70>;
++			clock-latency-ns = <200000>;
++		};
++		opp-1977600000 {
++			opp-hz = /bits/ 64 <1977600000>;
++			opp-supported-hw = <0x30>;
++			clock-latency-ns = <200000>;
++		};
++		opp-2054400000 {
++			opp-hz = /bits/ 64 <2054400000>;
++			opp-supported-hw = <0x30>;
++			clock-latency-ns = <200000>;
++		};
++		opp-2150400000 {
++			opp-hz = /bits/ 64 <2150400000>;
++			opp-supported-hw = <0x30>;
++			clock-latency-ns = <200000>;
++		};
++		opp-2246400000 {
++			opp-hz = /bits/ 64 <2246400000>;
++			opp-supported-hw = <0x10>;
++			clock-latency-ns = <200000>;
++		};
++		opp-2342400000 {
++			opp-hz = /bits/ 64 <2342400000>;
++			opp-supported-hw = <0x10>;
++			clock-latency-ns = <200000>;
++		};
++	};
++};
+diff --git a/arch/arm64/boot/dts/qcom/pm6350.dtsi b/arch/arm64/boot/dts/qcom/pm6350.dtsi
+index ecf9b99191828..68245d78d2b93 100644
+--- a/arch/arm64/boot/dts/qcom/pm6350.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm6350.dtsi
+@@ -3,6 +3,7 @@
+  * Copyright (c) 2021, Luca Weiss <luca@z3ntu.xyz>
+  */
+ 
++#include <dt-bindings/input/input.h>
+ #include <dt-bindings/spmi/spmi.h>
+ 
+ &spmi_bus {
+diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi
+index d0eefbb516634..d8c9ece20cd9a 100644
+--- a/arch/arm64/boot/dts/qcom/pm660.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm660.dtsi
+@@ -163,7 +163,7 @@
+ 				qcom,pre-scaling = <1 3>;
+ 			};
+ 
+-			vcoin: vcoin@83 {
++			vcoin: vcoin@85 {
+ 				reg = <ADC5_VCOIN>;
+ 				qcom,decimation = <1024>;
+ 				qcom,pre-scaling = <1 3>;
+diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
+index 1bd6c7dcd9e91..bfab67f4a7c9c 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
+@@ -194,6 +194,12 @@ ap_ts_pen_1v8: &i2c4 {
+ 		pins = "gpio49", "gpio50", "gpio51", "gpio52";
+ 		function = "mi2s_1";
+ 	};
++
++	pinconf {
++		pins = "gpio49", "gpio50", "gpio51", "gpio52";
++		drive-strength = <2>;
++		bias-pull-down;
++	};
+ };
+ 
+ &ts_reset_l {
+diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+index 1bc9091cad2a8..12f01815230bc 100644
+--- a/arch/arm64/boot/dts/qcom/sdm630.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
+@@ -773,7 +773,7 @@
+ 					pins = "gpio17", "gpio18", "gpio19";
+ 					function = "gpio";
+ 					drive-strength = <2>;
+-					bias-no-pull;
++					bias-disable;
+ 				};
+ 			};
+ 
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
+index b5eb8f7eca1d5..b5f11fbcc3004 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
++++ b/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
+@@ -1436,7 +1436,7 @@ ap_ts_i2c: &i2c14 {
+ 		config {
+ 			pins = "gpio126";
+ 			function = "gpio";
+-			bias-no-pull;
++			bias-disable;
+ 			drive-strength = <2>;
+ 			output-low;
+ 		};
+@@ -1446,7 +1446,7 @@ ap_ts_i2c: &i2c14 {
+ 		config {
+ 			pins = "gpio126";
+ 			function = "gpio";
+-			bias-no-pull;
++			bias-disable;
+ 			drive-strength = <2>;
+ 			output-high;
+ 		};
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+index c6e2c571b4527..b2eddcd875069 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+@@ -1081,7 +1081,7 @@
+ 	pinctrl-names = "default";
+ 	clock-names = "extclk";
+ 	clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
+-	reset-gpios = <&tlmm 64 0>;
++	reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
+ 	vdd-buck-supply = <&vreg_s4a_1p8>;
+ 	vdd-buck-sido-supply = <&vreg_s4a_1p8>;
+ 	vdd-tx-supply = <&vreg_s4a_1p8>;
+@@ -1255,7 +1255,7 @@
+ 		reg = <0x60>;
+ 
+ 		// CAM3_RST_N
+-		enable-gpios = <&tlmm 21 0>;
++		enable-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+ 		pinctrl-names = "default";
+ 		pinctrl-0 = <&cam3_default>;
+ 		gpios = <&tlmm 16 0>,
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts
+index 82c27f90d300d..0f470cf1ed1c1 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts
+@@ -546,7 +546,7 @@
+ 	pinctrl-names = "default";
+ 	clock-names = "extclk";
+ 	clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
+-	reset-gpios = <&tlmm 64 0>;
++	reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
+ 	vdd-buck-supply = <&vreg_s4a_1p8>;
+ 	vdd-buck-sido-supply = <&vreg_s4a_1p8>;
+ 	vdd-tx-supply = <&vreg_s4a_1p8>;
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+index dba7c2693ff50..1cc477c309451 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+@@ -126,7 +126,7 @@
+ 		regulator-min-microvolt = <1800000>;
+ 		regulator-max-microvolt = <1800000>;
+ 
+-		gpio = <&tlmm 23 0>;
++		gpio = <&tlmm 23 GPIO_ACTIVE_HIGH>;
+ 		regulator-always-on;
+ 		regulator-boot-on;
+ 		enable-active-high;
+@@ -628,7 +628,7 @@
+ 	};
+ 
+ 	wcd_intr_default: wcd-intr-default {
+-		pins = "goui54";
++		pins = "gpio54";
+ 		function = "gpio";
+ 		input-enable;
+ 		bias-pull-down;
+@@ -712,7 +712,7 @@
+ 	pinctrl-names = "default";
+ 	clock-names = "extclk";
+ 	clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
+-	reset-gpios = <&tlmm 64 0>;
++	reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
+ 	vdd-buck-sido-supply = <&vreg_s4a_1p8>;
+ 	vdd-buck-supply = <&vreg_s4a_1p8>;
+ 	vdd-tx-supply = <&vreg_s4a_1p8>;
+diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+index a7af1bed43129..be59a8ba9c1fe 100644
+--- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
++++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+@@ -772,7 +772,7 @@
+ 	pinctrl-names = "default";
+ 	clock-names = "extclk";
+ 	clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
+-	reset-gpios = <&tlmm 64 0>;
++	reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
+ 	vdd-buck-supply = <&vreg_s4a_1p8>;
+ 	vdd-buck-sido-supply = <&vreg_s4a_1p8>;
+ 	vdd-tx-supply = <&vreg_s4a_1p8>;
+diff --git a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
+index b0315eeb13205..f954fe5cb61ab 100644
+--- a/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
++++ b/arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts
+@@ -704,7 +704,7 @@
+ 	pinctrl-names = "default";
+ 	clock-names = "extclk";
+ 	clocks = <&rpmhcc RPMH_LN_BB_CLK2>;
+-	reset-gpios = <&tlmm 64 0>;
++	reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
+ 	vdd-buck-supply = <&vreg_s4a_1p8>;
+ 	vdd-buck-sido-supply = <&vreg_s4a_1p8>;
+ 	vdd-tx-supply = <&vreg_s4a_1p8>;
+diff --git a/arch/arm64/boot/dts/qcom/sm6125.dtsi b/arch/arm64/boot/dts/qcom/sm6125.dtsi
+index 8c582a9e4ada4..0127224086823 100644
+--- a/arch/arm64/boot/dts/qcom/sm6125.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi
+@@ -458,7 +458,7 @@
+ 		sdhc_1: mmc@4744000 {
+ 			compatible = "qcom,sm6125-sdhci", "qcom,sdhci-msm-v5";
+ 			reg = <0x04744000 0x1000>, <0x04745000 0x1000>;
+-			reg-names = "hc", "core";
++			reg-names = "hc", "cqhci";
+ 
+ 			interrupts = <GIC_SPI 348 IRQ_TYPE_LEVEL_HIGH>,
+ 				     <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
+diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+index d06aefdf3d9ed..76608c1d7f0c4 100644
+--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi
+@@ -482,6 +482,7 @@
+ 			interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH>,
+ 				     <GIC_SPI 644 IRQ_TYPE_LEVEL_HIGH>;
+ 			interrupt-names = "hc_irq", "pwr_irq";
++			iommus = <&apps_smmu 0x60 0x0>;
+ 
+ 			clocks = <&gcc GCC_SDCC1_AHB_CLK>,
+ 				 <&gcc GCC_SDCC1_APPS_CLK>,
+@@ -928,6 +929,7 @@
+ 			interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>,
+ 				     <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
+ 			interrupt-names = "hc_irq", "pwr_irq";
++			iommus = <&apps_smmu 0x560 0x0>;
+ 
+ 			clocks = <&gcc GCC_SDCC2_AHB_CLK>,
+ 				 <&gcc GCC_SDCC2_APPS_CLK>,
+@@ -1005,15 +1007,11 @@
+ 			dp_phy: dp-phy@88ea200 {
+ 				reg = <0 0x088ea200 0 0x200>,
+ 				      <0 0x088ea400 0 0x200>,
+-				      <0 0x088eac00 0 0x400>,
++				      <0 0x088eaa00 0 0x200>,
+ 				      <0 0x088ea600 0 0x200>,
+-				      <0 0x088ea800 0 0x200>,
+-				      <0 0x088eaa00 0 0x100>;
++				      <0 0x088ea800 0 0x200>;
+ 				#phy-cells = <0>;
+ 				#clock-cells = <1>;
+-				clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+-				clock-names = "pipe0";
+-				clock-output-names = "usb3_phy_pipe_clk_src";
+ 			};
+ 		};
+ 
+diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+index 916f12b799b79..3df80dde92496 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
+@@ -2038,11 +2038,11 @@
+ 			status = "disabled";
+ 
+ 			ufs_mem_phy_lanes: phy@1d87400 {
+-				reg = <0 0x01d87400 0 0x108>,
+-				      <0 0x01d87600 0 0x1e0>,
+-				      <0 0x01d87c00 0 0x1dc>,
+-				      <0 0x01d87800 0 0x108>,
+-				      <0 0x01d87a00 0 0x1e0>;
++				reg = <0 0x01d87400 0 0x16c>,
++				      <0 0x01d87600 0 0x200>,
++				      <0 0x01d87c00 0 0x200>,
++				      <0 0x01d87800 0 0x16c>,
++				      <0 0x01d87a00 0 0x200>;
+ 				#phy-cells = <0>;
+ 			};
+ 		};
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts
+index 7ab3627cc347d..a05fe468e0b41 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-mtp.dts
++++ b/arch/arm64/boot/dts/qcom/sm8250-mtp.dts
+@@ -635,7 +635,7 @@
+ 	wcd938x: codec {
+ 		compatible = "qcom,wcd9380-codec";
+ 		#sound-dai-cells = <1>;
+-		reset-gpios = <&tlmm 32 0>;
++		reset-gpios = <&tlmm 32 GPIO_ACTIVE_LOW>;
+ 		vdd-buck-supply = <&vreg_s4a_1p8>;
+ 		vdd-rxtx-supply = <&vreg_s4a_1p8>;
+ 		vdd-io-supply = <&vreg_s4a_1p8>;
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+index 5428aab3058dd..e4769dcfaad7b 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+@@ -619,7 +619,7 @@
+ 		pins = "gpio39";
+ 		function = "gpio";
+ 		drive-strength = <2>;
+-		bias-disabled;
++		bias-disable;
+ 		input-enable;
+ 	};
+ 
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index 052b4dbc1ee44..652fb0231da0e 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -2172,11 +2172,11 @@
+ 			status = "disabled";
+ 
+ 			ufs_mem_phy_lanes: phy@1d87400 {
+-				reg = <0 0x01d87400 0 0x108>,
+-				      <0 0x01d87600 0 0x1e0>,
+-				      <0 0x01d87c00 0 0x1dc>,
+-				      <0 0x01d87800 0 0x108>,
+-				      <0 0x01d87a00 0 0x1e0>;
++				reg = <0 0x01d87400 0 0x16c>,
++				      <0 0x01d87600 0 0x200>,
++				      <0 0x01d87c00 0 0x200>,
++				      <0 0x01d87800 0 0x16c>,
++				      <0 0x01d87a00 0 0x200>;
+ 				#phy-cells = <0>;
+ 			};
+ 		};
+@@ -2447,7 +2447,7 @@
+ 					pins = "gpio7";
+ 					function = "dmic1_data";
+ 					drive-strength = <2>;
+-					pull-down;
++					bias-pull-down;
+ 					input-enable;
+ 				};
+ 			};
+@@ -2884,15 +2884,11 @@
+ 			dp_phy: dp-phy@88ea200 {
+ 				reg = <0 0x088ea200 0 0x200>,
+ 				      <0 0x088ea400 0 0x200>,
+-				      <0 0x088eac00 0 0x400>,
++				      <0 0x088eaa00 0 0x200>,
+ 				      <0 0x088ea600 0 0x200>,
+-				      <0 0x088ea800 0 0x200>,
+-				      <0 0x088eaa00 0 0x100>;
++				      <0 0x088ea800 0 0x200>;
+ 				#phy-cells = <0>;
+ 				#clock-cells = <1>;
+-				clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+-				clock-names = "pipe0";
+-				clock-output-names = "usb3_phy_pipe_clk_src";
+ 			};
+ 		};
+ 
+diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+index d9b08dfc2980d..eace5b2ee3812 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
+@@ -2142,11 +2142,11 @@
+ 			status = "disabled";
+ 
+ 			ufs_mem_phy_lanes: phy@1d87400 {
+-				reg = <0 0x01d87400 0 0x108>,
+-				      <0 0x01d87600 0 0x1e0>,
+-				      <0 0x01d87c00 0 0x1dc>,
+-				      <0 0x01d87800 0 0x108>,
+-				      <0 0x01d87a00 0 0x1e0>;
++				reg = <0 0x01d87400 0 0x188>,
++				      <0 0x01d87600 0 0x200>,
++				      <0 0x01d87c00 0 0x200>,
++				      <0 0x01d87800 0 0x188>,
++				      <0 0x01d87a00 0 0x200>;
+ 				#phy-cells = <0>;
+ 			};
+ 		};
+diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+index 8a6c0f3e7bb70..ed3e1eff4f58f 100644
+--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+@@ -3131,11 +3131,11 @@
+ 			status = "disabled";
+ 
+ 			ufs_mem_phy_lanes: phy@1d87400 {
+-				reg = <0 0x01d87400 0 0x108>,
+-				      <0 0x01d87600 0 0x1e0>,
+-				      <0 0x01d87c00 0 0x1dc>,
+-				      <0 0x01d87800 0 0x108>,
+-				      <0 0x01d87a00 0 0x1e0>;
++				reg = <0 0x01d87400 0 0x188>,
++				      <0 0x01d87600 0 0x200>,
++				      <0 0x01d87c00 0 0x200>,
++				      <0 0x01d87800 0 0x188>,
++				      <0 0x01d87a00 0 0x200>;
+ 				#phy-cells = <0>;
+ 			};
+ 		};
+diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
+index 384817ffa4deb..d4f3ebfe841ab 100644
+--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
+@@ -442,7 +442,7 @@
+ 			reg = <0 0xe6540000 0 0x60>;
+ 			interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>;
+ 			clocks = <&cpg CPG_MOD 514>,
+-				 <&cpg CPG_CORE R8A779F0_CLK_S0D3>,
++				 <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ 				 <&scif_clk>;
+ 			clock-names = "fck", "brg_int", "scif_clk";
+ 			dmas = <&dmac0 0x31>, <&dmac0 0x30>,
+@@ -459,7 +459,7 @@
+ 			reg = <0 0xe6550000 0 0x60>;
+ 			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+ 			clocks = <&cpg CPG_MOD 515>,
+-				 <&cpg CPG_CORE R8A779F0_CLK_S0D3>,
++				 <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ 				 <&scif_clk>;
+ 			clock-names = "fck", "brg_int", "scif_clk";
+ 			dmas = <&dmac0 0x33>, <&dmac0 0x32>,
+@@ -476,7 +476,7 @@
+ 			reg = <0 0xe6560000 0 0x60>;
+ 			interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+ 			clocks = <&cpg CPG_MOD 516>,
+-				 <&cpg CPG_CORE R8A779F0_CLK_S0D3>,
++				 <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ 				 <&scif_clk>;
+ 			clock-names = "fck", "brg_int", "scif_clk";
+ 			dmas = <&dmac0 0x35>, <&dmac0 0x34>,
+@@ -493,7 +493,7 @@
+ 			reg = <0 0xe66a0000 0 0x60>;
+ 			interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
+ 			clocks = <&cpg CPG_MOD 517>,
+-				 <&cpg CPG_CORE R8A779F0_CLK_S0D3>,
++				 <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ 				 <&scif_clk>;
+ 			clock-names = "fck", "brg_int", "scif_clk";
+ 			dmas = <&dmac0 0x37>, <&dmac0 0x36>,
+@@ -522,7 +522,7 @@
+ 			reg = <0 0xe6e60000 0 64>;
+ 			interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
+ 			clocks = <&cpg CPG_MOD 702>,
+-				 <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>,
++				 <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ 				 <&scif_clk>;
+ 			clock-names = "fck", "brg_int", "scif_clk";
+ 			dmas = <&dmac0 0x51>, <&dmac0 0x50>,
+@@ -539,7 +539,7 @@
+ 			reg = <0 0xe6e68000 0 64>;
+ 			interrupts = <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>;
+ 			clocks = <&cpg CPG_MOD 703>,
+-				 <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>,
++				 <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ 				 <&scif_clk>;
+ 			clock-names = "fck", "brg_int", "scif_clk";
+ 			dmas = <&dmac0 0x53>, <&dmac0 0x52>,
+@@ -556,7 +556,7 @@
+ 			reg = <0 0xe6c50000 0 64>;
+ 			interrupts = <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH>;
+ 			clocks = <&cpg CPG_MOD 704>,
+-				 <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>,
++				 <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ 				 <&scif_clk>;
+ 			clock-names = "fck", "brg_int", "scif_clk";
+ 			dmas = <&dmac0 0x57>, <&dmac0 0x56>,
+@@ -573,7 +573,7 @@
+ 			reg = <0 0xe6c40000 0 64>;
+ 			interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>;
+ 			clocks = <&cpg CPG_MOD 705>,
+-				 <&cpg CPG_CORE R8A779F0_CLK_S0D3_PER>,
++				 <&cpg CPG_CORE R8A779F0_CLK_SASYNCPERD1>,
+ 				 <&scif_clk>;
+ 			clock-names = "fck", "brg_int", "scif_clk";
+ 			dmas = <&dmac0 0x59>, <&dmac0 0x58>,
+diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
+index 1c15726cff8bf..4bd3cb107b38b 100644
+--- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
++++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
+@@ -87,7 +87,7 @@
+ 			reg = <0 0xe6540000 0 96>;
+ 			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+ 			clocks = <&cpg CPG_MOD 514>,
+-				 <&cpg CPG_CORE R8A779G0_CLK_S0D3_PER>,
++				 <&cpg CPG_CORE R8A779G0_CLK_SASYNCPERD1>,
+ 				 <&scif_clk>;
+ 			clock-names = "fck", "brg_int", "scif_clk";
+ 			power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
+diff --git a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
+index d4cc5459fbb76..4ce0f39446492 100644
+--- a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
+@@ -48,7 +48,7 @@
+ 		#size-cells = <2>;
+ 		ranges;
+ 
+-		gic: interrupt-controller@82000000 {
++		gic: interrupt-controller@82010000 {
+ 			compatible = "arm,gic-400";
+ 			#interrupt-cells = <3>;
+ 			#address-cells = <0>;
+diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
+index d0abb9aa0e9ed..e3852c9463528 100644
+--- a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
++++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
+@@ -55,14 +55,14 @@
+ 		samsung,pins = "gpf5-0";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_NONE>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV2>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	ufs_refclk_out: ufs-refclk-out-pins {
+ 		samsung,pins = "gpf5-1";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_NONE>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV2>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ };
+ 
+@@ -239,105 +239,105 @@
+ 		samsung,pins = "gpb6-1";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV2>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	pwm1_out: pwm1-out-pins {
+ 		samsung,pins = "gpb6-5";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV2>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	hs_i2c0_bus: hs-i2c0-bus-pins {
+ 		samsung,pins = "gpb0-0", "gpb0-1";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	hs_i2c1_bus: hs-i2c1-bus-pins {
+ 		samsung,pins = "gpb0-2", "gpb0-3";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	hs_i2c2_bus: hs-i2c2-bus-pins {
+ 		samsung,pins = "gpb0-4", "gpb0-5";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	hs_i2c3_bus: hs-i2c3-bus-pins {
+ 		samsung,pins = "gpb0-6", "gpb0-7";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	hs_i2c4_bus: hs-i2c4-bus-pins {
+ 		samsung,pins = "gpb1-0", "gpb1-1";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	hs_i2c5_bus: hs-i2c5-bus-pins {
+ 		samsung,pins = "gpb1-2", "gpb1-3";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	hs_i2c6_bus: hs-i2c6-bus-pins {
+ 		samsung,pins = "gpb1-4", "gpb1-5";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	hs_i2c7_bus: hs-i2c7-bus-pins {
+ 		samsung,pins = "gpb1-6", "gpb1-7";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	uart0_data: uart0-data-pins {
+ 		samsung,pins = "gpb7-0", "gpb7-1";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_NONE>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	uart1_data: uart1-data-pins {
+ 		samsung,pins = "gpb7-4", "gpb7-5";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_NONE>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	spi0_bus: spi0-bus-pins {
+ 		samsung,pins = "gpb4-0", "gpb4-2", "gpb4-3";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	spi1_bus: spi1-bus-pins {
+ 		samsung,pins = "gpb4-4", "gpb4-6", "gpb4-7";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ 
+ 	spi2_bus: spi2-bus-pins {
+ 		samsung,pins = "gpb5-0", "gpb5-2", "gpb5-3";
+ 		samsung,pin-function = <FSD_PIN_FUNC_2>;
+ 		samsung,pin-pud = <FSD_PIN_PULL_UP>;
+-		samsung,pin-drv = <FSD_PIN_DRV_LV1>;
++		samsung,pin-drv = <FSD_PIN_DRV_LV4>;
+ 	};
+ };
+ 
+diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.h b/arch/arm64/boot/dts/tesla/fsd-pinctrl.h
+index 6ffbda3624930..c397d02208a08 100644
+--- a/arch/arm64/boot/dts/tesla/fsd-pinctrl.h
++++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.h
+@@ -16,9 +16,9 @@
+ #define FSD_PIN_PULL_UP			3
+ 
+ #define FSD_PIN_DRV_LV1			0
+-#define FSD_PIN_DRV_LV2			2
+-#define FSD_PIN_DRV_LV3			1
+-#define FSD_PIN_DRV_LV4			3
++#define FSD_PIN_DRV_LV2			1
++#define FSD_PIN_DRV_LV4			2
++#define FSD_PIN_DRV_LV6			3
+ 
+ #define FSD_PIN_FUNC_INPUT		0
+ #define FSD_PIN_FUNC_OUTPUT		1
+diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+index 8919fede3cd76..ef960386c62cb 100644
+--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+@@ -120,7 +120,6 @@
+ 		dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>,
+ 				<&main_udmap 0x4001>;
+ 		dma-names = "tx", "rx1", "rx2";
+-		dma-coherent;
+ 
+ 		rng: rng@4e10000 {
+ 			compatible = "inside-secure,safexcel-eip76";
+diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+index 43b6cf5791eee..75789c0f82bd3 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+@@ -337,7 +337,6 @@
+ 		dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>,
+ 				<&main_udmap 0x4001>;
+ 		dma-names = "tx", "rx1", "rx2";
+-		dma-coherent;
+ 
+ 		rng: rng@4e10000 {
+ 			compatible = "inside-secure,safexcel-eip76";
+diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+index 34e7d577ae13b..c89f28235812a 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+@@ -60,7 +60,7 @@
+ 		#interrupt-cells = <1>;
+ 		ti,sci = <&sms>;
+ 		ti,sci-dev-id = <148>;
+-		ti,interrupt-ranges = <8 360 56>;
++		ti,interrupt-ranges = <8 392 56>;
+ 	};
+ 
+ 	main_pmx0: pinctrl@11c000 {
+diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
+index 4d1bfabd1313a..f0644851602cd 100644
+--- a/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
+@@ -65,7 +65,7 @@
+ 		#interrupt-cells = <1>;
+ 		ti,sci = <&sms>;
+ 		ti,sci-dev-id = <125>;
+-		ti,interrupt-ranges = <16 928 16>;
++		ti,interrupt-ranges = <16 960 16>;
+ 	};
+ 
+ 	mcu_conf: syscon@40f00000 {
+diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
+index 86eb0bfe3b380..d9144b6e078c8 100644
+--- a/arch/arm64/include/asm/processor.h
++++ b/arch/arm64/include/asm/processor.h
+@@ -308,13 +308,13 @@ static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
+ }
+ #endif
+ 
+-static inline bool is_ttbr0_addr(unsigned long addr)
++static __always_inline bool is_ttbr0_addr(unsigned long addr)
+ {
+ 	/* entry assembly clears tags for TTBR0 addrs */
+ 	return addr < TASK_SIZE;
+ }
+ 
+-static inline bool is_ttbr1_addr(unsigned long addr)
++static __always_inline bool is_ttbr1_addr(unsigned long addr)
+ {
+ 	/* TTBR1 addresses may have a tag if KASAN_SW_TAGS is in use */
+ 	return arch_kasan_reset_tag(addr) >= PAGE_OFFSET;
+diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
+index c33f1fad27450..89628bd370d91 100644
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -353,6 +353,11 @@ static bool is_el1_mte_sync_tag_check_fault(unsigned long esr)
+ 	return false;
+ }
+ 
++static bool is_translation_fault(unsigned long esr)
++{
++	return (esr & ESR_ELx_FSC_TYPE) == ESR_ELx_FSC_FAULT;
++}
++
+ static void __do_kernel_fault(unsigned long addr, unsigned long esr,
+ 			      struct pt_regs *regs)
+ {
+@@ -385,7 +390,8 @@ static void __do_kernel_fault(unsigned long addr, unsigned long esr,
+ 	} else if (addr < PAGE_SIZE) {
+ 		msg = "NULL pointer dereference";
+ 	} else {
+-		if (kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
++		if (is_translation_fault(esr) &&
++		    kfence_handle_page_fault(addr, esr & ESR_ELx_WNR, regs))
+ 			return;
+ 
+ 		msg = "paging request";
+diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
+index 6e6756e8fa0a9..86a6e25908664 100644
+--- a/arch/mips/bcm63xx/clk.c
++++ b/arch/mips/bcm63xx/clk.c
+@@ -361,6 +361,8 @@ static struct clk clk_periph = {
+  */
+ int clk_enable(struct clk *clk)
+ {
++	if (!clk)
++		return 0;
+ 	mutex_lock(&clocks_mutex);
+ 	clk_enable_unlocked(clk);
+ 	mutex_unlock(&clocks_mutex);
+diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
+index d09d0769f5496..0fd9ac76eb742 100644
+--- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
++++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
+@@ -211,7 +211,7 @@ union cvmx_helper_link_info __cvmx_helper_board_link_get(int ipd_port)
+ {
+ 	union cvmx_helper_link_info result;
+ 
+-	WARN(!octeon_is_simulation(),
++	WARN_ONCE(!octeon_is_simulation(),
+ 	     "Using deprecated link status - please update your DT");
+ 
+ 	/* Unless we fix it later, all links are defaulted to down */
+diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c
+index 6f49fd9be1f3c..9abfc4bf9bd83 100644
+--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c
++++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c
+@@ -1096,7 +1096,7 @@ union cvmx_helper_link_info cvmx_helper_link_get(int ipd_port)
+ 		if (index == 0)
+ 			result = __cvmx_helper_rgmii_link_get(ipd_port);
+ 		else {
+-			WARN(1, "Using deprecated link status - please update your DT");
++			WARN_ONCE(1, "Using deprecated link status - please update your DT");
+ 			result.s.full_duplex = 1;
+ 			result.s.link_up = 1;
+ 			result.s.speed = 1000;
+diff --git a/arch/mips/include/asm/mach-ralink/mt7621.h b/arch/mips/include/asm/mach-ralink/mt7621.h
+index 6bbf082dd149e..79d5bb0e06d63 100644
+--- a/arch/mips/include/asm/mach-ralink/mt7621.h
++++ b/arch/mips/include/asm/mach-ralink/mt7621.h
+@@ -7,10 +7,12 @@
+ #ifndef _MT7621_REGS_H_
+ #define _MT7621_REGS_H_
+ 
++#define IOMEM(x)			((void __iomem *)(KSEG1ADDR(x)))
++
+ #define MT7621_PALMBUS_BASE		0x1C000000
+ #define MT7621_PALMBUS_SIZE		0x03FFFFFF
+ 
+-#define MT7621_SYSC_BASE		0x1E000000
++#define MT7621_SYSC_BASE		IOMEM(0x1E000000)
+ 
+ #define SYSC_REG_CHIP_NAME0		0x00
+ #define SYSC_REG_CHIP_NAME1		0x04
+diff --git a/arch/mips/kernel/vpe-cmp.c b/arch/mips/kernel/vpe-cmp.c
+index e673603e11e5d..92140edb3ce3e 100644
+--- a/arch/mips/kernel/vpe-cmp.c
++++ b/arch/mips/kernel/vpe-cmp.c
+@@ -75,7 +75,6 @@ ATTRIBUTE_GROUPS(vpe);
+ 
+ static void vpe_device_release(struct device *cd)
+ {
+-	kfree(cd);
+ }
+ 
+ static struct class vpe_class = {
+@@ -157,6 +156,7 @@ out_dev:
+ 	device_del(&vpe_device);
+ 
+ out_class:
++	put_device(&vpe_device);
+ 	class_unregister(&vpe_class);
+ 
+ out_chrdev:
+@@ -169,7 +169,7 @@ void __exit vpe_module_exit(void)
+ {
+ 	struct vpe *v, *n;
+ 
+-	device_del(&vpe_device);
++	device_unregister(&vpe_device);
+ 	class_unregister(&vpe_class);
+ 	unregister_chrdev(major, VPE_MODULE_NAME);
+ 
+diff --git a/arch/mips/kernel/vpe-mt.c b/arch/mips/kernel/vpe-mt.c
+index bad6b0891b2b5..84a82b551ec35 100644
+--- a/arch/mips/kernel/vpe-mt.c
++++ b/arch/mips/kernel/vpe-mt.c
+@@ -313,7 +313,6 @@ ATTRIBUTE_GROUPS(vpe);
+ 
+ static void vpe_device_release(struct device *cd)
+ {
+-	kfree(cd);
+ }
+ 
+ static struct class vpe_class = {
+@@ -497,6 +496,7 @@ out_dev:
+ 	device_del(&vpe_device);
+ 
+ out_class:
++	put_device(&vpe_device);
+ 	class_unregister(&vpe_class);
+ 
+ out_chrdev:
+@@ -509,7 +509,7 @@ void __exit vpe_module_exit(void)
+ {
+ 	struct vpe *v, *n;
+ 
+-	device_del(&vpe_device);
++	device_unregister(&vpe_device);
+ 	class_unregister(&vpe_class);
+ 	unregister_chrdev(major, VPE_MODULE_NAME);
+ 
+diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
+index fb0565bc34fda..bbf5811afbf2c 100644
+--- a/arch/mips/ralink/mt7621.c
++++ b/arch/mips/ralink/mt7621.c
+@@ -25,6 +25,7 @@
+ #define MT7621_MEM_TEST_PATTERN         0xaa5555aa
+ 
+ static u32 detect_magic __initdata;
++static struct ralink_soc_info *soc_info_ptr;
+ 
+ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
+ {
+@@ -97,41 +98,83 @@ void __init ralink_of_remap(void)
+ 		panic("Failed to remap core resources");
+ }
+ 
+-static void soc_dev_init(struct ralink_soc_info *soc_info, u32 rev)
++static unsigned int __init mt7621_get_soc_name0(void)
++{
++	return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME0);
++}
++
++static unsigned int __init mt7621_get_soc_name1(void)
++{
++	return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME1);
++}
++
++static bool __init mt7621_soc_valid(void)
++{
++	if (mt7621_get_soc_name0() == MT7621_CHIP_NAME0 &&
++			mt7621_get_soc_name1() == MT7621_CHIP_NAME1)
++		return true;
++	else
++		return false;
++}
++
++static const char __init *mt7621_get_soc_id(void)
++{
++	if (mt7621_soc_valid())
++		return "MT7621";
++	else
++		return "invalid";
++}
++
++static unsigned int __init mt7621_get_soc_rev(void)
++{
++	return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_REV);
++}
++
++static unsigned int __init mt7621_get_soc_ver(void)
++{
++	return (mt7621_get_soc_rev() >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK;
++}
++
++static unsigned int __init mt7621_get_soc_eco(void)
++{
++	return (mt7621_get_soc_rev() & CHIP_REV_ECO_MASK);
++}
++
++static const char __init *mt7621_get_soc_revision(void)
++{
++	if (mt7621_get_soc_rev() == 1 && mt7621_get_soc_eco() == 1)
++		return "E2";
++	else
++		return "E1";
++}
++
++static int __init mt7621_soc_dev_init(void)
+ {
+ 	struct soc_device *soc_dev;
+ 	struct soc_device_attribute *soc_dev_attr;
+ 
+ 	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+ 	if (!soc_dev_attr)
+-		return;
++		return -ENOMEM;
+ 
+ 	soc_dev_attr->soc_id = "mt7621";
+ 	soc_dev_attr->family = "Ralink";
++	soc_dev_attr->revision = mt7621_get_soc_revision();
+ 
+-	if (((rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK) == 1 &&
+-	    (rev & CHIP_REV_ECO_MASK) == 1)
+-		soc_dev_attr->revision = "E2";
+-	else
+-		soc_dev_attr->revision = "E1";
+-
+-	soc_dev_attr->data = soc_info;
++	soc_dev_attr->data = soc_info_ptr;
+ 
+ 	soc_dev = soc_device_register(soc_dev_attr);
+ 	if (IS_ERR(soc_dev)) {
+ 		kfree(soc_dev_attr);
+-		return;
++		return PTR_ERR(soc_dev);
+ 	}
++
++	return 0;
+ }
++device_initcall(mt7621_soc_dev_init);
+ 
+ void __init prom_soc_init(struct ralink_soc_info *soc_info)
+ {
+-	void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
+-	unsigned char *name = NULL;
+-	u32 n0;
+-	u32 n1;
+-	u32 rev;
+-
+ 	/* Early detection of CMP support */
+ 	mips_cm_probe();
+ 	mips_cpc_probe();
+@@ -154,27 +197,23 @@ void __init prom_soc_init(struct ralink_soc_info *soc_info)
+ 		__sync();
+ 	}
+ 
+-	n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0);
+-	n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1);
+-
+-	if (n0 == MT7621_CHIP_NAME0 && n1 == MT7621_CHIP_NAME1) {
+-		name = "MT7621";
++	if (mt7621_soc_valid())
+ 		soc_info->compatible = "mediatek,mt7621-soc";
+-	} else {
+-		panic("mt7621: unknown SoC, n0:%08x n1:%08x\n", n0, n1);
+-	}
++	else
++		panic("mt7621: unknown SoC, n0:%08x n1:%08x\n",
++				mt7621_get_soc_name0(),
++				mt7621_get_soc_name1());
+ 	ralink_soc = MT762X_SOC_MT7621AT;
+-	rev = __raw_readl(sysc + SYSC_REG_CHIP_REV);
+ 
+ 	snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
+ 		"MediaTek %s ver:%u eco:%u",
+-		name,
+-		(rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
+-		(rev & CHIP_REV_ECO_MASK));
++		mt7621_get_soc_id(),
++		mt7621_get_soc_ver(),
++		mt7621_get_soc_eco());
+ 
+ 	soc_info->mem_detect = mt7621_memory_detect;
+ 
+-	soc_dev_init(soc_info, rev);
++	soc_info_ptr = soc_info;
+ 
+ 	if (!register_cps_smp_ops())
+ 		return;
+diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c
+index ea8072acf8d94..01c132bc33d54 100644
+--- a/arch/mips/ralink/of.c
++++ b/arch/mips/ralink/of.c
+@@ -21,6 +21,7 @@
+ #include <asm/bootinfo.h>
+ #include <asm/addrspace.h>
+ #include <asm/prom.h>
++#include <asm/mach-ralink/ralink_regs.h>
+ 
+ #include "common.h"
+ 
+@@ -81,7 +82,8 @@ static int __init plat_of_setup(void)
+ 	__dt_register_buses(soc_info.compatible, "palmbus");
+ 
+ 	/* make sure that the reset controller is setup early */
+-	ralink_rst_init();
++	if (ralink_soc != MT762X_SOC_MT7621AT)
++		ralink_rst_init();
+ 
+ 	return 0;
+ }
+diff --git a/arch/powerpc/boot/dts/turris1x.dts b/arch/powerpc/boot/dts/turris1x.dts
+index 045af668e9284..e9cda34a140e0 100644
+--- a/arch/powerpc/boot/dts/turris1x.dts
++++ b/arch/powerpc/boot/dts/turris1x.dts
+@@ -69,6 +69,20 @@
+ 				interrupt-parent = <&gpio>;
+ 				interrupts = <12 IRQ_TYPE_LEVEL_LOW>, /* GPIO12 - ALERT pin */
+ 					     <13 IRQ_TYPE_LEVEL_LOW>; /* GPIO13 - CRIT pin */
++				#address-cells = <1>;
++				#size-cells = <0>;
++
++				/* Local temperature sensor (SA56004ED internal) */
++				channel@0 {
++					reg = <0>;
++					label = "board";
++				};
++
++				/* Remote temperature sensor (D+/D- connected to P2020 CPU Temperature Diode) */
++				channel@1 {
++					reg = <1>;
++					label = "cpu";
++				};
+ 			};
+ 
+ 			/* DDR3 SPD/EEPROM */
+diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
+index 8abae463f6c12..95fd7f9485d55 100644
+--- a/arch/powerpc/include/asm/hvcall.h
++++ b/arch/powerpc/include/asm/hvcall.h
+@@ -79,7 +79,7 @@
+ #define H_NOT_ENOUGH_RESOURCES -44
+ #define H_R_STATE       -45
+ #define H_RESCINDED     -46
+-#define H_P1		-54
++#define H_ABORTED	-54
+ #define H_P2		-55
+ #define H_P3		-56
+ #define H_P4		-57
+@@ -100,7 +100,6 @@
+ #define H_COP_HW	-74
+ #define H_STATE		-75
+ #define H_IN_USE	-77
+-#define H_ABORTED	-78
+ #define H_UNSUPPORTED_FLAG_START	-256
+ #define H_UNSUPPORTED_FLAG_END		-511
+ #define H_MULTI_THREADS_ACTIVE	-9005
+diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
+index 082f6d0308a47..8718289c051dd 100644
+--- a/arch/powerpc/perf/callchain.c
++++ b/arch/powerpc/perf/callchain.c
+@@ -61,6 +61,7 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
+ 		next_sp = fp[0];
+ 
+ 		if (next_sp == sp + STACK_INT_FRAME_SIZE &&
++		    validate_sp(sp, current, STACK_INT_FRAME_SIZE) &&
+ 		    fp[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) {
+ 			/*
+ 			 * This looks like an interrupt frame for an
+diff --git a/arch/powerpc/perf/hv-gpci-requests.h b/arch/powerpc/perf/hv-gpci-requests.h
+index 8965b4463d433..5e86371a20c78 100644
+--- a/arch/powerpc/perf/hv-gpci-requests.h
++++ b/arch/powerpc/perf/hv-gpci-requests.h
+@@ -79,6 +79,7 @@ REQUEST(__field(0,	8,	partition_id)
+ )
+ #include I(REQUEST_END)
+ 
++#ifdef ENABLE_EVENTS_COUNTERINFO_V6
+ /*
+  * Not available for counter_info_version >= 0x8, use
+  * run_instruction_cycles_by_partition(0x100) instead.
+@@ -92,6 +93,7 @@ REQUEST(__field(0,	8,	partition_id)
+ 	__count(0x10,	8,	cycles)
+ )
+ #include I(REQUEST_END)
++#endif
+ 
+ #define REQUEST_NAME system_performance_capabilities
+ #define REQUEST_NUM 0x40
+@@ -103,6 +105,7 @@ REQUEST(__field(0,	1,	perf_collect_privileged)
+ )
+ #include I(REQUEST_END)
+ 
++#ifdef ENABLE_EVENTS_COUNTERINFO_V6
+ #define REQUEST_NAME processor_bus_utilization_abc_links
+ #define REQUEST_NUM 0x50
+ #define REQUEST_IDX_KIND "hw_chip_id=?"
+@@ -194,6 +197,7 @@ REQUEST(__field(0,	4,	phys_processor_idx)
+ 	__count(0x28,	8,	instructions_completed)
+ )
+ #include I(REQUEST_END)
++#endif
+ 
+ /* Processor_core_power_mode (0x95) skipped, no counters */
+ /* Affinity_domain_information_by_virtual_processor (0xA0) skipped,
+diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c
+index 5eb60ed5b5e8a..7ff8ff3509f5f 100644
+--- a/arch/powerpc/perf/hv-gpci.c
++++ b/arch/powerpc/perf/hv-gpci.c
+@@ -70,9 +70,9 @@ static const struct attribute_group format_group = {
+ 	.attrs = format_attrs,
+ };
+ 
+-static const struct attribute_group event_group = {
++static struct attribute_group event_group = {
+ 	.name  = "events",
+-	.attrs = hv_gpci_event_attrs,
++	/* .attrs is set in init */
+ };
+ 
+ #define HV_CAPS_ATTR(_name, _format)				\
+@@ -330,6 +330,7 @@ static int hv_gpci_init(void)
+ 	int r;
+ 	unsigned long hret;
+ 	struct hv_perf_caps caps;
++	struct hv_gpci_request_buffer *arg;
+ 
+ 	hv_gpci_assert_offsets_correct();
+ 
+@@ -353,6 +354,36 @@ static int hv_gpci_init(void)
+ 	/* sampling not supported */
+ 	h_gpci_pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
+ 
++	arg = (void *)get_cpu_var(hv_gpci_reqb);
++	memset(arg, 0, HGPCI_REQ_BUFFER_SIZE);
++
++	/*
++	 * hcall H_GET_PERF_COUNTER_INFO populates the output
++	 * counter_info_version value based on the system hypervisor.
++	 * Pass the counter request 0x10 corresponds to request type
++	 * 'Dispatch_timebase_by_processor', to get the supported
++	 * counter_info_version.
++	 */
++	arg->params.counter_request = cpu_to_be32(0x10);
++
++	r = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
++			virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE);
++	if (r) {
++		pr_devel("hcall failed, can't get supported counter_info_version: 0x%x\n", r);
++		arg->params.counter_info_version_out = 0x8;
++	}
++
++	/*
++	 * Use counter_info_version_out value to assign
++	 * required hv-gpci event list.
++	 */
++	if (arg->params.counter_info_version_out >= 0x8)
++		event_group.attrs = hv_gpci_event_attrs;
++	else
++		event_group.attrs = hv_gpci_event_attrs_v6;
++
++	put_cpu_var(hv_gpci_reqb);
++
+ 	r = perf_pmu_register(&h_gpci_pmu, h_gpci_pmu.name, -1);
+ 	if (r)
+ 		return r;
+diff --git a/arch/powerpc/perf/hv-gpci.h b/arch/powerpc/perf/hv-gpci.h
+index 4d108262bed79..c72020912dea5 100644
+--- a/arch/powerpc/perf/hv-gpci.h
++++ b/arch/powerpc/perf/hv-gpci.h
+@@ -26,6 +26,7 @@ enum {
+ #define REQUEST_FILE "../hv-gpci-requests.h"
+ #define NAME_LOWER hv_gpci
+ #define NAME_UPPER HV_GPCI
++#define ENABLE_EVENTS_COUNTERINFO_V6
+ #include "req-gen/perf.h"
+ #undef REQUEST_FILE
+ #undef NAME_LOWER
+diff --git a/arch/powerpc/perf/req-gen/perf.h b/arch/powerpc/perf/req-gen/perf.h
+index fa9bc804e67af..6b2a59fefffa7 100644
+--- a/arch/powerpc/perf/req-gen/perf.h
++++ b/arch/powerpc/perf/req-gen/perf.h
+@@ -139,6 +139,26 @@ PMU_EVENT_ATTR_STRING(							\
+ #define REQUEST_(r_name, r_value, r_idx_1, r_fields)			\
+ 	r_fields
+ 
++/* Generate event list for platforms with counter_info_version 0x6 or below */
++static __maybe_unused struct attribute *hv_gpci_event_attrs_v6[] = {
++#include REQUEST_FILE
++	NULL
++};
++
++/*
++ * Based on getPerfCountInfo v1.018 documentation, some of the hv-gpci
++ * events were deprecated for platform firmware that supports
++ * counter_info_version 0x8 or above.
++ * Those deprecated events are still part of platform firmware that
++ * support counter_info_version 0x6 and below. As per the getPerfCountInfo
++ * v1.018 documentation there is no counter_info_version 0x7.
++ * Undefining macro ENABLE_EVENTS_COUNTERINFO_V6, to disable the addition of
++ * deprecated events in "hv_gpci_event_attrs" attribute group, for platforms
++ * that supports counter_info_version 0x8 or above.
++ */
++#undef ENABLE_EVENTS_COUNTERINFO_V6
++
++/* Generate event list for platforms with counter_info_version 0x8 or above*/
+ static __maybe_unused struct attribute *hv_gpci_event_attrs[] = {
+ #include REQUEST_FILE
+ 	NULL
+diff --git a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+index 48038aaedbd36..2875c206ac0f8 100644
+--- a/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
++++ b/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c
+@@ -531,6 +531,7 @@ static int mpc52xx_lpbfifo_probe(struct platform_device *op)
+  err_bcom_rx_irq:
+ 	bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task);
+  err_bcom_rx:
++	free_irq(lpbfifo.irq, &lpbfifo);
+  err_irq:
+ 	iounmap(lpbfifo.regs);
+ 	lpbfifo.regs = NULL;
+diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+index bb8caa5071f8c..dddb5c6f81209 100644
+--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
++++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+@@ -107,7 +107,7 @@ static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
+ 
+ 		goto next;
+ unreg:
+-		platform_device_del(pdev);
++		platform_device_put(pdev);
+ err:
+ 		pr_err("%pOF: registration failed\n", np);
+ next:
+diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
+index 8e40ccac0f44e..e5a58a9b2fe9f 100644
+--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
+@@ -848,16 +848,7 @@ static int __init eeh_pseries_init(void)
+ 	}
+ 
+ 	/* Initialize error log size */
+-	eeh_error_buf_size = rtas_token("rtas-error-log-max");
+-	if (eeh_error_buf_size == RTAS_UNKNOWN_SERVICE) {
+-		pr_info("%s: unknown EEH error log size\n",
+-			__func__);
+-		eeh_error_buf_size = 1024;
+-	} else if (eeh_error_buf_size > RTAS_ERROR_LOG_MAX) {
+-		pr_info("%s: EEH error log size %d exceeds the maximal %d\n",
+-			__func__, eeh_error_buf_size, RTAS_ERROR_LOG_MAX);
+-		eeh_error_buf_size = RTAS_ERROR_LOG_MAX;
+-	}
++	eeh_error_buf_size = rtas_get_error_log_max();
+ 
+ 	/* Set EEH probe mode */
+ 	eeh_add_flag(EEH_PROBE_MODE_DEVTREE | EEH_ENABLE_IO_FOR_LOG);
+diff --git a/arch/powerpc/platforms/pseries/plpks.c b/arch/powerpc/platforms/pseries/plpks.c
+index f4b5b5a64db3d..63a1e1fe01851 100644
+--- a/arch/powerpc/platforms/pseries/plpks.c
++++ b/arch/powerpc/platforms/pseries/plpks.c
+@@ -75,7 +75,7 @@ static int pseries_status_to_err(int rc)
+ 	case H_FUNCTION:
+ 		err = -ENXIO;
+ 		break;
+-	case H_P1:
++	case H_PARAMETER:
+ 	case H_P2:
+ 	case H_P3:
+ 	case H_P4:
+@@ -111,7 +111,7 @@ static int pseries_status_to_err(int rc)
+ 		err = -EEXIST;
+ 		break;
+ 	case H_ABORTED:
+-		err = -EINTR;
++		err = -EIO;
+ 		break;
+ 	default:
+ 		err = -EINVAL;
+@@ -366,22 +366,24 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)
+ {
+ 	unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
+ 	struct plpks_auth *auth;
+-	struct label *label;
++	struct label *label = NULL;
+ 	u8 *output;
+ 	int rc;
+ 
+ 	if (var->namelen > MAX_NAME_SIZE)
+ 		return -EINVAL;
+ 
+-	auth = construct_auth(PKS_OS_OWNER);
++	auth = construct_auth(consumer);
+ 	if (IS_ERR(auth))
+ 		return PTR_ERR(auth);
+ 
+-	label = construct_label(var->component, var->os, var->name,
+-				var->namelen);
+-	if (IS_ERR(label)) {
+-		rc = PTR_ERR(label);
+-		goto out_free_auth;
++	if (consumer == PKS_OS_OWNER) {
++		label = construct_label(var->component, var->os, var->name,
++					var->namelen);
++		if (IS_ERR(label)) {
++			rc = PTR_ERR(label);
++			goto out_free_auth;
++		}
+ 	}
+ 
+ 	output = kzalloc(maxobjsize, GFP_KERNEL);
+@@ -390,9 +392,15 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)
+ 		goto out_free_label;
+ 	}
+ 
+-	rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth),
+-			 virt_to_phys(label), label->size, virt_to_phys(output),
+-			 maxobjsize);
++	if (consumer == PKS_OS_OWNER)
++		rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth),
++				 virt_to_phys(label), label->size, virt_to_phys(output),
++				 maxobjsize);
++	else
++		rc = plpar_hcall(H_PKS_READ_OBJECT, retbuf, virt_to_phys(auth),
++				 virt_to_phys(var->name), var->namelen, virt_to_phys(output),
++				 maxobjsize);
++
+ 
+ 	if (rc != H_SUCCESS) {
+ 		pr_err("Failed to read variable %s for component %s with error %d\n",
+diff --git a/arch/powerpc/platforms/pseries/plpks.h b/arch/powerpc/platforms/pseries/plpks.h
+index c6a291367bb13..275ccd86bfb5e 100644
+--- a/arch/powerpc/platforms/pseries/plpks.h
++++ b/arch/powerpc/platforms/pseries/plpks.h
+@@ -17,7 +17,7 @@
+ #define WORLDREADABLE 0x08000000
+ #define SIGNEDUPDATE 0x01000000
+ 
+-#define PLPKS_VAR_LINUX	0x01
++#define PLPKS_VAR_LINUX	0x02
+ #define PLPKS_VAR_COMMON	0x04
+ 
+ struct plpks_var {
+diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c
+index e2c8f93b535ba..e454192643910 100644
+--- a/arch/powerpc/sysdev/xive/spapr.c
++++ b/arch/powerpc/sysdev/xive/spapr.c
+@@ -439,6 +439,7 @@ static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data)
+ 
+ 	data->trig_mmio = ioremap(data->trig_page, 1u << data->esb_shift);
+ 	if (!data->trig_mmio) {
++		iounmap(data->eoi_mmio);
+ 		pr_err("Failed to map trigger page for irq 0x%x\n", hw_irq);
+ 		return -ENOMEM;
+ 	}
+diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
+index 26ef3388c24c4..df91dfc7ff727 100644
+--- a/arch/powerpc/xmon/xmon.c
++++ b/arch/powerpc/xmon/xmon.c
+@@ -1525,9 +1525,9 @@ bpt_cmds(void)
+ 	cmd = inchar();
+ 
+ 	switch (cmd) {
+-	static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
+-	int mode;
+-	case 'd':	/* bd - hardware data breakpoint */
++	case 'd': {	/* bd - hardware data breakpoint */
++		static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
++		int mode;
+ 		if (xmon_is_ro) {
+ 			printf(xmon_ro_msg);
+ 			break;
+@@ -1560,6 +1560,7 @@ bpt_cmds(void)
+ 
+ 		force_enable_xmon();
+ 		break;
++	}
+ 
+ 	case 'i':	/* bi - hardware instr breakpoint */
+ 		if (xmon_is_ro) {
+diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hugetlb.h
+index a5c2ca1d1cd8b..ec19d6afc8965 100644
+--- a/arch/riscv/include/asm/hugetlb.h
++++ b/arch/riscv/include/asm/hugetlb.h
+@@ -5,4 +5,10 @@
+ #include <asm-generic/hugetlb.h>
+ #include <asm/page.h>
+ 
++static inline void arch_clear_hugepage_flags(struct page *page)
++{
++	clear_bit(PG_dcache_clean, &page->flags);
++}
++#define arch_clear_hugepage_flags arch_clear_hugepage_flags
++
+ #endif /* _ASM_RISCV_HUGETLB_H */
+diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
+index 92080a2279372..42497d487a174 100644
+--- a/arch/riscv/include/asm/io.h
++++ b/arch/riscv/include/asm/io.h
+@@ -135,4 +135,9 @@ __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw())
+ 
+ #include <asm-generic/io.h>
+ 
++#ifdef CONFIG_MMU
++#define arch_memremap_wb(addr, size)	\
++	((__force void *)ioremap_prot((addr), (size), _PAGE_KERNEL))
++#endif
++
+ #endif /* _ASM_RISCV_IO_H */
+diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
+index dc42375c23571..42a042c0e13ed 100644
+--- a/arch/riscv/include/asm/pgtable-64.h
++++ b/arch/riscv/include/asm/pgtable-64.h
+@@ -25,7 +25,11 @@ extern bool pgtable_l5_enabled;
+ #define PGDIR_MASK      (~(PGDIR_SIZE - 1))
+ 
+ /* p4d is folded into pgd in case of 4-level page table */
+-#define P4D_SHIFT      39
++#define P4D_SHIFT_L3   30
++#define P4D_SHIFT_L4   39
++#define P4D_SHIFT_L5   39
++#define P4D_SHIFT      (pgtable_l5_enabled ? P4D_SHIFT_L5 : \
++		(pgtable_l4_enabled ? P4D_SHIFT_L4 : P4D_SHIFT_L3))
+ #define P4D_SIZE       (_AC(1, UL) << P4D_SHIFT)
+ #define P4D_MASK       (~(P4D_SIZE - 1))
+ 
+diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
+index 186abd146eaff..3221a9e5f3724 100644
+--- a/arch/riscv/kernel/entry.S
++++ b/arch/riscv/kernel/entry.S
+@@ -263,12 +263,11 @@ ret_from_exception:
+ #endif
+ 	bnez s0, resume_kernel
+ 
+-resume_userspace:
+ 	/* Interrupts must be disabled here so flags are checked atomically */
+ 	REG_L s0, TASK_TI_FLAGS(tp) /* current_thread_info->flags */
+ 	andi s1, s0, _TIF_WORK_MASK
+-	bnez s1, work_pending
+-
++	bnez s1, resume_userspace_slow
++resume_userspace:
+ #ifdef CONFIG_CONTEXT_TRACKING_USER
+ 	call user_enter_callable
+ #endif
+@@ -368,19 +367,12 @@ resume_kernel:
+ 	j restore_all
+ #endif
+ 
+-work_pending:
++resume_userspace_slow:
+ 	/* Enter slow path for supplementary processing */
+-	la ra, ret_from_exception
+-	andi s1, s0, _TIF_NEED_RESCHED
+-	bnez s1, work_resched
+-work_notifysig:
+-	/* Handle pending signals and notify-resume requests */
+-	csrs CSR_STATUS, SR_IE /* Enable interrupts for do_notify_resume() */
+ 	move a0, sp /* pt_regs */
+ 	move a1, s0 /* current_thread_info->flags */
+-	tail do_notify_resume
+-work_resched:
+-	tail schedule
++	call do_work_pending
++	j resume_userspace
+ 
+ /* Slow paths for ptrace. */
+ handle_syscall_trace_enter:
+diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
+index 5c591123c4409..bfb2afa4135f8 100644
+--- a/arch/riscv/kernel/signal.c
++++ b/arch/riscv/kernel/signal.c
+@@ -313,19 +313,27 @@ static void do_signal(struct pt_regs *regs)
+ }
+ 
+ /*
+- * notification of userspace execution resumption
+- * - triggered by the _TIF_WORK_MASK flags
++ * Handle any pending work on the resume-to-userspace path, as indicated by
++ * _TIF_WORK_MASK. Entered from assembly with IRQs off.
+  */
+-asmlinkage __visible void do_notify_resume(struct pt_regs *regs,
+-					   unsigned long thread_info_flags)
++asmlinkage __visible void do_work_pending(struct pt_regs *regs,
++					  unsigned long thread_info_flags)
+ {
+-	if (thread_info_flags & _TIF_UPROBE)
+-		uprobe_notify_resume(regs);
+-
+-	/* Handle pending signal delivery */
+-	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
+-		do_signal(regs);
+-
+-	if (thread_info_flags & _TIF_NOTIFY_RESUME)
+-		resume_user_mode_work(regs);
++	do {
++		if (thread_info_flags & _TIF_NEED_RESCHED) {
++			schedule();
++		} else {
++			local_irq_enable();
++			if (thread_info_flags & _TIF_UPROBE)
++				uprobe_notify_resume(regs);
++			/* Handle pending signal delivery */
++			if (thread_info_flags & (_TIF_SIGPENDING |
++						 _TIF_NOTIFY_SIGNAL))
++				do_signal(regs);
++			if (thread_info_flags & _TIF_NOTIFY_RESUME)
++				resume_user_mode_work(regs);
++		}
++		local_irq_disable();
++		thread_info_flags = read_thread_flags();
++	} while (thread_info_flags & _TIF_WORK_MASK);
+ }
+diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
+index 6e8822446069e..026b458331582 100644
+--- a/arch/riscv/kernel/traps.c
++++ b/arch/riscv/kernel/traps.c
+@@ -211,7 +211,7 @@ static DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)],
+  * shadow stack, handled_ kernel_ stack_ overflow(in kernel/entry.S) is used
+  * to get per-cpu overflow stack(get_overflow_stack).
+  */
+-long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE/sizeof(long)];
++long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE/sizeof(long)] __aligned(16);
+ asmlinkage unsigned long get_overflow_stack(void)
+ {
+ 	return (unsigned long)this_cpu_ptr(overflow_stack) +
+diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
+index f692c0716aa7a..aa7ae63270449 100644
+--- a/arch/riscv/kvm/vcpu.c
++++ b/arch/riscv/kvm/vcpu.c
+@@ -286,12 +286,15 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
+ 	if (copy_from_user(&reg_val, uaddr, KVM_REG_SIZE(reg->id)))
+ 		return -EFAULT;
+ 
+-	/* This ONE REG interface is only defined for single letter extensions */
+-	if (fls(reg_val) >= RISCV_ISA_EXT_BASE)
+-		return -EINVAL;
+-
+ 	switch (reg_num) {
+ 	case KVM_REG_RISCV_CONFIG_REG(isa):
++		/*
++		 * This ONE REG interface is only defined for
++		 * single letter extensions.
++		 */
++		if (fls(reg_val) >= RISCV_ISA_EXT_BASE)
++			return -EINVAL;
++
+ 		if (!vcpu->arch.ran_atleast_once) {
+ 			/* Ignore the enable/disable request for certain extensions */
+ 			for (i = 0; i < RISCV_ISA_EXT_BASE; i++) {
+diff --git a/arch/riscv/mm/physaddr.c b/arch/riscv/mm/physaddr.c
+index 19cf25a74ee29..9b18bda74154e 100644
+--- a/arch/riscv/mm/physaddr.c
++++ b/arch/riscv/mm/physaddr.c
+@@ -22,7 +22,7 @@ EXPORT_SYMBOL(__virt_to_phys);
+ phys_addr_t __phys_addr_symbol(unsigned long x)
+ {
+ 	unsigned long kernel_start = kernel_map.virt_addr;
+-	unsigned long kernel_end = (unsigned long)_end;
++	unsigned long kernel_end = kernel_start + kernel_map.size;
+ 
+ 	/*
+ 	 * Boundary checking aginst the kernel image mapping.
+diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
+index 00df3a8f92acd..f2417ac54edd6 100644
+--- a/arch/riscv/net/bpf_jit_comp64.c
++++ b/arch/riscv/net/bpf_jit_comp64.c
+@@ -136,6 +136,25 @@ static bool in_auipc_jalr_range(s64 val)
+ 		val < ((1L << 31) - (1L << 11));
+ }
+ 
++/* Emit fixed-length instructions for address */
++static int emit_addr(u8 rd, u64 addr, bool extra_pass, struct rv_jit_context *ctx)
++{
++	u64 ip = (u64)(ctx->insns + ctx->ninsns);
++	s64 off = addr - ip;
++	s64 upper = (off + (1 << 11)) >> 12;
++	s64 lower = off & 0xfff;
++
++	if (extra_pass && !in_auipc_jalr_range(off)) {
++		pr_err("bpf-jit: target offset 0x%llx is out of range\n", off);
++		return -ERANGE;
++	}
++
++	emit(rv_auipc(rd, upper), ctx);
++	emit(rv_addi(rd, rd, lower), ctx);
++	return 0;
++}
++
++/* Emit variable-length instructions for 32-bit and 64-bit imm */
+ static void emit_imm(u8 rd, s64 val, struct rv_jit_context *ctx)
+ {
+ 	/* Note that the immediate from the add is sign-extended,
+@@ -1050,7 +1069,15 @@ out_be:
+ 		u64 imm64;
+ 
+ 		imm64 = (u64)insn1.imm << 32 | (u32)imm;
+-		emit_imm(rd, imm64, ctx);
++		if (bpf_pseudo_func(insn)) {
++			/* fixed-length insns for extra jit pass */
++			ret = emit_addr(rd, imm64, extra_pass, ctx);
++			if (ret)
++				return ret;
++		} else {
++			emit_imm(rd, imm64, ctx);
++		}
++
+ 		return 1;
+ 	}
+ 
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 4728d3f5d5c40..3fec0e9d92410 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -450,8 +450,8 @@ config X86_X2APIC
+ 
+ 	  Some Intel systems circa 2022 and later are locked into x2APIC mode
+ 	  and can not fall back to the legacy APIC modes if SGX or TDX are
+-	  enabled in the BIOS.  They will be unable to boot without enabling
+-	  this option.
++	  enabled in the BIOS. They will boot with very reduced functionality
++	  without enabling this option.
+ 
+ 	  If you don't know what to do here, say N.
+ 
+diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c
+index 1ef4f7861e2ec..1f4869227efb9 100644
+--- a/arch/x86/events/intel/uncore_snb.c
++++ b/arch/x86/events/intel/uncore_snb.c
+@@ -1338,6 +1338,7 @@ static void __uncore_imc_init_box(struct intel_uncore_box *box,
+ 	/* MCHBAR is disabled */
+ 	if (!(mch_bar & BIT(0))) {
+ 		pr_warn("perf uncore: MCHBAR is disabled. Failed to map IMC free-running counters.\n");
++		pci_dev_put(pdev);
+ 		return;
+ 	}
+ 	mch_bar &= ~BIT(0);
+@@ -1352,6 +1353,8 @@ static void __uncore_imc_init_box(struct intel_uncore_box *box,
+ 	box->io_addr = ioremap(addr, type->mmio_map_size);
+ 	if (!box->io_addr)
+ 		pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
++
++	pci_dev_put(pdev);
+ }
+ 
+ static void tgl_uncore_imc_freerunning_init_box(struct intel_uncore_box *box)
+diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c
+index ed869443efb21..fcd95e93f479a 100644
+--- a/arch/x86/events/intel/uncore_snbep.c
++++ b/arch/x86/events/intel/uncore_snbep.c
+@@ -2891,6 +2891,7 @@ static bool hswep_has_limit_sbox(unsigned int device)
+ 		return false;
+ 
+ 	pci_read_config_dword(dev, HSWEP_PCU_CAPID4_OFFET, &capid4);
++	pci_dev_put(dev);
+ 	if (!hswep_get_chop(capid4))
+ 		return true;
+ 
+@@ -4492,6 +4493,8 @@ static int sad_cfg_iio_topology(struct intel_uncore_type *type, u8 *sad_pmon_map
+ 		type->topology = NULL;
+ 	}
+ 
++	pci_dev_put(dev);
++
+ 	return ret;
+ }
+ 
+@@ -4857,6 +4860,8 @@ static int snr_uncore_mmio_map(struct intel_uncore_box *box,
+ 
+ 	addr += box_ctl;
+ 
++	pci_dev_put(pdev);
++
+ 	box->io_addr = ioremap(addr, type->mmio_map_size);
+ 	if (!box->io_addr) {
+ 		pr_warn("perf uncore: Failed to ioremap for %s.\n", type->name);
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+index a0165df3c4d8c..d03561b2fffe6 100644
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -536,8 +536,6 @@ void hyperv_cleanup(void)
+ {
+ 	union hv_x64_msr_hypercall_contents hypercall_msr;
+ 
+-	unregister_syscore_ops(&hv_syscore_ops);
+-
+ 	/* Reset our OS id */
+ 	wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
+ 	hv_ghcb_msr_write(HV_X64_MSR_GUEST_OS_ID, 0);
+diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
+index 3415321c8240c..3216da7074bad 100644
+--- a/arch/x86/include/asm/apic.h
++++ b/arch/x86/include/asm/apic.h
+@@ -249,7 +249,6 @@ static inline u64 native_x2apic_icr_read(void)
+ extern int x2apic_mode;
+ extern int x2apic_phys;
+ extern void __init x2apic_set_max_apicid(u32 apicid);
+-extern void __init check_x2apic(void);
+ extern void x2apic_setup(void);
+ static inline int x2apic_enabled(void)
+ {
+@@ -258,13 +257,13 @@ static inline int x2apic_enabled(void)
+ 
+ #define x2apic_supported()	(boot_cpu_has(X86_FEATURE_X2APIC))
+ #else /* !CONFIG_X86_X2APIC */
+-static inline void check_x2apic(void) { }
+ static inline void x2apic_setup(void) { }
+ static inline int x2apic_enabled(void) { return 0; }
+ 
+ #define x2apic_mode		(0)
+ #define	x2apic_supported()	(0)
+ #endif /* !CONFIG_X86_X2APIC */
++extern void __init check_x2apic(void);
+ 
+ struct irq_data;
+ 
+diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h
+index fd6f6e5b755a7..a336feef0af14 100644
+--- a/arch/x86/include/asm/realmode.h
++++ b/arch/x86/include/asm/realmode.h
+@@ -91,6 +91,7 @@ static inline void set_real_mode_mem(phys_addr_t mem)
+ 
+ void reserve_real_mode(void);
+ void load_trampoline_pgtable(void);
++void init_real_mode(void);
+ 
+ #endif /* __ASSEMBLY__ */
+ 
+diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
+index e9170457697e4..c1c8c581759d6 100644
+--- a/arch/x86/include/asm/x86_init.h
++++ b/arch/x86/include/asm/x86_init.h
+@@ -285,6 +285,8 @@ struct x86_hyper_runtime {
+  * 				possible in x86_early_init_platform_quirks() by
+  * 				only using the current x86_hardware_subarch
+  * 				semantics.
++ * @realmode_reserve:		reserve memory for realmode trampoline
++ * @realmode_init:		initialize realmode trampoline
+  * @hyper:			x86 hypervisor specific runtime callbacks
+  */
+ struct x86_platform_ops {
+@@ -301,6 +303,8 @@ struct x86_platform_ops {
+ 	void (*apic_post_init)(void);
+ 	struct x86_legacy_features legacy;
+ 	void (*set_legacy_features)(void);
++	void (*realmode_reserve)(void);
++	void (*realmode_init)(void);
+ 	struct x86_hyper_runtime hyper;
+ 	struct x86_guest guest;
+ };
+diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
+index c6876d3ea4b17..20d9a604da7c4 100644
+--- a/arch/x86/kernel/apic/apic.c
++++ b/arch/x86/kernel/apic/apic.c
+@@ -1931,16 +1931,19 @@ void __init check_x2apic(void)
+ 	}
+ }
+ #else /* CONFIG_X86_X2APIC */
+-static int __init validate_x2apic(void)
++void __init check_x2apic(void)
+ {
+ 	if (!apic_is_x2apic_enabled())
+-		return 0;
++		return;
+ 	/*
+-	 * Checkme: Can we simply turn off x2apic here instead of panic?
++	 * Checkme: Can we simply turn off x2APIC here instead of disabling the APIC?
+ 	 */
+-	panic("BIOS has enabled x2apic but kernel doesn't support x2apic, please disable x2apic in BIOS.\n");
++	pr_err("Kernel does not support x2APIC, please recompile with CONFIG_X86_X2APIC.\n");
++	pr_err("Disabling APIC, expect reduced performance and functionality.\n");
++
++	disable_apic = 1;
++	setup_clear_cpu_cap(X86_FEATURE_APIC);
+ }
+-early_initcall(validate_x2apic);
+ 
+ static inline void try_to_enable_x2apic(int remap_mode) { }
+ static inline void __x2apic_enable(void) { }
+diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
+index 2d7ea5480ec33..4278996504833 100644
+--- a/arch/x86/kernel/cpu/intel.c
++++ b/arch/x86/kernel/cpu/intel.c
+@@ -1034,8 +1034,32 @@ static const struct {
+ 
+ static struct ratelimit_state bld_ratelimit;
+ 
++static unsigned int sysctl_sld_mitigate = 1;
+ static DEFINE_SEMAPHORE(buslock_sem);
+ 
++#ifdef CONFIG_PROC_SYSCTL
++static struct ctl_table sld_sysctls[] = {
++	{
++		.procname       = "split_lock_mitigate",
++		.data           = &sysctl_sld_mitigate,
++		.maxlen         = sizeof(unsigned int),
++		.mode           = 0644,
++		.proc_handler	= proc_douintvec_minmax,
++		.extra1         = SYSCTL_ZERO,
++		.extra2         = SYSCTL_ONE,
++	},
++	{}
++};
++
++static int __init sld_mitigate_sysctl_init(void)
++{
++	register_sysctl_init("kernel", sld_sysctls);
++	return 0;
++}
++
++late_initcall(sld_mitigate_sysctl_init);
++#endif
++
+ static inline bool match_option(const char *arg, int arglen, const char *opt)
+ {
+ 	int len = strlen(opt), ratelimit;
+@@ -1146,12 +1170,20 @@ static void split_lock_init(void)
+ 		split_lock_verify_msr(sld_state != sld_off);
+ }
+ 
+-static void __split_lock_reenable(struct work_struct *work)
++static void __split_lock_reenable_unlock(struct work_struct *work)
+ {
+ 	sld_update_msr(true);
+ 	up(&buslock_sem);
+ }
+ 
++static DECLARE_DELAYED_WORK(sl_reenable_unlock, __split_lock_reenable_unlock);
++
++static void __split_lock_reenable(struct work_struct *work)
++{
++	sld_update_msr(true);
++}
++static DECLARE_DELAYED_WORK(sl_reenable, __split_lock_reenable);
++
+ /*
+  * If a CPU goes offline with pending delayed work to re-enable split lock
+  * detection then the delayed work will be executed on some other CPU. That
+@@ -1169,10 +1201,9 @@ static int splitlock_cpu_offline(unsigned int cpu)
+ 	return 0;
+ }
+ 
+-static DECLARE_DELAYED_WORK(split_lock_reenable, __split_lock_reenable);
+-
+ static void split_lock_warn(unsigned long ip)
+ {
++	struct delayed_work *work;
+ 	int cpu;
+ 
+ 	if (!current->reported_split_lock)
+@@ -1180,14 +1211,26 @@ static void split_lock_warn(unsigned long ip)
+ 				    current->comm, current->pid, ip);
+ 	current->reported_split_lock = 1;
+ 
+-	/* misery factor #1, sleep 10ms before trying to execute split lock */
+-	if (msleep_interruptible(10) > 0)
+-		return;
+-	/* Misery factor #2, only allow one buslocked disabled core at a time */
+-	if (down_interruptible(&buslock_sem) == -EINTR)
+-		return;
++	if (sysctl_sld_mitigate) {
++		/*
++		 * misery factor #1:
++		 * sleep 10ms before trying to execute split lock.
++		 */
++		if (msleep_interruptible(10) > 0)
++			return;
++		/*
++		 * Misery factor #2:
++		 * only allow one buslocked disabled core at a time.
++		 */
++		if (down_interruptible(&buslock_sem) == -EINTR)
++			return;
++		work = &sl_reenable_unlock;
++	} else {
++		work = &sl_reenable;
++	}
++
+ 	cpu = get_cpu();
+-	schedule_delayed_work_on(cpu, &split_lock_reenable, 2);
++	schedule_delayed_work_on(cpu, work, 2);
+ 
+ 	/* Disable split lock detection on this CPU to make progress */
+ 	sld_update_msr(false);
+diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
+index 8bdeae2fc3091..6942a3d8b578c 100644
+--- a/arch/x86/kernel/cpu/sgx/encl.c
++++ b/arch/x86/kernel/cpu/sgx/encl.c
+@@ -677,11 +677,15 @@ const struct vm_operations_struct sgx_vm_ops = {
+ void sgx_encl_release(struct kref *ref)
+ {
+ 	struct sgx_encl *encl = container_of(ref, struct sgx_encl, refcount);
++	unsigned long max_page_index = PFN_DOWN(encl->base + encl->size - 1);
+ 	struct sgx_va_page *va_page;
+ 	struct sgx_encl_page *entry;
+-	unsigned long index;
++	unsigned long count = 0;
++
++	XA_STATE(xas, &encl->page_array, PFN_DOWN(encl->base));
+ 
+-	xa_for_each(&encl->page_array, index, entry) {
++	xas_lock(&xas);
++	xas_for_each(&xas, entry, max_page_index) {
+ 		if (entry->epc_page) {
+ 			/*
+ 			 * The page and its radix tree entry cannot be freed
+@@ -696,9 +700,20 @@ void sgx_encl_release(struct kref *ref)
+ 		}
+ 
+ 		kfree(entry);
+-		/* Invoke scheduler to prevent soft lockups. */
+-		cond_resched();
++		/*
++		 * Invoke scheduler on every XA_CHECK_SCHED iteration
++		 * to prevent soft lockups.
++		 */
++		if (!(++count % XA_CHECK_SCHED)) {
++			xas_pause(&xas);
++			xas_unlock(&xas);
++
++			cond_resched();
++
++			xas_lock(&xas);
++		}
+ 	}
++	xas_unlock(&xas);
+ 
+ 	xa_destroy(&encl->page_array);
+ 
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index 216fee7144eef..892609cde4a20 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -1175,7 +1175,7 @@ void __init setup_arch(char **cmdline_p)
+ 	 * Moreover, on machines with SandyBridge graphics or in setups that use
+ 	 * crashkernel the entire 1M is reserved anyway.
+ 	 */
+-	reserve_real_mode();
++	x86_platform.realmode_reserve();
+ 
+ 	init_mem_mapping();
+ 
+diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
+index b63cf8f7745ee..6c07f6daaa227 100644
+--- a/arch/x86/kernel/uprobes.c
++++ b/arch/x86/kernel/uprobes.c
+@@ -722,8 +722,9 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
+ 	switch (opc1) {
+ 	case 0xeb:	/* jmp 8 */
+ 	case 0xe9:	/* jmp 32 */
+-	case 0x90:	/* prefix* + nop; same as jmp with .offs = 0 */
+ 		break;
++	case 0x90:	/* prefix* + nop; same as jmp with .offs = 0 */
++		goto setup;
+ 
+ 	case 0xe8:	/* call relative */
+ 		branch_clear_offset(auprobe, insn);
+@@ -753,6 +754,7 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
+ 			return -ENOTSUPP;
+ 	}
+ 
++setup:
+ 	auprobe->branch.opc1 = opc1;
+ 	auprobe->branch.ilen = insn->length;
+ 	auprobe->branch.offs = insn->immediate.value;
+diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
+index e84ee5cdbd8c6..3a164fb0d4c3e 100644
+--- a/arch/x86/kernel/x86_init.c
++++ b/arch/x86/kernel/x86_init.c
+@@ -25,6 +25,7 @@
+ #include <asm/iommu.h>
+ #include <asm/mach_traps.h>
+ #include <asm/irqdomain.h>
++#include <asm/realmode.h>
+ 
+ void x86_init_noop(void) { }
+ void __init x86_init_uint_noop(unsigned int unused) { }
+@@ -145,6 +146,8 @@ struct x86_platform_ops x86_platform __ro_after_init = {
+ 	.get_nmi_reason			= default_get_nmi_reason,
+ 	.save_sched_clock_state		= tsc_save_sched_clock_state,
+ 	.restore_sched_clock_state	= tsc_restore_sched_clock_state,
++	.realmode_reserve		= reserve_real_mode,
++	.realmode_init			= init_real_mode,
+ 	.hyper.pin_vcpu			= x86_op_int_noop,
+ 
+ 	.guest = {
+diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
+index 41d7669a97ad1..af565816d2ba6 100644
+--- a/arch/x86/realmode/init.c
++++ b/arch/x86/realmode/init.c
+@@ -200,14 +200,18 @@ static void __init set_real_mode_permissions(void)
+ 	set_memory_x((unsigned long) text_start, text_size >> PAGE_SHIFT);
+ }
+ 
+-static int __init init_real_mode(void)
++void __init init_real_mode(void)
+ {
+ 	if (!real_mode_header)
+ 		panic("Real mode trampoline was not allocated");
+ 
+ 	setup_real_mode();
+ 	set_real_mode_permissions();
++}
+ 
++static int __init do_init_real_mode(void)
++{
++	x86_platform.realmode_init();
+ 	return 0;
+ }
+-early_initcall(init_real_mode);
++early_initcall(do_init_real_mode);
+diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
+index 9b1a58dda935b..807ab4fbe2c42 100644
+--- a/arch/x86/xen/enlighten_pv.c
++++ b/arch/x86/xen/enlighten_pv.c
+@@ -1224,6 +1224,8 @@ asmlinkage __visible void __init xen_start_kernel(struct start_info *si)
+ 	xen_vcpu_info_reset(0);
+ 
+ 	x86_platform.get_nmi_reason = xen_get_nmi_reason;
++	x86_platform.realmode_reserve = x86_init_noop;
++	x86_platform.realmode_init = x86_init_noop;
+ 
+ 	x86_init.resources.memory_setup = xen_memory_setup;
+ 	x86_init.irqs.intr_mode_select	= x86_init_noop;
+diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
+index c3e1f9a7d43aa..4b0d6fff88de5 100644
+--- a/arch/x86/xen/smp.c
++++ b/arch/x86/xen/smp.c
+@@ -32,30 +32,30 @@ static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id)
+ 
+ void xen_smp_intr_free(unsigned int cpu)
+ {
++	kfree(per_cpu(xen_resched_irq, cpu).name);
++	per_cpu(xen_resched_irq, cpu).name = NULL;
+ 	if (per_cpu(xen_resched_irq, cpu).irq >= 0) {
+ 		unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu).irq, NULL);
+ 		per_cpu(xen_resched_irq, cpu).irq = -1;
+-		kfree(per_cpu(xen_resched_irq, cpu).name);
+-		per_cpu(xen_resched_irq, cpu).name = NULL;
+ 	}
++	kfree(per_cpu(xen_callfunc_irq, cpu).name);
++	per_cpu(xen_callfunc_irq, cpu).name = NULL;
+ 	if (per_cpu(xen_callfunc_irq, cpu).irq >= 0) {
+ 		unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu).irq, NULL);
+ 		per_cpu(xen_callfunc_irq, cpu).irq = -1;
+-		kfree(per_cpu(xen_callfunc_irq, cpu).name);
+-		per_cpu(xen_callfunc_irq, cpu).name = NULL;
+ 	}
++	kfree(per_cpu(xen_debug_irq, cpu).name);
++	per_cpu(xen_debug_irq, cpu).name = NULL;
+ 	if (per_cpu(xen_debug_irq, cpu).irq >= 0) {
+ 		unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu).irq, NULL);
+ 		per_cpu(xen_debug_irq, cpu).irq = -1;
+-		kfree(per_cpu(xen_debug_irq, cpu).name);
+-		per_cpu(xen_debug_irq, cpu).name = NULL;
+ 	}
++	kfree(per_cpu(xen_callfuncsingle_irq, cpu).name);
++	per_cpu(xen_callfuncsingle_irq, cpu).name = NULL;
+ 	if (per_cpu(xen_callfuncsingle_irq, cpu).irq >= 0) {
+ 		unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu).irq,
+ 				       NULL);
+ 		per_cpu(xen_callfuncsingle_irq, cpu).irq = -1;
+-		kfree(per_cpu(xen_callfuncsingle_irq, cpu).name);
+-		per_cpu(xen_callfuncsingle_irq, cpu).name = NULL;
+ 	}
+ }
+ 
+@@ -65,6 +65,7 @@ int xen_smp_intr_init(unsigned int cpu)
+ 	char *resched_name, *callfunc_name, *debug_name;
+ 
+ 	resched_name = kasprintf(GFP_KERNEL, "resched%d", cpu);
++	per_cpu(xen_resched_irq, cpu).name = resched_name;
+ 	rc = bind_ipi_to_irqhandler(XEN_RESCHEDULE_VECTOR,
+ 				    cpu,
+ 				    xen_reschedule_interrupt,
+@@ -74,9 +75,9 @@ int xen_smp_intr_init(unsigned int cpu)
+ 	if (rc < 0)
+ 		goto fail;
+ 	per_cpu(xen_resched_irq, cpu).irq = rc;
+-	per_cpu(xen_resched_irq, cpu).name = resched_name;
+ 
+ 	callfunc_name = kasprintf(GFP_KERNEL, "callfunc%d", cpu);
++	per_cpu(xen_callfunc_irq, cpu).name = callfunc_name;
+ 	rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_VECTOR,
+ 				    cpu,
+ 				    xen_call_function_interrupt,
+@@ -86,10 +87,10 @@ int xen_smp_intr_init(unsigned int cpu)
+ 	if (rc < 0)
+ 		goto fail;
+ 	per_cpu(xen_callfunc_irq, cpu).irq = rc;
+-	per_cpu(xen_callfunc_irq, cpu).name = callfunc_name;
+ 
+ 	if (!xen_fifo_events) {
+ 		debug_name = kasprintf(GFP_KERNEL, "debug%d", cpu);
++		per_cpu(xen_debug_irq, cpu).name = debug_name;
+ 		rc = bind_virq_to_irqhandler(VIRQ_DEBUG, cpu,
+ 					     xen_debug_interrupt,
+ 					     IRQF_PERCPU | IRQF_NOBALANCING,
+@@ -97,10 +98,10 @@ int xen_smp_intr_init(unsigned int cpu)
+ 		if (rc < 0)
+ 			goto fail;
+ 		per_cpu(xen_debug_irq, cpu).irq = rc;
+-		per_cpu(xen_debug_irq, cpu).name = debug_name;
+ 	}
+ 
+ 	callfunc_name = kasprintf(GFP_KERNEL, "callfuncsingle%d", cpu);
++	per_cpu(xen_callfuncsingle_irq, cpu).name = callfunc_name;
+ 	rc = bind_ipi_to_irqhandler(XEN_CALL_FUNCTION_SINGLE_VECTOR,
+ 				    cpu,
+ 				    xen_call_function_single_interrupt,
+@@ -110,7 +111,6 @@ int xen_smp_intr_init(unsigned int cpu)
+ 	if (rc < 0)
+ 		goto fail;
+ 	per_cpu(xen_callfuncsingle_irq, cpu).irq = rc;
+-	per_cpu(xen_callfuncsingle_irq, cpu).name = callfunc_name;
+ 
+ 	return 0;
+ 
+diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c
+index ba7af2eca755b..cd80f8422e173 100644
+--- a/arch/x86/xen/smp_pv.c
++++ b/arch/x86/xen/smp_pv.c
+@@ -97,18 +97,18 @@ asmlinkage __visible void cpu_bringup_and_idle(void)
+ 
+ void xen_smp_intr_free_pv(unsigned int cpu)
+ {
++	kfree(per_cpu(xen_irq_work, cpu).name);
++	per_cpu(xen_irq_work, cpu).name = NULL;
+ 	if (per_cpu(xen_irq_work, cpu).irq >= 0) {
+ 		unbind_from_irqhandler(per_cpu(xen_irq_work, cpu).irq, NULL);
+ 		per_cpu(xen_irq_work, cpu).irq = -1;
+-		kfree(per_cpu(xen_irq_work, cpu).name);
+-		per_cpu(xen_irq_work, cpu).name = NULL;
+ 	}
+ 
++	kfree(per_cpu(xen_pmu_irq, cpu).name);
++	per_cpu(xen_pmu_irq, cpu).name = NULL;
+ 	if (per_cpu(xen_pmu_irq, cpu).irq >= 0) {
+ 		unbind_from_irqhandler(per_cpu(xen_pmu_irq, cpu).irq, NULL);
+ 		per_cpu(xen_pmu_irq, cpu).irq = -1;
+-		kfree(per_cpu(xen_pmu_irq, cpu).name);
+-		per_cpu(xen_pmu_irq, cpu).name = NULL;
+ 	}
+ }
+ 
+@@ -118,6 +118,7 @@ int xen_smp_intr_init_pv(unsigned int cpu)
+ 	char *callfunc_name, *pmu_name;
+ 
+ 	callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu);
++	per_cpu(xen_irq_work, cpu).name = callfunc_name;
+ 	rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR,
+ 				    cpu,
+ 				    xen_irq_work_interrupt,
+@@ -127,10 +128,10 @@ int xen_smp_intr_init_pv(unsigned int cpu)
+ 	if (rc < 0)
+ 		goto fail;
+ 	per_cpu(xen_irq_work, cpu).irq = rc;
+-	per_cpu(xen_irq_work, cpu).name = callfunc_name;
+ 
+ 	if (is_xen_pmu) {
+ 		pmu_name = kasprintf(GFP_KERNEL, "pmu%d", cpu);
++		per_cpu(xen_pmu_irq, cpu).name = pmu_name;
+ 		rc = bind_virq_to_irqhandler(VIRQ_XENPMU, cpu,
+ 					     xen_pmu_irq_handler,
+ 					     IRQF_PERCPU|IRQF_NOBALANCING,
+@@ -138,7 +139,6 @@ int xen_smp_intr_init_pv(unsigned int cpu)
+ 		if (rc < 0)
+ 			goto fail;
+ 		per_cpu(xen_pmu_irq, cpu).irq = rc;
+-		per_cpu(xen_pmu_irq, cpu).name = pmu_name;
+ 	}
+ 
+ 	return 0;
+diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
+index 043c73dfd2c98..5c6fc16e4b925 100644
+--- a/arch/x86/xen/spinlock.c
++++ b/arch/x86/xen/spinlock.c
+@@ -75,6 +75,7 @@ void xen_init_lock_cpu(int cpu)
+ 	     cpu, per_cpu(lock_kicker_irq, cpu));
+ 
+ 	name = kasprintf(GFP_KERNEL, "spinlock%d", cpu);
++	per_cpu(irq_name, cpu) = name;
+ 	irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR,
+ 				     cpu,
+ 				     dummy_handler,
+@@ -85,7 +86,6 @@ void xen_init_lock_cpu(int cpu)
+ 	if (irq >= 0) {
+ 		disable_irq(irq); /* make sure it's never delivered */
+ 		per_cpu(lock_kicker_irq, cpu) = irq;
+-		per_cpu(irq_name, cpu) = name;
+ 	}
+ 
+ 	printk("cpu %d spinlock event irq %d\n", cpu, irq);
+@@ -98,6 +98,8 @@ void xen_uninit_lock_cpu(int cpu)
+ 	if (!xen_pvspin)
+ 		return;
+ 
++	kfree(per_cpu(irq_name, cpu));
++	per_cpu(irq_name, cpu) = NULL;
+ 	/*
+ 	 * When booting the kernel with 'mitigations=auto,nosmt', the secondary
+ 	 * CPUs are not activated, and lock_kicker_irq is not initialized.
+@@ -108,8 +110,6 @@ void xen_uninit_lock_cpu(int cpu)
+ 
+ 	unbind_from_irqhandler(irq, NULL);
+ 	per_cpu(lock_kicker_irq, cpu) = -1;
+-	kfree(per_cpu(irq_name, cpu));
+-	per_cpu(irq_name, cpu) = NULL;
+ }
+ 
+ PV_CALLEE_SAVE_REGS_THUNK(xen_vcpu_stolen);
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index c740b41fe0a49..528ca21044a57 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -386,6 +386,12 @@ static void bfq_put_stable_ref(struct bfq_queue *bfqq);
+ 
+ void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq, bool is_sync)
+ {
++	struct bfq_queue *old_bfqq = bic->bfqq[is_sync];
++
++	/* Clear bic pointer if bfqq is detached from this bic */
++	if (old_bfqq && old_bfqq->bic == bic)
++		old_bfqq->bic = NULL;
++
+ 	/*
+ 	 * If bfqq != NULL, then a non-stable queue merge between
+ 	 * bic->bfqq and bfqq is happening here. This causes troubles
+@@ -5379,7 +5385,6 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync)
+ 		unsigned long flags;
+ 
+ 		spin_lock_irqsave(&bfqd->lock, flags);
+-		bfqq->bic = NULL;
+ 		bfq_exit_bfqq(bfqd, bfqq);
+ 		bic_set_bfqq(bic, NULL, is_sync);
+ 		spin_unlock_irqrestore(&bfqd->lock, flags);
+@@ -6786,6 +6791,12 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
+ 				bfqq = bfq_get_bfqq_handle_split(bfqd, bic, bio,
+ 								 true, is_sync,
+ 								 NULL);
++				if (unlikely(bfqq == &bfqd->oom_bfqq))
++					bfqq_already_existing = true;
++			} else
++				bfqq_already_existing = true;
++
++			if (!bfqq_already_existing) {
+ 				bfqq->waker_bfqq = old_bfqq->waker_bfqq;
+ 				bfqq->tentative_waker_bfqq = NULL;
+ 
+@@ -6799,8 +6810,7 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
+ 				if (bfqq->waker_bfqq)
+ 					hlist_add_head(&bfqq->woken_list_node,
+ 						       &bfqq->waker_bfqq->woken_list);
+-			} else
+-				bfqq_already_existing = true;
++			}
+ 		}
+ 	}
+ 
+diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c
+index 93997d297d427..4515288fbe351 100644
+--- a/block/blk-mq-sysfs.c
++++ b/block/blk-mq-sysfs.c
+@@ -185,7 +185,7 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
+ {
+ 	struct request_queue *q = hctx->queue;
+ 	struct blk_mq_ctx *ctx;
+-	int i, ret;
++	int i, j, ret;
+ 
+ 	if (!hctx->nr_ctx)
+ 		return 0;
+@@ -197,9 +197,16 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
+ 	hctx_for_each_ctx(hctx, ctx, i) {
+ 		ret = kobject_add(&ctx->kobj, &hctx->kobj, "cpu%u", ctx->cpu);
+ 		if (ret)
+-			break;
++			goto out;
+ 	}
+ 
++	return 0;
++out:
++	hctx_for_each_ctx(hctx, ctx, j) {
++		if (j < i)
++			kobject_del(&ctx->kobj);
++	}
++	kobject_del(&hctx->kobj);
+ 	return ret;
+ }
+ 
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 3f1f5e3e0951d..1a30f65802749 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -1442,7 +1442,13 @@ static void blk_mq_rq_timed_out(struct request *req)
+ 	blk_add_timer(req);
+ }
+ 
+-static bool blk_mq_req_expired(struct request *rq, unsigned long *next)
++struct blk_expired_data {
++	bool has_timedout_rq;
++	unsigned long next;
++	unsigned long timeout_start;
++};
++
++static bool blk_mq_req_expired(struct request *rq, struct blk_expired_data *expired)
+ {
+ 	unsigned long deadline;
+ 
+@@ -1452,13 +1458,13 @@ static bool blk_mq_req_expired(struct request *rq, unsigned long *next)
+ 		return false;
+ 
+ 	deadline = READ_ONCE(rq->deadline);
+-	if (time_after_eq(jiffies, deadline))
++	if (time_after_eq(expired->timeout_start, deadline))
+ 		return true;
+ 
+-	if (*next == 0)
+-		*next = deadline;
+-	else if (time_after(*next, deadline))
+-		*next = deadline;
++	if (expired->next == 0)
++		expired->next = deadline;
++	else if (time_after(expired->next, deadline))
++		expired->next = deadline;
+ 	return false;
+ }
+ 
+@@ -1472,7 +1478,7 @@ void blk_mq_put_rq_ref(struct request *rq)
+ 
+ static bool blk_mq_check_expired(struct request *rq, void *priv)
+ {
+-	unsigned long *next = priv;
++	struct blk_expired_data *expired = priv;
+ 
+ 	/*
+ 	 * blk_mq_queue_tag_busy_iter() has locked the request, so it cannot
+@@ -1481,7 +1487,18 @@ static bool blk_mq_check_expired(struct request *rq, void *priv)
+ 	 * it was completed and reallocated as a new request after returning
+ 	 * from blk_mq_check_expired().
+ 	 */
+-	if (blk_mq_req_expired(rq, next))
++	if (blk_mq_req_expired(rq, expired)) {
++		expired->has_timedout_rq = true;
++		return false;
++	}
++	return true;
++}
++
++static bool blk_mq_handle_expired(struct request *rq, void *priv)
++{
++	struct blk_expired_data *expired = priv;
++
++	if (blk_mq_req_expired(rq, expired))
+ 		blk_mq_rq_timed_out(rq);
+ 	return true;
+ }
+@@ -1490,7 +1507,9 @@ static void blk_mq_timeout_work(struct work_struct *work)
+ {
+ 	struct request_queue *q =
+ 		container_of(work, struct request_queue, timeout_work);
+-	unsigned long next = 0;
++	struct blk_expired_data expired = {
++		.timeout_start = jiffies,
++	};
+ 	struct blk_mq_hw_ctx *hctx;
+ 	unsigned long i;
+ 
+@@ -1510,10 +1529,23 @@ static void blk_mq_timeout_work(struct work_struct *work)
+ 	if (!percpu_ref_tryget(&q->q_usage_counter))
+ 		return;
+ 
+-	blk_mq_queue_tag_busy_iter(q, blk_mq_check_expired, &next);
++	/* check if there is any timed-out request */
++	blk_mq_queue_tag_busy_iter(q, blk_mq_check_expired, &expired);
++	if (expired.has_timedout_rq) {
++		/*
++		 * Before walking tags, we must ensure any submit started
++		 * before the current time has finished. Since the submit
++		 * uses srcu or rcu, wait for a synchronization point to
++		 * ensure all running submits have finished
++		 */
++		blk_mq_wait_quiesce_done(q);
++
++		expired.next = 0;
++		blk_mq_queue_tag_busy_iter(q, blk_mq_handle_expired, &expired);
++	}
+ 
+-	if (next != 0) {
+-		mod_timer(&q->timeout, next);
++	if (expired.next != 0) {
++		mod_timer(&q->timeout, expired.next);
+ 	} else {
+ 		/*
+ 		 * Request timeouts are handled as a forward rolling timer. If
+diff --git a/block/genhd.c b/block/genhd.c
+index 044ff97381e33..28654723bc2b2 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -522,6 +522,7 @@ out_unregister_queue:
+ 	rq_qos_exit(disk->queue);
+ out_put_slave_dir:
+ 	kobject_put(disk->slave_dir);
++	disk->slave_dir = NULL;
+ out_put_holder_dir:
+ 	kobject_put(disk->part0->bd_holder_dir);
+ out_del_integrity:
+@@ -618,6 +619,7 @@ void del_gendisk(struct gendisk *disk)
+ 
+ 	kobject_put(disk->part0->bd_holder_dir);
+ 	kobject_put(disk->slave_dir);
++	disk->slave_dir = NULL;
+ 
+ 	part_stat_set_all(disk->part0, 0);
+ 	disk->part0->bd_stamp = 0;
+diff --git a/crypto/cryptd.c b/crypto/cryptd.c
+index 668095eca0faf..ca3a40fc7da91 100644
+--- a/crypto/cryptd.c
++++ b/crypto/cryptd.c
+@@ -68,11 +68,12 @@ struct aead_instance_ctx {
+ 
+ struct cryptd_skcipher_ctx {
+ 	refcount_t refcnt;
+-	struct crypto_sync_skcipher *child;
++	struct crypto_skcipher *child;
+ };
+ 
+ struct cryptd_skcipher_request_ctx {
+ 	crypto_completion_t complete;
++	struct skcipher_request req;
+ };
+ 
+ struct cryptd_hash_ctx {
+@@ -227,13 +228,13 @@ static int cryptd_skcipher_setkey(struct crypto_skcipher *parent,
+ 				  const u8 *key, unsigned int keylen)
+ {
+ 	struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(parent);
+-	struct crypto_sync_skcipher *child = ctx->child;
++	struct crypto_skcipher *child = ctx->child;
+ 
+-	crypto_sync_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
+-	crypto_sync_skcipher_set_flags(child,
+-				       crypto_skcipher_get_flags(parent) &
+-					 CRYPTO_TFM_REQ_MASK);
+-	return crypto_sync_skcipher_setkey(child, key, keylen);
++	crypto_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
++	crypto_skcipher_set_flags(child,
++				  crypto_skcipher_get_flags(parent) &
++				  CRYPTO_TFM_REQ_MASK);
++	return crypto_skcipher_setkey(child, key, keylen);
+ }
+ 
+ static void cryptd_skcipher_complete(struct skcipher_request *req, int err)
+@@ -258,13 +259,13 @@ static void cryptd_skcipher_encrypt(struct crypto_async_request *base,
+ 	struct cryptd_skcipher_request_ctx *rctx = skcipher_request_ctx(req);
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+-	struct crypto_sync_skcipher *child = ctx->child;
+-	SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, child);
++	struct skcipher_request *subreq = &rctx->req;
++	struct crypto_skcipher *child = ctx->child;
+ 
+ 	if (unlikely(err == -EINPROGRESS))
+ 		goto out;
+ 
+-	skcipher_request_set_sync_tfm(subreq, child);
++	skcipher_request_set_tfm(subreq, child);
+ 	skcipher_request_set_callback(subreq, CRYPTO_TFM_REQ_MAY_SLEEP,
+ 				      NULL, NULL);
+ 	skcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
+@@ -286,13 +287,13 @@ static void cryptd_skcipher_decrypt(struct crypto_async_request *base,
+ 	struct cryptd_skcipher_request_ctx *rctx = skcipher_request_ctx(req);
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+-	struct crypto_sync_skcipher *child = ctx->child;
+-	SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, child);
++	struct skcipher_request *subreq = &rctx->req;
++	struct crypto_skcipher *child = ctx->child;
+ 
+ 	if (unlikely(err == -EINPROGRESS))
+ 		goto out;
+ 
+-	skcipher_request_set_sync_tfm(subreq, child);
++	skcipher_request_set_tfm(subreq, child);
+ 	skcipher_request_set_callback(subreq, CRYPTO_TFM_REQ_MAY_SLEEP,
+ 				      NULL, NULL);
+ 	skcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
+@@ -343,9 +344,10 @@ static int cryptd_skcipher_init_tfm(struct crypto_skcipher *tfm)
+ 	if (IS_ERR(cipher))
+ 		return PTR_ERR(cipher);
+ 
+-	ctx->child = (struct crypto_sync_skcipher *)cipher;
++	ctx->child = cipher;
+ 	crypto_skcipher_set_reqsize(
+-		tfm, sizeof(struct cryptd_skcipher_request_ctx));
++		tfm, sizeof(struct cryptd_skcipher_request_ctx) +
++		     crypto_skcipher_reqsize(cipher));
+ 	return 0;
+ }
+ 
+@@ -353,7 +355,7 @@ static void cryptd_skcipher_exit_tfm(struct crypto_skcipher *tfm)
+ {
+ 	struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ 
+-	crypto_free_sync_skcipher(ctx->child);
++	crypto_free_skcipher(ctx->child);
+ }
+ 
+ static void cryptd_skcipher_free(struct skcipher_instance *inst)
+@@ -931,7 +933,7 @@ struct crypto_skcipher *cryptd_skcipher_child(struct cryptd_skcipher *tfm)
+ {
+ 	struct cryptd_skcipher_ctx *ctx = crypto_skcipher_ctx(&tfm->base);
+ 
+-	return &ctx->child->base;
++	return ctx->child;
+ }
+ EXPORT_SYMBOL_GPL(cryptd_skcipher_child);
+ 
+diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
+index 59eb8ec366643..bc57b182f3047 100644
+--- a/crypto/tcrypt.c
++++ b/crypto/tcrypt.c
+@@ -1101,15 +1101,6 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs,
+ 			goto out_free_tfm;
+ 		}
+ 
+-
+-	for (i = 0; i < num_mb; ++i)
+-		if (testmgr_alloc_buf(data[i].xbuf)) {
+-			while (i--)
+-				testmgr_free_buf(data[i].xbuf);
+-			goto out_free_tfm;
+-		}
+-
+-
+ 	for (i = 0; i < num_mb; ++i) {
+ 		data[i].req = skcipher_request_alloc(tfm, GFP_KERNEL);
+ 		if (!data[i].req) {
+@@ -1494,387 +1485,387 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
+ 		}
+ 
+ 		for (i = 1; i < 200; i++)
+-			ret += do_test(NULL, 0, 0, i, num_mb);
++			ret = min(ret, do_test(NULL, 0, 0, i, num_mb));
+ 		break;
+ 
+ 	case 1:
+-		ret += tcrypt_test("md5");
++		ret = min(ret, tcrypt_test("md5"));
+ 		break;
+ 
+ 	case 2:
+-		ret += tcrypt_test("sha1");
++		ret = min(ret, tcrypt_test("sha1"));
+ 		break;
+ 
+ 	case 3:
+-		ret += tcrypt_test("ecb(des)");
+-		ret += tcrypt_test("cbc(des)");
+-		ret += tcrypt_test("ctr(des)");
++		ret = min(ret, tcrypt_test("ecb(des)"));
++		ret = min(ret, tcrypt_test("cbc(des)"));
++		ret = min(ret, tcrypt_test("ctr(des)"));
+ 		break;
+ 
+ 	case 4:
+-		ret += tcrypt_test("ecb(des3_ede)");
+-		ret += tcrypt_test("cbc(des3_ede)");
+-		ret += tcrypt_test("ctr(des3_ede)");
++		ret = min(ret, tcrypt_test("ecb(des3_ede)"));
++		ret = min(ret, tcrypt_test("cbc(des3_ede)"));
++		ret = min(ret, tcrypt_test("ctr(des3_ede)"));
+ 		break;
+ 
+ 	case 5:
+-		ret += tcrypt_test("md4");
++		ret = min(ret, tcrypt_test("md4"));
+ 		break;
+ 
+ 	case 6:
+-		ret += tcrypt_test("sha256");
++		ret = min(ret, tcrypt_test("sha256"));
+ 		break;
+ 
+ 	case 7:
+-		ret += tcrypt_test("ecb(blowfish)");
+-		ret += tcrypt_test("cbc(blowfish)");
+-		ret += tcrypt_test("ctr(blowfish)");
++		ret = min(ret, tcrypt_test("ecb(blowfish)"));
++		ret = min(ret, tcrypt_test("cbc(blowfish)"));
++		ret = min(ret, tcrypt_test("ctr(blowfish)"));
+ 		break;
+ 
+ 	case 8:
+-		ret += tcrypt_test("ecb(twofish)");
+-		ret += tcrypt_test("cbc(twofish)");
+-		ret += tcrypt_test("ctr(twofish)");
+-		ret += tcrypt_test("lrw(twofish)");
+-		ret += tcrypt_test("xts(twofish)");
++		ret = min(ret, tcrypt_test("ecb(twofish)"));
++		ret = min(ret, tcrypt_test("cbc(twofish)"));
++		ret = min(ret, tcrypt_test("ctr(twofish)"));
++		ret = min(ret, tcrypt_test("lrw(twofish)"));
++		ret = min(ret, tcrypt_test("xts(twofish)"));
+ 		break;
+ 
+ 	case 9:
+-		ret += tcrypt_test("ecb(serpent)");
+-		ret += tcrypt_test("cbc(serpent)");
+-		ret += tcrypt_test("ctr(serpent)");
+-		ret += tcrypt_test("lrw(serpent)");
+-		ret += tcrypt_test("xts(serpent)");
++		ret = min(ret, tcrypt_test("ecb(serpent)"));
++		ret = min(ret, tcrypt_test("cbc(serpent)"));
++		ret = min(ret, tcrypt_test("ctr(serpent)"));
++		ret = min(ret, tcrypt_test("lrw(serpent)"));
++		ret = min(ret, tcrypt_test("xts(serpent)"));
+ 		break;
+ 
+ 	case 10:
+-		ret += tcrypt_test("ecb(aes)");
+-		ret += tcrypt_test("cbc(aes)");
+-		ret += tcrypt_test("lrw(aes)");
+-		ret += tcrypt_test("xts(aes)");
+-		ret += tcrypt_test("ctr(aes)");
+-		ret += tcrypt_test("rfc3686(ctr(aes))");
+-		ret += tcrypt_test("ofb(aes)");
+-		ret += tcrypt_test("cfb(aes)");
+-		ret += tcrypt_test("xctr(aes)");
++		ret = min(ret, tcrypt_test("ecb(aes)"));
++		ret = min(ret, tcrypt_test("cbc(aes)"));
++		ret = min(ret, tcrypt_test("lrw(aes)"));
++		ret = min(ret, tcrypt_test("xts(aes)"));
++		ret = min(ret, tcrypt_test("ctr(aes)"));
++		ret = min(ret, tcrypt_test("rfc3686(ctr(aes))"));
++		ret = min(ret, tcrypt_test("ofb(aes)"));
++		ret = min(ret, tcrypt_test("cfb(aes)"));
++		ret = min(ret, tcrypt_test("xctr(aes)"));
+ 		break;
+ 
+ 	case 11:
+-		ret += tcrypt_test("sha384");
++		ret = min(ret, tcrypt_test("sha384"));
+ 		break;
+ 
+ 	case 12:
+-		ret += tcrypt_test("sha512");
++		ret = min(ret, tcrypt_test("sha512"));
+ 		break;
+ 
+ 	case 13:
+-		ret += tcrypt_test("deflate");
++		ret = min(ret, tcrypt_test("deflate"));
+ 		break;
+ 
+ 	case 14:
+-		ret += tcrypt_test("ecb(cast5)");
+-		ret += tcrypt_test("cbc(cast5)");
+-		ret += tcrypt_test("ctr(cast5)");
++		ret = min(ret, tcrypt_test("ecb(cast5)"));
++		ret = min(ret, tcrypt_test("cbc(cast5)"));
++		ret = min(ret, tcrypt_test("ctr(cast5)"));
+ 		break;
+ 
+ 	case 15:
+-		ret += tcrypt_test("ecb(cast6)");
+-		ret += tcrypt_test("cbc(cast6)");
+-		ret += tcrypt_test("ctr(cast6)");
+-		ret += tcrypt_test("lrw(cast6)");
+-		ret += tcrypt_test("xts(cast6)");
++		ret = min(ret, tcrypt_test("ecb(cast6)"));
++		ret = min(ret, tcrypt_test("cbc(cast6)"));
++		ret = min(ret, tcrypt_test("ctr(cast6)"));
++		ret = min(ret, tcrypt_test("lrw(cast6)"));
++		ret = min(ret, tcrypt_test("xts(cast6)"));
+ 		break;
+ 
+ 	case 16:
+-		ret += tcrypt_test("ecb(arc4)");
++		ret = min(ret, tcrypt_test("ecb(arc4)"));
+ 		break;
+ 
+ 	case 17:
+-		ret += tcrypt_test("michael_mic");
++		ret = min(ret, tcrypt_test("michael_mic"));
+ 		break;
+ 
+ 	case 18:
+-		ret += tcrypt_test("crc32c");
++		ret = min(ret, tcrypt_test("crc32c"));
+ 		break;
+ 
+ 	case 19:
+-		ret += tcrypt_test("ecb(tea)");
++		ret = min(ret, tcrypt_test("ecb(tea)"));
+ 		break;
+ 
+ 	case 20:
+-		ret += tcrypt_test("ecb(xtea)");
++		ret = min(ret, tcrypt_test("ecb(xtea)"));
+ 		break;
+ 
+ 	case 21:
+-		ret += tcrypt_test("ecb(khazad)");
++		ret = min(ret, tcrypt_test("ecb(khazad)"));
+ 		break;
+ 
+ 	case 22:
+-		ret += tcrypt_test("wp512");
++		ret = min(ret, tcrypt_test("wp512"));
+ 		break;
+ 
+ 	case 23:
+-		ret += tcrypt_test("wp384");
++		ret = min(ret, tcrypt_test("wp384"));
+ 		break;
+ 
+ 	case 24:
+-		ret += tcrypt_test("wp256");
++		ret = min(ret, tcrypt_test("wp256"));
+ 		break;
+ 
+ 	case 26:
+-		ret += tcrypt_test("ecb(anubis)");
+-		ret += tcrypt_test("cbc(anubis)");
++		ret = min(ret, tcrypt_test("ecb(anubis)"));
++		ret = min(ret, tcrypt_test("cbc(anubis)"));
+ 		break;
+ 
+ 	case 30:
+-		ret += tcrypt_test("ecb(xeta)");
++		ret = min(ret, tcrypt_test("ecb(xeta)"));
+ 		break;
+ 
+ 	case 31:
+-		ret += tcrypt_test("pcbc(fcrypt)");
++		ret = min(ret, tcrypt_test("pcbc(fcrypt)"));
+ 		break;
+ 
+ 	case 32:
+-		ret += tcrypt_test("ecb(camellia)");
+-		ret += tcrypt_test("cbc(camellia)");
+-		ret += tcrypt_test("ctr(camellia)");
+-		ret += tcrypt_test("lrw(camellia)");
+-		ret += tcrypt_test("xts(camellia)");
++		ret = min(ret, tcrypt_test("ecb(camellia)"));
++		ret = min(ret, tcrypt_test("cbc(camellia)"));
++		ret = min(ret, tcrypt_test("ctr(camellia)"));
++		ret = min(ret, tcrypt_test("lrw(camellia)"));
++		ret = min(ret, tcrypt_test("xts(camellia)"));
+ 		break;
+ 
+ 	case 33:
+-		ret += tcrypt_test("sha224");
++		ret = min(ret, tcrypt_test("sha224"));
+ 		break;
+ 
+ 	case 35:
+-		ret += tcrypt_test("gcm(aes)");
++		ret = min(ret, tcrypt_test("gcm(aes)"));
+ 		break;
+ 
+ 	case 36:
+-		ret += tcrypt_test("lzo");
++		ret = min(ret, tcrypt_test("lzo"));
+ 		break;
+ 
+ 	case 37:
+-		ret += tcrypt_test("ccm(aes)");
++		ret = min(ret, tcrypt_test("ccm(aes)"));
+ 		break;
+ 
+ 	case 38:
+-		ret += tcrypt_test("cts(cbc(aes))");
++		ret = min(ret, tcrypt_test("cts(cbc(aes))"));
+ 		break;
+ 
+         case 39:
+-		ret += tcrypt_test("xxhash64");
++		ret = min(ret, tcrypt_test("xxhash64"));
+ 		break;
+ 
+         case 40:
+-		ret += tcrypt_test("rmd160");
++		ret = min(ret, tcrypt_test("rmd160"));
+ 		break;
+ 
+ 	case 42:
+-		ret += tcrypt_test("blake2b-512");
++		ret = min(ret, tcrypt_test("blake2b-512"));
+ 		break;
+ 
+ 	case 43:
+-		ret += tcrypt_test("ecb(seed)");
++		ret = min(ret, tcrypt_test("ecb(seed)"));
+ 		break;
+ 
+ 	case 45:
+-		ret += tcrypt_test("rfc4309(ccm(aes))");
++		ret = min(ret, tcrypt_test("rfc4309(ccm(aes))"));
+ 		break;
+ 
+ 	case 46:
+-		ret += tcrypt_test("ghash");
++		ret = min(ret, tcrypt_test("ghash"));
+ 		break;
+ 
+ 	case 47:
+-		ret += tcrypt_test("crct10dif");
++		ret = min(ret, tcrypt_test("crct10dif"));
+ 		break;
+ 
+ 	case 48:
+-		ret += tcrypt_test("sha3-224");
++		ret = min(ret, tcrypt_test("sha3-224"));
+ 		break;
+ 
+ 	case 49:
+-		ret += tcrypt_test("sha3-256");
++		ret = min(ret, tcrypt_test("sha3-256"));
+ 		break;
+ 
+ 	case 50:
+-		ret += tcrypt_test("sha3-384");
++		ret = min(ret, tcrypt_test("sha3-384"));
+ 		break;
+ 
+ 	case 51:
+-		ret += tcrypt_test("sha3-512");
++		ret = min(ret, tcrypt_test("sha3-512"));
+ 		break;
+ 
+ 	case 52:
+-		ret += tcrypt_test("sm3");
++		ret = min(ret, tcrypt_test("sm3"));
+ 		break;
+ 
+ 	case 53:
+-		ret += tcrypt_test("streebog256");
++		ret = min(ret, tcrypt_test("streebog256"));
+ 		break;
+ 
+ 	case 54:
+-		ret += tcrypt_test("streebog512");
++		ret = min(ret, tcrypt_test("streebog512"));
+ 		break;
+ 
+ 	case 55:
+-		ret += tcrypt_test("gcm(sm4)");
++		ret = min(ret, tcrypt_test("gcm(sm4)"));
+ 		break;
+ 
+ 	case 56:
+-		ret += tcrypt_test("ccm(sm4)");
++		ret = min(ret, tcrypt_test("ccm(sm4)"));
+ 		break;
+ 
+ 	case 57:
+-		ret += tcrypt_test("polyval");
++		ret = min(ret, tcrypt_test("polyval"));
+ 		break;
+ 
+ 	case 58:
+-		ret += tcrypt_test("gcm(aria)");
++		ret = min(ret, tcrypt_test("gcm(aria)"));
+ 		break;
+ 
+ 	case 100:
+-		ret += tcrypt_test("hmac(md5)");
++		ret = min(ret, tcrypt_test("hmac(md5)"));
+ 		break;
+ 
+ 	case 101:
+-		ret += tcrypt_test("hmac(sha1)");
++		ret = min(ret, tcrypt_test("hmac(sha1)"));
+ 		break;
+ 
+ 	case 102:
+-		ret += tcrypt_test("hmac(sha256)");
++		ret = min(ret, tcrypt_test("hmac(sha256)"));
+ 		break;
+ 
+ 	case 103:
+-		ret += tcrypt_test("hmac(sha384)");
++		ret = min(ret, tcrypt_test("hmac(sha384)"));
+ 		break;
+ 
+ 	case 104:
+-		ret += tcrypt_test("hmac(sha512)");
++		ret = min(ret, tcrypt_test("hmac(sha512)"));
+ 		break;
+ 
+ 	case 105:
+-		ret += tcrypt_test("hmac(sha224)");
++		ret = min(ret, tcrypt_test("hmac(sha224)"));
+ 		break;
+ 
+ 	case 106:
+-		ret += tcrypt_test("xcbc(aes)");
++		ret = min(ret, tcrypt_test("xcbc(aes)"));
+ 		break;
+ 
+ 	case 108:
+-		ret += tcrypt_test("hmac(rmd160)");
++		ret = min(ret, tcrypt_test("hmac(rmd160)"));
+ 		break;
+ 
+ 	case 109:
+-		ret += tcrypt_test("vmac64(aes)");
++		ret = min(ret, tcrypt_test("vmac64(aes)"));
+ 		break;
+ 
+ 	case 111:
+-		ret += tcrypt_test("hmac(sha3-224)");
++		ret = min(ret, tcrypt_test("hmac(sha3-224)"));
+ 		break;
+ 
+ 	case 112:
+-		ret += tcrypt_test("hmac(sha3-256)");
++		ret = min(ret, tcrypt_test("hmac(sha3-256)"));
+ 		break;
+ 
+ 	case 113:
+-		ret += tcrypt_test("hmac(sha3-384)");
++		ret = min(ret, tcrypt_test("hmac(sha3-384)"));
+ 		break;
+ 
+ 	case 114:
+-		ret += tcrypt_test("hmac(sha3-512)");
++		ret = min(ret, tcrypt_test("hmac(sha3-512)"));
+ 		break;
+ 
+ 	case 115:
+-		ret += tcrypt_test("hmac(streebog256)");
++		ret = min(ret, tcrypt_test("hmac(streebog256)"));
+ 		break;
+ 
+ 	case 116:
+-		ret += tcrypt_test("hmac(streebog512)");
++		ret = min(ret, tcrypt_test("hmac(streebog512)"));
+ 		break;
+ 
+ 	case 150:
+-		ret += tcrypt_test("ansi_cprng");
++		ret = min(ret, tcrypt_test("ansi_cprng"));
+ 		break;
+ 
+ 	case 151:
+-		ret += tcrypt_test("rfc4106(gcm(aes))");
++		ret = min(ret, tcrypt_test("rfc4106(gcm(aes))"));
+ 		break;
+ 
+ 	case 152:
+-		ret += tcrypt_test("rfc4543(gcm(aes))");
++		ret = min(ret, tcrypt_test("rfc4543(gcm(aes))"));
+ 		break;
+ 
+ 	case 153:
+-		ret += tcrypt_test("cmac(aes)");
++		ret = min(ret, tcrypt_test("cmac(aes)"));
+ 		break;
+ 
+ 	case 154:
+-		ret += tcrypt_test("cmac(des3_ede)");
++		ret = min(ret, tcrypt_test("cmac(des3_ede)"));
+ 		break;
+ 
+ 	case 155:
+-		ret += tcrypt_test("authenc(hmac(sha1),cbc(aes))");
++		ret = min(ret, tcrypt_test("authenc(hmac(sha1),cbc(aes))"));
+ 		break;
+ 
+ 	case 156:
+-		ret += tcrypt_test("authenc(hmac(md5),ecb(cipher_null))");
++		ret = min(ret, tcrypt_test("authenc(hmac(md5),ecb(cipher_null))"));
+ 		break;
+ 
+ 	case 157:
+-		ret += tcrypt_test("authenc(hmac(sha1),ecb(cipher_null))");
++		ret = min(ret, tcrypt_test("authenc(hmac(sha1),ecb(cipher_null))"));
+ 		break;
+ 
+ 	case 158:
+-		ret += tcrypt_test("cbcmac(sm4)");
++		ret = min(ret, tcrypt_test("cbcmac(sm4)"));
+ 		break;
+ 
+ 	case 159:
+-		ret += tcrypt_test("cmac(sm4)");
++		ret = min(ret, tcrypt_test("cmac(sm4)"));
+ 		break;
+ 
+ 	case 181:
+-		ret += tcrypt_test("authenc(hmac(sha1),cbc(des))");
++		ret = min(ret, tcrypt_test("authenc(hmac(sha1),cbc(des))"));
+ 		break;
+ 	case 182:
+-		ret += tcrypt_test("authenc(hmac(sha1),cbc(des3_ede))");
++		ret = min(ret, tcrypt_test("authenc(hmac(sha1),cbc(des3_ede))"));
+ 		break;
+ 	case 183:
+-		ret += tcrypt_test("authenc(hmac(sha224),cbc(des))");
++		ret = min(ret, tcrypt_test("authenc(hmac(sha224),cbc(des))"));
+ 		break;
+ 	case 184:
+-		ret += tcrypt_test("authenc(hmac(sha224),cbc(des3_ede))");
++		ret = min(ret, tcrypt_test("authenc(hmac(sha224),cbc(des3_ede))"));
+ 		break;
+ 	case 185:
+-		ret += tcrypt_test("authenc(hmac(sha256),cbc(des))");
++		ret = min(ret, tcrypt_test("authenc(hmac(sha256),cbc(des))"));
+ 		break;
+ 	case 186:
+-		ret += tcrypt_test("authenc(hmac(sha256),cbc(des3_ede))");
++		ret = min(ret, tcrypt_test("authenc(hmac(sha256),cbc(des3_ede))"));
+ 		break;
+ 	case 187:
+-		ret += tcrypt_test("authenc(hmac(sha384),cbc(des))");
++		ret = min(ret, tcrypt_test("authenc(hmac(sha384),cbc(des))"));
+ 		break;
+ 	case 188:
+-		ret += tcrypt_test("authenc(hmac(sha384),cbc(des3_ede))");
++		ret = min(ret, tcrypt_test("authenc(hmac(sha384),cbc(des3_ede))"));
+ 		break;
+ 	case 189:
+-		ret += tcrypt_test("authenc(hmac(sha512),cbc(des))");
++		ret = min(ret, tcrypt_test("authenc(hmac(sha512),cbc(des))"));
+ 		break;
+ 	case 190:
+-		ret += tcrypt_test("authenc(hmac(sha512),cbc(des3_ede))");
++		ret = min(ret, tcrypt_test("authenc(hmac(sha512),cbc(des3_ede))"));
+ 		break;
+ 	case 191:
+-		ret += tcrypt_test("ecb(sm4)");
+-		ret += tcrypt_test("cbc(sm4)");
+-		ret += tcrypt_test("cfb(sm4)");
+-		ret += tcrypt_test("ctr(sm4)");
++		ret = min(ret, tcrypt_test("ecb(sm4)"));
++		ret = min(ret, tcrypt_test("cbc(sm4)"));
++		ret = min(ret, tcrypt_test("cfb(sm4)"));
++		ret = min(ret, tcrypt_test("ctr(sm4)"));
+ 		break;
+ 	case 192:
+-		ret += tcrypt_test("ecb(aria)");
+-		ret += tcrypt_test("cbc(aria)");
+-		ret += tcrypt_test("cfb(aria)");
+-		ret += tcrypt_test("ctr(aria)");
++		ret = min(ret, tcrypt_test("ecb(aria)"));
++		ret = min(ret, tcrypt_test("cbc(aria)"));
++		ret = min(ret, tcrypt_test("cfb(aria)"));
++		ret = min(ret, tcrypt_test("ctr(aria)"));
+ 		break;
+ 	case 200:
+ 		test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
+diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c
+index ae2e768830bfc..9332bc688713c 100644
+--- a/drivers/acpi/acpica/dsmethod.c
++++ b/drivers/acpi/acpica/dsmethod.c
+@@ -517,7 +517,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
+ 	info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
+ 	if (!info) {
+ 		status = AE_NO_MEMORY;
+-		goto cleanup;
++		goto pop_walk_state;
+ 	}
+ 
+ 	info->parameters = &this_walk_state->operands[0];
+@@ -529,7 +529,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
+ 
+ 	ACPI_FREE(info);
+ 	if (ACPI_FAILURE(status)) {
+-		goto cleanup;
++		goto pop_walk_state;
+ 	}
+ 
+ 	next_walk_state->method_nesting_depth =
+@@ -575,6 +575,12 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
+ 
+ 	return_ACPI_STATUS(status);
+ 
++pop_walk_state:
++
++	/* On error, pop the walk state to be deleted from thread */
++
++	acpi_ds_pop_walk_state(thread);
++
+ cleanup:
+ 
+ 	/* On error, we must terminate the method properly */
+diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
+index 400b9e15a709c..63c17f420fb86 100644
+--- a/drivers/acpi/acpica/utcopy.c
++++ b/drivers/acpi/acpica/utcopy.c
+@@ -916,13 +916,6 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
+ 	status = acpi_ut_walk_package_tree(source_obj, dest_obj,
+ 					   acpi_ut_copy_ielement_to_ielement,
+ 					   walk_state);
+-	if (ACPI_FAILURE(status)) {
+-
+-		/* On failure, delete the destination package object */
+-
+-		acpi_ut_remove_reference(dest_obj);
+-	}
+-
+ 	return_ACPI_STATUS(status);
+ }
+ 
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index c95e535035a04..fdc760e1e09ef 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -1879,6 +1879,16 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"),
+ 		},
+ 	},
++	{
++		/*
++		 * HP Pavilion Gaming Laptop 15-cx0041ur
++		 */
++		.callback = ec_honor_dsdt_gpe,
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "HP 15-cx0041ur"),
++		},
++	},
+ 	{
+ 		/*
+ 		 * Samsung hardware
+diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
+index dabe45eba055d..0d9a17fdd83eb 100644
+--- a/drivers/acpi/irq.c
++++ b/drivers/acpi/irq.c
+@@ -94,6 +94,7 @@ EXPORT_SYMBOL_GPL(acpi_unregister_gsi);
+ /**
+  * acpi_get_irq_source_fwhandle() - Retrieve fwhandle from IRQ resource source.
+  * @source: acpi_resource_source to use for the lookup.
++ * @gsi: GSI IRQ number
+  *
+  * Description:
+  * Retrieve the fwhandle of the device referenced by the given IRQ resource
+@@ -295,8 +296,8 @@ EXPORT_SYMBOL_GPL(acpi_irq_get);
+ /**
+  * acpi_set_irq_model - Setup the GSI irqdomain information
+  * @model: the value assigned to acpi_irq_model
+- * @fwnode: the irq_domain identifier for mapping and looking up
+- *          GSI interrupts
++ * @fn: a dispatcher function that will return the domain fwnode
++ *	for a given GSI
+  */
+ void __init acpi_set_irq_model(enum acpi_irq_model_id model,
+ 			       struct fwnode_handle *(*fn)(u32))
+diff --git a/drivers/acpi/pfr_telemetry.c b/drivers/acpi/pfr_telemetry.c
+index 9abf350bd7a5a..27fb6cdad75f9 100644
+--- a/drivers/acpi/pfr_telemetry.c
++++ b/drivers/acpi/pfr_telemetry.c
+@@ -144,7 +144,7 @@ static int get_pfrt_log_data_info(struct pfrt_log_data_info *data_info,
+ 	ret = 0;
+ 
+ free_acpi_buffer:
+-	kfree(out_obj);
++	ACPI_FREE(out_obj);
+ 
+ 	return ret;
+ }
+@@ -180,7 +180,7 @@ static int set_pfrt_log_level(int level, struct pfrt_log_device *pfrt_log_dev)
+ 		ret = -EBUSY;
+ 	}
+ 
+-	kfree(out_obj);
++	ACPI_FREE(out_obj);
+ 
+ 	return ret;
+ }
+@@ -218,7 +218,7 @@ static int get_pfrt_log_level(struct pfrt_log_device *pfrt_log_dev)
+ 	ret = obj->integer.value;
+ 
+ free_acpi_buffer:
+-	kfree(out_obj);
++	ACPI_FREE(out_obj);
+ 
+ 	return ret;
+ }
+diff --git a/drivers/acpi/pfr_update.c b/drivers/acpi/pfr_update.c
+index 6bb0b778b5da5..9d2bdc13253a5 100644
+--- a/drivers/acpi/pfr_update.c
++++ b/drivers/acpi/pfr_update.c
+@@ -178,7 +178,7 @@ static int query_capability(struct pfru_update_cap_info *cap_hdr,
+ 	ret = 0;
+ 
+ free_acpi_buffer:
+-	kfree(out_obj);
++	ACPI_FREE(out_obj);
+ 
+ 	return ret;
+ }
+@@ -224,7 +224,7 @@ static int query_buffer(struct pfru_com_buf_info *info,
+ 	ret = 0;
+ 
+ free_acpi_buffer:
+-	kfree(out_obj);
++	ACPI_FREE(out_obj);
+ 
+ 	return ret;
+ }
+@@ -385,7 +385,7 @@ static int start_update(int action, struct pfru_device *pfru_dev)
+ 	ret = 0;
+ 
+ free_acpi_buffer:
+-	kfree(out_obj);
++	ACPI_FREE(out_obj);
+ 
+ 	return ret;
+ }
+diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
+index 9f40917c49efb..4d1dd255c1228 100644
+--- a/drivers/acpi/processor_idle.c
++++ b/drivers/acpi/processor_idle.c
+@@ -1134,6 +1134,9 @@ static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
+ 	status = acpi_get_parent(handle, &pr_ahandle);
+ 	while (ACPI_SUCCESS(status)) {
+ 		d = acpi_fetch_acpi_dev(pr_ahandle);
++		if (!d)
++			break;
++
+ 		handle = pr_ahandle;
+ 
+ 		if (strcmp(acpi_device_hid(d), ACPI_PROCESSOR_CONTAINER_HID))
+diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
+index 950a93922ca8f..ae60e4aae0eec 100644
+--- a/drivers/acpi/x86/utils.c
++++ b/drivers/acpi/x86/utils.c
+@@ -308,7 +308,7 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
+ 					ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
+ 	},
+ 	{
+-		/* Lenovo Yoga Tablet 1050F/L */
++		/* Lenovo Yoga Tablet 2 1050F/L */
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
+@@ -319,6 +319,27 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
+ 		.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
+ 					ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
+ 	},
++	{
++		/* Lenovo Yoga Tab 3 Pro X90F */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
++			DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
++		},
++		.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
++					ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
++	},
++	{
++		/* Medion Lifetab S10346 */
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
++			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
++			/* Way too generic, also match on BIOS data */
++			DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"),
++		},
++		.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
++					ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
++	},
+ 	{
+ 		/* Nextbook Ares 8 */
+ 		.matches = {
+@@ -348,6 +369,7 @@ static const struct acpi_device_id i2c_acpi_known_good_ids[] = {
+ 	{ "10EC5640", 0 }, /* RealTek ALC5640 audio codec */
+ 	{ "INT33F4", 0 },  /* X-Powers AXP288 PMIC */
+ 	{ "INT33FD", 0 },  /* Intel Crystal Cove PMIC */
++	{ "INT34D3", 0 },  /* Intel Whiskey Cove PMIC */
+ 	{ "NPCE69A", 0 },  /* Asus Transformer keyboard dock */
+ 	{}
+ };
+diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c
+index 13b9d0fdd42c8..8e292e2abb046 100644
+--- a/drivers/ata/libata-sata.c
++++ b/drivers/ata/libata-sata.c
+@@ -1392,7 +1392,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
+ 	tf->hob_lbah = buf[10];
+ 	tf->nsect = buf[12];
+ 	tf->hob_nsect = buf[13];
+-	if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id))
++	if (dev->class == ATA_DEV_ZAC && ata_id_has_ncq_autosense(dev->id) &&
++	    (tf->status & ATA_SENSE))
+ 		tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16];
+ 
+ 	return 0;
+@@ -1456,8 +1457,12 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
+ 	memcpy(&qc->result_tf, &tf, sizeof(tf));
+ 	qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
+ 	qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ;
+-	if (dev->class == ATA_DEV_ZAC &&
+-	    ((qc->result_tf.status & ATA_SENSE) || qc->result_tf.auxiliary)) {
++
++	/*
++	 * If the device supports NCQ autosense, ata_eh_read_log_10h() will have
++	 * stored the sense data in qc->result_tf.auxiliary.
++	 */
++	if (qc->result_tf.auxiliary) {
+ 		char sense_key, asc, ascq;
+ 
+ 		sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
+diff --git a/drivers/base/class.c b/drivers/base/class.c
+index 8feb85e186e3b..e394e3e473b5d 100644
+--- a/drivers/base/class.c
++++ b/drivers/base/class.c
+@@ -192,6 +192,11 @@ int __class_register(struct class *cls, struct lock_class_key *key)
+ 	}
+ 	error = class_add_groups(class_get(cls), cls->class_groups);
+ 	class_put(cls);
++	if (error) {
++		kobject_del(&cp->subsys.kobj);
++		kfree_const(cp->subsys.kobj.name);
++		kfree(cp);
++	}
+ 	return error;
+ }
+ EXPORT_SYMBOL_GPL(__class_register);
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
+index 997be3ac20a79..d36fb07190bf5 100644
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -484,7 +484,17 @@ static int rpm_idle(struct device *dev, int rpmflags)
+ 
+ 	dev->power.idle_notification = true;
+ 
+-	retval = __rpm_callback(callback, dev);
++	if (dev->power.irq_safe)
++		spin_unlock(&dev->power.lock);
++	else
++		spin_unlock_irq(&dev->power.lock);
++
++	retval = callback(dev);
++
++	if (dev->power.irq_safe)
++		spin_lock(&dev->power.lock);
++	else
++		spin_lock_irq(&dev->power.lock);
+ 
+ 	dev->power.idle_notification = false;
+ 	wake_up_all(&dev->power.wait_queue);
+diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
+index 4ef9488d05cde..3de89795f5843 100644
+--- a/drivers/base/regmap/regmap-irq.c
++++ b/drivers/base/regmap/regmap-irq.c
+@@ -722,6 +722,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
+ 	int i;
+ 	int ret = -ENOMEM;
+ 	int num_type_reg;
++	int num_regs;
+ 	u32 reg;
+ 
+ 	if (chip->num_regs <= 0)
+@@ -796,14 +797,20 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
+ 			goto err_alloc;
+ 	}
+ 
+-	num_type_reg = chip->type_in_mask ? chip->num_regs : chip->num_type_reg;
+-	if (num_type_reg) {
+-		d->type_buf_def = kcalloc(num_type_reg,
++	/*
++	 * Use num_config_regs if defined, otherwise fall back to num_type_reg
++	 * to maintain backward compatibility.
++	 */
++	num_type_reg = chip->num_config_regs ? chip->num_config_regs
++			: chip->num_type_reg;
++	num_regs = chip->type_in_mask ? chip->num_regs : num_type_reg;
++	if (num_regs) {
++		d->type_buf_def = kcalloc(num_regs,
+ 					  sizeof(*d->type_buf_def), GFP_KERNEL);
+ 		if (!d->type_buf_def)
+ 			goto err_alloc;
+ 
+-		d->type_buf = kcalloc(num_type_reg, sizeof(*d->type_buf),
++		d->type_buf = kcalloc(num_regs, sizeof(*d->type_buf),
+ 				      GFP_KERNEL);
+ 		if (!d->type_buf)
+ 			goto err_alloc;
+diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
+index 8532b839a3435..6772402326842 100644
+--- a/drivers/block/drbd/drbd_main.c
++++ b/drivers/block/drbd/drbd_main.c
+@@ -2217,7 +2217,8 @@ void drbd_destroy_device(struct kref *kref)
+ 		kref_put(&peer_device->connection->kref, drbd_destroy_connection);
+ 		kfree(peer_device);
+ 	}
+-	memset(device, 0xfd, sizeof(*device));
++	if (device->submit.wq)
++		destroy_workqueue(device->submit.wq);
+ 	kfree(device);
+ 	kref_put(&resource->kref, drbd_destroy_resource);
+ }
+@@ -2309,7 +2310,6 @@ void drbd_destroy_resource(struct kref *kref)
+ 	idr_destroy(&resource->devices);
+ 	free_cpumask_var(resource->cpu_mask);
+ 	kfree(resource->name);
+-	memset(resource, 0xf2, sizeof(*resource));
+ 	kfree(resource);
+ }
+ 
+@@ -2650,7 +2650,6 @@ void drbd_destroy_connection(struct kref *kref)
+ 	drbd_free_socket(&connection->data);
+ 	kfree(connection->int_dig_in);
+ 	kfree(connection->int_dig_vv);
+-	memset(connection, 0xfc, sizeof(*connection));
+ 	kfree(connection);
+ 	kref_put(&resource->kref, drbd_destroy_resource);
+ }
+@@ -2774,7 +2773,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
+ 
+ 	err = add_disk(disk);
+ 	if (err)
+-		goto out_idr_remove_from_resource;
++		goto out_destroy_workqueue;
+ 
+ 	/* inherit the connection state */
+ 	device->state.conn = first_connection(resource)->cstate;
+@@ -2788,6 +2787,8 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
+ 	drbd_debugfs_device_add(device);
+ 	return NO_ERROR;
+ 
++out_destroy_workqueue:
++	destroy_workqueue(device->submit.wq);
+ out_idr_remove_from_resource:
+ 	for_each_connection_safe(connection, n, resource) {
+ 		peer_device = idr_remove(&connection->peer_devices, vnr);
+diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
+index 013d355a2033b..921c303a7b5c4 100644
+--- a/drivers/block/drbd/drbd_nl.c
++++ b/drivers/block/drbd/drbd_nl.c
+@@ -1210,6 +1210,7 @@ static void decide_on_discard_support(struct drbd_device *device,
+ 	struct drbd_connection *connection =
+ 		first_peer_device(device)->connection;
+ 	struct request_queue *q = device->rq_queue;
++	unsigned int max_discard_sectors;
+ 
+ 	if (bdev && !bdev_max_discard_sectors(bdev->backing_bdev))
+ 		goto not_supported;
+@@ -1230,15 +1231,14 @@ static void decide_on_discard_support(struct drbd_device *device,
+ 	 * topology on all peers.
+ 	 */
+ 	blk_queue_discard_granularity(q, 512);
+-	q->limits.max_discard_sectors = drbd_max_discard_sectors(connection);
+-	q->limits.max_write_zeroes_sectors =
+-		drbd_max_discard_sectors(connection);
++	max_discard_sectors = drbd_max_discard_sectors(connection);
++	blk_queue_max_discard_sectors(q, max_discard_sectors);
++	blk_queue_max_write_zeroes_sectors(q, max_discard_sectors);
+ 	return;
+ 
+ not_supported:
+ 	blk_queue_discard_granularity(q, 0);
+-	q->limits.max_discard_sectors = 0;
+-	q->limits.max_write_zeroes_sectors = 0;
++	blk_queue_max_discard_sectors(q, 0);
+ }
+ 
+ static void fixup_write_zeroes(struct drbd_device *device, struct request_queue *q)
+diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
+index ccad3d7b3ddd9..487840e3564df 100644
+--- a/drivers/block/floppy.c
++++ b/drivers/block/floppy.c
+@@ -4593,8 +4593,10 @@ static int __init do_floppy_init(void)
+ 			goto out_put_disk;
+ 
+ 		err = floppy_alloc_disk(drive, 0);
+-		if (err)
++		if (err) {
++			blk_mq_free_tag_set(&tag_sets[drive]);
+ 			goto out_put_disk;
++		}
+ 
+ 		timer_setup(&motor_off_timer[drive], motor_off_callback, 0);
+ 	}
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index ad92192c7d617..d12d3d171ec4c 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1773,7 +1773,16 @@ static const struct block_device_operations lo_fops = {
+ /*
+  * And now the modules code and kernel interface.
+  */
+-static int max_loop;
++
++/*
++ * If max_loop is specified, create that many devices upfront.
++ * This also becomes a hard limit. If max_loop is not specified,
++ * create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module
++ * init time. Loop devices can be requested on-demand with the
++ * /dev/loop-control interface, or be instantiated by accessing
++ * a 'dead' device node.
++ */
++static int max_loop = CONFIG_BLK_DEV_LOOP_MIN_COUNT;
+ module_param(max_loop, int, 0444);
+ MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
+ module_param(max_part, int, 0444);
+@@ -2181,7 +2190,7 @@ MODULE_ALIAS("devname:loop-control");
+ 
+ static int __init loop_init(void)
+ {
+-	int i, nr;
++	int i;
+ 	int err;
+ 
+ 	part_shift = 0;
+@@ -2209,19 +2218,6 @@ static int __init loop_init(void)
+ 		goto err_out;
+ 	}
+ 
+-	/*
+-	 * If max_loop is specified, create that many devices upfront.
+-	 * This also becomes a hard limit. If max_loop is not specified,
+-	 * create CONFIG_BLK_DEV_LOOP_MIN_COUNT loop devices at module
+-	 * init time. Loop devices can be requested on-demand with the
+-	 * /dev/loop-control interface, or be instantiated by accessing
+-	 * a 'dead' device node.
+-	 */
+-	if (max_loop)
+-		nr = max_loop;
+-	else
+-		nr = CONFIG_BLK_DEV_LOOP_MIN_COUNT;
+-
+ 	err = misc_register(&loop_misc);
+ 	if (err < 0)
+ 		goto err_out;
+@@ -2233,7 +2229,7 @@ static int __init loop_init(void)
+ 	}
+ 
+ 	/* pre-create number of devices given by config or max_loop */
+-	for (i = 0; i < nr; i++)
++	for (i = 0; i < max_loop; i++)
+ 		loop_add(i);
+ 
+ 	printk(KERN_INFO "loop: module loaded\n");
+diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
+index d44a966675179..0c2542cee294b 100644
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -2522,7 +2522,7 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ 		 */
+ 		err = btintel_read_version(hdev, &ver);
+ 		if (err)
+-			return err;
++			break;
+ 
+ 		/* Apply the device specific HCI quirks
+ 		 *
+@@ -2563,7 +2563,8 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ 	default:
+ 		bt_dev_err(hdev, "Unsupported Intel hw variant (%u)",
+ 			   INTEL_HW_VARIANT(ver_tlv.cnvi_bt));
+-		return -EINVAL;
++		err = -EINVAL;
++		break;
+ 	}
+ 
+ exit_error:
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 882b5893f9108..a132e7aba6054 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -788,13 +788,13 @@ static inline void btusb_free_frags(struct btusb_data *data)
+ 
+ 	spin_lock_irqsave(&data->rxlock, flags);
+ 
+-	kfree_skb(data->evt_skb);
++	dev_kfree_skb_irq(data->evt_skb);
+ 	data->evt_skb = NULL;
+ 
+-	kfree_skb(data->acl_skb);
++	dev_kfree_skb_irq(data->acl_skb);
+ 	data->acl_skb = NULL;
+ 
+-	kfree_skb(data->sco_skb);
++	dev_kfree_skb_irq(data->sco_skb);
+ 	data->sco_skb = NULL;
+ 
+ 	spin_unlock_irqrestore(&data->rxlock, flags);
+diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
+index d7e0b75db8a60..2b6c0e1922cb3 100644
+--- a/drivers/bluetooth/hci_bcm.c
++++ b/drivers/bluetooth/hci_bcm.c
+@@ -53,11 +53,13 @@
+  * struct bcm_device_data - device specific data
+  * @no_early_set_baudrate: Disallow set baudrate before driver setup()
+  * @drive_rts_on_open: drive RTS signal on ->open() when platform requires it
++ * @no_uart_clock_set: UART clock set command for >3Mbps mode is unavailable
+  * @max_autobaud_speed: max baudrate supported by device in autobaud mode
+  */
+ struct bcm_device_data {
+ 	bool	no_early_set_baudrate;
+ 	bool	drive_rts_on_open;
++	bool	no_uart_clock_set;
+ 	u32	max_autobaud_speed;
+ };
+ 
+@@ -100,6 +102,7 @@ struct bcm_device_data {
+  * @is_suspended: whether flow control is currently disabled
+  * @no_early_set_baudrate: don't set_baudrate before setup()
+  * @drive_rts_on_open: drive RTS signal on ->open() when platform requires it
++ * @no_uart_clock_set: UART clock set command for >3Mbps mode is unavailable
+  * @pcm_int_params: keep the initial PCM configuration
+  * @use_autobaud_mode: start Bluetooth device in autobaud mode
+  * @max_autobaud_speed: max baudrate supported by device in autobaud mode
+@@ -140,6 +143,7 @@ struct bcm_device {
+ #endif
+ 	bool			no_early_set_baudrate;
+ 	bool			drive_rts_on_open;
++	bool			no_uart_clock_set;
+ 	bool			use_autobaud_mode;
+ 	u8			pcm_int_params[5];
+ 	u32			max_autobaud_speed;
+@@ -172,10 +176,11 @@ static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed)
+ static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
+ {
+ 	struct hci_dev *hdev = hu->hdev;
++	struct bcm_data *bcm = hu->priv;
+ 	struct sk_buff *skb;
+ 	struct bcm_update_uart_baud_rate param;
+ 
+-	if (speed > 3000000) {
++	if (speed > 3000000 && !bcm->dev->no_uart_clock_set) {
+ 		struct bcm_write_uart_clock_setting clock;
+ 
+ 		clock.type = BCM_UART_CLOCK_48MHZ;
+@@ -1529,6 +1534,7 @@ static int bcm_serdev_probe(struct serdev_device *serdev)
+ 		bcmdev->max_autobaud_speed = data->max_autobaud_speed;
+ 		bcmdev->no_early_set_baudrate = data->no_early_set_baudrate;
+ 		bcmdev->drive_rts_on_open = data->drive_rts_on_open;
++		bcmdev->no_uart_clock_set = data->no_uart_clock_set;
+ 	}
+ 
+ 	return hci_uart_register_device(&bcmdev->serdev_hu, &bcm_proto);
+@@ -1550,6 +1556,10 @@ static struct bcm_device_data bcm43438_device_data = {
+ 	.drive_rts_on_open = true,
+ };
+ 
++static struct bcm_device_data cyw4373a0_device_data = {
++	.no_uart_clock_set = true,
++};
++
+ static struct bcm_device_data cyw55572_device_data = {
+ 	.max_autobaud_speed = 921600,
+ };
+@@ -1566,6 +1576,7 @@ static const struct of_device_id bcm_bluetooth_of_match[] = {
+ 	{ .compatible = "brcm,bcm4349-bt", .data = &bcm43438_device_data },
+ 	{ .compatible = "brcm,bcm43540-bt", .data = &bcm4354_device_data },
+ 	{ .compatible = "brcm,bcm4335a0" },
++	{ .compatible = "cypress,cyw4373a0-bt", .data = &cyw4373a0_device_data },
+ 	{ .compatible = "infineon,cyw55572-bt", .data = &cyw55572_device_data },
+ 	{ },
+ };
+diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
+index cf4a560958173..8055f63603f45 100644
+--- a/drivers/bluetooth/hci_bcsp.c
++++ b/drivers/bluetooth/hci_bcsp.c
+@@ -378,7 +378,7 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
+ 		i++;
+ 
+ 		__skb_unlink(skb, &bcsp->unack);
+-		kfree_skb(skb);
++		dev_kfree_skb_irq(skb);
+ 	}
+ 
+ 	if (skb_queue_empty(&bcsp->unack))
+diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
+index c5a0409ef84fd..6455bc4fb5bb3 100644
+--- a/drivers/bluetooth/hci_h5.c
++++ b/drivers/bluetooth/hci_h5.c
+@@ -313,7 +313,7 @@ static void h5_pkt_cull(struct h5 *h5)
+ 			break;
+ 
+ 		__skb_unlink(skb, &h5->unack);
+-		kfree_skb(skb);
++		dev_kfree_skb_irq(skb);
+ 	}
+ 
+ 	if (skb_queue_empty(&h5->unack))
+diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
+index 4eb420a9ed04e..5abc01a2acf72 100644
+--- a/drivers/bluetooth/hci_ll.c
++++ b/drivers/bluetooth/hci_ll.c
+@@ -345,7 +345,7 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
+ 	default:
+ 		BT_ERR("illegal hcill state: %ld (losing packet)",
+ 		       ll->hcill_state);
+-		kfree_skb(skb);
++		dev_kfree_skb_irq(skb);
+ 		break;
+ 	}
+ 
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
+index 8df11016fd51b..bae9b2a408d95 100644
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -912,7 +912,7 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
+ 	default:
+ 		BT_ERR("Illegal tx state: %d (losing packet)",
+ 		       qca->tx_ibs_state);
+-		kfree_skb(skb);
++		dev_kfree_skb_irq(skb);
+ 		break;
+ 	}
+ 
+diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c
+index c22d4184bb612..0555e3838bce1 100644
+--- a/drivers/char/hw_random/amd-rng.c
++++ b/drivers/char/hw_random/amd-rng.c
+@@ -143,15 +143,19 @@ static int __init amd_rng_mod_init(void)
+ found:
+ 	err = pci_read_config_dword(pdev, 0x58, &pmbase);
+ 	if (err)
+-		return err;
++		goto put_dev;
+ 
+ 	pmbase &= 0x0000FF00;
+-	if (pmbase == 0)
+-		return -EIO;
++	if (pmbase == 0) {
++		err = -EIO;
++		goto put_dev;
++	}
+ 
+ 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+-	if (!priv)
+-		return -ENOMEM;
++	if (!priv) {
++		err = -ENOMEM;
++		goto put_dev;
++	}
+ 
+ 	if (!request_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) {
+ 		dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n",
+@@ -185,6 +189,8 @@ err_iomap:
+ 	release_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE);
+ out:
+ 	kfree(priv);
++put_dev:
++	pci_dev_put(pdev);
+ 	return err;
+ }
+ 
+@@ -200,6 +206,8 @@ static void __exit amd_rng_mod_exit(void)
+ 
+ 	release_region(priv->pmbase + PMBASE_OFFSET, PMBASE_SIZE);
+ 
++	pci_dev_put(priv->pcidev);
++
+ 	kfree(priv);
+ }
+ 
+diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c
+index 138ce434f86b2..12fbe80918319 100644
+--- a/drivers/char/hw_random/geode-rng.c
++++ b/drivers/char/hw_random/geode-rng.c
+@@ -51,6 +51,10 @@ static const struct pci_device_id pci_tbl[] = {
+ };
+ MODULE_DEVICE_TABLE(pci, pci_tbl);
+ 
++struct amd_geode_priv {
++	struct pci_dev *pcidev;
++	void __iomem *membase;
++};
+ 
+ static int geode_rng_data_read(struct hwrng *rng, u32 *data)
+ {
+@@ -90,6 +94,7 @@ static int __init geode_rng_init(void)
+ 	const struct pci_device_id *ent;
+ 	void __iomem *mem;
+ 	unsigned long rng_base;
++	struct amd_geode_priv *priv;
+ 
+ 	for_each_pci_dev(pdev) {
+ 		ent = pci_match_id(pci_tbl, pdev);
+@@ -97,17 +102,26 @@ static int __init geode_rng_init(void)
+ 			goto found;
+ 	}
+ 	/* Device not found. */
+-	goto out;
++	return err;
+ 
+ found:
++	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
++	if (!priv) {
++		err = -ENOMEM;
++		goto put_dev;
++	}
++
+ 	rng_base = pci_resource_start(pdev, 0);
+ 	if (rng_base == 0)
+-		goto out;
++		goto free_priv;
+ 	err = -ENOMEM;
+ 	mem = ioremap(rng_base, 0x58);
+ 	if (!mem)
+-		goto out;
+-	geode_rng.priv = (unsigned long)mem;
++		goto free_priv;
++
++	geode_rng.priv = (unsigned long)priv;
++	priv->membase = mem;
++	priv->pcidev = pdev;
+ 
+ 	pr_info("AMD Geode RNG detected\n");
+ 	err = hwrng_register(&geode_rng);
+@@ -116,20 +130,26 @@ found:
+ 		       err);
+ 		goto err_unmap;
+ 	}
+-out:
+ 	return err;
+ 
+ err_unmap:
+ 	iounmap(mem);
+-	goto out;
++free_priv:
++	kfree(priv);
++put_dev:
++	pci_dev_put(pdev);
++	return err;
+ }
+ 
+ static void __exit geode_rng_exit(void)
+ {
+-	void __iomem *mem = (void __iomem *)geode_rng.priv;
++	struct amd_geode_priv *priv;
+ 
++	priv = (struct amd_geode_priv *)geode_rng.priv;
+ 	hwrng_unregister(&geode_rng);
+-	iounmap(mem);
++	iounmap(priv->membase);
++	pci_dev_put(priv->pcidev);
++	kfree(priv);
+ }
+ 
+ module_init(geode_rng_init);
+diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
+index 703433493c852..c9e32d100b7eb 100644
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -3710,12 +3710,16 @@ static void deliver_smi_err_response(struct ipmi_smi *intf,
+ 				     struct ipmi_smi_msg *msg,
+ 				     unsigned char err)
+ {
++	int rv;
+ 	msg->rsp[0] = msg->data[0] | 4;
+ 	msg->rsp[1] = msg->data[1];
+ 	msg->rsp[2] = err;
+ 	msg->rsp_size = 3;
+-	/* It's an error, so it will never requeue, no need to check return. */
+-	handle_one_recv_msg(intf, msg);
++
++	/* This will never requeue, but it may ask us to free the message. */
++	rv = handle_one_recv_msg(intf, msg);
++	if (rv == 0)
++		ipmi_free_smi_msg(msg);
+ }
+ 
+ static void cleanup_smi_msgs(struct ipmi_smi *intf)
+diff --git a/drivers/char/ipmi/kcs_bmc_aspeed.c b/drivers/char/ipmi/kcs_bmc_aspeed.c
+index cdc88cde1e9aa..417e5a3ccfaeb 100644
+--- a/drivers/char/ipmi/kcs_bmc_aspeed.c
++++ b/drivers/char/ipmi/kcs_bmc_aspeed.c
+@@ -399,13 +399,31 @@ static void aspeed_kcs_check_obe(struct timer_list *timer)
+ static void aspeed_kcs_irq_mask_update(struct kcs_bmc_device *kcs_bmc, u8 mask, u8 state)
+ {
+ 	struct aspeed_kcs_bmc *priv = to_aspeed_kcs_bmc(kcs_bmc);
++	int rc;
++	u8 str;
+ 
+ 	/* We don't have an OBE IRQ, emulate it */
+ 	if (mask & KCS_BMC_EVENT_TYPE_OBE) {
+-		if (KCS_BMC_EVENT_TYPE_OBE & state)
+-			mod_timer(&priv->obe.timer, jiffies + OBE_POLL_PERIOD);
+-		else
++		if (KCS_BMC_EVENT_TYPE_OBE & state) {
++			/*
++			 * Given we don't have an OBE IRQ, delay by polling briefly to see if we can
++			 * observe such an event before returning to the caller. This is not
++			 * incorrect because OBF may have already become clear before enabling the
++			 * IRQ if we had one, under which circumstance no event will be propagated
++			 * anyway.
++			 *
++			 * The onus is on the client to perform a race-free check that it hasn't
++			 * missed the event.
++			 */
++			rc = read_poll_timeout_atomic(aspeed_kcs_inb, str,
++						      !(str & KCS_BMC_STR_OBF), 1, 100, false,
++						      &priv->kcs_bmc, priv->kcs_bmc.ioreg.str);
++			/* Time for the slow path? */
++			if (rc == -ETIMEDOUT)
++				mod_timer(&priv->obe.timer, jiffies + OBE_POLL_PERIOD);
++		} else {
+ 			del_timer(&priv->obe.timer);
++		}
+ 	}
+ 
+ 	if (mask & KCS_BMC_EVENT_TYPE_IBF) {
+diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
+index 18606651d1aa4..65f8f179a27f0 100644
+--- a/drivers/char/tpm/tpm_crb.c
++++ b/drivers/char/tpm/tpm_crb.c
+@@ -252,7 +252,7 @@ static int __crb_relinquish_locality(struct device *dev,
+ 	iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl);
+ 	if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, mask, value,
+ 				 TPM2_TIMEOUT_C)) {
+-		dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n");
++		dev_warn(dev, "TPM_LOC_STATE_x.Relinquish timed out\n");
+ 		return -ETIME;
+ 	}
+ 
+diff --git a/drivers/char/tpm/tpm_ftpm_tee.c b/drivers/char/tpm/tpm_ftpm_tee.c
+index 5c233423c56fa..deff23bb54bf1 100644
+--- a/drivers/char/tpm/tpm_ftpm_tee.c
++++ b/drivers/char/tpm/tpm_ftpm_tee.c
+@@ -397,7 +397,13 @@ static int __init ftpm_mod_init(void)
+ 	if (rc)
+ 		return rc;
+ 
+-	return driver_register(&ftpm_tee_driver.driver);
++	rc = driver_register(&ftpm_tee_driver.driver);
++	if (rc) {
++		platform_driver_unregister(&ftpm_tee_plat_driver);
++		return rc;
++	}
++
++	return 0;
+ }
+ 
+ static void __exit ftpm_mod_exit(void)
+diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
+index 757623bacfd50..3f98e587b3e84 100644
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -682,15 +682,19 @@ static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status)
+ {
+ 	struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+ 
+-	switch (priv->manufacturer_id) {
+-	case TPM_VID_WINBOND:
+-		return ((status == TPM_STS_VALID) ||
+-			(status == (TPM_STS_VALID | TPM_STS_COMMAND_READY)));
+-	case TPM_VID_STM:
+-		return (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY));
+-	default:
+-		return (status == TPM_STS_COMMAND_READY);
++	if (!test_bit(TPM_TIS_DEFAULT_CANCELLATION, &priv->flags)) {
++		switch (priv->manufacturer_id) {
++		case TPM_VID_WINBOND:
++			return ((status == TPM_STS_VALID) ||
++				(status == (TPM_STS_VALID | TPM_STS_COMMAND_READY)));
++		case TPM_VID_STM:
++			return (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY));
++		default:
++			break;
++		}
+ 	}
++
++	return status == TPM_STS_COMMAND_READY;
+ }
+ 
+ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
+diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
+index 66a5a13cd1df2..b68479e0de10f 100644
+--- a/drivers/char/tpm/tpm_tis_core.h
++++ b/drivers/char/tpm/tpm_tis_core.h
+@@ -86,6 +86,7 @@ enum tis_defaults {
+ enum tpm_tis_flags {
+ 	TPM_TIS_ITPM_WORKAROUND		= BIT(0),
+ 	TPM_TIS_INVALID_STATUS		= BIT(1),
++	TPM_TIS_DEFAULT_CANCELLATION	= BIT(2),
+ };
+ 
+ struct tpm_tis_data {
+diff --git a/drivers/char/tpm/tpm_tis_i2c.c b/drivers/char/tpm/tpm_tis_i2c.c
+index ba0911b1d1ff3..e728a61659f86 100644
+--- a/drivers/char/tpm/tpm_tis_i2c.c
++++ b/drivers/char/tpm/tpm_tis_i2c.c
+@@ -49,7 +49,7 @@
+ 
+ /* Masks with bits that must be read zero */
+ #define TPM_ACCESS_READ_ZERO 0x48
+-#define TPM_INT_ENABLE_ZERO 0x7FFFFF6
++#define TPM_INT_ENABLE_ZERO 0x7FFFFF60
+ #define TPM_STS_READ_ZERO 0x23
+ #define TPM_INTF_CAPABILITY_ZERO 0x0FFFF000
+ #define TPM_I2C_INTERFACE_CAPABILITY_ZERO 0x80000000
+@@ -329,6 +329,7 @@ static int tpm_tis_i2c_probe(struct i2c_client *dev,
+ 	if (!phy->io_buf)
+ 		return -ENOMEM;
+ 
++	set_bit(TPM_TIS_DEFAULT_CANCELLATION, &phy->priv.flags);
+ 	phy->i2c_client = dev;
+ 
+ 	/* must precede all communication with the tpm */
+diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
+index d37c45b676abe..2afea905f7f3c 100644
+--- a/drivers/clk/imx/clk-imx8mn.c
++++ b/drivers/clk/imx/clk-imx8mn.c
+@@ -27,10 +27,10 @@ static u32 share_count_nand;
+ static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+ static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+ static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+-static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
++static const char * const video_pll_bypass_sels[] = {"video_pll", "video_pll_ref_sel", };
+ static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
+ static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
+-static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
++static const char * const m7_alt_pll_bypass_sels[] = {"m7_alt_pll", "m7_alt_pll_ref_sel", };
+ static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+ static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+ 
+@@ -40,24 +40,24 @@ static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pl
+ 
+ static const char * const imx8mn_a53_core_sels[] = {"arm_a53_div", "arm_pll_out", };
+ 
+-static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "vpu_pll_out",
+-				       "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", };
++static const char * const imx8mn_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "m7_alt_pll_out",
++				       "sys_pll1_800m", "audio_pll1_out", "video_pll_out", "sys_pll3_out", };
+ 
+ static const char * const imx8mn_gpu_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+ 						    "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+-						    "video_pll1_out", "audio_pll2_out", };
++						    "video_pll_out", "audio_pll2_out", };
+ 
+ static const char * const imx8mn_gpu_shader_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+ 						      "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+-						      "video_pll1_out", "audio_pll2_out", };
++						      "video_pll_out", "audio_pll2_out", };
+ 
+ static const char * const imx8mn_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m",
+ 						    "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out",
+-						    "video_pll1_out", "sys_pll1_100m",};
++						    "video_pll_out", "sys_pll1_100m",};
+ 
+ static const char * const imx8mn_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
+ 						    "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
+-						    "video_pll1_out", "sys_pll3_out", };
++						    "video_pll_out", "sys_pll3_out", };
+ 
+ static const char * const imx8mn_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
+ 						      "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
+@@ -77,23 +77,23 @@ static const char * const imx8mn_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "
+ 
+ static const char * const imx8mn_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
+ 						   "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+-						   "video_pll1_out", "audio_pll2_out", };
++						   "video_pll_out", "audio_pll2_out", };
+ 
+ static const char * const imx8mn_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
+ 						   "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+-						   "video_pll1_out", "audio_pll2_out", };
++						   "video_pll_out", "audio_pll2_out", };
+ 
+ static const char * const imx8mn_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
+ 					       "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
+-					       "video_pll1_out", "audio_pll2_out", };
++					       "video_pll_out", "audio_pll2_out", };
+ 
+ static const char * const imx8mn_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m",
+ 					       "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out",
+-					       "audio_pll1_out", "video_pll1_out", };
++					       "audio_pll1_out", "video_pll_out", };
+ 
+ static const char * const imx8mn_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
+ 						     "sys_pll2_1000m", "sys_pll2_166m", "sys_pll3_out",
+-						     "audio_pll1_out", "video_pll1_out", };
++						     "audio_pll1_out", "video_pll_out", };
+ 
+ static const char * const imx8mn_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m",
+ 						    "sys_pll2_500m", "sys_pll2_1000m", "sys_pll3_out",
+@@ -103,49 +103,49 @@ static const char * const imx8mn_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m",
+ 						    "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+ 						    "sys_pll2_250m", "audio_pll2_out", };
+ 
+-static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
++static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll_out", "audio_pll2_out",
+ 						      "audio_pll1_out", "sys_pll1_800m", "sys_pll2_1000m",
+ 						      "sys_pll3_out", "clk_ext4", };
+ 
+ static const char * const imx8mn_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+-						"clk_ext3", "clk_ext4", };
++						"video_pll_out", "sys_pll1_133m", "dummy",
++						"clk_ext2", "clk_ext3", };
+ 
+ static const char * const imx8mn_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++						"video_pll_out", "sys_pll1_133m", "dummy",
+ 						"clk_ext3", "clk_ext4", };
+ 
+ static const char * const imx8mn_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++						"video_pll_out", "sys_pll1_133m", "dummy",
+ 						"clk_ext2", "clk_ext3", };
+ 
+ static const char * const imx8mn_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++						"video_pll_out", "sys_pll1_133m", "dummy",
+ 						"clk_ext3", "clk_ext4", };
+ 
+ static const char * const imx8mn_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+-						"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++						"video_pll_out", "sys_pll1_133m", "dummy",
+ 						"clk_ext3", "clk_ext4", };
+ 
+ static const char * const imx8mn_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+-						  "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
++						  "video_pll_out", "sys_pll1_133m", "dummy",
+ 						  "clk_ext2", "clk_ext3", };
+ 
+ static const char * const imx8mn_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
+ 						    "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
+-						    "video_pll1_out", "clk_ext4", };
++						    "video_pll_out", "clk_ext4", };
+ 
+ static const char * const imx8mn_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
+ 						      "clk_ext1", "clk_ext2", "clk_ext3",
+-						      "clk_ext4", "video_pll1_out", };
++						      "clk_ext4", "video_pll_out", };
+ 
+ static const char * const imx8mn_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m",
+-						    "sys_pll2_200m", "sys_pll2_500m", "video_pll1_out",
+-						    "audio_pll2_out", };
++						    "sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out",
++						    "video_pll_out", "audio_pll2_out", };
+ 
+ static const char * const imx8mn_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out",
+ 						"sys_pll1_400m", "audio_pll2_out", "sys_pll3_out",
+-						"sys_pll2_250m", "video_pll1_out", };
++						"sys_pll2_250m", "video_pll_out", };
+ 
+ static const char * const imx8mn_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m",
+ 						"sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m",
+@@ -160,19 +160,19 @@ static const char * const imx8mn_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "s
+ 						  "audio_pll2_out", "sys_pll1_100m", };
+ 
+ static const char * const imx8mn_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
++						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
+ 						"audio_pll2_out", "sys_pll1_133m", };
+ 
+ static const char * const imx8mn_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
++						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
+ 						"audio_pll2_out", "sys_pll1_133m", };
+ 
+ static const char * const imx8mn_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+-						"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
++						"sys_pll3_out", "audio_pll1_out", "video_pll_out",
+ 						"audio_pll2_out", "sys_pll1_133m", };
+ 
+ static const char * const imx8mn_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+-						"sys_pll3_out",	"audio_pll1_out", "video_pll1_out",
++						"sys_pll3_out",	"audio_pll1_out", "video_pll_out",
+ 						"audio_pll2_out", "sys_pll1_133m", };
+ 
+ static const char * const imx8mn_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+@@ -213,63 +213,63 @@ static const char * const imx8mn_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "s
+ 
+ static const char * const imx8mn_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+ 						"sys_pll1_40m", "sys_pll3_out", "clk_ext1",
+-						"sys_pll1_80m", "video_pll1_out", };
++						"sys_pll1_80m", "video_pll_out", };
+ 
+ static const char * const imx8mn_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+ 						"sys_pll1_40m", "sys_pll3_out", "clk_ext1",
+-						"sys_pll1_80m", "video_pll1_out", };
++						"sys_pll1_80m", "video_pll_out", };
+ 
+ static const char * const imx8mn_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+ 						"sys_pll1_40m", "sys_pll3_out", "clk_ext2",
+-						"sys_pll1_80m", "video_pll1_out", };
++						"sys_pll1_80m", "video_pll_out", };
+ 
+ static const char * const imx8mn_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+ 						"sys_pll1_40m", "sys_pll3_out", "clk_ext2",
+-						"sys_pll1_80m", "video_pll1_out", };
++						"sys_pll1_80m", "video_pll_out", };
+ 
+ static const char * const imx8mn_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
++						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
+ 						"audio_pll1_out", "clk_ext1", };
+ 
+ static const char * const imx8mn_gpt2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
++						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
+ 						"audio_pll1_out", "clk_ext1", };
+ 
+ static const char * const imx8mn_gpt3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
++						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
+ 						"audio_pll1_out", "clk_ext1", };
+ 
+ static const char * const imx8mn_gpt4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
++						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
+ 						"audio_pll1_out", "clk_ext1", };
+ 
+ static const char * const imx8mn_gpt5_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
++						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
+ 						"audio_pll1_out", "clk_ext1", };
+ 
+ static const char * const imx8mn_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+-						"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
++						"sys_pll1_40m", "video_pll_out", "sys_pll1_80m",
+ 						"audio_pll1_out", "clk_ext1", };
+ 
+ static const char * const imx8mn_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m",
+-						"vpu_pll_out", "sys_pll2_125m", "sys_pll3_out",
++						"m7_alt_pll_out", "sys_pll2_125m", "sys_pll3_out",
+ 						"sys_pll1_80m", "sys_pll2_166m", };
+ 
+-static const char * const imx8mn_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out",
++static const char * const imx8mn_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "m7_alt_pll_out",
+ 						 "sys_pll3_out", "sys_pll2_200m", "sys_pll1_266m",
+ 						 "sys_pll2_500m", "sys_pll1_100m", };
+ 
+ static const char * const imx8mn_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
+ 						    "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+-						    "audio_pll2_out", "video_pll1_out", };
++						    "audio_pll2_out", "video_pll_out", };
+ 
+ static const char * const imx8mn_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m",
+ 						   "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+-						   "audio_pll2_out", "video_pll1_out", };
++						   "audio_pll2_out", "video_pll_out", };
+ 
+ static const char * const imx8mn_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m",
+ 						   "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+-						   "audio_pll2_out", "video_pll1_out", };
++						   "audio_pll2_out", "video_pll_out", };
+ 
+ static const char * const imx8mn_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
+ 						  "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+@@ -277,15 +277,15 @@ static const char * const imx8mn_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "s
+ 
+ static const char * const imx8mn_camera_pixel_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
+ 							"sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+-							"audio_pll2_out", "video_pll1_out", };
++							"audio_pll2_out", "video_pll_out", };
+ 
+ static const char * const imx8mn_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
+ 						    "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+-						    "audio_pll2_out", "video_pll1_out", };
++						    "audio_pll2_out", "video_pll_out", };
+ 
+ static const char * const imx8mn_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
+ 						    "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+-						    "audio_pll2_out", "video_pll1_out", };
++						    "audio_pll2_out", "video_pll_out", };
+ 
+ static const char * const imx8mn_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
+ 						    "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+@@ -306,9 +306,9 @@ static const char * const imx8mn_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "du
+ 						 "dummy", "sys_pll1_80m", };
+ static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m",
+ 						 "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out",
+-						 "video_pll1_out", "osc_32k", };
++						 "video_pll_out", "osc_32k", };
+ 
+-static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
++static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll_out",
+ 					   "dummy", "dummy", "gpu_pll_out", "dummy",
+ 					   "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
+ 					   "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
+@@ -349,19 +349,19 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
+ 
+ 	hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ 	hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+-	hws[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
++	hws[IMX8MN_VIDEO_PLL_REF_SEL] = imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ 	hws[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ 	hws[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+-	hws[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
++	hws[IMX8MN_M7_ALT_PLL_REF_SEL] = imx_clk_hw_mux("m7_alt_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ 	hws[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ 	hws[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+ 
+ 	hws[IMX8MN_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
+ 	hws[IMX8MN_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
+-	hws[IMX8MN_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
++	hws[IMX8MN_VIDEO_PLL] = imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", base + 0x28, &imx_1443x_pll);
+ 	hws[IMX8MN_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll);
+ 	hws[IMX8MN_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
+-	hws[IMX8MN_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
++	hws[IMX8MN_M7_ALT_PLL] = imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_ref_sel", base + 0x74, &imx_1416x_pll);
+ 	hws[IMX8MN_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
+ 	hws[IMX8MN_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000);
+ 	hws[IMX8MN_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000);
+@@ -370,20 +370,20 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
+ 	/* PLL bypass out */
+ 	hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+ 	hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+-	hws[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
++	hws[IMX8MN_VIDEO_PLL_BYPASS] = imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ 	hws[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ 	hws[IMX8MN_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+-	hws[IMX8MN_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
++	hws[IMX8MN_M7_ALT_PLL_BYPASS] = imx_clk_hw_mux_flags("m7_alt_pll_bypass", base + 0x74, 28, 1, m7_alt_pll_bypass_sels, ARRAY_SIZE(m7_alt_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ 	hws[IMX8MN_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+ 	hws[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+ 
+ 	/* PLL out gate */
+ 	hws[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
+ 	hws[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
+-	hws[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
++	hws[IMX8MN_VIDEO_PLL_OUT] = imx_clk_hw_gate("video_pll_out", "video_pll_bypass", base + 0x28, 13);
+ 	hws[IMX8MN_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
+ 	hws[IMX8MN_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
+-	hws[IMX8MN_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
++	hws[IMX8MN_M7_ALT_PLL_OUT] = imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_pll_bypass", base + 0x74, 11);
+ 	hws[IMX8MN_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
+ 	hws[IMX8MN_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
+ 
+diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
+index 652ae58c2735f..5d68d975b4eb1 100644
+--- a/drivers/clk/imx/clk-imx8mp.c
++++ b/drivers/clk/imx/clk-imx8mp.c
+@@ -17,6 +17,7 @@
+ 
+ static u32 share_count_nand;
+ static u32 share_count_media;
++static u32 share_count_usb;
+ 
+ static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+ static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+@@ -673,7 +674,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
+ 	hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0);
+ 	hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0);
+ 	hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0);
+-	hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0);
++	hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate2_shared2("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0, &share_count_usb);
++	hws[IMX8MP_CLK_USB_SUSP] = imx_clk_hw_gate2_shared2("usb_suspend_clk", "osc_32k", ccm_base + 0x44d0, 0, &share_count_usb);
+ 	hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0);
+ 	hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0);
+ 	hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0);
+diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c
+index dcc41d178238e..2e99c3443d3c3 100644
+--- a/drivers/clk/imx/clk-imx93.c
++++ b/drivers/clk/imx/clk-imx93.c
+@@ -162,7 +162,7 @@ static const struct imx93_clk_ccgr {
+ 	{ IMX93_CLK_MU_B_GATE,		"mu_b",		"bus_aon_root",		0x8500, },
+ 	{ IMX93_CLK_EDMA1_GATE,		"edma1",	"m33_root",		0x8540, },
+ 	{ IMX93_CLK_EDMA2_GATE,		"edma2",	"wakeup_axi_root",	0x8580, },
+-	{ IMX93_CLK_FLEXSPI1_GATE,	"flexspi",	"flexspi_root",		0x8640, },
++	{ IMX93_CLK_FLEXSPI1_GATE,	"flexspi1",	"flexspi1_root",	0x8640, },
+ 	{ IMX93_CLK_GPIO1_GATE,		"gpio1",	"m33_root",		0x8880, },
+ 	{ IMX93_CLK_GPIO2_GATE,		"gpio2",	"bus_wakeup_root",	0x88c0, },
+ 	{ IMX93_CLK_GPIO3_GATE,		"gpio3",	"bus_wakeup_root",	0x8900, },
+@@ -229,7 +229,7 @@ static const struct imx93_clk_ccgr {
+ 	{ IMX93_CLK_AUD_XCVR_GATE,	"aud_xcvr",	"audio_xcvr_root",	0x9b80, },
+ 	{ IMX93_CLK_SPDIF_GATE,		"spdif",	"spdif_root",		0x9c00, },
+ 	{ IMX93_CLK_HSIO_32K_GATE,	"hsio_32k",	"osc_32k",		0x9dc0, },
+-	{ IMX93_CLK_ENET1_GATE,		"enet1",	"enet_root",		0x9e00, },
++	{ IMX93_CLK_ENET1_GATE,		"enet1",	"wakeup_axi_root",	0x9e00, },
+ 	{ IMX93_CLK_ENET_QOS_GATE,	"enet_qos",	"wakeup_axi_root",	0x9e40, },
+ 	{ IMX93_CLK_SYS_CNT_GATE,	"sys_cnt",	"osc_24m",		0x9e80, },
+ 	{ IMX93_CLK_TSTMR1_GATE,	"tstmr1",	"bus_aon_root",		0x9ec0, },
+@@ -247,7 +247,7 @@ static int imx93_clocks_probe(struct platform_device *pdev)
+ 	struct device_node *np = dev->of_node;
+ 	const struct imx93_clk_root *root;
+ 	const struct imx93_clk_ccgr *ccgr;
+-	void __iomem *base = NULL;
++	void __iomem *base, *anatop_base;
+ 	int i, ret;
+ 
+ 	clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
+@@ -274,20 +274,22 @@ static int imx93_clocks_probe(struct platform_device *pdev)
+ 								    "sys_pll_pfd2", 1, 2);
+ 
+ 	np = of_find_compatible_node(NULL, NULL, "fsl,imx93-anatop");
+-	base = of_iomap(np, 0);
++	anatop_base = of_iomap(np, 0);
+ 	of_node_put(np);
+-	if (WARN_ON(!base))
++	if (WARN_ON(!anatop_base))
+ 		return -ENOMEM;
+ 
+-	clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", base + 0x1200,
++	clks[IMX93_CLK_AUDIO_PLL] = imx_clk_fracn_gppll("audio_pll", "osc_24m", anatop_base + 0x1200,
+ 							&imx_fracn_gppll);
+-	clks[IMX93_CLK_VIDEO_PLL] = imx_clk_fracn_gppll("video_pll", "osc_24m", base + 0x1400,
++	clks[IMX93_CLK_VIDEO_PLL] = imx_clk_fracn_gppll("video_pll", "osc_24m", anatop_base + 0x1400,
+ 							&imx_fracn_gppll);
+ 
+ 	np = dev->of_node;
+ 	base = devm_platform_ioremap_resource(pdev, 0);
+-	if (WARN_ON(IS_ERR(base)))
++	if (WARN_ON(IS_ERR(base))) {
++		iounmap(anatop_base);
+ 		return PTR_ERR(base);
++	}
+ 
+ 	for (i = 0; i < ARRAY_SIZE(root_array); i++) {
+ 		root = &root_array[i];
+@@ -317,6 +319,7 @@ static int imx93_clocks_probe(struct platform_device *pdev)
+ 
+ unregister_hws:
+ 	imx_unregister_hw_clocks(clks, IMX93_CLK_END);
++	iounmap(anatop_base);
+ 
+ 	return ret;
+ }
+diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c
+index 9539d35588ee9..26108e9f7e67a 100644
+--- a/drivers/clk/imx/clk-imxrt1050.c
++++ b/drivers/clk/imx/clk-imxrt1050.c
+@@ -140,7 +140,7 @@ static int imxrt1050_clocks_probe(struct platform_device *pdev)
+ 	hws[IMXRT1050_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", ccm_base + 0x80, 2);
+ 	hws[IMXRT1050_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", ccm_base + 0x80, 4);
+ 	hws[IMXRT1050_CLK_LPUART1] = imx_clk_hw_gate2("lpuart1", "lpuart_podf", ccm_base + 0x7c, 24);
+-	hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x74, 10);
++	hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x70, 28);
+ 	hws[IMXRT1050_CLK_DMA] = imx_clk_hw_gate("dma", "ipg", ccm_base + 0x7C, 6);
+ 	hws[IMXRT1050_CLK_DMA_MUX] = imx_clk_hw_gate("dmamux0", "ipg", ccm_base + 0x7C, 7);
+ 	imx_check_clk_hws(hws, IMXRT1050_CLK_END);
+diff --git a/drivers/clk/mediatek/clk-mt7986-infracfg.c b/drivers/clk/mediatek/clk-mt7986-infracfg.c
+index d90727a53283c..49666047bf0ed 100644
+--- a/drivers/clk/mediatek/clk-mt7986-infracfg.c
++++ b/drivers/clk/mediatek/clk-mt7986-infracfg.c
+@@ -153,7 +153,7 @@ static const struct mtk_gate infra_clks[] = {
+ 		    18),
+ 	GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m", "infra_sysaxi_d2",
+ 		    19),
+-	GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "csw_f26m_sel", 20),
++	GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "infra_adc_frc", 20),
+ 	GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc", "csw_f26m_sel", 21),
+ 	GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", "nfi1x_sel", 23),
+ 	/* INFRA2 */
+diff --git a/drivers/clk/qcom/clk-krait.c b/drivers/clk/qcom/clk-krait.c
+index 45da736bd5f4c..293a9dfa7151a 100644
+--- a/drivers/clk/qcom/clk-krait.c
++++ b/drivers/clk/qcom/clk-krait.c
+@@ -114,6 +114,8 @@ static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate,
+ 
+ 	if (d->lpl)
+ 		mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift;
++	else
++		mask <<= d->shift;
+ 
+ 	spin_lock_irqsave(&krait_clock_reg_lock, flags);
+ 	val = krait_get_l2_indirect_reg(d->offset);
+diff --git a/drivers/clk/qcom/dispcc-sm6350.c b/drivers/clk/qcom/dispcc-sm6350.c
+index 0c3c2e26ede90..ea6f54ed846ec 100644
+--- a/drivers/clk/qcom/dispcc-sm6350.c
++++ b/drivers/clk/qcom/dispcc-sm6350.c
+@@ -306,7 +306,7 @@ static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
+ 		.name = "disp_cc_mdss_pclk0_clk_src",
+ 		.parent_data = disp_cc_parent_data_5,
+ 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
+-		.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
++		.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE,
+ 		.ops = &clk_pixel_ops,
+ 	},
+ };
+@@ -385,7 +385,7 @@ static struct clk_branch disp_cc_mdss_byte0_clk = {
+ 				&disp_cc_mdss_byte0_clk_src.clkr.hw,
+ 			},
+ 			.num_parents = 1,
+-			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
++			.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE | CLK_OPS_PARENT_ENABLE,
+ 			.ops = &clk_branch2_ops,
+ 		},
+ 	},
+diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c
+index 718de17a1e600..6447f3e81b555 100644
+--- a/drivers/clk/qcom/gcc-ipq806x.c
++++ b/drivers/clk/qcom/gcc-ipq806x.c
+@@ -79,7 +79,9 @@ static struct clk_regmap pll4_vote = {
+ 	.enable_mask = BIT(4),
+ 	.hw.init = &(struct clk_init_data){
+ 		.name = "pll4_vote",
+-		.parent_names = (const char *[]){ "pll4" },
++		.parent_data = &(const struct clk_parent_data){
++			.fw_name = "pll4", .name = "pll4",
++		},
+ 		.num_parents = 1,
+ 		.ops = &clk_pll_vote_ops,
+ 	},
+diff --git a/drivers/clk/qcom/gcc-sm8250.c b/drivers/clk/qcom/gcc-sm8250.c
+index 9755ef4888c19..a0ba37656b07b 100644
+--- a/drivers/clk/qcom/gcc-sm8250.c
++++ b/drivers/clk/qcom/gcc-sm8250.c
+@@ -3267,7 +3267,7 @@ static struct gdsc usb30_prim_gdsc = {
+ 	.pd = {
+ 		.name = "usb30_prim_gdsc",
+ 	},
+-	.pwrsts = PWRSTS_OFF_ON,
++	.pwrsts = PWRSTS_RET_ON,
+ };
+ 
+ static struct gdsc usb30_sec_gdsc = {
+@@ -3275,7 +3275,7 @@ static struct gdsc usb30_sec_gdsc = {
+ 	.pd = {
+ 		.name = "usb30_sec_gdsc",
+ 	},
+-	.pwrsts = PWRSTS_OFF_ON,
++	.pwrsts = PWRSTS_RET_ON,
+ };
+ 
+ static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
+diff --git a/drivers/clk/qcom/lpassaudiocc-sc7280.c b/drivers/clk/qcom/lpassaudiocc-sc7280.c
+index 6ab6e5a34c724..b2646b7e13c9f 100644
+--- a/drivers/clk/qcom/lpassaudiocc-sc7280.c
++++ b/drivers/clk/qcom/lpassaudiocc-sc7280.c
+@@ -12,6 +12,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/regmap.h>
+ 
++#include <dt-bindings/clock/qcom,lpass-sc7280.h>
+ #include <dt-bindings/clock/qcom,lpassaudiocc-sc7280.h>
+ 
+ #include "clk-alpha-pll.h"
+@@ -22,6 +23,7 @@
+ #include "clk-regmap-mux.h"
+ #include "common.h"
+ #include "gdsc.h"
++#include "reset.h"
+ 
+ enum {
+ 	P_BI_TCXO,
+@@ -38,6 +40,32 @@ static const struct pll_vco zonda_vco[] = {
+ 	{ 595200000UL, 3600000000UL, 0 },
+ };
+ 
++static struct clk_branch lpass_q6ss_ahbm_clk = {
++	.halt_reg = 0x901c,
++	.halt_check = BRANCH_HALT,
++	.clkr = {
++		.enable_reg = 0x901c,
++		.enable_mask = BIT(0),
++		.hw.init = &(struct clk_init_data){
++				.name = "lpass_q6ss_ahbm_clk",
++				.ops = &clk_branch2_ops,
++		},
++	},
++};
++
++static struct clk_branch lpass_q6ss_ahbs_clk = {
++	.halt_reg = 0x9020,
++	.halt_check = BRANCH_HALT_VOTED,
++	.clkr = {
++		.enable_reg = 0x9020,
++		.enable_mask = BIT(0),
++		.hw.init = &(struct clk_init_data){
++			.name = "lpass_q6ss_ahbs_clk",
++			.ops = &clk_branch2_ops,
++		},
++	},
++};
++
+ /* 1128.96MHz configuration */
+ static const struct alpha_pll_config lpass_audio_cc_pll_config = {
+ 	.l = 0x3a,
+@@ -221,7 +249,7 @@ static struct clk_rcg2 lpass_aon_cc_main_rcg_clk_src = {
+ 		.parent_data = lpass_aon_cc_parent_data_0,
+ 		.num_parents = ARRAY_SIZE(lpass_aon_cc_parent_data_0),
+ 		.flags = CLK_OPS_PARENT_ENABLE,
+-		.ops = &clk_rcg2_ops,
++		.ops = &clk_rcg2_shared_ops,
+ 	},
+ };
+ 
+@@ -614,6 +642,11 @@ static struct gdsc lpass_aon_cc_lpass_audio_hm_gdsc = {
+ 	.flags = RETAIN_FF_ENABLE,
+ };
+ 
++static struct clk_regmap *lpass_cc_sc7280_clocks[] = {
++	[LPASS_Q6SS_AHBM_CLK] = &lpass_q6ss_ahbm_clk.clkr,
++	[LPASS_Q6SS_AHBS_CLK] = &lpass_q6ss_ahbs_clk.clkr,
++};
++
+ static struct clk_regmap *lpass_aon_cc_sc7280_clocks[] = {
+ 	[LPASS_AON_CC_AUDIO_HM_H_CLK] = &lpass_aon_cc_audio_hm_h_clk.clkr,
+ 	[LPASS_AON_CC_VA_MEM0_CLK] = &lpass_aon_cc_va_mem0_clk.clkr,
+@@ -659,45 +692,47 @@ static struct regmap_config lpass_audio_cc_sc7280_regmap_config = {
+ 	.fast_io = true,
+ };
+ 
++static const struct qcom_cc_desc lpass_cc_sc7280_desc = {
++	.config = &lpass_audio_cc_sc7280_regmap_config,
++	.clks = lpass_cc_sc7280_clocks,
++	.num_clks = ARRAY_SIZE(lpass_cc_sc7280_clocks),
++};
++
+ static const struct qcom_cc_desc lpass_audio_cc_sc7280_desc = {
+ 	.config = &lpass_audio_cc_sc7280_regmap_config,
+ 	.clks = lpass_audio_cc_sc7280_clocks,
+ 	.num_clks = ARRAY_SIZE(lpass_audio_cc_sc7280_clocks),
+ };
+ 
++static const struct qcom_reset_map lpass_audio_cc_sc7280_resets[] = {
++	[LPASS_AUDIO_SWR_RX_CGCR] =  { 0xa0, 1 },
++	[LPASS_AUDIO_SWR_TX_CGCR] =  { 0xa8, 1 },
++	[LPASS_AUDIO_SWR_WSA_CGCR] = { 0xb0, 1 },
++};
++
++static const struct qcom_cc_desc lpass_audio_cc_reset_sc7280_desc = {
++	.config = &lpass_audio_cc_sc7280_regmap_config,
++	.resets = lpass_audio_cc_sc7280_resets,
++	.num_resets = ARRAY_SIZE(lpass_audio_cc_sc7280_resets),
++};
++
+ static const struct of_device_id lpass_audio_cc_sc7280_match_table[] = {
+ 	{ .compatible = "qcom,sc7280-lpassaudiocc" },
+ 	{ }
+ };
+ MODULE_DEVICE_TABLE(of, lpass_audio_cc_sc7280_match_table);
+ 
+-static void lpassaudio_pm_runtime_disable(void *data)
+-{
+-	pm_runtime_disable(data);
+-}
+-
+-static void lpassaudio_pm_clk_destroy(void *data)
+-{
+-	pm_clk_destroy(data);
+-}
+-
+-static int lpassaudio_create_pm_clks(struct platform_device *pdev)
++static int lpass_audio_setup_runtime_pm(struct platform_device *pdev)
+ {
+ 	int ret;
+ 
+ 	pm_runtime_use_autosuspend(&pdev->dev);
+ 	pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
+-	pm_runtime_enable(&pdev->dev);
+-
+-	ret = devm_add_action_or_reset(&pdev->dev, lpassaudio_pm_runtime_disable, &pdev->dev);
+-	if (ret)
+-		return ret;
+-
+-	ret = pm_clk_create(&pdev->dev);
++	ret = devm_pm_runtime_enable(&pdev->dev);
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = devm_add_action_or_reset(&pdev->dev, lpassaudio_pm_clk_destroy, &pdev->dev);
++	ret = devm_pm_clk_create(&pdev->dev);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -705,7 +740,7 @@ static int lpassaudio_create_pm_clks(struct platform_device *pdev)
+ 	if (ret < 0)
+ 		dev_err(&pdev->dev, "failed to acquire iface clock\n");
+ 
+-	return ret;
++	return pm_runtime_resume_and_get(&pdev->dev);
+ }
+ 
+ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev)
+@@ -714,7 +749,7 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev)
+ 	struct regmap *regmap;
+ 	int ret;
+ 
+-	ret = lpassaudio_create_pm_clks(pdev);
++	ret = lpass_audio_setup_runtime_pm(pdev);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -724,8 +759,8 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev)
+ 
+ 	regmap = qcom_cc_map(pdev, desc);
+ 	if (IS_ERR(regmap)) {
+-		pm_runtime_disable(&pdev->dev);
+-		return PTR_ERR(regmap);
++		ret = PTR_ERR(regmap);
++		goto exit;
+ 	}
+ 
+ 	clk_zonda_pll_configure(&lpass_audio_cc_pll, regmap, &lpass_audio_cc_pll_config);
+@@ -734,16 +769,21 @@ static int lpass_audio_cc_sc7280_probe(struct platform_device *pdev)
+ 	regmap_write(regmap, 0x4, 0x3b);
+ 	regmap_write(regmap, 0x8, 0xff05);
+ 
+-	ret = qcom_cc_really_probe(pdev, &lpass_audio_cc_sc7280_desc, regmap);
++	ret = qcom_cc_probe_by_index(pdev, 0, &lpass_audio_cc_sc7280_desc);
+ 	if (ret) {
+ 		dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC clocks\n");
+-		pm_runtime_disable(&pdev->dev);
+-		return ret;
++		goto exit;
++	}
++
++	ret = qcom_cc_probe_by_index(pdev, 1, &lpass_audio_cc_reset_sc7280_desc);
++	if (ret) {
++		dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC Resets\n");
++		goto exit;
+ 	}
+ 
+ 	pm_runtime_mark_last_busy(&pdev->dev);
++exit:
+ 	pm_runtime_put_autosuspend(&pdev->dev);
+-	pm_runtime_put_sync(&pdev->dev);
+ 
+ 	return ret;
+ }
+@@ -781,27 +821,38 @@ static int lpass_aon_cc_sc7280_probe(struct platform_device *pdev)
+ 	struct regmap *regmap;
+ 	int ret;
+ 
+-	ret = lpassaudio_create_pm_clks(pdev);
++	ret = lpass_audio_setup_runtime_pm(pdev);
+ 	if (ret)
+ 		return ret;
+ 
++	if (of_property_read_bool(pdev->dev.of_node, "qcom,adsp-pil-mode")) {
++		lpass_audio_cc_sc7280_regmap_config.name = "cc";
++		desc = &lpass_cc_sc7280_desc;
++		ret = qcom_cc_probe(pdev, desc);
++		goto exit;
++	}
++
+ 	lpass_audio_cc_sc7280_regmap_config.name = "lpasscc_aon";
+ 	lpass_audio_cc_sc7280_regmap_config.max_register = 0xa0008;
+ 	desc = &lpass_aon_cc_sc7280_desc;
+ 
+ 	regmap = qcom_cc_map(pdev, desc);
+-	if (IS_ERR(regmap))
+-		return PTR_ERR(regmap);
++	if (IS_ERR(regmap)) {
++		ret = PTR_ERR(regmap);
++		goto exit;
++	}
+ 
+ 	clk_lucid_pll_configure(&lpass_aon_cc_pll, regmap, &lpass_aon_cc_pll_config);
+ 
+ 	ret = qcom_cc_really_probe(pdev, &lpass_aon_cc_sc7280_desc, regmap);
+-	if (ret)
++	if (ret) {
+ 		dev_err(&pdev->dev, "Failed to register LPASS AON CC clocks\n");
++		goto exit;
++	}
+ 
+ 	pm_runtime_mark_last_busy(&pdev->dev);
++exit:
+ 	pm_runtime_put_autosuspend(&pdev->dev);
+-	pm_runtime_put_sync(&pdev->dev);
+ 
+ 	return ret;
+ }
+diff --git a/drivers/clk/qcom/lpasscc-sc7280.c b/drivers/clk/qcom/lpasscc-sc7280.c
+index b39ee1c9647bc..5c1e17bd0d763 100644
+--- a/drivers/clk/qcom/lpasscc-sc7280.c
++++ b/drivers/clk/qcom/lpasscc-sc7280.c
+@@ -17,32 +17,6 @@
+ #include "clk-branch.h"
+ #include "common.h"
+ 
+-static struct clk_branch lpass_q6ss_ahbm_clk = {
+-	.halt_reg = 0x1c,
+-	.halt_check = BRANCH_HALT,
+-	.clkr = {
+-		.enable_reg = 0x1c,
+-		.enable_mask = BIT(0),
+-		.hw.init = &(struct clk_init_data){
+-			.name = "lpass_q6ss_ahbm_clk",
+-			.ops = &clk_branch2_ops,
+-		},
+-	},
+-};
+-
+-static struct clk_branch lpass_q6ss_ahbs_clk = {
+-	.halt_reg = 0x20,
+-	.halt_check = BRANCH_HALT_VOTED,
+-	.clkr = {
+-		.enable_reg = 0x20,
+-		.enable_mask = BIT(0),
+-		.hw.init = &(struct clk_init_data){
+-			.name = "lpass_q6ss_ahbs_clk",
+-			.ops = &clk_branch2_ops,
+-		},
+-	},
+-};
+-
+ static struct clk_branch lpass_top_cc_lpi_q6_axim_hs_clk = {
+ 	.halt_reg = 0x0,
+ 	.halt_check = BRANCH_HALT,
+@@ -105,17 +79,6 @@ static struct regmap_config lpass_regmap_config = {
+ 	.fast_io	= true,
+ };
+ 
+-static struct clk_regmap *lpass_cc_sc7280_clocks[] = {
+-	[LPASS_Q6SS_AHBM_CLK] = &lpass_q6ss_ahbm_clk.clkr,
+-	[LPASS_Q6SS_AHBS_CLK] = &lpass_q6ss_ahbs_clk.clkr,
+-};
+-
+-static const struct qcom_cc_desc lpass_cc_sc7280_desc = {
+-	.config = &lpass_regmap_config,
+-	.clks = lpass_cc_sc7280_clocks,
+-	.num_clks = ARRAY_SIZE(lpass_cc_sc7280_clocks),
+-};
+-
+ static struct clk_regmap *lpass_cc_top_sc7280_clocks[] = {
+ 	[LPASS_TOP_CC_LPI_Q6_AXIM_HS_CLK] =
+ 				&lpass_top_cc_lpi_q6_axim_hs_clk.clkr,
+@@ -169,13 +132,6 @@ static int lpass_cc_sc7280_probe(struct platform_device *pdev)
+ 	if (ret)
+ 		goto destroy_pm_clk;
+ 
+-	lpass_regmap_config.name = "cc";
+-	desc = &lpass_cc_sc7280_desc;
+-
+-	ret = qcom_cc_probe_by_index(pdev, 2, desc);
+-	if (ret)
+-		goto destroy_pm_clk;
+-
+ 	return 0;
+ 
+ destroy_pm_clk:
+diff --git a/drivers/clk/qcom/lpasscorecc-sc7180.c b/drivers/clk/qcom/lpasscorecc-sc7180.c
+index ac09b7b840aba..a5731994cbed1 100644
+--- a/drivers/clk/qcom/lpasscorecc-sc7180.c
++++ b/drivers/clk/qcom/lpasscorecc-sc7180.c
+@@ -356,7 +356,7 @@ static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = {
+ 	.num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs),
+ };
+ 
+-static int lpass_create_pm_clks(struct platform_device *pdev)
++static int lpass_setup_runtime_pm(struct platform_device *pdev)
+ {
+ 	int ret;
+ 
+@@ -375,7 +375,7 @@ static int lpass_create_pm_clks(struct platform_device *pdev)
+ 	if (ret < 0)
+ 		dev_err(&pdev->dev, "failed to acquire iface clock\n");
+ 
+-	return ret;
++	return pm_runtime_resume_and_get(&pdev->dev);
+ }
+ 
+ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev)
+@@ -384,7 +384,7 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev)
+ 	struct regmap *regmap;
+ 	int ret;
+ 
+-	ret = lpass_create_pm_clks(pdev);
++	ret = lpass_setup_runtime_pm(pdev);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -392,12 +392,14 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev)
+ 	desc = &lpass_audio_hm_sc7180_desc;
+ 	ret = qcom_cc_probe_by_index(pdev, 1, desc);
+ 	if (ret)
+-		return ret;
++		goto exit;
+ 
+ 	lpass_core_cc_sc7180_regmap_config.name = "lpass_core_cc";
+ 	regmap = qcom_cc_map(pdev, &lpass_core_cc_sc7180_desc);
+-	if (IS_ERR(regmap))
+-		return PTR_ERR(regmap);
++	if (IS_ERR(regmap)) {
++		ret = PTR_ERR(regmap);
++		goto exit;
++	}
+ 
+ 	/*
+ 	 * Keep the CLK always-ON
+@@ -415,6 +417,7 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev)
+ 	ret = qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap);
+ 
+ 	pm_runtime_mark_last_busy(&pdev->dev);
++exit:
+ 	pm_runtime_put_autosuspend(&pdev->dev);
+ 
+ 	return ret;
+@@ -425,14 +428,19 @@ static int lpass_hm_core_probe(struct platform_device *pdev)
+ 	const struct qcom_cc_desc *desc;
+ 	int ret;
+ 
+-	ret = lpass_create_pm_clks(pdev);
++	ret = lpass_setup_runtime_pm(pdev);
+ 	if (ret)
+ 		return ret;
+ 
+ 	lpass_core_cc_sc7180_regmap_config.name = "lpass_hm_core";
+ 	desc = &lpass_core_hm_sc7180_desc;
+ 
+-	return qcom_cc_probe_by_index(pdev, 0, desc);
++	ret = qcom_cc_probe_by_index(pdev, 0, desc);
++
++	pm_runtime_mark_last_busy(&pdev->dev);
++	pm_runtime_put_autosuspend(&pdev->dev);
++
++	return ret;
+ }
+ 
+ static const struct of_device_id lpass_hm_sc7180_match_table[] = {
+diff --git a/drivers/clk/qcom/lpasscorecc-sc7280.c b/drivers/clk/qcom/lpasscorecc-sc7280.c
+index 1f1f1bd1b68ef..6ad19b06b1ce3 100644
+--- a/drivers/clk/qcom/lpasscorecc-sc7280.c
++++ b/drivers/clk/qcom/lpasscorecc-sc7280.c
+@@ -190,6 +190,19 @@ static struct clk_rcg2 lpass_core_cc_ext_if1_clk_src = {
+ 	},
+ };
+ 
++static struct clk_rcg2 lpass_core_cc_ext_mclk0_clk_src = {
++	.cmd_rcgr = 0x20000,
++	.mnd_width = 8,
++	.hid_width = 5,
++	.parent_map = lpass_core_cc_parent_map_0,
++	.freq_tbl = ftbl_lpass_core_cc_ext_if0_clk_src,
++	.clkr.hw.init = &(const struct clk_init_data){
++		.name = "lpass_core_cc_ext_mclk0_clk_src",
++		.parent_data = lpass_core_cc_parent_data_0,
++		.num_parents = ARRAY_SIZE(lpass_core_cc_parent_data_0),
++		.ops = &clk_rcg2_ops,
++	},
++};
+ 
+ static struct clk_branch lpass_core_cc_core_clk = {
+ 	.halt_reg = 0x1f000,
+@@ -283,6 +296,24 @@ static struct clk_branch lpass_core_cc_lpm_mem0_core_clk = {
+ 	},
+ };
+ 
++static struct clk_branch lpass_core_cc_ext_mclk0_clk = {
++	.halt_reg = 0x20014,
++	.halt_check = BRANCH_HALT,
++	.clkr = {
++		.enable_reg = 0x20014,
++		.enable_mask = BIT(0),
++		.hw.init = &(const struct clk_init_data){
++			.name = "lpass_core_cc_ext_mclk0_clk",
++			.parent_hws = (const struct clk_hw*[]){
++				&lpass_core_cc_ext_mclk0_clk_src.clkr.hw,
++			},
++			.num_parents = 1,
++			.flags = CLK_SET_RATE_PARENT,
++			.ops = &clk_branch2_ops,
++		},
++	},
++};
++
+ static struct clk_branch lpass_core_cc_sysnoc_mport_core_clk = {
+ 	.halt_reg = 0x23000,
+ 	.halt_check = BRANCH_HALT_VOTED,
+@@ -326,6 +357,8 @@ static struct clk_regmap *lpass_core_cc_sc7280_clocks[] = {
+ 	[LPASS_CORE_CC_LPM_CORE_CLK] = &lpass_core_cc_lpm_core_clk.clkr,
+ 	[LPASS_CORE_CC_LPM_MEM0_CORE_CLK] = &lpass_core_cc_lpm_mem0_core_clk.clkr,
+ 	[LPASS_CORE_CC_SYSNOC_MPORT_CORE_CLK] = &lpass_core_cc_sysnoc_mport_core_clk.clkr,
++	[LPASS_CORE_CC_EXT_MCLK0_CLK] = &lpass_core_cc_ext_mclk0_clk.clkr,
++	[LPASS_CORE_CC_EXT_MCLK0_CLK_SRC] = &lpass_core_cc_ext_mclk0_clk_src.clkr,
+ };
+ 
+ static struct regmap_config lpass_core_cc_sc7280_regmap_config = {
+diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c
+index d74d46833012f..e02542ca24a06 100644
+--- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c
+@@ -116,7 +116,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
+ 	DEF_FIXED("cp",		R8A779A0_CLK_CP,	CLK_EXTAL,	2, 1),
+ 	DEF_FIXED("cl16mck",	R8A779A0_CLK_CL16MCK,	CLK_PLL1_DIV2,	64, 1),
+ 
+-	DEF_GEN4_SDH("sdh0",	R8A779A0_CLK_SD0H,	CLK_SDSRC,	   0x870),
++	DEF_GEN4_SDH("sd0h",	R8A779A0_CLK_SD0H,	CLK_SDSRC,	   0x870),
+ 	DEF_GEN4_SD("sd0",	R8A779A0_CLK_SD0,	R8A779A0_CLK_SD0H, 0x870),
+ 
+ 	DEF_BASE("rpc",		R8A779A0_CLK_RPC, CLK_TYPE_GEN4_RPC, CLK_RPCSRC),
+diff --git a/drivers/clk/renesas/r8a779f0-cpg-mssr.c b/drivers/clk/renesas/r8a779f0-cpg-mssr.c
+index cd80b6084eceb..ab104a25a6019 100644
+--- a/drivers/clk/renesas/r8a779f0-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a779f0-cpg-mssr.c
+@@ -108,7 +108,13 @@ static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = {
+ 	DEF_FIXED("cbfusa",	R8A779F0_CLK_CBFUSA,	CLK_EXTAL,	2, 1),
+ 	DEF_FIXED("cpex",	R8A779F0_CLK_CPEX,	CLK_EXTAL,	2, 1),
+ 
+-	DEF_GEN4_SD("sd0",	R8A779F0_CLK_SD0,	CLK_SDSRC,	0x870),
++	DEF_FIXED("sasyncrt",	R8A779F0_CLK_SASYNCRT,	CLK_PLL5_DIV4,	48, 1),
++	DEF_FIXED("sasyncperd1", R8A779F0_CLK_SASYNCPERD1, CLK_PLL5_DIV4, 3, 1),
++	DEF_FIXED("sasyncperd2", R8A779F0_CLK_SASYNCPERD2, R8A779F0_CLK_SASYNCPERD1, 2, 1),
++	DEF_FIXED("sasyncperd4", R8A779F0_CLK_SASYNCPERD4, R8A779F0_CLK_SASYNCPERD1, 4, 1),
++
++	DEF_GEN4_SDH("sd0h",	R8A779F0_CLK_SD0H,	CLK_SDSRC,	   0x870),
++	DEF_GEN4_SD("sd0",	R8A779F0_CLK_SD0,	R8A779F0_CLK_SD0H, 0x870),
+ 
+ 	DEF_BASE("rpc",		R8A779F0_CLK_RPC,	CLK_TYPE_GEN4_RPC, CLK_RPCSRC),
+ 	DEF_BASE("rpcd2",	R8A779F0_CLK_RPCD2,	CLK_TYPE_GEN4_RPCD2, R8A779F0_CLK_RPC),
+@@ -120,10 +126,10 @@ static const struct cpg_core_clk r8a779f0_core_clks[] __initconst = {
+ };
+ 
+ static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = {
+-	DEF_MOD("hscif0",	514,	R8A779F0_CLK_S0D3),
+-	DEF_MOD("hscif1",	515,	R8A779F0_CLK_S0D3),
+-	DEF_MOD("hscif2",	516,	R8A779F0_CLK_S0D3),
+-	DEF_MOD("hscif3",	517,	R8A779F0_CLK_S0D3),
++	DEF_MOD("hscif0",	514,	R8A779F0_CLK_SASYNCPERD1),
++	DEF_MOD("hscif1",	515,	R8A779F0_CLK_SASYNCPERD1),
++	DEF_MOD("hscif2",	516,	R8A779F0_CLK_SASYNCPERD1),
++	DEF_MOD("hscif3",	517,	R8A779F0_CLK_SASYNCPERD1),
+ 	DEF_MOD("i2c0",		518,	R8A779F0_CLK_S0D6_PER),
+ 	DEF_MOD("i2c1",		519,	R8A779F0_CLK_S0D6_PER),
+ 	DEF_MOD("i2c2",		520,	R8A779F0_CLK_S0D6_PER),
+@@ -132,13 +138,18 @@ static const struct mssr_mod_clk r8a779f0_mod_clks[] __initconst = {
+ 	DEF_MOD("i2c5",		523,	R8A779F0_CLK_S0D6_PER),
+ 	DEF_MOD("pcie0",	624,	R8A779F0_CLK_S0D2),
+ 	DEF_MOD("pcie1",	625,	R8A779F0_CLK_S0D2),
+-	DEF_MOD("scif0",	702,	R8A779F0_CLK_S0D12_PER),
+-	DEF_MOD("scif1",	703,	R8A779F0_CLK_S0D12_PER),
+-	DEF_MOD("scif3",	704,	R8A779F0_CLK_S0D12_PER),
+-	DEF_MOD("scif4",	705,	R8A779F0_CLK_S0D12_PER),
++	DEF_MOD("scif0",	702,	R8A779F0_CLK_SASYNCPERD4),
++	DEF_MOD("scif1",	703,	R8A779F0_CLK_SASYNCPERD4),
++	DEF_MOD("scif3",	704,	R8A779F0_CLK_SASYNCPERD4),
++	DEF_MOD("scif4",	705,	R8A779F0_CLK_SASYNCPERD4),
+ 	DEF_MOD("sdhi0",        706,    R8A779F0_CLK_SD0),
+ 	DEF_MOD("sys-dmac0",	709,	R8A779F0_CLK_S0D3_PER),
+ 	DEF_MOD("sys-dmac1",	710,	R8A779F0_CLK_S0D3_PER),
++	DEF_MOD("tmu0",		713,	R8A779F0_CLK_SASYNCRT),
++	DEF_MOD("tmu1",		714,	R8A779F0_CLK_SASYNCPERD2),
++	DEF_MOD("tmu2",		715,	R8A779F0_CLK_SASYNCPERD2),
++	DEF_MOD("tmu3",		716,	R8A779F0_CLK_SASYNCPERD2),
++	DEF_MOD("tmu4",		717,	R8A779F0_CLK_SASYNCPERD2),
+ 	DEF_MOD("wdt",		907,	R8A779F0_CLK_R),
+ 	DEF_MOD("pfc0",		915,	R8A779F0_CLK_CL16M),
+ 	DEF_MOD("tsc",		919,	R8A779F0_CLK_CL16M),
+diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c
+index 1488c9d6e6394..983faa5707b9c 100644
+--- a/drivers/clk/renesas/r9a06g032-clocks.c
++++ b/drivers/clk/renesas/r9a06g032-clocks.c
+@@ -412,7 +412,7 @@ static int r9a06g032_attach_dev(struct generic_pm_domain *pd,
+ 	int error;
+ 	int index;
+ 
+-	while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
++	while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i++,
+ 					   &clkspec)) {
+ 		if (clkspec.np != pd->dev.of_node)
+ 			continue;
+@@ -425,7 +425,6 @@ static int r9a06g032_attach_dev(struct generic_pm_domain *pd,
+ 			if (error)
+ 				return error;
+ 		}
+-		i++;
+ 	}
+ 
+ 	return 0;
+diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
+index f7827b3b7fc1c..6e5e502be44a6 100644
+--- a/drivers/clk/rockchip/clk-pll.c
++++ b/drivers/clk/rockchip/clk-pll.c
+@@ -981,6 +981,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
+ 	return mux_clk;
+ 
+ err_pll:
++	kfree(pll->rate_table);
+ 	clk_unregister(mux_clk);
+ 	mux_clk = pll_clk;
+ err_mux:
+diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
+index fe383471c5f0a..0ff28938943f0 100644
+--- a/drivers/clk/samsung/clk-pll.c
++++ b/drivers/clk/samsung/clk-pll.c
+@@ -1583,6 +1583,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
+ 	if (ret) {
+ 		pr_err("%s: failed to register pll clock %s : %d\n",
+ 			__func__, pll_clk->name, ret);
++		kfree(pll->rate_table);
+ 		kfree(pll);
+ 		return;
+ 	}
+diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
+index 53d6e3ec4309f..c94b59b80dd43 100644
+--- a/drivers/clk/socfpga/clk-gate.c
++++ b/drivers/clk/socfpga/clk-gate.c
+@@ -188,8 +188,10 @@ void __init socfpga_gate_init(struct device_node *node)
+ 		return;
+ 
+ 	ops = kmemdup(&gateclk_ops, sizeof(gateclk_ops), GFP_KERNEL);
+-	if (WARN_ON(!ops))
++	if (WARN_ON(!ops)) {
++		kfree(socfpga_clk);
+ 		return;
++	}
+ 
+ 	rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
+ 	if (rc)
+@@ -243,6 +245,7 @@ void __init socfpga_gate_init(struct device_node *node)
+ 
+ 	err = clk_hw_register(NULL, hw_clk);
+ 	if (err) {
++		kfree(ops);
+ 		kfree(socfpga_clk);
+ 		return;
+ 	}
+diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c
+index d820292a381d0..40df1db102a77 100644
+--- a/drivers/clk/st/clkgen-fsyn.c
++++ b/drivers/clk/st/clkgen-fsyn.c
+@@ -1020,9 +1020,10 @@ static void __init st_of_quadfs_setup(struct device_node *np,
+ 
+ 	clk = st_clk_register_quadfs_pll(pll_name, clk_parent_name, datac->data,
+ 			reg, lock);
+-	if (IS_ERR(clk))
++	if (IS_ERR(clk)) {
++		kfree(lock);
+ 		goto err_exit;
+-	else
++	} else
+ 		pr_debug("%s: parent %s rate %u\n",
+ 			__clk_get_name(clk),
+ 			__clk_get_name(clk_get_parent(clk)),
+diff --git a/drivers/clk/visconti/pll.c b/drivers/clk/visconti/pll.c
+index a484cb945d67b..1f3234f226674 100644
+--- a/drivers/clk/visconti/pll.c
++++ b/drivers/clk/visconti/pll.c
+@@ -277,6 +277,7 @@ static struct clk_hw *visconti_register_pll(struct visconti_pll_provider *ctx,
+ 	ret = clk_hw_register(NULL, &pll->hw);
+ 	if (ret) {
+ 		pr_err("failed to register pll clock %s : %d\n", name, ret);
++		kfree(pll->rate_table);
+ 		kfree(pll);
+ 		pll_hw_clk = ERR_PTR(ret);
+ 	}
+diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
+index 64dcb082d4cf6..7b952aa52c0b9 100644
+--- a/drivers/clocksource/sh_cmt.c
++++ b/drivers/clocksource/sh_cmt.c
+@@ -13,6 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/ioport.h>
+ #include <linux/irq.h>
+ #include <linux/module.h>
+@@ -116,6 +117,7 @@ struct sh_cmt_device {
+ 	void __iomem *mapbase;
+ 	struct clk *clk;
+ 	unsigned long rate;
++	unsigned int reg_delay;
+ 
+ 	raw_spinlock_t lock; /* Protect the shared start/stop register */
+ 
+@@ -247,10 +249,17 @@ static inline u32 sh_cmt_read_cmstr(struct sh_cmt_channel *ch)
+ 
+ static inline void sh_cmt_write_cmstr(struct sh_cmt_channel *ch, u32 value)
+ {
+-	if (ch->iostart)
+-		ch->cmt->info->write_control(ch->iostart, 0, value);
+-	else
+-		ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
++	u32 old_value = sh_cmt_read_cmstr(ch);
++
++	if (value != old_value) {
++		if (ch->iostart) {
++			ch->cmt->info->write_control(ch->iostart, 0, value);
++			udelay(ch->cmt->reg_delay);
++		} else {
++			ch->cmt->info->write_control(ch->cmt->mapbase, 0, value);
++			udelay(ch->cmt->reg_delay);
++		}
++	}
+ }
+ 
+ static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
+@@ -260,7 +269,12 @@ static inline u32 sh_cmt_read_cmcsr(struct sh_cmt_channel *ch)
+ 
+ static inline void sh_cmt_write_cmcsr(struct sh_cmt_channel *ch, u32 value)
+ {
+-	ch->cmt->info->write_control(ch->ioctrl, CMCSR, value);
++	u32 old_value = sh_cmt_read_cmcsr(ch);
++
++	if (value != old_value) {
++		ch->cmt->info->write_control(ch->ioctrl, CMCSR, value);
++		udelay(ch->cmt->reg_delay);
++	}
+ }
+ 
+ static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
+@@ -268,14 +282,33 @@ static inline u32 sh_cmt_read_cmcnt(struct sh_cmt_channel *ch)
+ 	return ch->cmt->info->read_count(ch->ioctrl, CMCNT);
+ }
+ 
+-static inline void sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value)
++static inline int sh_cmt_write_cmcnt(struct sh_cmt_channel *ch, u32 value)
+ {
++	/* Tests showed that we need to wait 3 clocks here */
++	unsigned int cmcnt_delay = DIV_ROUND_UP(3 * ch->cmt->reg_delay, 2);
++	u32 reg;
++
++	if (ch->cmt->info->model > SH_CMT_16BIT) {
++		int ret = read_poll_timeout_atomic(sh_cmt_read_cmcsr, reg,
++						   !(reg & SH_CMT32_CMCSR_WRFLG),
++						   1, cmcnt_delay, false, ch);
++		if (ret < 0)
++			return ret;
++	}
++
+ 	ch->cmt->info->write_count(ch->ioctrl, CMCNT, value);
++	udelay(cmcnt_delay);
++	return 0;
+ }
+ 
+ static inline void sh_cmt_write_cmcor(struct sh_cmt_channel *ch, u32 value)
+ {
+-	ch->cmt->info->write_count(ch->ioctrl, CMCOR, value);
++	u32 old_value = ch->cmt->info->read_count(ch->ioctrl, CMCOR);
++
++	if (value != old_value) {
++		ch->cmt->info->write_count(ch->ioctrl, CMCOR, value);
++		udelay(ch->cmt->reg_delay);
++	}
+ }
+ 
+ static u32 sh_cmt_get_counter(struct sh_cmt_channel *ch, u32 *has_wrapped)
+@@ -319,7 +352,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
+ 
+ static int sh_cmt_enable(struct sh_cmt_channel *ch)
+ {
+-	int k, ret;
++	int ret;
+ 
+ 	dev_pm_syscore_device(&ch->cmt->pdev->dev, true);
+ 
+@@ -347,26 +380,9 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch)
+ 	}
+ 
+ 	sh_cmt_write_cmcor(ch, 0xffffffff);
+-	sh_cmt_write_cmcnt(ch, 0);
+-
+-	/*
+-	 * According to the sh73a0 user's manual, as CMCNT can be operated
+-	 * only by the RCLK (Pseudo 32 kHz), there's one restriction on
+-	 * modifying CMCNT register; two RCLK cycles are necessary before
+-	 * this register is either read or any modification of the value
+-	 * it holds is reflected in the LSI's actual operation.
+-	 *
+-	 * While at it, we're supposed to clear out the CMCNT as of this
+-	 * moment, so make sure it's processed properly here.  This will
+-	 * take RCLKx2 at maximum.
+-	 */
+-	for (k = 0; k < 100; k++) {
+-		if (!sh_cmt_read_cmcnt(ch))
+-			break;
+-		udelay(1);
+-	}
++	ret = sh_cmt_write_cmcnt(ch, 0);
+ 
+-	if (sh_cmt_read_cmcnt(ch)) {
++	if (ret || sh_cmt_read_cmcnt(ch)) {
+ 		dev_err(&ch->cmt->pdev->dev, "ch%u: cannot clear CMCNT\n",
+ 			ch->index);
+ 		ret = -ETIMEDOUT;
+@@ -995,8 +1011,8 @@ MODULE_DEVICE_TABLE(of, sh_cmt_of_table);
+ 
+ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+ {
+-	unsigned int mask;
+-	unsigned int i;
++	unsigned int mask, i;
++	unsigned long rate;
+ 	int ret;
+ 
+ 	cmt->pdev = pdev;
+@@ -1032,10 +1048,16 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
+ 	if (ret < 0)
+ 		goto err_clk_unprepare;
+ 
+-	if (cmt->info->width == 16)
+-		cmt->rate = clk_get_rate(cmt->clk) / 512;
+-	else
+-		cmt->rate = clk_get_rate(cmt->clk) / 8;
++	rate = clk_get_rate(cmt->clk);
++	if (!rate) {
++		ret = -EINVAL;
++		goto err_clk_disable;
++	}
++
++	/* We shall wait 2 input clks after register writes */
++	if (cmt->info->model >= SH_CMT_48BIT)
++		cmt->reg_delay = DIV_ROUND_UP(2UL * USEC_PER_SEC, rate);
++	cmt->rate = rate / (cmt->info->width == 16 ? 512 : 8);
+ 
+ 	/* Map the memory resource(s). */
+ 	ret = sh_cmt_map_memory(cmt);
+diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c
+index 2737407ff0698..632523c1232f6 100644
+--- a/drivers/clocksource/timer-ti-dm-systimer.c
++++ b/drivers/clocksource/timer-ti-dm-systimer.c
+@@ -345,8 +345,10 @@ static int __init dmtimer_systimer_init_clock(struct dmtimer_systimer *t,
+ 		return error;
+ 
+ 	r = clk_get_rate(clock);
+-	if (!r)
++	if (!r) {
++		clk_disable_unprepare(clock);
+ 		return -ENODEV;
++	}
+ 
+ 	if (is_ick)
+ 		t->ick = clock;
+diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c
+index 469f7c91564b6..78c2c038d3ae4 100644
+--- a/drivers/clocksource/timer-ti-dm.c
++++ b/drivers/clocksource/timer-ti-dm.c
+@@ -1081,7 +1081,7 @@ static struct platform_driver omap_dm_timer_driver = {
+ 	.remove = omap_dm_timer_remove,
+ 	.driver = {
+ 		.name   = "omap_timer",
+-		.of_match_table = of_match_ptr(omap_timer_match),
++		.of_match_table = omap_timer_match,
+ 		.pm = &omap_dm_timer_pm_ops,
+ 	},
+ };
+diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
+index 68031d93ce895..aee3b1a8aaa77 100644
+--- a/drivers/counter/stm32-lptimer-cnt.c
++++ b/drivers/counter/stm32-lptimer-cnt.c
+@@ -69,7 +69,7 @@ static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv,
+ 
+ 	/* ensure CMP & ARR registers are properly written */
+ 	ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
+-				       (val & STM32_LPTIM_CMPOK_ARROK),
++				       (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
+ 				       100, 1000);
+ 	if (ret)
+ 		return ret;
+diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c
+index 6448e03bcf488..59b19b9975e8c 100644
+--- a/drivers/cpufreq/amd_freq_sensitivity.c
++++ b/drivers/cpufreq/amd_freq_sensitivity.c
+@@ -125,6 +125,8 @@ static int __init amd_freq_sensitivity_init(void)
+ 	if (!pcidev) {
+ 		if (!boot_cpu_has(X86_FEATURE_PROC_FEEDBACK))
+ 			return -ENODEV;
++	} else {
++		pci_dev_put(pcidev);
+ 	}
+ 
+ 	if (rdmsrl_safe(MSR_AMD64_FREQ_SENSITIVITY_ACTUAL, &val))
+diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
+index bb32659820ceb..823b069203e1b 100644
+--- a/drivers/cpufreq/qcom-cpufreq-hw.c
++++ b/drivers/cpufreq/qcom-cpufreq-hw.c
+@@ -122,7 +122,35 @@ static int qcom_cpufreq_hw_target_index(struct cpufreq_policy *policy,
+ 	return 0;
+ }
+ 
++static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data)
++{
++	unsigned int lval;
++
++	if (data->soc_data->reg_current_vote)
++		lval = readl_relaxed(data->base + data->soc_data->reg_current_vote) & 0x3ff;
++	else
++		lval = readl_relaxed(data->base + data->soc_data->reg_domain_state) & 0xff;
++
++	return lval * xo_rate;
++}
++
++/* Get the current frequency of the CPU (after throttling) */
+ static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
++{
++	struct qcom_cpufreq_data *data;
++	struct cpufreq_policy *policy;
++
++	policy = cpufreq_cpu_get_raw(cpu);
++	if (!policy)
++		return 0;
++
++	data = policy->driver_data;
++
++	return qcom_lmh_get_throttle_freq(data) / HZ_PER_KHZ;
++}
++
++/* Get the frequency requested by the cpufreq core for the CPU */
++static unsigned int qcom_cpufreq_get_freq(unsigned int cpu)
+ {
+ 	struct qcom_cpufreq_data *data;
+ 	const struct qcom_cpufreq_soc_data *soc_data;
+@@ -190,6 +218,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev,
+ 		}
+ 	} else if (ret != -ENODEV) {
+ 		dev_err(cpu_dev, "Invalid opp table in device tree\n");
++		kfree(table);
+ 		return ret;
+ 	} else {
+ 		policy->fast_switch_possible = true;
+@@ -283,18 +312,6 @@ static void qcom_get_related_cpus(int index, struct cpumask *m)
+ 	}
+ }
+ 
+-static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data)
+-{
+-	unsigned int lval;
+-
+-	if (data->soc_data->reg_current_vote)
+-		lval = readl_relaxed(data->base + data->soc_data->reg_current_vote) & 0x3ff;
+-	else
+-		lval = readl_relaxed(data->base + data->soc_data->reg_domain_state) & 0xff;
+-
+-	return lval * xo_rate;
+-}
+-
+ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data)
+ {
+ 	struct cpufreq_policy *policy = data->policy;
+@@ -336,7 +353,7 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data)
+ 	 * If h/w throttled frequency is higher than what cpufreq has requested
+ 	 * for, then stop polling and switch back to interrupt mechanism.
+ 	 */
+-	if (throttled_freq >= qcom_cpufreq_hw_get(cpu))
++	if (throttled_freq >= qcom_cpufreq_get_freq(cpu))
+ 		enable_irq(data->throttle_irq);
+ 	else
+ 		mod_delayed_work(system_highpri_wq, &data->throttle_work,
+diff --git a/drivers/cpuidle/dt_idle_states.c b/drivers/cpuidle/dt_idle_states.c
+index 252f2a9686a62..448bc796b0b40 100644
+--- a/drivers/cpuidle/dt_idle_states.c
++++ b/drivers/cpuidle/dt_idle_states.c
+@@ -223,6 +223,6 @@ int dt_init_idle_driver(struct cpuidle_driver *drv,
+ 	 * also be 0 on platforms with missing DT idle states or legacy DT
+ 	 * configuration predating the DT idle states bindings.
+ 	 */
+-	return i;
++	return state_idx - start_idx;
+ }
+ EXPORT_SYMBOL_GPL(dt_init_idle_driver);
+diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
+index 3e6aa319920b7..79d9e14b70c87 100644
+--- a/drivers/crypto/Kconfig
++++ b/drivers/crypto/Kconfig
+@@ -669,7 +669,12 @@ config CRYPTO_DEV_IMGTEC_HASH
+ config CRYPTO_DEV_ROCKCHIP
+ 	tristate "Rockchip's Cryptographic Engine driver"
+ 	depends on OF && ARCH_ROCKCHIP
++	depends on PM
++	select CRYPTO_ECB
++	select CRYPTO_CBC
++	select CRYPTO_DES
+ 	select CRYPTO_AES
++	select CRYPTO_ENGINE
+ 	select CRYPTO_LIB_DES
+ 	select CRYPTO_MD5
+ 	select CRYPTO_SHA1
+diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+index 910d6751644cf..902f6be057ec6 100644
+--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
++++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c
+@@ -124,7 +124,7 @@ static int sun8i_ss_setup_ivs(struct skcipher_request *areq)
+ 	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+ 	struct sun8i_ss_flow *sf = &ss->flows[rctx->flow];
+ 	int i = 0;
+-	u32 a;
++	dma_addr_t a;
+ 	int err;
+ 
+ 	rctx->ivlen = ivsize;
+diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
+index 6e7ae896717cd..937187027ad57 100644
+--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
++++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
+@@ -237,7 +237,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
+ 		return err;
+ 	}
+ 
+-	mc->irqs = devm_kcalloc(mc->dev, MAXFLOW, sizeof(int), GFP_KERNEL);
+ 	for (i = 0; i < MAXFLOW; i++) {
+ 		mc->irqs[i] = platform_get_irq(pdev, i);
+ 		if (mc->irqs[i] < 0)
+diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
+index dc0f142324a3c..8c0746a1d6d43 100644
+--- a/drivers/crypto/amlogic/amlogic-gxl.h
++++ b/drivers/crypto/amlogic/amlogic-gxl.h
+@@ -95,7 +95,7 @@ struct meson_dev {
+ 	struct device *dev;
+ 	struct meson_flow *chanlist;
+ 	atomic_t flow;
+-	int *irqs;
++	int irqs[MAXFLOW];
+ #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ 	struct dentry *dbgfs_dir;
+ #endif
+diff --git a/drivers/crypto/cavium/nitrox/nitrox_mbx.c b/drivers/crypto/cavium/nitrox/nitrox_mbx.c
+index 9e7308e39b304..d4e06999af9b7 100644
+--- a/drivers/crypto/cavium/nitrox/nitrox_mbx.c
++++ b/drivers/crypto/cavium/nitrox/nitrox_mbx.c
+@@ -195,6 +195,7 @@ int nitrox_mbox_init(struct nitrox_device *ndev)
+ 	ndev->iov.pf2vf_wq = alloc_workqueue("nitrox_pf2vf", 0, 0);
+ 	if (!ndev->iov.pf2vf_wq) {
+ 		kfree(ndev->iov.vfdev);
++		ndev->iov.vfdev = NULL;
+ 		return -ENOMEM;
+ 	}
+ 	/* enable pf2vf mailbox interrupts */
+diff --git a/drivers/crypto/ccree/cc_debugfs.c b/drivers/crypto/ccree/cc_debugfs.c
+index 7083767602fcf..8f008f024f8f1 100644
+--- a/drivers/crypto/ccree/cc_debugfs.c
++++ b/drivers/crypto/ccree/cc_debugfs.c
+@@ -55,7 +55,7 @@ void __init cc_debugfs_global_init(void)
+ 	cc_debugfs_dir = debugfs_create_dir("ccree", NULL);
+ }
+ 
+-void __exit cc_debugfs_global_fini(void)
++void cc_debugfs_global_fini(void)
+ {
+ 	debugfs_remove(cc_debugfs_dir);
+ }
+diff --git a/drivers/crypto/ccree/cc_driver.c b/drivers/crypto/ccree/cc_driver.c
+index cadead18b59e8..d489c6f808925 100644
+--- a/drivers/crypto/ccree/cc_driver.c
++++ b/drivers/crypto/ccree/cc_driver.c
+@@ -651,9 +651,17 @@ static struct platform_driver ccree_driver = {
+ 
+ static int __init ccree_init(void)
+ {
++	int rc;
++
+ 	cc_debugfs_global_init();
+ 
+-	return platform_driver_register(&ccree_driver);
++	rc = platform_driver_register(&ccree_driver);
++	if (rc) {
++		cc_debugfs_global_fini();
++		return rc;
++	}
++
++	return 0;
+ }
+ module_init(ccree_init);
+ 
+diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
+index 9d529df0eab9b..7a50ca664ada1 100644
+--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
++++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
+@@ -457,7 +457,7 @@ static void hpre_open_sva_prefetch(struct hisi_qm *qm)
+ 	u32 val;
+ 	int ret;
+ 
+-	if (qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ 		return;
+ 
+ 	/* Enable prefetch */
+@@ -478,7 +478,7 @@ static void hpre_close_sva_prefetch(struct hisi_qm *qm)
+ 	u32 val;
+ 	int ret;
+ 
+-	if (qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ 		return;
+ 
+ 	val = readl_relaxed(qm->io_base + HPRE_PREFETCH_CFG);
+@@ -1287,18 +1287,12 @@ err_with_qm_init:
+ static void hpre_remove(struct pci_dev *pdev)
+ {
+ 	struct hisi_qm *qm = pci_get_drvdata(pdev);
+-	int ret;
+ 
+ 	hisi_qm_pm_uninit(qm);
+ 	hisi_qm_wait_task_finish(qm, &hpre_devices);
+ 	hisi_qm_alg_unregister(qm, &hpre_devices);
+-	if (qm->fun_type == QM_HW_PF && qm->vfs_num) {
+-		ret = hisi_qm_sriov_disable(pdev, true);
+-		if (ret) {
+-			pci_err(pdev, "Disable SRIOV fail!\n");
+-			return;
+-		}
+-	}
++	if (qm->fun_type == QM_HW_PF && qm->vfs_num)
++		hisi_qm_sriov_disable(pdev, true);
+ 
+ 	hpre_debugfs_exit(qm);
+ 	hisi_qm_stop(qm, QM_NORMAL);
+diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
+index 9fa2efe601537..959f4846aa233 100644
+--- a/drivers/crypto/hisilicon/qm.c
++++ b/drivers/crypto/hisilicon/qm.c
+@@ -86,9 +86,7 @@
+ #define QM_DB_CMD_SHIFT_V1		16
+ #define QM_DB_INDEX_SHIFT_V1		32
+ #define QM_DB_PRIORITY_SHIFT_V1		48
+-#define QM_QUE_ISO_CFG_V		0x0030
+ #define QM_PAGE_SIZE			0x0034
+-#define QM_QUE_ISO_EN			0x100154
+ #define QM_CAPBILITY			0x100158
+ #define QM_QP_NUN_MASK			GENMASK(10, 0)
+ #define QM_QP_DB_INTERVAL		0x10000
+@@ -205,6 +203,8 @@
+ #define MAX_WAIT_COUNTS			1000
+ #define QM_CACHE_WB_START		0x204
+ #define QM_CACHE_WB_DONE		0x208
++#define QM_FUNC_CAPS_REG		0x3100
++#define QM_CAPBILITY_VERSION		GENMASK(7, 0)
+ 
+ #define PCI_BAR_2			2
+ #define PCI_BAR_4			4
+@@ -252,7 +252,6 @@
+ #define QM_QOS_MIN_CIR_B		100
+ #define QM_QOS_MAX_CIR_U		6
+ #define QM_QOS_MAX_CIR_S		11
+-#define QM_QOS_VAL_MAX_LEN		32
+ #define QM_DFX_BASE		0x0100000
+ #define QM_DFX_STATE1		0x0104000
+ #define QM_DFX_STATE2		0x01040C8
+@@ -329,6 +328,22 @@ enum qm_mb_cmd {
+ 	QM_VF_GET_QOS,
+ };
+ 
++static const struct hisi_qm_cap_info qm_cap_info_comm[] = {
++	{QM_SUPPORT_DB_ISOLATION, 0x30,   0, BIT(0),  0x0, 0x0, 0x0},
++	{QM_SUPPORT_FUNC_QOS,     0x3100, 0, BIT(8),  0x0, 0x0, 0x1},
++	{QM_SUPPORT_STOP_QP,      0x3100, 0, BIT(9),  0x0, 0x0, 0x1},
++	{QM_SUPPORT_MB_COMMAND,   0x3100, 0, BIT(11), 0x0, 0x0, 0x1},
++	{QM_SUPPORT_SVA_PREFETCH, 0x3100, 0, BIT(14), 0x0, 0x0, 0x1},
++};
++
++static const struct hisi_qm_cap_info qm_cap_info_pf[] = {
++	{QM_SUPPORT_RPM, 0x3100, 0, BIT(13), 0x0, 0x0, 0x1},
++};
++
++static const struct hisi_qm_cap_info qm_cap_info_vf[] = {
++	{QM_SUPPORT_RPM, 0x3100, 0, BIT(12), 0x0, 0x0, 0x0},
++};
++
+ struct qm_cqe {
+ 	__le32 rsvd0;
+ 	__le16 cmd_id;
+@@ -426,10 +441,7 @@ struct hisi_qm_hw_ops {
+ 	void (*hw_error_init)(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe);
+ 	void (*hw_error_uninit)(struct hisi_qm *qm);
+ 	enum acc_err_result (*hw_error_handle)(struct hisi_qm *qm);
+-	int (*stop_qp)(struct hisi_qp *qp);
+ 	int (*set_msi)(struct hisi_qm *qm, bool set);
+-	int (*ping_all_vfs)(struct hisi_qm *qm, u64 cmd);
+-	int (*ping_pf)(struct hisi_qm *qm, u64 cmd);
+ };
+ 
+ struct qm_dfx_item {
+@@ -828,6 +840,36 @@ static int qm_dev_mem_reset(struct hisi_qm *qm)
+ 					  POLL_TIMEOUT);
+ }
+ 
++/**
++ * hisi_qm_get_hw_info() - Get device information.
++ * @qm: The qm which want to get information.
++ * @info_table: Array for storing device information.
++ * @index: Index in info_table.
++ * @is_read: Whether read from reg, 0: not support read from reg.
++ *
++ * This function returns device information the caller needs.
++ */
++u32 hisi_qm_get_hw_info(struct hisi_qm *qm,
++			const struct hisi_qm_cap_info *info_table,
++			u32 index, bool is_read)
++{
++	u32 val;
++
++	switch (qm->ver) {
++	case QM_HW_V1:
++		return info_table[index].v1_val;
++	case QM_HW_V2:
++		return info_table[index].v2_val;
++	default:
++		if (!is_read)
++			return info_table[index].v3_val;
++
++		val = readl(qm->io_base + info_table[index].offset);
++		return (val >> info_table[index].shift) & info_table[index].mask;
++	}
++}
++EXPORT_SYMBOL_GPL(hisi_qm_get_hw_info);
++
+ static u32 qm_get_irq_num_v1(struct hisi_qm *qm)
+ {
+ 	return QM_IRQ_NUM_V1;
+@@ -854,7 +896,7 @@ static int qm_pm_get_sync(struct hisi_qm *qm)
+ 	struct device *dev = &qm->pdev->dev;
+ 	int ret;
+ 
+-	if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_RPM, &qm->caps))
+ 		return 0;
+ 
+ 	ret = pm_runtime_resume_and_get(dev);
+@@ -870,7 +912,7 @@ static void qm_pm_put_sync(struct hisi_qm *qm)
+ {
+ 	struct device *dev = &qm->pdev->dev;
+ 
+-	if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_RPM, &qm->caps))
+ 		return;
+ 
+ 	pm_runtime_mark_last_busy(dev);
+@@ -1151,7 +1193,7 @@ static void qm_init_prefetch(struct hisi_qm *qm)
+ 	struct device *dev = &qm->pdev->dev;
+ 	u32 page_type = 0x0;
+ 
+-	if (qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ 		return;
+ 
+ 	switch (PAGE_SIZE) {
+@@ -1270,7 +1312,7 @@ static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base,
+ 			}
+ 			break;
+ 		case SHAPER_VFT:
+-			if (qm->ver >= QM_HW_V3) {
++			if (factor) {
+ 				tmp = factor->cir_b |
+ 				(factor->cir_u << QM_SHAPER_FACTOR_CIR_U_SHIFT) |
+ 				(factor->cir_s << QM_SHAPER_FACTOR_CIR_S_SHIFT) |
+@@ -1288,10 +1330,13 @@ static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base,
+ static int qm_set_vft_common(struct hisi_qm *qm, enum vft_type type,
+ 			     u32 fun_num, u32 base, u32 number)
+ {
+-	struct qm_shaper_factor *factor = &qm->factor[fun_num];
++	struct qm_shaper_factor *factor = NULL;
+ 	unsigned int val;
+ 	int ret;
+ 
++	if (type == SHAPER_VFT && test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
++		factor = &qm->factor[fun_num];
++
+ 	ret = readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val,
+ 					 val & BIT(0), POLL_PERIOD,
+ 					 POLL_TIMEOUT);
+@@ -1349,7 +1394,7 @@ static int qm_set_sqc_cqc_vft(struct hisi_qm *qm, u32 fun_num, u32 base,
+ 	}
+ 
+ 	/* init default shaper qos val */
+-	if (qm->ver >= QM_HW_V3) {
++	if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) {
+ 		ret = qm_shaper_init_vft(qm, fun_num);
+ 		if (ret)
+ 			goto back_sqc_cqc;
+@@ -2495,7 +2540,7 @@ static int qm_wait_vf_prepare_finish(struct hisi_qm *qm)
+ 	u64 val;
+ 	u32 i;
+ 
+-	if (!qm->vfs_num || qm->ver < QM_HW_V3)
++	if (!qm->vfs_num || !test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
+ 		return 0;
+ 
+ 	while (true) {
+@@ -2780,10 +2825,7 @@ static const struct hisi_qm_hw_ops qm_hw_ops_v3 = {
+ 	.hw_error_init = qm_hw_error_init_v3,
+ 	.hw_error_uninit = qm_hw_error_uninit_v3,
+ 	.hw_error_handle = qm_hw_error_handle_v2,
+-	.stop_qp = qm_stop_qp,
+ 	.set_msi = qm_set_msi_v3,
+-	.ping_all_vfs = qm_ping_all_vfs,
+-	.ping_pf = qm_ping_pf,
+ };
+ 
+ static void *qm_get_avail_sqe(struct hisi_qp *qp)
+@@ -3080,8 +3122,8 @@ static int qm_drain_qp(struct hisi_qp *qp)
+ 		return 0;
+ 
+ 	/* Kunpeng930 supports drain qp by device */
+-	if (qm->ops->stop_qp) {
+-		ret = qm->ops->stop_qp(qp);
++	if (test_bit(QM_SUPPORT_STOP_QP, &qm->caps)) {
++		ret = qm_stop_qp(qp);
+ 		if (ret)
+ 			dev_err(dev, "Failed to stop qp(%u)!\n", qp->qp_id);
+ 		return ret;
+@@ -3312,7 +3354,7 @@ static int hisi_qm_uacce_mmap(struct uacce_queue *q,
+ 		if (qm->ver == QM_HW_V1) {
+ 			if (sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR)
+ 				return -EINVAL;
+-		} else if (qm->ver == QM_HW_V2 || !qm->use_db_isolation) {
++		} else if (!test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) {
+ 			if (sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR +
+ 			    QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE))
+ 				return -EINVAL;
+@@ -3466,7 +3508,7 @@ static int qm_alloc_uacce(struct hisi_qm *qm)
+ 
+ 	if (qm->ver == QM_HW_V1)
+ 		mmio_page_nr = QM_DOORBELL_PAGE_NR;
+-	else if (qm->ver == QM_HW_V2 || !qm->use_db_isolation)
++	else if (!test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps))
+ 		mmio_page_nr = QM_DOORBELL_PAGE_NR +
+ 			QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE;
+ 	else
+@@ -3628,7 +3670,7 @@ static void hisi_qm_pre_init(struct hisi_qm *qm)
+ 	init_rwsem(&qm->qps_lock);
+ 	qm->qp_in_used = 0;
+ 	qm->misc_ctl = false;
+-	if (qm->fun_type == QM_HW_PF && qm->ver > QM_HW_V2) {
++	if (test_bit(QM_SUPPORT_RPM, &qm->caps)) {
+ 		if (!acpi_device_power_manageable(ACPI_COMPANION(&pdev->dev)))
+ 			dev_info(&pdev->dev, "_PS0 and _PR0 are not defined");
+ 	}
+@@ -3638,7 +3680,7 @@ static void qm_cmd_uninit(struct hisi_qm *qm)
+ {
+ 	u32 val;
+ 
+-	if (qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
+ 		return;
+ 
+ 	val = readl(qm->io_base + QM_IFC_INT_MASK);
+@@ -3650,7 +3692,7 @@ static void qm_cmd_init(struct hisi_qm *qm)
+ {
+ 	u32 val;
+ 
+-	if (qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
+ 		return;
+ 
+ 	/* Clear communication interrupt source */
+@@ -3666,7 +3708,7 @@ static void qm_put_pci_res(struct hisi_qm *qm)
+ {
+ 	struct pci_dev *pdev = qm->pdev;
+ 
+-	if (qm->use_db_isolation)
++	if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps))
+ 		iounmap(qm->db_io_base);
+ 
+ 	iounmap(qm->io_base);
+@@ -3716,7 +3758,9 @@ static void hisi_qm_memory_uninit(struct hisi_qm *qm)
+ 	}
+ 
+ 	idr_destroy(&qm->qp_idr);
+-	kfree(qm->factor);
++
++	if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
++		kfree(qm->factor);
+ }
+ 
+ /**
+@@ -4499,12 +4543,10 @@ static int qm_vf_read_qos(struct hisi_qm *qm)
+ 	qm->mb_qos = 0;
+ 
+ 	/* vf ping pf to get function qos */
+-	if (qm->ops->ping_pf) {
+-		ret = qm->ops->ping_pf(qm, QM_VF_GET_QOS);
+-		if (ret) {
+-			pci_err(qm->pdev, "failed to send cmd to PF to get qos!\n");
+-			return ret;
+-		}
++	ret = qm_ping_pf(qm, QM_VF_GET_QOS);
++	if (ret) {
++		pci_err(qm->pdev, "failed to send cmd to PF to get qos!\n");
++		return ret;
+ 	}
+ 
+ 	while (true) {
+@@ -4583,7 +4625,7 @@ static ssize_t qm_get_qos_value(struct hisi_qm *qm, const char *buf,
+ 			       unsigned int *fun_index)
+ {
+ 	char tbuf_bdf[QM_DBG_READ_LEN] = {0};
+-	char val_buf[QM_QOS_VAL_MAX_LEN] = {0};
++	char val_buf[QM_DBG_READ_LEN] = {0};
+ 	u32 tmp1, device, function;
+ 	int ret, bus;
+ 
+@@ -4676,14 +4718,14 @@ static const struct file_operations qm_algqos_fops = {
+  * hisi_qm_set_algqos_init() - Initialize function qos debugfs files.
+  * @qm: The qm for which we want to add debugfs files.
+  *
+- * Create function qos debugfs files.
++ * Create function qos debugfs files, VF ping PF to get function qos.
+  */
+ static void hisi_qm_set_algqos_init(struct hisi_qm *qm)
+ {
+ 	if (qm->fun_type == QM_HW_PF)
+ 		debugfs_create_file("alg_qos", 0644, qm->debug.debug_root,
+ 				    qm, &qm_algqos_fops);
+-	else
++	else if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
+ 		debugfs_create_file("alg_qos", 0444, qm->debug.debug_root,
+ 				    qm, &qm_algqos_fops);
+ }
+@@ -4731,7 +4773,7 @@ void hisi_qm_debug_init(struct hisi_qm *qm)
+ 			&qm_atomic64_ops);
+ 	}
+ 
+-	if (qm->ver >= QM_HW_V3)
++	if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
+ 		hisi_qm_set_algqos_init(qm);
+ }
+ EXPORT_SYMBOL_GPL(hisi_qm_debug_init);
+@@ -4848,7 +4890,9 @@ int hisi_qm_sriov_disable(struct pci_dev *pdev, bool is_frozen)
+ 
+ 	pci_disable_sriov(pdev);
+ 	/* clear vf function shaper configure array */
+-	memset(qm->factor + 1, 0, sizeof(struct qm_shaper_factor) * total_vfs);
++	if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
++		memset(qm->factor + 1, 0, sizeof(struct qm_shaper_factor) * total_vfs);
++
+ 	ret = qm_clear_vft_config(qm);
+ 	if (ret)
+ 		return ret;
+@@ -5072,8 +5116,8 @@ static int qm_try_stop_vfs(struct hisi_qm *qm, u64 cmd,
+ 		return 0;
+ 
+ 	/* Kunpeng930 supports to notify VFs to stop before PF reset */
+-	if (qm->ops->ping_all_vfs) {
+-		ret = qm->ops->ping_all_vfs(qm, cmd);
++	if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) {
++		ret = qm_ping_all_vfs(qm, cmd);
+ 		if (ret)
+ 			pci_err(pdev, "failed to send cmd to all VFs before PF reset!\n");
+ 	} else {
+@@ -5264,8 +5308,8 @@ static int qm_try_start_vfs(struct hisi_qm *qm, enum qm_mb_cmd cmd)
+ 	}
+ 
+ 	/* Kunpeng930 supports to notify VFs to start after PF reset. */
+-	if (qm->ops->ping_all_vfs) {
+-		ret = qm->ops->ping_all_vfs(qm, cmd);
++	if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) {
++		ret = qm_ping_all_vfs(qm, cmd);
+ 		if (ret)
+ 			pci_warn(pdev, "failed to send cmd to all VFs after PF reset!\n");
+ 	} else {
+@@ -5713,7 +5757,7 @@ err_prepare:
+ 	hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET);
+ out:
+ 	pci_save_state(pdev);
+-	ret = qm->ops->ping_pf(qm, cmd);
++	ret = qm_ping_pf(qm, cmd);
+ 	if (ret)
+ 		dev_warn(&pdev->dev, "PF responds timeout in reset prepare!\n");
+ }
+@@ -5731,7 +5775,8 @@ static void qm_pf_reset_vf_done(struct hisi_qm *qm)
+ 		cmd = QM_VF_START_FAIL;
+ 	}
+ 
+-	ret = qm->ops->ping_pf(qm, cmd);
++	qm_cmd_init(qm);
++	ret = qm_ping_pf(qm, cmd);
+ 	if (ret)
+ 		dev_warn(&pdev->dev, "PF responds timeout in reset done!\n");
+ 
+@@ -5792,7 +5837,6 @@ static void qm_pf_reset_vf_process(struct hisi_qm *qm,
+ 		goto err_get_status;
+ 
+ 	qm_pf_reset_vf_done(qm);
+-	qm_cmd_init(qm);
+ 
+ 	dev_info(dev, "device reset done.\n");
+ 
+@@ -5936,7 +5980,7 @@ static int qm_get_qp_num(struct hisi_qm *qm)
+ 		qm->ctrl_qp_num = readl(qm->io_base + QM_CAPBILITY) &
+ 					QM_QP_NUN_MASK;
+ 
+-	if (qm->use_db_isolation)
++	if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps))
+ 		qm->max_qp_num = (readl(qm->io_base + QM_CAPBILITY) >>
+ 				  QM_QP_MAX_NUM_SHIFT) & QM_QP_NUN_MASK;
+ 	else
+@@ -5952,6 +5996,39 @@ static int qm_get_qp_num(struct hisi_qm *qm)
+ 	return 0;
+ }
+ 
++static void qm_get_hw_caps(struct hisi_qm *qm)
++{
++	const struct hisi_qm_cap_info *cap_info = qm->fun_type == QM_HW_PF ?
++						  qm_cap_info_pf : qm_cap_info_vf;
++	u32 size = qm->fun_type == QM_HW_PF ? ARRAY_SIZE(qm_cap_info_pf) :
++				   ARRAY_SIZE(qm_cap_info_vf);
++	u32 val, i;
++
++	/* Doorbell isolate register is a independent register. */
++	val = hisi_qm_get_hw_info(qm, qm_cap_info_comm, QM_SUPPORT_DB_ISOLATION, true);
++	if (val)
++		set_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps);
++
++	if (qm->ver >= QM_HW_V3) {
++		val = readl(qm->io_base + QM_FUNC_CAPS_REG);
++		qm->cap_ver = val & QM_CAPBILITY_VERSION;
++	}
++
++	/* Get PF/VF common capbility */
++	for (i = 1; i < ARRAY_SIZE(qm_cap_info_comm); i++) {
++		val = hisi_qm_get_hw_info(qm, qm_cap_info_comm, i, qm->cap_ver);
++		if (val)
++			set_bit(qm_cap_info_comm[i].type, &qm->caps);
++	}
++
++	/* Get PF/VF different capbility */
++	for (i = 0; i < size; i++) {
++		val = hisi_qm_get_hw_info(qm, cap_info, i, qm->cap_ver);
++		if (val)
++			set_bit(cap_info[i].type, &qm->caps);
++	}
++}
++
+ static int qm_get_pci_res(struct hisi_qm *qm)
+ {
+ 	struct pci_dev *pdev = qm->pdev;
+@@ -5971,16 +6048,8 @@ static int qm_get_pci_res(struct hisi_qm *qm)
+ 		goto err_request_mem_regions;
+ 	}
+ 
+-	if (qm->ver > QM_HW_V2) {
+-		if (qm->fun_type == QM_HW_PF)
+-			qm->use_db_isolation = readl(qm->io_base +
+-						     QM_QUE_ISO_EN) & BIT(0);
+-		else
+-			qm->use_db_isolation = readl(qm->io_base +
+-						     QM_QUE_ISO_CFG_V) & BIT(0);
+-	}
+-
+-	if (qm->use_db_isolation) {
++	qm_get_hw_caps(qm);
++	if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) {
+ 		qm->db_interval = QM_QP_DB_INTERVAL;
+ 		qm->db_phys_base = pci_resource_start(pdev, PCI_BAR_4);
+ 		qm->db_io_base = ioremap(qm->db_phys_base,
+@@ -6004,7 +6073,7 @@ static int qm_get_pci_res(struct hisi_qm *qm)
+ 	return 0;
+ 
+ err_db_ioremap:
+-	if (qm->use_db_isolation)
++	if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps))
+ 		iounmap(qm->db_io_base);
+ err_ioremap:
+ 	iounmap(qm->io_base);
+@@ -6121,12 +6190,15 @@ static int hisi_qm_memory_init(struct hisi_qm *qm)
+ 	int ret, total_func, i;
+ 	size_t off = 0;
+ 
+-	total_func = pci_sriov_get_totalvfs(qm->pdev) + 1;
+-	qm->factor = kcalloc(total_func, sizeof(struct qm_shaper_factor), GFP_KERNEL);
+-	if (!qm->factor)
+-		return -ENOMEM;
+-	for (i = 0; i < total_func; i++)
+-		qm->factor[i].func_qos = QM_QOS_MAX_VAL;
++	if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) {
++		total_func = pci_sriov_get_totalvfs(qm->pdev) + 1;
++		qm->factor = kcalloc(total_func, sizeof(struct qm_shaper_factor), GFP_KERNEL);
++		if (!qm->factor)
++			return -ENOMEM;
++
++		for (i = 0; i < total_func; i++)
++			qm->factor[i].func_qos = QM_QOS_MAX_VAL;
++	}
+ 
+ #define QM_INIT_BUF(qm, type, num) do { \
+ 	(qm)->type = ((qm)->qdma.va + (off)); \
+@@ -6143,8 +6215,8 @@ static int hisi_qm_memory_init(struct hisi_qm *qm)
+ 					 GFP_ATOMIC);
+ 	dev_dbg(dev, "allocate qm dma buf size=%zx)\n", qm->qdma.size);
+ 	if (!qm->qdma.va) {
+-		ret =  -ENOMEM;
+-		goto err_alloc_qdma;
++		ret = -ENOMEM;
++		goto err_destroy_idr;
+ 	}
+ 
+ 	QM_INIT_BUF(qm, eqe, QM_EQ_DEPTH);
+@@ -6160,8 +6232,10 @@ static int hisi_qm_memory_init(struct hisi_qm *qm)
+ 
+ err_alloc_qp_array:
+ 	dma_free_coherent(dev, qm->qdma.size, qm->qdma.va, qm->qdma.dma);
+-err_alloc_qdma:
+-	kfree(qm->factor);
++err_destroy_idr:
++	idr_destroy(&qm->qp_idr);
++	if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
++		kfree(qm->factor);
+ 
+ 	return ret;
+ }
+@@ -6304,7 +6378,7 @@ void hisi_qm_pm_init(struct hisi_qm *qm)
+ {
+ 	struct device *dev = &qm->pdev->dev;
+ 
+-	if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_RPM, &qm->caps))
+ 		return;
+ 
+ 	pm_runtime_set_autosuspend_delay(dev, QM_AUTOSUSPEND_DELAY);
+@@ -6323,7 +6397,7 @@ void hisi_qm_pm_uninit(struct hisi_qm *qm)
+ {
+ 	struct device *dev = &qm->pdev->dev;
+ 
+-	if (qm->fun_type == QM_HW_VF || qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_RPM, &qm->caps))
+ 		return;
+ 
+ 	pm_runtime_get_noresume(dev);
+diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
+index 2c0be91c0b094..1ec3b06345fd4 100644
+--- a/drivers/crypto/hisilicon/sec2/sec_main.c
++++ b/drivers/crypto/hisilicon/sec2/sec_main.c
+@@ -415,7 +415,7 @@ static void sec_open_sva_prefetch(struct hisi_qm *qm)
+ 	u32 val;
+ 	int ret;
+ 
+-	if (qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ 		return;
+ 
+ 	/* Enable prefetch */
+@@ -435,7 +435,7 @@ static void sec_close_sva_prefetch(struct hisi_qm *qm)
+ 	u32 val;
+ 	int ret;
+ 
+-	if (qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ 		return;
+ 
+ 	val = readl_relaxed(qm->io_base + SEC_PREFETCH_CFG);
+diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
+index c3303d99acac7..65ed2ae8e1319 100644
+--- a/drivers/crypto/hisilicon/zip/zip_main.c
++++ b/drivers/crypto/hisilicon/zip/zip_main.c
+@@ -348,7 +348,7 @@ static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm)
+ 	u32 val;
+ 	int ret;
+ 
+-	if (qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ 		return;
+ 
+ 	/* Enable prefetch */
+@@ -368,7 +368,7 @@ static void hisi_zip_close_sva_prefetch(struct hisi_qm *qm)
+ 	u32 val;
+ 	int ret;
+ 
+-	if (qm->ver < QM_HW_V3)
++	if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
+ 		return;
+ 
+ 	val = readl_relaxed(qm->io_base + HZIP_PREFETCH_CFG);
+diff --git a/drivers/crypto/img-hash.c b/drivers/crypto/img-hash.c
+index d8e82d69745d8..9629e98bd68b7 100644
+--- a/drivers/crypto/img-hash.c
++++ b/drivers/crypto/img-hash.c
+@@ -358,12 +358,16 @@ static int img_hash_dma_init(struct img_hash_dev *hdev)
+ static void img_hash_dma_task(unsigned long d)
+ {
+ 	struct img_hash_dev *hdev = (struct img_hash_dev *)d;
+-	struct img_hash_request_ctx *ctx = ahash_request_ctx(hdev->req);
++	struct img_hash_request_ctx *ctx;
+ 	u8 *addr;
+ 	size_t nbytes, bleft, wsend, len, tbc;
+ 	struct scatterlist tsg;
+ 
+-	if (!hdev->req || !ctx->sg)
++	if (!hdev->req)
++		return;
++
++	ctx = ahash_request_ctx(hdev->req);
++	if (!ctx->sg)
+ 		return;
+ 
+ 	addr = sg_virt(ctx->sg);
+diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
+index 655a7f5a406a1..cbeda59c6b191 100644
+--- a/drivers/crypto/omap-sham.c
++++ b/drivers/crypto/omap-sham.c
+@@ -2114,7 +2114,7 @@ static int omap_sham_probe(struct platform_device *pdev)
+ 
+ 	pm_runtime_enable(dev);
+ 
+-	err = pm_runtime_get_sync(dev);
++	err = pm_runtime_resume_and_get(dev);
+ 	if (err < 0) {
+ 		dev_err(dev, "failed to get sync: %d\n", err);
+ 		goto err_pm;
+diff --git a/drivers/crypto/qat/qat_4xxx/adf_drv.c b/drivers/crypto/qat/qat_4xxx/adf_drv.c
+index 2f212561acc47..670a58b25cb16 100644
+--- a/drivers/crypto/qat/qat_4xxx/adf_drv.c
++++ b/drivers/crypto/qat/qat_4xxx/adf_drv.c
+@@ -261,6 +261,7 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev);
+ 	if (!hw_data->accel_capabilities_mask) {
+ 		dev_err(&pdev->dev, "Failed to get capabilities mask.\n");
++		ret = -EINVAL;
+ 		goto out_err;
+ 	}
+ 
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
+index 35d73061d1569..14a0aef18ab13 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.c
++++ b/drivers/crypto/rockchip/rk3288_crypto.c
+@@ -65,186 +65,24 @@ static void rk_crypto_disable_clk(struct rk_crypto_info *dev)
+ 	clk_disable_unprepare(dev->sclk);
+ }
+ 
+-static int check_alignment(struct scatterlist *sg_src,
+-			   struct scatterlist *sg_dst,
+-			   int align_mask)
+-{
+-	int in, out, align;
+-
+-	in = IS_ALIGNED((uint32_t)sg_src->offset, 4) &&
+-	     IS_ALIGNED((uint32_t)sg_src->length, align_mask);
+-	if (!sg_dst)
+-		return in;
+-	out = IS_ALIGNED((uint32_t)sg_dst->offset, 4) &&
+-	      IS_ALIGNED((uint32_t)sg_dst->length, align_mask);
+-	align = in && out;
+-
+-	return (align && (sg_src->length == sg_dst->length));
+-}
+-
+-static int rk_load_data(struct rk_crypto_info *dev,
+-			struct scatterlist *sg_src,
+-			struct scatterlist *sg_dst)
+-{
+-	unsigned int count;
+-
+-	dev->aligned = dev->aligned ?
+-		check_alignment(sg_src, sg_dst, dev->align_size) :
+-		dev->aligned;
+-	if (dev->aligned) {
+-		count = min(dev->left_bytes, sg_src->length);
+-		dev->left_bytes -= count;
+-
+-		if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) {
+-			dev_err(dev->dev, "[%s:%d] dma_map_sg(src)  error\n",
+-				__func__, __LINE__);
+-			return -EINVAL;
+-		}
+-		dev->addr_in = sg_dma_address(sg_src);
+-
+-		if (sg_dst) {
+-			if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) {
+-				dev_err(dev->dev,
+-					"[%s:%d] dma_map_sg(dst)  error\n",
+-					__func__, __LINE__);
+-				dma_unmap_sg(dev->dev, sg_src, 1,
+-					     DMA_TO_DEVICE);
+-				return -EINVAL;
+-			}
+-			dev->addr_out = sg_dma_address(sg_dst);
+-		}
+-	} else {
+-		count = (dev->left_bytes > PAGE_SIZE) ?
+-			PAGE_SIZE : dev->left_bytes;
+-
+-		if (!sg_pcopy_to_buffer(dev->first, dev->src_nents,
+-					dev->addr_vir, count,
+-					dev->total - dev->left_bytes)) {
+-			dev_err(dev->dev, "[%s:%d] pcopy err\n",
+-				__func__, __LINE__);
+-			return -EINVAL;
+-		}
+-		dev->left_bytes -= count;
+-		sg_init_one(&dev->sg_tmp, dev->addr_vir, count);
+-		if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1, DMA_TO_DEVICE)) {
+-			dev_err(dev->dev, "[%s:%d] dma_map_sg(sg_tmp)  error\n",
+-				__func__, __LINE__);
+-			return -ENOMEM;
+-		}
+-		dev->addr_in = sg_dma_address(&dev->sg_tmp);
+-
+-		if (sg_dst) {
+-			if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1,
+-					DMA_FROM_DEVICE)) {
+-				dev_err(dev->dev,
+-					"[%s:%d] dma_map_sg(sg_tmp)  error\n",
+-					__func__, __LINE__);
+-				dma_unmap_sg(dev->dev, &dev->sg_tmp, 1,
+-					     DMA_TO_DEVICE);
+-				return -ENOMEM;
+-			}
+-			dev->addr_out = sg_dma_address(&dev->sg_tmp);
+-		}
+-	}
+-	dev->count = count;
+-	return 0;
+-}
+-
+-static void rk_unload_data(struct rk_crypto_info *dev)
+-{
+-	struct scatterlist *sg_in, *sg_out;
+-
+-	sg_in = dev->aligned ? dev->sg_src : &dev->sg_tmp;
+-	dma_unmap_sg(dev->dev, sg_in, 1, DMA_TO_DEVICE);
+-
+-	if (dev->sg_dst) {
+-		sg_out = dev->aligned ? dev->sg_dst : &dev->sg_tmp;
+-		dma_unmap_sg(dev->dev, sg_out, 1, DMA_FROM_DEVICE);
+-	}
+-}
+-
+ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id)
+ {
+ 	struct rk_crypto_info *dev  = platform_get_drvdata(dev_id);
+ 	u32 interrupt_status;
+ 
+-	spin_lock(&dev->lock);
+ 	interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS);
+ 	CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status);
+ 
++	dev->status = 1;
+ 	if (interrupt_status & 0x0a) {
+ 		dev_warn(dev->dev, "DMA Error\n");
+-		dev->err = -EFAULT;
++		dev->status = 0;
+ 	}
+-	tasklet_schedule(&dev->done_task);
++	complete(&dev->complete);
+ 
+-	spin_unlock(&dev->lock);
+ 	return IRQ_HANDLED;
+ }
+ 
+-static int rk_crypto_enqueue(struct rk_crypto_info *dev,
+-			      struct crypto_async_request *async_req)
+-{
+-	unsigned long flags;
+-	int ret;
+-
+-	spin_lock_irqsave(&dev->lock, flags);
+-	ret = crypto_enqueue_request(&dev->queue, async_req);
+-	if (dev->busy) {
+-		spin_unlock_irqrestore(&dev->lock, flags);
+-		return ret;
+-	}
+-	dev->busy = true;
+-	spin_unlock_irqrestore(&dev->lock, flags);
+-	tasklet_schedule(&dev->queue_task);
+-
+-	return ret;
+-}
+-
+-static void rk_crypto_queue_task_cb(unsigned long data)
+-{
+-	struct rk_crypto_info *dev = (struct rk_crypto_info *)data;
+-	struct crypto_async_request *async_req, *backlog;
+-	unsigned long flags;
+-	int err = 0;
+-
+-	dev->err = 0;
+-	spin_lock_irqsave(&dev->lock, flags);
+-	backlog   = crypto_get_backlog(&dev->queue);
+-	async_req = crypto_dequeue_request(&dev->queue);
+-
+-	if (!async_req) {
+-		dev->busy = false;
+-		spin_unlock_irqrestore(&dev->lock, flags);
+-		return;
+-	}
+-	spin_unlock_irqrestore(&dev->lock, flags);
+-
+-	if (backlog) {
+-		backlog->complete(backlog, -EINPROGRESS);
+-		backlog = NULL;
+-	}
+-
+-	dev->async_req = async_req;
+-	err = dev->start(dev);
+-	if (err)
+-		dev->complete(dev->async_req, err);
+-}
+-
+-static void rk_crypto_done_task_cb(unsigned long data)
+-{
+-	struct rk_crypto_info *dev = (struct rk_crypto_info *)data;
+-
+-	if (dev->err) {
+-		dev->complete(dev->async_req, dev->err);
+-		return;
+-	}
+-
+-	dev->err = dev->update(dev);
+-	if (dev->err)
+-		dev->complete(dev->async_req, dev->err);
+-}
+-
+ static struct rk_crypto_tmp *rk_cipher_algs[] = {
+ 	&rk_ecb_aes_alg,
+ 	&rk_cbc_aes_alg,
+@@ -337,8 +175,6 @@ static int rk_crypto_probe(struct platform_device *pdev)
+ 	if (err)
+ 		goto err_crypto;
+ 
+-	spin_lock_init(&crypto_info->lock);
+-
+ 	crypto_info->reg = devm_platform_ioremap_resource(pdev, 0);
+ 	if (IS_ERR(crypto_info->reg)) {
+ 		err = PTR_ERR(crypto_info->reg);
+@@ -389,18 +225,11 @@ static int rk_crypto_probe(struct platform_device *pdev)
+ 	crypto_info->dev = &pdev->dev;
+ 	platform_set_drvdata(pdev, crypto_info);
+ 
+-	tasklet_init(&crypto_info->queue_task,
+-		     rk_crypto_queue_task_cb, (unsigned long)crypto_info);
+-	tasklet_init(&crypto_info->done_task,
+-		     rk_crypto_done_task_cb, (unsigned long)crypto_info);
+-	crypto_init_queue(&crypto_info->queue, 50);
++	crypto_info->engine = crypto_engine_alloc_init(&pdev->dev, true);
++	crypto_engine_start(crypto_info->engine);
++	init_completion(&crypto_info->complete);
+ 
+-	crypto_info->enable_clk = rk_crypto_enable_clk;
+-	crypto_info->disable_clk = rk_crypto_disable_clk;
+-	crypto_info->load_data = rk_load_data;
+-	crypto_info->unload_data = rk_unload_data;
+-	crypto_info->enqueue = rk_crypto_enqueue;
+-	crypto_info->busy = false;
++	rk_crypto_enable_clk(crypto_info);
+ 
+ 	err = rk_crypto_register(crypto_info);
+ 	if (err) {
+@@ -412,9 +241,9 @@ static int rk_crypto_probe(struct platform_device *pdev)
+ 	return 0;
+ 
+ err_register_alg:
+-	tasklet_kill(&crypto_info->queue_task);
+-	tasklet_kill(&crypto_info->done_task);
++	crypto_engine_exit(crypto_info->engine);
+ err_crypto:
++	dev_err(dev, "Crypto Accelerator not successfully registered\n");
+ 	return err;
+ }
+ 
+@@ -423,8 +252,8 @@ static int rk_crypto_remove(struct platform_device *pdev)
+ 	struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev);
+ 
+ 	rk_crypto_unregister();
+-	tasklet_kill(&crypto_tmp->done_task);
+-	tasklet_kill(&crypto_tmp->queue_task);
++	rk_crypto_disable_clk(crypto_tmp);
++	crypto_engine_exit(crypto_tmp->engine);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
+index 97278c2574ff9..045e811b4af84 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto.h
++++ b/drivers/crypto/rockchip/rk3288_crypto.h
+@@ -5,9 +5,11 @@
+ #include <crypto/aes.h>
+ #include <crypto/internal/des.h>
+ #include <crypto/algapi.h>
++#include <linux/dma-mapping.h>
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
+ #include <linux/scatterlist.h>
++#include <crypto/engine.h>
+ #include <crypto/internal/hash.h>
+ #include <crypto/internal/skcipher.h>
+ 
+@@ -193,45 +195,15 @@ struct rk_crypto_info {
+ 	struct reset_control		*rst;
+ 	void __iomem			*reg;
+ 	int				irq;
+-	struct crypto_queue		queue;
+-	struct tasklet_struct		queue_task;
+-	struct tasklet_struct		done_task;
+-	struct crypto_async_request	*async_req;
+-	int 				err;
+-	/* device lock */
+-	spinlock_t			lock;
+-
+-	/* the public variable */
+-	struct scatterlist		*sg_src;
+-	struct scatterlist		*sg_dst;
+-	struct scatterlist		sg_tmp;
+-	struct scatterlist		*first;
+-	unsigned int			left_bytes;
+-	void				*addr_vir;
+-	int				aligned;
+-	int				align_size;
+-	size_t				src_nents;
+-	size_t				dst_nents;
+-	unsigned int			total;
+-	unsigned int			count;
+-	dma_addr_t			addr_in;
+-	dma_addr_t			addr_out;
+-	bool				busy;
+-	int (*start)(struct rk_crypto_info *dev);
+-	int (*update)(struct rk_crypto_info *dev);
+-	void (*complete)(struct crypto_async_request *base, int err);
+-	int (*enable_clk)(struct rk_crypto_info *dev);
+-	void (*disable_clk)(struct rk_crypto_info *dev);
+-	int (*load_data)(struct rk_crypto_info *dev,
+-			 struct scatterlist *sg_src,
+-			 struct scatterlist *sg_dst);
+-	void (*unload_data)(struct rk_crypto_info *dev);
+-	int (*enqueue)(struct rk_crypto_info *dev,
+-		       struct crypto_async_request *async_req);
++
++	struct crypto_engine *engine;
++	struct completion complete;
++	int status;
+ };
+ 
+ /* the private variable of hash */
+ struct rk_ahash_ctx {
++	struct crypto_engine_ctx enginectx;
+ 	struct rk_crypto_info		*dev;
+ 	/* for fallback */
+ 	struct crypto_ahash		*fallback_tfm;
+@@ -241,14 +213,23 @@ struct rk_ahash_ctx {
+ struct rk_ahash_rctx {
+ 	struct ahash_request		fallback_req;
+ 	u32				mode;
++	int nrsg;
+ };
+ 
+ /* the private variable of cipher */
+ struct rk_cipher_ctx {
++	struct crypto_engine_ctx enginectx;
+ 	struct rk_crypto_info		*dev;
+ 	unsigned int			keylen;
+-	u32				mode;
++	u8				key[AES_MAX_KEY_SIZE];
+ 	u8				iv[AES_BLOCK_SIZE];
++	struct crypto_skcipher *fallback_tfm;
++};
++
++struct rk_cipher_rctx {
++	u8 backup_iv[AES_BLOCK_SIZE];
++	u32				mode;
++	struct skcipher_request fallback_req;   // keep at the end
+ };
+ 
+ enum alg_type {
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+index ed03058497bc2..edd40e16a3f0a 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+@@ -9,6 +9,7 @@
+  * Some ideas are from marvell/cesa.c and s5p-sss.c driver.
+  */
+ #include <linux/device.h>
++#include <asm/unaligned.h>
+ #include "rk3288_crypto.h"
+ 
+ /*
+@@ -16,6 +17,40 @@
+  * so we put the fixed hash out when met zero message.
+  */
+ 
++static bool rk_ahash_need_fallback(struct ahash_request *req)
++{
++	struct scatterlist *sg;
++
++	sg = req->src;
++	while (sg) {
++		if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
++			return true;
++		}
++		if (sg->length % 4) {
++			return true;
++		}
++		sg = sg_next(sg);
++	}
++	return false;
++}
++
++static int rk_ahash_digest_fb(struct ahash_request *areq)
++{
++	struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
++	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++	struct rk_ahash_ctx *tfmctx = crypto_ahash_ctx(tfm);
++
++	ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
++	rctx->fallback_req.base.flags = areq->base.flags &
++					CRYPTO_TFM_REQ_MAY_SLEEP;
++
++	rctx->fallback_req.nbytes = areq->nbytes;
++	rctx->fallback_req.src = areq->src;
++	rctx->fallback_req.result = areq->result;
++
++	return crypto_ahash_digest(&rctx->fallback_req);
++}
++
+ static int zero_message_process(struct ahash_request *req)
+ {
+ 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+@@ -38,16 +73,12 @@ static int zero_message_process(struct ahash_request *req)
+ 	return 0;
+ }
+ 
+-static void rk_ahash_crypto_complete(struct crypto_async_request *base, int err)
+-{
+-	if (base->complete)
+-		base->complete(base, err);
+-}
+-
+-static void rk_ahash_reg_init(struct rk_crypto_info *dev)
++static void rk_ahash_reg_init(struct ahash_request *req)
+ {
+-	struct ahash_request *req = ahash_request_cast(dev->async_req);
+ 	struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
++	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
++	struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
++	struct rk_crypto_info *dev = tctx->dev;
+ 	int reg_status;
+ 
+ 	reg_status = CRYPTO_READ(dev, RK_CRYPTO_CTRL) |
+@@ -74,7 +105,7 @@ static void rk_ahash_reg_init(struct rk_crypto_info *dev)
+ 					  RK_CRYPTO_BYTESWAP_BRFIFO |
+ 					  RK_CRYPTO_BYTESWAP_BTFIFO);
+ 
+-	CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, dev->total);
++	CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, req->nbytes);
+ }
+ 
+ static int rk_ahash_init(struct ahash_request *req)
+@@ -167,48 +198,64 @@ static int rk_ahash_digest(struct ahash_request *req)
+ 	struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
+ 	struct rk_crypto_info *dev = tctx->dev;
+ 
++	if (rk_ahash_need_fallback(req))
++		return rk_ahash_digest_fb(req);
++
+ 	if (!req->nbytes)
+ 		return zero_message_process(req);
+-	else
+-		return dev->enqueue(dev, &req->base);
++
++	return crypto_transfer_hash_request_to_engine(dev->engine, req);
+ }
+ 
+-static void crypto_ahash_dma_start(struct rk_crypto_info *dev)
++static void crypto_ahash_dma_start(struct rk_crypto_info *dev, struct scatterlist *sg)
+ {
+-	CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, dev->addr_in);
+-	CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, (dev->count + 3) / 4);
++	CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, sg_dma_address(sg));
++	CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, sg_dma_len(sg) / 4);
+ 	CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_HASH_START |
+ 					  (RK_CRYPTO_HASH_START << 16));
+ }
+ 
+-static int rk_ahash_set_data_start(struct rk_crypto_info *dev)
++static int rk_hash_prepare(struct crypto_engine *engine, void *breq)
++{
++	struct ahash_request *areq = container_of(breq, struct ahash_request, base);
++	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++	struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
++	struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
++	int ret;
++
++	ret = dma_map_sg(tctx->dev->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
++	if (ret <= 0)
++		return -EINVAL;
++
++	rctx->nrsg = ret;
++
++	return 0;
++}
++
++static int rk_hash_unprepare(struct crypto_engine *engine, void *breq)
+ {
+-	int err;
++	struct ahash_request *areq = container_of(breq, struct ahash_request, base);
++	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++	struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
++	struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
+ 
+-	err = dev->load_data(dev, dev->sg_src, NULL);
+-	if (!err)
+-		crypto_ahash_dma_start(dev);
+-	return err;
++	dma_unmap_sg(tctx->dev->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE);
++	return 0;
+ }
+ 
+-static int rk_ahash_start(struct rk_crypto_info *dev)
++static int rk_hash_run(struct crypto_engine *engine, void *breq)
+ {
+-	struct ahash_request *req = ahash_request_cast(dev->async_req);
+-	struct crypto_ahash *tfm;
+-	struct rk_ahash_rctx *rctx;
+-
+-	dev->total = req->nbytes;
+-	dev->left_bytes = req->nbytes;
+-	dev->aligned = 0;
+-	dev->align_size = 4;
+-	dev->sg_dst = NULL;
+-	dev->sg_src = req->src;
+-	dev->first = req->src;
+-	dev->src_nents = sg_nents(req->src);
+-	rctx = ahash_request_ctx(req);
++	struct ahash_request *areq = container_of(breq, struct ahash_request, base);
++	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++	struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
++	struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
++	struct scatterlist *sg = areq->src;
++	int err = 0;
++	int i;
++	u32 v;
++
+ 	rctx->mode = 0;
+ 
+-	tfm = crypto_ahash_reqtfm(req);
+ 	switch (crypto_ahash_digestsize(tfm)) {
+ 	case SHA1_DIGEST_SIZE:
+ 		rctx->mode = RK_CRYPTO_HASH_SHA1;
+@@ -220,32 +267,26 @@ static int rk_ahash_start(struct rk_crypto_info *dev)
+ 		rctx->mode = RK_CRYPTO_HASH_MD5;
+ 		break;
+ 	default:
+-		return -EINVAL;
++		err =  -EINVAL;
++		goto theend;
+ 	}
+ 
+-	rk_ahash_reg_init(dev);
+-	return rk_ahash_set_data_start(dev);
+-}
+-
+-static int rk_ahash_crypto_rx(struct rk_crypto_info *dev)
+-{
+-	int err = 0;
+-	struct ahash_request *req = ahash_request_cast(dev->async_req);
+-	struct crypto_ahash *tfm;
+-
+-	dev->unload_data(dev);
+-	if (dev->left_bytes) {
+-		if (dev->aligned) {
+-			if (sg_is_last(dev->sg_src)) {
+-				dev_warn(dev->dev, "[%s:%d], Lack of data\n",
+-					 __func__, __LINE__);
+-				err = -ENOMEM;
+-				goto out_rx;
+-			}
+-			dev->sg_src = sg_next(dev->sg_src);
++	rk_ahash_reg_init(areq);
++
++	while (sg) {
++		reinit_completion(&tctx->dev->complete);
++		tctx->dev->status = 0;
++		crypto_ahash_dma_start(tctx->dev, sg);
++		wait_for_completion_interruptible_timeout(&tctx->dev->complete,
++							  msecs_to_jiffies(2000));
++		if (!tctx->dev->status) {
++			dev_err(tctx->dev->dev, "DMA timeout\n");
++			err = -EFAULT;
++			goto theend;
+ 		}
+-		err = rk_ahash_set_data_start(dev);
+-	} else {
++		sg = sg_next(sg);
++	}
++
+ 		/*
+ 		 * it will take some time to process date after last dma
+ 		 * transmission.
+@@ -256,18 +297,20 @@ static int rk_ahash_crypto_rx(struct rk_crypto_info *dev)
+ 		 * efficiency, and make it response quickly when dma
+ 		 * complete.
+ 		 */
+-		while (!CRYPTO_READ(dev, RK_CRYPTO_HASH_STS))
+-			udelay(10);
+-
+-		tfm = crypto_ahash_reqtfm(req);
+-		memcpy_fromio(req->result, dev->reg + RK_CRYPTO_HASH_DOUT_0,
+-			      crypto_ahash_digestsize(tfm));
+-		dev->complete(dev->async_req, 0);
+-		tasklet_schedule(&dev->queue_task);
++	while (!CRYPTO_READ(tctx->dev, RK_CRYPTO_HASH_STS))
++		udelay(10);
++
++	for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) {
++		v = readl(tctx->dev->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4);
++		put_unaligned_le32(v, areq->result + i * 4);
+ 	}
+ 
+-out_rx:
+-	return err;
++theend:
++	local_bh_disable();
++	crypto_finalize_hash_request(engine, breq, err);
++	local_bh_enable();
++
++	return 0;
+ }
+ 
+ static int rk_cra_hash_init(struct crypto_tfm *tfm)
+@@ -281,14 +324,6 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
+ 	algt = container_of(alg, struct rk_crypto_tmp, alg.hash);
+ 
+ 	tctx->dev = algt->dev;
+-	tctx->dev->addr_vir = (void *)__get_free_page(GFP_KERNEL);
+-	if (!tctx->dev->addr_vir) {
+-		dev_err(tctx->dev->dev, "failed to kmalloc for addr_vir\n");
+-		return -ENOMEM;
+-	}
+-	tctx->dev->start = rk_ahash_start;
+-	tctx->dev->update = rk_ahash_crypto_rx;
+-	tctx->dev->complete = rk_ahash_crypto_complete;
+ 
+ 	/* for fallback */
+ 	tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0,
+@@ -297,19 +332,23 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
+ 		dev_err(tctx->dev->dev, "Could not load fallback driver.\n");
+ 		return PTR_ERR(tctx->fallback_tfm);
+ 	}
++
+ 	crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
+ 				 sizeof(struct rk_ahash_rctx) +
+ 				 crypto_ahash_reqsize(tctx->fallback_tfm));
+ 
+-	return tctx->dev->enable_clk(tctx->dev);
++	tctx->enginectx.op.do_one_request = rk_hash_run;
++	tctx->enginectx.op.prepare_request = rk_hash_prepare;
++	tctx->enginectx.op.unprepare_request = rk_hash_unprepare;
++
++	return 0;
+ }
+ 
+ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
+ {
+ 	struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);
+ 
+-	free_page((unsigned long)tctx->dev->addr_vir);
+-	return tctx->dev->disable_clk(tctx->dev);
++	crypto_free_ahash(tctx->fallback_tfm);
+ }
+ 
+ struct rk_crypto_tmp rk_ahash_sha1 = {
+diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+index 5bbf0d2722e11..67a7e05d5ae31 100644
+--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
++++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+@@ -9,23 +9,77 @@
+  * Some ideas are from marvell-cesa.c and s5p-sss.c driver.
+  */
+ #include <linux/device.h>
++#include <crypto/scatterwalk.h>
+ #include "rk3288_crypto.h"
+ 
+ #define RK_CRYPTO_DEC			BIT(0)
+ 
+-static void rk_crypto_complete(struct crypto_async_request *base, int err)
++static int rk_cipher_need_fallback(struct skcipher_request *req)
+ {
+-	if (base->complete)
+-		base->complete(base, err);
++	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
++	unsigned int bs = crypto_skcipher_blocksize(tfm);
++	struct scatterlist *sgs, *sgd;
++	unsigned int stodo, dtodo, len;
++
++	if (!req->cryptlen)
++		return true;
++
++	len = req->cryptlen;
++	sgs = req->src;
++	sgd = req->dst;
++	while (sgs && sgd) {
++		if (!IS_ALIGNED(sgs->offset, sizeof(u32))) {
++			return true;
++		}
++		if (!IS_ALIGNED(sgd->offset, sizeof(u32))) {
++			return true;
++		}
++		stodo = min(len, sgs->length);
++		if (stodo % bs) {
++			return true;
++		}
++		dtodo = min(len, sgd->length);
++		if (dtodo % bs) {
++			return true;
++		}
++		if (stodo != dtodo) {
++			return true;
++		}
++		len -= stodo;
++		sgs = sg_next(sgs);
++		sgd = sg_next(sgd);
++	}
++	return false;
++}
++
++static int rk_cipher_fallback(struct skcipher_request *areq)
++{
++	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
++	struct rk_cipher_ctx *op = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq);
++	int err;
++
++	skcipher_request_set_tfm(&rctx->fallback_req, op->fallback_tfm);
++	skcipher_request_set_callback(&rctx->fallback_req, areq->base.flags,
++				      areq->base.complete, areq->base.data);
++	skcipher_request_set_crypt(&rctx->fallback_req, areq->src, areq->dst,
++				   areq->cryptlen, areq->iv);
++	if (rctx->mode & RK_CRYPTO_DEC)
++		err = crypto_skcipher_decrypt(&rctx->fallback_req);
++	else
++		err = crypto_skcipher_encrypt(&rctx->fallback_req);
++	return err;
+ }
+ 
+ static int rk_handle_req(struct rk_crypto_info *dev,
+ 			 struct skcipher_request *req)
+ {
+-	if (!IS_ALIGNED(req->cryptlen, dev->align_size))
+-		return -EINVAL;
+-	else
+-		return dev->enqueue(dev, &req->base);
++	struct crypto_engine *engine = dev->engine;
++
++	if (rk_cipher_need_fallback(req))
++		return rk_cipher_fallback(req);
++
++	return crypto_transfer_skcipher_request_to_engine(engine, req);
+ }
+ 
+ static int rk_aes_setkey(struct crypto_skcipher *cipher,
+@@ -38,8 +92,9 @@ static int rk_aes_setkey(struct crypto_skcipher *cipher,
+ 	    keylen != AES_KEYSIZE_256)
+ 		return -EINVAL;
+ 	ctx->keylen = keylen;
+-	memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen);
+-	return 0;
++	memcpy(ctx->key, key, keylen);
++
++	return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
+ }
+ 
+ static int rk_des_setkey(struct crypto_skcipher *cipher,
+@@ -53,8 +108,9 @@ static int rk_des_setkey(struct crypto_skcipher *cipher,
+ 		return err;
+ 
+ 	ctx->keylen = keylen;
+-	memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
+-	return 0;
++	memcpy(ctx->key, key, keylen);
++
++	return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
+ }
+ 
+ static int rk_tdes_setkey(struct crypto_skcipher *cipher,
+@@ -68,17 +124,19 @@ static int rk_tdes_setkey(struct crypto_skcipher *cipher,
+ 		return err;
+ 
+ 	ctx->keylen = keylen;
+-	memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
+-	return 0;
++	memcpy(ctx->key, key, keylen);
++
++	return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
+ }
+ 
+ static int rk_aes_ecb_encrypt(struct skcipher_request *req)
+ {
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_crypto_info *dev = ctx->dev;
+ 
+-	ctx->mode = RK_CRYPTO_AES_ECB_MODE;
++	rctx->mode = RK_CRYPTO_AES_ECB_MODE;
+ 	return rk_handle_req(dev, req);
+ }
+ 
+@@ -86,9 +144,10 @@ static int rk_aes_ecb_decrypt(struct skcipher_request *req)
+ {
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_crypto_info *dev = ctx->dev;
+ 
+-	ctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
++	rctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
+ 	return rk_handle_req(dev, req);
+ }
+ 
+@@ -96,9 +155,10 @@ static int rk_aes_cbc_encrypt(struct skcipher_request *req)
+ {
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_crypto_info *dev = ctx->dev;
+ 
+-	ctx->mode = RK_CRYPTO_AES_CBC_MODE;
++	rctx->mode = RK_CRYPTO_AES_CBC_MODE;
+ 	return rk_handle_req(dev, req);
+ }
+ 
+@@ -106,9 +166,10 @@ static int rk_aes_cbc_decrypt(struct skcipher_request *req)
+ {
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_crypto_info *dev = ctx->dev;
+ 
+-	ctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
++	rctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
+ 	return rk_handle_req(dev, req);
+ }
+ 
+@@ -116,9 +177,10 @@ static int rk_des_ecb_encrypt(struct skcipher_request *req)
+ {
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_crypto_info *dev = ctx->dev;
+ 
+-	ctx->mode = 0;
++	rctx->mode = 0;
+ 	return rk_handle_req(dev, req);
+ }
+ 
+@@ -126,9 +188,10 @@ static int rk_des_ecb_decrypt(struct skcipher_request *req)
+ {
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_crypto_info *dev = ctx->dev;
+ 
+-	ctx->mode = RK_CRYPTO_DEC;
++	rctx->mode = RK_CRYPTO_DEC;
+ 	return rk_handle_req(dev, req);
+ }
+ 
+@@ -136,9 +199,10 @@ static int rk_des_cbc_encrypt(struct skcipher_request *req)
+ {
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_crypto_info *dev = ctx->dev;
+ 
+-	ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
++	rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
+ 	return rk_handle_req(dev, req);
+ }
+ 
+@@ -146,9 +210,10 @@ static int rk_des_cbc_decrypt(struct skcipher_request *req)
+ {
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_crypto_info *dev = ctx->dev;
+ 
+-	ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
++	rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
+ 	return rk_handle_req(dev, req);
+ }
+ 
+@@ -156,9 +221,10 @@ static int rk_des3_ede_ecb_encrypt(struct skcipher_request *req)
+ {
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_crypto_info *dev = ctx->dev;
+ 
+-	ctx->mode = RK_CRYPTO_TDES_SELECT;
++	rctx->mode = RK_CRYPTO_TDES_SELECT;
+ 	return rk_handle_req(dev, req);
+ }
+ 
+@@ -166,9 +232,10 @@ static int rk_des3_ede_ecb_decrypt(struct skcipher_request *req)
+ {
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_crypto_info *dev = ctx->dev;
+ 
+-	ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
++	rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
+ 	return rk_handle_req(dev, req);
+ }
+ 
+@@ -176,9 +243,10 @@ static int rk_des3_ede_cbc_encrypt(struct skcipher_request *req)
+ {
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_crypto_info *dev = ctx->dev;
+ 
+-	ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
++	rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
+ 	return rk_handle_req(dev, req);
+ }
+ 
+@@ -186,43 +254,42 @@ static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req)
+ {
+ 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_crypto_info *dev = ctx->dev;
+ 
+-	ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
++	rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
+ 		    RK_CRYPTO_DEC;
+ 	return rk_handle_req(dev, req);
+ }
+ 
+-static void rk_ablk_hw_init(struct rk_crypto_info *dev)
++static void rk_ablk_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req)
+ {
+-	struct skcipher_request *req =
+-		skcipher_request_cast(dev->async_req);
+ 	struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
+ 	struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
+-	u32 ivsize, block, conf_reg = 0;
++	u32 block, conf_reg = 0;
+ 
+ 	block = crypto_tfm_alg_blocksize(tfm);
+-	ivsize = crypto_skcipher_ivsize(cipher);
+ 
+ 	if (block == DES_BLOCK_SIZE) {
+-		ctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
++		rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
+ 			     RK_CRYPTO_TDES_BYTESWAP_KEY |
+ 			     RK_CRYPTO_TDES_BYTESWAP_IV;
+-		CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, ctx->mode);
+-		memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize);
++		CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode);
++		memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen);
+ 		conf_reg = RK_CRYPTO_DESSEL;
+ 	} else {
+-		ctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
++		rctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
+ 			     RK_CRYPTO_AES_KEY_CHANGE |
+ 			     RK_CRYPTO_AES_BYTESWAP_KEY |
+ 			     RK_CRYPTO_AES_BYTESWAP_IV;
+ 		if (ctx->keylen == AES_KEYSIZE_192)
+-			ctx->mode |= RK_CRYPTO_AES_192BIT_key;
++			rctx->mode |= RK_CRYPTO_AES_192BIT_key;
+ 		else if (ctx->keylen == AES_KEYSIZE_256)
+-			ctx->mode |= RK_CRYPTO_AES_256BIT_key;
+-		CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, ctx->mode);
+-		memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize);
++			rctx->mode |= RK_CRYPTO_AES_256BIT_key;
++		CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode);
++		memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen);
+ 	}
+ 	conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
+ 		    RK_CRYPTO_BYTESWAP_BRFIFO;
+@@ -231,146 +298,138 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
+ 		     RK_CRYPTO_BCDMA_ERR_ENA | RK_CRYPTO_BCDMA_DONE_ENA);
+ }
+ 
+-static void crypto_dma_start(struct rk_crypto_info *dev)
++static void crypto_dma_start(struct rk_crypto_info *dev,
++			     struct scatterlist *sgs,
++			     struct scatterlist *sgd, unsigned int todo)
+ {
+-	CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, dev->addr_in);
+-	CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, dev->count / 4);
+-	CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, dev->addr_out);
++	CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, sg_dma_address(sgs));
++	CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, todo);
++	CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, sg_dma_address(sgd));
+ 	CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_BLOCK_START |
+ 		     _SBF(RK_CRYPTO_BLOCK_START, 16));
+ }
+ 
+-static int rk_set_data_start(struct rk_crypto_info *dev)
++static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
+ {
+-	int err;
+-	struct skcipher_request *req =
+-		skcipher_request_cast(dev->async_req);
+-	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
++	struct skcipher_request *areq = container_of(async_req, struct skcipher_request, base);
++	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+-	u32 ivsize = crypto_skcipher_ivsize(tfm);
+-	u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
+-		dev->sg_src->offset + dev->sg_src->length - ivsize;
+-
+-	/* Store the iv that need to be updated in chain mode.
+-	 * And update the IV buffer to contain the next IV for decryption mode.
+-	 */
+-	if (ctx->mode & RK_CRYPTO_DEC) {
+-		memcpy(ctx->iv, src_last_blk, ivsize);
+-		sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv,
+-				   ivsize, dev->total - ivsize);
+-	}
+-
+-	err = dev->load_data(dev, dev->sg_src, dev->sg_dst);
+-	if (!err)
+-		crypto_dma_start(dev);
+-	return err;
+-}
+-
+-static int rk_ablk_start(struct rk_crypto_info *dev)
+-{
+-	struct skcipher_request *req =
+-		skcipher_request_cast(dev->async_req);
+-	unsigned long flags;
++	struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq);
++	struct scatterlist *sgs, *sgd;
+ 	int err = 0;
++	int ivsize = crypto_skcipher_ivsize(tfm);
++	int offset;
++	u8 iv[AES_BLOCK_SIZE];
++	u8 biv[AES_BLOCK_SIZE];
++	u8 *ivtouse = areq->iv;
++	unsigned int len = areq->cryptlen;
++	unsigned int todo;
++
++	ivsize = crypto_skcipher_ivsize(tfm);
++	if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) {
++		if (rctx->mode & RK_CRYPTO_DEC) {
++			offset = areq->cryptlen - ivsize;
++			scatterwalk_map_and_copy(rctx->backup_iv, areq->src,
++						 offset, ivsize, 0);
++		}
++	}
+ 
+-	dev->left_bytes = req->cryptlen;
+-	dev->total = req->cryptlen;
+-	dev->sg_src = req->src;
+-	dev->first = req->src;
+-	dev->src_nents = sg_nents(req->src);
+-	dev->sg_dst = req->dst;
+-	dev->dst_nents = sg_nents(req->dst);
+-	dev->aligned = 1;
+-
+-	spin_lock_irqsave(&dev->lock, flags);
+-	rk_ablk_hw_init(dev);
+-	err = rk_set_data_start(dev);
+-	spin_unlock_irqrestore(&dev->lock, flags);
+-	return err;
+-}
++	sgs = areq->src;
++	sgd = areq->dst;
+ 
+-static void rk_iv_copyback(struct rk_crypto_info *dev)
+-{
+-	struct skcipher_request *req =
+-		skcipher_request_cast(dev->async_req);
+-	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+-	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+-	u32 ivsize = crypto_skcipher_ivsize(tfm);
+-
+-	/* Update the IV buffer to contain the next IV for encryption mode. */
+-	if (!(ctx->mode & RK_CRYPTO_DEC)) {
+-		if (dev->aligned) {
+-			memcpy(req->iv, sg_virt(dev->sg_dst) +
+-				dev->sg_dst->length - ivsize, ivsize);
++	while (sgs && sgd && len) {
++		if (!sgs->length) {
++			sgs = sg_next(sgs);
++			sgd = sg_next(sgd);
++			continue;
++		}
++		if (rctx->mode & RK_CRYPTO_DEC) {
++			/* we backup last block of source to be used as IV at next step */
++			offset = sgs->length - ivsize;
++			scatterwalk_map_and_copy(biv, sgs, offset, ivsize, 0);
++		}
++		if (sgs == sgd) {
++			err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
++			if (err <= 0) {
++				err = -EINVAL;
++				goto theend_iv;
++			}
++		} else {
++			err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
++			if (err <= 0) {
++				err = -EINVAL;
++				goto theend_iv;
++			}
++			err = dma_map_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
++			if (err <= 0) {
++				err = -EINVAL;
++				goto theend_sgs;
++			}
++		}
++		err = 0;
++		rk_ablk_hw_init(ctx->dev, areq);
++		if (ivsize) {
++			if (ivsize == DES_BLOCK_SIZE)
++				memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize);
++			else
++				memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize);
++		}
++		reinit_completion(&ctx->dev->complete);
++		ctx->dev->status = 0;
++
++		todo = min(sg_dma_len(sgs), len);
++		len -= todo;
++		crypto_dma_start(ctx->dev, sgs, sgd, todo / 4);
++		wait_for_completion_interruptible_timeout(&ctx->dev->complete,
++							  msecs_to_jiffies(2000));
++		if (!ctx->dev->status) {
++			dev_err(ctx->dev->dev, "DMA timeout\n");
++			err = -EFAULT;
++			goto theend;
++		}
++		if (sgs == sgd) {
++			dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
++		} else {
++			dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
++			dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
++		}
++		if (rctx->mode & RK_CRYPTO_DEC) {
++			memcpy(iv, biv, ivsize);
++			ivtouse = iv;
+ 		} else {
+-			memcpy(req->iv, dev->addr_vir +
+-				dev->count - ivsize, ivsize);
++			offset = sgd->length - ivsize;
++			scatterwalk_map_and_copy(iv, sgd, offset, ivsize, 0);
++			ivtouse = iv;
+ 		}
++		sgs = sg_next(sgs);
++		sgd = sg_next(sgd);
+ 	}
+-}
+-
+-static void rk_update_iv(struct rk_crypto_info *dev)
+-{
+-	struct skcipher_request *req =
+-		skcipher_request_cast(dev->async_req);
+-	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+-	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+-	u32 ivsize = crypto_skcipher_ivsize(tfm);
+-	u8 *new_iv = NULL;
+ 
+-	if (ctx->mode & RK_CRYPTO_DEC) {
+-		new_iv = ctx->iv;
+-	} else {
+-		new_iv = page_address(sg_page(dev->sg_dst)) +
+-			 dev->sg_dst->offset + dev->sg_dst->length - ivsize;
++	if (areq->iv && ivsize > 0) {
++		offset = areq->cryptlen - ivsize;
++		if (rctx->mode & RK_CRYPTO_DEC) {
++			memcpy(areq->iv, rctx->backup_iv, ivsize);
++			memzero_explicit(rctx->backup_iv, ivsize);
++		} else {
++			scatterwalk_map_and_copy(areq->iv, areq->dst, offset,
++						 ivsize, 0);
++		}
+ 	}
+ 
+-	if (ivsize == DES_BLOCK_SIZE)
+-		memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, new_iv, ivsize);
+-	else if (ivsize == AES_BLOCK_SIZE)
+-		memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, new_iv, ivsize);
+-}
++theend:
++	local_bh_disable();
++	crypto_finalize_skcipher_request(engine, areq, err);
++	local_bh_enable();
++	return 0;
+ 
+-/* return:
+- *	true	some err was occurred
+- *	fault	no err, continue
+- */
+-static int rk_ablk_rx(struct rk_crypto_info *dev)
+-{
+-	int err = 0;
+-	struct skcipher_request *req =
+-		skcipher_request_cast(dev->async_req);
+-
+-	dev->unload_data(dev);
+-	if (!dev->aligned) {
+-		if (!sg_pcopy_from_buffer(req->dst, dev->dst_nents,
+-					  dev->addr_vir, dev->count,
+-					  dev->total - dev->left_bytes -
+-					  dev->count)) {
+-			err = -EINVAL;
+-			goto out_rx;
+-		}
+-	}
+-	if (dev->left_bytes) {
+-		rk_update_iv(dev);
+-		if (dev->aligned) {
+-			if (sg_is_last(dev->sg_src)) {
+-				dev_err(dev->dev, "[%s:%d] Lack of data\n",
+-					__func__, __LINE__);
+-				err = -ENOMEM;
+-				goto out_rx;
+-			}
+-			dev->sg_src = sg_next(dev->sg_src);
+-			dev->sg_dst = sg_next(dev->sg_dst);
+-		}
+-		err = rk_set_data_start(dev);
++theend_sgs:
++	if (sgs == sgd) {
++		dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
+ 	} else {
+-		rk_iv_copyback(dev);
+-		/* here show the calculation is over without any err */
+-		dev->complete(dev->async_req, 0);
+-		tasklet_schedule(&dev->queue_task);
++		dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
++		dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
+ 	}
+-out_rx:
++theend_iv:
+ 	return err;
+ }
+ 
+@@ -378,26 +437,34 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
+ {
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ 	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
++	const char *name = crypto_tfm_alg_name(&tfm->base);
+ 	struct rk_crypto_tmp *algt;
+ 
+ 	algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
+ 
+ 	ctx->dev = algt->dev;
+-	ctx->dev->align_size = crypto_tfm_alg_alignmask(crypto_skcipher_tfm(tfm)) + 1;
+-	ctx->dev->start = rk_ablk_start;
+-	ctx->dev->update = rk_ablk_rx;
+-	ctx->dev->complete = rk_crypto_complete;
+-	ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL);
+ 
+-	return ctx->dev->addr_vir ? ctx->dev->enable_clk(ctx->dev) : -ENOMEM;
++	ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
++	if (IS_ERR(ctx->fallback_tfm)) {
++		dev_err(ctx->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n",
++			name, PTR_ERR(ctx->fallback_tfm));
++		return PTR_ERR(ctx->fallback_tfm);
++	}
++
++	tfm->reqsize = sizeof(struct rk_cipher_rctx) +
++		crypto_skcipher_reqsize(ctx->fallback_tfm);
++
++	ctx->enginectx.op.do_one_request = rk_cipher_run;
++
++	return 0;
+ }
+ 
+ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
+ {
+ 	struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ 
+-	free_page((unsigned long)ctx->dev->addr_vir);
+-	ctx->dev->disable_clk(ctx->dev);
++	memzero_explicit(ctx->key, ctx->keylen);
++	crypto_free_skcipher(ctx->fallback_tfm);
+ }
+ 
+ struct rk_crypto_tmp rk_ecb_aes_alg = {
+@@ -406,7 +473,7 @@ struct rk_crypto_tmp rk_ecb_aes_alg = {
+ 		.base.cra_name		= "ecb(aes)",
+ 		.base.cra_driver_name	= "ecb-aes-rk",
+ 		.base.cra_priority	= 300,
+-		.base.cra_flags		= CRYPTO_ALG_ASYNC,
++		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ 		.base.cra_blocksize	= AES_BLOCK_SIZE,
+ 		.base.cra_ctxsize	= sizeof(struct rk_cipher_ctx),
+ 		.base.cra_alignmask	= 0x0f,
+@@ -428,7 +495,7 @@ struct rk_crypto_tmp rk_cbc_aes_alg = {
+ 		.base.cra_name		= "cbc(aes)",
+ 		.base.cra_driver_name	= "cbc-aes-rk",
+ 		.base.cra_priority	= 300,
+-		.base.cra_flags		= CRYPTO_ALG_ASYNC,
++		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ 		.base.cra_blocksize	= AES_BLOCK_SIZE,
+ 		.base.cra_ctxsize	= sizeof(struct rk_cipher_ctx),
+ 		.base.cra_alignmask	= 0x0f,
+@@ -451,7 +518,7 @@ struct rk_crypto_tmp rk_ecb_des_alg = {
+ 		.base.cra_name		= "ecb(des)",
+ 		.base.cra_driver_name	= "ecb-des-rk",
+ 		.base.cra_priority	= 300,
+-		.base.cra_flags		= CRYPTO_ALG_ASYNC,
++		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ 		.base.cra_blocksize	= DES_BLOCK_SIZE,
+ 		.base.cra_ctxsize	= sizeof(struct rk_cipher_ctx),
+ 		.base.cra_alignmask	= 0x07,
+@@ -473,7 +540,7 @@ struct rk_crypto_tmp rk_cbc_des_alg = {
+ 		.base.cra_name		= "cbc(des)",
+ 		.base.cra_driver_name	= "cbc-des-rk",
+ 		.base.cra_priority	= 300,
+-		.base.cra_flags		= CRYPTO_ALG_ASYNC,
++		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ 		.base.cra_blocksize	= DES_BLOCK_SIZE,
+ 		.base.cra_ctxsize	= sizeof(struct rk_cipher_ctx),
+ 		.base.cra_alignmask	= 0x07,
+@@ -496,7 +563,7 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
+ 		.base.cra_name		= "ecb(des3_ede)",
+ 		.base.cra_driver_name	= "ecb-des3-ede-rk",
+ 		.base.cra_priority	= 300,
+-		.base.cra_flags		= CRYPTO_ALG_ASYNC,
++		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ 		.base.cra_blocksize	= DES_BLOCK_SIZE,
+ 		.base.cra_ctxsize	= sizeof(struct rk_cipher_ctx),
+ 		.base.cra_alignmask	= 0x07,
+@@ -518,7 +585,7 @@ struct rk_crypto_tmp rk_cbc_des3_ede_alg = {
+ 		.base.cra_name		= "cbc(des3_ede)",
+ 		.base.cra_driver_name	= "cbc-des3-ede-rk",
+ 		.base.cra_priority	= 300,
+-		.base.cra_flags		= CRYPTO_ALG_ASYNC,
++		.base.cra_flags		= CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ 		.base.cra_blocksize	= DES_BLOCK_SIZE,
+ 		.base.cra_ctxsize	= sizeof(struct rk_cipher_ctx),
+ 		.base.cra_alignmask	= 0x07,
+diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c
+index 0e5a5662d5a40..0a051d6568800 100644
+--- a/drivers/dio/dio.c
++++ b/drivers/dio/dio.c
+@@ -109,6 +109,12 @@ static char dio_no_name[] = { 0 };
+ 
+ #endif /* CONFIG_DIO_CONSTANTS */
+ 
++static void dio_dev_release(struct device *dev)
++{
++	struct dio_dev *ddev = container_of(dev, typeof(struct dio_dev), dev);
++	kfree(ddev);
++}
++
+ int __init dio_find(int deviceid)
+ {
+ 	/* Called to find a DIO device before the full bus scan has run.
+@@ -225,6 +231,7 @@ static int __init dio_init(void)
+ 		dev->bus = &dio_bus;
+ 		dev->dev.parent = &dio_bus.dev;
+ 		dev->dev.bus = &dio_bus_type;
++		dev->dev.release = dio_dev_release;
+ 		dev->scode = scode;
+ 		dev->resource.start = pa;
+ 		dev->resource.end = pa + DIO_SIZE(scode, va);
+@@ -252,6 +259,7 @@ static int __init dio_init(void)
+ 		if (error) {
+ 			pr_err("DIO: Error registering device %s\n",
+ 			       dev->name);
++			put_device(&dev->dev);
+ 			continue;
+ 		}
+ 		error = dio_create_sysfs_dev_files(dev);
+diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c
+index 6780761a16403..e3334762be853 100644
+--- a/drivers/dma/apple-admac.c
++++ b/drivers/dma/apple-admac.c
+@@ -20,6 +20,12 @@
+ #define NCHANNELS_MAX	64
+ #define IRQ_NOUTPUTS	4
+ 
++/*
++ * For allocation purposes we split the cache
++ * memory into blocks of fixed size (given in bytes).
++ */
++#define SRAM_BLOCK	2048
++
+ #define RING_WRITE_SLOT		GENMASK(1, 0)
+ #define RING_READ_SLOT		GENMASK(5, 4)
+ #define RING_FULL		BIT(9)
+@@ -35,6 +41,9 @@
+ #define REG_TX_STOP		0x0004
+ #define REG_RX_START		0x0008
+ #define REG_RX_STOP		0x000c
++#define REG_IMPRINT		0x0090
++#define REG_TX_SRAM_SIZE	0x0094
++#define REG_RX_SRAM_SIZE	0x0098
+ 
+ #define REG_CHAN_CTL(ch)	(0x8000 + (ch) * 0x200)
+ #define REG_CHAN_CTL_RST_RINGS	BIT(0)
+@@ -52,7 +61,9 @@
+ #define BUS_WIDTH_FRAME_2_WORDS	0x10
+ #define BUS_WIDTH_FRAME_4_WORDS	0x20
+ 
+-#define CHAN_BUFSIZE		0x8000
++#define REG_CHAN_SRAM_CARVEOUT(ch)	(0x8050 + (ch) * 0x200)
++#define CHAN_SRAM_CARVEOUT_SIZE		GENMASK(31, 16)
++#define CHAN_SRAM_CARVEOUT_BASE		GENMASK(15, 0)
+ 
+ #define REG_CHAN_FIFOCTL(ch)	(0x8054 + (ch) * 0x200)
+ #define CHAN_FIFOCTL_LIMIT	GENMASK(31, 16)
+@@ -75,6 +86,8 @@ struct admac_chan {
+ 	struct dma_chan chan;
+ 	struct tasklet_struct tasklet;
+ 
++	u32 carveout;
++
+ 	spinlock_t lock;
+ 	struct admac_tx *current_tx;
+ 	int nperiod_acks;
+@@ -91,11 +104,24 @@ struct admac_chan {
+ 	struct list_head to_free;
+ };
+ 
++struct admac_sram {
++	u32 size;
++	/*
++	 * SRAM_CARVEOUT has 16-bit fields, so the SRAM cannot be larger than
++	 * 64K and a 32-bit bitfield over 2K blocks covers it.
++	 */
++	u32 allocated;
++};
++
+ struct admac_data {
+ 	struct dma_device dma;
+ 	struct device *dev;
+ 	__iomem void *base;
+ 
++	struct mutex cache_alloc_lock;
++	struct admac_sram txcache, rxcache;
++
++	int irq;
+ 	int irq_index;
+ 	int nchannels;
+ 	struct admac_chan channels[];
+@@ -115,6 +141,60 @@ struct admac_tx {
+ 	struct list_head node;
+ };
+ 
++static int admac_alloc_sram_carveout(struct admac_data *ad,
++				     enum dma_transfer_direction dir,
++				     u32 *out)
++{
++	struct admac_sram *sram;
++	int i, ret = 0, nblocks;
++
++	if (dir == DMA_MEM_TO_DEV)
++		sram = &ad->txcache;
++	else
++		sram = &ad->rxcache;
++
++	mutex_lock(&ad->cache_alloc_lock);
++
++	nblocks = sram->size / SRAM_BLOCK;
++	for (i = 0; i < nblocks; i++)
++		if (!(sram->allocated & BIT(i)))
++			break;
++
++	if (i < nblocks) {
++		*out = FIELD_PREP(CHAN_SRAM_CARVEOUT_BASE, i * SRAM_BLOCK) |
++			FIELD_PREP(CHAN_SRAM_CARVEOUT_SIZE, SRAM_BLOCK);
++		sram->allocated |= BIT(i);
++	} else {
++		ret = -EBUSY;
++	}
++
++	mutex_unlock(&ad->cache_alloc_lock);
++
++	return ret;
++}
++
++static void admac_free_sram_carveout(struct admac_data *ad,
++				     enum dma_transfer_direction dir,
++				     u32 carveout)
++{
++	struct admac_sram *sram;
++	u32 base = FIELD_GET(CHAN_SRAM_CARVEOUT_BASE, carveout);
++	int i;
++
++	if (dir == DMA_MEM_TO_DEV)
++		sram = &ad->txcache;
++	else
++		sram = &ad->rxcache;
++
++	if (WARN_ON(base >= sram->size))
++		return;
++
++	mutex_lock(&ad->cache_alloc_lock);
++	i = base / SRAM_BLOCK;
++	sram->allocated &= ~BIT(i);
++	mutex_unlock(&ad->cache_alloc_lock);
++}
++
+ static void admac_modify(struct admac_data *ad, int reg, u32 mask, u32 val)
+ {
+ 	void __iomem *addr = ad->base + reg;
+@@ -463,15 +543,28 @@ static void admac_synchronize(struct dma_chan *chan)
+ static int admac_alloc_chan_resources(struct dma_chan *chan)
+ {
+ 	struct admac_chan *adchan = to_admac_chan(chan);
++	struct admac_data *ad = adchan->host;
++	int ret;
+ 
+ 	dma_cookie_init(&adchan->chan);
++	ret = admac_alloc_sram_carveout(ad, admac_chan_direction(adchan->no),
++					&adchan->carveout);
++	if (ret < 0)
++		return ret;
++
++	writel_relaxed(adchan->carveout,
++		       ad->base + REG_CHAN_SRAM_CARVEOUT(adchan->no));
+ 	return 0;
+ }
+ 
+ static void admac_free_chan_resources(struct dma_chan *chan)
+ {
++	struct admac_chan *adchan = to_admac_chan(chan);
++
+ 	admac_terminate_all(chan);
+ 	admac_synchronize(chan);
++	admac_free_sram_carveout(adchan->host, admac_chan_direction(adchan->no),
++				 adchan->carveout);
+ }
+ 
+ static struct dma_chan *admac_dma_of_xlate(struct of_phandle_args *dma_spec,
+@@ -709,6 +802,7 @@ static int admac_probe(struct platform_device *pdev)
+ 	platform_set_drvdata(pdev, ad);
+ 	ad->dev = &pdev->dev;
+ 	ad->nchannels = nchannels;
++	mutex_init(&ad->cache_alloc_lock);
+ 
+ 	/*
+ 	 * The controller has 4 IRQ outputs. Try them all until
+@@ -724,12 +818,7 @@ static int admac_probe(struct platform_device *pdev)
+ 
+ 	if (irq < 0)
+ 		return dev_err_probe(&pdev->dev, irq, "no usable interrupt\n");
+-
+-	err = devm_request_irq(&pdev->dev, irq, admac_interrupt,
+-			       0, dev_name(&pdev->dev), ad);
+-	if (err)
+-		return dev_err_probe(&pdev->dev, err,
+-				     "unable to register interrupt\n");
++	ad->irq = irq;
+ 
+ 	ad->base = devm_platform_ioremap_resource(pdev, 0);
+ 	if (IS_ERR(ad->base))
+@@ -774,17 +863,36 @@ static int admac_probe(struct platform_device *pdev)
+ 		tasklet_setup(&adchan->tasklet, admac_chan_tasklet);
+ 	}
+ 
+-	err = dma_async_device_register(&ad->dma);
++	err = request_irq(irq, admac_interrupt, 0, dev_name(&pdev->dev), ad);
+ 	if (err)
+-		return dev_err_probe(&pdev->dev, err, "failed to register DMA device\n");
++		return dev_err_probe(&pdev->dev, err,
++				     "unable to register interrupt\n");
++
++	err = dma_async_device_register(&ad->dma);
++	if (err) {
++		dev_err_probe(&pdev->dev, err, "failed to register DMA device\n");
++		goto free_irq;
++	}
+ 
+ 	err = of_dma_controller_register(pdev->dev.of_node, admac_dma_of_xlate, ad);
+ 	if (err) {
+ 		dma_async_device_unregister(&ad->dma);
+-		return dev_err_probe(&pdev->dev, err, "failed to register with OF\n");
++		dev_err_probe(&pdev->dev, err, "failed to register with OF\n");
++		goto free_irq;
+ 	}
+ 
++	ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE);
++	ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE);
++
++	dev_info(&pdev->dev, "Audio DMA Controller\n");
++	dev_info(&pdev->dev, "imprint %x TX cache %u RX cache %u\n",
++		 readl_relaxed(ad->base + REG_IMPRINT), ad->txcache.size, ad->rxcache.size);
++
+ 	return 0;
++
++free_irq:
++	free_irq(ad->irq, ad);
++	return err;
+ }
+ 
+ static int admac_remove(struct platform_device *pdev)
+@@ -793,6 +901,7 @@ static int admac_remove(struct platform_device *pdev)
+ 
+ 	of_dma_controller_free(pdev->dev.of_node);
+ 	dma_async_device_unregister(&ad->dma);
++	free_irq(ad->irq, ad);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c
+index 6cf50ee0b77c5..e0af60833d28c 100644
+--- a/drivers/edac/i10nm_base.c
++++ b/drivers/edac/i10nm_base.c
+@@ -198,11 +198,10 @@ static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus,
+ 	if (unlikely(pci_enable_device(pdev) < 0)) {
+ 		edac_dbg(2, "Failed to enable device %02x:%02x.%x\n",
+ 			 bus, dev, fun);
++		pci_dev_put(pdev);
+ 		return NULL;
+ 	}
+ 
+-	pci_dev_get(pdev);
+-
+ 	return pdev;
+ }
+ 
+diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
+index dca7cecb37e34..290186e44e6bd 100644
+--- a/drivers/extcon/Kconfig
++++ b/drivers/extcon/Kconfig
+@@ -183,7 +183,7 @@ config EXTCON_USBC_CROS_EC
+ 
+ config EXTCON_USBC_TUSB320
+ 	tristate "TI TUSB320 USB-C extcon support"
+-	depends on I2C
++	depends on I2C && TYPEC
+ 	select REGMAP_I2C
+ 	help
+ 	  Say Y here to enable support for USB Type C cable detection extcon
+diff --git a/drivers/extcon/extcon-usbc-tusb320.c b/drivers/extcon/extcon-usbc-tusb320.c
+index 6ba3d89b106d0..7223c4b9dc707 100644
+--- a/drivers/extcon/extcon-usbc-tusb320.c
++++ b/drivers/extcon/extcon-usbc-tusb320.c
+@@ -6,6 +6,7 @@
+  * Author: Michael Auchter <michael.auchter@ni.com>
+  */
+ 
++#include <linux/bitfield.h>
+ #include <linux/extcon-provider.h>
+ #include <linux/i2c.h>
+ #include <linux/init.h>
+@@ -13,6 +14,24 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/regmap.h>
++#include <linux/usb/typec.h>
++
++#define TUSB320_REG8				0x8
++#define TUSB320_REG8_CURRENT_MODE_ADVERTISE	GENMASK(7, 6)
++#define TUSB320_REG8_CURRENT_MODE_ADVERTISE_USB	0x0
++#define TUSB320_REG8_CURRENT_MODE_ADVERTISE_15A	0x1
++#define TUSB320_REG8_CURRENT_MODE_ADVERTISE_30A	0x2
++#define TUSB320_REG8_CURRENT_MODE_DETECT	GENMASK(5, 4)
++#define TUSB320_REG8_CURRENT_MODE_DETECT_DEF	0x0
++#define TUSB320_REG8_CURRENT_MODE_DETECT_MED	0x1
++#define TUSB320_REG8_CURRENT_MODE_DETECT_ACC	0x2
++#define TUSB320_REG8_CURRENT_MODE_DETECT_HI	0x3
++#define TUSB320_REG8_ACCESSORY_CONNECTED	GENMASK(3, 2)
++#define TUSB320_REG8_ACCESSORY_CONNECTED_NONE	0x0
++#define TUSB320_REG8_ACCESSORY_CONNECTED_AUDIO	0x4
++#define TUSB320_REG8_ACCESSORY_CONNECTED_ACC	0x5
++#define TUSB320_REG8_ACCESSORY_CONNECTED_DEBUG	0x6
++#define TUSB320_REG8_ACTIVE_CABLE_DETECTION	BIT(0)
+ 
+ #define TUSB320_REG9				0x9
+ #define TUSB320_REG9_ATTACHED_STATE_SHIFT	6
+@@ -55,6 +74,10 @@ struct tusb320_priv {
+ 	struct extcon_dev *edev;
+ 	struct tusb320_ops *ops;
+ 	enum tusb320_attached_state state;
++	struct typec_port *port;
++	struct typec_capability	cap;
++	enum typec_port_type port_type;
++	enum typec_pwr_opmode pwr_opmode;
+ };
+ 
+ static const char * const tusb_attached_states[] = {
+@@ -184,19 +207,47 @@ static struct tusb320_ops tusb320l_ops = {
+ 	.get_revision = tusb320l_get_revision,
+ };
+ 
+-static irqreturn_t tusb320_irq_handler(int irq, void *dev_id)
++static int tusb320_set_adv_pwr_mode(struct tusb320_priv *priv)
+ {
+-	struct tusb320_priv *priv = dev_id;
+-	int state, polarity;
+-	unsigned reg;
++	u8 mode;
++
++	if (priv->pwr_opmode == TYPEC_PWR_MODE_USB)
++		mode = TUSB320_REG8_CURRENT_MODE_ADVERTISE_USB;
++	else if (priv->pwr_opmode == TYPEC_PWR_MODE_1_5A)
++		mode = TUSB320_REG8_CURRENT_MODE_ADVERTISE_15A;
++	else if (priv->pwr_opmode == TYPEC_PWR_MODE_3_0A)
++		mode = TUSB320_REG8_CURRENT_MODE_ADVERTISE_30A;
++	else	/* No other mode is supported. */
++		return -EINVAL;
+ 
+-	if (regmap_read(priv->regmap, TUSB320_REG9, &reg)) {
+-		dev_err(priv->dev, "error during i2c read!\n");
+-		return IRQ_NONE;
+-	}
++	return regmap_write_bits(priv->regmap, TUSB320_REG8,
++				 TUSB320_REG8_CURRENT_MODE_ADVERTISE,
++				 FIELD_PREP(TUSB320_REG8_CURRENT_MODE_ADVERTISE,
++					    mode));
++}
+ 
+-	if (!(reg & TUSB320_REG9_INTERRUPT_STATUS))
+-		return IRQ_NONE;
++static int tusb320_port_type_set(struct typec_port *port,
++				 enum typec_port_type type)
++{
++	struct tusb320_priv *priv = typec_get_drvdata(port);
++
++	if (type == TYPEC_PORT_SRC)
++		return priv->ops->set_mode(priv, TUSB320_MODE_DFP);
++	else if (type == TYPEC_PORT_SNK)
++		return priv->ops->set_mode(priv, TUSB320_MODE_UFP);
++	else if (type == TYPEC_PORT_DRP)
++		return priv->ops->set_mode(priv, TUSB320_MODE_DRP);
++	else
++		return priv->ops->set_mode(priv, TUSB320_MODE_PORT);
++}
++
++static const struct typec_operations tusb320_typec_ops = {
++	.port_type_set	= tusb320_port_type_set,
++};
++
++static void tusb320_extcon_irq_handler(struct tusb320_priv *priv, u8 reg)
++{
++	int state, polarity;
+ 
+ 	state = (reg >> TUSB320_REG9_ATTACHED_STATE_SHIFT) &
+ 		TUSB320_REG9_ATTACHED_STATE_MASK;
+@@ -219,19 +270,166 @@ static irqreturn_t tusb320_irq_handler(int irq, void *dev_id)
+ 	extcon_sync(priv->edev, EXTCON_USB_HOST);
+ 
+ 	priv->state = state;
++}
++
++static void tusb320_typec_irq_handler(struct tusb320_priv *priv, u8 reg9)
++{
++	struct typec_port *port = priv->port;
++	struct device *dev = priv->dev;
++	u8 mode, role, state;
++	int ret, reg8;
++	bool ori;
++
++	ori = reg9 & TUSB320_REG9_CABLE_DIRECTION;
++	typec_set_orientation(port, ori ? TYPEC_ORIENTATION_REVERSE :
++					  TYPEC_ORIENTATION_NORMAL);
++
++	state = (reg9 >> TUSB320_REG9_ATTACHED_STATE_SHIFT) &
++		TUSB320_REG9_ATTACHED_STATE_MASK;
++	if (state == TUSB320_ATTACHED_STATE_DFP)
++		role = TYPEC_SOURCE;
++	else
++		role = TYPEC_SINK;
++
++	typec_set_vconn_role(port, role);
++	typec_set_pwr_role(port, role);
++	typec_set_data_role(port, role == TYPEC_SOURCE ?
++				  TYPEC_HOST : TYPEC_DEVICE);
++
++	ret = regmap_read(priv->regmap, TUSB320_REG8, &reg8);
++	if (ret) {
++		dev_err(dev, "error during reg8 i2c read, ret=%d!\n", ret);
++		return;
++	}
++
++	mode = FIELD_GET(TUSB320_REG8_CURRENT_MODE_DETECT, reg8);
++	if (mode == TUSB320_REG8_CURRENT_MODE_DETECT_DEF)
++		typec_set_pwr_opmode(port, TYPEC_PWR_MODE_USB);
++	else if (mode == TUSB320_REG8_CURRENT_MODE_DETECT_MED)
++		typec_set_pwr_opmode(port, TYPEC_PWR_MODE_1_5A);
++	else if (mode == TUSB320_REG8_CURRENT_MODE_DETECT_HI)
++		typec_set_pwr_opmode(port, TYPEC_PWR_MODE_3_0A);
++	else	/* Charge through accessory */
++		typec_set_pwr_opmode(port, TYPEC_PWR_MODE_USB);
++}
++
++static irqreturn_t tusb320_state_update_handler(struct tusb320_priv *priv,
++						bool force_update)
++{
++	unsigned int reg;
++
++	if (regmap_read(priv->regmap, TUSB320_REG9, &reg)) {
++		dev_err(priv->dev, "error during i2c read!\n");
++		return IRQ_NONE;
++	}
++
++	if (!force_update && !(reg & TUSB320_REG9_INTERRUPT_STATUS))
++		return IRQ_NONE;
++
++	tusb320_extcon_irq_handler(priv, reg);
++
++	/*
++	 * Type-C support is optional. Only call the Type-C handler if a
++	 * port had been registered previously.
++	 */
++	if (priv->port)
++		tusb320_typec_irq_handler(priv, reg);
+ 
+ 	regmap_write(priv->regmap, TUSB320_REG9, reg);
+ 
+ 	return IRQ_HANDLED;
+ }
+ 
++static irqreturn_t tusb320_irq_handler(int irq, void *dev_id)
++{
++	struct tusb320_priv *priv = dev_id;
++
++	return tusb320_state_update_handler(priv, false);
++}
++
+ static const struct regmap_config tusb320_regmap_config = {
+ 	.reg_bits = 8,
+ 	.val_bits = 8,
+ };
+ 
+-static int tusb320_extcon_probe(struct i2c_client *client,
+-				const struct i2c_device_id *id)
++static int tusb320_extcon_probe(struct tusb320_priv *priv)
++{
++	int ret;
++
++	priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable);
++	if (IS_ERR(priv->edev)) {
++		dev_err(priv->dev, "failed to allocate extcon device\n");
++		return PTR_ERR(priv->edev);
++	}
++
++	ret = devm_extcon_dev_register(priv->dev, priv->edev);
++	if (ret < 0) {
++		dev_err(priv->dev, "failed to register extcon device\n");
++		return ret;
++	}
++
++	extcon_set_property_capability(priv->edev, EXTCON_USB,
++				       EXTCON_PROP_USB_TYPEC_POLARITY);
++	extcon_set_property_capability(priv->edev, EXTCON_USB_HOST,
++				       EXTCON_PROP_USB_TYPEC_POLARITY);
++
++	return 0;
++}
++
++static int tusb320_typec_probe(struct i2c_client *client,
++			       struct tusb320_priv *priv)
++{
++	struct fwnode_handle *connector;
++	const char *cap_str;
++	int ret;
++
++	/* The Type-C connector is optional, for backward compatibility. */
++	connector = device_get_named_child_node(&client->dev, "connector");
++	if (!connector)
++		return 0;
++
++	/* Type-C connector found. */
++	ret = typec_get_fw_cap(&priv->cap, connector);
++	if (ret)
++		return ret;
++
++	priv->port_type = priv->cap.type;
++
++	/* This goes into register 0x8 field CURRENT_MODE_ADVERTISE */
++	ret = fwnode_property_read_string(connector, "typec-power-opmode", &cap_str);
++	if (ret)
++		return ret;
++
++	ret = typec_find_pwr_opmode(cap_str);
++	if (ret < 0)
++		return ret;
++	if (ret == TYPEC_PWR_MODE_PD)
++		return -EINVAL;
++
++	priv->pwr_opmode = ret;
++
++	/* Initialize the hardware with the devicetree settings. */
++	ret = tusb320_set_adv_pwr_mode(priv);
++	if (ret)
++		return ret;
++
++	priv->cap.revision		= USB_TYPEC_REV_1_1;
++	priv->cap.accessory[0]		= TYPEC_ACCESSORY_AUDIO;
++	priv->cap.accessory[1]		= TYPEC_ACCESSORY_DEBUG;
++	priv->cap.orientation_aware	= true;
++	priv->cap.driver_data		= priv;
++	priv->cap.ops			= &tusb320_typec_ops;
++	priv->cap.fwnode		= connector;
++
++	priv->port = typec_register_port(&client->dev, &priv->cap);
++	if (IS_ERR(priv->port))
++		return PTR_ERR(priv->port);
++
++	return 0;
++}
++
++static int tusb320_probe(struct i2c_client *client,
++			 const struct i2c_device_id *id)
+ {
+ 	struct tusb320_priv *priv;
+ 	const void *match_data;
+@@ -257,12 +455,6 @@ static int tusb320_extcon_probe(struct i2c_client *client,
+ 
+ 	priv->ops = (struct tusb320_ops*)match_data;
+ 
+-	priv->edev = devm_extcon_dev_allocate(priv->dev, tusb320_extcon_cable);
+-	if (IS_ERR(priv->edev)) {
+-		dev_err(priv->dev, "failed to allocate extcon device\n");
+-		return PTR_ERR(priv->edev);
+-	}
+-
+ 	if (priv->ops->get_revision) {
+ 		ret = priv->ops->get_revision(priv, &revision);
+ 		if (ret)
+@@ -272,19 +464,16 @@ static int tusb320_extcon_probe(struct i2c_client *client,
+ 			dev_info(priv->dev, "chip revision %d\n", revision);
+ 	}
+ 
+-	ret = devm_extcon_dev_register(priv->dev, priv->edev);
+-	if (ret < 0) {
+-		dev_err(priv->dev, "failed to register extcon device\n");
++	ret = tusb320_extcon_probe(priv);
++	if (ret)
+ 		return ret;
+-	}
+ 
+-	extcon_set_property_capability(priv->edev, EXTCON_USB,
+-				       EXTCON_PROP_USB_TYPEC_POLARITY);
+-	extcon_set_property_capability(priv->edev, EXTCON_USB_HOST,
+-				       EXTCON_PROP_USB_TYPEC_POLARITY);
++	ret = tusb320_typec_probe(client, priv);
++	if (ret)
++		return ret;
+ 
+ 	/* update initial state */
+-	tusb320_irq_handler(client->irq, priv);
++	tusb320_state_update_handler(priv, true);
+ 
+ 	/* Reset chip to its default state */
+ 	ret = tusb320_reset(priv);
+@@ -295,7 +484,7 @@ static int tusb320_extcon_probe(struct i2c_client *client,
+ 		 * State and polarity might change after a reset, so update
+ 		 * them again and make sure the interrupt status bit is cleared.
+ 		 */
+-		tusb320_irq_handler(client->irq, priv);
++		tusb320_state_update_handler(priv, true);
+ 
+ 	ret = devm_request_threaded_irq(priv->dev, client->irq, NULL,
+ 					tusb320_irq_handler,
+@@ -313,7 +502,7 @@ static const struct of_device_id tusb320_extcon_dt_match[] = {
+ MODULE_DEVICE_TABLE(of, tusb320_extcon_dt_match);
+ 
+ static struct i2c_driver tusb320_extcon_driver = {
+-	.probe		= tusb320_extcon_probe,
++	.probe		= tusb320_probe,
+ 	.driver		= {
+ 		.name	= "extcon-tusb320",
+ 		.of_match_table = tusb320_extcon_dt_match,
+diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
+index 4b8978b254f9a..dba315f675bc7 100644
+--- a/drivers/firmware/raspberrypi.c
++++ b/drivers/firmware/raspberrypi.c
+@@ -272,6 +272,7 @@ static int rpi_firmware_probe(struct platform_device *pdev)
+ 		int ret = PTR_ERR(fw->chan);
+ 		if (ret != -EPROBE_DEFER)
+ 			dev_err(dev, "Failed to get mbox channel: %d\n", ret);
++		kfree(fw);
+ 		return ret;
+ 	}
+ 
+diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
+index ebc32bbd9b833..6281e7153b475 100644
+--- a/drivers/firmware/ti_sci.c
++++ b/drivers/firmware/ti_sci.c
+@@ -429,15 +429,14 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info,
+ 		 * during noirq phase, so we must manually poll the completion.
+ 		 */
+ 		ret = read_poll_timeout_atomic(try_wait_for_completion, done_state,
+-					       true, 1,
++					       done_state, 1,
+ 					       info->desc->max_rx_timeout_ms * 1000,
+ 					       false, &xfer->done);
+ 	}
+ 
+-	if (ret == -ETIMEDOUT || !done_state) {
++	if (ret == -ETIMEDOUT)
+ 		dev_err(dev, "Mbox timedout in resp(caller: %pS)\n",
+ 			(void *)_RET_IP_);
+-	}
+ 
+ 	/*
+ 	 * NOTE: we might prefer not to need the mailbox ticker to manage the
+diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
+index 92f185575e941..12e068dc60bc2 100644
+--- a/drivers/gpio/gpiolib-cdev.c
++++ b/drivers/gpio/gpiolib-cdev.c
+@@ -55,6 +55,50 @@ static_assert(IS_ALIGNED(sizeof(struct gpio_v2_line_values), 8));
+  * interface to gpiolib GPIOs via ioctl()s.
+  */
+ 
++typedef __poll_t (*poll_fn)(struct file *, struct poll_table_struct *);
++typedef long (*ioctl_fn)(struct file *, unsigned int, unsigned long);
++typedef ssize_t (*read_fn)(struct file *, char __user *,
++			   size_t count, loff_t *);
++
++static __poll_t call_poll_locked(struct file *file,
++				 struct poll_table_struct *wait,
++				 struct gpio_device *gdev, poll_fn func)
++{
++	__poll_t ret;
++
++	down_read(&gdev->sem);
++	ret = func(file, wait);
++	up_read(&gdev->sem);
++
++	return ret;
++}
++
++static long call_ioctl_locked(struct file *file, unsigned int cmd,
++			      unsigned long arg, struct gpio_device *gdev,
++			      ioctl_fn func)
++{
++	long ret;
++
++	down_read(&gdev->sem);
++	ret = func(file, cmd, arg);
++	up_read(&gdev->sem);
++
++	return ret;
++}
++
++static ssize_t call_read_locked(struct file *file, char __user *buf,
++				size_t count, loff_t *f_ps,
++				struct gpio_device *gdev, read_fn func)
++{
++	ssize_t ret;
++
++	down_read(&gdev->sem);
++	ret = func(file, buf, count, f_ps);
++	up_read(&gdev->sem);
++
++	return ret;
++}
++
+ /*
+  * GPIO line handle management
+  */
+@@ -191,8 +235,8 @@ static long linehandle_set_config(struct linehandle_state *lh,
+ 	return 0;
+ }
+ 
+-static long linehandle_ioctl(struct file *file, unsigned int cmd,
+-			     unsigned long arg)
++static long linehandle_ioctl_unlocked(struct file *file, unsigned int cmd,
++				      unsigned long arg)
+ {
+ 	struct linehandle_state *lh = file->private_data;
+ 	void __user *ip = (void __user *)arg;
+@@ -201,6 +245,9 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,
+ 	unsigned int i;
+ 	int ret;
+ 
++	if (!lh->gdev->chip)
++		return -ENODEV;
++
+ 	switch (cmd) {
+ 	case GPIOHANDLE_GET_LINE_VALUES_IOCTL:
+ 		/* NOTE: It's okay to read values of output lines */
+@@ -247,6 +294,15 @@ static long linehandle_ioctl(struct file *file, unsigned int cmd,
+ 	}
+ }
+ 
++static long linehandle_ioctl(struct file *file, unsigned int cmd,
++			     unsigned long arg)
++{
++	struct linehandle_state *lh = file->private_data;
++
++	return call_ioctl_locked(file, cmd, arg, lh->gdev,
++				 linehandle_ioctl_unlocked);
++}
++
+ #ifdef CONFIG_COMPAT
+ static long linehandle_ioctl_compat(struct file *file, unsigned int cmd,
+ 				    unsigned long arg)
+@@ -1378,12 +1434,15 @@ static long linereq_set_config(struct linereq *lr, void __user *ip)
+ 	return ret;
+ }
+ 
+-static long linereq_ioctl(struct file *file, unsigned int cmd,
+-			  unsigned long arg)
++static long linereq_ioctl_unlocked(struct file *file, unsigned int cmd,
++				   unsigned long arg)
+ {
+ 	struct linereq *lr = file->private_data;
+ 	void __user *ip = (void __user *)arg;
+ 
++	if (!lr->gdev->chip)
++		return -ENODEV;
++
+ 	switch (cmd) {
+ 	case GPIO_V2_LINE_GET_VALUES_IOCTL:
+ 		return linereq_get_values(lr, ip);
+@@ -1396,6 +1455,15 @@ static long linereq_ioctl(struct file *file, unsigned int cmd,
+ 	}
+ }
+ 
++static long linereq_ioctl(struct file *file, unsigned int cmd,
++			  unsigned long arg)
++{
++	struct linereq *lr = file->private_data;
++
++	return call_ioctl_locked(file, cmd, arg, lr->gdev,
++				 linereq_ioctl_unlocked);
++}
++
+ #ifdef CONFIG_COMPAT
+ static long linereq_ioctl_compat(struct file *file, unsigned int cmd,
+ 				 unsigned long arg)
+@@ -1404,12 +1472,15 @@ static long linereq_ioctl_compat(struct file *file, unsigned int cmd,
+ }
+ #endif
+ 
+-static __poll_t linereq_poll(struct file *file,
+-			    struct poll_table_struct *wait)
++static __poll_t linereq_poll_unlocked(struct file *file,
++				      struct poll_table_struct *wait)
+ {
+ 	struct linereq *lr = file->private_data;
+ 	__poll_t events = 0;
+ 
++	if (!lr->gdev->chip)
++		return EPOLLHUP | EPOLLERR;
++
+ 	poll_wait(file, &lr->wait, wait);
+ 
+ 	if (!kfifo_is_empty_spinlocked_noirqsave(&lr->events,
+@@ -1419,16 +1490,25 @@ static __poll_t linereq_poll(struct file *file,
+ 	return events;
+ }
+ 
+-static ssize_t linereq_read(struct file *file,
+-			    char __user *buf,
+-			    size_t count,
+-			    loff_t *f_ps)
++static __poll_t linereq_poll(struct file *file,
++			     struct poll_table_struct *wait)
++{
++	struct linereq *lr = file->private_data;
++
++	return call_poll_locked(file, wait, lr->gdev, linereq_poll_unlocked);
++}
++
++static ssize_t linereq_read_unlocked(struct file *file, char __user *buf,
++				     size_t count, loff_t *f_ps)
+ {
+ 	struct linereq *lr = file->private_data;
+ 	struct gpio_v2_line_event le;
+ 	ssize_t bytes_read = 0;
+ 	int ret;
+ 
++	if (!lr->gdev->chip)
++		return -ENODEV;
++
+ 	if (count < sizeof(le))
+ 		return -EINVAL;
+ 
+@@ -1473,6 +1553,15 @@ static ssize_t linereq_read(struct file *file,
+ 	return bytes_read;
+ }
+ 
++static ssize_t linereq_read(struct file *file, char __user *buf,
++			    size_t count, loff_t *f_ps)
++{
++	struct linereq *lr = file->private_data;
++
++	return call_read_locked(file, buf, count, f_ps, lr->gdev,
++				linereq_read_unlocked);
++}
++
+ static void linereq_free(struct linereq *lr)
+ {
+ 	unsigned int i;
+@@ -1692,12 +1781,15 @@ struct lineevent_state {
+ 	(GPIOEVENT_REQUEST_RISING_EDGE | \
+ 	GPIOEVENT_REQUEST_FALLING_EDGE)
+ 
+-static __poll_t lineevent_poll(struct file *file,
+-			       struct poll_table_struct *wait)
++static __poll_t lineevent_poll_unlocked(struct file *file,
++					struct poll_table_struct *wait)
+ {
+ 	struct lineevent_state *le = file->private_data;
+ 	__poll_t events = 0;
+ 
++	if (!le->gdev->chip)
++		return EPOLLHUP | EPOLLERR;
++
+ 	poll_wait(file, &le->wait, wait);
+ 
+ 	if (!kfifo_is_empty_spinlocked_noirqsave(&le->events, &le->wait.lock))
+@@ -1706,15 +1798,21 @@ static __poll_t lineevent_poll(struct file *file,
+ 	return events;
+ }
+ 
++static __poll_t lineevent_poll(struct file *file,
++			       struct poll_table_struct *wait)
++{
++	struct lineevent_state *le = file->private_data;
++
++	return call_poll_locked(file, wait, le->gdev, lineevent_poll_unlocked);
++}
++
+ struct compat_gpioeevent_data {
+ 	compat_u64	timestamp;
+ 	u32		id;
+ };
+ 
+-static ssize_t lineevent_read(struct file *file,
+-			      char __user *buf,
+-			      size_t count,
+-			      loff_t *f_ps)
++static ssize_t lineevent_read_unlocked(struct file *file, char __user *buf,
++				       size_t count, loff_t *f_ps)
+ {
+ 	struct lineevent_state *le = file->private_data;
+ 	struct gpioevent_data ge;
+@@ -1722,6 +1820,9 @@ static ssize_t lineevent_read(struct file *file,
+ 	ssize_t ge_size;
+ 	int ret;
+ 
++	if (!le->gdev->chip)
++		return -ENODEV;
++
+ 	/*
+ 	 * When compatible system call is being used the struct gpioevent_data,
+ 	 * in case of at least ia32, has different size due to the alignment
+@@ -1779,6 +1880,15 @@ static ssize_t lineevent_read(struct file *file,
+ 	return bytes_read;
+ }
+ 
++static ssize_t lineevent_read(struct file *file, char __user *buf,
++			      size_t count, loff_t *f_ps)
++{
++	struct lineevent_state *le = file->private_data;
++
++	return call_read_locked(file, buf, count, f_ps, le->gdev,
++				lineevent_read_unlocked);
++}
++
+ static void lineevent_free(struct lineevent_state *le)
+ {
+ 	if (le->irq)
+@@ -1796,13 +1906,16 @@ static int lineevent_release(struct inode *inode, struct file *file)
+ 	return 0;
+ }
+ 
+-static long lineevent_ioctl(struct file *file, unsigned int cmd,
+-			    unsigned long arg)
++static long lineevent_ioctl_unlocked(struct file *file, unsigned int cmd,
++				     unsigned long arg)
+ {
+ 	struct lineevent_state *le = file->private_data;
+ 	void __user *ip = (void __user *)arg;
+ 	struct gpiohandle_data ghd;
+ 
++	if (!le->gdev->chip)
++		return -ENODEV;
++
+ 	/*
+ 	 * We can get the value for an event line but not set it,
+ 	 * because it is input by definition.
+@@ -1825,6 +1938,15 @@ static long lineevent_ioctl(struct file *file, unsigned int cmd,
+ 	return -EINVAL;
+ }
+ 
++static long lineevent_ioctl(struct file *file, unsigned int cmd,
++			    unsigned long arg)
++{
++	struct lineevent_state *le = file->private_data;
++
++	return call_ioctl_locked(file, cmd, arg, le->gdev,
++				 lineevent_ioctl_unlocked);
++}
++
+ #ifdef CONFIG_COMPAT
+ static long lineevent_ioctl_compat(struct file *file, unsigned int cmd,
+ 				   unsigned long arg)
+@@ -2383,12 +2505,15 @@ static int lineinfo_changed_notify(struct notifier_block *nb,
+ 	return NOTIFY_OK;
+ }
+ 
+-static __poll_t lineinfo_watch_poll(struct file *file,
+-				    struct poll_table_struct *pollt)
++static __poll_t lineinfo_watch_poll_unlocked(struct file *file,
++					     struct poll_table_struct *pollt)
+ {
+ 	struct gpio_chardev_data *cdev = file->private_data;
+ 	__poll_t events = 0;
+ 
++	if (!cdev->gdev->chip)
++		return EPOLLHUP | EPOLLERR;
++
+ 	poll_wait(file, &cdev->wait, pollt);
+ 
+ 	if (!kfifo_is_empty_spinlocked_noirqsave(&cdev->events,
+@@ -2398,8 +2523,17 @@ static __poll_t lineinfo_watch_poll(struct file *file,
+ 	return events;
+ }
+ 
+-static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
+-				   size_t count, loff_t *off)
++static __poll_t lineinfo_watch_poll(struct file *file,
++				    struct poll_table_struct *pollt)
++{
++	struct gpio_chardev_data *cdev = file->private_data;
++
++	return call_poll_locked(file, pollt, cdev->gdev,
++				lineinfo_watch_poll_unlocked);
++}
++
++static ssize_t lineinfo_watch_read_unlocked(struct file *file, char __user *buf,
++					    size_t count, loff_t *off)
+ {
+ 	struct gpio_chardev_data *cdev = file->private_data;
+ 	struct gpio_v2_line_info_changed event;
+@@ -2407,6 +2541,9 @@ static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
+ 	int ret;
+ 	size_t event_size;
+ 
++	if (!cdev->gdev->chip)
++		return -ENODEV;
++
+ #ifndef CONFIG_GPIO_CDEV_V1
+ 	event_size = sizeof(struct gpio_v2_line_info_changed);
+ 	if (count < event_size)
+@@ -2474,6 +2611,15 @@ static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
+ 	return bytes_read;
+ }
+ 
++static ssize_t lineinfo_watch_read(struct file *file, char __user *buf,
++				   size_t count, loff_t *off)
++{
++	struct gpio_chardev_data *cdev = file->private_data;
++
++	return call_read_locked(file, buf, count, off, cdev->gdev,
++				lineinfo_watch_read_unlocked);
++}
++
+ /**
+  * gpio_chrdev_open() - open the chardev for ioctl operations
+  * @inode: inode for this chardev
+@@ -2487,13 +2633,17 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file)
+ 	struct gpio_chardev_data *cdev;
+ 	int ret = -ENOMEM;
+ 
++	down_read(&gdev->sem);
++
+ 	/* Fail on open if the backing gpiochip is gone */
+-	if (!gdev->chip)
+-		return -ENODEV;
++	if (!gdev->chip) {
++		ret = -ENODEV;
++		goto out_unlock;
++	}
+ 
+ 	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
+ 	if (!cdev)
+-		return -ENOMEM;
++		goto out_unlock;
+ 
+ 	cdev->watched_lines = bitmap_zalloc(gdev->chip->ngpio, GFP_KERNEL);
+ 	if (!cdev->watched_lines)
+@@ -2516,6 +2666,8 @@ static int gpio_chrdev_open(struct inode *inode, struct file *file)
+ 	if (ret)
+ 		goto out_unregister_notifier;
+ 
++	up_read(&gdev->sem);
++
+ 	return ret;
+ 
+ out_unregister_notifier:
+@@ -2525,6 +2677,8 @@ out_free_bitmap:
+ 	bitmap_free(cdev->watched_lines);
+ out_free_cdev:
+ 	kfree(cdev);
++out_unlock:
++	up_read(&gdev->sem);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index eb7d00608c7fb..2adca7c2dd5c8 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -735,6 +735,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
+ 	spin_unlock_irqrestore(&gpio_lock, flags);
+ 
+ 	BLOCKING_INIT_NOTIFIER_HEAD(&gdev->notifier);
++	init_rwsem(&gdev->sem);
+ 
+ #ifdef CONFIG_PINCTRL
+ 	INIT_LIST_HEAD(&gdev->pin_ranges);
+@@ -875,6 +876,8 @@ void gpiochip_remove(struct gpio_chip *gc)
+ 	unsigned long	flags;
+ 	unsigned int	i;
+ 
++	down_write(&gdev->sem);
++
+ 	/* FIXME: should the legacy sysfs handling be moved to gpio_device? */
+ 	gpiochip_sysfs_unregister(gdev);
+ 	gpiochip_free_hogs(gc);
+@@ -909,6 +912,7 @@ void gpiochip_remove(struct gpio_chip *gc)
+ 	 * gone.
+ 	 */
+ 	gcdev_unregister(gdev);
++	up_write(&gdev->sem);
+ 	put_device(&gdev->dev);
+ }
+ EXPORT_SYMBOL_GPL(gpiochip_remove);
+diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
+index d900ecdbac46d..9ad68a0adf4a8 100644
+--- a/drivers/gpio/gpiolib.h
++++ b/drivers/gpio/gpiolib.h
+@@ -15,6 +15,7 @@
+ #include <linux/device.h>
+ #include <linux/module.h>
+ #include <linux/cdev.h>
++#include <linux/rwsem.h>
+ 
+ #define GPIOCHIP_NAME	"gpiochip"
+ 
+@@ -39,6 +40,9 @@
+  * @list: links gpio_device:s together for traversal
+  * @notifier: used to notify subscribers about lines being requested, released
+  *            or reconfigured
++ * @sem: protects the structure from a NULL-pointer dereference of @chip by
++ *       user-space operations when the device gets unregistered during
++ *       a hot-unplug event
+  * @pin_ranges: range of pins served by the GPIO driver
+  *
+  * This state container holds most of the runtime variable data
+@@ -60,6 +64,7 @@ struct gpio_device {
+ 	void			*data;
+ 	struct list_head        list;
+ 	struct blocking_notifier_head notifier;
++	struct rw_semaphore	sem;
+ 
+ #ifdef CONFIG_PINCTRL
+ 	/*
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 5e184952ec988..6659630303a38 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -2253,7 +2253,7 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct amdgpu_device *adev,
+ 
+ 	ret = drm_vma_node_allow(&obj->vma_node, drm_priv);
+ 	if (ret) {
+-		kfree(mem);
++		kfree(*mem);
+ 		return ret;
+ 	}
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+index e363f56c72af1..30c28a69e847d 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+@@ -317,6 +317,7 @@ static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev)
+ 
+ 	if (!found)
+ 		return false;
++	pci_dev_put(pdev);
+ 
+ 	adev->bios = kmalloc(size, GFP_KERNEL);
+ 	if (!adev->bios) {
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index e0c960cc1d2e1..f04e698e631c5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -5004,6 +5004,8 @@ static void amdgpu_device_resume_display_audio(struct amdgpu_device *adev)
+ 		pm_runtime_enable(&(p->dev));
+ 		pm_runtime_resume(&(p->dev));
+ 	}
++
++	pci_dev_put(p);
+ }
+ 
+ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
+@@ -5042,6 +5044,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
+ 
+ 		if (expires < ktime_get_mono_fast_ns()) {
+ 			dev_warn(adev->dev, "failed to suspend display audio\n");
++			pci_dev_put(p);
+ 			/* TODO: abort the succeeding gpu reset? */
+ 			return -ETIMEDOUT;
+ 		}
+@@ -5049,6 +5052,7 @@ static int amdgpu_device_suspend_display_audio(struct amdgpu_device *adev)
+ 
+ 	pm_runtime_disable(&(p->dev));
+ 
++	pci_dev_put(p);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+index 617d072275ebe..77210fd64a2bc 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+@@ -75,6 +75,8 @@ struct amdgpu_vf_error_buffer {
+ 	uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE];
+ };
+ 
++enum idh_request;
++
+ /**
+  * struct amdgpu_virt_ops - amdgpu device virt operations
+  */
+@@ -84,7 +86,8 @@ struct amdgpu_virt_ops {
+ 	int (*req_init_data)(struct amdgpu_device *adev);
+ 	int (*reset_gpu)(struct amdgpu_device *adev);
+ 	int (*wait_reset)(struct amdgpu_device *adev);
+-	void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3);
++	void (*trans_msg)(struct amdgpu_device *adev, enum idh_request req,
++			  u32 data1, u32 data2, u32 data3);
+ };
+ 
+ /*
+diff --git a/drivers/gpu/drm/amd/amdgpu/nv.c b/drivers/gpu/drm/amd/amdgpu/nv.c
+index b3fba8dea63ca..6853b93ac82e7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/nv.c
++++ b/drivers/gpu/drm/amd/amdgpu/nv.c
+@@ -82,10 +82,10 @@ static const struct amdgpu_video_codecs nv_video_codecs_encode =
+ /* Navi1x */
+ static const struct amdgpu_video_codec_info nv_video_codecs_decode_array[] =
+ {
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+@@ -100,10 +100,10 @@ static const struct amdgpu_video_codecs nv_video_codecs_decode =
+ /* Sienna Cichlid */
+ static const struct amdgpu_video_codec_info sc_video_codecs_decode_array[] =
+ {
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+@@ -125,10 +125,10 @@ static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] =
+ 
+ static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array[] =
+ {
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+@@ -149,7 +149,7 @@ static struct amdgpu_video_codecs sriov_sc_video_codecs_decode =
+ 
+ /* Beige Goby*/
+ static const struct amdgpu_video_codec_info bg_video_codecs_decode_array[] = {
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+ };
+@@ -166,7 +166,7 @@ static const struct amdgpu_video_codecs bg_video_codecs_encode = {
+ 
+ /* Yellow Carp*/
+ static const struct amdgpu_video_codec_info yc_video_codecs_decode_array[] = {
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
+index e3b2b6b4f1a66..7cd17dda32ceb 100644
+--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
+@@ -103,10 +103,10 @@ static const struct amdgpu_video_codecs vega_video_codecs_encode =
+ /* Vega */
+ static const struct amdgpu_video_codec_info vega_video_codecs_decode_array[] =
+ {
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ };
+@@ -120,10 +120,10 @@ static const struct amdgpu_video_codecs vega_video_codecs_decode =
+ /* Raven */
+ static const struct amdgpu_video_codec_info rv_video_codecs_decode_array[] =
+ {
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 4096, 4096, 0)},
+@@ -138,10 +138,10 @@ static const struct amdgpu_video_codecs rv_video_codecs_decode =
+ /* Renoir, Arcturus */
+ static const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] =
+ {
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4906, 3)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4906, 5)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4906, 4)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c
+index 9c3463b481396..6d21c975b73d1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/soc21.c
++++ b/drivers/gpu/drm/amd/amdgpu/soc21.c
+@@ -61,7 +61,7 @@ static const struct amdgpu_video_codecs vcn_4_0_0_video_codecs_encode =
+ 
+ static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_decode_array[] =
+ {
+-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4906, 52)},
++	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
+ 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+index a0154a5f71832..e2d3027c39936 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+@@ -41,39 +41,6 @@
+ #include "dm_helpers.h"
+ #include "ddc_service_types.h"
+ 
+-struct monitor_patch_info {
+-	unsigned int manufacturer_id;
+-	unsigned int product_id;
+-	void (*patch_func)(struct dc_edid_caps *edid_caps, unsigned int param);
+-	unsigned int patch_param;
+-};
+-static void set_max_dsc_bpp_limit(struct dc_edid_caps *edid_caps, unsigned int param);
+-
+-static const struct monitor_patch_info monitor_patch_table[] = {
+-{0x6D1E, 0x5BBF, set_max_dsc_bpp_limit, 15},
+-{0x6D1E, 0x5B9A, set_max_dsc_bpp_limit, 15},
+-};
+-
+-static void set_max_dsc_bpp_limit(struct dc_edid_caps *edid_caps, unsigned int param)
+-{
+-	if (edid_caps)
+-		edid_caps->panel_patch.max_dsc_target_bpp_limit = param;
+-}
+-
+-static int amdgpu_dm_patch_edid_caps(struct dc_edid_caps *edid_caps)
+-{
+-	int i, ret = 0;
+-
+-	for (i = 0; i < ARRAY_SIZE(monitor_patch_table); i++)
+-		if ((edid_caps->manufacturer_id == monitor_patch_table[i].manufacturer_id)
+-			&&  (edid_caps->product_id == monitor_patch_table[i].product_id)) {
+-			monitor_patch_table[i].patch_func(edid_caps, monitor_patch_table[i].patch_param);
+-			ret++;
+-		}
+-
+-	return ret;
+-}
+-
+ /* dm_helpers_parse_edid_caps
+  *
+  * Parse edid caps
+@@ -148,8 +115,6 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
+ 	kfree(sads);
+ 	kfree(sadb);
+ 
+-	amdgpu_dm_patch_edid_caps(edid_caps);
+-
+ 	return result;
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+index de3a1f3fd4f1a..c98cd7c5b9f7a 100644
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+@@ -487,6 +487,7 @@ static enum bp_result get_gpio_i2c_info(
+ 	uint32_t count = 0;
+ 	unsigned int table_index = 0;
+ 	bool find_valid = false;
++	struct atom_gpio_pin_assignment *pin;
+ 
+ 	if (!info)
+ 		return BP_RESULT_BADINPUT;
+@@ -514,20 +515,17 @@ static enum bp_result get_gpio_i2c_info(
+ 			- sizeof(struct atom_common_table_header))
+ 				/ sizeof(struct atom_gpio_pin_assignment);
+ 
++	pin = (struct atom_gpio_pin_assignment *) header->gpio_pin;
++
+ 	for (table_index = 0; table_index < count; table_index++) {
+-		if (((record->i2c_id & I2C_HW_CAP) == (
+-		header->gpio_pin[table_index].gpio_id &
+-						I2C_HW_CAP)) &&
+-		((record->i2c_id & I2C_HW_ENGINE_ID_MASK)  ==
+-		(header->gpio_pin[table_index].gpio_id &
+-					I2C_HW_ENGINE_ID_MASK)) &&
+-		((record->i2c_id & I2C_HW_LANE_MUX) ==
+-		(header->gpio_pin[table_index].gpio_id &
+-						I2C_HW_LANE_MUX))) {
++		if (((record->i2c_id & I2C_HW_CAP) 				== (pin->gpio_id & I2C_HW_CAP)) &&
++		    ((record->i2c_id & I2C_HW_ENGINE_ID_MASK)	== (pin->gpio_id & I2C_HW_ENGINE_ID_MASK)) &&
++		    ((record->i2c_id & I2C_HW_LANE_MUX) 		== (pin->gpio_id & I2C_HW_LANE_MUX))) {
+ 			/* still valid */
+ 			find_valid = true;
+ 			break;
+ 		}
++		pin = (struct atom_gpio_pin_assignment *)((uint8_t *)pin + sizeof(struct atom_gpio_pin_assignment));
+ 	}
+ 
+ 	/* If we don't find the entry that we are looking for then
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
+index e7f1d5f8166f9..59a29c32f66a8 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
+@@ -436,7 +436,7 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
+ 	}
+ 
+ 	if (!new_clocks->dtbclk_en) {
+-		new_clocks->ref_dtbclk_khz = 0;
++		new_clocks->ref_dtbclk_khz = clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz * 1000;
+ 	}
+ 
+ 	/* clock limits are received with MHz precision, divide by 1000 to prevent setting clocks at every call */
+diff --git a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
+index fc6aa098bda06..8db9f75144662 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce60/dce60_resource.c
+@@ -1128,6 +1128,7 @@ struct resource_pool *dce60_create_resource_pool(
+ 	if (dce60_construct(num_virtual_links, dc, pool))
+ 		return &pool->base;
+ 
++	kfree(pool);
+ 	BREAK_TO_DEBUGGER();
+ 	return NULL;
+ }
+@@ -1325,6 +1326,7 @@ struct resource_pool *dce61_create_resource_pool(
+ 	if (dce61_construct(num_virtual_links, dc, pool))
+ 		return &pool->base;
+ 
++	kfree(pool);
+ 	BREAK_TO_DEBUGGER();
+ 	return NULL;
+ }
+@@ -1518,6 +1520,7 @@ struct resource_pool *dce64_create_resource_pool(
+ 	if (dce64_construct(num_virtual_links, dc, pool))
+ 		return &pool->base;
+ 
++	kfree(pool);
+ 	BREAK_TO_DEBUGGER();
+ 	return NULL;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+index b28025960050c..5825e6f412bd7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
+@@ -1137,6 +1137,7 @@ struct resource_pool *dce80_create_resource_pool(
+ 	if (dce80_construct(num_virtual_links, dc, pool))
+ 		return &pool->base;
+ 
++	kfree(pool);
+ 	BREAK_TO_DEBUGGER();
+ 	return NULL;
+ }
+@@ -1336,6 +1337,7 @@ struct resource_pool *dce81_create_resource_pool(
+ 	if (dce81_construct(num_virtual_links, dc, pool))
+ 		return &pool->base;
+ 
++	kfree(pool);
+ 	BREAK_TO_DEBUGGER();
+ 	return NULL;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+index bc9b92838ea9f..d7757e7900ba7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -867,6 +867,32 @@ static void false_optc_underflow_wa(
+ 		tg->funcs->clear_optc_underflow(tg);
+ }
+ 
++static int calculate_vready_offset_for_group(struct pipe_ctx *pipe)
++{
++	struct pipe_ctx *other_pipe;
++	int vready_offset = pipe->pipe_dlg_param.vready_offset;
++
++	/* Always use the largest vready_offset of all connected pipes */
++	for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) {
++		if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++			vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++	}
++	for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) {
++		if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++			vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++	}
++	for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) {
++		if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++			vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++	}
++	for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) {
++		if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++			vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++	}
++
++	return vready_offset;
++}
++
+ enum dc_status dcn10_enable_stream_timing(
+ 		struct pipe_ctx *pipe_ctx,
+ 		struct dc_state *context,
+@@ -902,7 +928,7 @@ enum dc_status dcn10_enable_stream_timing(
+ 	pipe_ctx->stream_res.tg->funcs->program_timing(
+ 			pipe_ctx->stream_res.tg,
+ 			&stream->timing,
+-			pipe_ctx->pipe_dlg_param.vready_offset,
++			calculate_vready_offset_for_group(pipe_ctx),
+ 			pipe_ctx->pipe_dlg_param.vstartup_start,
+ 			pipe_ctx->pipe_dlg_param.vupdate_offset,
+ 			pipe_ctx->pipe_dlg_param.vupdate_width,
+@@ -2869,7 +2895,7 @@ void dcn10_program_pipe(
+ 
+ 		pipe_ctx->stream_res.tg->funcs->program_global_sync(
+ 				pipe_ctx->stream_res.tg,
+-				pipe_ctx->pipe_dlg_param.vready_offset,
++				calculate_vready_offset_for_group(pipe_ctx),
+ 				pipe_ctx->pipe_dlg_param.vstartup_start,
+ 				pipe_ctx->pipe_dlg_param.vupdate_offset,
+ 				pipe_ctx->pipe_dlg_param.vupdate_width);
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+index 0f30df523fdf5..cd799ce6e48b8 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+@@ -1608,6 +1608,31 @@ static void dcn20_update_dchubp_dpp(
+ 		hubp->funcs->phantom_hubp_post_enable(hubp);
+ }
+ 
++static int calculate_vready_offset_for_group(struct pipe_ctx *pipe)
++{
++	struct pipe_ctx *other_pipe;
++	int vready_offset = pipe->pipe_dlg_param.vready_offset;
++
++	/* Always use the largest vready_offset of all connected pipes */
++	for (other_pipe = pipe->bottom_pipe; other_pipe != NULL; other_pipe = other_pipe->bottom_pipe) {
++		if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++			vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++	}
++	for (other_pipe = pipe->top_pipe; other_pipe != NULL; other_pipe = other_pipe->top_pipe) {
++		if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++			vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++	}
++	for (other_pipe = pipe->next_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->next_odm_pipe) {
++		if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++			vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++	}
++	for (other_pipe = pipe->prev_odm_pipe; other_pipe != NULL; other_pipe = other_pipe->prev_odm_pipe) {
++		if (other_pipe->pipe_dlg_param.vready_offset > vready_offset)
++			vready_offset = other_pipe->pipe_dlg_param.vready_offset;
++	}
++
++	return vready_offset;
++}
+ 
+ static void dcn20_program_pipe(
+ 		struct dc *dc,
+@@ -1626,16 +1651,14 @@ static void dcn20_program_pipe(
+ 			&& !pipe_ctx->prev_odm_pipe) {
+ 		pipe_ctx->stream_res.tg->funcs->program_global_sync(
+ 				pipe_ctx->stream_res.tg,
+-				pipe_ctx->pipe_dlg_param.vready_offset,
++				calculate_vready_offset_for_group(pipe_ctx),
+ 				pipe_ctx->pipe_dlg_param.vstartup_start,
+ 				pipe_ctx->pipe_dlg_param.vupdate_offset,
+ 				pipe_ctx->pipe_dlg_param.vupdate_width);
+ 
+ 		if (pipe_ctx->stream->mall_stream_config.type != SUBVP_PHANTOM) {
+-			pipe_ctx->stream_res.tg->funcs->wait_for_state(
+-				pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
+-			pipe_ctx->stream_res.tg->funcs->wait_for_state(
+-				pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
++			pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
++			pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
+ 		}
+ 
+ 		pipe_ctx->stream_res.tg->funcs->set_vtg_params(
+@@ -2040,7 +2063,7 @@ bool dcn20_update_bandwidth(
+ 
+ 			pipe_ctx->stream_res.tg->funcs->program_global_sync(
+ 					pipe_ctx->stream_res.tg,
+-					pipe_ctx->pipe_dlg_param.vready_offset,
++					calculate_vready_offset_for_group(pipe_ctx),
+ 					pipe_ctx->pipe_dlg_param.vstartup_start,
+ 					pipe_ctx->pipe_dlg_param.vupdate_offset,
+ 					pipe_ctx->pipe_dlg_param.vupdate_width);
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
+index 6dd8dadd68a5d..6f160f65c8fa9 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
+@@ -225,11 +225,7 @@ void dccg32_set_dtbclk_dto(
+ 	} else {
+ 		REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+ 				DTBCLK_DTO_ENABLE[params->otg_inst], 0,
+-				PIPE_DTO_SRC_SEL[params->otg_inst], 1);
+-		if (params->is_hdmi)
+-			REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+-				PIPE_DTO_SRC_SEL[params->otg_inst], 0);
+-
++				PIPE_DTO_SRC_SEL[params->otg_inst], params->is_hdmi ? 0 : 1);
+ 		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
+ 		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
+ 	}
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+index 07c56e231b045..d05df4f7139fd 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+@@ -485,9 +485,11 @@ void dcn32_set_phantom_stream_timing(struct dc *dc,
+ 	unsigned int i, pipe_idx;
+ 	struct pipe_ctx *pipe;
+ 	uint32_t phantom_vactive, phantom_bp, pstate_width_fw_delay_lines;
++	unsigned int num_dpp;
+ 	unsigned int vlevel = context->bw_ctx.dml.vba.VoltageLevel;
+ 	unsigned int dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
+ 	unsigned int socclk = context->bw_ctx.dml.vba.SOCCLKPerState[vlevel];
++	struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
+ 
+ 	dc_assert_fp_enabled();
+ 
+@@ -523,6 +525,11 @@ void dcn32_set_phantom_stream_timing(struct dc *dc,
+ 	phantom_vactive = get_subviewport_lines_needed_in_mall(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx) +
+ 				pstate_width_fw_delay_lines + dc->caps.subvp_swath_height_margin_lines;
+ 
++	// W/A for DCC corruption with certain high resolution timings.
++	// Determing if pipesplit is used. If so, add meta_row_height to the phantom vactive.
++	num_dpp = vba->NoOfDPP[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]];
++	phantom_vactive += num_dpp > 1 ? vba->meta_row_height[vba->pipe_plane[pipe_idx]] : 0;
++
+ 	// For backporch of phantom pipe, use vstartup of the main pipe
+ 	phantom_bp = get_vstartup(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
+ 
+diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+index 7e3231c2191ca..ffe19883b2ee9 100644
+--- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h
++++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h
+@@ -354,7 +354,8 @@ struct amd_pm_funcs {
+ 	int (*get_power_profile_mode)(void *handle, char *buf);
+ 	int (*set_power_profile_mode)(void *handle, long *input, uint32_t size);
+ 	int (*set_fine_grain_clk_vol)(void *handle, uint32_t type, long *input, uint32_t size);
+-	int (*odn_edit_dpm_table)(void *handle, uint32_t type, long *input, uint32_t size);
++	int (*odn_edit_dpm_table)(void *handle, enum PP_OD_DPM_TABLE_COMMAND type,
++				  long *input, uint32_t size);
+ 	int (*set_mp1_state)(void *handle, enum pp_mp1_state mp1_state);
+ 	int (*smu_i2c_bus_access)(void *handle, bool acquire);
+ 	int (*gfx_state_change_set)(void *handle, uint32_t state);
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
+index 1eb4e613b27a5..6562978de84a0 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
+@@ -838,7 +838,8 @@ static int pp_set_fine_grain_clk_vol(void *handle, uint32_t type, long *input, u
+ 	return hwmgr->hwmgr_func->set_fine_grain_clk_vol(hwmgr, type, input, size);
+ }
+ 
+-static int pp_odn_edit_dpm_table(void *handle, uint32_t type, long *input, uint32_t size)
++static int pp_odn_edit_dpm_table(void *handle, enum PP_OD_DPM_TABLE_COMMAND type,
++				 long *input, uint32_t size)
+ {
+ 	struct pp_hwmgr *hwmgr = handle;
+ 
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c
+index 67d7da0b6fed5..1d829402cd2e2 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c
+@@ -75,8 +75,10 @@ int psm_init_power_state_table(struct pp_hwmgr *hwmgr)
+ 	for (i = 0; i < table_entries; i++) {
+ 		result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state);
+ 		if (result) {
++			kfree(hwmgr->current_ps);
+ 			kfree(hwmgr->request_ps);
+ 			kfree(hwmgr->ps);
++			hwmgr->current_ps = NULL;
+ 			hwmgr->request_ps = NULL;
+ 			hwmgr->ps = NULL;
+ 			return -EINVAL;
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
+index 97b3ad3690467..b30684c84e20e 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
+@@ -2961,7 +2961,8 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
+ 			data->od8_settings.od8_settings_array;
+ 	OverDriveTable_t *od_table =
+ 			&(data->smc_state_table.overdrive_table);
+-	int32_t input_index, input_clk, input_vol, i;
++	int32_t input_clk, input_vol, i;
++	uint32_t input_index;
+ 	int od8_id;
+ 	int ret;
+ 
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+index 70b560737687e..ad5f6a15a1d7d 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+@@ -1588,6 +1588,10 @@ bool smu_v11_0_baco_is_support(struct smu_context *smu)
+ 	if (amdgpu_sriov_vf(smu->adev) || !smu_baco->platform_support)
+ 		return false;
+ 
++	/* return true if ASIC is in BACO state already */
++	if (smu_v11_0_baco_get_state(smu) == SMU_BACO_STATE_ENTER)
++		return true;
++
+ 	/* Arcturus does not support this bit mask */
+ 	if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) &&
+ 	   !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT))
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+index d74debc584f89..39deb06a86ba3 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+@@ -1436,7 +1436,7 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
+ 
+ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf)
+ {
+-	DpmActivityMonitorCoeffIntExternal_t activity_monitor_external[PP_SMC_POWER_PROFILE_COUNT];
++	DpmActivityMonitorCoeffIntExternal_t *activity_monitor_external;
+ 	uint32_t i, j, size = 0;
+ 	int16_t workload_type = 0;
+ 	int result = 0;
+@@ -1444,6 +1444,12 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf
+ 	if (!buf)
+ 		return -EINVAL;
+ 
++	activity_monitor_external = kcalloc(PP_SMC_POWER_PROFILE_COUNT,
++					    sizeof(*activity_monitor_external),
++					    GFP_KERNEL);
++	if (!activity_monitor_external)
++		return -ENOMEM;
++
+ 	size += sysfs_emit_at(buf, size, "                              ");
+ 	for (i = 0; i <= PP_SMC_POWER_PROFILE_WINDOW3D; i++)
+ 		size += sysfs_emit_at(buf, size, "%-14s%s", amdgpu_pp_profile_name[i],
+@@ -1456,15 +1462,17 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf
+ 		workload_type = smu_cmn_to_asic_specific_index(smu,
+ 							       CMN2ASIC_MAPPING_WORKLOAD,
+ 							       i);
+-		if (workload_type < 0)
+-			return -EINVAL;
++		if (workload_type < 0) {
++			result = -EINVAL;
++			goto out;
++		}
+ 
+ 		result = smu_cmn_update_table(smu,
+ 					  SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type,
+ 					  (void *)(&activity_monitor_external[i]), false);
+ 		if (result) {
+ 			dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
+-			return result;
++			goto out;
+ 		}
+ 	}
+ 
+@@ -1492,7 +1500,10 @@ do {													\
+ 	PRINT_DPM_MONITOR(Fclk_BoosterFreq);
+ #undef PRINT_DPM_MONITOR
+ 
+-	return size;
++	result = size;
++out:
++	kfree(activity_monitor_external);
++	return result;
+ }
+ 
+ static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+index 94de73cbeb2dd..17445800248dd 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+@@ -402,7 +402,8 @@ static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
+ 
+ void adv7533_dsi_power_on(struct adv7511 *adv);
+ void adv7533_dsi_power_off(struct adv7511 *adv);
+-void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode);
++enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
++					const struct drm_display_mode *mode);
+ int adv7533_patch_registers(struct adv7511 *adv);
+ int adv7533_patch_cec_registers(struct adv7511 *adv);
+ int adv7533_attach_dsi(struct adv7511 *adv);
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 6031bdd923420..0f0950c111960 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -697,7 +697,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector)
+ }
+ 
+ static enum drm_mode_status adv7511_mode_valid(struct adv7511 *adv7511,
+-			      struct drm_display_mode *mode)
++			      const struct drm_display_mode *mode)
+ {
+ 	if (mode->clock > 165000)
+ 		return MODE_CLOCK_HIGH;
+@@ -791,9 +791,6 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
+ 	regmap_update_bits(adv7511->regmap, 0x17,
+ 		0x60, (vsync_polarity << 6) | (hsync_polarity << 5));
+ 
+-	if (adv7511->type == ADV7533 || adv7511->type == ADV7535)
+-		adv7533_mode_set(adv7511, adj_mode);
+-
+ 	drm_mode_copy(&adv7511->curr_mode, adj_mode);
+ 
+ 	/*
+@@ -913,6 +910,18 @@ static void adv7511_bridge_mode_set(struct drm_bridge *bridge,
+ 	adv7511_mode_set(adv, mode, adj_mode);
+ }
+ 
++static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge,
++						      const struct drm_display_info *info,
++		const struct drm_display_mode *mode)
++{
++	struct adv7511 *adv = bridge_to_adv7511(bridge);
++
++	if (adv->type == ADV7533 || adv->type == ADV7535)
++		return adv7533_mode_valid(adv, mode);
++	else
++		return adv7511_mode_valid(adv, mode);
++}
++
+ static int adv7511_bridge_attach(struct drm_bridge *bridge,
+ 				 enum drm_bridge_attach_flags flags)
+ {
+@@ -960,6 +969,7 @@ static const struct drm_bridge_funcs adv7511_bridge_funcs = {
+ 	.enable = adv7511_bridge_enable,
+ 	.disable = adv7511_bridge_disable,
+ 	.mode_set = adv7511_bridge_mode_set,
++	.mode_valid = adv7511_bridge_mode_valid,
+ 	.attach = adv7511_bridge_attach,
+ 	.detect = adv7511_bridge_detect,
+ 	.get_edid = adv7511_bridge_get_edid,
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c
+index ef6270806d1d3..258c79d4dab0a 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7533.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c
+@@ -100,26 +100,27 @@ void adv7533_dsi_power_off(struct adv7511 *adv)
+ 	regmap_write(adv->regmap_cec, 0x27, 0x0b);
+ }
+ 
+-void adv7533_mode_set(struct adv7511 *adv, const struct drm_display_mode *mode)
++enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv,
++					const struct drm_display_mode *mode)
+ {
++	int lanes;
+ 	struct mipi_dsi_device *dsi = adv->dsi;
+-	int lanes, ret;
+-
+-	if (adv->num_dsi_lanes != 4)
+-		return;
+ 
+ 	if (mode->clock > 80000)
+ 		lanes = 4;
+ 	else
+ 		lanes = 3;
+ 
+-	if (lanes != dsi->lanes) {
+-		mipi_dsi_detach(dsi);
+-		dsi->lanes = lanes;
+-		ret = mipi_dsi_attach(dsi);
+-		if (ret)
+-			dev_err(&dsi->dev, "failed to change host lanes\n");
+-	}
++	/*
++	 * TODO: add support for dynamic switching of lanes
++	 * by using the bridge pre_enable() op . Till then filter
++	 * out the modes which shall need different number of lanes
++	 * than what was configured in the device tree.
++	 */
++	if (lanes != dsi->lanes)
++		return MODE_BAD;
++
++	return MODE_OK;
+ }
+ 
+ int adv7533_patch_registers(struct adv7511 *adv)
+diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
+index a09d1a39ab0ae..711f403afe7ce 100644
+--- a/drivers/gpu/drm/bridge/ite-it6505.c
++++ b/drivers/gpu/drm/bridge/ite-it6505.c
+@@ -2854,10 +2854,7 @@ static int it6505_bridge_attach(struct drm_bridge *bridge,
+ 	}
+ 
+ 	/* Register aux channel */
+-	it6505->aux.name = "DP-AUX";
+-	it6505->aux.dev = dev;
+ 	it6505->aux.drm_dev = bridge->dev;
+-	it6505->aux.transfer = it6505_aux_transfer;
+ 
+ 	ret = drm_dp_aux_register(&it6505->aux);
+ 
+@@ -3310,6 +3307,11 @@ static int it6505_i2c_probe(struct i2c_client *client,
+ 	DRM_DEV_DEBUG_DRIVER(dev, "it6505 device name: %s", dev_name(dev));
+ 	debugfs_init(it6505);
+ 
++	it6505->aux.name = "DP-AUX";
++	it6505->aux.dev = dev;
++	it6505->aux.transfer = it6505_aux_transfer;
++	drm_dp_aux_init(&it6505->aux);
++
+ 	it6505->bridge.funcs = &it6505_bridge_funcs;
+ 	it6505->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
+ 	it6505->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
+diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
+index 8bf41aa240687..6526d6ade04bf 100644
+--- a/drivers/gpu/drm/drm_atomic_helper.c
++++ b/drivers/gpu/drm/drm_atomic_helper.c
+@@ -899,7 +899,6 @@ int drm_atomic_helper_check_crtc_state(struct drm_crtc_state *crtc_state,
+ 				       bool can_disable_primary_planes)
+ {
+ 	struct drm_device *dev = crtc_state->crtc->dev;
+-	struct drm_atomic_state *state = crtc_state->state;
+ 
+ 	if (!crtc_state->enable)
+ 		return 0;
+@@ -910,14 +909,7 @@ int drm_atomic_helper_check_crtc_state(struct drm_crtc_state *crtc_state,
+ 		struct drm_plane *plane;
+ 
+ 		drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
+-			struct drm_plane_state *plane_state;
+-
+-			if (plane->type != DRM_PLANE_TYPE_PRIMARY)
+-				continue;
+-			plane_state = drm_atomic_get_plane_state(state, plane);
+-			if (IS_ERR(plane_state))
+-				return PTR_ERR(plane_state);
+-			if (plane_state->fb && plane_state->crtc) {
++			if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
+ 				has_primary_plane = true;
+ 				break;
+ 			}
+diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
+index eaa819381281b..fefcfac999d99 100644
+--- a/drivers/gpu/drm/drm_edid.c
++++ b/drivers/gpu/drm/drm_edid.c
+@@ -87,6 +87,8 @@ static int oui(u8 first, u8 second, u8 third)
+ #define EDID_QUIRK_FORCE_10BPC			(1 << 11)
+ /* Non desktop display (i.e. HMD) */
+ #define EDID_QUIRK_NON_DESKTOP			(1 << 12)
++/* Cap the DSC target bitrate to 15bpp */
++#define EDID_QUIRK_CAP_DSC_15BPP		(1 << 13)
+ 
+ #define MICROSOFT_IEEE_OUI	0xca125c
+ 
+@@ -147,6 +149,12 @@ static const struct edid_quirk {
+ 	EDID_QUIRK('F', 'C', 'M', 13600, EDID_QUIRK_PREFER_LARGE_75 |
+ 				       EDID_QUIRK_DETAILED_IN_CM),
+ 
++	/* LG 27GP950 */
++	EDID_QUIRK('G', 'S', 'M', 0x5bbf, EDID_QUIRK_CAP_DSC_15BPP),
++
++	/* LG 27GN950 */
++	EDID_QUIRK('G', 'S', 'M', 0x5b9a, EDID_QUIRK_CAP_DSC_15BPP),
++
+ 	/* LGD panel of HP zBook 17 G2, eDP 10 bpc, but reports unknown bpc */
+ 	EDID_QUIRK('L', 'G', 'D', 764, EDID_QUIRK_FORCE_10BPC),
+ 
+@@ -6116,6 +6124,7 @@ static void drm_reset_display_info(struct drm_connector *connector)
+ 
+ 	info->mso_stream_count = 0;
+ 	info->mso_pixel_overlap = 0;
++	info->max_dsc_bpp = 0;
+ }
+ 
+ static u32 update_display_info(struct drm_connector *connector,
+@@ -6202,6 +6211,9 @@ out:
+ 		info->non_desktop = true;
+ 	}
+ 
++	if (quirks & EDID_QUIRK_CAP_DSC_15BPP)
++		info->max_dsc_bpp = 15;
++
+ 	return quirks;
+ }
+ 
+diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
+index 07741b678798b..6768b7d18b6fb 100644
+--- a/drivers/gpu/drm/drm_fourcc.c
++++ b/drivers/gpu/drm/drm_fourcc.c
+@@ -263,12 +263,12 @@ const struct drm_format_info *__drm_format_info(u32 format)
+ 		  .vsub = 2, .is_yuv = true },
+ 		{ .format = DRM_FORMAT_Q410,		.depth = 0,
+ 		  .num_planes = 3, .char_per_block = { 2, 2, 2 },
+-		  .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
+-		  .vsub = 0, .is_yuv = true },
++		  .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1,
++		  .vsub = 1, .is_yuv = true },
+ 		{ .format = DRM_FORMAT_Q401,		.depth = 0,
+ 		  .num_planes = 3, .char_per_block = { 2, 2, 2 },
+-		  .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 0,
+-		  .vsub = 0, .is_yuv = true },
++		  .block_w = { 1, 1, 1 }, .block_h = { 1, 1, 1 }, .hsub = 1,
++		  .vsub = 1, .is_yuv = true },
+ 		{ .format = DRM_FORMAT_P030,            .depth = 0,  .num_planes = 2,
+ 		  .char_per_block = { 4, 8, 0 }, .block_w = { 3, 3, 0 }, .block_h = { 1, 1, 0 },
+ 		  .hsub = 2, .vsub = 2, .is_yuv = true},
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+index 37018bc55810d..f667e7906d1f4 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+@@ -416,6 +416,12 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
+ 	if (gpu->identity.model == chipModel_GC700)
+ 		gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
+ 
++	/* These models/revisions don't have the 2D pipe bit */
++	if ((gpu->identity.model == chipModel_GC500 &&
++	     gpu->identity.revision <= 2) ||
++	    gpu->identity.model == chipModel_GC300)
++		gpu->identity.features |= chipFeatures_PIPE_2D;
++
+ 	if ((gpu->identity.model == chipModel_GC500 &&
+ 	     gpu->identity.revision < 2) ||
+ 	    (gpu->identity.model == chipModel_GC300 &&
+@@ -449,8 +455,9 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
+ 				gpu_read(gpu, VIVS_HI_CHIP_MINOR_FEATURE_5);
+ 	}
+ 
+-	/* GC600 idle register reports zero bits where modules aren't present */
+-	if (gpu->identity.model == chipModel_GC600)
++	/* GC600/300 idle register reports zero bits where modules aren't present */
++	if (gpu->identity.model == chipModel_GC600 ||
++	    gpu->identity.model == chipModel_GC300)
+ 		gpu->idle_mask = VIVS_HI_IDLE_STATE_TX |
+ 				 VIVS_HI_IDLE_STATE_RA |
+ 				 VIVS_HI_IDLE_STATE_SE |
+diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+index 4d4a715b429d1..2c2b92324a2e9 100644
+--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+@@ -60,8 +60,9 @@ static int fsl_dcu_drm_connector_get_modes(struct drm_connector *connector)
+ 	return drm_panel_get_modes(fsl_connector->panel, connector);
+ }
+ 
+-static int fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector,
+-					    struct drm_display_mode *mode)
++static enum drm_mode_status
++fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector,
++				 struct drm_display_mode *mode)
+ {
+ 	if (mode->hdisplay & 0xf)
+ 		return MODE_ERROR;
+diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
+index 459571e2cc575..2bfcfbfa52a4f 100644
+--- a/drivers/gpu/drm/i915/display/intel_bios.c
++++ b/drivers/gpu/drm/i915/display/intel_bios.c
+@@ -414,7 +414,7 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
+ 		ptrs->lvds_entries++;
+ 
+ 	if (size != 0 || ptrs->lvds_entries != 3) {
+-		kfree(ptrs);
++		kfree(ptrs_block);
+ 		return NULL;
+ 	}
+ 
+diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
+index 21ba510716b6c..d852cfd1d6eba 100644
+--- a/drivers/gpu/drm/i915/display/intel_dp.c
++++ b/drivers/gpu/drm/i915/display/intel_dp.c
+@@ -3641,61 +3641,6 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp,
+ 	}
+ }
+ 
+-static void
+-intel_dp_autotest_phy_ddi_disable(struct intel_dp *intel_dp,
+-				  const struct intel_crtc_state *crtc_state)
+-{
+-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+-	struct drm_device *dev = dig_port->base.base.dev;
+-	struct drm_i915_private *dev_priv = to_i915(dev);
+-	struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
+-	enum pipe pipe = crtc->pipe;
+-	u32 trans_ddi_func_ctl_value, trans_conf_value, dp_tp_ctl_value;
+-
+-	trans_ddi_func_ctl_value = intel_de_read(dev_priv,
+-						 TRANS_DDI_FUNC_CTL(pipe));
+-	trans_conf_value = intel_de_read(dev_priv, PIPECONF(pipe));
+-	dp_tp_ctl_value = intel_de_read(dev_priv, TGL_DP_TP_CTL(pipe));
+-
+-	trans_ddi_func_ctl_value &= ~(TRANS_DDI_FUNC_ENABLE |
+-				      TGL_TRANS_DDI_PORT_MASK);
+-	trans_conf_value &= ~PIPECONF_ENABLE;
+-	dp_tp_ctl_value &= ~DP_TP_CTL_ENABLE;
+-
+-	intel_de_write(dev_priv, PIPECONF(pipe), trans_conf_value);
+-	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(pipe),
+-		       trans_ddi_func_ctl_value);
+-	intel_de_write(dev_priv, TGL_DP_TP_CTL(pipe), dp_tp_ctl_value);
+-}
+-
+-static void
+-intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp,
+-				 const struct intel_crtc_state *crtc_state)
+-{
+-	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+-	struct drm_device *dev = dig_port->base.base.dev;
+-	struct drm_i915_private *dev_priv = to_i915(dev);
+-	enum port port = dig_port->base.port;
+-	struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc);
+-	enum pipe pipe = crtc->pipe;
+-	u32 trans_ddi_func_ctl_value, trans_conf_value, dp_tp_ctl_value;
+-
+-	trans_ddi_func_ctl_value = intel_de_read(dev_priv,
+-						 TRANS_DDI_FUNC_CTL(pipe));
+-	trans_conf_value = intel_de_read(dev_priv, PIPECONF(pipe));
+-	dp_tp_ctl_value = intel_de_read(dev_priv, TGL_DP_TP_CTL(pipe));
+-
+-	trans_ddi_func_ctl_value |= TRANS_DDI_FUNC_ENABLE |
+-				    TGL_TRANS_DDI_SELECT_PORT(port);
+-	trans_conf_value |= PIPECONF_ENABLE;
+-	dp_tp_ctl_value |= DP_TP_CTL_ENABLE;
+-
+-	intel_de_write(dev_priv, PIPECONF(pipe), trans_conf_value);
+-	intel_de_write(dev_priv, TGL_DP_TP_CTL(pipe), dp_tp_ctl_value);
+-	intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(pipe),
+-		       trans_ddi_func_ctl_value);
+-}
+-
+ static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
+ 					 const struct intel_crtc_state *crtc_state)
+ {
+@@ -3714,14 +3659,10 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
+ 	intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX,
+ 				  link_status);
+ 
+-	intel_dp_autotest_phy_ddi_disable(intel_dp, crtc_state);
+-
+ 	intel_dp_set_signal_levels(intel_dp, crtc_state, DP_PHY_DPRX);
+ 
+ 	intel_dp_phy_pattern_update(intel_dp, crtc_state);
+ 
+-	intel_dp_autotest_phy_ddi_enable(intel_dp, crtc_state);
+-
+ 	drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
+ 			  intel_dp->train_set, crtc_state->lane_count);
+ 
+diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
+index 04e435bce79bd..cbc8b857d5f7a 100644
+--- a/drivers/gpu/drm/i915/gt/intel_engine.h
++++ b/drivers/gpu/drm/i915/gt/intel_engine.h
+@@ -348,4 +348,10 @@ intel_engine_get_hung_context(struct intel_engine_cs *engine)
+ 	return engine->hung_ce;
+ }
+ 
++u64 intel_clamp_heartbeat_interval_ms(struct intel_engine_cs *engine, u64 value);
++u64 intel_clamp_max_busywait_duration_ns(struct intel_engine_cs *engine, u64 value);
++u64 intel_clamp_preempt_timeout_ms(struct intel_engine_cs *engine, u64 value);
++u64 intel_clamp_stop_timeout_ms(struct intel_engine_cs *engine, u64 value);
++u64 intel_clamp_timeslice_duration_ms(struct intel_engine_cs *engine, u64 value);
++
+ #endif /* _INTEL_RINGBUFFER_H_ */
+diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+index 37fa813af7661..3dd0af057e6b1 100644
+--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
++++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+@@ -486,6 +486,17 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id,
+ 	engine->logical_mask = BIT(logical_instance);
+ 	__sprint_engine_name(engine);
+ 
++	if ((engine->class == COMPUTE_CLASS && !RCS_MASK(engine->gt) &&
++	     __ffs(CCS_MASK(engine->gt)) == engine->instance) ||
++	     engine->class == RENDER_CLASS)
++		engine->flags |= I915_ENGINE_FIRST_RENDER_COMPUTE;
++
++	/* features common between engines sharing EUs */
++	if (engine->class == RENDER_CLASS || engine->class == COMPUTE_CLASS) {
++		engine->flags |= I915_ENGINE_HAS_RCS_REG_STATE;
++		engine->flags |= I915_ENGINE_HAS_EU_PRIORITY;
++	}
++
+ 	engine->props.heartbeat_interval_ms =
+ 		CONFIG_DRM_I915_HEARTBEAT_INTERVAL;
+ 	engine->props.max_busywait_duration_ns =
+@@ -498,19 +509,28 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id,
+ 		CONFIG_DRM_I915_TIMESLICE_DURATION;
+ 
+ 	/* Override to uninterruptible for OpenCL workloads. */
+-	if (GRAPHICS_VER(i915) == 12 && engine->class == RENDER_CLASS)
++	if (GRAPHICS_VER(i915) == 12 && (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE))
+ 		engine->props.preempt_timeout_ms = 0;
+ 
+-	if ((engine->class == COMPUTE_CLASS && !RCS_MASK(engine->gt) &&
+-	     __ffs(CCS_MASK(engine->gt)) == engine->instance) ||
+-	     engine->class == RENDER_CLASS)
+-		engine->flags |= I915_ENGINE_FIRST_RENDER_COMPUTE;
+-
+-	/* features common between engines sharing EUs */
+-	if (engine->class == RENDER_CLASS || engine->class == COMPUTE_CLASS) {
+-		engine->flags |= I915_ENGINE_HAS_RCS_REG_STATE;
+-		engine->flags |= I915_ENGINE_HAS_EU_PRIORITY;
+-	}
++	/* Cap properties according to any system limits */
++#define CLAMP_PROP(field) \
++	do { \
++		u64 clamp = intel_clamp_##field(engine, engine->props.field); \
++		if (clamp != engine->props.field) { \
++			drm_notice(&engine->i915->drm, \
++				   "Warning, clamping %s to %lld to prevent overflow\n", \
++				   #field, clamp); \
++			engine->props.field = clamp; \
++		} \
++	} while (0)
++
++	CLAMP_PROP(heartbeat_interval_ms);
++	CLAMP_PROP(max_busywait_duration_ns);
++	CLAMP_PROP(preempt_timeout_ms);
++	CLAMP_PROP(stop_timeout_ms);
++	CLAMP_PROP(timeslice_duration_ms);
++
++#undef CLAMP_PROP
+ 
+ 	engine->defaults = engine->props; /* never to change again */
+ 
+@@ -534,6 +554,55 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id,
+ 	return 0;
+ }
+ 
++u64 intel_clamp_heartbeat_interval_ms(struct intel_engine_cs *engine, u64 value)
++{
++	value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
++
++	return value;
++}
++
++u64 intel_clamp_max_busywait_duration_ns(struct intel_engine_cs *engine, u64 value)
++{
++	value = min(value, jiffies_to_nsecs(2));
++
++	return value;
++}
++
++u64 intel_clamp_preempt_timeout_ms(struct intel_engine_cs *engine, u64 value)
++{
++	/*
++	 * NB: The GuC API only supports 32bit values. However, the limit is further
++	 * reduced due to internal calculations which would otherwise overflow.
++	 */
++	if (intel_guc_submission_is_wanted(&engine->gt->uc.guc))
++		value = min_t(u64, value, guc_policy_max_preempt_timeout_ms());
++
++	value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
++
++	return value;
++}
++
++u64 intel_clamp_stop_timeout_ms(struct intel_engine_cs *engine, u64 value)
++{
++	value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
++
++	return value;
++}
++
++u64 intel_clamp_timeslice_duration_ms(struct intel_engine_cs *engine, u64 value)
++{
++	/*
++	 * NB: The GuC API only supports 32bit values. However, the limit is further
++	 * reduced due to internal calculations which would otherwise overflow.
++	 */
++	if (intel_guc_submission_is_wanted(&engine->gt->uc.guc))
++		value = min_t(u64, value, guc_policy_max_exec_quantum_ms());
++
++	value = min_t(u64, value, jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT));
++
++	return value;
++}
++
+ static void __setup_engine_capabilities(struct intel_engine_cs *engine)
+ {
+ 	struct drm_i915_private *i915 = engine->i915;
+diff --git a/drivers/gpu/drm/i915/gt/sysfs_engines.c b/drivers/gpu/drm/i915/gt/sysfs_engines.c
+index 9670310562029..f2d9858d827c2 100644
+--- a/drivers/gpu/drm/i915/gt/sysfs_engines.c
++++ b/drivers/gpu/drm/i915/gt/sysfs_engines.c
+@@ -144,7 +144,7 @@ max_spin_store(struct kobject *kobj, struct kobj_attribute *attr,
+ 	       const char *buf, size_t count)
+ {
+ 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
+-	unsigned long long duration;
++	unsigned long long duration, clamped;
+ 	int err;
+ 
+ 	/*
+@@ -168,7 +168,8 @@ max_spin_store(struct kobject *kobj, struct kobj_attribute *attr,
+ 	if (err)
+ 		return err;
+ 
+-	if (duration > jiffies_to_nsecs(2))
++	clamped = intel_clamp_max_busywait_duration_ns(engine, duration);
++	if (duration != clamped)
+ 		return -EINVAL;
+ 
+ 	WRITE_ONCE(engine->props.max_busywait_duration_ns, duration);
+@@ -203,7 +204,7 @@ timeslice_store(struct kobject *kobj, struct kobj_attribute *attr,
+ 		const char *buf, size_t count)
+ {
+ 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
+-	unsigned long long duration;
++	unsigned long long duration, clamped;
+ 	int err;
+ 
+ 	/*
+@@ -218,7 +219,8 @@ timeslice_store(struct kobject *kobj, struct kobj_attribute *attr,
+ 	if (err)
+ 		return err;
+ 
+-	if (duration > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
++	clamped = intel_clamp_timeslice_duration_ms(engine, duration);
++	if (duration != clamped)
+ 		return -EINVAL;
+ 
+ 	WRITE_ONCE(engine->props.timeslice_duration_ms, duration);
+@@ -256,7 +258,7 @@ stop_store(struct kobject *kobj, struct kobj_attribute *attr,
+ 	   const char *buf, size_t count)
+ {
+ 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
+-	unsigned long long duration;
++	unsigned long long duration, clamped;
+ 	int err;
+ 
+ 	/*
+@@ -272,7 +274,8 @@ stop_store(struct kobject *kobj, struct kobj_attribute *attr,
+ 	if (err)
+ 		return err;
+ 
+-	if (duration > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
++	clamped = intel_clamp_stop_timeout_ms(engine, duration);
++	if (duration != clamped)
+ 		return -EINVAL;
+ 
+ 	WRITE_ONCE(engine->props.stop_timeout_ms, duration);
+@@ -306,7 +309,7 @@ preempt_timeout_store(struct kobject *kobj, struct kobj_attribute *attr,
+ 		      const char *buf, size_t count)
+ {
+ 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
+-	unsigned long long timeout;
++	unsigned long long timeout, clamped;
+ 	int err;
+ 
+ 	/*
+@@ -322,7 +325,8 @@ preempt_timeout_store(struct kobject *kobj, struct kobj_attribute *attr,
+ 	if (err)
+ 		return err;
+ 
+-	if (timeout > jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
++	clamped = intel_clamp_preempt_timeout_ms(engine, timeout);
++	if (timeout != clamped)
+ 		return -EINVAL;
+ 
+ 	WRITE_ONCE(engine->props.preempt_timeout_ms, timeout);
+@@ -362,7 +366,7 @@ heartbeat_store(struct kobject *kobj, struct kobj_attribute *attr,
+ 		const char *buf, size_t count)
+ {
+ 	struct intel_engine_cs *engine = kobj_to_engine(kobj);
+-	unsigned long long delay;
++	unsigned long long delay, clamped;
+ 	int err;
+ 
+ 	/*
+@@ -379,7 +383,8 @@ heartbeat_store(struct kobject *kobj, struct kobj_attribute *attr,
+ 	if (err)
+ 		return err;
+ 
+-	if (delay >= jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT))
++	clamped = intel_clamp_heartbeat_interval_ms(engine, delay);
++	if (delay != clamped)
+ 		return -EINVAL;
+ 
+ 	err = intel_engine_set_heartbeat(engine, delay);
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+index 2706a8c650900..7fbcfeda91951 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+@@ -224,53 +224,22 @@ static u32 guc_ctl_feature_flags(struct intel_guc *guc)
+ 
+ static u32 guc_ctl_log_params_flags(struct intel_guc *guc)
+ {
+-	u32 offset = intel_guc_ggtt_offset(guc, guc->log.vma) >> PAGE_SHIFT;
+-	u32 flags;
+-
+-	#if (((CRASH_BUFFER_SIZE) % SZ_1M) == 0)
+-	#define LOG_UNIT SZ_1M
+-	#define LOG_FLAG GUC_LOG_LOG_ALLOC_UNITS
+-	#else
+-	#define LOG_UNIT SZ_4K
+-	#define LOG_FLAG 0
+-	#endif
+-
+-	#if (((CAPTURE_BUFFER_SIZE) % SZ_1M) == 0)
+-	#define CAPTURE_UNIT SZ_1M
+-	#define CAPTURE_FLAG GUC_LOG_CAPTURE_ALLOC_UNITS
+-	#else
+-	#define CAPTURE_UNIT SZ_4K
+-	#define CAPTURE_FLAG 0
+-	#endif
+-
+-	BUILD_BUG_ON(!CRASH_BUFFER_SIZE);
+-	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, LOG_UNIT));
+-	BUILD_BUG_ON(!DEBUG_BUFFER_SIZE);
+-	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, LOG_UNIT));
+-	BUILD_BUG_ON(!CAPTURE_BUFFER_SIZE);
+-	BUILD_BUG_ON(!IS_ALIGNED(CAPTURE_BUFFER_SIZE, CAPTURE_UNIT));
+-
+-	BUILD_BUG_ON((CRASH_BUFFER_SIZE / LOG_UNIT - 1) >
+-			(GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT));
+-	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) >
+-			(GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT));
+-	BUILD_BUG_ON((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) >
+-			(GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT));
++	struct intel_guc_log *log = &guc->log;
++	u32 offset, flags;
++
++	GEM_BUG_ON(!log->sizes_initialised);
++
++	offset = intel_guc_ggtt_offset(guc, log->vma) >> PAGE_SHIFT;
+ 
+ 	flags = GUC_LOG_VALID |
+ 		GUC_LOG_NOTIFY_ON_HALF_FULL |
+-		CAPTURE_FLAG |
+-		LOG_FLAG |
+-		((CRASH_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
+-		((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
+-		((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) << GUC_LOG_CAPTURE_SHIFT) |
++		log->sizes[GUC_LOG_SECTIONS_DEBUG].flag |
++		log->sizes[GUC_LOG_SECTIONS_CAPTURE].flag |
++		(log->sizes[GUC_LOG_SECTIONS_CRASH].count << GUC_LOG_CRASH_SHIFT) |
++		(log->sizes[GUC_LOG_SECTIONS_DEBUG].count << GUC_LOG_DEBUG_SHIFT) |
++		(log->sizes[GUC_LOG_SECTIONS_CAPTURE].count << GUC_LOG_CAPTURE_SHIFT) |
+ 		(offset << GUC_LOG_BUF_ADDR_SHIFT);
+ 
+-	#undef LOG_UNIT
+-	#undef LOG_FLAG
+-	#undef CAPTURE_UNIT
+-	#undef CAPTURE_FLAG
+-
+ 	return flags;
+ }
+ 
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+index 75257bd20ff01..4c51888fd78b4 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+@@ -165,7 +165,7 @@ static const struct __guc_mmio_reg_descr empty_regs_list[] = {
+ 	}
+ 
+ /* List of lists */
+-static struct __guc_mmio_reg_descr_group default_lists[] = {
++static const struct __guc_mmio_reg_descr_group default_lists[] = {
+ 	MAKE_REGLIST(default_global_regs, PF, GLOBAL, 0),
+ 	MAKE_REGLIST(default_rc_class_regs, PF, ENGINE_CLASS, GUC_RENDER_CLASS),
+ 	MAKE_REGLIST(xe_lpd_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_RENDER_CLASS),
+@@ -419,6 +419,44 @@ guc_capture_get_device_reglist(struct intel_guc *guc)
+ 	return default_lists;
+ }
+ 
++static const char *
++__stringify_type(u32 type)
++{
++	switch (type) {
++	case GUC_CAPTURE_LIST_TYPE_GLOBAL:
++		return "Global";
++	case GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS:
++		return "Class";
++	case GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE:
++		return "Instance";
++	default:
++		break;
++	}
++
++	return "unknown";
++}
++
++static const char *
++__stringify_engclass(u32 class)
++{
++	switch (class) {
++	case GUC_RENDER_CLASS:
++		return "Render";
++	case GUC_VIDEO_CLASS:
++		return "Video";
++	case GUC_VIDEOENHANCE_CLASS:
++		return "VideoEnhance";
++	case GUC_BLITTER_CLASS:
++		return "Blitter";
++	case GUC_COMPUTE_CLASS:
++		return "Compute";
++	default:
++		break;
++	}
++
++	return "unknown";
++}
++
+ static int
+ guc_capture_list_init(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
+ 		      struct guc_mmio_reg *ptr, u16 num_entries)
+@@ -482,32 +520,55 @@ guc_cap_list_num_regs(struct intel_guc_state_capture *gc, u32 owner, u32 type, u
+ 	return num_regs;
+ }
+ 
+-int
+-intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
+-			      size_t *size)
++static int
++guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
++			size_t *size, bool is_purpose_est)
+ {
+ 	struct intel_guc_state_capture *gc = guc->capture;
++	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
+ 	struct __guc_capture_ads_cache *cache = &gc->ads_cache[owner][type][classid];
+ 	int num_regs;
+ 
+-	if (!gc->reglists)
++	if (!gc->reglists) {
++		drm_warn(&i915->drm, "GuC-capture: No reglist on this device\n");
+ 		return -ENODEV;
++	}
+ 
+ 	if (cache->is_valid) {
+ 		*size = cache->size;
+ 		return cache->status;
+ 	}
+ 
++	if (!is_purpose_est && owner == GUC_CAPTURE_LIST_INDEX_PF &&
++	    !guc_capture_get_one_list(gc->reglists, owner, type, classid)) {
++		if (type == GUC_CAPTURE_LIST_TYPE_GLOBAL)
++			drm_warn(&i915->drm, "Missing GuC-Err-Cap reglist Global!\n");
++		else
++			drm_warn(&i915->drm, "Missing GuC-Err-Cap reglist %s(%u):%s(%u)!\n",
++				 __stringify_type(type), type,
++				 __stringify_engclass(classid), classid);
++		return -ENODATA;
++	}
++
+ 	num_regs = guc_cap_list_num_regs(gc, owner, type, classid);
++	/* intentional empty lists can exist depending on hw config */
+ 	if (!num_regs)
+ 		return -ENODATA;
+ 
+-	*size = PAGE_ALIGN((sizeof(struct guc_debug_capture_list)) +
+-			   (num_regs * sizeof(struct guc_mmio_reg)));
++	if (size)
++		*size = PAGE_ALIGN((sizeof(struct guc_debug_capture_list)) +
++				   (num_regs * sizeof(struct guc_mmio_reg)));
+ 
+ 	return 0;
+ }
+ 
++int
++intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
++			      size_t *size)
++{
++	return guc_capture_getlistsize(guc, owner, type, classid, size, false);
++}
++
+ static void guc_capture_create_prealloc_nodes(struct intel_guc *guc);
+ 
+ int
+@@ -600,15 +661,13 @@ intel_guc_capture_getnullheader(struct intel_guc *guc,
+ 	return 0;
+ }
+ 
+-#define GUC_CAPTURE_OVERBUFFER_MULTIPLIER 3
+-
+-int
+-intel_guc_capture_output_min_size_est(struct intel_guc *guc)
++static int
++guc_capture_output_min_size_est(struct intel_guc *guc)
+ {
+ 	struct intel_gt *gt = guc_to_gt(guc);
+ 	struct intel_engine_cs *engine;
+ 	enum intel_engine_id id;
+-	int worst_min_size = 0, num_regs = 0;
++	int worst_min_size = 0;
+ 	size_t tmp = 0;
+ 
+ 	if (!guc->capture)
+@@ -623,33 +682,58 @@ intel_guc_capture_output_min_size_est(struct intel_guc *guc)
+ 	 * For each engine instance, there would be 1 x guc_state_capture_group_t output
+ 	 * followed by 3 x guc_state_capture_t lists. The latter is how the register
+ 	 * dumps are split across different register types (where the '3' are global vs class
+-	 * vs instance). Finally, let's multiply the whole thing by 3x (just so we are
+-	 * not limited to just 1 round of data in a worst case full register dump log)
+-	 *
+-	 * NOTE: intel_guc_log that allocates the log buffer would round this size up to
+-	 * a power of two.
++	 * vs instance).
+ 	 */
+-
+ 	for_each_engine(engine, gt, id) {
+ 		worst_min_size += sizeof(struct guc_state_capture_group_header_t) +
+ 					 (3 * sizeof(struct guc_state_capture_header_t));
+ 
+-		if (!intel_guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_GLOBAL, 0, &tmp))
+-			num_regs += tmp;
++		if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_GLOBAL, 0, &tmp, true))
++			worst_min_size += tmp;
+ 
+-		if (!intel_guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS,
+-						   engine->class, &tmp)) {
+-			num_regs += tmp;
++		if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS,
++					     engine->class, &tmp, true)) {
++			worst_min_size += tmp;
+ 		}
+-		if (!intel_guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE,
+-						   engine->class, &tmp)) {
+-			num_regs += tmp;
++		if (!guc_capture_getlistsize(guc, 0, GUC_CAPTURE_LIST_TYPE_ENGINE_INSTANCE,
++					     engine->class, &tmp, true)) {
++			worst_min_size += tmp;
+ 		}
+ 	}
+ 
+-	worst_min_size += (num_regs * sizeof(struct guc_mmio_reg));
++	return worst_min_size;
++}
++
++/*
++ * Add on a 3x multiplier to allow for multiple back-to-back captures occurring
++ * before the i915 can read the data out and process it
++ */
++#define GUC_CAPTURE_OVERBUFFER_MULTIPLIER 3
+ 
+-	return (worst_min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER);
++static void check_guc_capture_size(struct intel_guc *guc)
++{
++	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
++	int min_size = guc_capture_output_min_size_est(guc);
++	int spare_size = min_size * GUC_CAPTURE_OVERBUFFER_MULTIPLIER;
++	u32 buffer_size = intel_guc_log_section_size_capture(&guc->log);
++
++	/*
++	 * NOTE: min_size is much smaller than the capture region allocation (DG2: <80K vs 1MB)
++	 * Additionally, its based on space needed to fit all engines getting reset at once
++	 * within the same G2H handler task slot. This is very unlikely. However, if GuC really
++	 * does run out of space for whatever reason, we will see an separate warning message
++	 * when processing the G2H event capture-notification, search for:
++	 * INTEL_GUC_STATE_CAPTURE_EVENT_STATUS_NOSPACE.
++	 */
++	if (min_size < 0)
++		drm_warn(&i915->drm, "Failed to calculate GuC error state capture buffer minimum size: %d!\n",
++			 min_size);
++	else if (min_size > buffer_size)
++		drm_warn(&i915->drm, "GuC error state capture buffer maybe small: %d < %d\n",
++			 buffer_size, min_size);
++	else if (spare_size > buffer_size)
++		drm_dbg(&i915->drm, "GuC error state capture buffer lacks spare size: %d < %d (min = %d)\n",
++			buffer_size, spare_size, min_size);
+ }
+ 
+ /*
+@@ -1278,7 +1362,8 @@ static void __guc_capture_process_output(struct intel_guc *guc)
+ 
+ 	log_buf_state = guc->log.buf_addr +
+ 			(sizeof(struct guc_log_buffer_state) * GUC_CAPTURE_LOG_BUFFER);
+-	src_data = guc->log.buf_addr + intel_guc_get_log_buffer_offset(GUC_CAPTURE_LOG_BUFFER);
++	src_data = guc->log.buf_addr +
++		   intel_guc_get_log_buffer_offset(&guc->log, GUC_CAPTURE_LOG_BUFFER);
+ 
+ 	/*
+ 	 * Make a copy of the state structure, inside GuC log buffer
+@@ -1286,7 +1371,7 @@ static void __guc_capture_process_output(struct intel_guc *guc)
+ 	 * from it multiple times.
+ 	 */
+ 	memcpy(&log_buf_state_local, log_buf_state, sizeof(struct guc_log_buffer_state));
+-	buffer_size = intel_guc_get_log_buffer_size(GUC_CAPTURE_LOG_BUFFER);
++	buffer_size = intel_guc_get_log_buffer_size(&guc->log, GUC_CAPTURE_LOG_BUFFER);
+ 	read_offset = log_buf_state_local.read_ptr;
+ 	write_offset = log_buf_state_local.sampled_write_ptr;
+ 	full_count = log_buf_state_local.buffer_full_cnt;
+@@ -1580,5 +1665,7 @@ int intel_guc_capture_init(struct intel_guc *guc)
+ 	INIT_LIST_HEAD(&guc->capture->outlist);
+ 	INIT_LIST_HEAD(&guc->capture->cachelist);
+ 
++	check_guc_capture_size(guc);
++
+ 	return 0;
+ }
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
+index d3d7bd0b6db64..fbd3713c7832d 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
+@@ -21,7 +21,6 @@ int intel_guc_capture_print_engine_node(struct drm_i915_error_state_buf *m,
+ void intel_guc_capture_get_matching_node(struct intel_gt *gt, struct intel_engine_coredump *ee,
+ 					 struct intel_context *ce);
+ void intel_guc_capture_process(struct intel_guc *guc);
+-int intel_guc_capture_output_min_size_est(struct intel_guc *guc);
+ int intel_guc_capture_getlist(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
+ 			      void **outptr);
+ int intel_guc_capture_getlistsize(struct intel_guc *guc, u32 owner, u32 type, u32 classid,
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+index 323b055e5db97..502e7cb5a3025 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+@@ -305,6 +305,27 @@ struct guc_update_context_policy {
+ 
+ #define GLOBAL_POLICY_DEFAULT_DPC_PROMOTE_TIME_US 500000
+ 
++/*
++ * GuC converts the timeout to clock ticks internally. Different platforms have
++ * different GuC clocks. Thus, the maximum value before overflow is platform
++ * dependent. Current worst case scenario is about 110s. So, the spec says to
++ * limit to 100s to be safe.
++ */
++#define GUC_POLICY_MAX_EXEC_QUANTUM_US		(100 * 1000 * 1000UL)
++#define GUC_POLICY_MAX_PREEMPT_TIMEOUT_US	(100 * 1000 * 1000UL)
++
++static inline u32 guc_policy_max_exec_quantum_ms(void)
++{
++	BUILD_BUG_ON(GUC_POLICY_MAX_EXEC_QUANTUM_US >= UINT_MAX);
++	return GUC_POLICY_MAX_EXEC_QUANTUM_US / 1000;
++}
++
++static inline u32 guc_policy_max_preempt_timeout_ms(void)
++{
++	BUILD_BUG_ON(GUC_POLICY_MAX_PREEMPT_TIMEOUT_US >= UINT_MAX);
++	return GUC_POLICY_MAX_PREEMPT_TIMEOUT_US / 1000;
++}
++
+ struct guc_policies {
+ 	u32 submission_queue_depth[GUC_MAX_ENGINE_CLASSES];
+ 	/* In micro seconds. How much time to allow before DPC processing is
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+index 25b2d7ce6640d..8d755d285247e 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+@@ -13,8 +13,187 @@
+ #include "intel_guc_capture.h"
+ #include "intel_guc_log.h"
+ 
++#if defined(CONFIG_DRM_I915_DEBUG_GUC)
++#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE	SZ_2M
++#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE	SZ_16M
++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE	SZ_1M
++#elif defined(CONFIG_DRM_I915_DEBUG_GEM)
++#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE	SZ_1M
++#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE	SZ_2M
++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE	SZ_1M
++#else
++#define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE	SZ_8K
++#define GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE	SZ_64K
++#define GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE	SZ_1M
++#endif
++
+ static void guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log);
+ 
++struct guc_log_section {
++	u32 max;
++	u32 flag;
++	u32 default_val;
++	const char *name;
++};
++
++static s32 scale_log_param(struct intel_guc_log *log, const struct guc_log_section *section,
++			   s32 param)
++{
++	/* -1 means default */
++	if (param < 0)
++		return section->default_val;
++
++	/* Check for 32-bit overflow */
++	if (param >= SZ_4K) {
++		drm_err(&guc_to_gt(log_to_guc(log))->i915->drm, "Size too large for GuC %s log: %dMB!",
++			section->name, param);
++		return section->default_val;
++	}
++
++	/* Param units are 1MB */
++	return param * SZ_1M;
++}
++
++static void _guc_log_init_sizes(struct intel_guc_log *log)
++{
++	struct intel_guc *guc = log_to_guc(log);
++	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
++	static const struct guc_log_section sections[GUC_LOG_SECTIONS_LIMIT] = {
++		{
++			GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT,
++			GUC_LOG_LOG_ALLOC_UNITS,
++			GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE,
++			"crash dump"
++		},
++		{
++			GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT,
++			GUC_LOG_LOG_ALLOC_UNITS,
++			GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE,
++			"debug",
++		},
++		{
++			GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT,
++			GUC_LOG_CAPTURE_ALLOC_UNITS,
++			GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE,
++			"capture",
++		}
++	};
++	s32 params[GUC_LOG_SECTIONS_LIMIT] = {
++		i915->params.guc_log_size_crash,
++		i915->params.guc_log_size_debug,
++		i915->params.guc_log_size_capture,
++	};
++	int i;
++
++	for (i = 0; i < GUC_LOG_SECTIONS_LIMIT; i++)
++		log->sizes[i].bytes = scale_log_param(log, sections + i, params[i]);
++
++	/* If debug size > 1MB then bump default crash size to keep the same units */
++	if (log->sizes[GUC_LOG_SECTIONS_DEBUG].bytes >= SZ_1M &&
++	    (i915->params.guc_log_size_crash == -1) &&
++	    GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE < SZ_1M)
++		log->sizes[GUC_LOG_SECTIONS_CRASH].bytes = SZ_1M;
++
++	/* Prepare the GuC API structure fields: */
++	for (i = 0; i < GUC_LOG_SECTIONS_LIMIT; i++) {
++		/* Convert to correct units */
++		if ((log->sizes[i].bytes % SZ_1M) == 0) {
++			log->sizes[i].units = SZ_1M;
++			log->sizes[i].flag = sections[i].flag;
++		} else {
++			log->sizes[i].units = SZ_4K;
++			log->sizes[i].flag = 0;
++		}
++
++		if (!IS_ALIGNED(log->sizes[i].bytes, log->sizes[i].units))
++			drm_err(&i915->drm, "Mis-aligned GuC log %s size: 0x%X vs 0x%X!",
++				sections[i].name, log->sizes[i].bytes, log->sizes[i].units);
++		log->sizes[i].count = log->sizes[i].bytes / log->sizes[i].units;
++
++		if (!log->sizes[i].count) {
++			drm_err(&i915->drm, "Zero GuC log %s size!", sections[i].name);
++		} else {
++			/* Size is +1 unit */
++			log->sizes[i].count--;
++		}
++
++		/* Clip to field size */
++		if (log->sizes[i].count > sections[i].max) {
++			drm_err(&i915->drm, "GuC log %s size too large: %d vs %d!",
++				sections[i].name, log->sizes[i].count + 1, sections[i].max + 1);
++			log->sizes[i].count = sections[i].max;
++		}
++	}
++
++	if (log->sizes[GUC_LOG_SECTIONS_CRASH].units != log->sizes[GUC_LOG_SECTIONS_DEBUG].units) {
++		drm_err(&i915->drm, "Unit mis-match for GuC log crash and debug sections: %d vs %d!",
++			log->sizes[GUC_LOG_SECTIONS_CRASH].units,
++			log->sizes[GUC_LOG_SECTIONS_DEBUG].units);
++		log->sizes[GUC_LOG_SECTIONS_CRASH].units = log->sizes[GUC_LOG_SECTIONS_DEBUG].units;
++		log->sizes[GUC_LOG_SECTIONS_CRASH].count = 0;
++	}
++
++	log->sizes_initialised = true;
++}
++
++static void guc_log_init_sizes(struct intel_guc_log *log)
++{
++	if (log->sizes_initialised)
++		return;
++
++	_guc_log_init_sizes(log);
++}
++
++static u32 intel_guc_log_section_size_crash(struct intel_guc_log *log)
++{
++	guc_log_init_sizes(log);
++
++	return log->sizes[GUC_LOG_SECTIONS_CRASH].bytes;
++}
++
++static u32 intel_guc_log_section_size_debug(struct intel_guc_log *log)
++{
++	guc_log_init_sizes(log);
++
++	return log->sizes[GUC_LOG_SECTIONS_DEBUG].bytes;
++}
++
++u32 intel_guc_log_section_size_capture(struct intel_guc_log *log)
++{
++	guc_log_init_sizes(log);
++
++	return log->sizes[GUC_LOG_SECTIONS_CAPTURE].bytes;
++}
++
++static u32 intel_guc_log_size(struct intel_guc_log *log)
++{
++	/*
++	 *  GuC Log buffer Layout:
++	 *
++	 *  NB: Ordering must follow "enum guc_log_buffer_type".
++	 *
++	 *  +===============================+ 00B
++	 *  |      Debug state header       |
++	 *  +-------------------------------+ 32B
++	 *  |    Crash dump state header    |
++	 *  +-------------------------------+ 64B
++	 *  |     Capture state header      |
++	 *  +-------------------------------+ 96B
++	 *  |                               |
++	 *  +===============================+ PAGE_SIZE (4KB)
++	 *  |          Debug logs           |
++	 *  +===============================+ + DEBUG_SIZE
++	 *  |        Crash Dump logs        |
++	 *  +===============================+ + CRASH_SIZE
++	 *  |         Capture logs          |
++	 *  +===============================+ + CAPTURE_SIZE
++	 */
++	return PAGE_SIZE +
++		intel_guc_log_section_size_crash(log) +
++		intel_guc_log_section_size_debug(log) +
++		intel_guc_log_section_size_capture(log);
++}
++
+ /**
+  * DOC: GuC firmware log
+  *
+@@ -139,7 +318,8 @@ static void guc_move_to_next_buf(struct intel_guc_log *log)
+ 	smp_wmb();
+ 
+ 	/* All data has been written, so now move the offset of sub buffer. */
+-	relay_reserve(log->relay.channel, log->vma->obj->base.size - CAPTURE_BUFFER_SIZE);
++	relay_reserve(log->relay.channel, log->vma->obj->base.size -
++					  intel_guc_log_section_size_capture(log));
+ 
+ 	/* Switch to the next sub buffer */
+ 	relay_flush(log->relay.channel);
+@@ -184,15 +364,16 @@ bool intel_guc_check_log_buf_overflow(struct intel_guc_log *log,
+ 	return overflow;
+ }
+ 
+-unsigned int intel_guc_get_log_buffer_size(enum guc_log_buffer_type type)
++unsigned int intel_guc_get_log_buffer_size(struct intel_guc_log *log,
++					   enum guc_log_buffer_type type)
+ {
+ 	switch (type) {
+ 	case GUC_DEBUG_LOG_BUFFER:
+-		return DEBUG_BUFFER_SIZE;
++		return intel_guc_log_section_size_debug(log);
+ 	case GUC_CRASH_DUMP_LOG_BUFFER:
+-		return CRASH_BUFFER_SIZE;
++		return intel_guc_log_section_size_crash(log);
+ 	case GUC_CAPTURE_LOG_BUFFER:
+-		return CAPTURE_BUFFER_SIZE;
++		return intel_guc_log_section_size_capture(log);
+ 	default:
+ 		MISSING_CASE(type);
+ 	}
+@@ -200,7 +381,8 @@ unsigned int intel_guc_get_log_buffer_size(enum guc_log_buffer_type type)
+ 	return 0;
+ }
+ 
+-size_t intel_guc_get_log_buffer_offset(enum guc_log_buffer_type type)
++size_t intel_guc_get_log_buffer_offset(struct intel_guc_log *log,
++				       enum guc_log_buffer_type type)
+ {
+ 	enum guc_log_buffer_type i;
+ 	size_t offset = PAGE_SIZE;/* for the log_buffer_states */
+@@ -208,7 +390,7 @@ size_t intel_guc_get_log_buffer_offset(enum guc_log_buffer_type type)
+ 	for (i = GUC_DEBUG_LOG_BUFFER; i < GUC_MAX_LOG_BUFFER; ++i) {
+ 		if (i == type)
+ 			break;
+-		offset += intel_guc_get_log_buffer_size(i);
++		offset += intel_guc_get_log_buffer_size(log, i);
+ 	}
+ 
+ 	return offset;
+@@ -259,7 +441,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log)
+ 		 */
+ 		memcpy(&log_buf_state_local, log_buf_state,
+ 		       sizeof(struct guc_log_buffer_state));
+-		buffer_size = intel_guc_get_log_buffer_size(type);
++		buffer_size = intel_guc_get_log_buffer_size(log, type);
+ 		read_offset = log_buf_state_local.read_ptr;
+ 		write_offset = log_buf_state_local.sampled_write_ptr;
+ 		full_cnt = log_buf_state_local.buffer_full_cnt;
+@@ -374,7 +556,7 @@ static int guc_log_relay_create(struct intel_guc_log *log)
+ 	  * Keep the size of sub buffers same as shared log buffer
+ 	  * but GuC log-events excludes the error-state-capture logs
+ 	  */
+-	subbuf_size = log->vma->size - CAPTURE_BUFFER_SIZE;
++	subbuf_size = log->vma->size - intel_guc_log_section_size_capture(log);
+ 
+ 	/*
+ 	 * Store up to 8 snapshots, which is large enough to buffer sufficient
+@@ -461,32 +643,7 @@ int intel_guc_log_create(struct intel_guc_log *log)
+ 
+ 	GEM_BUG_ON(log->vma);
+ 
+-	/*
+-	 *  GuC Log buffer Layout
+-	 * (this ordering must follow "enum guc_log_buffer_type" definition)
+-	 *
+-	 *  +===============================+ 00B
+-	 *  |      Debug state header       |
+-	 *  +-------------------------------+ 32B
+-	 *  |    Crash dump state header    |
+-	 *  +-------------------------------+ 64B
+-	 *  |     Capture state header      |
+-	 *  +-------------------------------+ 96B
+-	 *  |                               |
+-	 *  +===============================+ PAGE_SIZE (4KB)
+-	 *  |          Debug logs           |
+-	 *  +===============================+ + DEBUG_SIZE
+-	 *  |        Crash Dump logs        |
+-	 *  +===============================+ + CRASH_SIZE
+-	 *  |         Capture logs          |
+-	 *  +===============================+ + CAPTURE_SIZE
+-	 */
+-	if (intel_guc_capture_output_min_size_est(guc) > CAPTURE_BUFFER_SIZE)
+-		DRM_WARN("GuC log buffer for state_capture maybe too small. %d < %d\n",
+-			 CAPTURE_BUFFER_SIZE, intel_guc_capture_output_min_size_est(guc));
+-
+-	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE +
+-		       CAPTURE_BUFFER_SIZE;
++	guc_log_size = intel_guc_log_size(log);
+ 
+ 	vma = intel_guc_allocate_vma(guc, guc_log_size);
+ 	if (IS_ERR(vma)) {
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
+index 18007e639be99..02127703be809 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
+@@ -15,20 +15,6 @@
+ 
+ struct intel_guc;
+ 
+-#if defined(CONFIG_DRM_I915_DEBUG_GUC)
+-#define CRASH_BUFFER_SIZE	SZ_2M
+-#define DEBUG_BUFFER_SIZE	SZ_16M
+-#define CAPTURE_BUFFER_SIZE	SZ_4M
+-#elif defined(CONFIG_DRM_I915_DEBUG_GEM)
+-#define CRASH_BUFFER_SIZE	SZ_1M
+-#define DEBUG_BUFFER_SIZE	SZ_2M
+-#define CAPTURE_BUFFER_SIZE	SZ_1M
+-#else
+-#define CRASH_BUFFER_SIZE	SZ_8K
+-#define DEBUG_BUFFER_SIZE	SZ_64K
+-#define CAPTURE_BUFFER_SIZE	SZ_16K
+-#endif
+-
+ /*
+  * While we're using plain log level in i915, GuC controls are much more...
+  * "elaborate"? We have a couple of bits for verbosity, separate bit for actual
+@@ -46,10 +32,30 @@ struct intel_guc;
+ #define GUC_VERBOSITY_TO_LOG_LEVEL(x)	((x) + 2)
+ #define GUC_LOG_LEVEL_MAX GUC_VERBOSITY_TO_LOG_LEVEL(GUC_LOG_VERBOSITY_MAX)
+ 
++enum {
++	GUC_LOG_SECTIONS_CRASH,
++	GUC_LOG_SECTIONS_DEBUG,
++	GUC_LOG_SECTIONS_CAPTURE,
++	GUC_LOG_SECTIONS_LIMIT
++};
++
+ struct intel_guc_log {
+ 	u32 level;
++
++	/* Allocation settings */
++	struct {
++		s32 bytes;	/* Size in bytes */
++		s32 units;	/* GuC API units - 1MB or 4KB */
++		s32 count;	/* Number of API units */
++		u32 flag;	/* GuC API units flag */
++	} sizes[GUC_LOG_SECTIONS_LIMIT];
++	bool sizes_initialised;
++
++	/* Combined buffer allocation */
+ 	struct i915_vma *vma;
+ 	void *buf_addr;
++
++	/* RelayFS support */
+ 	struct {
+ 		bool buf_in_use;
+ 		bool started;
+@@ -58,6 +64,7 @@ struct intel_guc_log {
+ 		struct mutex lock;
+ 		u32 full_count;
+ 	} relay;
++
+ 	/* logging related stats */
+ 	struct {
+ 		u32 sampled_overflow;
+@@ -69,8 +76,9 @@ struct intel_guc_log {
+ void intel_guc_log_init_early(struct intel_guc_log *log);
+ bool intel_guc_check_log_buf_overflow(struct intel_guc_log *log, enum guc_log_buffer_type type,
+ 				      unsigned int full_cnt);
+-unsigned int intel_guc_get_log_buffer_size(enum guc_log_buffer_type type);
+-size_t intel_guc_get_log_buffer_offset(enum guc_log_buffer_type type);
++unsigned int intel_guc_get_log_buffer_size(struct intel_guc_log *log,
++					   enum guc_log_buffer_type type);
++size_t intel_guc_get_log_buffer_offset(struct intel_guc_log *log, enum guc_log_buffer_type type);
+ int intel_guc_log_create(struct intel_guc_log *log);
+ void intel_guc_log_destroy(struct intel_guc_log *log);
+ 
+@@ -92,4 +100,6 @@ void intel_guc_log_info(struct intel_guc_log *log, struct drm_printer *p);
+ int intel_guc_log_dump(struct intel_guc_log *log, struct drm_printer *p,
+ 		       bool dump_load_err);
+ 
++u32 intel_guc_log_section_size_capture(struct intel_guc_log *log);
++
+ #endif
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+index fe179146d51b9..cd0c5043863b6 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+@@ -2430,6 +2430,10 @@ static int guc_context_policy_init_v70(struct intel_context *ce, bool loop)
+ 	int ret;
+ 
+ 	/* NB: For both of these, zero means disabled. */
++	GEM_BUG_ON(overflows_type(engine->props.timeslice_duration_ms * 1000,
++				  execution_quantum));
++	GEM_BUG_ON(overflows_type(engine->props.preempt_timeout_ms * 1000,
++				  preemption_timeout));
+ 	execution_quantum = engine->props.timeslice_duration_ms * 1000;
+ 	preemption_timeout = engine->props.preempt_timeout_ms * 1000;
+ 
+@@ -2486,6 +2490,10 @@ static void guc_context_policy_init_v69(struct intel_engine_cs *engine,
+ 		desc->policy_flags |= CONTEXT_POLICY_FLAG_PREEMPT_TO_IDLE_V69;
+ 
+ 	/* NB: For both of these, zero means disabled. */
++	GEM_BUG_ON(overflows_type(engine->props.timeslice_duration_ms * 1000,
++				  desc->execution_quantum));
++	GEM_BUG_ON(overflows_type(engine->props.preempt_timeout_ms * 1000,
++				  desc->preemption_timeout));
+ 	desc->execution_quantum = engine->props.timeslice_duration_ms * 1000;
+ 	desc->preemption_timeout = engine->props.preempt_timeout_ms * 1000;
+ }
+diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
+index 6fc475a5db615..06ca5b8221118 100644
+--- a/drivers/gpu/drm/i915/i915_params.c
++++ b/drivers/gpu/drm/i915/i915_params.c
+@@ -171,6 +171,18 @@ i915_param_named(guc_log_level, int, 0400,
+ 	"GuC firmware logging level. Requires GuC to be loaded. "
+ 	"(-1=auto [default], 0=disable, 1..4=enable with verbosity min..max)");
+ 
++i915_param_named(guc_log_size_crash, int, 0400,
++	"GuC firmware logging buffer size for crash dumps (in MB)"
++	"(-1=auto [default], NB: max = 4, other restrictions apply)");
++
++i915_param_named(guc_log_size_debug, int, 0400,
++	"GuC firmware logging buffer size for debug logs (in MB)"
++	"(-1=auto [default], NB: max = 16, other restrictions apply)");
++
++i915_param_named(guc_log_size_capture, int, 0400,
++	"GuC error capture register dump buffer size (in MB)"
++	"(-1=auto [default], NB: max = 4, other restrictions apply)");
++
+ i915_param_named_unsafe(guc_firmware_path, charp, 0400,
+ 	"GuC firmware path to use instead of the default one");
+ 
+diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
+index 2733cb6cfe094..f684d1ab87078 100644
+--- a/drivers/gpu/drm/i915/i915_params.h
++++ b/drivers/gpu/drm/i915/i915_params.h
+@@ -61,6 +61,9 @@ struct drm_printer;
+ 	param(int, invert_brightness, 0, 0600) \
+ 	param(int, enable_guc, -1, 0400) \
+ 	param(int, guc_log_level, -1, 0400) \
++	param(int, guc_log_size_crash, -1, 0400) \
++	param(int, guc_log_size_debug, -1, 0400) \
++	param(int, guc_log_size_capture, -1, 0400) \
+ 	param(char *, guc_firmware_path, NULL, 0400) \
+ 	param(char *, huc_firmware_path, NULL, 0400) \
+ 	param(char *, dmc_firmware_path, NULL, 0400) \
+diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c
+index 630a4e301ef6c..b11b5a2c06639 100644
+--- a/drivers/gpu/drm/mediatek/mtk_dpi.c
++++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
+@@ -462,9 +462,6 @@ static void mtk_dpi_power_off(struct mtk_dpi *dpi)
+ 	if (--dpi->refcount != 0)
+ 		return;
+ 
+-	if (dpi->pinctrl && dpi->pins_gpio)
+-		pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
+-
+ 	mtk_dpi_disable(dpi);
+ 	clk_disable_unprepare(dpi->pixel_clk);
+ 	clk_disable_unprepare(dpi->engine_clk);
+@@ -489,9 +486,6 @@ static int mtk_dpi_power_on(struct mtk_dpi *dpi)
+ 		goto err_pixel;
+ 	}
+ 
+-	if (dpi->pinctrl && dpi->pins_dpi)
+-		pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
+-
+ 	return 0;
+ 
+ err_pixel:
+@@ -722,12 +716,18 @@ static void mtk_dpi_bridge_disable(struct drm_bridge *bridge)
+ 	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
+ 
+ 	mtk_dpi_power_off(dpi);
++
++	if (dpi->pinctrl && dpi->pins_gpio)
++		pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio);
+ }
+ 
+ static void mtk_dpi_bridge_enable(struct drm_bridge *bridge)
+ {
+ 	struct mtk_dpi *dpi = bridge_to_dpi(bridge);
+ 
++	if (dpi->pinctrl && dpi->pins_dpi)
++		pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi);
++
+ 	mtk_dpi_power_on(dpi);
+ 	mtk_dpi_set_display_mode(dpi, &dpi->mode);
+ 	mtk_dpi_enable(dpi);
+diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi.c b/drivers/gpu/drm/mediatek/mtk_hdmi.c
+index 3196189429bcf..7613b0fa2be6e 100644
+--- a/drivers/gpu/drm/mediatek/mtk_hdmi.c
++++ b/drivers/gpu/drm/mediatek/mtk_hdmi.c
+@@ -1203,9 +1203,10 @@ static enum drm_connector_status mtk_hdmi_detect(struct mtk_hdmi *hdmi)
+ 	return mtk_hdmi_update_plugged_status(hdmi);
+ }
+ 
+-static int mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
+-				      const struct drm_display_info *info,
+-				      const struct drm_display_mode *mode)
++static enum drm_mode_status
++mtk_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
++			   const struct drm_display_info *info,
++			   const struct drm_display_mode *mode)
+ {
+ 	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
+ 	struct drm_bridge *next_bridge;
+diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+index 5675bc2a92cf8..3f73b211fa8e3 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
++++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+@@ -116,9 +116,10 @@ static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge,
+ 	return i;
+ }
+ 
+-static int meson_encoder_cvbs_mode_valid(struct drm_bridge *bridge,
+-					const struct drm_display_info *display_info,
+-					const struct drm_display_mode *mode)
++static enum drm_mode_status
++meson_encoder_cvbs_mode_valid(struct drm_bridge *bridge,
++			      const struct drm_display_info *display_info,
++			      const struct drm_display_mode *mode)
+ {
+ 	if (meson_cvbs_get_mode(mode))
+ 		return MODE_OK;
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+index 4d501100b9e45..5804c35ae74b3 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+@@ -1869,7 +1869,7 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse)
+ 
+ 	if (val == UINT_MAX) {
+ 		DRM_DEV_ERROR(dev,
+-			"missing support for speed-bin: %u. Some OPPs may not be supported by hardware",
++			"missing support for speed-bin: %u. Some OPPs may not be supported by hardware\n",
+ 			fuse);
+ 		return UINT_MAX;
+ 	}
+@@ -1879,7 +1879,7 @@ static u32 fuse_to_supp_hw(struct device *dev, struct adreno_rev rev, u32 fuse)
+ 
+ static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev)
+ {
+-	u32 supp_hw = UINT_MAX;
++	u32 supp_hw;
+ 	u32 speedbin;
+ 	int ret;
+ 
+@@ -1891,15 +1891,13 @@ static int a6xx_set_supported_hw(struct device *dev, struct adreno_rev rev)
+ 	if (ret == -ENOENT) {
+ 		return 0;
+ 	} else if (ret) {
+-		DRM_DEV_ERROR(dev,
+-			      "failed to read speed-bin (%d). Some OPPs may not be supported by hardware",
+-			      ret);
+-		goto done;
++		dev_err_probe(dev, ret,
++			      "failed to read speed-bin. Some OPPs may not be supported by hardware\n");
++		return ret;
+ 	}
+ 
+ 	supp_hw = fuse_to_supp_hw(dev, rev, speedbin);
+ 
+-done:
+ 	ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1);
+ 	if (ret)
+ 		return ret;
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+index 52a626117f70f..7f5dba96b2ffa 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+@@ -162,7 +162,7 @@ enum dpu_enc_rc_states {
+  * @vsync_event_work:		worker to handle vsync event for autorefresh
+  * @topology:                   topology of the display
+  * @idle_timeout:		idle timeout duration in milliseconds
+- * @dsc:			msm_display_dsc_config pointer, for DSC-enabled encoders
++ * @dsc:			drm_dsc_config pointer, for DSC-enabled encoders
+  */
+ struct dpu_encoder_virt {
+ 	struct drm_encoder base;
+@@ -208,7 +208,7 @@ struct dpu_encoder_virt {
+ 	bool wide_bus_en;
+ 
+ 	/* DSC configuration */
+-	struct msm_display_dsc_config *dsc;
++	struct drm_dsc_config *dsc;
+ };
+ 
+ #define to_dpu_encoder_virt(x) container_of(x, struct dpu_encoder_virt, base)
+@@ -1791,12 +1791,12 @@ static void dpu_encoder_vsync_event_work_handler(struct kthread_work *work)
+ }
+ 
+ static u32
+-dpu_encoder_dsc_initial_line_calc(struct msm_display_dsc_config *dsc,
++dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config *dsc,
+ 				  u32 enc_ip_width)
+ {
+ 	int ssm_delay, total_pixels, soft_slice_per_enc;
+ 
+-	soft_slice_per_enc = enc_ip_width / dsc->drm->slice_width;
++	soft_slice_per_enc = enc_ip_width / dsc->slice_width;
+ 
+ 	/*
+ 	 * minimum number of initial line pixels is a sum of:
+@@ -1808,16 +1808,16 @@ dpu_encoder_dsc_initial_line_calc(struct msm_display_dsc_config *dsc,
+ 	 * 5. 6 additional pixels as the output of the rate buffer is
+ 	 *    48 bits wide
+ 	 */
+-	ssm_delay = ((dsc->drm->bits_per_component < 10) ? 84 : 92);
+-	total_pixels = ssm_delay * 3 + dsc->drm->initial_xmit_delay + 47;
++	ssm_delay = ((dsc->bits_per_component < 10) ? 84 : 92);
++	total_pixels = ssm_delay * 3 + dsc->initial_xmit_delay + 47;
+ 	if (soft_slice_per_enc > 1)
+ 		total_pixels += (ssm_delay * 3);
+-	return DIV_ROUND_UP(total_pixels, dsc->drm->slice_width);
++	return DIV_ROUND_UP(total_pixels, dsc->slice_width);
+ }
+ 
+ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,
+ 				     struct dpu_hw_pingpong *hw_pp,
+-				     struct msm_display_dsc_config *dsc,
++				     struct drm_dsc_config *dsc,
+ 				     u32 common_mode,
+ 				     u32 initial_lines)
+ {
+@@ -1835,7 +1835,7 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,
+ }
+ 
+ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
+-				 struct msm_display_dsc_config *dsc)
++				 struct drm_dsc_config *dsc)
+ {
+ 	/* coding only for 2LM, 2enc, 1 dsc config */
+ 	struct dpu_encoder_phys *enc_master = dpu_enc->cur_master;
+@@ -1858,14 +1858,15 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
+ 		}
+ 	}
+ 
+-	pic_width = dsc->drm->pic_width;
++	dsc_common_mode = 0;
++	pic_width = dsc->pic_width;
+ 
+ 	dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL;
+ 	if (enc_master->intf_mode == INTF_MODE_VIDEO)
+ 		dsc_common_mode |= DSC_MODE_VIDEO;
+ 
+-	this_frame_slices = pic_width / dsc->drm->slice_width;
+-	intf_ip_w = this_frame_slices * dsc->drm->slice_width;
++	this_frame_slices = pic_width / dsc->slice_width;
++	intf_ip_w = this_frame_slices * dsc->slice_width;
+ 
+ 	/*
+ 	 * dsc merge case: when using 2 encoders for the same stream,
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+index d4d1ecd416e39..9e7236ef34e6d 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+@@ -36,7 +36,7 @@ struct msm_display_info {
+ 	uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY];
+ 	bool is_cmd_mode;
+ 	bool is_te_using_watchdog_timer;
+-	struct msm_display_dsc_config *dsc;
++	struct drm_dsc_config *dsc;
+ };
+ 
+ /**
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
+index 411689ae63825..3662df698dae5 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c
+@@ -37,12 +37,12 @@ static void dpu_hw_dsc_disable(struct dpu_hw_dsc *dsc)
+ }
+ 
+ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc,
+-			      struct msm_display_dsc_config *dsc,
++			      struct drm_dsc_config *dsc,
+ 			      u32 mode,
+ 			      u32 initial_lines)
+ {
+ 	struct dpu_hw_blk_reg_map *c = &hw_dsc->hw;
+-	u32 data, lsb, bpp;
++	u32 data;
+ 	u32 slice_last_group_size;
+ 	u32 det_thresh_flatness;
+ 	bool is_cmd_mode = !(mode & DSC_MODE_VIDEO);
+@@ -52,89 +52,82 @@ static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc,
+ 	if (is_cmd_mode)
+ 		initial_lines += 1;
+ 
+-	slice_last_group_size = 3 - (dsc->drm->slice_width % 3);
++	slice_last_group_size = 3 - (dsc->slice_width % 3);
+ 	data = (initial_lines << 20);
+ 	data |= ((slice_last_group_size - 1) << 18);
+ 	/* bpp is 6.4 format, 4 LSBs bits are for fractional part */
+-	data |= dsc->drm->bits_per_pixel << 12;
+-	lsb = dsc->drm->bits_per_pixel % 4;
+-	bpp = dsc->drm->bits_per_pixel / 4;
+-	bpp *= 4;
+-	bpp <<= 4;
+-	bpp |= lsb;
+-
+-	data |= bpp << 8;
+-	data |= (dsc->drm->block_pred_enable << 7);
+-	data |= (dsc->drm->line_buf_depth << 3);
+-	data |= (dsc->drm->simple_422 << 2);
+-	data |= (dsc->drm->convert_rgb << 1);
+-	data |= dsc->drm->bits_per_component;
++	data |= (dsc->bits_per_pixel << 8);
++	data |= (dsc->block_pred_enable << 7);
++	data |= (dsc->line_buf_depth << 3);
++	data |= (dsc->simple_422 << 2);
++	data |= (dsc->convert_rgb << 1);
++	data |= dsc->bits_per_component;
+ 
+ 	DPU_REG_WRITE(c, DSC_ENC, data);
+ 
+-	data = dsc->drm->pic_width << 16;
+-	data |= dsc->drm->pic_height;
++	data = dsc->pic_width << 16;
++	data |= dsc->pic_height;
+ 	DPU_REG_WRITE(c, DSC_PICTURE, data);
+ 
+-	data = dsc->drm->slice_width << 16;
+-	data |= dsc->drm->slice_height;
++	data = dsc->slice_width << 16;
++	data |= dsc->slice_height;
+ 	DPU_REG_WRITE(c, DSC_SLICE, data);
+ 
+-	data = dsc->drm->slice_chunk_size << 16;
++	data = dsc->slice_chunk_size << 16;
+ 	DPU_REG_WRITE(c, DSC_CHUNK_SIZE, data);
+ 
+-	data = dsc->drm->initial_dec_delay << 16;
+-	data |= dsc->drm->initial_xmit_delay;
++	data = dsc->initial_dec_delay << 16;
++	data |= dsc->initial_xmit_delay;
+ 	DPU_REG_WRITE(c, DSC_DELAY, data);
+ 
+-	data = dsc->drm->initial_scale_value;
++	data = dsc->initial_scale_value;
+ 	DPU_REG_WRITE(c, DSC_SCALE_INITIAL, data);
+ 
+-	data = dsc->drm->scale_decrement_interval;
++	data = dsc->scale_decrement_interval;
+ 	DPU_REG_WRITE(c, DSC_SCALE_DEC_INTERVAL, data);
+ 
+-	data = dsc->drm->scale_increment_interval;
++	data = dsc->scale_increment_interval;
+ 	DPU_REG_WRITE(c, DSC_SCALE_INC_INTERVAL, data);
+ 
+-	data = dsc->drm->first_line_bpg_offset;
++	data = dsc->first_line_bpg_offset;
+ 	DPU_REG_WRITE(c, DSC_FIRST_LINE_BPG_OFFSET, data);
+ 
+-	data = dsc->drm->nfl_bpg_offset << 16;
+-	data |= dsc->drm->slice_bpg_offset;
++	data = dsc->nfl_bpg_offset << 16;
++	data |= dsc->slice_bpg_offset;
+ 	DPU_REG_WRITE(c, DSC_BPG_OFFSET, data);
+ 
+-	data = dsc->drm->initial_offset << 16;
+-	data |= dsc->drm->final_offset;
++	data = dsc->initial_offset << 16;
++	data |= dsc->final_offset;
+ 	DPU_REG_WRITE(c, DSC_DSC_OFFSET, data);
+ 
+-	det_thresh_flatness = 7 + 2 * (dsc->drm->bits_per_component - 8);
++	det_thresh_flatness = 7 + 2 * (dsc->bits_per_component - 8);
+ 	data = det_thresh_flatness << 10;
+-	data |= dsc->drm->flatness_max_qp << 5;
+-	data |= dsc->drm->flatness_min_qp;
++	data |= dsc->flatness_max_qp << 5;
++	data |= dsc->flatness_min_qp;
+ 	DPU_REG_WRITE(c, DSC_FLATNESS, data);
+ 
+-	data = dsc->drm->rc_model_size;
++	data = dsc->rc_model_size;
+ 	DPU_REG_WRITE(c, DSC_RC_MODEL_SIZE, data);
+ 
+-	data = dsc->drm->rc_tgt_offset_low << 18;
+-	data |= dsc->drm->rc_tgt_offset_high << 14;
+-	data |= dsc->drm->rc_quant_incr_limit1 << 9;
+-	data |= dsc->drm->rc_quant_incr_limit0 << 4;
+-	data |= dsc->drm->rc_edge_factor;
++	data = dsc->rc_tgt_offset_low << 18;
++	data |= dsc->rc_tgt_offset_high << 14;
++	data |= dsc->rc_quant_incr_limit1 << 9;
++	data |= dsc->rc_quant_incr_limit0 << 4;
++	data |= dsc->rc_edge_factor;
+ 	DPU_REG_WRITE(c, DSC_RC, data);
+ }
+ 
+ static void dpu_hw_dsc_config_thresh(struct dpu_hw_dsc *hw_dsc,
+-				     struct msm_display_dsc_config *dsc)
++				     struct drm_dsc_config *dsc)
+ {
+-	struct drm_dsc_rc_range_parameters *rc = dsc->drm->rc_range_params;
++	struct drm_dsc_rc_range_parameters *rc = dsc->rc_range_params;
+ 	struct dpu_hw_blk_reg_map *c = &hw_dsc->hw;
+ 	u32 off;
+ 	int i;
+ 
+ 	off = DSC_RC_BUF_THRESH;
+ 	for (i = 0; i < DSC_NUM_BUF_RANGES - 1 ; i++) {
+-		DPU_REG_WRITE(c, off, dsc->drm->rc_buf_thresh[i]);
++		DPU_REG_WRITE(c, off, dsc->rc_buf_thresh[i]);
+ 		off += 4;
+ 	}
+ 
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
+index 45e4118f1fa27..c0b77fe1a6968 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
+@@ -31,7 +31,7 @@ struct dpu_hw_dsc_ops {
+ 	 * @initial_lines: amount of initial lines to be used
+ 	 */
+ 	void (*dsc_config)(struct dpu_hw_dsc *hw_dsc,
+-			   struct msm_display_dsc_config *dsc,
++			   struct drm_dsc_config *dsc,
+ 			   u32 mode,
+ 			   u32 initial_lines);
+ 
+@@ -41,7 +41,7 @@ struct dpu_hw_dsc_ops {
+ 	 * @dsc: panel dsc parameters
+ 	 */
+ 	void (*dsc_config_thresh)(struct dpu_hw_dsc *hw_dsc,
+-				  struct msm_display_dsc_config *dsc);
++				  struct drm_dsc_config *dsc);
+ };
+ 
+ struct dpu_hw_dsc {
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+index b0d21838a1343..29ae5c9613f36 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+@@ -203,7 +203,7 @@ static int mdp5_set_split_display(struct msm_kms *kms,
+ 							  slave_encoder);
+ }
+ 
+-static void mdp5_destroy(struct platform_device *pdev);
++static void mdp5_destroy(struct mdp5_kms *mdp5_kms);
+ 
+ static void mdp5_kms_destroy(struct msm_kms *kms)
+ {
+@@ -223,7 +223,7 @@ static void mdp5_kms_destroy(struct msm_kms *kms)
+ 	}
+ 
+ 	mdp_kms_destroy(&mdp5_kms->base);
+-	mdp5_destroy(mdp5_kms->pdev);
++	mdp5_destroy(mdp5_kms);
+ }
+ 
+ #ifdef CONFIG_DEBUG_FS
+@@ -559,6 +559,8 @@ static int mdp5_kms_init(struct drm_device *dev)
+ 	int irq, i, ret;
+ 
+ 	ret = mdp5_init(to_platform_device(dev->dev), dev);
++	if (ret)
++		return ret;
+ 
+ 	/* priv->kms would have been populated by the MDP5 driver */
+ 	kms = priv->kms;
+@@ -632,9 +634,8 @@ fail:
+ 	return ret;
+ }
+ 
+-static void mdp5_destroy(struct platform_device *pdev)
++static void mdp5_destroy(struct mdp5_kms *mdp5_kms)
+ {
+-	struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
+ 	int i;
+ 
+ 	if (mdp5_kms->ctlm)
+@@ -648,7 +649,7 @@ static void mdp5_destroy(struct platform_device *pdev)
+ 		kfree(mdp5_kms->intfs[i]);
+ 
+ 	if (mdp5_kms->rpm_enabled)
+-		pm_runtime_disable(&pdev->dev);
++		pm_runtime_disable(&mdp5_kms->pdev->dev);
+ 
+ 	drm_atomic_private_obj_fini(&mdp5_kms->glob_state);
+ 	drm_modeset_lock_fini(&mdp5_kms->glob_state_lock);
+@@ -797,8 +798,6 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
+ 		goto fail;
+ 	}
+ 
+-	platform_set_drvdata(pdev, mdp5_kms);
+-
+ 	spin_lock_init(&mdp5_kms->resource_lock);
+ 
+ 	mdp5_kms->dev = dev;
+@@ -839,6 +838,9 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
+ 	 */
+ 	clk_set_rate(mdp5_kms->core_clk, 200000000);
+ 
++	/* set uninit-ed kms */
++	priv->kms = &mdp5_kms->base.base;
++
+ 	pm_runtime_enable(&pdev->dev);
+ 	mdp5_kms->rpm_enabled = true;
+ 
+@@ -890,13 +892,10 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
+ 	if (ret)
+ 		goto fail;
+ 
+-	/* set uninit-ed kms */
+-	priv->kms = &mdp5_kms->base.base;
+-
+ 	return 0;
+ fail:
+ 	if (mdp5_kms)
+-		mdp5_destroy(pdev);
++		mdp5_destroy(mdp5_kms);
+ 	return ret;
+ }
+ 
+@@ -953,7 +952,8 @@ static int mdp5_dev_remove(struct platform_device *pdev)
+ static __maybe_unused int mdp5_runtime_suspend(struct device *dev)
+ {
+ 	struct platform_device *pdev = to_platform_device(dev);
+-	struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
++	struct msm_drm_private *priv = platform_get_drvdata(pdev);
++	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+ 
+ 	DBG("");
+ 
+@@ -963,7 +963,8 @@ static __maybe_unused int mdp5_runtime_suspend(struct device *dev)
+ static __maybe_unused int mdp5_runtime_resume(struct device *dev)
+ {
+ 	struct platform_device *pdev = to_platform_device(dev);
+-	struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
++	struct msm_drm_private *priv = platform_get_drvdata(pdev);
++	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+ 
+ 	DBG("");
+ 
+diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
+index a49f6dbbe8883..c9d9b384ddd03 100644
+--- a/drivers/gpu/drm/msm/dp/dp_display.c
++++ b/drivers/gpu/drm/msm/dp/dp_display.c
+@@ -857,7 +857,7 @@ static int dp_display_set_mode(struct msm_dp *dp_display,
+ 
+ 	dp = container_of(dp_display, struct dp_display_private, dp_display);
+ 
+-	dp->panel->dp_mode.drm_mode = mode->drm_mode;
++	drm_mode_copy(&dp->panel->dp_mode.drm_mode, &mode->drm_mode);
+ 	dp->panel->dp_mode.bpp = mode->bpp;
+ 	dp->panel->dp_mode.capabilities = mode->capabilities;
+ 	dp_panel_init_panel_info(dp->panel);
+diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
+index 3db85b5c0febd..31e452ede71f0 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi.c
++++ b/drivers/gpu/drm/msm/dsi/dsi.c
+@@ -21,7 +21,7 @@ bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi)
+ 	return !(host_flags & MIPI_DSI_MODE_VIDEO);
+ }
+ 
+-struct msm_display_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
++struct drm_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
+ {
+ 	return msm_dsi_host_get_dsc_config(msm_dsi->host);
+ }
+diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
+index 580a1e6358bfc..df46cdda1b433 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi.h
++++ b/drivers/gpu/drm/msm/dsi/dsi.h
+@@ -154,7 +154,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
+ int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
+ void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct mipi_dsi_host *host);
+ void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host);
+-struct msm_display_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host);
++struct drm_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host);
+ 
+ /* dsi phy */
+ struct msm_dsi_phy;
+diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
+index a34078497af12..cf7d5b69aac58 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
++++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
+@@ -21,6 +21,7 @@
+ 
+ #include <video/mipi_display.h>
+ 
++#include <drm/display/drm_dsc_helper.h>
+ #include <drm/drm_of.h>
+ 
+ #include "dsi.h"
+@@ -33,7 +34,7 @@
+ 
+ #define DSI_RESET_TOGGLE_DELAY_MS 20
+ 
+-static int dsi_populate_dsc_params(struct msm_display_dsc_config *dsc);
++static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc);
+ 
+ static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor)
+ {
+@@ -161,7 +162,7 @@ struct msm_dsi_host {
+ 	struct regmap *sfpb;
+ 
+ 	struct drm_display_mode *mode;
+-	struct msm_display_dsc_config *dsc;
++	struct drm_dsc_config *dsc;
+ 
+ 	/* connected device info */
+ 	struct device_node *device_node;
+@@ -916,35 +917,28 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable,
+ 
+ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mode, u32 hdisplay)
+ {
+-	struct msm_display_dsc_config *dsc = msm_host->dsc;
+-	u32 reg, intf_width, reg_ctrl, reg_ctrl2;
++	struct drm_dsc_config *dsc = msm_host->dsc;
++	u32 reg, reg_ctrl, reg_ctrl2;
+ 	u32 slice_per_intf, total_bytes_per_intf;
+ 	u32 pkt_per_line;
+-	u32 bytes_in_slice;
+ 	u32 eol_byte_num;
+ 
+ 	/* first calculate dsc parameters and then program
+ 	 * compress mode registers
+ 	 */
+-	intf_width = hdisplay;
+-	slice_per_intf = DIV_ROUND_UP(intf_width, dsc->drm->slice_width);
++	slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->slice_width);
+ 
+ 	/* If slice_per_pkt is greater than slice_per_intf
+ 	 * then default to 1. This can happen during partial
+ 	 * update.
+ 	 */
+-	if (slice_per_intf > dsc->drm->slice_count)
+-		dsc->drm->slice_count = 1;
++	if (slice_per_intf > dsc->slice_count)
++		dsc->slice_count = 1;
+ 
+-	slice_per_intf = DIV_ROUND_UP(hdisplay, dsc->drm->slice_width);
+-	bytes_in_slice = DIV_ROUND_UP(dsc->drm->slice_width * dsc->drm->bits_per_pixel, 8);
+-
+-	dsc->drm->slice_chunk_size = bytes_in_slice;
+-
+-	total_bytes_per_intf = bytes_in_slice * slice_per_intf;
++	total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
+ 
+ 	eol_byte_num = total_bytes_per_intf % 3;
+-	pkt_per_line = slice_per_intf / dsc->drm->slice_count;
++	pkt_per_line = slice_per_intf / dsc->slice_count;
+ 
+ 	if (is_cmd_mode) /* packet data type */
+ 		reg = DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE);
+@@ -967,7 +961,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mod
+ 		reg_ctrl |= reg;
+ 
+ 		reg_ctrl2 &= ~DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH__MASK;
+-		reg_ctrl2 |= DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH(bytes_in_slice);
++		reg_ctrl2 |= DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH(dsc->slice_chunk_size);
+ 
+ 		dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, reg_ctrl);
+ 		dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, reg_ctrl2);
+@@ -990,6 +984,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+ 	u32 va_end = va_start + mode->vdisplay;
+ 	u32 hdisplay = mode->hdisplay;
+ 	u32 wc;
++	int ret;
+ 
+ 	DBG("");
+ 
+@@ -1009,7 +1004,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+ 	}
+ 
+ 	if (msm_host->dsc) {
+-		struct msm_display_dsc_config *dsc = msm_host->dsc;
++		struct drm_dsc_config *dsc = msm_host->dsc;
+ 
+ 		/* update dsc params with timing params */
+ 		if (!dsc || !mode->hdisplay || !mode->vdisplay) {
+@@ -1018,14 +1013,16 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+ 			return;
+ 		}
+ 
+-		dsc->drm->pic_width = mode->hdisplay;
+-		dsc->drm->pic_height = mode->vdisplay;
+-		DBG("Mode %dx%d\n", dsc->drm->pic_width, dsc->drm->pic_height);
++		dsc->pic_width = mode->hdisplay;
++		dsc->pic_height = mode->vdisplay;
++		DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height);
+ 
+ 		/* we do the calculations for dsc parameters here so that
+ 		 * panel can use these parameters
+ 		 */
+-		dsi_populate_dsc_params(dsc);
++		ret = dsi_populate_dsc_params(msm_host, dsc);
++		if (ret)
++			return;
+ 
+ 		/* Divide the display by 3 but keep back/font porch and
+ 		 * pulse width same
+@@ -1841,113 +1838,65 @@ static char bpg_offset[DSC_NUM_BUF_RANGES] = {
+ 	2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
+ };
+ 
+-static int dsi_populate_dsc_params(struct msm_display_dsc_config *dsc)
+-{
+-	int mux_words_size;
+-	int groups_per_line, groups_total;
+-	int min_rate_buffer_size;
+-	int hrd_delay;
+-	int pre_num_extra_mux_bits, num_extra_mux_bits;
+-	int slice_bits;
+-	int target_bpp_x16;
+-	int data;
+-	int final_value, final_scale;
++static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc)
++{
+ 	int i;
++	u16 bpp = dsc->bits_per_pixel >> 4;
++
++	if (dsc->bits_per_pixel & 0xf) {
++		DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support fractional bits_per_pixel\n");
++		return -EINVAL;
++	}
+ 
+-	dsc->drm->rc_model_size = 8192;
+-	dsc->drm->first_line_bpg_offset = 12;
+-	dsc->drm->rc_edge_factor = 6;
+-	dsc->drm->rc_tgt_offset_high = 3;
+-	dsc->drm->rc_tgt_offset_low = 3;
+-	dsc->drm->simple_422 = 0;
+-	dsc->drm->convert_rgb = 1;
+-	dsc->drm->vbr_enable = 0;
++	if (dsc->bits_per_component != 8) {
++		DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support bits_per_component != 8 yet\n");
++		return -EOPNOTSUPP;
++	}
++
++	dsc->rc_model_size = 8192;
++	dsc->first_line_bpg_offset = 12;
++	dsc->rc_edge_factor = 6;
++	dsc->rc_tgt_offset_high = 3;
++	dsc->rc_tgt_offset_low = 3;
++	dsc->simple_422 = 0;
++	dsc->convert_rgb = 1;
++	dsc->vbr_enable = 0;
+ 
+ 	/* handle only bpp = bpc = 8 */
+ 	for (i = 0; i < DSC_NUM_BUF_RANGES - 1 ; i++)
+-		dsc->drm->rc_buf_thresh[i] = dsi_dsc_rc_buf_thresh[i];
++		dsc->rc_buf_thresh[i] = dsi_dsc_rc_buf_thresh[i];
+ 
+ 	for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
+-		dsc->drm->rc_range_params[i].range_min_qp = min_qp[i];
+-		dsc->drm->rc_range_params[i].range_max_qp = max_qp[i];
+-		dsc->drm->rc_range_params[i].range_bpg_offset = bpg_offset[i];
++		dsc->rc_range_params[i].range_min_qp = min_qp[i];
++		dsc->rc_range_params[i].range_max_qp = max_qp[i];
++		/*
++		 * Range BPG Offset contains two's-complement signed values that fill
++		 * 8 bits, yet the registers and DCS PPS field are only 6 bits wide.
++		 */
++		dsc->rc_range_params[i].range_bpg_offset = bpg_offset[i] & DSC_RANGE_BPG_OFFSET_MASK;
+ 	}
+ 
+-	dsc->drm->initial_offset = 6144; /* Not bpp 12 */
+-	if (dsc->drm->bits_per_pixel != 8)
+-		dsc->drm->initial_offset = 2048;	/* bpp = 12 */
++	dsc->initial_offset = 6144;		/* Not bpp 12 */
++	if (bpp != 8)
++		dsc->initial_offset = 2048;	/* bpp = 12 */
+ 
+-	mux_words_size = 48;		/* bpc == 8/10 */
+-	if (dsc->drm->bits_per_component == 12)
+-		mux_words_size = 64;
++	if (dsc->bits_per_component <= 10)
++		dsc->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
++	else
++		dsc->mux_word_size = DSC_MUX_WORD_SIZE_12_BPC;
+ 
+-	dsc->drm->initial_xmit_delay = 512;
+-	dsc->drm->initial_scale_value = 32;
+-	dsc->drm->first_line_bpg_offset = 12;
+-	dsc->drm->line_buf_depth = dsc->drm->bits_per_component + 1;
++	dsc->initial_xmit_delay = 512;
++	dsc->initial_scale_value = 32;
++	dsc->first_line_bpg_offset = 12;
++	dsc->line_buf_depth = dsc->bits_per_component + 1;
+ 
+ 	/* bpc 8 */
+-	dsc->drm->flatness_min_qp = 3;
+-	dsc->drm->flatness_max_qp = 12;
+-	dsc->drm->rc_quant_incr_limit0 = 11;
+-	dsc->drm->rc_quant_incr_limit1 = 11;
+-	dsc->drm->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
+-
+-	/* FIXME: need to call drm_dsc_compute_rc_parameters() so that rest of
+-	 * params are calculated
+-	 */
+-	groups_per_line = DIV_ROUND_UP(dsc->drm->slice_width, 3);
+-	dsc->drm->slice_chunk_size = dsc->drm->slice_width * dsc->drm->bits_per_pixel / 8;
+-	if ((dsc->drm->slice_width * dsc->drm->bits_per_pixel) % 8)
+-		dsc->drm->slice_chunk_size++;
+-
+-	/* rbs-min */
+-	min_rate_buffer_size =  dsc->drm->rc_model_size - dsc->drm->initial_offset +
+-				dsc->drm->initial_xmit_delay * dsc->drm->bits_per_pixel +
+-				groups_per_line * dsc->drm->first_line_bpg_offset;
+-
+-	hrd_delay = DIV_ROUND_UP(min_rate_buffer_size, dsc->drm->bits_per_pixel);
+-
+-	dsc->drm->initial_dec_delay = hrd_delay - dsc->drm->initial_xmit_delay;
++	dsc->flatness_min_qp = 3;
++	dsc->flatness_max_qp = 12;
++	dsc->rc_quant_incr_limit0 = 11;
++	dsc->rc_quant_incr_limit1 = 11;
+ 
+-	dsc->drm->initial_scale_value = 8 * dsc->drm->rc_model_size /
+-				       (dsc->drm->rc_model_size - dsc->drm->initial_offset);
+-
+-	slice_bits = 8 * dsc->drm->slice_chunk_size * dsc->drm->slice_height;
+-
+-	groups_total = groups_per_line * dsc->drm->slice_height;
+-
+-	data = dsc->drm->first_line_bpg_offset * 2048;
+-
+-	dsc->drm->nfl_bpg_offset = DIV_ROUND_UP(data, (dsc->drm->slice_height - 1));
+-
+-	pre_num_extra_mux_bits = 3 * (mux_words_size + (4 * dsc->drm->bits_per_component + 4) - 2);
+-
+-	num_extra_mux_bits = pre_num_extra_mux_bits - (mux_words_size -
+-			     ((slice_bits - pre_num_extra_mux_bits) % mux_words_size));
+-
+-	data = 2048 * (dsc->drm->rc_model_size - dsc->drm->initial_offset + num_extra_mux_bits);
+-	dsc->drm->slice_bpg_offset = DIV_ROUND_UP(data, groups_total);
+-
+-	/* bpp * 16 + 0.5 */
+-	data = dsc->drm->bits_per_pixel * 16;
+-	data *= 2;
+-	data++;
+-	data /= 2;
+-	target_bpp_x16 = data;
+-
+-	data = (dsc->drm->initial_xmit_delay * target_bpp_x16) / 16;
+-	final_value =  dsc->drm->rc_model_size - data + num_extra_mux_bits;
+-	dsc->drm->final_offset = final_value;
+-
+-	final_scale = 8 * dsc->drm->rc_model_size / (dsc->drm->rc_model_size - final_value);
+-
+-	data = (final_scale - 9) * (dsc->drm->nfl_bpg_offset + dsc->drm->slice_bpg_offset);
+-	dsc->drm->scale_increment_interval = (2048 * dsc->drm->final_offset) / data;
+-
+-	dsc->drm->scale_decrement_interval = groups_per_line / (dsc->drm->initial_scale_value - 8);
+-
+-	return 0;
++	return drm_dsc_compute_rc_parameters(dsc);
+ }
+ 
+ static int dsi_host_parse_dt(struct msm_dsi_host *msm_host)
+@@ -2165,17 +2114,8 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
+ 	msm_host->dev = dev;
+ 	panel = msm_dsi_host_get_panel(&msm_host->base);
+ 
+-	if (!IS_ERR(panel) && panel->dsc) {
+-		struct msm_display_dsc_config *dsc = msm_host->dsc;
+-
+-		if (!dsc) {
+-			dsc = devm_kzalloc(&msm_host->pdev->dev, sizeof(*dsc), GFP_KERNEL);
+-			if (!dsc)
+-				return -ENOMEM;
+-			dsc->drm = panel->dsc;
+-			msm_host->dsc = dsc;
+-		}
+-	}
++	if (!IS_ERR(panel) && panel->dsc)
++		msm_host->dsc = panel->dsc;
+ 
+ 	ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
+ 	if (ret) {
+@@ -2659,22 +2599,22 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
+ 					    const struct drm_display_mode *mode)
+ {
+ 	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+-	struct msm_display_dsc_config *dsc = msm_host->dsc;
++	struct drm_dsc_config *dsc = msm_host->dsc;
+ 	int pic_width = mode->hdisplay;
+ 	int pic_height = mode->vdisplay;
+ 
+ 	if (!msm_host->dsc)
+ 		return MODE_OK;
+ 
+-	if (pic_width % dsc->drm->slice_width) {
++	if (pic_width % dsc->slice_width) {
+ 		pr_err("DSI: pic_width %d has to be multiple of slice %d\n",
+-		       pic_width, dsc->drm->slice_width);
++		       pic_width, dsc->slice_width);
+ 		return MODE_H_ILLEGAL;
+ 	}
+ 
+-	if (pic_height % dsc->drm->slice_height) {
++	if (pic_height % dsc->slice_height) {
+ 		pr_err("DSI: pic_height %d has to be multiple of slice %d\n",
+-		       pic_height, dsc->drm->slice_height);
++		       pic_height, dsc->slice_height);
+ 		return MODE_V_ILLEGAL;
+ 	}
+ 
+@@ -2771,7 +2711,7 @@ void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host)
+ 				DSI_TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER_SW_TRIGGER);
+ }
+ 
+-struct msm_display_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host)
++struct drm_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host)
+ {
+ 	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+ 
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
+index f28fb21e38911..8cd5d50639a53 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
+@@ -252,7 +252,7 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev)
+ 	if (hdmi->hpd_gpiod)
+ 		gpiod_set_consumer_name(hdmi->hpd_gpiod, "HDMI_HPD");
+ 
+-	pm_runtime_enable(&pdev->dev);
++	devm_pm_runtime_enable(&pdev->dev);
+ 
+ 	hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);
+ 
+diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
+index 80da0d3cfdc13..03e5b6863319d 100644
+--- a/drivers/gpu/drm/msm/msm_drv.h
++++ b/drivers/gpu/drm/msm/msm_drv.h
+@@ -96,11 +96,6 @@ struct msm_drm_thread {
+ 	struct kthread_worker *worker;
+ };
+ 
+-/* DSC config */
+-struct msm_display_dsc_config {
+-	struct drm_dsc_config *drm;
+-};
+-
+ struct msm_drm_private {
+ 
+ 	struct drm_device *dev;
+@@ -290,7 +285,7 @@ void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi *msm_dsi
+ bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi);
+ bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi);
+ bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi);
+-struct msm_display_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi);
++struct drm_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi);
+ #else
+ static inline void __init msm_dsi_register(void)
+ {
+@@ -320,7 +315,7 @@ static inline bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi)
+ 	return false;
+ }
+ 
+-static inline struct msm_display_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
++static inline struct drm_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
+ {
+ 	return NULL;
+ }
+diff --git a/drivers/gpu/drm/mxsfb/lcdif_kms.c b/drivers/gpu/drm/mxsfb/lcdif_kms.c
+index 1bec1279c8b56..d419c61c3407c 100644
+--- a/drivers/gpu/drm/mxsfb/lcdif_kms.c
++++ b/drivers/gpu/drm/mxsfb/lcdif_kms.c
+@@ -5,6 +5,7 @@
+  * This code is based on drivers/gpu/drm/mxsfb/mxsfb*
+  */
+ 
++#include <linux/bitfield.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
+ #include <linux/iopoll.h>
+@@ -53,16 +54,22 @@ static void lcdif_set_formats(struct lcdif_drm_private *lcdif,
+ 		writel(DISP_PARA_LINE_PATTERN_UYVY_H,
+ 		       lcdif->base + LCDC_V8_DISP_PARA);
+ 
+-		/* CSC: BT.601 Full Range RGB to YCbCr coefficients. */
+-		writel(CSC0_COEF0_A2(0x096) | CSC0_COEF0_A1(0x04c),
++		/*
++		 * CSC: BT.601 Limited Range RGB to YCbCr coefficients.
++		 *
++		 * |Y |   | 0.2568  0.5041  0.0979|   |R|   |16 |
++		 * |Cb| = |-0.1482 -0.2910  0.4392| * |G| + |128|
++		 * |Cr|   | 0.4392  0.4392 -0.3678|   |B|   |128|
++		 */
++		writel(CSC0_COEF0_A2(0x081) | CSC0_COEF0_A1(0x041),
+ 		       lcdif->base + LCDC_V8_CSC0_COEF0);
+-		writel(CSC0_COEF1_B1(0x7d5) | CSC0_COEF1_A3(0x01d),
++		writel(CSC0_COEF1_B1(0x7db) | CSC0_COEF1_A3(0x019),
+ 		       lcdif->base + LCDC_V8_CSC0_COEF1);
+-		writel(CSC0_COEF2_B3(0x080) | CSC0_COEF2_B2(0x7ac),
++		writel(CSC0_COEF2_B3(0x070) | CSC0_COEF2_B2(0x7b6),
+ 		       lcdif->base + LCDC_V8_CSC0_COEF2);
+-		writel(CSC0_COEF3_C2(0x795) | CSC0_COEF3_C1(0x080),
++		writel(CSC0_COEF3_C2(0x7a2) | CSC0_COEF3_C1(0x070),
+ 		       lcdif->base + LCDC_V8_CSC0_COEF3);
+-		writel(CSC0_COEF4_D1(0x000) | CSC0_COEF4_C3(0x7ec),
++		writel(CSC0_COEF4_D1(0x010) | CSC0_COEF4_C3(0x7ee),
+ 		       lcdif->base + LCDC_V8_CSC0_COEF4);
+ 		writel(CSC0_COEF5_D3(0x080) | CSC0_COEF5_D2(0x080),
+ 		       lcdif->base + LCDC_V8_CSC0_COEF5);
+@@ -143,14 +150,36 @@ static void lcdif_set_mode(struct lcdif_drm_private *lcdif, u32 bus_flags)
+ 	       CTRLDESCL0_1_WIDTH(m->crtc_hdisplay),
+ 	       lcdif->base + LCDC_V8_CTRLDESCL0_1);
+ 
+-	writel(CTRLDESCL0_3_PITCH(lcdif->crtc.primary->state->fb->pitches[0]),
+-	       lcdif->base + LCDC_V8_CTRLDESCL0_3);
++	/*
++	 * Undocumented P_SIZE and T_SIZE register but those written in the
++	 * downstream kernel those registers control the AXI burst size. As of
++	 * now there are two known values:
++	 *  1 - 128Byte
++	 *  2 - 256Byte
++	 * Downstream set it to 256B burst size to improve the memory
++	 * efficiency so set it here too.
++	 */
++	ctrl = CTRLDESCL0_3_P_SIZE(2) | CTRLDESCL0_3_T_SIZE(2) |
++	       CTRLDESCL0_3_PITCH(lcdif->crtc.primary->state->fb->pitches[0]);
++	writel(ctrl, lcdif->base + LCDC_V8_CTRLDESCL0_3);
+ }
+ 
+ static void lcdif_enable_controller(struct lcdif_drm_private *lcdif)
+ {
+ 	u32 reg;
+ 
++	/* Set FIFO Panic watermarks, low 1/3, high 2/3 . */
++	writel(FIELD_PREP(PANIC0_THRES_LOW_MASK, 1 * PANIC0_THRES_MAX / 3) |
++	       FIELD_PREP(PANIC0_THRES_HIGH_MASK, 2 * PANIC0_THRES_MAX / 3),
++	       lcdif->base + LCDC_V8_PANIC0_THRES);
++
++	/*
++	 * Enable FIFO Panic, this does not generate interrupt, but
++	 * boosts NoC priority based on FIFO Panic watermarks.
++	 */
++	writel(INT_ENABLE_D1_PLANE_PANIC_EN,
++	       lcdif->base + LCDC_V8_INT_ENABLE_D1);
++
+ 	reg = readl(lcdif->base + LCDC_V8_DISP_PARA);
+ 	reg |= DISP_PARA_DISP_ON;
+ 	writel(reg, lcdif->base + LCDC_V8_DISP_PARA);
+@@ -178,6 +207,9 @@ static void lcdif_disable_controller(struct lcdif_drm_private *lcdif)
+ 	reg = readl(lcdif->base + LCDC_V8_DISP_PARA);
+ 	reg &= ~DISP_PARA_DISP_ON;
+ 	writel(reg, lcdif->base + LCDC_V8_DISP_PARA);
++
++	/* Disable FIFO Panic NoC priority booster. */
++	writel(0, lcdif->base + LCDC_V8_INT_ENABLE_D1);
+ }
+ 
+ static void lcdif_reset_block(struct lcdif_drm_private *lcdif)
+diff --git a/drivers/gpu/drm/mxsfb/lcdif_regs.h b/drivers/gpu/drm/mxsfb/lcdif_regs.h
+index c70220651e3a5..37f0d9a06b104 100644
+--- a/drivers/gpu/drm/mxsfb/lcdif_regs.h
++++ b/drivers/gpu/drm/mxsfb/lcdif_regs.h
+@@ -190,6 +190,10 @@
+ #define CTRLDESCL0_1_WIDTH(n)		((n) & 0xffff)
+ #define CTRLDESCL0_1_WIDTH_MASK		GENMASK(15, 0)
+ 
++#define CTRLDESCL0_3_P_SIZE(n)		(((n) << 20) & CTRLDESCL0_3_P_SIZE_MASK)
++#define CTRLDESCL0_3_P_SIZE_MASK	GENMASK(22, 20)
++#define CTRLDESCL0_3_T_SIZE(n)		(((n) << 16) & CTRLDESCL0_3_T_SIZE_MASK)
++#define CTRLDESCL0_3_T_SIZE_MASK	GENMASK(17, 16)
+ #define CTRLDESCL0_3_PITCH(n)		((n) & 0xffff)
+ #define CTRLDESCL0_3_PITCH_MASK		GENMASK(15, 0)
+ 
+@@ -248,6 +252,7 @@
+ 
+ #define PANIC0_THRES_LOW_MASK		GENMASK(24, 16)
+ #define PANIC0_THRES_HIGH_MASK		GENMASK(8, 0)
++#define PANIC0_THRES_MAX		511
+ 
+ #define LCDIF_MIN_XRES			120
+ #define LCDIF_MIN_YRES			120
+diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7701.c b/drivers/gpu/drm/panel/panel-sitronix-st7701.c
+index 320a2a8fd4592..098955526b687 100644
+--- a/drivers/gpu/drm/panel/panel-sitronix-st7701.c
++++ b/drivers/gpu/drm/panel/panel-sitronix-st7701.c
+@@ -384,7 +384,15 @@ static int st7701_dsi_probe(struct mipi_dsi_device *dsi)
+ 	st7701->dsi = dsi;
+ 	st7701->desc = desc;
+ 
+-	return mipi_dsi_attach(dsi);
++	ret = mipi_dsi_attach(dsi);
++	if (ret)
++		goto err_attach;
++
++	return 0;
++
++err_attach:
++	drm_panel_remove(&st7701->panel);
++	return ret;
+ }
+ 
+ static int st7701_dsi_remove(struct mipi_dsi_device *dsi)
+diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
+index 33121655d50bb..63bdc9f6fc243 100644
+--- a/drivers/gpu/drm/radeon/radeon_bios.c
++++ b/drivers/gpu/drm/radeon/radeon_bios.c
+@@ -227,6 +227,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
+ 
+ 	if (!found)
+ 		return false;
++	pci_dev_put(pdev);
+ 
+ 	rdev->bios = kmalloc(size, GFP_KERNEL);
+ 	if (!rdev->bios) {
+@@ -612,13 +613,14 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+ 	acpi_size tbl_size;
+ 	UEFI_ACPI_VFCT *vfct;
+ 	unsigned offset;
++	bool r = false;
+ 
+ 	if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ 		return false;
+ 	tbl_size = hdr->length;
+ 	if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+ 		DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
+-		return false;
++		goto out;
+ 	}
+ 
+ 	vfct = (UEFI_ACPI_VFCT *)hdr;
+@@ -631,13 +633,13 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+ 		offset += sizeof(VFCT_IMAGE_HEADER);
+ 		if (offset > tbl_size) {
+ 			DRM_ERROR("ACPI VFCT image header truncated\n");
+-			return false;
++			goto out;
+ 		}
+ 
+ 		offset += vhdr->ImageLength;
+ 		if (offset > tbl_size) {
+ 			DRM_ERROR("ACPI VFCT image truncated\n");
+-			return false;
++			goto out;
+ 		}
+ 
+ 		if (vhdr->ImageLength &&
+@@ -649,15 +651,18 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+ 			rdev->bios = kmemdup(&vbios->VbiosContent,
+ 					     vhdr->ImageLength,
+ 					     GFP_KERNEL);
++			if (rdev->bios)
++				r = true;
+ 
+-			if (!rdev->bios)
+-				return false;
+-			return true;
++			goto out;
+ 		}
+ 	}
+ 
+ 	DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
+-	return false;
++
++out:
++	acpi_put_table(hdr);
++	return r;
+ }
+ #else
+ static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
+index f6e6a6d5d987b..b3c29ca7726e0 100644
+--- a/drivers/gpu/drm/rcar-du/Kconfig
++++ b/drivers/gpu/drm/rcar-du/Kconfig
+@@ -41,8 +41,6 @@ config DRM_RCAR_LVDS
+ 	depends on DRM_RCAR_USE_LVDS
+ 	select DRM_KMS_HELPER
+ 	select DRM_PANEL
+-	select OF_FLATTREE
+-	select OF_OVERLAY
+ 
+ config DRM_RCAR_MIPI_DSI
+ 	tristate "R-Car DU MIPI DSI Encoder Support"
+diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
+index 518ee13b1d6f4..8526dda919317 100644
+--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
++++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
+@@ -571,7 +571,7 @@ static void cdn_dp_encoder_mode_set(struct drm_encoder *encoder,
+ 	video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
+ 	video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
+ 
+-	memcpy(&dp->mode, adjusted, sizeof(*mode));
++	drm_mode_copy(&dp->mode, adjusted);
+ }
+ 
+ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
+diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+index 1aa3700551f4d..1e1a8bc6c8567 100644
+--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+@@ -1201,7 +1201,7 @@ static int dw_mipi_dsi_dphy_power_on(struct phy *phy)
+ 		return i;
+ 	}
+ 
+-	ret = pm_runtime_get_sync(dsi->dev);
++	ret = pm_runtime_resume_and_get(dsi->dev);
+ 	if (ret < 0) {
+ 		DRM_DEV_ERROR(dsi->dev, "failed to enable device: %d\n", ret);
+ 		return ret;
+diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c
+index 87b2243ea23e3..f51774866f412 100644
+--- a/drivers/gpu/drm/rockchip/inno_hdmi.c
++++ b/drivers/gpu/drm/rockchip/inno_hdmi.c
+@@ -499,7 +499,7 @@ static void inno_hdmi_encoder_mode_set(struct drm_encoder *encoder,
+ 	inno_hdmi_setup(hdmi, adj_mode);
+ 
+ 	/* Store the display mode for plugin/DPMS poweron events */
+-	memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
++	drm_mode_copy(&hdmi->previous_mode, adj_mode);
+ }
+ 
+ static void inno_hdmi_encoder_enable(struct drm_encoder *encoder)
+diff --git a/drivers/gpu/drm/rockchip/rk3066_hdmi.c b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+index cf2cf51091a3e..90145ad969841 100644
+--- a/drivers/gpu/drm/rockchip/rk3066_hdmi.c
++++ b/drivers/gpu/drm/rockchip/rk3066_hdmi.c
+@@ -395,7 +395,7 @@ rk3066_hdmi_encoder_mode_set(struct drm_encoder *encoder,
+ 	struct rk3066_hdmi *hdmi = encoder_to_rk3066_hdmi(encoder);
+ 
+ 	/* Store the display mode for plugin/DPMS poweron events. */
+-	memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode));
++	drm_mode_copy(&hdmi->previous_mode, adj_mode);
+ }
+ 
+ static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder)
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+index ad3958b6f8bf3..9a039a31fe48e 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+@@ -605,7 +605,7 @@ static int vop_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
+ 	struct vop *vop = to_vop(crtc);
+ 	int ret, i;
+ 
+-	ret = pm_runtime_get_sync(vop->dev);
++	ret = pm_runtime_resume_and_get(vop->dev);
+ 	if (ret < 0) {
+ 		DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
+ 		return ret;
+@@ -1953,7 +1953,7 @@ static int vop_initial(struct vop *vop)
+ 		return PTR_ERR(vop->dclk);
+ 	}
+ 
+-	ret = pm_runtime_get_sync(vop->dev);
++	ret = pm_runtime_resume_and_get(vop->dev);
+ 	if (ret < 0) {
+ 		DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
+ 		return ret;
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+index 1fc04019dfd83..6dc14ea7f6fc8 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+@@ -823,7 +823,7 @@ static void vop2_enable(struct vop2 *vop2)
+ {
+ 	int ret;
+ 
+-	ret = pm_runtime_get_sync(vop2->dev);
++	ret = pm_runtime_resume_and_get(vop2->dev);
+ 	if (ret < 0) {
+ 		drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret);
+ 		return;
+diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
+index 5a284332ec49e..68f6ebb33460b 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
++++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
+@@ -152,7 +152,7 @@ static int rk3288_lvds_poweron(struct rockchip_lvds *lvds)
+ 		DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret);
+ 		return ret;
+ 	}
+-	ret = pm_runtime_get_sync(lvds->dev);
++	ret = pm_runtime_resume_and_get(lvds->dev);
+ 	if (ret < 0) {
+ 		DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
+ 		clk_disable(lvds->pclk);
+@@ -336,16 +336,20 @@ static int px30_lvds_poweron(struct rockchip_lvds *lvds)
+ {
+ 	int ret;
+ 
+-	ret = pm_runtime_get_sync(lvds->dev);
++	ret = pm_runtime_resume_and_get(lvds->dev);
+ 	if (ret < 0) {
+ 		DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
+ 		return ret;
+ 	}
+ 
+ 	/* Enable LVDS mode */
+-	return regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
++	ret = regmap_update_bits(lvds->grf, PX30_LVDS_GRF_PD_VO_CON1,
+ 				  PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1),
+ 				  PX30_LVDS_MODE_EN(1) | PX30_LVDS_P2S_EN(1));
++	if (ret)
++		pm_runtime_put(lvds->dev);
++
++	return ret;
+ }
+ 
+ static void px30_lvds_poweroff(struct rockchip_lvds *lvds)
+diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
+index b6ee8a82e656c..577c477b5f467 100644
+--- a/drivers/gpu/drm/sti/sti_dvo.c
++++ b/drivers/gpu/drm/sti/sti_dvo.c
+@@ -288,7 +288,7 @@ static void sti_dvo_set_mode(struct drm_bridge *bridge,
+ 
+ 	DRM_DEBUG_DRIVER("\n");
+ 
+-	memcpy(&dvo->mode, mode, sizeof(struct drm_display_mode));
++	drm_mode_copy(&dvo->mode, mode);
+ 
+ 	/* According to the path used (main or aux), the dvo clocks should
+ 	 * have a different parent clock. */
+@@ -346,8 +346,9 @@ static int sti_dvo_connector_get_modes(struct drm_connector *connector)
+ 
+ #define CLK_TOLERANCE_HZ 50
+ 
+-static int sti_dvo_connector_mode_valid(struct drm_connector *connector,
+-					struct drm_display_mode *mode)
++static enum drm_mode_status
++sti_dvo_connector_mode_valid(struct drm_connector *connector,
++			     struct drm_display_mode *mode)
+ {
+ 	int target = mode->clock * 1000;
+ 	int target_min = target - CLK_TOLERANCE_HZ;
+diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
+index 03cc401ed5934..15097ac679314 100644
+--- a/drivers/gpu/drm/sti/sti_hda.c
++++ b/drivers/gpu/drm/sti/sti_hda.c
+@@ -524,7 +524,7 @@ static void sti_hda_set_mode(struct drm_bridge *bridge,
+ 
+ 	DRM_DEBUG_DRIVER("\n");
+ 
+-	memcpy(&hda->mode, mode, sizeof(struct drm_display_mode));
++	drm_mode_copy(&hda->mode, mode);
+ 
+ 	if (!hda_get_mode_idx(hda->mode, &mode_idx)) {
+ 		DRM_ERROR("Undefined mode\n");
+@@ -601,8 +601,9 @@ static int sti_hda_connector_get_modes(struct drm_connector *connector)
+ 
+ #define CLK_TOLERANCE_HZ 50
+ 
+-static int sti_hda_connector_mode_valid(struct drm_connector *connector,
+-					struct drm_display_mode *mode)
++static enum drm_mode_status
++sti_hda_connector_mode_valid(struct drm_connector *connector,
++			     struct drm_display_mode *mode)
+ {
+ 	int target = mode->clock * 1000;
+ 	int target_min = target - CLK_TOLERANCE_HZ;
+diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
+index cb82622877d20..8539fe1fedc4c 100644
+--- a/drivers/gpu/drm/sti/sti_hdmi.c
++++ b/drivers/gpu/drm/sti/sti_hdmi.c
+@@ -941,7 +941,7 @@ static void sti_hdmi_set_mode(struct drm_bridge *bridge,
+ 	DRM_DEBUG_DRIVER("\n");
+ 
+ 	/* Copy the drm display mode in the connector local structure */
+-	memcpy(&hdmi->mode, mode, sizeof(struct drm_display_mode));
++	drm_mode_copy(&hdmi->mode, mode);
+ 
+ 	/* Update clock framerate according to the selected mode */
+ 	ret = clk_set_rate(hdmi->clk_pix, mode->clock * 1000);
+@@ -1004,8 +1004,9 @@ fail:
+ 
+ #define CLK_TOLERANCE_HZ 50
+ 
+-static int sti_hdmi_connector_mode_valid(struct drm_connector *connector,
+-					struct drm_display_mode *mode)
++static enum drm_mode_status
++sti_hdmi_connector_mode_valid(struct drm_connector *connector,
++			      struct drm_display_mode *mode)
+ {
+ 	int target = mode->clock * 1000;
+ 	int target_min = target - CLK_TOLERANCE_HZ;
+diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
+index 747abafb6a5cf..b8035b3be3d32 100644
+--- a/drivers/gpu/drm/tegra/dc.c
++++ b/drivers/gpu/drm/tegra/dc.c
+@@ -3206,8 +3206,10 @@ static int tegra_dc_probe(struct platform_device *pdev)
+ 	usleep_range(2000, 4000);
+ 
+ 	err = reset_control_assert(dc->rst);
+-	if (err < 0)
++	if (err < 0) {
++		clk_disable_unprepare(dc->clk);
+ 		return err;
++	}
+ 
+ 	usleep_range(2000, 4000);
+ 
+diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+index 8275bba636119..ab125f79408f2 100644
+--- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c
++++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+@@ -237,6 +237,10 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata)
+ 		in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8,
+ 								  &cl_data->sensor_dma_addr[i],
+ 								  GFP_KERNEL);
++		if (!in_data->sensor_virt_addr[i]) {
++			rc = -ENOMEM;
++			goto cleanup;
++		}
+ 		cl_data->sensor_sts[i] = SENSOR_DISABLED;
+ 		cl_data->sensor_requested_cnt[i] = 0;
+ 		cl_data->cur_hid_dev = i;
+diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
+index 6970797cdc56d..c671ce94671ca 100644
+--- a/drivers/hid/hid-apple.c
++++ b/drivers/hid/hid-apple.c
+@@ -314,6 +314,7 @@ static const struct apple_key_translation swapped_option_cmd_keys[] = {
+ 
+ static const struct apple_key_translation swapped_fn_leftctrl_keys[] = {
+ 	{ KEY_FN, KEY_LEFTCTRL },
++	{ KEY_LEFTCTRL, KEY_FN },
+ 	{ }
+ };
+ 
+@@ -375,24 +376,40 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
+ 	struct apple_sc *asc = hid_get_drvdata(hid);
+ 	const struct apple_key_translation *trans, *table;
+ 	bool do_translate;
+-	u16 code = 0;
++	u16 code = usage->code;
+ 	unsigned int real_fnmode;
+ 
+-	u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN);
+-
+-	if (usage->code == fn_keycode) {
+-		asc->fn_on = !!value;
+-		input_event_with_scancode(input, usage->type, KEY_FN,
+-				usage->hid, value);
+-		return 1;
+-	}
+-
+ 	if (fnmode == 3) {
+ 		real_fnmode = (asc->quirks & APPLE_IS_NON_APPLE) ? 2 : 1;
+ 	} else {
+ 		real_fnmode = fnmode;
+ 	}
+ 
++	if (swap_fn_leftctrl) {
++		trans = apple_find_translation(swapped_fn_leftctrl_keys, code);
++
++		if (trans)
++			code = trans->to;
++	}
++
++	if (iso_layout > 0 || (iso_layout < 0 && (asc->quirks & APPLE_ISO_TILDE_QUIRK) &&
++			hid->country == HID_COUNTRY_INTERNATIONAL_ISO)) {
++		trans = apple_find_translation(apple_iso_keyboard, code);
++
++		if (trans)
++			code = trans->to;
++	}
++
++	if (swap_opt_cmd) {
++		trans = apple_find_translation(swapped_option_cmd_keys, code);
++
++		if (trans)
++			code = trans->to;
++	}
++
++	if (code == KEY_FN)
++		asc->fn_on = !!value;
++
+ 	if (real_fnmode) {
+ 		if (hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI ||
+ 		    hid->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO ||
+@@ -430,15 +447,18 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
+ 		else
+ 			table = apple_fn_keys;
+ 
+-		trans = apple_find_translation (table, usage->code);
++		trans = apple_find_translation(table, code);
+ 
+ 		if (trans) {
+-			if (test_bit(trans->from, input->key))
++			bool from_is_set = test_bit(trans->from, input->key);
++			bool to_is_set = test_bit(trans->to, input->key);
++
++			if (from_is_set)
+ 				code = trans->from;
+-			else if (test_bit(trans->to, input->key))
++			else if (to_is_set)
+ 				code = trans->to;
+ 
+-			if (!code) {
++			if (!(from_is_set || to_is_set)) {
+ 				if (trans->flags & APPLE_FLAG_FKEY) {
+ 					switch (real_fnmode) {
+ 					case 1:
+@@ -455,62 +475,31 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
+ 					do_translate = asc->fn_on;
+ 				}
+ 
+-				code = do_translate ? trans->to : trans->from;
++				if (do_translate)
++					code = trans->to;
+ 			}
+-
+-			input_event_with_scancode(input, usage->type, code,
+-					usage->hid, value);
+-			return 1;
+ 		}
+ 
+ 		if (asc->quirks & APPLE_NUMLOCK_EMULATION &&
+-				(test_bit(usage->code, asc->pressed_numlock) ||
++				(test_bit(code, asc->pressed_numlock) ||
+ 				test_bit(LED_NUML, input->led))) {
+-			trans = apple_find_translation(powerbook_numlock_keys,
+-					usage->code);
++			trans = apple_find_translation(powerbook_numlock_keys, code);
+ 
+ 			if (trans) {
+ 				if (value)
+-					set_bit(usage->code,
+-							asc->pressed_numlock);
++					set_bit(code, asc->pressed_numlock);
+ 				else
+-					clear_bit(usage->code,
+-							asc->pressed_numlock);
++					clear_bit(code, asc->pressed_numlock);
+ 
+-				input_event_with_scancode(input, usage->type,
+-						trans->to, usage->hid, value);
++				code = trans->to;
+ 			}
+-
+-			return 1;
+ 		}
+ 	}
+ 
+-	if (iso_layout > 0 || (iso_layout < 0 && (asc->quirks & APPLE_ISO_TILDE_QUIRK) &&
+-			hid->country == HID_COUNTRY_INTERNATIONAL_ISO)) {
+-		trans = apple_find_translation(apple_iso_keyboard, usage->code);
+-		if (trans) {
+-			input_event_with_scancode(input, usage->type,
+-					trans->to, usage->hid, value);
+-			return 1;
+-		}
+-	}
+-
+-	if (swap_opt_cmd) {
+-		trans = apple_find_translation(swapped_option_cmd_keys, usage->code);
+-		if (trans) {
+-			input_event_with_scancode(input, usage->type,
+-					trans->to, usage->hid, value);
+-			return 1;
+-		}
+-	}
++	if (usage->code != code) {
++		input_event_with_scancode(input, usage->type, code, usage->hid, value);
+ 
+-	if (swap_fn_leftctrl) {
+-		trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code);
+-		if (trans) {
+-			input_event_with_scancode(input, usage->type,
+-					trans->to, usage->hid, value);
+-			return 1;
+-		}
++		return 1;
+ 	}
+ 
+ 	return 0;
+@@ -640,9 +629,6 @@ static void apple_setup_input(struct input_dev *input)
+ 	apple_setup_key_translation(input, apple2021_fn_keys);
+ 	apple_setup_key_translation(input, macbookpro_no_esc_fn_keys);
+ 	apple_setup_key_translation(input, macbookpro_dedicated_esc_fn_keys);
+-
+-	if (swap_fn_leftctrl)
+-		apple_setup_key_translation(input, swapped_fn_leftctrl_keys);
+ }
+ 
+ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+@@ -1011,21 +997,21 @@ static const struct hid_device_id apple_devices[] = {
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS),
+ 		.driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K),
+-		.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL },
++		.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132),
+-		.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL },
++		.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680),
+-		.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL },
++		.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213),
+-		.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL },
++		.driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K),
+-		.driver_data = APPLE_HAS_FN },
++		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223),
+-		.driver_data = APPLE_HAS_FN },
++		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K),
+-		.driver_data = APPLE_HAS_FN },
++		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F),
+-		.driver_data = APPLE_HAS_FN },
++		.driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK },
+ 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
+ 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
+ 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 859aeb07542e3..d728a94c642eb 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -340,6 +340,7 @@ static enum power_supply_property hidinput_battery_props[] = {
+ #define HID_BATTERY_QUIRK_PERCENT	(1 << 0) /* always reports percent */
+ #define HID_BATTERY_QUIRK_FEATURE	(1 << 1) /* ask for feature report */
+ #define HID_BATTERY_QUIRK_IGNORE	(1 << 2) /* completely ignore the battery */
++#define HID_BATTERY_QUIRK_AVOID_QUERY	(1 << 3) /* do not query the battery */
+ 
+ static const struct hid_device_id hid_battery_quirks[] = {
+ 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
+@@ -373,6 +374,8 @@ static const struct hid_device_id hid_battery_quirks[] = {
+ 	  HID_BATTERY_QUIRK_IGNORE },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
+ 	  HID_BATTERY_QUIRK_IGNORE },
++	{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L),
++	  HID_BATTERY_QUIRK_AVOID_QUERY },
+ 	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15),
+ 	  HID_BATTERY_QUIRK_IGNORE },
+ 	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100),
+@@ -554,6 +557,9 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
+ 	dev->battery_avoid_query = report_type == HID_INPUT_REPORT &&
+ 				   field->physical == HID_DG_STYLUS;
+ 
++	if (quirks & HID_BATTERY_QUIRK_AVOID_QUERY)
++		dev->battery_avoid_query = true;
++
+ 	dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
+ 	if (IS_ERR(dev->battery)) {
+ 		error = PTR_ERR(dev->battery);
+diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
+index 68f9e9d207f42..ba14b6f69ff7a 100644
+--- a/drivers/hid/hid-logitech-hidpp.c
++++ b/drivers/hid/hid-logitech-hidpp.c
+@@ -2545,12 +2545,17 @@ static int hidpp_ff_init(struct hidpp_device *hidpp,
+ 	struct hid_device *hid = hidpp->hid_dev;
+ 	struct hid_input *hidinput;
+ 	struct input_dev *dev;
+-	const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor);
+-	const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice);
++	struct usb_device_descriptor *udesc;
++	u16 bcdDevice;
+ 	struct ff_device *ff;
+ 	int error, j, num_slots = data->num_effects;
+ 	u8 version;
+ 
++	if (!hid_is_usb(hid)) {
++		hid_err(hid, "device is not USB\n");
++		return -ENODEV;
++	}
++
+ 	if (list_empty(&hid->inputs)) {
+ 		hid_err(hid, "no inputs found\n");
+ 		return -ENODEV;
+@@ -2564,6 +2569,8 @@ static int hidpp_ff_init(struct hidpp_device *hidpp,
+ 	}
+ 
+ 	/* Get firmware release */
++	udesc = &(hid_to_usb_dev(hid)->descriptor);
++	bcdDevice = le16_to_cpu(udesc->bcdDevice);
+ 	version = bcdDevice & 255;
+ 
+ 	/* Set supported force feedback capabilities */
+diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
+index de52e9f7bb8cb..560eeec4035aa 100644
+--- a/drivers/hid/hid-mcp2221.c
++++ b/drivers/hid/hid-mcp2221.c
+@@ -840,12 +840,19 @@ static int mcp2221_probe(struct hid_device *hdev,
+ 		return ret;
+ 	}
+ 
+-	ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
++	/*
++	 * This driver uses the .raw_event callback and therefore does not need any
++	 * HID_CONNECT_xxx flags.
++	 */
++	ret = hid_hw_start(hdev, 0);
+ 	if (ret) {
+ 		hid_err(hdev, "can't start hardware\n");
+ 		return ret;
+ 	}
+ 
++	hid_info(hdev, "USB HID v%x.%02x Device [%s] on %s\n", hdev->version >> 8,
++			hdev->version & 0xff, hdev->name, hdev->phys);
++
+ 	ret = hid_hw_open(hdev);
+ 	if (ret) {
+ 		hid_err(hdev, "can't open device\n");
+@@ -870,8 +877,7 @@ static int mcp2221_probe(struct hid_device *hdev,
+ 	mcp->adapter.retries = 1;
+ 	mcp->adapter.dev.parent = &hdev->dev;
+ 	snprintf(mcp->adapter.name, sizeof(mcp->adapter.name),
+-			"MCP2221 usb-i2c bridge on hidraw%d",
+-			((struct hidraw *)hdev->hidraw)->minor);
++			"MCP2221 usb-i2c bridge");
+ 
+ 	ret = i2c_add_adapter(&mcp->adapter);
+ 	if (ret) {
+diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
+index 311eee599ce97..b2bf588d18c39 100644
+--- a/drivers/hid/hid-rmi.c
++++ b/drivers/hid/hid-rmi.c
+@@ -327,6 +327,8 @@ static int rmi_input_event(struct hid_device *hdev, u8 *data, int size)
+ 	if (!(test_bit(RMI_STARTED, &hdata->flags)))
+ 		return 0;
+ 
++	pm_wakeup_event(hdev->dev.parent, 0);
++
+ 	local_irq_save(flags);
+ 
+ 	rmi_set_attn_data(rmi_dev, data[1], &data[2], size - 2);
+diff --git a/drivers/hid/hid-sensor-custom.c b/drivers/hid/hid-sensor-custom.c
+index 32c2306e240d6..602465ad27458 100644
+--- a/drivers/hid/hid-sensor-custom.c
++++ b/drivers/hid/hid-sensor-custom.c
+@@ -62,7 +62,7 @@ struct hid_sensor_sample {
+ 	u32 raw_len;
+ } __packed;
+ 
+-static struct attribute hid_custom_attrs[] = {
++static struct attribute hid_custom_attrs[HID_CUSTOM_TOTAL_ATTRS] = {
+ 	{.name = "name", .mode = S_IRUGO},
+ 	{.name = "units", .mode = S_IRUGO},
+ 	{.name = "unit-expo", .mode = S_IRUGO},
+diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c
+index c078f09a2318a..5a365648206e7 100644
+--- a/drivers/hid/i2c-hid/i2c-hid-core.c
++++ b/drivers/hid/i2c-hid/i2c-hid-core.c
+@@ -554,7 +554,8 @@ static void i2c_hid_get_input(struct i2c_hid *ihid)
+ 	i2c_hid_dbg(ihid, "input: %*ph\n", ret_size, ihid->inbuf);
+ 
+ 	if (test_bit(I2C_HID_STARTED, &ihid->flags)) {
+-		pm_wakeup_event(&ihid->client->dev, 0);
++		if (ihid->hid->group != HID_GROUP_RMI)
++			pm_wakeup_event(&ihid->client->dev, 0);
+ 
+ 		hid_input_report(ihid->hid, HID_INPUT_REPORT,
+ 				ihid->inbuf + sizeof(__le16),
+diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
+index 194a2e3275914..45aee464e31ab 100644
+--- a/drivers/hid/wacom_sys.c
++++ b/drivers/hid/wacom_sys.c
+@@ -160,6 +160,9 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
+ {
+ 	struct wacom *wacom = hid_get_drvdata(hdev);
+ 
++	if (wacom->wacom_wac.features.type == BOOTLOADER)
++		return 0;
++
+ 	if (size > WACOM_PKGLEN_MAX)
+ 		return 1;
+ 
+@@ -2790,6 +2793,11 @@ static int wacom_probe(struct hid_device *hdev,
+ 		return error;
+ 	}
+ 
++	if (features->type == BOOTLOADER) {
++		hid_warn(hdev, "Using device in hidraw-only mode");
++		return hid_hw_start(hdev, HID_CONNECT_HIDRAW);
++	}
++
+ 	error = wacom_parse_and_register(wacom, false);
+ 	if (error)
+ 		return error;
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
+index 2bd1a43021c92..dc5478dc855be 100644
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -4880,6 +4880,9 @@ static const struct wacom_features wacom_features_0x3c8 =
+ static const struct wacom_features wacom_features_HID_ANY_ID =
+ 	{ "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID };
+ 
++static const struct wacom_features wacom_features_0x94 =
++	{ "Wacom Bootloader", .type = BOOTLOADER };
++
+ #define USB_DEVICE_WACOM(prod)						\
+ 	HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
+ 	.driver_data = (kernel_ulong_t)&wacom_features_##prod
+@@ -4953,6 +4956,7 @@ const struct hid_device_id wacom_ids[] = {
+ 	{ USB_DEVICE_WACOM(0x84) },
+ 	{ USB_DEVICE_WACOM(0x90) },
+ 	{ USB_DEVICE_WACOM(0x93) },
++	{ USB_DEVICE_WACOM(0x94) },
+ 	{ USB_DEVICE_WACOM(0x97) },
+ 	{ USB_DEVICE_WACOM(0x9A) },
+ 	{ USB_DEVICE_WACOM(0x9F) },
+diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
+index fef1538005b5d..174b300c49ddb 100644
+--- a/drivers/hid/wacom_wac.h
++++ b/drivers/hid/wacom_wac.h
+@@ -245,6 +245,7 @@ enum {
+ 	MTTPC,
+ 	MTTPC_B,
+ 	HID_GENERIC,
++	BOOTLOADER,
+ 	MAX_TYPE
+ };
+ 
+diff --git a/drivers/hsi/controllers/omap_ssi_core.c b/drivers/hsi/controllers/omap_ssi_core.c
+index eb98201583185..26f2c3c012978 100644
+--- a/drivers/hsi/controllers/omap_ssi_core.c
++++ b/drivers/hsi/controllers/omap_ssi_core.c
+@@ -502,8 +502,10 @@ static int ssi_probe(struct platform_device *pd)
+ 	platform_set_drvdata(pd, ssi);
+ 
+ 	err = ssi_add_controller(ssi, pd);
+-	if (err < 0)
++	if (err < 0) {
++		hsi_put_controller(ssi);
+ 		goto out1;
++	}
+ 
+ 	pm_runtime_enable(&pd->dev);
+ 
+@@ -536,9 +538,9 @@ out3:
+ 	device_for_each_child(&pd->dev, NULL, ssi_remove_ports);
+ out2:
+ 	ssi_remove_controller(ssi);
++	pm_runtime_disable(&pd->dev);
+ out1:
+ 	platform_set_drvdata(pd, NULL);
+-	pm_runtime_disable(&pd->dev);
+ 
+ 	return err;
+ }
+@@ -629,7 +631,13 @@ static int __init ssi_init(void) {
+ 	if (ret)
+ 		return ret;
+ 
+-	return platform_driver_register(&ssi_port_pdriver);
++	ret = platform_driver_register(&ssi_port_pdriver);
++	if (ret) {
++		platform_driver_unregister(&ssi_pdriver);
++		return ret;
++	}
++
++	return 0;
+ }
+ module_init(ssi_init);
+ 
+diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
+index 59a4aa86d1f35..c6692fd5ab155 100644
+--- a/drivers/hv/ring_buffer.c
++++ b/drivers/hv/ring_buffer.c
+@@ -280,6 +280,19 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
+ 	ring_info->pkt_buffer_size = 0;
+ }
+ 
++/*
++ * Check if the ring buffer spinlock is available to take or not; used on
++ * atomic contexts, like panic path (see the Hyper-V framebuffer driver).
++ */
++
++bool hv_ringbuffer_spinlock_busy(struct vmbus_channel *channel)
++{
++	struct hv_ring_buffer_info *rinfo = &channel->outbound;
++
++	return spin_is_locked(&rinfo->ring_lock);
++}
++EXPORT_SYMBOL_GPL(hv_ringbuffer_spinlock_busy);
++
+ /* Write to the ring buffer. */
+ int hv_ringbuffer_write(struct vmbus_channel *channel,
+ 			const struct kvec *kv_list, u32 kv_count,
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index e70d9614bec2c..1533127960e7e 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -798,6 +798,7 @@ config SENSORS_IT87
+ config SENSORS_JC42
+ 	tristate "JEDEC JC42.4 compliant memory module temperature sensors"
+ 	depends on I2C
++	select REGMAP_I2C
+ 	help
+ 	  If you say yes here, you get support for JEDEC JC42.4 compliant
+ 	  temperature sensors, which are used on many DDR3 memory modules for
+diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c
+index 07f7f8b5b73d7..50aea882ac09b 100644
+--- a/drivers/hwmon/jc42.c
++++ b/drivers/hwmon/jc42.c
+@@ -19,6 +19,7 @@
+ #include <linux/err.h>
+ #include <linux/mutex.h>
+ #include <linux/of.h>
++#include <linux/regmap.h>
+ 
+ /* Addresses to scan */
+ static const unsigned short normal_i2c[] = {
+@@ -199,31 +200,14 @@ static struct jc42_chips jc42_chips[] = {
+ 	{ STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK },
+ };
+ 
+-enum temp_index {
+-	t_input = 0,
+-	t_crit,
+-	t_min,
+-	t_max,
+-	t_num_temp
+-};
+-
+-static const u8 temp_regs[t_num_temp] = {
+-	[t_input] = JC42_REG_TEMP,
+-	[t_crit] = JC42_REG_TEMP_CRITICAL,
+-	[t_min] = JC42_REG_TEMP_LOWER,
+-	[t_max] = JC42_REG_TEMP_UPPER,
+-};
+-
+ /* Each client has this additional data */
+ struct jc42_data {
+-	struct i2c_client *client;
+ 	struct mutex	update_lock;	/* protect register access */
++	struct regmap	*regmap;
+ 	bool		extended;	/* true if extended range supported */
+ 	bool		valid;
+-	unsigned long	last_updated;	/* In jiffies */
+ 	u16		orig_config;	/* original configuration */
+ 	u16		config;		/* current configuration */
+-	u16		temp[t_num_temp];/* Temperatures */
+ };
+ 
+ #define JC42_TEMP_MIN_EXTENDED	(-40000)
+@@ -248,85 +232,102 @@ static int jc42_temp_from_reg(s16 reg)
+ 	return reg * 125 / 2;
+ }
+ 
+-static struct jc42_data *jc42_update_device(struct device *dev)
+-{
+-	struct jc42_data *data = dev_get_drvdata(dev);
+-	struct i2c_client *client = data->client;
+-	struct jc42_data *ret = data;
+-	int i, val;
+-
+-	mutex_lock(&data->update_lock);
+-
+-	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+-		for (i = 0; i < t_num_temp; i++) {
+-			val = i2c_smbus_read_word_swapped(client, temp_regs[i]);
+-			if (val < 0) {
+-				ret = ERR_PTR(val);
+-				goto abort;
+-			}
+-			data->temp[i] = val;
+-		}
+-		data->last_updated = jiffies;
+-		data->valid = true;
+-	}
+-abort:
+-	mutex_unlock(&data->update_lock);
+-	return ret;
+-}
+-
+ static int jc42_read(struct device *dev, enum hwmon_sensor_types type,
+ 		     u32 attr, int channel, long *val)
+ {
+-	struct jc42_data *data = jc42_update_device(dev);
+-	int temp, hyst;
++	struct jc42_data *data = dev_get_drvdata(dev);
++	unsigned int regval;
++	int ret, temp, hyst;
+ 
+-	if (IS_ERR(data))
+-		return PTR_ERR(data);
++	mutex_lock(&data->update_lock);
+ 
+ 	switch (attr) {
+ 	case hwmon_temp_input:
+-		*val = jc42_temp_from_reg(data->temp[t_input]);
+-		return 0;
++		ret = regmap_read(data->regmap, JC42_REG_TEMP, &regval);
++		if (ret)
++			break;
++
++		*val = jc42_temp_from_reg(regval);
++		break;
+ 	case hwmon_temp_min:
+-		*val = jc42_temp_from_reg(data->temp[t_min]);
+-		return 0;
++		ret = regmap_read(data->regmap, JC42_REG_TEMP_LOWER, &regval);
++		if (ret)
++			break;
++
++		*val = jc42_temp_from_reg(regval);
++		break;
+ 	case hwmon_temp_max:
+-		*val = jc42_temp_from_reg(data->temp[t_max]);
+-		return 0;
++		ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, &regval);
++		if (ret)
++			break;
++
++		*val = jc42_temp_from_reg(regval);
++		break;
+ 	case hwmon_temp_crit:
+-		*val = jc42_temp_from_reg(data->temp[t_crit]);
+-		return 0;
++		ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL,
++				  &regval);
++		if (ret)
++			break;
++
++		*val = jc42_temp_from_reg(regval);
++		break;
+ 	case hwmon_temp_max_hyst:
+-		temp = jc42_temp_from_reg(data->temp[t_max]);
++		ret = regmap_read(data->regmap, JC42_REG_TEMP_UPPER, &regval);
++		if (ret)
++			break;
++
++		temp = jc42_temp_from_reg(regval);
+ 		hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK)
+ 						>> JC42_CFG_HYST_SHIFT];
+ 		*val = temp - hyst;
+-		return 0;
++		break;
+ 	case hwmon_temp_crit_hyst:
+-		temp = jc42_temp_from_reg(data->temp[t_crit]);
++		ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL,
++				  &regval);
++		if (ret)
++			break;
++
++		temp = jc42_temp_from_reg(regval);
+ 		hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK)
+ 						>> JC42_CFG_HYST_SHIFT];
+ 		*val = temp - hyst;
+-		return 0;
++		break;
+ 	case hwmon_temp_min_alarm:
+-		*val = (data->temp[t_input] >> JC42_ALARM_MIN_BIT) & 1;
+-		return 0;
++		ret = regmap_read(data->regmap, JC42_REG_TEMP, &regval);
++		if (ret)
++			break;
++
++		*val = (regval >> JC42_ALARM_MIN_BIT) & 1;
++		break;
+ 	case hwmon_temp_max_alarm:
+-		*val = (data->temp[t_input] >> JC42_ALARM_MAX_BIT) & 1;
+-		return 0;
++		ret = regmap_read(data->regmap, JC42_REG_TEMP, &regval);
++		if (ret)
++			break;
++
++		*val = (regval >> JC42_ALARM_MAX_BIT) & 1;
++		break;
+ 	case hwmon_temp_crit_alarm:
+-		*val = (data->temp[t_input] >> JC42_ALARM_CRIT_BIT) & 1;
+-		return 0;
++		ret = regmap_read(data->regmap, JC42_REG_TEMP, &regval);
++		if (ret)
++			break;
++
++		*val = (regval >> JC42_ALARM_CRIT_BIT) & 1;
++		break;
+ 	default:
+-		return -EOPNOTSUPP;
++		ret = -EOPNOTSUPP;
++		break;
+ 	}
++
++	mutex_unlock(&data->update_lock);
++
++	return ret;
+ }
+ 
+ static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
+ 		      u32 attr, int channel, long val)
+ {
+ 	struct jc42_data *data = dev_get_drvdata(dev);
+-	struct i2c_client *client = data->client;
++	unsigned int regval;
+ 	int diff, hyst;
+ 	int ret;
+ 
+@@ -334,21 +335,23 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
+ 
+ 	switch (attr) {
+ 	case hwmon_temp_min:
+-		data->temp[t_min] = jc42_temp_to_reg(val, data->extended);
+-		ret = i2c_smbus_write_word_swapped(client, temp_regs[t_min],
+-						   data->temp[t_min]);
++		ret = regmap_write(data->regmap, JC42_REG_TEMP_LOWER,
++				   jc42_temp_to_reg(val, data->extended));
+ 		break;
+ 	case hwmon_temp_max:
+-		data->temp[t_max] = jc42_temp_to_reg(val, data->extended);
+-		ret = i2c_smbus_write_word_swapped(client, temp_regs[t_max],
+-						   data->temp[t_max]);
++		ret = regmap_write(data->regmap, JC42_REG_TEMP_UPPER,
++				   jc42_temp_to_reg(val, data->extended));
+ 		break;
+ 	case hwmon_temp_crit:
+-		data->temp[t_crit] = jc42_temp_to_reg(val, data->extended);
+-		ret = i2c_smbus_write_word_swapped(client, temp_regs[t_crit],
+-						   data->temp[t_crit]);
++		ret = regmap_write(data->regmap, JC42_REG_TEMP_CRITICAL,
++				   jc42_temp_to_reg(val, data->extended));
+ 		break;
+ 	case hwmon_temp_crit_hyst:
++		ret = regmap_read(data->regmap, JC42_REG_TEMP_CRITICAL,
++				  &regval);
++		if (ret)
++			break;
++
+ 		/*
+ 		 * JC42.4 compliant chips only support four hysteresis values.
+ 		 * Pick best choice and go from there.
+@@ -356,7 +359,7 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
+ 		val = clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED
+ 						     : JC42_TEMP_MIN) - 6000,
+ 				JC42_TEMP_MAX);
+-		diff = jc42_temp_from_reg(data->temp[t_crit]) - val;
++		diff = jc42_temp_from_reg(regval) - val;
+ 		hyst = 0;
+ 		if (diff > 0) {
+ 			if (diff < 2250)
+@@ -368,9 +371,8 @@ static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
+ 		}
+ 		data->config = (data->config & ~JC42_CFG_HYST_MASK) |
+ 				(hyst << JC42_CFG_HYST_SHIFT);
+-		ret = i2c_smbus_write_word_swapped(data->client,
+-						   JC42_REG_CONFIG,
+-						   data->config);
++		ret = regmap_write(data->regmap, JC42_REG_CONFIG,
++				   data->config);
+ 		break;
+ 	default:
+ 		ret = -EOPNOTSUPP;
+@@ -470,51 +472,80 @@ static const struct hwmon_chip_info jc42_chip_info = {
+ 	.info = jc42_info,
+ };
+ 
++static bool jc42_readable_reg(struct device *dev, unsigned int reg)
++{
++	return (reg >= JC42_REG_CAP && reg <= JC42_REG_DEVICEID) ||
++		reg == JC42_REG_SMBUS;
++}
++
++static bool jc42_writable_reg(struct device *dev, unsigned int reg)
++{
++	return (reg >= JC42_REG_CONFIG && reg <= JC42_REG_TEMP_CRITICAL) ||
++		reg == JC42_REG_SMBUS;
++}
++
++static bool jc42_volatile_reg(struct device *dev, unsigned int reg)
++{
++	return reg == JC42_REG_CONFIG || reg == JC42_REG_TEMP;
++}
++
++static const struct regmap_config jc42_regmap_config = {
++	.reg_bits = 8,
++	.val_bits = 16,
++	.val_format_endian = REGMAP_ENDIAN_BIG,
++	.max_register = JC42_REG_SMBUS,
++	.writeable_reg = jc42_writable_reg,
++	.readable_reg = jc42_readable_reg,
++	.volatile_reg = jc42_volatile_reg,
++	.cache_type = REGCACHE_RBTREE,
++};
++
+ static int jc42_probe(struct i2c_client *client)
+ {
+ 	struct device *dev = &client->dev;
+ 	struct device *hwmon_dev;
++	unsigned int config, cap;
+ 	struct jc42_data *data;
+-	int config, cap;
++	int ret;
+ 
+ 	data = devm_kzalloc(dev, sizeof(struct jc42_data), GFP_KERNEL);
+ 	if (!data)
+ 		return -ENOMEM;
+ 
+-	data->client = client;
++	data->regmap = devm_regmap_init_i2c(client, &jc42_regmap_config);
++	if (IS_ERR(data->regmap))
++		return PTR_ERR(data->regmap);
++
+ 	i2c_set_clientdata(client, data);
+ 	mutex_init(&data->update_lock);
+ 
+-	cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP);
+-	if (cap < 0)
+-		return cap;
++	ret = regmap_read(data->regmap, JC42_REG_CAP, &cap);
++	if (ret)
++		return ret;
+ 
+ 	data->extended = !!(cap & JC42_CAP_RANGE);
+ 
+ 	if (device_property_read_bool(dev, "smbus-timeout-disable")) {
+-		int smbus;
+-
+ 		/*
+ 		 * Not all chips support this register, but from a
+ 		 * quick read of various datasheets no chip appears
+ 		 * incompatible with the below attempt to disable
+ 		 * the timeout. And the whole thing is opt-in...
+ 		 */
+-		smbus = i2c_smbus_read_word_swapped(client, JC42_REG_SMBUS);
+-		if (smbus < 0)
+-			return smbus;
+-		i2c_smbus_write_word_swapped(client, JC42_REG_SMBUS,
+-					     smbus | SMBUS_STMOUT);
++		ret = regmap_set_bits(data->regmap, JC42_REG_SMBUS,
++				      SMBUS_STMOUT);
++		if (ret)
++			return ret;
+ 	}
+ 
+-	config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG);
+-	if (config < 0)
+-		return config;
++	ret = regmap_read(data->regmap, JC42_REG_CONFIG, &config);
++	if (ret)
++		return ret;
+ 
+ 	data->orig_config = config;
+ 	if (config & JC42_CFG_SHUTDOWN) {
+ 		config &= ~JC42_CFG_SHUTDOWN;
+-		i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config);
++		regmap_write(data->regmap, JC42_REG_CONFIG, config);
+ 	}
+ 	data->config = config;
+ 
+@@ -535,7 +566,7 @@ static int jc42_remove(struct i2c_client *client)
+ 
+ 		config = (data->orig_config & ~JC42_CFG_HYST_MASK)
+ 		  | (data->config & JC42_CFG_HYST_MASK);
+-		i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config);
++		regmap_write(data->regmap, JC42_REG_CONFIG, config);
+ 	}
+ 	return 0;
+ }
+@@ -547,8 +578,11 @@ static int jc42_suspend(struct device *dev)
+ 	struct jc42_data *data = dev_get_drvdata(dev);
+ 
+ 	data->config |= JC42_CFG_SHUTDOWN;
+-	i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
+-				     data->config);
++	regmap_write(data->regmap, JC42_REG_CONFIG, data->config);
++
++	regcache_cache_only(data->regmap, true);
++	regcache_mark_dirty(data->regmap);
++
+ 	return 0;
+ }
+ 
+@@ -556,10 +590,13 @@ static int jc42_resume(struct device *dev)
+ {
+ 	struct jc42_data *data = dev_get_drvdata(dev);
+ 
++	regcache_cache_only(data->regmap, false);
++
+ 	data->config &= ~JC42_CFG_SHUTDOWN;
+-	i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
+-				     data->config);
+-	return 0;
++	regmap_write(data->regmap, JC42_REG_CONFIG, data->config);
++
++	/* Restore cached register values to hardware */
++	return regcache_sync(data->regmap);
+ }
+ 
+ static const struct dev_pm_ops jc42_dev_pm_ops = {
+diff --git a/drivers/hwmon/nct6775-platform.c b/drivers/hwmon/nct6775-platform.c
+index 41c97cfacfb8c..50fe9533cf439 100644
+--- a/drivers/hwmon/nct6775-platform.c
++++ b/drivers/hwmon/nct6775-platform.c
+@@ -1043,7 +1043,9 @@ static struct platform_device *pdev[2];
+ 
+ static const char * const asus_wmi_boards[] = {
+ 	"PRO H410T",
++	"ProArt B550-CREATOR",
+ 	"ProArt X570-CREATOR WIFI",
++	"ProArt Z490-CREATOR 10G",
+ 	"Pro B550M-C",
+ 	"Pro WS X570-ACE",
+ 	"PRIME B360-PLUS",
+@@ -1055,8 +1057,10 @@ static const char * const asus_wmi_boards[] = {
+ 	"PRIME X570-P",
+ 	"PRIME X570-PRO",
+ 	"ROG CROSSHAIR VIII DARK HERO",
++	"ROG CROSSHAIR VIII EXTREME",
+ 	"ROG CROSSHAIR VIII FORMULA",
+ 	"ROG CROSSHAIR VIII HERO",
++	"ROG CROSSHAIR VIII HERO (WI-FI)",
+ 	"ROG CROSSHAIR VIII IMPACT",
+ 	"ROG STRIX B550-A GAMING",
+ 	"ROG STRIX B550-E GAMING",
+@@ -1080,8 +1084,11 @@ static const char * const asus_wmi_boards[] = {
+ 	"ROG STRIX Z490-G GAMING (WI-FI)",
+ 	"ROG STRIX Z490-H GAMING",
+ 	"ROG STRIX Z490-I GAMING",
++	"TUF GAMING B550M-E",
++	"TUF GAMING B550M-E (WI-FI)",
+ 	"TUF GAMING B550M-PLUS",
+ 	"TUF GAMING B550M-PLUS (WI-FI)",
++	"TUF GAMING B550M-PLUS WIFI II",
+ 	"TUF GAMING B550-PLUS",
+ 	"TUF GAMING B550-PLUS WIFI II",
+ 	"TUF GAMING B550-PRO",
+diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
+index 2b386bb848f8d..1fc4fd79a1c69 100644
+--- a/drivers/hwtracing/coresight/coresight-trbe.c
++++ b/drivers/hwtracing/coresight/coresight-trbe.c
+@@ -1434,6 +1434,7 @@ static int arm_trbe_probe_cpuhp(struct trbe_drvdata *drvdata)
+ 
+ static void arm_trbe_remove_cpuhp(struct trbe_drvdata *drvdata)
+ {
++	cpuhp_state_remove_instance(drvdata->trbe_online, &drvdata->hotplug_node);
+ 	cpuhp_remove_multi_state(drvdata->trbe_online);
+ }
+ 
+diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c
+index 6078fa0c0d488..63120c41354c0 100644
+--- a/drivers/i2c/busses/i2c-ismt.c
++++ b/drivers/i2c/busses/i2c-ismt.c
+@@ -509,6 +509,9 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
+ 		if (read_write == I2C_SMBUS_WRITE) {
+ 			/* Block Write */
+ 			dev_dbg(dev, "I2C_SMBUS_BLOCK_DATA:  WRITE\n");
++			if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
++				return -EINVAL;
++
+ 			dma_size = data->block[0] + 1;
+ 			dma_direction = DMA_TO_DEVICE;
+ 			desc->wr_len_cmd = dma_size;
+diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c
+index f614cade432bb..30e38bc8b6db8 100644
+--- a/drivers/i2c/busses/i2c-pxa-pci.c
++++ b/drivers/i2c/busses/i2c-pxa-pci.c
+@@ -105,7 +105,7 @@ static int ce4100_i2c_probe(struct pci_dev *dev,
+ 	int i;
+ 	struct ce4100_devices *sds;
+ 
+-	ret = pci_enable_device_mem(dev);
++	ret = pcim_enable_device(dev);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -114,10 +114,8 @@ static int ce4100_i2c_probe(struct pci_dev *dev,
+ 		return -EINVAL;
+ 	}
+ 	sds = kzalloc(sizeof(*sds), GFP_KERNEL);
+-	if (!sds) {
+-		ret = -ENOMEM;
+-		goto err_mem;
+-	}
++	if (!sds)
++		return -ENOMEM;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(sds->pdev); i++) {
+ 		sds->pdev[i] = add_i2c_device(dev, i);
+@@ -133,8 +131,6 @@ static int ce4100_i2c_probe(struct pci_dev *dev,
+ 
+ err_dev_add:
+ 	kfree(sds);
+-err_mem:
+-	pci_disable_device(dev);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/i2c/muxes/i2c-mux-reg.c b/drivers/i2c/muxes/i2c-mux-reg.c
+index 0e0679f65cf77..30a6de1694e07 100644
+--- a/drivers/i2c/muxes/i2c-mux-reg.c
++++ b/drivers/i2c/muxes/i2c-mux-reg.c
+@@ -183,13 +183,12 @@ static int i2c_mux_reg_probe(struct platform_device *pdev)
+ 	if (!mux->data.reg) {
+ 		dev_info(&pdev->dev,
+ 			"Register not set, using platform resource\n");
+-		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-		mux->data.reg_size = resource_size(res);
+-		mux->data.reg = devm_ioremap_resource(&pdev->dev, res);
++		mux->data.reg = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ 		if (IS_ERR(mux->data.reg)) {
+ 			ret = PTR_ERR(mux->data.reg);
+ 			goto err_put_parent;
+ 		}
++		mux->data.reg_size = resource_size(res);
+ 	}
+ 
+ 	if (mux->data.reg_size != 4 && mux->data.reg_size != 2 &&
+diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
+index 261a9a6b45e15..d8570f620785a 100644
+--- a/drivers/iio/adc/ad_sigma_delta.c
++++ b/drivers/iio/adc/ad_sigma_delta.c
+@@ -281,10 +281,10 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
+ 	unsigned int data_reg;
+ 	int ret = 0;
+ 
+-	if (iio_buffer_enabled(indio_dev))
+-		return -EBUSY;
++	ret = iio_device_claim_direct_mode(indio_dev);
++	if (ret)
++		return ret;
+ 
+-	mutex_lock(&indio_dev->mlock);
+ 	ad_sigma_delta_set_channel(sigma_delta, chan->address);
+ 
+ 	spi_bus_lock(sigma_delta->spi->master);
+@@ -323,7 +323,7 @@ out:
+ 	ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
+ 	sigma_delta->bus_locked = false;
+ 	spi_bus_unlock(sigma_delta->spi->master);
+-	mutex_unlock(&indio_dev->mlock);
++	iio_device_release_direct_mode(indio_dev);
+ 
+ 	if (ret)
+ 		return ret;
+diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c
+index 622fd384983c7..b3d5b9b7255bc 100644
+--- a/drivers/iio/adc/ti-adc128s052.c
++++ b/drivers/iio/adc/ti-adc128s052.c
+@@ -181,13 +181,13 @@ static int adc128_probe(struct spi_device *spi)
+ }
+ 
+ static const struct of_device_id adc128_of_match[] = {
+-	{ .compatible = "ti,adc128s052", },
+-	{ .compatible = "ti,adc122s021", },
+-	{ .compatible = "ti,adc122s051", },
+-	{ .compatible = "ti,adc122s101", },
+-	{ .compatible = "ti,adc124s021", },
+-	{ .compatible = "ti,adc124s051", },
+-	{ .compatible = "ti,adc124s101", },
++	{ .compatible = "ti,adc128s052", .data = (void*)0L, },
++	{ .compatible = "ti,adc122s021", .data = (void*)1L, },
++	{ .compatible = "ti,adc122s051", .data = (void*)1L, },
++	{ .compatible = "ti,adc122s101", .data = (void*)1L, },
++	{ .compatible = "ti,adc124s021", .data = (void*)2L, },
++	{ .compatible = "ti,adc124s051", .data = (void*)2L, },
++	{ .compatible = "ti,adc124s101", .data = (void*)2L, },
+ 	{ /* sentinel */ },
+ };
+ MODULE_DEVICE_TABLE(of, adc128_of_match);
+diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c
+index 899bcd83f40bc..e0e130ba9d3ec 100644
+--- a/drivers/iio/addac/ad74413r.c
++++ b/drivers/iio/addac/ad74413r.c
+@@ -691,7 +691,7 @@ static int ad74413_get_input_current_offset(struct ad74413r_state *st,
+ 	if (ret)
+ 		return ret;
+ 
+-	*val = voltage_offset * AD74413R_ADC_RESULT_MAX / voltage_range;
++	*val = voltage_offset * (int)AD74413R_ADC_RESULT_MAX / voltage_range;
+ 
+ 	return IIO_VAL_INT;
+ }
+diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
+index f7fcfd04f659d..bc40240b29e26 100644
+--- a/drivers/iio/imu/adis.c
++++ b/drivers/iio/imu/adis.c
+@@ -270,23 +270,19 @@ EXPORT_SYMBOL_NS(adis_debugfs_reg_access, IIO_ADISLIB);
+ #endif
+ 
+ /**
+- * adis_enable_irq() - Enable or disable data ready IRQ
++ * __adis_enable_irq() - Enable or disable data ready IRQ (unlocked)
+  * @adis: The adis device
+  * @enable: Whether to enable the IRQ
+  *
+  * Returns 0 on success, negative error code otherwise
+  */
+-int adis_enable_irq(struct adis *adis, bool enable)
++int __adis_enable_irq(struct adis *adis, bool enable)
+ {
+-	int ret = 0;
++	int ret;
+ 	u16 msc;
+ 
+-	mutex_lock(&adis->state_lock);
+-
+-	if (adis->data->enable_irq) {
+-		ret = adis->data->enable_irq(adis, enable);
+-		goto out_unlock;
+-	}
++	if (adis->data->enable_irq)
++		return adis->data->enable_irq(adis, enable);
+ 
+ 	if (adis->data->unmasked_drdy) {
+ 		if (enable)
+@@ -294,12 +290,12 @@ int adis_enable_irq(struct adis *adis, bool enable)
+ 		else
+ 			disable_irq(adis->spi->irq);
+ 
+-		goto out_unlock;
++		return 0;
+ 	}
+ 
+ 	ret = __adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
+ 	if (ret)
+-		goto out_unlock;
++		return ret;
+ 
+ 	msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
+ 	msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
+@@ -308,13 +304,9 @@ int adis_enable_irq(struct adis *adis, bool enable)
+ 	else
+ 		msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
+ 
+-	ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
+-
+-out_unlock:
+-	mutex_unlock(&adis->state_lock);
+-	return ret;
++	return __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
+ }
+-EXPORT_SYMBOL_NS(adis_enable_irq, IIO_ADISLIB);
++EXPORT_SYMBOL_NS(__adis_enable_irq, IIO_ADISLIB);
+ 
+ /**
+  * __adis_check_status() - Check the device for error conditions (unlocked)
+@@ -445,7 +437,7 @@ int __adis_initial_startup(struct adis *adis)
+ 	 * with 'IRQF_NO_AUTOEN' anyways.
+ 	 */
+ 	if (!adis->data->unmasked_drdy)
+-		adis_enable_irq(adis, false);
++		__adis_enable_irq(adis, false);
+ 
+ 	if (!adis->data->prod_id_reg)
+ 		return 0;
+diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
+index b5e059e15b0ae..ef161fa08146d 100644
+--- a/drivers/iio/industrialio-event.c
++++ b/drivers/iio/industrialio-event.c
+@@ -550,7 +550,7 @@ int iio_device_register_eventset(struct iio_dev *indio_dev)
+ 
+ 	ret = iio_device_register_sysfs_group(indio_dev, &ev_int->group);
+ 	if (ret)
+-		goto error_free_setup_event_lines;
++		goto error_free_group_attrs;
+ 
+ 	ev_int->ioctl_handler.ioctl = iio_event_ioctl;
+ 	iio_device_ioctl_handler_register(&iio_dev_opaque->indio_dev,
+@@ -558,6 +558,8 @@ int iio_device_register_eventset(struct iio_dev *indio_dev)
+ 
+ 	return 0;
+ 
++error_free_group_attrs:
++	kfree(ev_int->group.attrs);
+ error_free_setup_event_lines:
+ 	iio_free_chan_devattr_list(&ev_int->dev_attr_list);
+ 	kfree(ev_int);
+diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
+index a60ccf1836872..1117991ca2ab6 100644
+--- a/drivers/iio/temperature/ltc2983.c
++++ b/drivers/iio/temperature/ltc2983.c
+@@ -209,6 +209,7 @@ struct ltc2983_data {
+ 	 * Holds the converted temperature
+ 	 */
+ 	__be32 temp __aligned(IIO_DMA_MINALIGN);
++	__be32 chan_val;
+ };
+ 
+ struct ltc2983_sensor {
+@@ -313,19 +314,18 @@ static int __ltc2983_fault_handler(const struct ltc2983_data *st,
+ 	return 0;
+ }
+ 
+-static int __ltc2983_chan_assign_common(const struct ltc2983_data *st,
++static int __ltc2983_chan_assign_common(struct ltc2983_data *st,
+ 					const struct ltc2983_sensor *sensor,
+ 					u32 chan_val)
+ {
+ 	u32 reg = LTC2983_CHAN_START_ADDR(sensor->chan);
+-	__be32 __chan_val;
+ 
+ 	chan_val |= LTC2983_CHAN_TYPE(sensor->type);
+ 	dev_dbg(&st->spi->dev, "Assign reg:0x%04X, val:0x%08X\n", reg,
+ 		chan_val);
+-	__chan_val = cpu_to_be32(chan_val);
+-	return regmap_bulk_write(st->regmap, reg, &__chan_val,
+-				 sizeof(__chan_val));
++	st->chan_val = cpu_to_be32(chan_val);
++	return regmap_bulk_write(st->regmap, reg, &st->chan_val,
++				 sizeof(st->chan_val));
+ }
+ 
+ static int __ltc2983_chan_custom_sensor_assign(struct ltc2983_data *st,
+diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
+index aa36ac618e729..17a2274152771 100644
+--- a/drivers/infiniband/Kconfig
++++ b/drivers/infiniband/Kconfig
+@@ -78,6 +78,7 @@ config INFINIBAND_VIRT_DMA
+ 	def_bool !HIGHMEM
+ 
+ if INFINIBAND_USER_ACCESS || !INFINIBAND_USER_ACCESS
++if !UML
+ source "drivers/infiniband/hw/bnxt_re/Kconfig"
+ source "drivers/infiniband/hw/cxgb4/Kconfig"
+ source "drivers/infiniband/hw/efa/Kconfig"
+@@ -94,6 +95,7 @@ source "drivers/infiniband/hw/qib/Kconfig"
+ source "drivers/infiniband/hw/usnic/Kconfig"
+ source "drivers/infiniband/hw/vmw_pvrdma/Kconfig"
+ source "drivers/infiniband/sw/rdmavt/Kconfig"
++endif # !UML
+ source "drivers/infiniband/sw/rxe/Kconfig"
+ source "drivers/infiniband/sw/siw/Kconfig"
+ endif
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
+index 4053a09b8d33e..267d6e7fb18e0 100644
+--- a/drivers/infiniband/core/device.c
++++ b/drivers/infiniband/core/device.c
+@@ -2851,8 +2851,8 @@ err:
+ static void __exit ib_core_cleanup(void)
+ {
+ 	roce_gid_mgmt_cleanup();
+-	nldev_exit();
+ 	rdma_nl_unregister(RDMA_NL_LS);
++	nldev_exit();
+ 	unregister_pernet_device(&rdma_dev_net_ops);
+ 	unregister_blocking_lsm_notifier(&ibdev_lsm_nb);
+ 	ib_sa_cleanup();
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+index 1893aa613ad73..674344eb8e2f4 100644
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -59,9 +59,6 @@ static void create_mad_addr_info(struct ib_mad_send_wr_private *mad_send_wr,
+ 			  struct ib_mad_qp_info *qp_info,
+ 			  struct trace_event_raw_ib_mad_send_template *entry)
+ {
+-	u16 pkey;
+-	struct ib_device *dev = qp_info->port_priv->device;
+-	u32 pnum = qp_info->port_priv->port_num;
+ 	struct ib_ud_wr *wr = &mad_send_wr->send_wr;
+ 	struct rdma_ah_attr attr = {};
+ 
+@@ -69,8 +66,6 @@ static void create_mad_addr_info(struct ib_mad_send_wr_private *mad_send_wr,
+ 
+ 	/* These are common */
+ 	entry->sl = attr.sl;
+-	ib_query_pkey(dev, pnum, wr->pkey_index, &pkey);
+-	entry->pkey = pkey;
+ 	entry->rqpn = wr->remote_qpn;
+ 	entry->rqkey = wr->remote_qkey;
+ 	entry->dlid = rdma_ah_get_dlid(&attr);
+diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
+index 12dc97067ed2b..222733a83ddb7 100644
+--- a/drivers/infiniband/core/nldev.c
++++ b/drivers/infiniband/core/nldev.c
+@@ -513,7 +513,7 @@ static int fill_res_qp_entry(struct sk_buff *msg, bool has_cap_net_admin,
+ 
+ 	/* In create_qp() port is not set yet */
+ 	if (qp->port && nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, qp->port))
+-		return -EINVAL;
++		return -EMSGSIZE;
+ 
+ 	ret = nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_LQPN, qp->qp_num);
+ 	if (ret)
+@@ -552,7 +552,7 @@ static int fill_res_cm_id_entry(struct sk_buff *msg, bool has_cap_net_admin,
+ 	struct rdma_cm_id *cm_id = &id_priv->id;
+ 
+ 	if (port && port != cm_id->port_num)
+-		return 0;
++		return -EAGAIN;
+ 
+ 	if (cm_id->port_num &&
+ 	    nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, cm_id->port_num))
+@@ -894,6 +894,8 @@ static int fill_stat_counter_qps(struct sk_buff *msg,
+ 	int ret = 0;
+ 
+ 	table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_QP);
++	if (!table_attr)
++		return -EMSGSIZE;
+ 
+ 	rt = &counter->device->res[RDMA_RESTRACK_QP];
+ 	xa_lock(&rt->xa);
+diff --git a/drivers/infiniband/core/restrack.c b/drivers/infiniband/core/restrack.c
+index 1f935d9f61785..01a499a8b88db 100644
+--- a/drivers/infiniband/core/restrack.c
++++ b/drivers/infiniband/core/restrack.c
+@@ -343,8 +343,6 @@ void rdma_restrack_del(struct rdma_restrack_entry *res)
+ 	rt = &dev->res[res->type];
+ 
+ 	old = xa_erase(&rt->xa, res->id);
+-	if (res->type == RDMA_RESTRACK_MR)
+-		return;
+ 	WARN_ON(old != res);
+ 
+ out:
+diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
+index 84c53bd2a52db..ee59d73915689 100644
+--- a/drivers/infiniband/core/sysfs.c
++++ b/drivers/infiniband/core/sysfs.c
+@@ -1213,6 +1213,9 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
+ 	p->port_num = port_num;
+ 	kobject_init(&p->kobj, &port_type);
+ 
++	if (device->port_data && is_full_dev)
++		device->port_data[port_num].sysfs = p;
++
+ 	cur_group = p->groups_list;
+ 	ret = alloc_port_table_group("gids", &p->groups[0], p->attrs_list,
+ 				     attr->gid_tbl_len, show_port_gid);
+@@ -1258,9 +1261,6 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,
+ 	}
+ 
+ 	list_add_tail(&p->kobj.entry, &coredev->port_list);
+-	if (device->port_data && is_full_dev)
+-		device->port_data[port_num].sysfs = p;
+-
+ 	return p;
+ 
+ err_groups:
+@@ -1268,6 +1268,8 @@ err_groups:
+ err_del:
+ 	kobject_del(&p->kobj);
+ err_put:
++	if (device->port_data && is_full_dev)
++		device->port_data[port_num].sysfs = NULL;
+ 	kobject_put(&p->kobj);
+ 	return ERR_PTR(ret);
+ }
+@@ -1276,14 +1278,17 @@ static void destroy_port(struct ib_core_device *coredev, struct ib_port *port)
+ {
+ 	bool is_full_dev = &port->ibdev->coredev == coredev;
+ 
+-	if (port->ibdev->port_data &&
+-	    port->ibdev->port_data[port->port_num].sysfs == port)
+-		port->ibdev->port_data[port->port_num].sysfs = NULL;
+ 	list_del(&port->kobj.entry);
+ 	if (is_full_dev)
+ 		sysfs_remove_groups(&port->kobj, port->ibdev->ops.port_groups);
++
+ 	sysfs_remove_groups(&port->kobj, port->groups_list);
+ 	kobject_del(&port->kobj);
++
++	if (port->ibdev->port_data &&
++	    port->ibdev->port_data[port->port_num].sysfs == port)
++		port->ibdev->port_data[port->port_num].sysfs = NULL;
++
+ 	kobject_put(&port->kobj);
+ }
+ 
+diff --git a/drivers/infiniband/hw/hfi1/affinity.c b/drivers/infiniband/hw/hfi1/affinity.c
+index 877f8e84a672a..77ee77d4000fb 100644
+--- a/drivers/infiniband/hw/hfi1/affinity.c
++++ b/drivers/infiniband/hw/hfi1/affinity.c
+@@ -177,6 +177,8 @@ out:
+ 	for (node = 0; node < node_affinity.num_possible_nodes; node++)
+ 		hfi1_per_node_cntr[node] = 1;
+ 
++	pci_dev_put(dev);
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/infiniband/hw/hfi1/firmware.c b/drivers/infiniband/hw/hfi1/firmware.c
+index aa15a5cc7cf3a..9705bd7ea0647 100644
+--- a/drivers/infiniband/hw/hfi1/firmware.c
++++ b/drivers/infiniband/hw/hfi1/firmware.c
+@@ -1743,6 +1743,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+ 
+ 	if (!dd->platform_config.data) {
+ 		dd_dev_err(dd, "%s: Missing config file\n", __func__);
++		ret = -EINVAL;
+ 		goto bail;
+ 	}
+ 	ptr = (u32 *)dd->platform_config.data;
+@@ -1751,6 +1752,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+ 	ptr++;
+ 	if (magic_num != PLATFORM_CONFIG_MAGIC_NUM) {
+ 		dd_dev_err(dd, "%s: Bad config file\n", __func__);
++		ret = -EINVAL;
+ 		goto bail;
+ 	}
+ 
+@@ -1774,6 +1776,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+ 	if (file_length > dd->platform_config.size) {
+ 		dd_dev_info(dd, "%s:File claims to be larger than read size\n",
+ 			    __func__);
++		ret = -EINVAL;
+ 		goto bail;
+ 	} else if (file_length < dd->platform_config.size) {
+ 		dd_dev_info(dd,
+@@ -1794,6 +1797,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+ 			dd_dev_err(dd, "%s: Failed validation at offset %ld\n",
+ 				   __func__, (ptr - (u32 *)
+ 					      dd->platform_config.data));
++			ret = -EINVAL;
+ 			goto bail;
+ 		}
+ 
+@@ -1837,6 +1841,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+ 					   __func__, table_type,
+ 					   (ptr - (u32 *)
+ 					    dd->platform_config.data));
++				ret = -EINVAL;
+ 				goto bail; /* We don't trust this file now */
+ 			}
+ 			pcfgcache->config_tables[table_type].table = ptr;
+@@ -1856,6 +1861,7 @@ int parse_platform_config(struct hfi1_devdata *dd)
+ 					   __func__, table_type,
+ 					   (ptr -
+ 					    (u32 *)dd->platform_config.data));
++				ret = -EINVAL;
+ 				goto bail; /* We don't trust this file now */
+ 			}
+ 			pcfgcache->config_tables[table_type].table_metadata =
+diff --git a/drivers/infiniband/hw/hns/Makefile b/drivers/infiniband/hw/hns/Makefile
+index 9f04f25d96317..a7d259238305b 100644
+--- a/drivers/infiniband/hw/hns/Makefile
++++ b/drivers/infiniband/hw/hns/Makefile
+@@ -10,6 +10,6 @@ hns-roce-objs := hns_roce_main.o hns_roce_cmd.o hns_roce_pd.o \
+ 	hns_roce_cq.o hns_roce_alloc.o hns_roce_db.o hns_roce_srq.o hns_roce_restrack.o
+ 
+ ifdef CONFIG_INFINIBAND_HNS_HIP08
+-hns-roce-hw-v2-objs := hns_roce_hw_v2.o hns_roce_hw_v2_dfx.o $(hns-roce-objs)
++hns-roce-hw-v2-objs := hns_roce_hw_v2.o $(hns-roce-objs)
+ obj-$(CONFIG_INFINIBAND_HNS) += hns-roce-hw-v2.o
+ endif
+diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
+index d24996526c4d9..48db4a42b7d3f 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_device.h
++++ b/drivers/infiniband/hw/hns/hns_roce_device.h
+@@ -202,6 +202,7 @@ struct hns_roce_ucontext {
+ 	struct list_head	page_list;
+ 	struct mutex		page_mutex;
+ 	struct hns_user_mmap_entry *db_mmap_entry;
++	u32			config;
+ };
+ 
+ struct hns_roce_pd {
+@@ -335,6 +336,7 @@ struct hns_roce_wq {
+ 	u32		head;
+ 	u32		tail;
+ 	void __iomem	*db_reg;
++	u32		ext_sge_cnt;
+ };
+ 
+ struct hns_roce_sge {
+@@ -637,6 +639,7 @@ struct hns_roce_qp {
+ 	struct list_head	rq_node; /* all recv qps are on a list */
+ 	struct list_head	sq_node; /* all send qps are on a list */
+ 	struct hns_user_mmap_entry *dwqe_mmap_entry;
++	u32			config;
+ };
+ 
+ struct hns_roce_ib_iboe {
+@@ -848,11 +851,6 @@ struct hns_roce_caps {
+ 	enum cong_type	cong_type;
+ };
+ 
+-struct hns_roce_dfx_hw {
+-	int (*query_cqc_info)(struct hns_roce_dev *hr_dev, u32 cqn,
+-			      int *buffer);
+-};
+-
+ enum hns_roce_device_state {
+ 	HNS_ROCE_DEVICE_STATE_INITED,
+ 	HNS_ROCE_DEVICE_STATE_RST_DOWN,
+@@ -898,6 +896,7 @@ struct hns_roce_hw {
+ 	int (*init_eq)(struct hns_roce_dev *hr_dev);
+ 	void (*cleanup_eq)(struct hns_roce_dev *hr_dev);
+ 	int (*write_srqc)(struct hns_roce_srq *srq, void *mb_buf);
++	int (*query_cqc)(struct hns_roce_dev *hr_dev, u32 cqn, void *buffer);
+ 	const struct ib_device_ops *hns_roce_dev_ops;
+ 	const struct ib_device_ops *hns_roce_dev_srq_ops;
+ };
+@@ -959,7 +958,6 @@ struct hns_roce_dev {
+ 	void			*priv;
+ 	struct workqueue_struct *irq_workq;
+ 	struct work_struct ecc_work;
+-	const struct hns_roce_dfx_hw *dfx;
+ 	u32 func_num;
+ 	u32 is_vf;
+ 	u32 cong_algo_tmpl_id;
+@@ -1227,8 +1225,7 @@ u8 hns_get_gid_index(struct hns_roce_dev *hr_dev, u32 port, int gid_index);
+ void hns_roce_handle_device_err(struct hns_roce_dev *hr_dev);
+ int hns_roce_init(struct hns_roce_dev *hr_dev);
+ void hns_roce_exit(struct hns_roce_dev *hr_dev);
+-int hns_roce_fill_res_cq_entry(struct sk_buff *msg,
+-			       struct ib_cq *ib_cq);
++int hns_roce_fill_res_cq_entry(struct sk_buff *msg, struct ib_cq *ib_cq);
+ struct hns_user_mmap_entry *
+ hns_roce_user_mmap_entry_insert(struct ib_ucontext *ucontext, u64 address,
+ 				size_t length,
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index 105888c6ccb77..b55a96863d1ae 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -192,8 +192,6 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+ 				 unsigned int *sge_idx, u32 msg_len)
+ {
+ 	struct ib_device *ibdev = &(to_hr_dev(qp->ibqp.device))->ib_dev;
+-	unsigned int dseg_len = sizeof(struct hns_roce_v2_wqe_data_seg);
+-	unsigned int ext_sge_sz = qp->sq.max_gs * dseg_len;
+ 	unsigned int left_len_in_pg;
+ 	unsigned int idx = *sge_idx;
+ 	unsigned int i = 0;
+@@ -201,7 +199,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+ 	void *addr;
+ 	void *dseg;
+ 
+-	if (msg_len > ext_sge_sz) {
++	if (msg_len > qp->sq.ext_sge_cnt * HNS_ROCE_SGE_SIZE) {
+ 		ibdev_err(ibdev,
+ 			  "no enough extended sge space for inline data.\n");
+ 		return -EINVAL;
+@@ -221,7 +219,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+ 		if (len <= left_len_in_pg) {
+ 			memcpy(dseg, addr, len);
+ 
+-			idx += len / dseg_len;
++			idx += len / HNS_ROCE_SGE_SIZE;
+ 
+ 			i++;
+ 			if (i >= wr->num_sge)
+@@ -236,7 +234,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
+ 
+ 			len -= left_len_in_pg;
+ 			addr += left_len_in_pg;
+-			idx += left_len_in_pg / dseg_len;
++			idx += left_len_in_pg / HNS_ROCE_SGE_SIZE;
+ 			dseg = hns_roce_get_extend_sge(qp,
+ 						idx & (qp->sge.sge_cnt - 1));
+ 			left_len_in_pg = 1 << HNS_HW_PAGE_SHIFT;
+@@ -1275,6 +1273,30 @@ static void update_cmdq_status(struct hns_roce_dev *hr_dev)
+ 		hr_dev->cmd.state = HNS_ROCE_CMDQ_STATE_FATAL_ERR;
+ }
+ 
++static int hns_roce_cmd_err_convert_errno(u16 desc_ret)
++{
++	struct hns_roce_cmd_errcode errcode_table[] = {
++		{CMD_EXEC_SUCCESS, 0},
++		{CMD_NO_AUTH, -EPERM},
++		{CMD_NOT_EXIST, -EOPNOTSUPP},
++		{CMD_CRQ_FULL, -EXFULL},
++		{CMD_NEXT_ERR, -ENOSR},
++		{CMD_NOT_EXEC, -ENOTBLK},
++		{CMD_PARA_ERR, -EINVAL},
++		{CMD_RESULT_ERR, -ERANGE},
++		{CMD_TIMEOUT, -ETIME},
++		{CMD_HILINK_ERR, -ENOLINK},
++		{CMD_INFO_ILLEGAL, -ENXIO},
++		{CMD_INVALID, -EBADR},
++	};
++	u16 i;
++
++	for (i = 0; i < ARRAY_SIZE(errcode_table); i++)
++		if (desc_ret == errcode_table[i].return_status)
++			return errcode_table[i].errno;
++	return -EIO;
++}
++
+ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
+ 			       struct hns_roce_cmq_desc *desc, int num)
+ {
+@@ -1320,7 +1342,7 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
+ 			dev_err_ratelimited(hr_dev->dev,
+ 					    "Cmdq IO error, opcode = 0x%x, return = 0x%x.\n",
+ 					    desc->opcode, desc_ret);
+-			ret = -EIO;
++			ret = hns_roce_cmd_err_convert_errno(desc_ret);
+ 		}
+ 	} else {
+ 		/* FW/HW reset or incorrect number of desc */
+@@ -2027,13 +2049,14 @@ static void set_default_caps(struct hns_roce_dev *hr_dev)
+ 
+ 	caps->flags |= HNS_ROCE_CAP_FLAG_ATOMIC | HNS_ROCE_CAP_FLAG_MW |
+ 		       HNS_ROCE_CAP_FLAG_SRQ | HNS_ROCE_CAP_FLAG_FRMR |
+-		       HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL | HNS_ROCE_CAP_FLAG_XRC;
++		       HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL;
+ 
+ 	caps->gid_table_len[0] = HNS_ROCE_V2_GID_INDEX_NUM;
+ 
+ 	if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09) {
+ 		caps->flags |= HNS_ROCE_CAP_FLAG_STASH |
+-			       HNS_ROCE_CAP_FLAG_DIRECT_WQE;
++			       HNS_ROCE_CAP_FLAG_DIRECT_WQE |
++			       HNS_ROCE_CAP_FLAG_XRC;
+ 		caps->max_sq_inline = HNS_ROCE_V3_MAX_SQ_INLINE;
+ 	} else {
+ 		caps->max_sq_inline = HNS_ROCE_V2_MAX_SQ_INLINE;
+@@ -2346,6 +2369,9 @@ static int hns_roce_query_pf_caps(struct hns_roce_dev *hr_dev)
+ 	caps->wqe_sge_hop_num = hr_reg_read(resp_d, PF_CAPS_D_EX_SGE_HOP_NUM);
+ 	caps->wqe_rq_hop_num = hr_reg_read(resp_d, PF_CAPS_D_RQWQE_HOP_NUM);
+ 
++	if (!(caps->page_size_cap & PAGE_SIZE))
++		caps->page_size_cap = HNS_ROCE_V2_PAGE_SIZE_SUPPORTED;
++
+ 	return 0;
+ }
+ 
+@@ -2635,31 +2661,124 @@ static void free_dip_list(struct hns_roce_dev *hr_dev)
+ 	spin_unlock_irqrestore(&hr_dev->dip_list_lock, flags);
+ }
+ 
+-static void free_mr_exit(struct hns_roce_dev *hr_dev)
++static struct ib_pd *free_mr_init_pd(struct hns_roce_dev *hr_dev)
++{
++	struct hns_roce_v2_priv *priv = hr_dev->priv;
++	struct hns_roce_v2_free_mr *free_mr = &priv->free_mr;
++	struct ib_device *ibdev = &hr_dev->ib_dev;
++	struct hns_roce_pd *hr_pd;
++	struct ib_pd *pd;
++
++	hr_pd = kzalloc(sizeof(*hr_pd), GFP_KERNEL);
++	if (ZERO_OR_NULL_PTR(hr_pd))
++		return NULL;
++	pd = &hr_pd->ibpd;
++	pd->device = ibdev;
++
++	if (hns_roce_alloc_pd(pd, NULL)) {
++		ibdev_err(ibdev, "failed to create pd for free mr.\n");
++		kfree(hr_pd);
++		return NULL;
++	}
++	free_mr->rsv_pd = to_hr_pd(pd);
++	free_mr->rsv_pd->ibpd.device = &hr_dev->ib_dev;
++	free_mr->rsv_pd->ibpd.uobject = NULL;
++	free_mr->rsv_pd->ibpd.__internal_mr = NULL;
++	atomic_set(&free_mr->rsv_pd->ibpd.usecnt, 0);
++
++	return pd;
++}
++
++static struct ib_cq *free_mr_init_cq(struct hns_roce_dev *hr_dev)
++{
++	struct hns_roce_v2_priv *priv = hr_dev->priv;
++	struct hns_roce_v2_free_mr *free_mr = &priv->free_mr;
++	struct ib_device *ibdev = &hr_dev->ib_dev;
++	struct ib_cq_init_attr cq_init_attr = {};
++	struct hns_roce_cq *hr_cq;
++	struct ib_cq *cq;
++
++	cq_init_attr.cqe = HNS_ROCE_FREE_MR_USED_CQE_NUM;
++
++	hr_cq = kzalloc(sizeof(*hr_cq), GFP_KERNEL);
++	if (ZERO_OR_NULL_PTR(hr_cq))
++		return NULL;
++
++	cq = &hr_cq->ib_cq;
++	cq->device = ibdev;
++
++	if (hns_roce_create_cq(cq, &cq_init_attr, NULL)) {
++		ibdev_err(ibdev, "failed to create cq for free mr.\n");
++		kfree(hr_cq);
++		return NULL;
++	}
++	free_mr->rsv_cq = to_hr_cq(cq);
++	free_mr->rsv_cq->ib_cq.device = &hr_dev->ib_dev;
++	free_mr->rsv_cq->ib_cq.uobject = NULL;
++	free_mr->rsv_cq->ib_cq.comp_handler = NULL;
++	free_mr->rsv_cq->ib_cq.event_handler = NULL;
++	free_mr->rsv_cq->ib_cq.cq_context = NULL;
++	atomic_set(&free_mr->rsv_cq->ib_cq.usecnt, 0);
++
++	return cq;
++}
++
++static int free_mr_init_qp(struct hns_roce_dev *hr_dev, struct ib_cq *cq,
++			   struct ib_qp_init_attr *init_attr, int i)
+ {
+ 	struct hns_roce_v2_priv *priv = hr_dev->priv;
+ 	struct hns_roce_v2_free_mr *free_mr = &priv->free_mr;
++	struct ib_device *ibdev = &hr_dev->ib_dev;
++	struct hns_roce_qp *hr_qp;
++	struct ib_qp *qp;
+ 	int ret;
++
++	hr_qp = kzalloc(sizeof(*hr_qp), GFP_KERNEL);
++	if (ZERO_OR_NULL_PTR(hr_qp))
++		return -ENOMEM;
++
++	qp = &hr_qp->ibqp;
++	qp->device = ibdev;
++
++	ret = hns_roce_create_qp(qp, init_attr, NULL);
++	if (ret) {
++		ibdev_err(ibdev, "failed to create qp for free mr.\n");
++		kfree(hr_qp);
++		return ret;
++	}
++
++	free_mr->rsv_qp[i] = hr_qp;
++	free_mr->rsv_qp[i]->ibqp.recv_cq = cq;
++	free_mr->rsv_qp[i]->ibqp.send_cq = cq;
++
++	return 0;
++}
++
++static void free_mr_exit(struct hns_roce_dev *hr_dev)
++{
++	struct hns_roce_v2_priv *priv = hr_dev->priv;
++	struct hns_roce_v2_free_mr *free_mr = &priv->free_mr;
++	struct ib_qp *qp;
+ 	int i;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(free_mr->rsv_qp); i++) {
+ 		if (free_mr->rsv_qp[i]) {
+-			ret = ib_destroy_qp(free_mr->rsv_qp[i]);
+-			if (ret)
+-				ibdev_err(&hr_dev->ib_dev,
+-					  "failed to destroy qp in free mr.\n");
+-
++			qp = &free_mr->rsv_qp[i]->ibqp;
++			hns_roce_v2_destroy_qp(qp, NULL);
++			kfree(free_mr->rsv_qp[i]);
+ 			free_mr->rsv_qp[i] = NULL;
+ 		}
+ 	}
+ 
+ 	if (free_mr->rsv_cq) {
+-		ib_destroy_cq(free_mr->rsv_cq);
++		hns_roce_destroy_cq(&free_mr->rsv_cq->ib_cq, NULL);
++		kfree(free_mr->rsv_cq);
+ 		free_mr->rsv_cq = NULL;
+ 	}
+ 
+ 	if (free_mr->rsv_pd) {
+-		ib_dealloc_pd(free_mr->rsv_pd);
++		hns_roce_dealloc_pd(&free_mr->rsv_pd->ibpd, NULL);
++		kfree(free_mr->rsv_pd);
+ 		free_mr->rsv_pd = NULL;
+ 	}
+ }
+@@ -2668,55 +2787,46 @@ static int free_mr_alloc_res(struct hns_roce_dev *hr_dev)
+ {
+ 	struct hns_roce_v2_priv *priv = hr_dev->priv;
+ 	struct hns_roce_v2_free_mr *free_mr = &priv->free_mr;
+-	struct ib_device *ibdev = &hr_dev->ib_dev;
+-	struct ib_cq_init_attr cq_init_attr = {};
+ 	struct ib_qp_init_attr qp_init_attr = {};
+ 	struct ib_pd *pd;
+ 	struct ib_cq *cq;
+-	struct ib_qp *qp;
+ 	int ret;
+ 	int i;
+ 
+-	pd = ib_alloc_pd(ibdev, 0);
+-	if (IS_ERR(pd)) {
+-		ibdev_err(ibdev, "failed to create pd for free mr.\n");
+-		return PTR_ERR(pd);
+-	}
+-	free_mr->rsv_pd = pd;
++	pd = free_mr_init_pd(hr_dev);
++	if (!pd)
++		return -ENOMEM;
+ 
+-	cq_init_attr.cqe = HNS_ROCE_FREE_MR_USED_CQE_NUM;
+-	cq = ib_create_cq(ibdev, NULL, NULL, NULL, &cq_init_attr);
+-	if (IS_ERR(cq)) {
+-		ibdev_err(ibdev, "failed to create cq for free mr.\n");
+-		ret = PTR_ERR(cq);
+-		goto create_failed;
++	cq = free_mr_init_cq(hr_dev);
++	if (!cq) {
++		ret = -ENOMEM;
++		goto create_failed_cq;
+ 	}
+-	free_mr->rsv_cq = cq;
+ 
+ 	qp_init_attr.qp_type = IB_QPT_RC;
+ 	qp_init_attr.sq_sig_type = IB_SIGNAL_ALL_WR;
+-	qp_init_attr.send_cq = free_mr->rsv_cq;
+-	qp_init_attr.recv_cq = free_mr->rsv_cq;
++	qp_init_attr.send_cq = cq;
++	qp_init_attr.recv_cq = cq;
+ 	for (i = 0; i < ARRAY_SIZE(free_mr->rsv_qp); i++) {
+ 		qp_init_attr.cap.max_send_wr = HNS_ROCE_FREE_MR_USED_SQWQE_NUM;
+ 		qp_init_attr.cap.max_send_sge = HNS_ROCE_FREE_MR_USED_SQSGE_NUM;
+ 		qp_init_attr.cap.max_recv_wr = HNS_ROCE_FREE_MR_USED_RQWQE_NUM;
+ 		qp_init_attr.cap.max_recv_sge = HNS_ROCE_FREE_MR_USED_RQSGE_NUM;
+ 
+-		qp = ib_create_qp(free_mr->rsv_pd, &qp_init_attr);
+-		if (IS_ERR(qp)) {
+-			ibdev_err(ibdev, "failed to create qp for free mr.\n");
+-			ret = PTR_ERR(qp);
+-			goto create_failed;
+-		}
+-
+-		free_mr->rsv_qp[i] = qp;
++		ret = free_mr_init_qp(hr_dev, cq, &qp_init_attr, i);
++		if (ret)
++			goto create_failed_qp;
+ 	}
+ 
+ 	return 0;
+ 
+-create_failed:
+-	free_mr_exit(hr_dev);
++create_failed_qp:
++	hns_roce_destroy_cq(cq, NULL);
++	kfree(cq);
++
++create_failed_cq:
++	hns_roce_dealloc_pd(pd, NULL);
++	kfree(pd);
+ 
+ 	return ret;
+ }
+@@ -2732,14 +2842,17 @@ static int free_mr_modify_rsv_qp(struct hns_roce_dev *hr_dev,
+ 	int mask;
+ 	int ret;
+ 
+-	hr_qp = to_hr_qp(free_mr->rsv_qp[sl_num]);
++	hr_qp = to_hr_qp(&free_mr->rsv_qp[sl_num]->ibqp);
+ 	hr_qp->free_mr_en = 1;
++	hr_qp->ibqp.device = ibdev;
++	hr_qp->ibqp.qp_type = IB_QPT_RC;
+ 
+ 	mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT | IB_QP_ACCESS_FLAGS;
+ 	attr->qp_state = IB_QPS_INIT;
+ 	attr->port_num = 1;
+ 	attr->qp_access_flags = IB_ACCESS_REMOTE_WRITE;
+-	ret = ib_modify_qp(&hr_qp->ibqp, attr, mask);
++	ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, attr, mask, IB_QPS_INIT,
++				    IB_QPS_INIT);
+ 	if (ret) {
+ 		ibdev_err(ibdev, "failed to modify qp to init, ret = %d.\n",
+ 			  ret);
+@@ -2760,7 +2873,8 @@ static int free_mr_modify_rsv_qp(struct hns_roce_dev *hr_dev,
+ 
+ 	rdma_ah_set_sl(&attr->ah_attr, (u8)sl_num);
+ 
+-	ret = ib_modify_qp(&hr_qp->ibqp, attr, mask);
++	ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, attr, mask, IB_QPS_INIT,
++				    IB_QPS_RTR);
+ 	hr_dev->loop_idc = loopback;
+ 	if (ret) {
+ 		ibdev_err(ibdev, "failed to modify qp to rtr, ret = %d.\n",
+@@ -2774,7 +2888,8 @@ static int free_mr_modify_rsv_qp(struct hns_roce_dev *hr_dev,
+ 	attr->sq_psn = HNS_ROCE_FREE_MR_USED_PSN;
+ 	attr->retry_cnt = HNS_ROCE_FREE_MR_USED_QP_RETRY_CNT;
+ 	attr->timeout = HNS_ROCE_FREE_MR_USED_QP_TIMEOUT;
+-	ret = ib_modify_qp(&hr_qp->ibqp, attr, mask);
++	ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, attr, mask, IB_QPS_RTR,
++				    IB_QPS_RTS);
+ 	if (ret)
+ 		ibdev_err(ibdev, "failed to modify qp to rts, ret = %d.\n",
+ 			  ret);
+@@ -3190,7 +3305,8 @@ static int set_mtpt_pbl(struct hns_roce_dev *hr_dev,
+ 	int i, count;
+ 
+ 	count = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages,
+-				  ARRAY_SIZE(pages), &pbl_ba);
++				  min_t(int, ARRAY_SIZE(pages), mr->npages),
++				  &pbl_ba);
+ 	if (count < 1) {
+ 		ibdev_err(ibdev, "failed to find PBL mtr, count = %d.\n",
+ 			  count);
+@@ -3418,7 +3534,7 @@ static void free_mr_send_cmd_to_hw(struct hns_roce_dev *hr_dev)
+ 	mutex_lock(&free_mr->mutex);
+ 
+ 	for (i = 0; i < ARRAY_SIZE(free_mr->rsv_qp); i++) {
+-		hr_qp = to_hr_qp(free_mr->rsv_qp[i]);
++		hr_qp = free_mr->rsv_qp[i];
+ 
+ 		ret = free_mr_post_send_lp_wqe(hr_qp);
+ 		if (ret) {
+@@ -3433,7 +3549,7 @@ static void free_mr_send_cmd_to_hw(struct hns_roce_dev *hr_dev)
+ 
+ 	end = msecs_to_jiffies(HNS_ROCE_V2_FREE_MR_TIMEOUT) + jiffies;
+ 	while (cqe_cnt) {
+-		npolled = hns_roce_v2_poll_cq(free_mr->rsv_cq, cqe_cnt, wc);
++		npolled = hns_roce_v2_poll_cq(&free_mr->rsv_cq->ib_cq, cqe_cnt, wc);
+ 		if (npolled < 0) {
+ 			ibdev_err(ibdev,
+ 				  "failed to poll cqe for free mr, remain %d cqe.\n",
+@@ -5383,6 +5499,8 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
+ 
+ 		rdma_ah_set_sl(&qp_attr->ah_attr,
+ 			       hr_reg_read(&context, QPC_SL));
++		rdma_ah_set_port_num(&qp_attr->ah_attr, hr_qp->port + 1);
++		rdma_ah_set_ah_flags(&qp_attr->ah_attr, IB_AH_GRH);
+ 		grh->flow_label = hr_reg_read(&context, QPC_FL);
+ 		grh->sgid_index = hr_reg_read(&context, QPC_GMV_IDX);
+ 		grh->hop_limit = hr_reg_read(&context, QPC_HOPLIMIT);
+@@ -5476,7 +5594,7 @@ static int hns_roce_v2_destroy_qp_common(struct hns_roce_dev *hr_dev,
+ 	return ret;
+ }
+ 
+-static int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
++int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
+ {
+ 	struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+ 	struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+@@ -5766,6 +5884,35 @@ static int hns_roce_v2_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
+ 	return ret;
+ }
+ 
++static int hns_roce_v2_query_cqc(struct hns_roce_dev *hr_dev, u32 cqn,
++				 void *buffer)
++{
++	struct hns_roce_v2_cq_context *context;
++	struct hns_roce_cmd_mailbox *mailbox;
++	int ret;
++
++	mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
++	if (IS_ERR(mailbox))
++		return PTR_ERR(mailbox);
++
++	context = mailbox->buf;
++	ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma,
++				HNS_ROCE_CMD_QUERY_CQC, cqn);
++	if (ret) {
++		ibdev_err(&hr_dev->ib_dev,
++			  "failed to process cmd when querying CQ, ret = %d.\n",
++			  ret);
++		goto err_mailbox;
++	}
++
++	memcpy(buffer, context, sizeof(*context));
++
++err_mailbox:
++	hns_roce_free_cmd_mailbox(hr_dev, mailbox);
++
++	return ret;
++}
++
+ static void hns_roce_irq_work_handle(struct work_struct *work)
+ {
+ 	struct hns_roce_work *irq_work =
+@@ -6567,10 +6714,6 @@ static void hns_roce_v2_cleanup_eq_table(struct hns_roce_dev *hr_dev)
+ 	kfree(eq_table->eq);
+ }
+ 
+-static const struct hns_roce_dfx_hw hns_roce_dfx_hw_v2 = {
+-	.query_cqc_info = hns_roce_v2_query_cqc_info,
+-};
+-
+ static const struct ib_device_ops hns_roce_v2_dev_ops = {
+ 	.destroy_qp = hns_roce_v2_destroy_qp,
+ 	.modify_cq = hns_roce_v2_modify_cq,
+@@ -6611,6 +6754,7 @@ static const struct hns_roce_hw hns_roce_hw_v2 = {
+ 	.init_eq = hns_roce_v2_init_eq_table,
+ 	.cleanup_eq = hns_roce_v2_cleanup_eq_table,
+ 	.write_srqc = hns_roce_v2_write_srqc,
++	.query_cqc = hns_roce_v2_query_cqc,
+ 	.hns_roce_dev_ops = &hns_roce_v2_dev_ops,
+ 	.hns_roce_dev_srq_ops = &hns_roce_v2_dev_srq_ops,
+ };
+@@ -6642,7 +6786,6 @@ static void hns_roce_hw_v2_get_cfg(struct hns_roce_dev *hr_dev,
+ 	hr_dev->is_vf = id->driver_data;
+ 	hr_dev->dev = &handle->pdev->dev;
+ 	hr_dev->hw = &hns_roce_hw_v2;
+-	hr_dev->dfx = &hns_roce_dfx_hw_v2;
+ 	hr_dev->sdb_offset = ROCEE_DB_SQ_L_0_REG;
+ 	hr_dev->odb_offset = hr_dev->sdb_offset;
+ 
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+index 4544a8775ce5a..4bf89c1280dc4 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+@@ -275,6 +275,11 @@ enum hns_roce_cmd_return_status {
+ 	CMD_OTHER_ERR = 0xff
+ };
+ 
++struct hns_roce_cmd_errcode {
++	enum hns_roce_cmd_return_status return_status;
++	int errno;
++};
++
+ enum hns_roce_sgid_type {
+ 	GID_TYPE_FLAG_ROCE_V1 = 0,
+ 	GID_TYPE_FLAG_ROCE_V2_IPV4,
+@@ -1328,9 +1333,9 @@ struct hns_roce_link_table {
+ #define HNS_ROCE_EXT_LLM_MIN_PAGES(que_num) ((que_num) * 4 + 2)
+ 
+ struct hns_roce_v2_free_mr {
+-	struct ib_qp *rsv_qp[HNS_ROCE_FREE_MR_USED_QP_NUM];
+-	struct ib_cq *rsv_cq;
+-	struct ib_pd *rsv_pd;
++	struct hns_roce_qp *rsv_qp[HNS_ROCE_FREE_MR_USED_QP_NUM];
++	struct hns_roce_cq *rsv_cq;
++	struct hns_roce_pd *rsv_pd;
+ 	struct mutex mutex;
+ };
+ 
+@@ -1460,8 +1465,7 @@ struct hns_roce_sccc_clr_done {
+ 	__le32 rsv[5];
+ };
+ 
+-int hns_roce_v2_query_cqc_info(struct hns_roce_dev *hr_dev, u32 cqn,
+-			       int *buffer);
++int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata);
+ 
+ static inline void hns_roce_write64(struct hns_roce_dev *hr_dev, __le32 val[2],
+ 				    void __iomem *dest)
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2_dfx.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2_dfx.c
+deleted file mode 100644
+index f7a75a7cda749..0000000000000
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2_dfx.c
++++ /dev/null
+@@ -1,34 +0,0 @@
+-// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+-// Copyright (c) 2019 Hisilicon Limited.
+-
+-#include "hnae3.h"
+-#include "hns_roce_device.h"
+-#include "hns_roce_cmd.h"
+-#include "hns_roce_hw_v2.h"
+-
+-int hns_roce_v2_query_cqc_info(struct hns_roce_dev *hr_dev, u32 cqn,
+-			       int *buffer)
+-{
+-	struct hns_roce_v2_cq_context *cq_context;
+-	struct hns_roce_cmd_mailbox *mailbox;
+-	int ret;
+-
+-	mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
+-	if (IS_ERR(mailbox))
+-		return PTR_ERR(mailbox);
+-
+-	cq_context = mailbox->buf;
+-	ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma, HNS_ROCE_CMD_QUERY_CQC,
+-				cqn);
+-	if (ret) {
+-		dev_err(hr_dev->dev, "QUERY cqc cmd process error\n");
+-		goto err_mailbox;
+-	}
+-
+-	memcpy(buffer, cq_context, sizeof(*cq_context));
+-
+-err_mailbox:
+-	hns_roce_free_cmd_mailbox(hr_dev, mailbox);
+-
+-	return ret;
+-}
+diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
+index 4ccb217b2841d..bf5c7729d7e84 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_main.c
++++ b/drivers/infiniband/hw/hns/hns_roce_main.c
+@@ -354,10 +354,11 @@ static int hns_roce_alloc_uar_entry(struct ib_ucontext *uctx)
+ static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx,
+ 				   struct ib_udata *udata)
+ {
+-	int ret;
+ 	struct hns_roce_ucontext *context = to_hr_ucontext(uctx);
+-	struct hns_roce_ib_alloc_ucontext_resp resp = {};
+ 	struct hns_roce_dev *hr_dev = to_hr_dev(uctx->device);
++	struct hns_roce_ib_alloc_ucontext_resp resp = {};
++	struct hns_roce_ib_alloc_ucontext ucmd = {};
++	int ret;
+ 
+ 	if (!hr_dev->active)
+ 		return -EAGAIN;
+@@ -365,6 +366,19 @@ static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx,
+ 	resp.qp_tab_size = hr_dev->caps.num_qps;
+ 	resp.srq_tab_size = hr_dev->caps.num_srqs;
+ 
++	ret = ib_copy_from_udata(&ucmd, udata,
++				 min(udata->inlen, sizeof(ucmd)));
++	if (ret)
++		return ret;
++
++	if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09)
++		context->config = ucmd.config & HNS_ROCE_EXSGE_FLAGS;
++
++	if (context->config & HNS_ROCE_EXSGE_FLAGS) {
++		resp.config |= HNS_ROCE_RSP_EXSGE_FLAGS;
++		resp.max_inline_data = hr_dev->caps.max_sq_inline;
++	}
++
+ 	ret = hns_roce_uar_alloc(hr_dev, &context->uar);
+ 	if (ret)
+ 		goto error_fail_uar_alloc;
+@@ -515,7 +529,6 @@ static const struct ib_device_ops hns_roce_dev_ops = {
+ 	.destroy_ah = hns_roce_destroy_ah,
+ 	.destroy_cq = hns_roce_destroy_cq,
+ 	.disassociate_ucontext = hns_roce_disassociate_ucontext,
+-	.fill_res_cq_entry = hns_roce_fill_res_cq_entry,
+ 	.get_dma_mr = hns_roce_get_dma_mr,
+ 	.get_link_layer = hns_roce_get_link_layer,
+ 	.get_port_immutable = hns_roce_port_immutable,
+@@ -566,6 +579,10 @@ static const struct ib_device_ops hns_roce_dev_xrcd_ops = {
+ 	INIT_RDMA_OBJ_SIZE(ib_xrcd, hns_roce_xrcd, ibxrcd),
+ };
+ 
++static const struct ib_device_ops hns_roce_dev_restrack_ops = {
++	.fill_res_cq_entry = hns_roce_fill_res_cq_entry,
++};
++
+ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
+ {
+ 	int ret;
+@@ -605,6 +622,7 @@ static int hns_roce_register_device(struct hns_roce_dev *hr_dev)
+ 
+ 	ib_set_device_ops(ib_dev, hr_dev->hw->hns_roce_dev_ops);
+ 	ib_set_device_ops(ib_dev, &hns_roce_dev_ops);
++	ib_set_device_ops(ib_dev, &hns_roce_dev_restrack_ops);
+ 	for (i = 0; i < hr_dev->caps.num_ports; i++) {
+ 		if (!hr_dev->iboe.netdevs[i])
+ 			continue;
+diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
+index dedfa56f57731..fb165069c8d9d 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
+@@ -392,10 +392,10 @@ struct ib_mr *hns_roce_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
+ 
+ 	return &mr->ibmr;
+ 
+-err_key:
+-	free_mr_key(hr_dev, mr);
+ err_pbl:
+ 	free_mr_pbl(hr_dev, mr);
++err_key:
++	free_mr_key(hr_dev, mr);
+ err_free:
+ 	kfree(mr);
+ 	return ERR_PTR(ret);
+diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
+index 7bee7f6c5e702..a0040096ddb1b 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
++++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
+@@ -479,38 +479,109 @@ static int set_rq_size(struct hns_roce_dev *hr_dev, struct ib_qp_cap *cap,
+ 	return 0;
+ }
+ 
+-static u32 get_wqe_ext_sge_cnt(struct hns_roce_qp *qp)
++static u32 get_max_inline_data(struct hns_roce_dev *hr_dev,
++			       struct ib_qp_cap *cap)
+ {
+-	/* GSI/UD QP only has extended sge */
+-	if (qp->ibqp.qp_type == IB_QPT_GSI || qp->ibqp.qp_type == IB_QPT_UD)
+-		return qp->sq.max_gs;
+-
+-	if (qp->sq.max_gs > HNS_ROCE_SGE_IN_WQE)
+-		return qp->sq.max_gs - HNS_ROCE_SGE_IN_WQE;
++	if (cap->max_inline_data) {
++		cap->max_inline_data = roundup_pow_of_two(cap->max_inline_data);
++		return min(cap->max_inline_data,
++			   hr_dev->caps.max_sq_inline);
++	}
+ 
+ 	return 0;
+ }
+ 
++static void update_inline_data(struct hns_roce_qp *hr_qp,
++			       struct ib_qp_cap *cap)
++{
++	u32 sge_num = hr_qp->sq.ext_sge_cnt;
++
++	if (hr_qp->config & HNS_ROCE_EXSGE_FLAGS) {
++		if (!(hr_qp->ibqp.qp_type == IB_QPT_GSI ||
++		      hr_qp->ibqp.qp_type == IB_QPT_UD))
++			sge_num = max((u32)HNS_ROCE_SGE_IN_WQE, sge_num);
++
++		cap->max_inline_data = max(cap->max_inline_data,
++					   sge_num * HNS_ROCE_SGE_SIZE);
++	}
++
++	hr_qp->max_inline_data = cap->max_inline_data;
++}
++
++static u32 get_sge_num_from_max_send_sge(bool is_ud_or_gsi,
++					 u32 max_send_sge)
++{
++	unsigned int std_sge_num;
++	unsigned int min_sge;
++
++	std_sge_num = is_ud_or_gsi ? 0 : HNS_ROCE_SGE_IN_WQE;
++	min_sge = is_ud_or_gsi ? 1 : 0;
++	return max_send_sge > std_sge_num ? (max_send_sge - std_sge_num) :
++				min_sge;
++}
++
++static unsigned int get_sge_num_from_max_inl_data(bool is_ud_or_gsi,
++						  u32 max_inline_data)
++{
++	unsigned int inline_sge;
++
++	inline_sge = roundup_pow_of_two(max_inline_data) / HNS_ROCE_SGE_SIZE;
++
++	/*
++	 * if max_inline_data less than
++	 * HNS_ROCE_SGE_IN_WQE * HNS_ROCE_SGE_SIZE,
++	 * In addition to ud's mode, no need to extend sge.
++	 */
++	if (!is_ud_or_gsi && inline_sge <= HNS_ROCE_SGE_IN_WQE)
++		inline_sge = 0;
++
++	return inline_sge;
++}
++
+ static void set_ext_sge_param(struct hns_roce_dev *hr_dev, u32 sq_wqe_cnt,
+ 			      struct hns_roce_qp *hr_qp, struct ib_qp_cap *cap)
+ {
++	bool is_ud_or_gsi = (hr_qp->ibqp.qp_type == IB_QPT_GSI ||
++				hr_qp->ibqp.qp_type == IB_QPT_UD);
++	unsigned int std_sge_num;
++	u32 inline_ext_sge = 0;
++	u32 ext_wqe_sge_cnt;
+ 	u32 total_sge_cnt;
+-	u32 wqe_sge_cnt;
++
++	cap->max_inline_data = get_max_inline_data(hr_dev, cap);
+ 
+ 	hr_qp->sge.sge_shift = HNS_ROCE_SGE_SHIFT;
++	std_sge_num = is_ud_or_gsi ? 0 : HNS_ROCE_SGE_IN_WQE;
++	ext_wqe_sge_cnt = get_sge_num_from_max_send_sge(is_ud_or_gsi,
++							cap->max_send_sge);
+ 
+-	hr_qp->sq.max_gs = max(1U, cap->max_send_sge);
++	if (hr_qp->config & HNS_ROCE_EXSGE_FLAGS) {
++		inline_ext_sge = max(ext_wqe_sge_cnt,
++				     get_sge_num_from_max_inl_data(is_ud_or_gsi,
++							 cap->max_inline_data));
++		hr_qp->sq.ext_sge_cnt = inline_ext_sge ?
++					roundup_pow_of_two(inline_ext_sge) : 0;
+ 
+-	wqe_sge_cnt = get_wqe_ext_sge_cnt(hr_qp);
++		hr_qp->sq.max_gs = max(1U, (hr_qp->sq.ext_sge_cnt + std_sge_num));
++		hr_qp->sq.max_gs = min(hr_qp->sq.max_gs, hr_dev->caps.max_sq_sg);
++
++		ext_wqe_sge_cnt = hr_qp->sq.ext_sge_cnt;
++	} else {
++		hr_qp->sq.max_gs = max(1U, cap->max_send_sge);
++		hr_qp->sq.max_gs = min(hr_qp->sq.max_gs, hr_dev->caps.max_sq_sg);
++		hr_qp->sq.ext_sge_cnt = hr_qp->sq.max_gs;
++	}
+ 
+ 	/* If the number of extended sge is not zero, they MUST use the
+ 	 * space of HNS_HW_PAGE_SIZE at least.
+ 	 */
+-	if (wqe_sge_cnt) {
+-		total_sge_cnt = roundup_pow_of_two(sq_wqe_cnt * wqe_sge_cnt);
++	if (ext_wqe_sge_cnt) {
++		total_sge_cnt = roundup_pow_of_two(sq_wqe_cnt * ext_wqe_sge_cnt);
+ 		hr_qp->sge.sge_cnt = max(total_sge_cnt,
+ 				(u32)HNS_HW_PAGE_SIZE / HNS_ROCE_SGE_SIZE);
+ 	}
++
++	update_inline_data(hr_qp, cap);
+ }
+ 
+ static int check_sq_size_with_integrity(struct hns_roce_dev *hr_dev,
+@@ -559,6 +630,7 @@ static int set_user_sq_size(struct hns_roce_dev *hr_dev,
+ 
+ 	hr_qp->sq.wqe_shift = ucmd->log_sq_stride;
+ 	hr_qp->sq.wqe_cnt = cnt;
++	cap->max_send_sge = hr_qp->sq.max_gs;
+ 
+ 	return 0;
+ }
+@@ -989,13 +1061,9 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
+ 			struct hns_roce_ib_create_qp *ucmd)
+ {
+ 	struct ib_device *ibdev = &hr_dev->ib_dev;
++	struct hns_roce_ucontext *uctx;
+ 	int ret;
+ 
+-	if (init_attr->cap.max_inline_data > hr_dev->caps.max_sq_inline)
+-		init_attr->cap.max_inline_data = hr_dev->caps.max_sq_inline;
+-
+-	hr_qp->max_inline_data = init_attr->cap.max_inline_data;
+-
+ 	if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
+ 		hr_qp->sq_signal_bits = IB_SIGNAL_ALL_WR;
+ 	else
+@@ -1018,12 +1086,17 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
+ 			return ret;
+ 		}
+ 
++		uctx = rdma_udata_to_drv_context(udata, struct hns_roce_ucontext,
++						 ibucontext);
++		hr_qp->config = uctx->config;
+ 		ret = set_user_sq_size(hr_dev, &init_attr->cap, hr_qp, ucmd);
+ 		if (ret)
+ 			ibdev_err(ibdev,
+ 				  "failed to set user SQ size, ret = %d.\n",
+ 				  ret);
+ 	} else {
++		if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP09)
++			hr_qp->config = HNS_ROCE_EXSGE_FLAGS;
+ 		ret = set_kernel_sq_size(hr_dev, &init_attr->cap, hr_qp);
+ 		if (ret)
+ 			ibdev_err(ibdev,
+diff --git a/drivers/infiniband/hw/hns/hns_roce_restrack.c b/drivers/infiniband/hw/hns/hns_roce_restrack.c
+index 24a154d646304..83417be15d3fa 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_restrack.c
++++ b/drivers/infiniband/hw/hns/hns_roce_restrack.c
+@@ -55,45 +55,34 @@ err:
+ 	return -EMSGSIZE;
+ }
+ 
+-int hns_roce_fill_res_cq_entry(struct sk_buff *msg,
+-			       struct ib_cq *ib_cq)
++int hns_roce_fill_res_cq_entry(struct sk_buff *msg, struct ib_cq *ib_cq)
+ {
+ 	struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
+ 	struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);
+-	struct hns_roce_v2_cq_context *context;
++	struct hns_roce_v2_cq_context context;
+ 	struct nlattr *table_attr;
+ 	int ret;
+ 
+-	if (!hr_dev->dfx->query_cqc_info)
++	if (!hr_dev->hw->query_cqc)
+ 		return -EINVAL;
+ 
+-	context = kzalloc(sizeof(struct hns_roce_v2_cq_context), GFP_KERNEL);
+-	if (!context)
+-		return -ENOMEM;
+-
+-	ret = hr_dev->dfx->query_cqc_info(hr_dev, hr_cq->cqn, (int *)context);
++	ret = hr_dev->hw->query_cqc(hr_dev, hr_cq->cqn, &context);
+ 	if (ret)
+-		goto err;
++		return -EINVAL;
+ 
+ 	table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_DRIVER);
+-	if (!table_attr) {
+-		ret = -EMSGSIZE;
+-		goto err;
+-	}
++	if (!table_attr)
++		return -EMSGSIZE;
+ 
+-	if (hns_roce_fill_cq(msg, context)) {
+-		ret = -EMSGSIZE;
+-		goto err_cancel_table;
+-	}
++	if (hns_roce_fill_cq(msg, &context))
++		goto err;
+ 
+ 	nla_nest_end(msg, table_attr);
+-	kfree(context);
+ 
+ 	return 0;
+ 
+-err_cancel_table:
+-	nla_nest_cancel(msg, table_attr);
+ err:
+-	kfree(context);
+-	return ret;
++	nla_nest_cancel(msg, table_attr);
++
++	return -EMSGSIZE;
+ }
+diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c
+index a6e5d350a94ce..16183e894da77 100644
+--- a/drivers/infiniband/hw/irdma/uk.c
++++ b/drivers/infiniband/hw/irdma/uk.c
+@@ -566,21 +566,37 @@ static void irdma_set_mw_bind_wqe_gen_1(__le64 *wqe,
+ 
+ /**
+  * irdma_copy_inline_data_gen_1 - Copy inline data to wqe
+- * @dest: pointer to wqe
+- * @src: pointer to inline data
+- * @len: length of inline data to copy
++ * @wqe: pointer to wqe
++ * @sge_list: table of pointers to inline data
++ * @num_sges: Total inline data length
+  * @polarity: compatibility parameter
+  */
+-static void irdma_copy_inline_data_gen_1(u8 *dest, u8 *src, u32 len,
+-					 u8 polarity)
++static void irdma_copy_inline_data_gen_1(u8 *wqe, struct ib_sge *sge_list,
++					 u32 num_sges, u8 polarity)
+ {
+-	if (len <= 16) {
+-		memcpy(dest, src, len);
+-	} else {
+-		memcpy(dest, src, 16);
+-		src += 16;
+-		dest = dest + 32;
+-		memcpy(dest, src, len - 16);
++	u32 quanta_bytes_remaining = 16;
++	int i;
++
++	for (i = 0; i < num_sges; i++) {
++		u8 *cur_sge = (u8 *)(uintptr_t)sge_list[i].addr;
++		u32 sge_len = sge_list[i].length;
++
++		while (sge_len) {
++			u32 bytes_copied;
++
++			bytes_copied = min(sge_len, quanta_bytes_remaining);
++			memcpy(wqe, cur_sge, bytes_copied);
++			wqe += bytes_copied;
++			cur_sge += bytes_copied;
++			quanta_bytes_remaining -= bytes_copied;
++			sge_len -= bytes_copied;
++
++			if (!quanta_bytes_remaining) {
++				/* Remaining inline bytes reside after hdr */
++				wqe += 16;
++				quanta_bytes_remaining = 32;
++			}
++		}
+ 	}
+ }
+ 
+@@ -612,35 +628,51 @@ static void irdma_set_mw_bind_wqe(__le64 *wqe,
+ 
+ /**
+  * irdma_copy_inline_data - Copy inline data to wqe
+- * @dest: pointer to wqe
+- * @src: pointer to inline data
+- * @len: length of inline data to copy
++ * @wqe: pointer to wqe
++ * @sge_list: table of pointers to inline data
++ * @num_sges: number of SGE's
+  * @polarity: polarity of wqe valid bit
+  */
+-static void irdma_copy_inline_data(u8 *dest, u8 *src, u32 len, u8 polarity)
++static void irdma_copy_inline_data(u8 *wqe, struct ib_sge *sge_list,
++				   u32 num_sges, u8 polarity)
+ {
+ 	u8 inline_valid = polarity << IRDMA_INLINE_VALID_S;
+-	u32 copy_size;
+-
+-	dest += 8;
+-	if (len <= 8) {
+-		memcpy(dest, src, len);
+-		return;
+-	}
+-
+-	*((u64 *)dest) = *((u64 *)src);
+-	len -= 8;
+-	src += 8;
+-	dest += 24; /* point to additional 32 byte quanta */
+-
+-	while (len) {
+-		copy_size = len < 31 ? len : 31;
+-		memcpy(dest, src, copy_size);
+-		*(dest + 31) = inline_valid;
+-		len -= copy_size;
+-		dest += 32;
+-		src += copy_size;
++	u32 quanta_bytes_remaining = 8;
++	bool first_quanta = true;
++	int i;
++
++	wqe += 8;
++
++	for (i = 0; i < num_sges; i++) {
++		u8 *cur_sge = (u8 *)(uintptr_t)sge_list[i].addr;
++		u32 sge_len = sge_list[i].length;
++
++		while (sge_len) {
++			u32 bytes_copied;
++
++			bytes_copied = min(sge_len, quanta_bytes_remaining);
++			memcpy(wqe, cur_sge, bytes_copied);
++			wqe += bytes_copied;
++			cur_sge += bytes_copied;
++			quanta_bytes_remaining -= bytes_copied;
++			sge_len -= bytes_copied;
++
++			if (!quanta_bytes_remaining) {
++				quanta_bytes_remaining = 31;
++
++				/* Remaining inline bytes reside after hdr */
++				if (first_quanta) {
++					first_quanta = false;
++					wqe += 16;
++				} else {
++					*wqe = inline_valid;
++					wqe++;
++				}
++			}
++		}
+ 	}
++	if (!first_quanta && quanta_bytes_remaining < 31)
++		*(wqe + quanta_bytes_remaining) = inline_valid;
+ }
+ 
+ /**
+@@ -679,20 +711,27 @@ int irdma_uk_inline_rdma_write(struct irdma_qp_uk *qp,
+ 			       struct irdma_post_sq_info *info, bool post_sq)
+ {
+ 	__le64 *wqe;
+-	struct irdma_inline_rdma_write *op_info;
++	struct irdma_rdma_write *op_info;
+ 	u64 hdr = 0;
+ 	u32 wqe_idx;
+ 	bool read_fence = false;
++	u32 i, total_size = 0;
+ 	u16 quanta;
+ 
+ 	info->push_wqe = qp->push_db ? true : false;
+-	op_info = &info->op.inline_rdma_write;
++	op_info = &info->op.rdma_write;
++
++	if (unlikely(qp->max_sq_frag_cnt < op_info->num_lo_sges))
++		return -EINVAL;
++
++	for (i = 0; i < op_info->num_lo_sges; i++)
++		total_size += op_info->lo_sg_list[i].length;
+ 
+-	if (op_info->len > qp->max_inline_data)
++	if (unlikely(total_size > qp->max_inline_data))
+ 		return -EINVAL;
+ 
+-	quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(op_info->len);
+-	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, op_info->len,
++	quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(total_size);
++	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size,
+ 					 info);
+ 	if (!wqe)
+ 		return -ENOMEM;
+@@ -705,7 +744,7 @@ int irdma_uk_inline_rdma_write(struct irdma_qp_uk *qp,
+ 
+ 	hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, op_info->rem_addr.lkey) |
+ 	      FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) |
+-	      FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, op_info->len) |
++	      FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, total_size) |
+ 	      FIELD_PREP(IRDMAQPSQ_REPORTRTT, info->report_rtt ? 1 : 0) |
+ 	      FIELD_PREP(IRDMAQPSQ_INLINEDATAFLAG, 1) |
+ 	      FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG, info->imm_data_valid ? 1 : 0) |
+@@ -719,7 +758,8 @@ int irdma_uk_inline_rdma_write(struct irdma_qp_uk *qp,
+ 		set_64bit_val(wqe, 0,
+ 			      FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data));
+ 
+-	qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->data, op_info->len,
++	qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->lo_sg_list,
++					op_info->num_lo_sges,
+ 					qp->swqe_polarity);
+ 	dma_wmb(); /* make sure WQE is populated before valid bit is set */
+ 
+@@ -745,20 +785,27 @@ int irdma_uk_inline_send(struct irdma_qp_uk *qp,
+ 			 struct irdma_post_sq_info *info, bool post_sq)
+ {
+ 	__le64 *wqe;
+-	struct irdma_post_inline_send *op_info;
++	struct irdma_post_send *op_info;
+ 	u64 hdr;
+ 	u32 wqe_idx;
+ 	bool read_fence = false;
++	u32 i, total_size = 0;
+ 	u16 quanta;
+ 
+ 	info->push_wqe = qp->push_db ? true : false;
+-	op_info = &info->op.inline_send;
++	op_info = &info->op.send;
++
++	if (unlikely(qp->max_sq_frag_cnt < op_info->num_sges))
++		return -EINVAL;
+ 
+-	if (op_info->len > qp->max_inline_data)
++	for (i = 0; i < op_info->num_sges; i++)
++		total_size += op_info->sg_list[i].length;
++
++	if (unlikely(total_size > qp->max_inline_data))
+ 		return -EINVAL;
+ 
+-	quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(op_info->len);
+-	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, op_info->len,
++	quanta = qp->wqe_ops.iw_inline_data_size_to_quanta(total_size);
++	wqe = irdma_qp_get_next_send_wqe(qp, &wqe_idx, quanta, total_size,
+ 					 info);
+ 	if (!wqe)
+ 		return -ENOMEM;
+@@ -773,7 +820,7 @@ int irdma_uk_inline_send(struct irdma_qp_uk *qp,
+ 	hdr = FIELD_PREP(IRDMAQPSQ_REMSTAG, info->stag_to_inv) |
+ 	      FIELD_PREP(IRDMAQPSQ_AHID, op_info->ah_id) |
+ 	      FIELD_PREP(IRDMAQPSQ_OPCODE, info->op_type) |
+-	      FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, op_info->len) |
++	      FIELD_PREP(IRDMAQPSQ_INLINEDATALEN, total_size) |
+ 	      FIELD_PREP(IRDMAQPSQ_IMMDATAFLAG,
+ 			 (info->imm_data_valid ? 1 : 0)) |
+ 	      FIELD_PREP(IRDMAQPSQ_REPORTRTT, (info->report_rtt ? 1 : 0)) |
+@@ -789,8 +836,8 @@ int irdma_uk_inline_send(struct irdma_qp_uk *qp,
+ 	if (info->imm_data_valid)
+ 		set_64bit_val(wqe, 0,
+ 			      FIELD_PREP(IRDMAQPSQ_IMMDATA, info->imm_data));
+-	qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->data, op_info->len,
+-					qp->swqe_polarity);
++	qp->wqe_ops.iw_copy_inline_data((u8 *)wqe, op_info->sg_list,
++					op_info->num_sges, qp->swqe_polarity);
+ 
+ 	dma_wmb(); /* make sure WQE is populated before valid bit is set */
+ 
+@@ -1002,11 +1049,10 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
+ 	__le64 *cqe;
+ 	struct irdma_qp_uk *qp;
+ 	struct irdma_ring *pring = NULL;
+-	u32 wqe_idx, q_type;
++	u32 wqe_idx;
+ 	int ret_code;
+ 	bool move_cq_head = true;
+ 	u8 polarity;
+-	u8 op_type;
+ 	bool ext_valid;
+ 	__le64 *ext_cqe;
+ 
+@@ -1074,7 +1120,7 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
+ 		info->ud_vlan_valid = false;
+ 	}
+ 
+-	q_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3);
++	info->q_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3);
+ 	info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, qword3);
+ 	info->push_dropped = (bool)FIELD_GET(IRDMACQ_PSHDROP, qword3);
+ 	info->ipv4 = (bool)FIELD_GET(IRDMACQ_IPV4, qword3);
+@@ -1113,8 +1159,9 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
+ 	}
+ 	wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, qword3);
+ 	info->qp_handle = (irdma_qp_handle)(unsigned long)qp;
++	info->op_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3);
+ 
+-	if (q_type == IRDMA_CQE_QTYPE_RQ) {
++	if (info->q_type == IRDMA_CQE_QTYPE_RQ) {
+ 		u32 array_idx;
+ 
+ 		array_idx = wqe_idx / qp->rq_wqe_size_multiplier;
+@@ -1134,10 +1181,6 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
+ 
+ 		info->bytes_xfered = (u32)FIELD_GET(IRDMACQ_PAYLDLEN, qword0);
+ 
+-		if (info->imm_valid)
+-			info->op_type = IRDMA_OP_TYPE_REC_IMM;
+-		else
+-			info->op_type = IRDMA_OP_TYPE_REC;
+ 		if (qword3 & IRDMACQ_STAG) {
+ 			info->stag_invalid_set = true;
+ 			info->inv_stag = (u32)FIELD_GET(IRDMACQ_INVSTAG, qword2);
+@@ -1195,17 +1238,18 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq,
+ 				sw_wqe = qp->sq_base[tail].elem;
+ 				get_64bit_val(sw_wqe, 24,
+ 					      &wqe_qword);
+-				op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE, wqe_qword);
+-				info->op_type = op_type;
++				info->op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE,
++							      wqe_qword);
+ 				IRDMA_RING_SET_TAIL(qp->sq_ring,
+ 						    tail + qp->sq_wrtrk_array[tail].quanta);
+-				if (op_type != IRDMAQP_OP_NOP) {
++				if (info->op_type != IRDMAQP_OP_NOP) {
+ 					info->wr_id = qp->sq_wrtrk_array[tail].wrid;
+ 					info->bytes_xfered = qp->sq_wrtrk_array[tail].wr_len;
+ 					break;
+ 				}
+ 			} while (1);
+-			if (op_type == IRDMA_OP_TYPE_BIND_MW && info->minor_err == FLUSH_PROT_ERR)
++			if (info->op_type == IRDMA_OP_TYPE_BIND_MW &&
++			    info->minor_err == FLUSH_PROT_ERR)
+ 				info->minor_err = FLUSH_MW_BIND_ERR;
+ 			qp->sq_flush_seen = true;
+ 			if (!IRDMA_RING_MORE_WORK(qp->sq_ring))
+diff --git a/drivers/infiniband/hw/irdma/user.h b/drivers/infiniband/hw/irdma/user.h
+index 2ef61923c9268..d0cdf609f5e06 100644
+--- a/drivers/infiniband/hw/irdma/user.h
++++ b/drivers/infiniband/hw/irdma/user.h
+@@ -173,14 +173,6 @@ struct irdma_post_send {
+ 	u32 ah_id;
+ };
+ 
+-struct irdma_post_inline_send {
+-	void *data;
+-	u32 len;
+-	u32 qkey;
+-	u32 dest_qp;
+-	u32 ah_id;
+-};
+-
+ struct irdma_post_rq_info {
+ 	u64 wr_id;
+ 	struct ib_sge *sg_list;
+@@ -193,12 +185,6 @@ struct irdma_rdma_write {
+ 	struct ib_sge rem_addr;
+ };
+ 
+-struct irdma_inline_rdma_write {
+-	void *data;
+-	u32 len;
+-	struct ib_sge rem_addr;
+-};
+-
+ struct irdma_rdma_read {
+ 	struct ib_sge *lo_sg_list;
+ 	u32 num_lo_sges;
+@@ -241,8 +227,6 @@ struct irdma_post_sq_info {
+ 		struct irdma_rdma_read rdma_read;
+ 		struct irdma_bind_window bind_window;
+ 		struct irdma_inv_local_stag inv_local_stag;
+-		struct irdma_inline_rdma_write inline_rdma_write;
+-		struct irdma_post_inline_send inline_send;
+ 	} op;
+ };
+ 
+@@ -261,6 +245,7 @@ struct irdma_cq_poll_info {
+ 	u16 ud_vlan;
+ 	u8 ud_smac[6];
+ 	u8 op_type;
++	u8 q_type;
+ 	bool stag_invalid_set:1; /* or L_R_Key set */
+ 	bool push_dropped:1;
+ 	bool error:1;
+@@ -291,7 +276,8 @@ int irdma_uk_stag_local_invalidate(struct irdma_qp_uk *qp,
+ 				   bool post_sq);
+ 
+ struct irdma_wqe_uk_ops {
+-	void (*iw_copy_inline_data)(u8 *dest, u8 *src, u32 len, u8 polarity);
++	void (*iw_copy_inline_data)(u8 *dest, struct ib_sge *sge_list,
++				    u32 num_sges, u8 polarity);
+ 	u16 (*iw_inline_data_size_to_quanta)(u32 data_size);
+ 	void (*iw_set_fragment)(__le64 *wqe, u32 offset, struct ib_sge *sge,
+ 				u8 valid);
+diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c
+index 8dfc9e154d733..445e69e864097 100644
+--- a/drivers/infiniband/hw/irdma/utils.c
++++ b/drivers/infiniband/hw/irdma/utils.c
+@@ -2591,6 +2591,7 @@ void irdma_generate_flush_completions(struct irdma_qp *iwqp)
+ 			sw_wqe = qp->sq_base[wqe_idx].elem;
+ 			get_64bit_val(sw_wqe, 24, &wqe_qword);
+ 			cmpl->cpi.op_type = (u8)FIELD_GET(IRDMAQPSQ_OPCODE, IRDMAQPSQ_OPCODE);
++			cmpl->cpi.q_type = IRDMA_CQE_QTYPE_SQ;
+ 			/* remove the SQ WR by moving SQ tail*/
+ 			IRDMA_RING_SET_TAIL(*sq_ring,
+ 				sq_ring->tail + qp->sq_wrtrk_array[sq_ring->tail].quanta);
+@@ -2629,6 +2630,7 @@ void irdma_generate_flush_completions(struct irdma_qp *iwqp)
+ 
+ 			cmpl->cpi.wr_id = qp->rq_wrid_array[wqe_idx];
+ 			cmpl->cpi.op_type = IRDMA_OP_TYPE_REC;
++			cmpl->cpi.q_type = IRDMA_CQE_QTYPE_RQ;
+ 			/* remove the RQ WR by moving RQ tail */
+ 			IRDMA_RING_SET_TAIL(*rq_ring, rq_ring->tail + 1);
+ 			ibdev_dbg(iwqp->iwrcq->ibcq.device,
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index a22afbb25bc58..f6973ea55eda7 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -63,36 +63,6 @@ static int irdma_query_device(struct ib_device *ibdev,
+ 	return 0;
+ }
+ 
+-/**
+- * irdma_get_eth_speed_and_width - Get IB port speed and width from netdev speed
+- * @link_speed: netdev phy link speed
+- * @active_speed: IB port speed
+- * @active_width: IB port width
+- */
+-static void irdma_get_eth_speed_and_width(u32 link_speed, u16 *active_speed,
+-					  u8 *active_width)
+-{
+-	if (link_speed <= SPEED_1000) {
+-		*active_width = IB_WIDTH_1X;
+-		*active_speed = IB_SPEED_SDR;
+-	} else if (link_speed <= SPEED_10000) {
+-		*active_width = IB_WIDTH_1X;
+-		*active_speed = IB_SPEED_FDR10;
+-	} else if (link_speed <= SPEED_20000) {
+-		*active_width = IB_WIDTH_4X;
+-		*active_speed = IB_SPEED_DDR;
+-	} else if (link_speed <= SPEED_25000) {
+-		*active_width = IB_WIDTH_1X;
+-		*active_speed = IB_SPEED_EDR;
+-	} else if (link_speed <= SPEED_40000) {
+-		*active_width = IB_WIDTH_4X;
+-		*active_speed = IB_SPEED_FDR10;
+-	} else {
+-		*active_width = IB_WIDTH_4X;
+-		*active_speed = IB_SPEED_EDR;
+-	}
+-}
+-
+ /**
+  * irdma_query_port - get port attributes
+  * @ibdev: device pointer from stack
+@@ -120,8 +90,9 @@ static int irdma_query_port(struct ib_device *ibdev, u32 port,
+ 		props->state = IB_PORT_DOWN;
+ 		props->phys_state = IB_PORT_PHYS_STATE_DISABLED;
+ 	}
+-	irdma_get_eth_speed_and_width(SPEED_100000, &props->active_speed,
+-				      &props->active_width);
++
++	ib_get_eth_speed(ibdev, port, &props->active_speed,
++			 &props->active_width);
+ 
+ 	if (rdma_protocol_roce(ibdev, 1)) {
+ 		props->gid_tbl_len = 32;
+@@ -1242,6 +1213,7 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 		av->attrs = attr->ah_attr;
+ 		rdma_gid2ip((struct sockaddr *)&av->sgid_addr, &sgid_attr->gid);
+ 		rdma_gid2ip((struct sockaddr *)&av->dgid_addr, &attr->ah_attr.grh.dgid);
++		av->net_type = rdma_gid_attr_network_type(sgid_attr);
+ 		if (av->net_type == RDMA_NETWORK_IPV6) {
+ 			__be32 *daddr =
+ 				av->dgid_addr.saddr_in6.sin6_addr.in6_u.u6_addr32;
+@@ -2358,9 +2330,10 @@ static bool irdma_check_mr_contiguous(struct irdma_pble_alloc *palloc,
+  * @rf: RDMA PCI function
+  * @iwmr: mr pointer for this memory registration
+  * @use_pbles: flag if to use pble's
++ * @lvl_1_only: request only level 1 pble if true
+  */
+ static int irdma_setup_pbles(struct irdma_pci_f *rf, struct irdma_mr *iwmr,
+-			     bool use_pbles)
++			     bool use_pbles, bool lvl_1_only)
+ {
+ 	struct irdma_pbl *iwpbl = &iwmr->iwpbl;
+ 	struct irdma_pble_alloc *palloc = &iwpbl->pble_alloc;
+@@ -2371,7 +2344,7 @@ static int irdma_setup_pbles(struct irdma_pci_f *rf, struct irdma_mr *iwmr,
+ 
+ 	if (use_pbles) {
+ 		status = irdma_get_pble(rf->pble_rsrc, palloc, iwmr->page_cnt,
+-					false);
++					lvl_1_only);
+ 		if (status)
+ 			return status;
+ 
+@@ -2414,16 +2387,10 @@ static int irdma_handle_q_mem(struct irdma_device *iwdev,
+ 	bool ret = true;
+ 
+ 	pg_size = iwmr->page_size;
+-	err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles);
++	err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles, true);
+ 	if (err)
+ 		return err;
+ 
+-	if (use_pbles && palloc->level != PBLE_LEVEL_1) {
+-		irdma_free_pble(iwdev->rf->pble_rsrc, palloc);
+-		iwpbl->pbl_allocated = false;
+-		return -ENOMEM;
+-	}
+-
+ 	if (use_pbles)
+ 		arr = palloc->level1.addr;
+ 
+@@ -2899,7 +2866,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
+ 	case IRDMA_MEMREG_TYPE_MEM:
+ 		use_pbles = (iwmr->page_cnt != 1);
+ 
+-		err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles);
++		err = irdma_setup_pbles(iwdev->rf, iwmr, use_pbles, false);
+ 		if (err)
+ 			goto error;
+ 
+@@ -3165,30 +3132,20 @@ static int irdma_post_send(struct ib_qp *ibqp,
+ 				info.stag_to_inv = ib_wr->ex.invalidate_rkey;
+ 			}
+ 
+-			if (ib_wr->send_flags & IB_SEND_INLINE) {
+-				info.op.inline_send.data = (void *)(unsigned long)
+-							   ib_wr->sg_list[0].addr;
+-				info.op.inline_send.len = ib_wr->sg_list[0].length;
+-				if (iwqp->ibqp.qp_type == IB_QPT_UD ||
+-				    iwqp->ibqp.qp_type == IB_QPT_GSI) {
+-					ah = to_iwah(ud_wr(ib_wr)->ah);
+-					info.op.inline_send.ah_id = ah->sc_ah.ah_info.ah_idx;
+-					info.op.inline_send.qkey = ud_wr(ib_wr)->remote_qkey;
+-					info.op.inline_send.dest_qp = ud_wr(ib_wr)->remote_qpn;
+-				}
++			info.op.send.num_sges = ib_wr->num_sge;
++			info.op.send.sg_list = ib_wr->sg_list;
++			if (iwqp->ibqp.qp_type == IB_QPT_UD ||
++			    iwqp->ibqp.qp_type == IB_QPT_GSI) {
++				ah = to_iwah(ud_wr(ib_wr)->ah);
++				info.op.send.ah_id = ah->sc_ah.ah_info.ah_idx;
++				info.op.send.qkey = ud_wr(ib_wr)->remote_qkey;
++				info.op.send.dest_qp = ud_wr(ib_wr)->remote_qpn;
++			}
++
++			if (ib_wr->send_flags & IB_SEND_INLINE)
+ 				err = irdma_uk_inline_send(ukqp, &info, false);
+-			} else {
+-				info.op.send.num_sges = ib_wr->num_sge;
+-				info.op.send.sg_list = ib_wr->sg_list;
+-				if (iwqp->ibqp.qp_type == IB_QPT_UD ||
+-				    iwqp->ibqp.qp_type == IB_QPT_GSI) {
+-					ah = to_iwah(ud_wr(ib_wr)->ah);
+-					info.op.send.ah_id = ah->sc_ah.ah_info.ah_idx;
+-					info.op.send.qkey = ud_wr(ib_wr)->remote_qkey;
+-					info.op.send.dest_qp = ud_wr(ib_wr)->remote_qpn;
+-				}
++			else
+ 				err = irdma_uk_send(ukqp, &info, false);
+-			}
+ 			break;
+ 		case IB_WR_RDMA_WRITE_WITH_IMM:
+ 			if (ukqp->qp_caps & IRDMA_WRITE_WITH_IMM) {
+@@ -3205,22 +3162,15 @@ static int irdma_post_send(struct ib_qp *ibqp,
+ 			else
+ 				info.op_type = IRDMA_OP_TYPE_RDMA_WRITE;
+ 
+-			if (ib_wr->send_flags & IB_SEND_INLINE) {
+-				info.op.inline_rdma_write.data = (void *)(uintptr_t)ib_wr->sg_list[0].addr;
+-				info.op.inline_rdma_write.len =
+-						ib_wr->sg_list[0].length;
+-				info.op.inline_rdma_write.rem_addr.addr =
+-						rdma_wr(ib_wr)->remote_addr;
+-				info.op.inline_rdma_write.rem_addr.lkey =
+-						rdma_wr(ib_wr)->rkey;
++			info.op.rdma_write.num_lo_sges = ib_wr->num_sge;
++			info.op.rdma_write.lo_sg_list = ib_wr->sg_list;
++			info.op.rdma_write.rem_addr.addr =
++				rdma_wr(ib_wr)->remote_addr;
++			info.op.rdma_write.rem_addr.lkey = rdma_wr(ib_wr)->rkey;
++			if (ib_wr->send_flags & IB_SEND_INLINE)
+ 				err = irdma_uk_inline_rdma_write(ukqp, &info, false);
+-			} else {
+-				info.op.rdma_write.lo_sg_list = (void *)ib_wr->sg_list;
+-				info.op.rdma_write.num_lo_sges = ib_wr->num_sge;
+-				info.op.rdma_write.rem_addr.addr = rdma_wr(ib_wr)->remote_addr;
+-				info.op.rdma_write.rem_addr.lkey = rdma_wr(ib_wr)->rkey;
++			else
+ 				err = irdma_uk_rdma_write(ukqp, &info, false);
+-			}
+ 			break;
+ 		case IB_WR_RDMA_READ_WITH_INV:
+ 			inv_stag = true;
+@@ -3380,7 +3330,6 @@ static enum ib_wc_status irdma_flush_err_to_ib_wc_status(enum irdma_flush_opcode
+ static void irdma_process_cqe(struct ib_wc *entry,
+ 			      struct irdma_cq_poll_info *cq_poll_info)
+ {
+-	struct irdma_qp *iwqp;
+ 	struct irdma_sc_qp *qp;
+ 
+ 	entry->wc_flags = 0;
+@@ -3388,7 +3337,6 @@ static void irdma_process_cqe(struct ib_wc *entry,
+ 	entry->wr_id = cq_poll_info->wr_id;
+ 
+ 	qp = cq_poll_info->qp_handle;
+-	iwqp = qp->qp_uk.back_qp;
+ 	entry->qp = qp->qp_uk.back_qp;
+ 
+ 	if (cq_poll_info->error) {
+@@ -3421,42 +3369,17 @@ static void irdma_process_cqe(struct ib_wc *entry,
+ 		}
+ 	}
+ 
+-	switch (cq_poll_info->op_type) {
+-	case IRDMA_OP_TYPE_RDMA_WRITE:
+-	case IRDMA_OP_TYPE_RDMA_WRITE_SOL:
+-		entry->opcode = IB_WC_RDMA_WRITE;
+-		break;
+-	case IRDMA_OP_TYPE_RDMA_READ_INV_STAG:
+-	case IRDMA_OP_TYPE_RDMA_READ:
+-		entry->opcode = IB_WC_RDMA_READ;
+-		break;
+-	case IRDMA_OP_TYPE_SEND_INV:
+-	case IRDMA_OP_TYPE_SEND_SOL:
+-	case IRDMA_OP_TYPE_SEND_SOL_INV:
+-	case IRDMA_OP_TYPE_SEND:
+-		entry->opcode = IB_WC_SEND;
+-		break;
+-	case IRDMA_OP_TYPE_FAST_REG_NSMR:
+-		entry->opcode = IB_WC_REG_MR;
+-		break;
+-	case IRDMA_OP_TYPE_INV_STAG:
+-		entry->opcode = IB_WC_LOCAL_INV;
+-		break;
+-	case IRDMA_OP_TYPE_REC_IMM:
+-	case IRDMA_OP_TYPE_REC:
+-		entry->opcode = cq_poll_info->op_type == IRDMA_OP_TYPE_REC_IMM ?
+-			IB_WC_RECV_RDMA_WITH_IMM : IB_WC_RECV;
++	if (cq_poll_info->q_type == IRDMA_CQE_QTYPE_SQ) {
++		set_ib_wc_op_sq(cq_poll_info, entry);
++	} else {
++		set_ib_wc_op_rq(cq_poll_info, entry,
++				qp->qp_uk.qp_caps & IRDMA_SEND_WITH_IMM ?
++				true : false);
+ 		if (qp->qp_uk.qp_type != IRDMA_QP_TYPE_ROCE_UD &&
+ 		    cq_poll_info->stag_invalid_set) {
+ 			entry->ex.invalidate_rkey = cq_poll_info->inv_stag;
+ 			entry->wc_flags |= IB_WC_WITH_INVALIDATE;
+ 		}
+-		break;
+-	default:
+-		ibdev_err(&iwqp->iwdev->ibdev,
+-			  "Invalid opcode = %d in CQE\n", cq_poll_info->op_type);
+-		entry->status = IB_WC_GENERAL_ERR;
+-		return;
+ 	}
+ 
+ 	if (qp->qp_uk.qp_type == IRDMA_QP_TYPE_ROCE_UD) {
+diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h
+index 4309b7159f42c..a536e9fa85ebf 100644
+--- a/drivers/infiniband/hw/irdma/verbs.h
++++ b/drivers/infiniband/hw/irdma/verbs.h
+@@ -232,6 +232,59 @@ static inline u16 irdma_fw_minor_ver(struct irdma_sc_dev *dev)
+ 	return (u16)FIELD_GET(IRDMA_FW_VER_MINOR, dev->feature_info[IRDMA_FEATURE_FW_INFO]);
+ }
+ 
++static inline void set_ib_wc_op_sq(struct irdma_cq_poll_info *cq_poll_info,
++				   struct ib_wc *entry)
++{
++	switch (cq_poll_info->op_type) {
++	case IRDMA_OP_TYPE_RDMA_WRITE:
++	case IRDMA_OP_TYPE_RDMA_WRITE_SOL:
++		entry->opcode = IB_WC_RDMA_WRITE;
++		break;
++	case IRDMA_OP_TYPE_RDMA_READ_INV_STAG:
++	case IRDMA_OP_TYPE_RDMA_READ:
++		entry->opcode = IB_WC_RDMA_READ;
++		break;
++	case IRDMA_OP_TYPE_SEND_SOL:
++	case IRDMA_OP_TYPE_SEND_SOL_INV:
++	case IRDMA_OP_TYPE_SEND_INV:
++	case IRDMA_OP_TYPE_SEND:
++		entry->opcode = IB_WC_SEND;
++		break;
++	case IRDMA_OP_TYPE_FAST_REG_NSMR:
++		entry->opcode = IB_WC_REG_MR;
++		break;
++	case IRDMA_OP_TYPE_INV_STAG:
++		entry->opcode = IB_WC_LOCAL_INV;
++		break;
++	default:
++		entry->status = IB_WC_GENERAL_ERR;
++	}
++}
++
++static inline void set_ib_wc_op_rq(struct irdma_cq_poll_info *cq_poll_info,
++				   struct ib_wc *entry, bool send_imm_support)
++{
++	/**
++	 * iWARP does not support sendImm, so the presence of Imm data
++	 * must be WriteImm.
++	 */
++	if (!send_imm_support) {
++		entry->opcode = cq_poll_info->imm_valid ?
++					IB_WC_RECV_RDMA_WITH_IMM :
++					IB_WC_RECV;
++		return;
++	}
++
++	switch (cq_poll_info->op_type) {
++	case IB_OPCODE_RDMA_WRITE_ONLY_WITH_IMMEDIATE:
++	case IB_OPCODE_RDMA_WRITE_LAST_WITH_IMMEDIATE:
++		entry->opcode = IB_WC_RECV_RDMA_WITH_IMM;
++		break;
++	default:
++		entry->opcode = IB_WC_RECV;
++	}
++}
++
+ void irdma_mcast_mac(u32 *ip_addr, u8 *mac, bool ipv4);
+ int irdma_ib_register_device(struct irdma_device *iwdev);
+ void irdma_ib_unregister_device(struct irdma_device *iwdev);
+diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
+index af34f198e6456..8cd6f1b165d55 100644
+--- a/drivers/infiniband/sw/rxe/rxe_mr.c
++++ b/drivers/infiniband/sw/rxe/rxe_mr.c
+@@ -99,6 +99,7 @@ err2:
+ 		kfree(mr->map[i]);
+ 
+ 	kfree(mr->map);
++	mr->map = NULL;
+ err1:
+ 	return -ENOMEM;
+ }
+@@ -122,7 +123,6 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
+ 	int			num_buf;
+ 	void			*vaddr;
+ 	int err;
+-	int i;
+ 
+ 	umem = ib_umem_get(&rxe->ib_dev, start, length, access);
+ 	if (IS_ERR(umem)) {
+@@ -163,9 +163,8 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
+ 				pr_warn("%s: Unable to get virtual address\n",
+ 						__func__);
+ 				err = -ENOMEM;
+-				goto err_cleanup_map;
++				goto err_release_umem;
+ 			}
+-
+ 			buf->addr = (uintptr_t)vaddr;
+ 			buf->size = PAGE_SIZE;
+ 			num_buf++;
+@@ -185,10 +184,6 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
+ 
+ 	return 0;
+ 
+-err_cleanup_map:
+-	for (i = 0; i < mr->num_map; i++)
+-		kfree(mr->map[i]);
+-	kfree(mr->map);
+ err_release_umem:
+ 	ib_umem_release(umem);
+ err_out:
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index d776dfda43b16..e9c573fe71553 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -830,12 +830,12 @@ static void rxe_qp_do_cleanup(struct work_struct *work)
+ 	if (qp->resp.mr)
+ 		rxe_put(qp->resp.mr);
+ 
+-	if (qp_type(qp) == IB_QPT_RC)
+-		sk_dst_reset(qp->sk->sk);
+-
+ 	free_rd_atomic_resources(qp);
+ 
+ 	if (qp->sk) {
++		if (qp_type(qp) == IB_QPT_RC)
++			sk_dst_reset(qp->sk->sk);
++
+ 		kernel_sock_shutdown(qp->sk, SHUT_RDWR);
+ 		sock_release(qp->sk);
+ 	}
+diff --git a/drivers/infiniband/sw/siw/siw_cq.c b/drivers/infiniband/sw/siw/siw_cq.c
+index d68e37859e73b..403029de6b92d 100644
+--- a/drivers/infiniband/sw/siw/siw_cq.c
++++ b/drivers/infiniband/sw/siw/siw_cq.c
+@@ -56,8 +56,6 @@ int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *wc)
+ 	if (READ_ONCE(cqe->flags) & SIW_WQE_VALID) {
+ 		memset(wc, 0, sizeof(*wc));
+ 		wc->wr_id = cqe->id;
+-		wc->status = map_cqe_status[cqe->status].ib;
+-		wc->opcode = map_wc_opcode[cqe->opcode];
+ 		wc->byte_len = cqe->bytes;
+ 
+ 		/*
+@@ -71,10 +69,32 @@ int siw_reap_cqe(struct siw_cq *cq, struct ib_wc *wc)
+ 				wc->wc_flags = IB_WC_WITH_INVALIDATE;
+ 			}
+ 			wc->qp = cqe->base_qp;
++			wc->opcode = map_wc_opcode[cqe->opcode];
++			wc->status = map_cqe_status[cqe->status].ib;
+ 			siw_dbg_cq(cq,
+ 				   "idx %u, type %d, flags %2x, id 0x%pK\n",
+ 				   cq->cq_get % cq->num_cqe, cqe->opcode,
+ 				   cqe->flags, (void *)(uintptr_t)cqe->id);
++		} else {
++			/*
++			 * A malicious user may set invalid opcode or
++			 * status in the user mmapped CQE array.
++			 * Sanity check and correct values in that case
++			 * to avoid out-of-bounds access to global arrays
++			 * for opcode and status mapping.
++			 */
++			u8 opcode = cqe->opcode;
++			u16 status = cqe->status;
++
++			if (opcode >= SIW_NUM_OPCODES) {
++				opcode = 0;
++				status = SIW_WC_GENERAL_ERR;
++			} else if (status >= SIW_NUM_WC_STATUS) {
++				status = SIW_WC_GENERAL_ERR;
++			}
++			wc->opcode = map_wc_opcode[opcode];
++			wc->status = map_cqe_status[status].ib;
++
+ 		}
+ 		WRITE_ONCE(cqe->flags, 0);
+ 		cq->cq_get++;
+diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c
+index 7d47b521070b1..05052b49107f2 100644
+--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
++++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
+@@ -29,7 +29,7 @@ static struct page *siw_get_pblpage(struct siw_mem *mem, u64 addr, int *idx)
+ 	dma_addr_t paddr = siw_pbl_get_buffer(pbl, offset, NULL, idx);
+ 
+ 	if (paddr)
+-		return virt_to_page((void *)paddr);
++		return virt_to_page((void *)(uintptr_t)paddr);
+ 
+ 	return NULL;
+ }
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index 3e814cfb298cf..906fde1a2a0de 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -676,13 +676,45 @@ static int siw_copy_inline_sgl(const struct ib_send_wr *core_wr,
+ static int siw_sq_flush_wr(struct siw_qp *qp, const struct ib_send_wr *wr,
+ 			   const struct ib_send_wr **bad_wr)
+ {
+-	struct siw_sqe sqe = {};
+ 	int rv = 0;
+ 
+ 	while (wr) {
+-		sqe.id = wr->wr_id;
+-		sqe.opcode = wr->opcode;
+-		rv = siw_sqe_complete(qp, &sqe, 0, SIW_WC_WR_FLUSH_ERR);
++		struct siw_sqe sqe = {};
++
++		switch (wr->opcode) {
++		case IB_WR_RDMA_WRITE:
++			sqe.opcode = SIW_OP_WRITE;
++			break;
++		case IB_WR_RDMA_READ:
++			sqe.opcode = SIW_OP_READ;
++			break;
++		case IB_WR_RDMA_READ_WITH_INV:
++			sqe.opcode = SIW_OP_READ_LOCAL_INV;
++			break;
++		case IB_WR_SEND:
++			sqe.opcode = SIW_OP_SEND;
++			break;
++		case IB_WR_SEND_WITH_IMM:
++			sqe.opcode = SIW_OP_SEND_WITH_IMM;
++			break;
++		case IB_WR_SEND_WITH_INV:
++			sqe.opcode = SIW_OP_SEND_REMOTE_INV;
++			break;
++		case IB_WR_LOCAL_INV:
++			sqe.opcode = SIW_OP_INVAL_STAG;
++			break;
++		case IB_WR_REG_MR:
++			sqe.opcode = SIW_OP_REG_MR;
++			break;
++		default:
++			rv = -EINVAL;
++			break;
++		}
++		if (!rv) {
++			sqe.id = wr->wr_id;
++			rv = siw_sqe_complete(qp, &sqe, 0,
++					      SIW_WC_WR_FLUSH_ERR);
++		}
+ 		if (rv) {
+ 			if (bad_wr)
+ 				*bad_wr = wr;
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+index ea16ba5d8da6c..9ad8d98562752 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+@@ -41,6 +41,11 @@ static const struct nla_policy ipoib_policy[IFLA_IPOIB_MAX + 1] = {
+ 	[IFLA_IPOIB_UMCAST]	= { .type = NLA_U16 },
+ };
+ 
++static unsigned int ipoib_get_max_num_queues(void)
++{
++	return min_t(unsigned int, num_possible_cpus(), 128);
++}
++
+ static int ipoib_fill_info(struct sk_buff *skb, const struct net_device *dev)
+ {
+ 	struct ipoib_dev_priv *priv = ipoib_priv(dev);
+@@ -172,6 +177,8 @@ static struct rtnl_link_ops ipoib_link_ops __read_mostly = {
+ 	.changelink	= ipoib_changelink,
+ 	.get_size	= ipoib_get_size,
+ 	.fill_info	= ipoib_fill_info,
++	.get_num_rx_queues = ipoib_get_max_num_queues,
++	.get_num_tx_queues = ipoib_get_max_num_queues,
+ };
+ 
+ struct rtnl_link_ops *ipoib_get_link_ops(void)
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index 9c9872868aeea..4f5e49393c854 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -3405,7 +3405,8 @@ static int srp_parse_options(struct net *net, const char *buf,
+ 			break;
+ 
+ 		case SRP_OPT_PKEY:
+-			if (match_hex(args, &token)) {
++			ret = match_hex(args, &token);
++			if (ret) {
+ 				pr_warn("bad P_Key parameter '%s'\n", p);
+ 				goto out;
+ 			}
+@@ -3465,7 +3466,8 @@ static int srp_parse_options(struct net *net, const char *buf,
+ 			break;
+ 
+ 		case SRP_OPT_MAX_SECT:
+-			if (match_int(args, &token)) {
++			ret = match_int(args, &token);
++			if (ret) {
+ 				pr_warn("bad max sect parameter '%s'\n", p);
+ 				goto out;
+ 			}
+@@ -3473,8 +3475,15 @@ static int srp_parse_options(struct net *net, const char *buf,
+ 			break;
+ 
+ 		case SRP_OPT_QUEUE_SIZE:
+-			if (match_int(args, &token) || token < 1) {
++			ret = match_int(args, &token);
++			if (ret) {
++				pr_warn("match_int() failed for queue_size parameter '%s', Error %d\n",
++					p, ret);
++				goto out;
++			}
++			if (token < 1) {
+ 				pr_warn("bad queue_size parameter '%s'\n", p);
++				ret = -EINVAL;
+ 				goto out;
+ 			}
+ 			target->scsi_host->can_queue = token;
+@@ -3485,25 +3494,40 @@ static int srp_parse_options(struct net *net, const char *buf,
+ 			break;
+ 
+ 		case SRP_OPT_MAX_CMD_PER_LUN:
+-			if (match_int(args, &token) || token < 1) {
++			ret = match_int(args, &token);
++			if (ret) {
++				pr_warn("match_int() failed for max cmd_per_lun parameter '%s', Error %d\n",
++					p, ret);
++				goto out;
++			}
++			if (token < 1) {
+ 				pr_warn("bad max cmd_per_lun parameter '%s'\n",
+ 					p);
++				ret = -EINVAL;
+ 				goto out;
+ 			}
+ 			target->scsi_host->cmd_per_lun = token;
+ 			break;
+ 
+ 		case SRP_OPT_TARGET_CAN_QUEUE:
+-			if (match_int(args, &token) || token < 1) {
++			ret = match_int(args, &token);
++			if (ret) {
++				pr_warn("match_int() failed for max target_can_queue parameter '%s', Error %d\n",
++					p, ret);
++				goto out;
++			}
++			if (token < 1) {
+ 				pr_warn("bad max target_can_queue parameter '%s'\n",
+ 					p);
++				ret = -EINVAL;
+ 				goto out;
+ 			}
+ 			target->target_can_queue = token;
+ 			break;
+ 
+ 		case SRP_OPT_IO_CLASS:
+-			if (match_hex(args, &token)) {
++			ret = match_hex(args, &token);
++			if (ret) {
+ 				pr_warn("bad IO class parameter '%s'\n", p);
+ 				goto out;
+ 			}
+@@ -3512,6 +3536,7 @@ static int srp_parse_options(struct net *net, const char *buf,
+ 				pr_warn("unknown IO class parameter value %x specified (use %x or %x).\n",
+ 					token, SRP_REV10_IB_IO_CLASS,
+ 					SRP_REV16A_IB_IO_CLASS);
++				ret = -EINVAL;
+ 				goto out;
+ 			}
+ 			target->io_class = token;
+@@ -3534,16 +3559,24 @@ static int srp_parse_options(struct net *net, const char *buf,
+ 			break;
+ 
+ 		case SRP_OPT_CMD_SG_ENTRIES:
+-			if (match_int(args, &token) || token < 1 || token > 255) {
++			ret = match_int(args, &token);
++			if (ret) {
++				pr_warn("match_int() failed for max cmd_sg_entries parameter '%s', Error %d\n",
++					p, ret);
++				goto out;
++			}
++			if (token < 1 || token > 255) {
+ 				pr_warn("bad max cmd_sg_entries parameter '%s'\n",
+ 					p);
++				ret = -EINVAL;
+ 				goto out;
+ 			}
+ 			target->cmd_sg_cnt = token;
+ 			break;
+ 
+ 		case SRP_OPT_ALLOW_EXT_SG:
+-			if (match_int(args, &token)) {
++			ret = match_int(args, &token);
++			if (ret) {
+ 				pr_warn("bad allow_ext_sg parameter '%s'\n", p);
+ 				goto out;
+ 			}
+@@ -3551,43 +3584,77 @@ static int srp_parse_options(struct net *net, const char *buf,
+ 			break;
+ 
+ 		case SRP_OPT_SG_TABLESIZE:
+-			if (match_int(args, &token) || token < 1 ||
+-					token > SG_MAX_SEGMENTS) {
++			ret = match_int(args, &token);
++			if (ret) {
++				pr_warn("match_int() failed for max sg_tablesize parameter '%s', Error %d\n",
++					p, ret);
++				goto out;
++			}
++			if (token < 1 || token > SG_MAX_SEGMENTS) {
+ 				pr_warn("bad max sg_tablesize parameter '%s'\n",
+ 					p);
++				ret = -EINVAL;
+ 				goto out;
+ 			}
+ 			target->sg_tablesize = token;
+ 			break;
+ 
+ 		case SRP_OPT_COMP_VECTOR:
+-			if (match_int(args, &token) || token < 0) {
++			ret = match_int(args, &token);
++			if (ret) {
++				pr_warn("match_int() failed for comp_vector parameter '%s', Error %d\n",
++					p, ret);
++				goto out;
++			}
++			if (token < 0) {
+ 				pr_warn("bad comp_vector parameter '%s'\n", p);
++				ret = -EINVAL;
+ 				goto out;
+ 			}
+ 			target->comp_vector = token;
+ 			break;
+ 
+ 		case SRP_OPT_TL_RETRY_COUNT:
+-			if (match_int(args, &token) || token < 2 || token > 7) {
++			ret = match_int(args, &token);
++			if (ret) {
++				pr_warn("match_int() failed for tl_retry_count parameter '%s', Error %d\n",
++					p, ret);
++				goto out;
++			}
++			if (token < 2 || token > 7) {
+ 				pr_warn("bad tl_retry_count parameter '%s' (must be a number between 2 and 7)\n",
+ 					p);
++				ret = -EINVAL;
+ 				goto out;
+ 			}
+ 			target->tl_retry_count = token;
+ 			break;
+ 
+ 		case SRP_OPT_MAX_IT_IU_SIZE:
+-			if (match_int(args, &token) || token < 0) {
++			ret = match_int(args, &token);
++			if (ret) {
++				pr_warn("match_int() failed for max it_iu_size parameter '%s', Error %d\n",
++					p, ret);
++				goto out;
++			}
++			if (token < 0) {
+ 				pr_warn("bad maximum initiator to target IU size '%s'\n", p);
++				ret = -EINVAL;
+ 				goto out;
+ 			}
+ 			target->max_it_iu_size = token;
+ 			break;
+ 
+ 		case SRP_OPT_CH_COUNT:
+-			if (match_int(args, &token) || token < 1) {
++			ret = match_int(args, &token);
++			if (ret) {
++				pr_warn("match_int() failed for channel count parameter '%s', Error %d\n",
++					p, ret);
++				goto out;
++			}
++			if (token < 1) {
+ 				pr_warn("bad channel count %s\n", p);
++				ret = -EINVAL;
+ 				goto out;
+ 			}
+ 			target->ch_count = token;
+@@ -3596,6 +3663,7 @@ static int srp_parse_options(struct net *net, const char *buf,
+ 		default:
+ 			pr_warn("unknown parameter or missing value '%s' in target creation request\n",
+ 				p);
++			ret = -EINVAL;
+ 			goto out;
+ 		}
+ 	}
+diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
+index 9dcf3f51f2dd9..04ca3d1c28162 100644
+--- a/drivers/input/joystick/Kconfig
++++ b/drivers/input/joystick/Kconfig
+@@ -46,6 +46,7 @@ config JOYSTICK_A3D
+ config JOYSTICK_ADC
+ 	tristate "Simple joystick connected over ADC"
+ 	depends on IIO
++	select IIO_BUFFER
+ 	select IIO_BUFFER_CB
+ 	help
+ 	  Say Y here if you have a simple joystick connected over ADC.
+diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
+index a18ab7358d8f3..54c116e56e9d0 100644
+--- a/drivers/input/misc/Kconfig
++++ b/drivers/input/misc/Kconfig
+@@ -330,7 +330,7 @@ config INPUT_CPCAP_PWRBUTTON
+ 
+ config INPUT_WISTRON_BTNS
+ 	tristate "x86 Wistron laptop button interface"
+-	depends on X86_32
++	depends on X86_32 && !UML
+ 	select INPUT_SPARSEKMAP
+ 	select NEW_LEDS
+ 	select LEDS_CLASS
+diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c
+index b2e8097a2e6d9..e47ab6c1177f5 100644
+--- a/drivers/input/misc/iqs7222.c
++++ b/drivers/input/misc/iqs7222.c
+@@ -86,7 +86,9 @@ enum iqs7222_reg_key_id {
+ 	IQS7222_REG_KEY_TOUCH,
+ 	IQS7222_REG_KEY_DEBOUNCE,
+ 	IQS7222_REG_KEY_TAP,
++	IQS7222_REG_KEY_TAP_LEGACY,
+ 	IQS7222_REG_KEY_AXIAL,
++	IQS7222_REG_KEY_AXIAL_LEGACY,
+ 	IQS7222_REG_KEY_WHEEL,
+ 	IQS7222_REG_KEY_NO_WHEEL,
+ 	IQS7222_REG_KEY_RESERVED
+@@ -105,14 +107,14 @@ enum iqs7222_reg_grp_id {
+ 	IQS7222_NUM_REG_GRPS
+ };
+ 
+-static const char * const iqs7222_reg_grp_names[] = {
++static const char * const iqs7222_reg_grp_names[IQS7222_NUM_REG_GRPS] = {
+ 	[IQS7222_REG_GRP_CYCLE] = "cycle",
+ 	[IQS7222_REG_GRP_CHAN] = "channel",
+ 	[IQS7222_REG_GRP_SLDR] = "slider",
+ 	[IQS7222_REG_GRP_GPIO] = "gpio",
+ };
+ 
+-static const unsigned int iqs7222_max_cols[] = {
++static const unsigned int iqs7222_max_cols[IQS7222_NUM_REG_GRPS] = {
+ 	[IQS7222_REG_GRP_STAT] = IQS7222_MAX_COLS_STAT,
+ 	[IQS7222_REG_GRP_CYCLE] = IQS7222_MAX_COLS_CYCLE,
+ 	[IQS7222_REG_GRP_GLBL] = IQS7222_MAX_COLS_GLBL,
+@@ -202,10 +204,68 @@ struct iqs7222_dev_desc {
+ 	int allow_offset;
+ 	int event_offset;
+ 	int comms_offset;
++	bool legacy_gesture;
+ 	struct iqs7222_reg_grp_desc reg_grps[IQS7222_NUM_REG_GRPS];
+ };
+ 
+ static const struct iqs7222_dev_desc iqs7222_devs[] = {
++	{
++		.prod_num = IQS7222_PROD_NUM_A,
++		.fw_major = 1,
++		.fw_minor = 13,
++		.sldr_res = U8_MAX * 16,
++		.touch_link = 1768,
++		.allow_offset = 9,
++		.event_offset = 10,
++		.comms_offset = 12,
++		.reg_grps = {
++			[IQS7222_REG_GRP_STAT] = {
++				.base = IQS7222_SYS_STATUS,
++				.num_row = 1,
++				.num_col = 8,
++			},
++			[IQS7222_REG_GRP_CYCLE] = {
++				.base = 0x8000,
++				.num_row = 7,
++				.num_col = 3,
++			},
++			[IQS7222_REG_GRP_GLBL] = {
++				.base = 0x8700,
++				.num_row = 1,
++				.num_col = 3,
++			},
++			[IQS7222_REG_GRP_BTN] = {
++				.base = 0x9000,
++				.num_row = 12,
++				.num_col = 3,
++			},
++			[IQS7222_REG_GRP_CHAN] = {
++				.base = 0xA000,
++				.num_row = 12,
++				.num_col = 6,
++			},
++			[IQS7222_REG_GRP_FILT] = {
++				.base = 0xAC00,
++				.num_row = 1,
++				.num_col = 2,
++			},
++			[IQS7222_REG_GRP_SLDR] = {
++				.base = 0xB000,
++				.num_row = 2,
++				.num_col = 11,
++			},
++			[IQS7222_REG_GRP_GPIO] = {
++				.base = 0xC000,
++				.num_row = 1,
++				.num_col = 3,
++			},
++			[IQS7222_REG_GRP_SYS] = {
++				.base = IQS7222_SYS_SETUP,
++				.num_row = 1,
++				.num_col = 13,
++			},
++		},
++	},
+ 	{
+ 		.prod_num = IQS7222_PROD_NUM_A,
+ 		.fw_major = 1,
+@@ -215,6 +275,7 @@ static const struct iqs7222_dev_desc iqs7222_devs[] = {
+ 		.allow_offset = 9,
+ 		.event_offset = 10,
+ 		.comms_offset = 12,
++		.legacy_gesture = true,
+ 		.reg_grps = {
+ 			[IQS7222_REG_GRP_STAT] = {
+ 				.base = IQS7222_SYS_STATUS,
+@@ -874,6 +935,16 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
+ 		.reg_offset = 9,
+ 		.reg_shift = 8,
+ 		.reg_width = 8,
++		.val_pitch = 16,
++		.label = "maximum gesture time",
++	},
++	{
++		.name = "azoteq,gesture-max-ms",
++		.reg_grp = IQS7222_REG_GRP_SLDR,
++		.reg_key = IQS7222_REG_KEY_TAP_LEGACY,
++		.reg_offset = 9,
++		.reg_shift = 8,
++		.reg_width = 8,
+ 		.val_pitch = 4,
+ 		.label = "maximum gesture time",
+ 	},
+@@ -884,6 +955,16 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
+ 		.reg_offset = 9,
+ 		.reg_shift = 3,
+ 		.reg_width = 5,
++		.val_pitch = 16,
++		.label = "minimum gesture time",
++	},
++	{
++		.name = "azoteq,gesture-min-ms",
++		.reg_grp = IQS7222_REG_GRP_SLDR,
++		.reg_key = IQS7222_REG_KEY_TAP_LEGACY,
++		.reg_offset = 9,
++		.reg_shift = 3,
++		.reg_width = 5,
+ 		.val_pitch = 4,
+ 		.label = "minimum gesture time",
+ 	},
+@@ -897,6 +978,16 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
+ 		.val_pitch = 16,
+ 		.label = "gesture distance",
+ 	},
++	{
++		.name = "azoteq,gesture-dist",
++		.reg_grp = IQS7222_REG_GRP_SLDR,
++		.reg_key = IQS7222_REG_KEY_AXIAL_LEGACY,
++		.reg_offset = 10,
++		.reg_shift = 8,
++		.reg_width = 8,
++		.val_pitch = 16,
++		.label = "gesture distance",
++	},
+ 	{
+ 		.name = "azoteq,gesture-max-ms",
+ 		.reg_grp = IQS7222_REG_GRP_SLDR,
+@@ -904,6 +995,16 @@ static const struct iqs7222_prop_desc iqs7222_props[] = {
+ 		.reg_offset = 10,
+ 		.reg_shift = 0,
+ 		.reg_width = 8,
++		.val_pitch = 16,
++		.label = "maximum gesture time",
++	},
++	{
++		.name = "azoteq,gesture-max-ms",
++		.reg_grp = IQS7222_REG_GRP_SLDR,
++		.reg_key = IQS7222_REG_KEY_AXIAL_LEGACY,
++		.reg_offset = 10,
++		.reg_shift = 0,
++		.reg_width = 8,
+ 		.val_pitch = 4,
+ 		.label = "maximum gesture time",
+ 	},
+@@ -1077,7 +1178,7 @@ static int iqs7222_hard_reset(struct iqs7222_private *iqs7222)
+ 
+ static int iqs7222_force_comms(struct iqs7222_private *iqs7222)
+ {
+-	u8 msg_buf[] = { 0xFF, 0x00, };
++	u8 msg_buf[] = { 0xFF, };
+ 	int ret;
+ 
+ 	/*
+@@ -1567,56 +1668,17 @@ static int iqs7222_gpio_select(struct iqs7222_private *iqs7222,
+ }
+ 
+ static int iqs7222_parse_props(struct iqs7222_private *iqs7222,
+-			       struct fwnode_handle **child_node,
+-			       int child_index,
++			       struct fwnode_handle *reg_grp_node,
++			       int reg_grp_index,
+ 			       enum iqs7222_reg_grp_id reg_grp,
+ 			       enum iqs7222_reg_key_id reg_key)
+ {
+-	u16 *setup = iqs7222_setup(iqs7222, reg_grp, child_index);
++	u16 *setup = iqs7222_setup(iqs7222, reg_grp, reg_grp_index);
+ 	struct i2c_client *client = iqs7222->client;
+-	struct fwnode_handle *reg_grp_node;
+-	char reg_grp_name[16];
+ 	int i;
+ 
+-	switch (reg_grp) {
+-	case IQS7222_REG_GRP_CYCLE:
+-	case IQS7222_REG_GRP_CHAN:
+-	case IQS7222_REG_GRP_SLDR:
+-	case IQS7222_REG_GRP_GPIO:
+-	case IQS7222_REG_GRP_BTN:
+-		/*
+-		 * These groups derive a child node and return it to the caller
+-		 * for additional group-specific processing. In some cases, the
+-		 * child node may have already been derived.
+-		 */
+-		reg_grp_node = *child_node;
+-		if (reg_grp_node)
+-			break;
+-
+-		snprintf(reg_grp_name, sizeof(reg_grp_name), "%s-%d",
+-			 iqs7222_reg_grp_names[reg_grp], child_index);
+-
+-		reg_grp_node = device_get_named_child_node(&client->dev,
+-							   reg_grp_name);
+-		if (!reg_grp_node)
+-			return 0;
+-
+-		*child_node = reg_grp_node;
+-		break;
+-
+-	case IQS7222_REG_GRP_GLBL:
+-	case IQS7222_REG_GRP_FILT:
+-	case IQS7222_REG_GRP_SYS:
+-		/*
+-		 * These groups are not organized beneath a child node, nor are
+-		 * they subject to any additional processing by the caller.
+-		 */
+-		reg_grp_node = dev_fwnode(&client->dev);
+-		break;
+-
+-	default:
+-		return -EINVAL;
+-	}
++	if (!setup)
++		return 0;
+ 
+ 	for (i = 0; i < ARRAY_SIZE(iqs7222_props); i++) {
+ 		const char *name = iqs7222_props[i].name;
+@@ -1686,11 +1748,66 @@ static int iqs7222_parse_props(struct iqs7222_private *iqs7222,
+ 	return 0;
+ }
+ 
+-static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index)
++static int iqs7222_parse_event(struct iqs7222_private *iqs7222,
++			       struct fwnode_handle *event_node,
++			       int reg_grp_index,
++			       enum iqs7222_reg_grp_id reg_grp,
++			       enum iqs7222_reg_key_id reg_key,
++			       u16 event_enable, u16 event_link,
++			       unsigned int *event_type,
++			       unsigned int *event_code)
++{
++	struct i2c_client *client = iqs7222->client;
++	int error;
++
++	error = iqs7222_parse_props(iqs7222, event_node, reg_grp_index,
++				    reg_grp, reg_key);
++	if (error)
++		return error;
++
++	error = iqs7222_gpio_select(iqs7222, event_node, event_enable,
++				    event_link);
++	if (error)
++		return error;
++
++	error = fwnode_property_read_u32(event_node, "linux,code", event_code);
++	if (error == -EINVAL) {
++		return 0;
++	} else if (error) {
++		dev_err(&client->dev, "Failed to read %s code: %d\n",
++			fwnode_get_name(event_node), error);
++		return error;
++	}
++
++	if (!event_type) {
++		input_set_capability(iqs7222->keypad, EV_KEY, *event_code);
++		return 0;
++	}
++
++	error = fwnode_property_read_u32(event_node, "linux,input-type",
++					 event_type);
++	if (error == -EINVAL) {
++		*event_type = EV_KEY;
++	} else if (error) {
++		dev_err(&client->dev, "Failed to read %s input type: %d\n",
++			fwnode_get_name(event_node), error);
++		return error;
++	} else if (*event_type != EV_KEY && *event_type != EV_SW) {
++		dev_err(&client->dev, "Invalid %s input type: %d\n",
++			fwnode_get_name(event_node), *event_type);
++		return -EINVAL;
++	}
++
++	input_set_capability(iqs7222->keypad, *event_type, *event_code);
++
++	return 0;
++}
++
++static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222,
++			       struct fwnode_handle *cycle_node, int cycle_index)
+ {
+ 	u16 *cycle_setup = iqs7222->cycle_setup[cycle_index];
+ 	struct i2c_client *client = iqs7222->client;
+-	struct fwnode_handle *cycle_node = NULL;
+ 	unsigned int pins[9];
+ 	int error, count, i;
+ 
+@@ -1698,17 +1815,7 @@ static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index)
+ 	 * Each channel shares a cycle with one other channel; the mapping of
+ 	 * channels to cycles is fixed. Properties defined for a cycle impact
+ 	 * both channels tied to the cycle.
+-	 */
+-	error = iqs7222_parse_props(iqs7222, &cycle_node, cycle_index,
+-				    IQS7222_REG_GRP_CYCLE,
+-				    IQS7222_REG_KEY_NONE);
+-	if (error)
+-		return error;
+-
+-	if (!cycle_node)
+-		return 0;
+-
+-	/*
++	 *
+ 	 * Unlike channels which are restricted to a select range of CRx pins
+ 	 * based on channel number, any cycle can claim any of the device's 9
+ 	 * CTx pins (CTx0-8).
+@@ -1750,11 +1857,11 @@ static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index)
+ 	return 0;
+ }
+ 
+-static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
++static int iqs7222_parse_chan(struct iqs7222_private *iqs7222,
++			      struct fwnode_handle *chan_node, int chan_index)
+ {
+ 	const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc;
+ 	struct i2c_client *client = iqs7222->client;
+-	struct fwnode_handle *chan_node = NULL;
+ 	int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row;
+ 	int ext_chan = rounddown(num_chan, 10);
+ 	int error, i;
+@@ -1762,20 +1869,9 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+ 	u16 *sys_setup = iqs7222->sys_setup;
+ 	unsigned int val;
+ 
+-	error = iqs7222_parse_props(iqs7222, &chan_node, chan_index,
+-				    IQS7222_REG_GRP_CHAN,
+-				    IQS7222_REG_KEY_NONE);
+-	if (error)
+-		return error;
+-
+-	if (!chan_node)
+-		return 0;
+-
+-	if (dev_desc->allow_offset) {
+-		sys_setup[dev_desc->allow_offset] |= BIT(chan_index);
+-		if (fwnode_property_present(chan_node, "azoteq,ulp-allow"))
+-			sys_setup[dev_desc->allow_offset] &= ~BIT(chan_index);
+-	}
++	if (dev_desc->allow_offset &&
++	    fwnode_property_present(chan_node, "azoteq,ulp-allow"))
++		sys_setup[dev_desc->allow_offset] &= ~BIT(chan_index);
+ 
+ 	chan_setup[0] |= IQS7222_CHAN_SETUP_0_CHAN_EN;
+ 
+@@ -1812,8 +1908,9 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+ 		chan_setup[0] |= IQS7222_CHAN_SETUP_0_REF_MODE_FOLLOW;
+ 		chan_setup[4] = val * 42 + 1048;
+ 
+-		if (!fwnode_property_read_u32(chan_node, "azoteq,ref-weight",
+-					      &val)) {
++		error = fwnode_property_read_u32(chan_node, "azoteq,ref-weight",
++						 &val);
++		if (!error) {
+ 			if (val > U16_MAX) {
+ 				dev_err(&client->dev,
+ 					"Invalid %s reference weight: %u\n",
+@@ -1822,6 +1919,11 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+ 			}
+ 
+ 			chan_setup[5] = val;
++		} else if (error != -EINVAL) {
++			dev_err(&client->dev,
++				"Failed to read %s reference weight: %d\n",
++				fwnode_get_name(chan_node), error);
++			return error;
+ 		}
+ 
+ 		/*
+@@ -1894,21 +1996,10 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+ 		if (!event_node)
+ 			continue;
+ 
+-		error = iqs7222_parse_props(iqs7222, &event_node, chan_index,
+-					    IQS7222_REG_GRP_BTN,
+-					    iqs7222_kp_events[i].reg_key);
+-		if (error)
+-			return error;
+-
+-		error = iqs7222_gpio_select(iqs7222, event_node,
+-					    BIT(chan_index),
+-					    dev_desc->touch_link - (i ? 0 : 2));
+-		if (error)
+-			return error;
+-
+-		if (!fwnode_property_read_u32(event_node,
+-					      "azoteq,timeout-press-ms",
+-					      &val)) {
++		error = fwnode_property_read_u32(event_node,
++						 "azoteq,timeout-press-ms",
++						 &val);
++		if (!error) {
+ 			/*
+ 			 * The IQS7222B employs a global pair of press timeout
+ 			 * registers as opposed to channel-specific registers.
+@@ -1921,57 +2012,31 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+ 			if (val > U8_MAX * 500) {
+ 				dev_err(&client->dev,
+ 					"Invalid %s press timeout: %u\n",
+-					fwnode_get_name(chan_node), val);
++					fwnode_get_name(event_node), val);
++				fwnode_handle_put(event_node);
+ 				return -EINVAL;
+ 			}
+ 
+ 			*setup &= ~(U8_MAX << i * 8);
+ 			*setup |= (val / 500 << i * 8);
+-		}
+-
+-		error = fwnode_property_read_u32(event_node, "linux,code",
+-						 &val);
+-		if (error) {
+-			dev_err(&client->dev, "Failed to read %s code: %d\n",
+-				fwnode_get_name(chan_node), error);
++		} else if (error != -EINVAL) {
++			dev_err(&client->dev,
++				"Failed to read %s press timeout: %d\n",
++				fwnode_get_name(event_node), error);
++			fwnode_handle_put(event_node);
+ 			return error;
+ 		}
+ 
+-		iqs7222->kp_code[chan_index][i] = val;
+-		iqs7222->kp_type[chan_index][i] = EV_KEY;
+-
+-		if (fwnode_property_present(event_node, "linux,input-type")) {
+-			error = fwnode_property_read_u32(event_node,
+-							 "linux,input-type",
+-							 &val);
+-			if (error) {
+-				dev_err(&client->dev,
+-					"Failed to read %s input type: %d\n",
+-					fwnode_get_name(chan_node), error);
+-				return error;
+-			}
+-
+-			if (val != EV_KEY && val != EV_SW) {
+-				dev_err(&client->dev,
+-					"Invalid %s input type: %u\n",
+-					fwnode_get_name(chan_node), val);
+-				return -EINVAL;
+-			}
+-
+-			iqs7222->kp_type[chan_index][i] = val;
+-		}
+-
+-		/*
+-		 * Reference channels can opt out of event reporting by using
+-		 * KEY_RESERVED in place of a true key or switch code.
+-		 */
+-		if (iqs7222->kp_type[chan_index][i] == EV_KEY &&
+-		    iqs7222->kp_code[chan_index][i] == KEY_RESERVED)
+-			continue;
+-
+-		input_set_capability(iqs7222->keypad,
+-				     iqs7222->kp_type[chan_index][i],
+-				     iqs7222->kp_code[chan_index][i]);
++		error = iqs7222_parse_event(iqs7222, event_node, chan_index,
++					    IQS7222_REG_GRP_BTN,
++					    iqs7222_kp_events[i].reg_key,
++					    BIT(chan_index),
++					    dev_desc->touch_link - (i ? 0 : 2),
++					    &iqs7222->kp_type[chan_index][i],
++					    &iqs7222->kp_code[chan_index][i]);
++		fwnode_handle_put(event_node);
++		if (error)
++			return error;
+ 
+ 		if (!dev_desc->event_offset)
+ 			continue;
+@@ -1983,16 +2048,16 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index)
+ 	 * The following call handles a special pair of properties that apply
+ 	 * to a channel node, but reside within the button (event) group.
+ 	 */
+-	return iqs7222_parse_props(iqs7222, &chan_node, chan_index,
++	return iqs7222_parse_props(iqs7222, chan_node, chan_index,
+ 				   IQS7222_REG_GRP_BTN,
+ 				   IQS7222_REG_KEY_DEBOUNCE);
+ }
+ 
+-static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
++static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222,
++			      struct fwnode_handle *sldr_node, int sldr_index)
+ {
+ 	const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc;
+ 	struct i2c_client *client = iqs7222->client;
+-	struct fwnode_handle *sldr_node = NULL;
+ 	int num_chan = dev_desc->reg_grps[IQS7222_REG_GRP_CHAN].num_row;
+ 	int ext_chan = rounddown(num_chan, 10);
+ 	int count, error, reg_offset, i;
+@@ -2000,15 +2065,6 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ 	u16 *sldr_setup = iqs7222->sldr_setup[sldr_index];
+ 	unsigned int chan_sel[4], val;
+ 
+-	error = iqs7222_parse_props(iqs7222, &sldr_node, sldr_index,
+-				    IQS7222_REG_GRP_SLDR,
+-				    IQS7222_REG_KEY_NONE);
+-	if (error)
+-		return error;
+-
+-	if (!sldr_node)
+-		return 0;
+-
+ 	/*
+ 	 * Each slider can be spread across 3 to 4 channels. It is possible to
+ 	 * select only 2 channels, but doing so prevents the slider from using
+@@ -2067,8 +2123,9 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ 	if (fwnode_property_present(sldr_node, "azoteq,use-prox"))
+ 		sldr_setup[4 + reg_offset] -= 2;
+ 
+-	if (!fwnode_property_read_u32(sldr_node, "azoteq,slider-size", &val)) {
+-		if (!val || val > dev_desc->sldr_res) {
++	error = fwnode_property_read_u32(sldr_node, "azoteq,slider-size", &val);
++	if (!error) {
++		if (val > dev_desc->sldr_res) {
+ 			dev_err(&client->dev, "Invalid %s size: %u\n",
+ 				fwnode_get_name(sldr_node), val);
+ 			return -EINVAL;
+@@ -2081,9 +2138,21 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ 			sldr_setup[2] |= (val / 16 <<
+ 					  IQS7222_SLDR_SETUP_2_RES_SHIFT);
+ 		}
++	} else if (error != -EINVAL) {
++		dev_err(&client->dev, "Failed to read %s size: %d\n",
++			fwnode_get_name(sldr_node), error);
++		return error;
++	}
++
++	if (!(reg_offset ? sldr_setup[3]
++			 : sldr_setup[2] & IQS7222_SLDR_SETUP_2_RES_MASK)) {
++		dev_err(&client->dev, "Undefined %s size\n",
++			fwnode_get_name(sldr_node));
++		return -EINVAL;
+ 	}
+ 
+-	if (!fwnode_property_read_u32(sldr_node, "azoteq,top-speed", &val)) {
++	error = fwnode_property_read_u32(sldr_node, "azoteq,top-speed", &val);
++	if (!error) {
+ 		if (val > (reg_offset ? U16_MAX : U8_MAX * 4)) {
+ 			dev_err(&client->dev, "Invalid %s top speed: %u\n",
+ 				fwnode_get_name(sldr_node), val);
+@@ -2096,9 +2165,14 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ 			sldr_setup[2] &= ~IQS7222_SLDR_SETUP_2_TOP_SPEED_MASK;
+ 			sldr_setup[2] |= (val / 4);
+ 		}
++	} else if (error != -EINVAL) {
++		dev_err(&client->dev, "Failed to read %s top speed: %d\n",
++			fwnode_get_name(sldr_node), error);
++		return error;
+ 	}
+ 
+-	if (!fwnode_property_read_u32(sldr_node, "linux,axis", &val)) {
++	error = fwnode_property_read_u32(sldr_node, "linux,axis", &val);
++	if (!error) {
+ 		u16 sldr_max = sldr_setup[3] - 1;
+ 
+ 		if (!reg_offset) {
+@@ -2112,6 +2186,10 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ 
+ 		input_set_abs_params(iqs7222->keypad, val, 0, sldr_max, 0, 0);
+ 		iqs7222->sl_axis[sldr_index] = val;
++	} else if (error != -EINVAL) {
++		dev_err(&client->dev, "Failed to read %s axis: %d\n",
++			fwnode_get_name(sldr_node), error);
++		return error;
+ 	}
+ 
+ 	if (dev_desc->wheel_enable) {
+@@ -2132,46 +2210,47 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ 	for (i = 0; i < ARRAY_SIZE(iqs7222_sl_events); i++) {
+ 		const char *event_name = iqs7222_sl_events[i].name;
+ 		struct fwnode_handle *event_node;
++		enum iqs7222_reg_key_id reg_key;
+ 
+ 		event_node = fwnode_get_named_child_node(sldr_node, event_name);
+ 		if (!event_node)
+ 			continue;
+ 
+-		error = iqs7222_parse_props(iqs7222, &event_node, sldr_index,
+-					    IQS7222_REG_GRP_SLDR,
+-					    reg_offset ?
+-					    IQS7222_REG_KEY_RESERVED :
+-					    iqs7222_sl_events[i].reg_key);
+-		if (error)
+-			return error;
++		/*
++		 * Depending on the device, gestures are either offered using
++		 * one of two timing resolutions, or are not supported at all.
++		 */
++		if (reg_offset)
++			reg_key = IQS7222_REG_KEY_RESERVED;
++		else if (dev_desc->legacy_gesture &&
++			 iqs7222_sl_events[i].reg_key == IQS7222_REG_KEY_TAP)
++			reg_key = IQS7222_REG_KEY_TAP_LEGACY;
++		else if (dev_desc->legacy_gesture &&
++			 iqs7222_sl_events[i].reg_key == IQS7222_REG_KEY_AXIAL)
++			reg_key = IQS7222_REG_KEY_AXIAL_LEGACY;
++		else
++			reg_key = iqs7222_sl_events[i].reg_key;
+ 
+ 		/*
+ 		 * The press/release event does not expose a direct GPIO link,
+ 		 * but one can be emulated by tying each of the participating
+ 		 * channels to the same GPIO.
+ 		 */
+-		error = iqs7222_gpio_select(iqs7222, event_node,
++		error = iqs7222_parse_event(iqs7222, event_node, sldr_index,
++					    IQS7222_REG_GRP_SLDR, reg_key,
+ 					    i ? iqs7222_sl_events[i].enable
+ 					      : sldr_setup[3 + reg_offset],
+ 					    i ? 1568 + sldr_index * 30
+-					      : sldr_setup[4 + reg_offset]);
++					      : sldr_setup[4 + reg_offset],
++					    NULL,
++					    &iqs7222->sl_code[sldr_index][i]);
++		fwnode_handle_put(event_node);
+ 		if (error)
+ 			return error;
+ 
+ 		if (!reg_offset)
+ 			sldr_setup[9] |= iqs7222_sl_events[i].enable;
+ 
+-		error = fwnode_property_read_u32(event_node, "linux,code",
+-						 &val);
+-		if (error) {
+-			dev_err(&client->dev, "Failed to read %s code: %d\n",
+-				fwnode_get_name(sldr_node), error);
+-			return error;
+-		}
+-
+-		iqs7222->sl_code[sldr_index][i] = val;
+-		input_set_capability(iqs7222->keypad, EV_KEY, val);
+-
+ 		if (!dev_desc->event_offset)
+ 			continue;
+ 
+@@ -2192,49 +2271,77 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index)
+ 	 * The following call handles a special pair of properties that shift
+ 	 * to make room for a wheel enable control in the case of IQS7222C.
+ 	 */
+-	return iqs7222_parse_props(iqs7222, &sldr_node, sldr_index,
++	return iqs7222_parse_props(iqs7222, sldr_node, sldr_index,
+ 				   IQS7222_REG_GRP_SLDR,
+ 				   dev_desc->wheel_enable ?
+ 				   IQS7222_REG_KEY_WHEEL :
+ 				   IQS7222_REG_KEY_NO_WHEEL);
+ }
+ 
++static int (*iqs7222_parse_extra[IQS7222_NUM_REG_GRPS])
++				(struct iqs7222_private *iqs7222,
++				 struct fwnode_handle *reg_grp_node,
++				 int reg_grp_index) = {
++	[IQS7222_REG_GRP_CYCLE] = iqs7222_parse_cycle,
++	[IQS7222_REG_GRP_CHAN] = iqs7222_parse_chan,
++	[IQS7222_REG_GRP_SLDR] = iqs7222_parse_sldr,
++};
++
++static int iqs7222_parse_reg_grp(struct iqs7222_private *iqs7222,
++				 enum iqs7222_reg_grp_id reg_grp,
++				 int reg_grp_index)
++{
++	struct i2c_client *client = iqs7222->client;
++	struct fwnode_handle *reg_grp_node;
++	int error;
++
++	if (iqs7222_reg_grp_names[reg_grp]) {
++		char reg_grp_name[16];
++
++		snprintf(reg_grp_name, sizeof(reg_grp_name), "%s-%d",
++			 iqs7222_reg_grp_names[reg_grp], reg_grp_index);
++
++		reg_grp_node = device_get_named_child_node(&client->dev,
++							   reg_grp_name);
++	} else {
++		reg_grp_node = fwnode_handle_get(dev_fwnode(&client->dev));
++	}
++
++	if (!reg_grp_node)
++		return 0;
++
++	error = iqs7222_parse_props(iqs7222, reg_grp_node, reg_grp_index,
++				    reg_grp, IQS7222_REG_KEY_NONE);
++
++	if (!error && iqs7222_parse_extra[reg_grp])
++		error = iqs7222_parse_extra[reg_grp](iqs7222, reg_grp_node,
++						     reg_grp_index);
++
++	fwnode_handle_put(reg_grp_node);
++
++	return error;
++}
++
+ static int iqs7222_parse_all(struct iqs7222_private *iqs7222)
+ {
+ 	const struct iqs7222_dev_desc *dev_desc = iqs7222->dev_desc;
+ 	const struct iqs7222_reg_grp_desc *reg_grps = dev_desc->reg_grps;
+ 	u16 *sys_setup = iqs7222->sys_setup;
+-	int error, i;
++	int error, i, j;
++
++	if (dev_desc->allow_offset)
++		sys_setup[dev_desc->allow_offset] = U16_MAX;
+ 
+ 	if (dev_desc->event_offset)
+ 		sys_setup[dev_desc->event_offset] = IQS7222_EVENT_MASK_ATI;
+ 
+-	for (i = 0; i < reg_grps[IQS7222_REG_GRP_CYCLE].num_row; i++) {
+-		error = iqs7222_parse_cycle(iqs7222, i);
+-		if (error)
+-			return error;
+-	}
+-
+-	error = iqs7222_parse_props(iqs7222, NULL, 0, IQS7222_REG_GRP_GLBL,
+-				    IQS7222_REG_KEY_NONE);
+-	if (error)
+-		return error;
+-
+ 	for (i = 0; i < reg_grps[IQS7222_REG_GRP_GPIO].num_row; i++) {
+-		struct fwnode_handle *gpio_node = NULL;
+ 		u16 *gpio_setup = iqs7222->gpio_setup[i];
+-		int j;
+ 
+ 		gpio_setup[0] &= ~IQS7222_GPIO_SETUP_0_GPIO_EN;
+ 		gpio_setup[1] = 0;
+ 		gpio_setup[2] = 0;
+ 
+-		error = iqs7222_parse_props(iqs7222, &gpio_node, i,
+-					    IQS7222_REG_GRP_GPIO,
+-					    IQS7222_REG_KEY_NONE);
+-		if (error)
+-			return error;
+-
+ 		if (reg_grps[IQS7222_REG_GRP_GPIO].num_row == 1)
+ 			continue;
+ 
+@@ -2257,29 +2364,21 @@ static int iqs7222_parse_all(struct iqs7222_private *iqs7222)
+ 		chan_setup[5] = 0;
+ 	}
+ 
+-	for (i = 0; i < reg_grps[IQS7222_REG_GRP_CHAN].num_row; i++) {
+-		error = iqs7222_parse_chan(iqs7222, i);
+-		if (error)
+-			return error;
+-	}
+-
+-	error = iqs7222_parse_props(iqs7222, NULL, 0, IQS7222_REG_GRP_FILT,
+-				    IQS7222_REG_KEY_NONE);
+-	if (error)
+-		return error;
+-
+ 	for (i = 0; i < reg_grps[IQS7222_REG_GRP_SLDR].num_row; i++) {
+ 		u16 *sldr_setup = iqs7222->sldr_setup[i];
+ 
+ 		sldr_setup[0] &= ~IQS7222_SLDR_SETUP_0_CHAN_CNT_MASK;
++	}
+ 
+-		error = iqs7222_parse_sldr(iqs7222, i);
+-		if (error)
+-			return error;
++	for (i = 0; i < IQS7222_NUM_REG_GRPS; i++) {
++		for (j = 0; j < reg_grps[i].num_row; j++) {
++			error = iqs7222_parse_reg_grp(iqs7222, i, j);
++			if (error)
++				return error;
++		}
+ 	}
+ 
+-	return iqs7222_parse_props(iqs7222, NULL, 0, IQS7222_REG_GRP_SYS,
+-				   IQS7222_REG_KEY_NONE);
++	return 0;
+ }
+ 
+ static int iqs7222_report(struct iqs7222_private *iqs7222)
+@@ -2326,6 +2425,9 @@ static int iqs7222_report(struct iqs7222_private *iqs7222)
+ 			int k = 2 + j * (num_chan > 16 ? 2 : 1);
+ 			u16 state = le16_to_cpu(status[k + i / 16]);
+ 
++			if (!iqs7222->kp_type[i][j])
++				continue;
++
+ 			input_event(iqs7222->keypad,
+ 				    iqs7222->kp_type[i][j],
+ 				    iqs7222->kp_code[i][j],
+diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c
+index 879a4d984c907..e1308e179dd6f 100644
+--- a/drivers/input/touchscreen/elants_i2c.c
++++ b/drivers/input/touchscreen/elants_i2c.c
+@@ -1329,14 +1329,12 @@ static int elants_i2c_power_on(struct elants_data *ts)
+ 	if (IS_ERR_OR_NULL(ts->reset_gpio))
+ 		return 0;
+ 
+-	gpiod_set_value_cansleep(ts->reset_gpio, 1);
+-
+ 	error = regulator_enable(ts->vcc33);
+ 	if (error) {
+ 		dev_err(&ts->client->dev,
+ 			"failed to enable vcc33 regulator: %d\n",
+ 			error);
+-		goto release_reset_gpio;
++		return error;
+ 	}
+ 
+ 	error = regulator_enable(ts->vccio);
+@@ -1345,7 +1343,7 @@ static int elants_i2c_power_on(struct elants_data *ts)
+ 			"failed to enable vccio regulator: %d\n",
+ 			error);
+ 		regulator_disable(ts->vcc33);
+-		goto release_reset_gpio;
++		return error;
+ 	}
+ 
+ 	/*
+@@ -1354,7 +1352,6 @@ static int elants_i2c_power_on(struct elants_data *ts)
+ 	 */
+ 	udelay(ELAN_POWERON_DELAY_USEC);
+ 
+-release_reset_gpio:
+ 	gpiod_set_value_cansleep(ts->reset_gpio, 0);
+ 	if (error)
+ 		return error;
+@@ -1462,7 +1459,7 @@ static int elants_i2c_probe(struct i2c_client *client)
+ 		return error;
+ 	}
+ 
+-	ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_LOW);
++	ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
+ 	if (IS_ERR(ts->reset_gpio)) {
+ 		error = PTR_ERR(ts->reset_gpio);
+ 
+diff --git a/drivers/interconnect/qcom/sc7180.c b/drivers/interconnect/qcom/sc7180.c
+index 35cd448efdfbe..82d5e8a8c19ea 100644
+--- a/drivers/interconnect/qcom/sc7180.c
++++ b/drivers/interconnect/qcom/sc7180.c
+@@ -369,7 +369,7 @@ static const struct qcom_icc_desc sc7180_gem_noc = {
+ 	.num_bcms = ARRAY_SIZE(gem_noc_bcms),
+ };
+ 
+-static struct qcom_icc_bcm *mc_virt_bcms[] = {
++static struct qcom_icc_bcm * const mc_virt_bcms[] = {
+ 	&bcm_acv,
+ 	&bcm_mc0,
+ };
+diff --git a/drivers/iommu/amd/iommu_v2.c b/drivers/iommu/amd/iommu_v2.c
+index 6a1f02c62dffc..9f7fab49a5a90 100644
+--- a/drivers/iommu/amd/iommu_v2.c
++++ b/drivers/iommu/amd/iommu_v2.c
+@@ -587,6 +587,7 @@ out_drop_state:
+ 	put_device_state(dev_state);
+ 
+ out:
++	pci_dev_put(pdev);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
+index 0d03f837a5d4e..7a1a413f75ab2 100644
+--- a/drivers/iommu/fsl_pamu.c
++++ b/drivers/iommu/fsl_pamu.c
+@@ -868,7 +868,7 @@ static int fsl_pamu_probe(struct platform_device *pdev)
+ 		ret = create_csd(ppaact_phys, mem_size, csd_port_id);
+ 		if (ret) {
+ 			dev_err(dev, "could not create coherence subdomain\n");
+-			return ret;
++			goto error;
+ 		}
+ 	}
+ 
+diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
+index 7e363b1f24dfe..ec73720e239b2 100644
+--- a/drivers/iommu/mtk_iommu.c
++++ b/drivers/iommu/mtk_iommu.c
+@@ -1041,20 +1041,24 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
+ 				  struct mtk_iommu_data *data)
+ {
+ 	struct device_node *larbnode, *smicomm_node, *smi_subcomm_node;
+-	struct platform_device *plarbdev;
++	struct platform_device *plarbdev, *pcommdev;
+ 	struct device_link *link;
+ 	int i, larb_nr, ret;
+ 
+ 	larb_nr = of_count_phandle_with_args(dev->of_node, "mediatek,larbs", NULL);
+ 	if (larb_nr < 0)
+ 		return larb_nr;
++	if (larb_nr == 0 || larb_nr > MTK_LARB_NR_MAX)
++		return -EINVAL;
+ 
+ 	for (i = 0; i < larb_nr; i++) {
+ 		u32 id;
+ 
+ 		larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
+-		if (!larbnode)
+-			return -EINVAL;
++		if (!larbnode) {
++			ret = -EINVAL;
++			goto err_larbdev_put;
++		}
+ 
+ 		if (!of_device_is_available(larbnode)) {
+ 			of_node_put(larbnode);
+@@ -1064,20 +1068,32 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
+ 		ret = of_property_read_u32(larbnode, "mediatek,larb-id", &id);
+ 		if (ret)/* The id is consecutive if there is no this property */
+ 			id = i;
++		if (id >= MTK_LARB_NR_MAX) {
++			of_node_put(larbnode);
++			ret = -EINVAL;
++			goto err_larbdev_put;
++		}
+ 
+ 		plarbdev = of_find_device_by_node(larbnode);
++		of_node_put(larbnode);
+ 		if (!plarbdev) {
+-			of_node_put(larbnode);
+-			return -ENODEV;
++			ret = -ENODEV;
++			goto err_larbdev_put;
+ 		}
+-		if (!plarbdev->dev.driver) {
+-			of_node_put(larbnode);
+-			return -EPROBE_DEFER;
++		if (data->larb_imu[id].dev) {
++			platform_device_put(plarbdev);
++			ret = -EEXIST;
++			goto err_larbdev_put;
+ 		}
+ 		data->larb_imu[id].dev = &plarbdev->dev;
+ 
+-		component_match_add_release(dev, match, component_release_of,
+-					    component_compare_of, larbnode);
++		if (!plarbdev->dev.driver) {
++			ret = -EPROBE_DEFER;
++			goto err_larbdev_put;
++		}
++
++		component_match_add(dev, match, component_compare_dev, &plarbdev->dev);
++		platform_device_put(plarbdev);
+ 	}
+ 
+ 	/* Get smi-(sub)-common dev from the last larb. */
+@@ -1095,17 +1111,28 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
+ 	else
+ 		smicomm_node = smi_subcomm_node;
+ 
+-	plarbdev = of_find_device_by_node(smicomm_node);
++	pcommdev = of_find_device_by_node(smicomm_node);
+ 	of_node_put(smicomm_node);
+-	data->smicomm_dev = &plarbdev->dev;
++	if (!pcommdev)
++		return -ENODEV;
++	data->smicomm_dev = &pcommdev->dev;
+ 
+ 	link = device_link_add(data->smicomm_dev, dev,
+ 			       DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
++	platform_device_put(pcommdev);
+ 	if (!link) {
+ 		dev_err(dev, "Unable to link %s.\n", dev_name(data->smicomm_dev));
+ 		return -EINVAL;
+ 	}
+ 	return 0;
++
++err_larbdev_put:
++	for (i = MTK_LARB_NR_MAX - 1; i >= 0; i--) {
++		if (!data->larb_imu[i].dev)
++			continue;
++		put_device(data->larb_imu[i].dev);
++	}
++	return ret;
+ }
+ 
+ static int mtk_iommu_probe(struct platform_device *pdev)
+@@ -1170,6 +1197,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
+ 
+ 	banks_num = data->plat_data->banks_num;
+ 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res)
++		return -EINVAL;
+ 	if (resource_size(res) < banks_num * MTK_IOMMU_BANK_SZ) {
+ 		dev_err(dev, "banknr %d. res %pR is not enough.\n", banks_num, res);
+ 		return -EINVAL;
+diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
+index ab57c4b8fade2..a0652e9a7db34 100644
+--- a/drivers/iommu/rockchip-iommu.c
++++ b/drivers/iommu/rockchip-iommu.c
+@@ -280,19 +280,17 @@ static u32 rk_mk_pte(phys_addr_t page, int prot)
+  *  11:9 - Page address bit 34:32
+  *   8:4 - Page address bit 39:35
+  *     3 - Security
+- *     2 - Readable
+- *     1 - Writable
++ *     2 - Writable
++ *     1 - Readable
+  *     0 - 1 if Page @ Page address is valid
+  */
+-#define RK_PTE_PAGE_READABLE_V2      BIT(2)
+-#define RK_PTE_PAGE_WRITABLE_V2      BIT(1)
+ 
+ static u32 rk_mk_pte_v2(phys_addr_t page, int prot)
+ {
+ 	u32 flags = 0;
+ 
+-	flags |= (prot & IOMMU_READ) ? RK_PTE_PAGE_READABLE_V2 : 0;
+-	flags |= (prot & IOMMU_WRITE) ? RK_PTE_PAGE_WRITABLE_V2 : 0;
++	flags |= (prot & IOMMU_READ) ? RK_PTE_PAGE_READABLE : 0;
++	flags |= (prot & IOMMU_WRITE) ? RK_PTE_PAGE_WRITABLE : 0;
+ 
+ 	return rk_mk_dte_v2(page) | flags;
+ }
+diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
+index c898bcbbce118..96173cfee3249 100644
+--- a/drivers/iommu/s390-iommu.c
++++ b/drivers/iommu/s390-iommu.c
+@@ -79,10 +79,36 @@ static void s390_domain_free(struct iommu_domain *domain)
+ {
+ 	struct s390_domain *s390_domain = to_s390_domain(domain);
+ 
++	WARN_ON(!list_empty(&s390_domain->devices));
+ 	dma_cleanup_tables(s390_domain->dma_table);
+ 	kfree(s390_domain);
+ }
+ 
++static void __s390_iommu_detach_device(struct zpci_dev *zdev)
++{
++	struct s390_domain *s390_domain = zdev->s390_domain;
++	struct s390_domain_device *domain_device, *tmp;
++	unsigned long flags;
++
++	if (!s390_domain)
++		return;
++
++	spin_lock_irqsave(&s390_domain->list_lock, flags);
++	list_for_each_entry_safe(domain_device, tmp, &s390_domain->devices,
++				 list) {
++		if (domain_device->zdev == zdev) {
++			list_del(&domain_device->list);
++			kfree(domain_device);
++			break;
++		}
++	}
++	spin_unlock_irqrestore(&s390_domain->list_lock, flags);
++
++	zpci_unregister_ioat(zdev, 0);
++	zdev->s390_domain = NULL;
++	zdev->dma_table = NULL;
++}
++
+ static int s390_iommu_attach_device(struct iommu_domain *domain,
+ 				    struct device *dev)
+ {
+@@ -90,7 +116,7 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
+ 	struct zpci_dev *zdev = to_zpci_dev(dev);
+ 	struct s390_domain_device *domain_device;
+ 	unsigned long flags;
+-	int cc, rc;
++	int cc, rc = 0;
+ 
+ 	if (!zdev)
+ 		return -ENODEV;
+@@ -99,24 +125,18 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
+ 	if (!domain_device)
+ 		return -ENOMEM;
+ 
+-	if (zdev->dma_table && !zdev->s390_domain) {
+-		cc = zpci_dma_exit_device(zdev);
+-		if (cc) {
+-			rc = -EIO;
+-			goto out_free;
+-		}
+-	}
+-
+ 	if (zdev->s390_domain)
+-		zpci_unregister_ioat(zdev, 0);
++		__s390_iommu_detach_device(zdev);
++	else if (zdev->dma_table)
++		zpci_dma_exit_device(zdev);
+ 
+-	zdev->dma_table = s390_domain->dma_table;
+ 	cc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
+-				virt_to_phys(zdev->dma_table));
++				virt_to_phys(s390_domain->dma_table));
+ 	if (cc) {
+ 		rc = -EIO;
+-		goto out_restore;
++		goto out_free;
+ 	}
++	zdev->dma_table = s390_domain->dma_table;
+ 
+ 	spin_lock_irqsave(&s390_domain->list_lock, flags);
+ 	/* First device defines the DMA range limits */
+@@ -127,9 +147,9 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
+ 	/* Allow only devices with identical DMA range limits */
+ 	} else if (domain->geometry.aperture_start != zdev->start_dma ||
+ 		   domain->geometry.aperture_end != zdev->end_dma) {
+-		rc = -EINVAL;
+ 		spin_unlock_irqrestore(&s390_domain->list_lock, flags);
+-		goto out_restore;
++		rc = -EINVAL;
++		goto out_unregister;
+ 	}
+ 	domain_device->zdev = zdev;
+ 	zdev->s390_domain = s390_domain;
+@@ -138,14 +158,9 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
+ 
+ 	return 0;
+ 
+-out_restore:
+-	if (!zdev->s390_domain) {
+-		zpci_dma_init_device(zdev);
+-	} else {
+-		zdev->dma_table = zdev->s390_domain->dma_table;
+-		zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
+-				   virt_to_phys(zdev->dma_table));
+-	}
++out_unregister:
++	zpci_unregister_ioat(zdev, 0);
++	zdev->dma_table = NULL;
+ out_free:
+ 	kfree(domain_device);
+ 
+@@ -155,32 +170,12 @@ out_free:
+ static void s390_iommu_detach_device(struct iommu_domain *domain,
+ 				     struct device *dev)
+ {
+-	struct s390_domain *s390_domain = to_s390_domain(domain);
+ 	struct zpci_dev *zdev = to_zpci_dev(dev);
+-	struct s390_domain_device *domain_device, *tmp;
+-	unsigned long flags;
+-	int found = 0;
+ 
+-	if (!zdev)
+-		return;
++	WARN_ON(zdev->s390_domain != to_s390_domain(domain));
+ 
+-	spin_lock_irqsave(&s390_domain->list_lock, flags);
+-	list_for_each_entry_safe(domain_device, tmp, &s390_domain->devices,
+-				 list) {
+-		if (domain_device->zdev == zdev) {
+-			list_del(&domain_device->list);
+-			kfree(domain_device);
+-			found = 1;
+-			break;
+-		}
+-	}
+-	spin_unlock_irqrestore(&s390_domain->list_lock, flags);
+-
+-	if (found && (zdev->s390_domain == s390_domain)) {
+-		zdev->s390_domain = NULL;
+-		zpci_unregister_ioat(zdev, 0);
+-		zpci_dma_init_device(zdev);
+-	}
++	__s390_iommu_detach_device(zdev);
++	zpci_dma_init_device(zdev);
+ }
+ 
+ static struct iommu_device *s390_iommu_probe_device(struct device *dev)
+@@ -193,24 +188,13 @@ static struct iommu_device *s390_iommu_probe_device(struct device *dev)
+ static void s390_iommu_release_device(struct device *dev)
+ {
+ 	struct zpci_dev *zdev = to_zpci_dev(dev);
+-	struct iommu_domain *domain;
+ 
+ 	/*
+-	 * This is a workaround for a scenario where the IOMMU API common code
+-	 * "forgets" to call the detach_dev callback: After binding a device
+-	 * to vfio-pci and completing the VFIO_SET_IOMMU ioctl (which triggers
+-	 * the attach_dev), removing the device via
+-	 * "echo 1 > /sys/bus/pci/devices/.../remove" won't trigger detach_dev,
+-	 * only release_device will be called via the BUS_NOTIFY_REMOVED_DEVICE
+-	 * notifier.
+-	 *
+-	 * So let's call detach_dev from here if it hasn't been called before.
++	 * release_device is expected to detach any domain currently attached
++	 * to the device, but keep it attached to other devices in the group.
+ 	 */
+-	if (zdev && zdev->s390_domain) {
+-		domain = iommu_get_domain_for_dev(dev);
+-		if (domain)
+-			s390_iommu_detach_device(domain, dev);
+-	}
++	if (zdev)
++		__s390_iommu_detach_device(zdev);
+ }
+ 
+ static int s390_iommu_update_trans(struct s390_domain *s390_domain,
+diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c
+index a84c63518773a..1d81a6aa939bf 100644
+--- a/drivers/iommu/sun50i-iommu.c
++++ b/drivers/iommu/sun50i-iommu.c
+@@ -27,6 +27,7 @@
+ #include <linux/types.h>
+ 
+ #define IOMMU_RESET_REG			0x010
++#define IOMMU_RESET_RELEASE_ALL			0xffffffff
+ #define IOMMU_ENABLE_REG		0x020
+ #define IOMMU_ENABLE_ENABLE			BIT(0)
+ 
+@@ -92,6 +93,8 @@
+ #define NUM_PT_ENTRIES			256
+ #define PT_SIZE				(NUM_PT_ENTRIES * PT_ENTRY_SIZE)
+ 
++#define SPAGE_SIZE			4096
++
+ struct sun50i_iommu {
+ 	struct iommu_device iommu;
+ 
+@@ -270,7 +273,7 @@ static u32 sun50i_mk_pte(phys_addr_t page, int prot)
+ 	enum sun50i_iommu_aci aci;
+ 	u32 flags = 0;
+ 
+-	if (prot & (IOMMU_READ | IOMMU_WRITE))
++	if ((prot & (IOMMU_READ | IOMMU_WRITE)) == (IOMMU_READ | IOMMU_WRITE))
+ 		aci = SUN50I_IOMMU_ACI_RD_WR;
+ 	else if (prot & IOMMU_READ)
+ 		aci = SUN50I_IOMMU_ACI_RD;
+@@ -294,6 +297,62 @@ static void sun50i_table_flush(struct sun50i_iommu_domain *sun50i_domain,
+ 	dma_sync_single_for_device(iommu->dev, dma, size, DMA_TO_DEVICE);
+ }
+ 
++static void sun50i_iommu_zap_iova(struct sun50i_iommu *iommu,
++				  unsigned long iova)
++{
++	u32 reg;
++	int ret;
++
++	iommu_write(iommu, IOMMU_TLB_IVLD_ADDR_REG, iova);
++	iommu_write(iommu, IOMMU_TLB_IVLD_ADDR_MASK_REG, GENMASK(31, 12));
++	iommu_write(iommu, IOMMU_TLB_IVLD_ENABLE_REG,
++		    IOMMU_TLB_IVLD_ENABLE_ENABLE);
++
++	ret = readl_poll_timeout_atomic(iommu->base + IOMMU_TLB_IVLD_ENABLE_REG,
++					reg, !reg, 1, 2000);
++	if (ret)
++		dev_warn(iommu->dev, "TLB invalidation timed out!\n");
++}
++
++static void sun50i_iommu_zap_ptw_cache(struct sun50i_iommu *iommu,
++				       unsigned long iova)
++{
++	u32 reg;
++	int ret;
++
++	iommu_write(iommu, IOMMU_PC_IVLD_ADDR_REG, iova);
++	iommu_write(iommu, IOMMU_PC_IVLD_ENABLE_REG,
++		    IOMMU_PC_IVLD_ENABLE_ENABLE);
++
++	ret = readl_poll_timeout_atomic(iommu->base + IOMMU_PC_IVLD_ENABLE_REG,
++					reg, !reg, 1, 2000);
++	if (ret)
++		dev_warn(iommu->dev, "PTW cache invalidation timed out!\n");
++}
++
++static void sun50i_iommu_zap_range(struct sun50i_iommu *iommu,
++				   unsigned long iova, size_t size)
++{
++	assert_spin_locked(&iommu->iommu_lock);
++
++	iommu_write(iommu, IOMMU_AUTO_GATING_REG, 0);
++
++	sun50i_iommu_zap_iova(iommu, iova);
++	sun50i_iommu_zap_iova(iommu, iova + SPAGE_SIZE);
++	if (size > SPAGE_SIZE) {
++		sun50i_iommu_zap_iova(iommu, iova + size);
++		sun50i_iommu_zap_iova(iommu, iova + size + SPAGE_SIZE);
++	}
++	sun50i_iommu_zap_ptw_cache(iommu, iova);
++	sun50i_iommu_zap_ptw_cache(iommu, iova + SZ_1M);
++	if (size > SZ_1M) {
++		sun50i_iommu_zap_ptw_cache(iommu, iova + size);
++		sun50i_iommu_zap_ptw_cache(iommu, iova + size + SZ_1M);
++	}
++
++	iommu_write(iommu, IOMMU_AUTO_GATING_REG, IOMMU_AUTO_GATING_ENABLE);
++}
++
+ static int sun50i_iommu_flush_all_tlb(struct sun50i_iommu *iommu)
+ {
+ 	u32 reg;
+@@ -343,6 +402,18 @@ static void sun50i_iommu_flush_iotlb_all(struct iommu_domain *domain)
+ 	spin_unlock_irqrestore(&iommu->iommu_lock, flags);
+ }
+ 
++static void sun50i_iommu_iotlb_sync_map(struct iommu_domain *domain,
++					unsigned long iova, size_t size)
++{
++	struct sun50i_iommu_domain *sun50i_domain = to_sun50i_domain(domain);
++	struct sun50i_iommu *iommu = sun50i_domain->iommu;
++	unsigned long flags;
++
++	spin_lock_irqsave(&iommu->iommu_lock, flags);
++	sun50i_iommu_zap_range(iommu, iova, size);
++	spin_unlock_irqrestore(&iommu->iommu_lock, flags);
++}
++
+ static void sun50i_iommu_iotlb_sync(struct iommu_domain *domain,
+ 				    struct iommu_iotlb_gather *gather)
+ {
+@@ -511,7 +582,7 @@ static u32 *sun50i_dte_get_page_table(struct sun50i_iommu_domain *sun50i_domain,
+ 		sun50i_iommu_free_page_table(iommu, drop_pt);
+ 	}
+ 
+-	sun50i_table_flush(sun50i_domain, page_table, PT_SIZE);
++	sun50i_table_flush(sun50i_domain, page_table, NUM_PT_ENTRIES);
+ 	sun50i_table_flush(sun50i_domain, dte_addr, 1);
+ 
+ 	return page_table;
+@@ -601,7 +672,6 @@ static struct iommu_domain *sun50i_iommu_domain_alloc(unsigned type)
+ 	struct sun50i_iommu_domain *sun50i_domain;
+ 
+ 	if (type != IOMMU_DOMAIN_DMA &&
+-	    type != IOMMU_DOMAIN_IDENTITY &&
+ 	    type != IOMMU_DOMAIN_UNMANAGED)
+ 		return NULL;
+ 
+@@ -766,6 +836,7 @@ static const struct iommu_ops sun50i_iommu_ops = {
+ 		.attach_dev	= sun50i_iommu_attach_device,
+ 		.detach_dev	= sun50i_iommu_detach_device,
+ 		.flush_iotlb_all = sun50i_iommu_flush_iotlb_all,
++		.iotlb_sync_map = sun50i_iommu_iotlb_sync_map,
+ 		.iotlb_sync	= sun50i_iommu_iotlb_sync,
+ 		.iova_to_phys	= sun50i_iommu_iova_to_phys,
+ 		.map		= sun50i_iommu_map,
+@@ -785,6 +856,8 @@ static void sun50i_iommu_report_fault(struct sun50i_iommu *iommu,
+ 		report_iommu_fault(iommu->domain, iommu->dev, iova, prot);
+ 	else
+ 		dev_err(iommu->dev, "Page fault while iommu not attached to any domain?\n");
++
++	sun50i_iommu_zap_range(iommu, iova, SPAGE_SIZE);
+ }
+ 
+ static phys_addr_t sun50i_iommu_handle_pt_irq(struct sun50i_iommu *iommu,
+@@ -868,8 +941,8 @@ static phys_addr_t sun50i_iommu_handle_perm_irq(struct sun50i_iommu *iommu)
+ 
+ static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id)
+ {
++	u32 status, l1_status, l2_status, resets;
+ 	struct sun50i_iommu *iommu = dev_id;
+-	u32 status;
+ 
+ 	spin_lock(&iommu->iommu_lock);
+ 
+@@ -879,6 +952,9 @@ static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id)
+ 		return IRQ_NONE;
+ 	}
+ 
++	l1_status = iommu_read(iommu, IOMMU_L1PG_INT_REG);
++	l2_status = iommu_read(iommu, IOMMU_L2PG_INT_REG);
++
+ 	if (status & IOMMU_INT_INVALID_L2PG)
+ 		sun50i_iommu_handle_pt_irq(iommu,
+ 					    IOMMU_INT_ERR_ADDR_L2_REG,
+@@ -892,8 +968,9 @@ static irqreturn_t sun50i_iommu_irq(int irq, void *dev_id)
+ 
+ 	iommu_write(iommu, IOMMU_INT_CLR_REG, status);
+ 
+-	iommu_write(iommu, IOMMU_RESET_REG, ~status);
+-	iommu_write(iommu, IOMMU_RESET_REG, status);
++	resets = (status | l1_status | l2_status) & IOMMU_INT_MASTER_MASK;
++	iommu_write(iommu, IOMMU_RESET_REG, ~resets);
++	iommu_write(iommu, IOMMU_RESET_REG, IOMMU_RESET_RELEASE_ALL);
+ 
+ 	spin_unlock(&iommu->iommu_lock);
+ 
+diff --git a/drivers/irqchip/irq-gic-pm.c b/drivers/irqchip/irq-gic-pm.c
+index b60e1853593f4..3989d16f997b3 100644
+--- a/drivers/irqchip/irq-gic-pm.c
++++ b/drivers/irqchip/irq-gic-pm.c
+@@ -102,7 +102,7 @@ static int gic_probe(struct platform_device *pdev)
+ 
+ 	pm_runtime_enable(dev);
+ 
+-	ret = pm_runtime_get_sync(dev);
++	ret = pm_runtime_resume_and_get(dev);
+ 	if (ret < 0)
+ 		goto rpm_disable;
+ 
+diff --git a/drivers/irqchip/irq-loongson-liointc.c b/drivers/irqchip/irq-loongson-liointc.c
+index 0da8716f8f24b..c4584e2f0ad3d 100644
+--- a/drivers/irqchip/irq-loongson-liointc.c
++++ b/drivers/irqchip/irq-loongson-liointc.c
+@@ -207,10 +207,13 @@ static int liointc_init(phys_addr_t addr, unsigned long size, int revision,
+ 					"reg-names", core_reg_names[i]);
+ 
+ 			if (index < 0)
+-				goto out_iounmap;
++				continue;
+ 
+ 			priv->core_isr[i] = of_iomap(node, index);
+ 		}
++
++		if (!priv->core_isr[0])
++			goto out_iounmap;
+ 	}
+ 
+ 	/* Setup IRQ domain */
+diff --git a/drivers/irqchip/irq-loongson-pch-pic.c b/drivers/irqchip/irq-loongson-pch-pic.c
+index c01b9c2570053..03493cda65a37 100644
+--- a/drivers/irqchip/irq-loongson-pch-pic.c
++++ b/drivers/irqchip/irq-loongson-pch-pic.c
+@@ -159,6 +159,9 @@ static int pch_pic_domain_translate(struct irq_domain *d,
+ 		return -EINVAL;
+ 
+ 	if (of_node) {
++		if (fwspec->param_count < 2)
++			return -EINVAL;
++
+ 		*hwirq = fwspec->param[0] + priv->ht_vec_base;
+ 		*type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
+ 	} else {
+diff --git a/drivers/irqchip/irq-wpcm450-aic.c b/drivers/irqchip/irq-wpcm450-aic.c
+index 0dcbeb1a05a1f..91df62a64cd91 100644
+--- a/drivers/irqchip/irq-wpcm450-aic.c
++++ b/drivers/irqchip/irq-wpcm450-aic.c
+@@ -146,6 +146,7 @@ static int __init wpcm450_aic_of_init(struct device_node *node,
+ 	aic->regs = of_iomap(node, 0);
+ 	if (!aic->regs) {
+ 		pr_err("Failed to map WPCM450 AIC registers\n");
++		kfree(aic);
+ 		return -ENOMEM;
+ 	}
+ 
+diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
+index 4f7eaa17fb274..e840609c50eb7 100644
+--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
++++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
+@@ -3217,6 +3217,7 @@ static int
+ hfcm_l1callback(struct dchannel *dch, u_int cmd)
+ {
+ 	struct hfc_multi	*hc = dch->hw;
++	struct sk_buff_head	free_queue;
+ 	u_long	flags;
+ 
+ 	switch (cmd) {
+@@ -3245,6 +3246,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
+ 		l1_event(dch->l1, HW_POWERUP_IND);
+ 		break;
+ 	case HW_DEACT_REQ:
++		__skb_queue_head_init(&free_queue);
+ 		/* start deactivation */
+ 		spin_lock_irqsave(&hc->lock, flags);
+ 		if (hc->ctype == HFC_TYPE_E1) {
+@@ -3264,20 +3266,21 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
+ 				plxsd_checksync(hc, 0);
+ 			}
+ 		}
+-		skb_queue_purge(&dch->squeue);
++		skb_queue_splice_init(&dch->squeue, &free_queue);
+ 		if (dch->tx_skb) {
+-			dev_kfree_skb(dch->tx_skb);
++			__skb_queue_tail(&free_queue, dch->tx_skb);
+ 			dch->tx_skb = NULL;
+ 		}
+ 		dch->tx_idx = 0;
+ 		if (dch->rx_skb) {
+-			dev_kfree_skb(dch->rx_skb);
++			__skb_queue_tail(&free_queue, dch->rx_skb);
+ 			dch->rx_skb = NULL;
+ 		}
+ 		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+ 		if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
+ 			del_timer(&dch->timer);
+ 		spin_unlock_irqrestore(&hc->lock, flags);
++		__skb_queue_purge(&free_queue);
+ 		break;
+ 	case HW_POWERUP_REQ:
+ 		spin_lock_irqsave(&hc->lock, flags);
+@@ -3384,6 +3387,9 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
+ 	case PH_DEACTIVATE_REQ:
+ 		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
+ 		if (dch->dev.D.protocol != ISDN_P_TE_S0) {
++			struct sk_buff_head free_queue;
++
++			__skb_queue_head_init(&free_queue);
+ 			spin_lock_irqsave(&hc->lock, flags);
+ 			if (debug & DEBUG_HFCMULTI_MSG)
+ 				printk(KERN_DEBUG
+@@ -3405,14 +3411,14 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
+ 				/* deactivate */
+ 				dch->state = 1;
+ 			}
+-			skb_queue_purge(&dch->squeue);
++			skb_queue_splice_init(&dch->squeue, &free_queue);
+ 			if (dch->tx_skb) {
+-				dev_kfree_skb(dch->tx_skb);
++				__skb_queue_tail(&free_queue, dch->tx_skb);
+ 				dch->tx_skb = NULL;
+ 			}
+ 			dch->tx_idx = 0;
+ 			if (dch->rx_skb) {
+-				dev_kfree_skb(dch->rx_skb);
++				__skb_queue_tail(&free_queue, dch->rx_skb);
+ 				dch->rx_skb = NULL;
+ 			}
+ 			test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+@@ -3424,6 +3430,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
+ #endif
+ 			ret = 0;
+ 			spin_unlock_irqrestore(&hc->lock, flags);
++			__skb_queue_purge(&free_queue);
+ 		} else
+ 			ret = l1_event(dch->l1, hh->prim);
+ 		break;
+diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
+index af17459c1a5c0..eba58b99cd29d 100644
+--- a/drivers/isdn/hardware/mISDN/hfcpci.c
++++ b/drivers/isdn/hardware/mISDN/hfcpci.c
+@@ -1617,16 +1617,19 @@ hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
+ 		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
+ 		spin_lock_irqsave(&hc->lock, flags);
+ 		if (hc->hw.protocol == ISDN_P_NT_S0) {
++			struct sk_buff_head free_queue;
++
++			__skb_queue_head_init(&free_queue);
+ 			/* prepare deactivation */
+ 			Write_hfc(hc, HFCPCI_STATES, 0x40);
+-			skb_queue_purge(&dch->squeue);
++			skb_queue_splice_init(&dch->squeue, &free_queue);
+ 			if (dch->tx_skb) {
+-				dev_kfree_skb(dch->tx_skb);
++				__skb_queue_tail(&free_queue, dch->tx_skb);
+ 				dch->tx_skb = NULL;
+ 			}
+ 			dch->tx_idx = 0;
+ 			if (dch->rx_skb) {
+-				dev_kfree_skb(dch->rx_skb);
++				__skb_queue_tail(&free_queue, dch->rx_skb);
+ 				dch->rx_skb = NULL;
+ 			}
+ 			test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+@@ -1639,10 +1642,12 @@ hfcpci_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
+ 			hc->hw.mst_m &= ~HFCPCI_MASTER;
+ 			Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
+ 			ret = 0;
++			spin_unlock_irqrestore(&hc->lock, flags);
++			__skb_queue_purge(&free_queue);
+ 		} else {
+ 			ret = l1_event(dch->l1, hh->prim);
++			spin_unlock_irqrestore(&hc->lock, flags);
+ 		}
+-		spin_unlock_irqrestore(&hc->lock, flags);
+ 		break;
+ 	}
+ 	if (!ret)
+diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
+index 651f2f8f685b7..1efd17979f240 100644
+--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
++++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
+@@ -326,20 +326,24 @@ hfcusb_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
+ 		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
+ 
+ 		if (hw->protocol == ISDN_P_NT_S0) {
++			struct sk_buff_head free_queue;
++
++			__skb_queue_head_init(&free_queue);
+ 			hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT);
+ 			spin_lock_irqsave(&hw->lock, flags);
+-			skb_queue_purge(&dch->squeue);
++			skb_queue_splice_init(&dch->squeue, &free_queue);
+ 			if (dch->tx_skb) {
+-				dev_kfree_skb(dch->tx_skb);
++				__skb_queue_tail(&free_queue, dch->tx_skb);
+ 				dch->tx_skb = NULL;
+ 			}
+ 			dch->tx_idx = 0;
+ 			if (dch->rx_skb) {
+-				dev_kfree_skb(dch->rx_skb);
++				__skb_queue_tail(&free_queue, dch->rx_skb);
+ 				dch->rx_skb = NULL;
+ 			}
+ 			test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+ 			spin_unlock_irqrestore(&hw->lock, flags);
++			__skb_queue_purge(&free_queue);
+ #ifdef FIXME
+ 			if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
+ 				dchannel_sched_event(&hc->dch, D_CLEARBUSY);
+@@ -1330,7 +1334,7 @@ tx_iso_complete(struct urb *urb)
+ 					printk("\n");
+ 				}
+ 
+-				dev_kfree_skb(tx_skb);
++				dev_consume_skb_irq(tx_skb);
+ 				tx_skb = NULL;
+ 				if (fifo->dch && get_next_dframe(fifo->dch))
+ 					tx_skb = fifo->dch->tx_skb;
+diff --git a/drivers/leds/leds-is31fl319x.c b/drivers/leds/leds-is31fl319x.c
+index 52b59b62f437c..b2f4c4ec7c567 100644
+--- a/drivers/leds/leds-is31fl319x.c
++++ b/drivers/leds/leds-is31fl319x.c
+@@ -38,6 +38,7 @@
+ #define IS31FL3190_CURRENT_uA_MIN	5000
+ #define IS31FL3190_CURRENT_uA_DEFAULT	42000
+ #define IS31FL3190_CURRENT_uA_MAX	42000
++#define IS31FL3190_CURRENT_SHIFT	2
+ #define IS31FL3190_CURRENT_MASK		GENMASK(4, 2)
+ #define IS31FL3190_CURRENT_5_mA		0x02
+ #define IS31FL3190_CURRENT_10_mA	0x01
+@@ -553,7 +554,7 @@ static int is31fl319x_probe(struct i2c_client *client)
+ 			     is31fl3196_db_to_gain(is31->audio_gain_db));
+ 	else
+ 		regmap_update_bits(is31->regmap, IS31FL3190_CURRENT, IS31FL3190_CURRENT_MASK,
+-				   is31fl3190_microamp_to_cs(dev, aggregated_led_microamp));
++				   is31fl3190_microamp_to_cs(dev, aggregated_led_microamp) << IS31FL3190_CURRENT_SHIFT);
+ 
+ 	for (i = 0; i < is31->cdef->num_leds; i++) {
+ 		struct is31fl319x_led *led = &is31->leds[i];
+diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
+index 02f51cc618376..c1a56259226fb 100644
+--- a/drivers/leds/rgb/leds-qcom-lpg.c
++++ b/drivers/leds/rgb/leds-qcom-lpg.c
+@@ -602,8 +602,8 @@ static void lpg_brightness_set(struct lpg_led *led, struct led_classdev *cdev,
+ 		lpg_lut_sync(lpg, lut_mask);
+ }
+ 
+-static void lpg_brightness_single_set(struct led_classdev *cdev,
+-				      enum led_brightness value)
++static int lpg_brightness_single_set(struct led_classdev *cdev,
++				     enum led_brightness value)
+ {
+ 	struct lpg_led *led = container_of(cdev, struct lpg_led, cdev);
+ 	struct mc_subled info;
+@@ -614,10 +614,12 @@ static void lpg_brightness_single_set(struct led_classdev *cdev,
+ 	lpg_brightness_set(led, cdev, &info);
+ 
+ 	mutex_unlock(&led->lpg->lock);
++
++	return 0;
+ }
+ 
+-static void lpg_brightness_mc_set(struct led_classdev *cdev,
+-				  enum led_brightness value)
++static int lpg_brightness_mc_set(struct led_classdev *cdev,
++				 enum led_brightness value)
+ {
+ 	struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
+ 	struct lpg_led *led = container_of(mc, struct lpg_led, mcdev);
+@@ -628,6 +630,8 @@ static void lpg_brightness_mc_set(struct led_classdev *cdev,
+ 	lpg_brightness_set(led, cdev, mc->subled_info);
+ 
+ 	mutex_unlock(&led->lpg->lock);
++
++	return 0;
+ }
+ 
+ static int lpg_blink_set(struct lpg_led *led,
+@@ -1118,7 +1122,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
+ 		led->mcdev.num_colors = num_channels;
+ 
+ 		cdev = &led->mcdev.led_cdev;
+-		cdev->brightness_set = lpg_brightness_mc_set;
++		cdev->brightness_set_blocking = lpg_brightness_mc_set;
+ 		cdev->blink_set = lpg_blink_mc_set;
+ 
+ 		/* Register pattern accessors only if we have a LUT block */
+@@ -1132,7 +1136,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
+ 			return ret;
+ 
+ 		cdev = &led->cdev;
+-		cdev->brightness_set = lpg_brightness_single_set;
++		cdev->brightness_set_blocking = lpg_brightness_single_set;
+ 		cdev->blink_set = lpg_blink_single_set;
+ 
+ 		/* Register pattern accessors only if we have a LUT block */
+@@ -1151,7 +1155,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
+ 	else
+ 		cdev->brightness = LED_OFF;
+ 
+-	cdev->brightness_set(cdev, cdev->brightness);
++	cdev->brightness_set_blocking(cdev, cdev->brightness);
+ 
+ 	init_data.fwnode = of_fwnode_handle(np);
+ 
+diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c
+index 9b63bd2551c63..cd4e34d15c26b 100644
+--- a/drivers/macintosh/macio-adb.c
++++ b/drivers/macintosh/macio-adb.c
+@@ -108,6 +108,10 @@ int macio_init(void)
+ 		return -ENXIO;
+ 	}
+ 	adb = ioremap(r.start, sizeof(struct adb_regs));
++	if (!adb) {
++		of_node_put(adbs);
++		return -ENOMEM;
++	}
+ 
+ 	out_8(&adb->ctrl.r, 0);
+ 	out_8(&adb->intr.r, 0);
+diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
+index 1ec1e5984563f..3bc1f374e6577 100644
+--- a/drivers/macintosh/macio_asic.c
++++ b/drivers/macintosh/macio_asic.c
+@@ -424,7 +424,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip,
+ 	if (of_device_register(&dev->ofdev) != 0) {
+ 		printk(KERN_DEBUG"macio: device registration error for %s!\n",
+ 		       dev_name(&dev->ofdev.dev));
+-		kfree(dev);
++		put_device(&dev->ofdev.dev);
+ 		return NULL;
+ 	}
+ 
+diff --git a/drivers/mailbox/arm_mhuv2.c b/drivers/mailbox/arm_mhuv2.c
+index a47aef8df52fd..c6d4957c4da83 100644
+--- a/drivers/mailbox/arm_mhuv2.c
++++ b/drivers/mailbox/arm_mhuv2.c
+@@ -1062,8 +1062,8 @@ static int mhuv2_probe(struct amba_device *adev, const struct amba_id *id)
+ 	int ret = -EINVAL;
+ 
+ 	reg = devm_of_iomap(dev, dev->of_node, 0, NULL);
+-	if (!reg)
+-		return -ENOMEM;
++	if (IS_ERR(reg))
++		return PTR_ERR(reg);
+ 
+ 	mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL);
+ 	if (!mhu)
+diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c
+index cfacb3f320a64..853901acaeec2 100644
+--- a/drivers/mailbox/mailbox-mpfs.c
++++ b/drivers/mailbox/mailbox-mpfs.c
+@@ -2,7 +2,7 @@
+ /*
+  * Microchip PolarFire SoC (MPFS) system controller/mailbox controller driver
+  *
+- * Copyright (c) 2020 Microchip Corporation. All rights reserved.
++ * Copyright (c) 2020-2022 Microchip Corporation. All rights reserved.
+  *
+  * Author: Conor Dooley <conor.dooley@microchip.com>
+  *
+@@ -56,7 +56,7 @@
+ #define SCB_STATUS_NOTIFY_MASK BIT(SCB_STATUS_NOTIFY)
+ 
+ #define SCB_STATUS_POS (16)
+-#define SCB_STATUS_MASK GENMASK_ULL(SCB_STATUS_POS + SCB_MASK_WIDTH, SCB_STATUS_POS)
++#define SCB_STATUS_MASK GENMASK(SCB_STATUS_POS + SCB_MASK_WIDTH - 1, SCB_STATUS_POS)
+ 
+ struct mpfs_mbox {
+ 	struct mbox_controller controller;
+@@ -130,13 +130,38 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan)
+ 	struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
+ 	struct mpfs_mss_response *response = mbox->response;
+ 	u16 num_words = ALIGN((response->resp_size), (4)) / 4U;
+-	u32 i;
++	u32 i, status;
+ 
+ 	if (!response->resp_msg) {
+ 		dev_err(mbox->dev, "failed to assign memory for response %d\n", -ENOMEM);
+ 		return;
+ 	}
+ 
++	/*
++	 * The status is stored in bits 31:16 of the SERVICES_SR register.
++	 * It is only valid when BUSY == 0.
++	 * We should *never* get an interrupt while the controller is
++	 * still in the busy state. If we do, something has gone badly
++	 * wrong & the content of the mailbox would not be valid.
++	 */
++	if (mpfs_mbox_busy(mbox)) {
++		dev_err(mbox->dev, "got an interrupt but system controller is busy\n");
++		response->resp_status = 0xDEAD;
++		return;
++	}
++
++	status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET);
++
++	/*
++	 * If the status of the individual servers is non-zero, the service has
++	 * failed. The contents of the mailbox at this point are not be valid,
++	 * so don't bother reading them. Set the status so that the driver
++	 * implementing the service can handle the result.
++	 */
++	response->resp_status = (status & SCB_STATUS_MASK) >> SCB_STATUS_POS;
++	if (response->resp_status)
++		return;
++
+ 	if (!mpfs_mbox_busy(mbox)) {
+ 		for (i = 0; i < num_words; i++) {
+ 			response->resp_msg[i] =
+diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
+index ebfa33a40fceb..5e232b3fb72a9 100644
+--- a/drivers/mailbox/pcc.c
++++ b/drivers/mailbox/pcc.c
+@@ -743,6 +743,7 @@ static int __init pcc_init(void)
+ 
+ 	if (IS_ERR(pcc_pdev)) {
+ 		pr_debug("Err creating PCC platform bundle\n");
++		pcc_chan_count = 0;
+ 		return PTR_ERR(pcc_pdev);
+ 	}
+ 
+diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c
+index 31a0fa9142744..12e004ff1a147 100644
+--- a/drivers/mailbox/zynqmp-ipi-mailbox.c
++++ b/drivers/mailbox/zynqmp-ipi-mailbox.c
+@@ -493,6 +493,7 @@ static int zynqmp_ipi_mbox_probe(struct zynqmp_ipi_mbox *ipi_mbox,
+ 	ret = device_register(&ipi_mbox->dev);
+ 	if (ret) {
+ 		dev_err(dev, "Failed to register ipi mbox dev.\n");
++		put_device(&ipi_mbox->dev);
+ 		return ret;
+ 	}
+ 	mdev = &ipi_mbox->dev;
+@@ -619,7 +620,8 @@ static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata)
+ 		ipi_mbox = &pdata->ipi_mboxes[i];
+ 		if (ipi_mbox->dev.parent) {
+ 			mbox_controller_unregister(&ipi_mbox->mbox);
+-			device_unregister(&ipi_mbox->dev);
++			if (device_is_registered(&ipi_mbox->dev))
++				device_unregister(&ipi_mbox->dev);
+ 		}
+ 	}
+ }
+diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c
+index 338fc889b357a..b8ad4f16b4acd 100644
+--- a/drivers/mcb/mcb-core.c
++++ b/drivers/mcb/mcb-core.c
+@@ -71,8 +71,10 @@ static int mcb_probe(struct device *dev)
+ 
+ 	get_device(dev);
+ 	ret = mdrv->probe(mdev, found_id);
+-	if (ret)
++	if (ret) {
+ 		module_put(carrier_mod);
++		put_device(dev);
++	}
+ 
+ 	return ret;
+ }
+diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c
+index 0266bfddfbe27..aa6938da0db85 100644
+--- a/drivers/mcb/mcb-parse.c
++++ b/drivers/mcb/mcb-parse.c
+@@ -108,7 +108,7 @@ static int chameleon_parse_gdd(struct mcb_bus *bus,
+ 	return 0;
+ 
+ err:
+-	mcb_free_dev(mdev);
++	put_device(&mdev->dev);
+ 
+ 	return ret;
+ }
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index b4a2cb5333fcc..bbde744f7dbaa 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -732,28 +732,48 @@ static char *_dm_claim_ptr = "I belong to device-mapper";
+ /*
+  * Open a table device so we can use it as a map destination.
+  */
+-static int open_table_device(struct table_device *td, dev_t dev,
+-			     struct mapped_device *md)
++static struct table_device *open_table_device(struct mapped_device *md,
++		dev_t dev, fmode_t mode)
+ {
++	struct table_device *td;
+ 	struct block_device *bdev;
+ 	u64 part_off;
+ 	int r;
+ 
+-	BUG_ON(td->dm_dev.bdev);
++	td = kmalloc_node(sizeof(*td), GFP_KERNEL, md->numa_node_id);
++	if (!td)
++		return ERR_PTR(-ENOMEM);
++	refcount_set(&td->count, 1);
+ 
+-	bdev = blkdev_get_by_dev(dev, td->dm_dev.mode | FMODE_EXCL, _dm_claim_ptr);
+-	if (IS_ERR(bdev))
+-		return PTR_ERR(bdev);
++	bdev = blkdev_get_by_dev(dev, mode | FMODE_EXCL, _dm_claim_ptr);
++	if (IS_ERR(bdev)) {
++		r = PTR_ERR(bdev);
++		goto out_free_td;
++	}
+ 
+-	r = bd_link_disk_holder(bdev, dm_disk(md));
+-	if (r) {
+-		blkdev_put(bdev, td->dm_dev.mode | FMODE_EXCL);
+-		return r;
++	/*
++	 * We can be called before the dm disk is added.  In that case we can't
++	 * register the holder relation here.  It will be done once add_disk was
++	 * called.
++	 */
++	if (md->disk->slave_dir) {
++		r = bd_link_disk_holder(bdev, md->disk);
++		if (r)
++			goto out_blkdev_put;
+ 	}
+ 
++	td->dm_dev.mode = mode;
+ 	td->dm_dev.bdev = bdev;
+ 	td->dm_dev.dax_dev = fs_dax_get_by_bdev(bdev, &part_off, NULL, NULL);
+-	return 0;
++	format_dev_t(td->dm_dev.name, dev);
++	list_add(&td->list, &md->table_devices);
++	return td;
++
++out_blkdev_put:
++	blkdev_put(bdev, mode | FMODE_EXCL);
++out_free_td:
++	kfree(td);
++	return ERR_PTR(r);
+ }
+ 
+ /*
+@@ -761,14 +781,12 @@ static int open_table_device(struct table_device *td, dev_t dev,
+  */
+ static void close_table_device(struct table_device *td, struct mapped_device *md)
+ {
+-	if (!td->dm_dev.bdev)
+-		return;
+-
+-	bd_unlink_disk_holder(td->dm_dev.bdev, dm_disk(md));
++	if (md->disk->slave_dir)
++		bd_unlink_disk_holder(td->dm_dev.bdev, md->disk);
+ 	blkdev_put(td->dm_dev.bdev, td->dm_dev.mode | FMODE_EXCL);
+ 	put_dax(td->dm_dev.dax_dev);
+-	td->dm_dev.bdev = NULL;
+-	td->dm_dev.dax_dev = NULL;
++	list_del(&td->list);
++	kfree(td);
+ }
+ 
+ static struct table_device *find_table_device(struct list_head *l, dev_t dev,
+@@ -786,31 +804,16 @@ static struct table_device *find_table_device(struct list_head *l, dev_t dev,
+ int dm_get_table_device(struct mapped_device *md, dev_t dev, fmode_t mode,
+ 			struct dm_dev **result)
+ {
+-	int r;
+ 	struct table_device *td;
+ 
+ 	mutex_lock(&md->table_devices_lock);
+ 	td = find_table_device(&md->table_devices, dev, mode);
+ 	if (!td) {
+-		td = kmalloc_node(sizeof(*td), GFP_KERNEL, md->numa_node_id);
+-		if (!td) {
++		td = open_table_device(md, dev, mode);
++		if (IS_ERR(td)) {
+ 			mutex_unlock(&md->table_devices_lock);
+-			return -ENOMEM;
++			return PTR_ERR(td);
+ 		}
+-
+-		td->dm_dev.mode = mode;
+-		td->dm_dev.bdev = NULL;
+-
+-		if ((r = open_table_device(td, dev, md))) {
+-			mutex_unlock(&md->table_devices_lock);
+-			kfree(td);
+-			return r;
+-		}
+-
+-		format_dev_t(td->dm_dev.name, dev);
+-
+-		refcount_set(&td->count, 1);
+-		list_add(&td->list, &md->table_devices);
+ 	} else {
+ 		refcount_inc(&td->count);
+ 	}
+@@ -825,11 +828,8 @@ void dm_put_table_device(struct mapped_device *md, struct dm_dev *d)
+ 	struct table_device *td = container_of(d, struct table_device, dm_dev);
+ 
+ 	mutex_lock(&md->table_devices_lock);
+-	if (refcount_dec_and_test(&td->count)) {
++	if (refcount_dec_and_test(&td->count))
+ 		close_table_device(td, md);
+-		list_del(&td->list);
+-		kfree(td);
+-	}
+ 	mutex_unlock(&md->table_devices_lock);
+ }
+ 
+@@ -1972,8 +1972,21 @@ static void cleanup_mapped_device(struct mapped_device *md)
+ 		md->disk->private_data = NULL;
+ 		spin_unlock(&_minor_lock);
+ 		if (dm_get_md_type(md) != DM_TYPE_NONE) {
++			struct table_device *td;
++
+ 			dm_sysfs_exit(md);
++			list_for_each_entry(td, &md->table_devices, list) {
++				bd_unlink_disk_holder(td->dm_dev.bdev,
++						      md->disk);
++			}
++
++			/*
++			 * Hold lock to make sure del_gendisk() won't concurrent
++			 * with open/close_table_device().
++			 */
++			mutex_lock(&md->table_devices_lock);
+ 			del_gendisk(md->disk);
++			mutex_unlock(&md->table_devices_lock);
+ 		}
+ 		dm_queue_destroy_crypto_profile(md->queue);
+ 		put_disk(md->disk);
+@@ -2305,6 +2318,7 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t)
+ {
+ 	enum dm_queue_mode type = dm_table_get_type(t);
+ 	struct queue_limits limits;
++	struct table_device *td;
+ 	int r;
+ 
+ 	switch (type) {
+@@ -2333,17 +2347,40 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t)
+ 	if (r)
+ 		return r;
+ 
++	/*
++	 * Hold lock to make sure add_disk() and del_gendisk() won't concurrent
++	 * with open_table_device() and close_table_device().
++	 */
++	mutex_lock(&md->table_devices_lock);
+ 	r = add_disk(md->disk);
++	mutex_unlock(&md->table_devices_lock);
+ 	if (r)
+ 		return r;
+ 
+-	r = dm_sysfs_init(md);
+-	if (r) {
+-		del_gendisk(md->disk);
+-		return r;
++	/*
++	 * Register the holder relationship for devices added before the disk
++	 * was live.
++	 */
++	list_for_each_entry(td, &md->table_devices, list) {
++		r = bd_link_disk_holder(td->dm_dev.bdev, md->disk);
++		if (r)
++			goto out_undo_holders;
+ 	}
++
++	r = dm_sysfs_init(md);
++	if (r)
++		goto out_undo_holders;
++
+ 	md->type = type;
+ 	return 0;
++
++out_undo_holders:
++	list_for_each_entry_continue_reverse(td, &md->table_devices, list)
++		bd_unlink_disk_holder(td->dm_dev.bdev, md->disk);
++	mutex_lock(&md->table_devices_lock);
++	del_gendisk(md->disk);
++	mutex_unlock(&md->table_devices_lock);
++	return r;
+ }
+ 
+ struct mapped_device *dm_get_md(dev_t dev)
+diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
+index bf6dffadbe6f6..63ece30114e53 100644
+--- a/drivers/md/md-bitmap.c
++++ b/drivers/md/md-bitmap.c
+@@ -2195,20 +2195,23 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
+ 
+ 		if (set) {
+ 			bmc_new = md_bitmap_get_counter(&bitmap->counts, block, &new_blocks, 1);
+-			if (*bmc_new == 0) {
+-				/* need to set on-disk bits too. */
+-				sector_t end = block + new_blocks;
+-				sector_t start = block >> chunkshift;
+-				start <<= chunkshift;
+-				while (start < end) {
+-					md_bitmap_file_set_bit(bitmap, block);
+-					start += 1 << chunkshift;
++			if (bmc_new) {
++				if (*bmc_new == 0) {
++					/* need to set on-disk bits too. */
++					sector_t end = block + new_blocks;
++					sector_t start = block >> chunkshift;
++
++					start <<= chunkshift;
++					while (start < end) {
++						md_bitmap_file_set_bit(bitmap, block);
++						start += 1 << chunkshift;
++					}
++					*bmc_new = 2;
++					md_bitmap_count_page(&bitmap->counts, block, 1);
++					md_bitmap_set_pending(&bitmap->counts, block);
+ 				}
+-				*bmc_new = 2;
+-				md_bitmap_count_page(&bitmap->counts, block, 1);
+-				md_bitmap_set_pending(&bitmap->counts, block);
++				*bmc_new |= NEEDED_MASK;
+ 			}
+-			*bmc_new |= NEEDED_MASK;
+ 			if (new_blocks < old_blocks)
+ 				old_blocks = new_blocks;
+ 		}
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
+index 857c49399c28e..b536befd88988 100644
+--- a/drivers/md/raid0.c
++++ b/drivers/md/raid0.c
+@@ -398,7 +398,6 @@ static int raid0_run(struct mddev *mddev)
+ 
+ 		blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors);
+ 		blk_queue_max_write_zeroes_sectors(mddev->queue, mddev->chunk_sectors);
+-		blk_queue_max_discard_sectors(mddev->queue, UINT_MAX);
+ 
+ 		blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9);
+ 		blk_queue_io_opt(mddev->queue,
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index 05d8438cfec88..58f705f429480 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -3159,6 +3159,7 @@ static int raid1_run(struct mddev *mddev)
+ 	 * RAID1 needs at least one disk in active
+ 	 */
+ 	if (conf->raid_disks - mddev->degraded < 1) {
++		md_unregister_thread(&conf->thread);
+ 		ret = -EINVAL;
+ 		goto abort;
+ 	}
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index 64d6e4cd8a3a0..b19c6ce89d5ea 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -4104,8 +4104,6 @@ static int raid10_run(struct mddev *mddev)
+ 	conf->thread = NULL;
+ 
+ 	if (mddev->queue) {
+-		blk_queue_max_discard_sectors(mddev->queue,
+-					      UINT_MAX);
+ 		blk_queue_max_write_zeroes_sectors(mddev->queue, 0);
+ 		blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9);
+ 		raid10_set_io_opt(conf);
+diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
+index 15a08d8c69ef8..c2d2792227f86 100644
+--- a/drivers/media/dvb-core/dvb_ca_en50221.c
++++ b/drivers/media/dvb-core/dvb_ca_en50221.c
+@@ -157,7 +157,7 @@ static void dvb_ca_private_free(struct dvb_ca_private *ca)
+ {
+ 	unsigned int i;
+ 
+-	dvb_free_device(ca->dvbdev);
++	dvb_device_put(ca->dvbdev);
+ 	for (i = 0; i < ca->slot_count; i++)
+ 		vfree(ca->slot_info[i].rx_buffer.data);
+ 
+diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
+index 48e735cdbe6bb..c41a7e5c2b928 100644
+--- a/drivers/media/dvb-core/dvb_frontend.c
++++ b/drivers/media/dvb-core/dvb_frontend.c
+@@ -136,7 +136,7 @@ static void __dvb_frontend_free(struct dvb_frontend *fe)
+ 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
+ 
+ 	if (fepriv)
+-		dvb_free_device(fepriv->dvbdev);
++		dvb_device_put(fepriv->dvbdev);
+ 
+ 	dvb_frontend_invoke_release(fe, fe->ops.release);
+ 
+@@ -2986,6 +2986,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
+ 		.name = fe->ops.info.name,
+ #endif
+ 	};
++	int ret;
+ 
+ 	dev_dbg(dvb->device, "%s:\n", __func__);
+ 
+@@ -3019,8 +3020,13 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
+ 		 "DVB: registering adapter %i frontend %i (%s)...\n",
+ 		 fe->dvb->num, fe->id, fe->ops.info.name);
+ 
+-	dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
++	ret = dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
+ 			    fe, DVB_DEVICE_FRONTEND, 0);
++	if (ret) {
++		dvb_frontend_put(fe);
++		mutex_unlock(&frontend_mutex);
++		return ret;
++	}
+ 
+ 	/*
+ 	 * Initialize the cache to the proper values according with the
+diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
+index 675d877a67b25..9934728734af9 100644
+--- a/drivers/media/dvb-core/dvbdev.c
++++ b/drivers/media/dvb-core/dvbdev.c
+@@ -97,7 +97,7 @@ static int dvb_device_open(struct inode *inode, struct file *file)
+ 		new_fops = fops_get(dvbdev->fops);
+ 		if (!new_fops)
+ 			goto fail;
+-		file->private_data = dvbdev;
++		file->private_data = dvb_device_get(dvbdev);
+ 		replace_fops(file, new_fops);
+ 		if (file->f_op->open)
+ 			err = file->f_op->open(inode, file);
+@@ -161,6 +161,9 @@ int dvb_generic_release(struct inode *inode, struct file *file)
+ 	}
+ 
+ 	dvbdev->users++;
++
++	dvb_device_put(dvbdev);
++
+ 	return 0;
+ }
+ EXPORT_SYMBOL(dvb_generic_release);
+@@ -478,6 +481,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ 	}
+ 
+ 	memcpy(dvbdev, template, sizeof(struct dvb_device));
++	kref_init(&dvbdev->ref);
+ 	dvbdev->type = type;
+ 	dvbdev->id = id;
+ 	dvbdev->adapter = adap;
+@@ -508,7 +512,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
+ #endif
+ 
+ 	dvbdev->minor = minor;
+-	dvb_minors[minor] = dvbdev;
++	dvb_minors[minor] = dvb_device_get(dvbdev);
+ 	up_write(&minor_rwsem);
+ 
+ 	ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
+@@ -553,6 +557,7 @@ void dvb_remove_device(struct dvb_device *dvbdev)
+ 
+ 	down_write(&minor_rwsem);
+ 	dvb_minors[dvbdev->minor] = NULL;
++	dvb_device_put(dvbdev);
+ 	up_write(&minor_rwsem);
+ 
+ 	dvb_media_device_free(dvbdev);
+@@ -564,21 +569,34 @@ void dvb_remove_device(struct dvb_device *dvbdev)
+ EXPORT_SYMBOL(dvb_remove_device);
+ 
+ 
+-void dvb_free_device(struct dvb_device *dvbdev)
++static void dvb_free_device(struct kref *ref)
+ {
+-	if (!dvbdev)
+-		return;
++	struct dvb_device *dvbdev = container_of(ref, struct dvb_device, ref);
+ 
+ 	kfree (dvbdev->fops);
+ 	kfree (dvbdev);
+ }
+-EXPORT_SYMBOL(dvb_free_device);
++
++
++struct dvb_device *dvb_device_get(struct dvb_device *dvbdev)
++{
++	kref_get(&dvbdev->ref);
++	return dvbdev;
++}
++EXPORT_SYMBOL(dvb_device_get);
++
++
++void dvb_device_put(struct dvb_device *dvbdev)
++{
++	if (dvbdev)
++		kref_put(&dvbdev->ref, dvb_free_device);
++}
+ 
+ 
+ void dvb_unregister_device(struct dvb_device *dvbdev)
+ {
+ 	dvb_remove_device(dvbdev);
+-	dvb_free_device(dvbdev);
++	dvb_device_put(dvbdev);
+ }
+ EXPORT_SYMBOL(dvb_unregister_device);
+ 
+diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c
+index da0ff7b44da41..68b92b4419cff 100644
+--- a/drivers/media/dvb-frontends/bcm3510.c
++++ b/drivers/media/dvb-frontends/bcm3510.c
+@@ -649,6 +649,7 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe)
+ 		deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
+ 		if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
+ 			err("firmware download failed: %d\n",ret);
++			release_firmware(fw);
+ 			return ret;
+ 		}
+ 		i += 4 + len;
+diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c
+index 2958a46944614..07639ecc85aa8 100644
+--- a/drivers/media/i2c/ad5820.c
++++ b/drivers/media/i2c/ad5820.c
+@@ -327,18 +327,18 @@ static int ad5820_probe(struct i2c_client *client,
+ 
+ 	ret = media_entity_pads_init(&coil->subdev.entity, 0, NULL);
+ 	if (ret < 0)
+-		goto cleanup2;
++		goto clean_mutex;
+ 
+ 	ret = v4l2_async_register_subdev(&coil->subdev);
+ 	if (ret < 0)
+-		goto cleanup;
++		goto clean_entity;
+ 
+ 	return ret;
+ 
+-cleanup2:
+-	mutex_destroy(&coil->power_lock);
+-cleanup:
++clean_entity:
+ 	media_entity_cleanup(&coil->subdev.entity);
++clean_mutex:
++	mutex_destroy(&coil->power_lock);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c b/drivers/media/i2c/adv748x/adv748x-afe.c
+index 02eabe10ab970..00095c7762c24 100644
+--- a/drivers/media/i2c/adv748x/adv748x-afe.c
++++ b/drivers/media/i2c/adv748x/adv748x-afe.c
+@@ -521,6 +521,10 @@ int adv748x_afe_init(struct adv748x_afe *afe)
+ 		}
+ 	}
+ 
++	adv748x_afe_s_input(afe, afe->input);
++
++	adv_dbg(state, "AFE Default input set to %d\n", afe->input);
++
+ 	/* Entity pads and sinks are 0-indexed to match the pads */
+ 	for (i = ADV748X_AFE_SINK_AIN0; i <= ADV748X_AFE_SINK_AIN7; i++)
+ 		afe->pads[i].flags = MEDIA_PAD_FL_SINK;
+diff --git a/drivers/media/i2c/dw9768.c b/drivers/media/i2c/dw9768.c
+index c086580efac78..60ae0adf51744 100644
+--- a/drivers/media/i2c/dw9768.c
++++ b/drivers/media/i2c/dw9768.c
+@@ -414,6 +414,7 @@ static int dw9768_probe(struct i2c_client *client)
+ {
+ 	struct device *dev = &client->dev;
+ 	struct dw9768 *dw9768;
++	bool full_power;
+ 	unsigned int i;
+ 	int ret;
+ 
+@@ -469,13 +470,23 @@ static int dw9768_probe(struct i2c_client *client)
+ 
+ 	dw9768->sd.entity.function = MEDIA_ENT_F_LENS;
+ 
++	/*
++	 * Figure out whether we're going to power up the device here. Generally
++	 * this is done if CONFIG_PM is disabled in a DT system or the device is
++	 * to be powered on in an ACPI system. Similarly for power off in
++	 * remove.
++	 */
+ 	pm_runtime_enable(dev);
+-	if (!pm_runtime_enabled(dev)) {
++	full_power = (is_acpi_node(dev_fwnode(dev)) &&
++		      acpi_dev_state_d0(dev)) ||
++		     (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev));
++	if (full_power) {
+ 		ret = dw9768_runtime_resume(dev);
+ 		if (ret < 0) {
+ 			dev_err(dev, "failed to power on: %d\n", ret);
+ 			goto err_clean_entity;
+ 		}
++		pm_runtime_set_active(dev);
+ 	}
+ 
+ 	ret = v4l2_async_register_subdev(&dw9768->sd);
+@@ -484,14 +495,17 @@ static int dw9768_probe(struct i2c_client *client)
+ 		goto err_power_off;
+ 	}
+ 
++	pm_runtime_idle(dev);
++
+ 	return 0;
+ 
+ err_power_off:
+-	if (pm_runtime_enabled(dev))
+-		pm_runtime_disable(dev);
+-	else
++	if (full_power) {
+ 		dw9768_runtime_suspend(dev);
++		pm_runtime_set_suspended(dev);
++	}
+ err_clean_entity:
++	pm_runtime_disable(dev);
+ 	media_entity_cleanup(&dw9768->sd.entity);
+ err_free_handler:
+ 	v4l2_ctrl_handler_free(&dw9768->ctrls);
+@@ -503,14 +517,17 @@ static int dw9768_remove(struct i2c_client *client)
+ {
+ 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ 	struct dw9768 *dw9768 = sd_to_dw9768(sd);
++	struct device *dev = &client->dev;
+ 
+ 	v4l2_async_unregister_subdev(&dw9768->sd);
+ 	v4l2_ctrl_handler_free(&dw9768->ctrls);
+ 	media_entity_cleanup(&dw9768->sd.entity);
+-	pm_runtime_disable(&client->dev);
+-	if (!pm_runtime_status_suspended(&client->dev))
+-		dw9768_runtime_suspend(&client->dev);
+-	pm_runtime_set_suspended(&client->dev);
++	if ((is_acpi_node(dev_fwnode(dev)) && acpi_dev_state_d0(dev)) ||
++	    (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev))) {
++		dw9768_runtime_suspend(dev);
++		pm_runtime_set_suspended(dev);
++	}
++	pm_runtime_disable(dev);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/media/i2c/hi846.c b/drivers/media/i2c/hi846.c
+index ad35c3ff36115..254031503c728 100644
+--- a/drivers/media/i2c/hi846.c
++++ b/drivers/media/i2c/hi846.c
+@@ -2008,22 +2008,24 @@ static int hi846_parse_dt(struct hi846 *hi846, struct device *dev)
+ 	    bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
+ 		dev_err(dev, "number of CSI2 data lanes %d is not supported",
+ 			bus_cfg.bus.mipi_csi2.num_data_lanes);
+-		v4l2_fwnode_endpoint_free(&bus_cfg);
+-		return -EINVAL;
++		ret = -EINVAL;
++		goto check_hwcfg_error;
+ 	}
+ 
+ 	hi846->nr_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
+ 
+ 	if (!bus_cfg.nr_of_link_frequencies) {
+ 		dev_err(dev, "link-frequency property not found in DT\n");
+-		return -EINVAL;
++		ret = -EINVAL;
++		goto check_hwcfg_error;
+ 	}
+ 
+ 	/* Check that link frequences for all the modes are in device tree */
+ 	fq = hi846_check_link_freqs(hi846, &bus_cfg);
+ 	if (fq) {
+ 		dev_err(dev, "Link frequency of %lld is not supported\n", fq);
+-		return -EINVAL;
++		ret = -EINVAL;
++		goto check_hwcfg_error;
+ 	}
+ 
+ 	v4l2_fwnode_endpoint_free(&bus_cfg);
+@@ -2044,6 +2046,10 @@ static int hi846_parse_dt(struct hi846 *hi846, struct device *dev)
+ 	}
+ 
+ 	return 0;
++
++check_hwcfg_error:
++	v4l2_fwnode_endpoint_free(&bus_cfg);
++	return ret;
+ }
+ 
+ static int hi846_probe(struct i2c_client *client)
+diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
+index 1fd4dc6e4726f..92f4e184353f8 100644
+--- a/drivers/media/i2c/mt9p031.c
++++ b/drivers/media/i2c/mt9p031.c
+@@ -702,7 +702,6 @@ static int mt9p031_init_cfg(struct v4l2_subdev *subdev,
+ 					     V4L2_SUBDEV_FORMAT_TRY;
+ 
+ 	crop = __mt9p031_get_pad_crop(mt9p031, sd_state, 0, which);
+-	v4l2_subdev_get_try_crop(subdev, sd_state, 0);
+ 	crop->left = MT9P031_COLUMN_START_DEF;
+ 	crop->top = MT9P031_ROW_START_DEF;
+ 	crop->width = MT9P031_WINDOW_WIDTH_DEF;
+diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
+index 502f0b62e9505..7e72e7c7b0ddc 100644
+--- a/drivers/media/i2c/ov5640.c
++++ b/drivers/media/i2c/ov5640.c
+@@ -3816,7 +3816,8 @@ static int ov5640_probe(struct i2c_client *client)
+ 	sensor->current_mode =
+ 		&ov5640_mode_data[OV5640_MODE_VGA_640_480];
+ 	sensor->last_mode = sensor->current_mode;
+-	sensor->current_link_freq = OV5640_DEFAULT_LINK_FREQ;
++	sensor->current_link_freq =
++		ov5640_csi2_link_freqs[OV5640_DEFAULT_LINK_FREQ];
+ 
+ 	sensor->ae_target = 52;
+ 
+diff --git a/drivers/media/i2c/ov5648.c b/drivers/media/i2c/ov5648.c
+index dfcd33e9ee136..220c53565b0a7 100644
+--- a/drivers/media/i2c/ov5648.c
++++ b/drivers/media/i2c/ov5648.c
+@@ -2597,6 +2597,7 @@ static int ov5648_remove(struct i2c_client *client)
+ 	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
+ 	mutex_destroy(&sensor->mutex);
+ 	media_entity_cleanup(&subdev->entity);
++	v4l2_fwnode_endpoint_free(&sensor->endpoint);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c
+index 7973ae42873a6..c10997e2271d2 100644
+--- a/drivers/media/pci/saa7164/saa7164-core.c
++++ b/drivers/media/pci/saa7164/saa7164-core.c
+@@ -1259,7 +1259,7 @@ static int saa7164_initdev(struct pci_dev *pci_dev,
+ 
+ 	if (saa7164_dev_setup(dev) < 0) {
+ 		err = -EINVAL;
+-		goto fail_free;
++		goto fail_dev;
+ 	}
+ 
+ 	/* print pci info */
+@@ -1427,6 +1427,8 @@ fail_fw:
+ 
+ fail_irq:
+ 	saa7164_dev_unregister(dev);
++fail_dev:
++	pci_disable_device(pci_dev);
+ fail_free:
+ 	v4l2_device_unregister(&dev->v4l2_dev);
+ 	kfree(dev);
+diff --git a/drivers/media/pci/solo6x10/solo6x10-core.c b/drivers/media/pci/solo6x10/solo6x10-core.c
+index 4a546eeefe38f..6d87fbb0ee04a 100644
+--- a/drivers/media/pci/solo6x10/solo6x10-core.c
++++ b/drivers/media/pci/solo6x10/solo6x10-core.c
+@@ -420,6 +420,7 @@ static int solo_sysfs_init(struct solo_dev *solo_dev)
+ 		     solo_dev->nr_chans);
+ 
+ 	if (device_register(dev)) {
++		put_device(dev);
+ 		dev->parent = NULL;
+ 		return -ENOMEM;
+ 	}
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index feb75dc204de8..b27e6bed85f0f 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -286,6 +286,7 @@ static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+ 	struct vpu_format *cur_fmt;
+ 	int i;
+ 
++	vpu_inst_lock(inst);
+ 	cur_fmt = vpu_get_format(inst, f->type);
+ 
+ 	pixmp->pixelformat = cur_fmt->pixfmt;
+@@ -303,6 +304,7 @@ static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+ 	f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+ 	f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+ 	f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
++	vpu_inst_unlock(inst);
+ 
+ 	return 0;
+ }
+@@ -753,6 +755,9 @@ static bool vdec_check_source_change(struct vpu_inst *inst)
+ 	if (!inst->fh.m2m_ctx)
+ 		return false;
+ 
++	if (vdec->reset_codec)
++		return false;
++
+ 	if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx)))
+ 		return true;
+ 	fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
+@@ -1088,7 +1093,8 @@ static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info
+ 		vdec->seq_tag = vdec->codec_info.tag;
+ 		if (vdec->is_source_changed) {
+ 			vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
+-			vpu_notify_source_change(inst);
++			vdec->source_change++;
++			vdec_handle_resolution_change(inst);
+ 			vdec->is_source_changed = false;
+ 		}
+ 	}
+@@ -1335,6 +1341,8 @@ static void vdec_abort(struct vpu_inst *inst)
+ 		  vdec->decoded_frame_count,
+ 		  vdec->display_frame_count,
+ 		  vdec->sequence);
++	if (!vdec->seq_hdr_found)
++		vdec->reset_codec = true;
+ 	vdec->params.end_flag = 0;
+ 	vdec->drain = 0;
+ 	vdec->params.frame_count = 0;
+@@ -1342,6 +1350,7 @@ static void vdec_abort(struct vpu_inst *inst)
+ 	vdec->display_frame_count = 0;
+ 	vdec->sequence = 0;
+ 	vdec->aborting = false;
++	inst->extra_size = 0;
+ }
+ 
+ static void vdec_stop(struct vpu_inst *inst, bool free)
+@@ -1464,8 +1473,7 @@ static int vdec_start_session(struct vpu_inst *inst, u32 type)
+ 	}
+ 
+ 	if (V4L2_TYPE_IS_OUTPUT(type)) {
+-		if (inst->state == VPU_CODEC_STATE_SEEK)
+-			vdec_update_state(inst, vdec->state, 1);
++		vdec_update_state(inst, vdec->state, 1);
+ 		vdec->eos_received = 0;
+ 		vpu_process_output_buffer(inst);
+ 	} else {
+@@ -1629,6 +1637,7 @@ static int vdec_open(struct file *file)
+ 		return ret;
+ 
+ 	vdec->fixed_fmt = false;
++	vdec->state = VPU_CODEC_STATE_ACTIVE;
+ 	inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
+ 	inst->min_buffer_out = VDEC_MIN_BUFFER_OUT;
+ 	vdec_init(file);
+diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h
+index beac0309ca8d9..048c23c2bf4db 100644
+--- a/drivers/media/platform/amphion/vpu.h
++++ b/drivers/media/platform/amphion/vpu.h
+@@ -13,6 +13,7 @@
+ #include <linux/mailbox_controller.h>
+ #include <linux/kfifo.h>
+ 
++#define VPU_TIMEOUT_WAKEUP	msecs_to_jiffies(200)
+ #define VPU_TIMEOUT		msecs_to_jiffies(1000)
+ #define VPU_INST_NULL_ID	(-1L)
+ #define VPU_MSG_BUFFER_SIZE	(8192)
+diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c
+index f4d7ca78a6212..fa581ba6bab2d 100644
+--- a/drivers/media/platform/amphion/vpu_cmds.c
++++ b/drivers/media/platform/amphion/vpu_cmds.c
+@@ -269,7 +269,7 @@ exit:
+ 	return flag;
+ }
+ 
+-static int sync_session_response(struct vpu_inst *inst, unsigned long key)
++static int sync_session_response(struct vpu_inst *inst, unsigned long key, long timeout, int try)
+ {
+ 	struct vpu_core *core;
+ 
+@@ -279,10 +279,12 @@ static int sync_session_response(struct vpu_inst *inst, unsigned long key)
+ 	core = inst->core;
+ 
+ 	call_void_vop(inst, wait_prepare);
+-	wait_event_timeout(core->ack_wq, check_is_responsed(inst, key), VPU_TIMEOUT);
++	wait_event_timeout(core->ack_wq, check_is_responsed(inst, key), timeout);
+ 	call_void_vop(inst, wait_finish);
+ 
+ 	if (!check_is_responsed(inst, key)) {
++		if (try)
++			return -EINVAL;
+ 		dev_err(inst->dev, "[%d] sync session timeout\n", inst->id);
+ 		set_bit(inst->id, &core->hang_mask);
+ 		mutex_lock(&inst->core->cmd_lock);
+@@ -294,6 +296,19 @@ static int sync_session_response(struct vpu_inst *inst, unsigned long key)
+ 	return 0;
+ }
+ 
++static void vpu_core_keep_active(struct vpu_core *core)
++{
++	struct vpu_rpc_event pkt;
++
++	memset(&pkt, 0, sizeof(pkt));
++	vpu_iface_pack_cmd(core, &pkt, 0, VPU_CMD_ID_NOOP, NULL);
++
++	dev_dbg(core->dev, "try to wake up\n");
++	mutex_lock(&core->cmd_lock);
++	vpu_cmd_send(core, &pkt);
++	mutex_unlock(&core->cmd_lock);
++}
++
+ static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data)
+ {
+ 	unsigned long key;
+@@ -304,9 +319,25 @@ static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data)
+ 		return -EINVAL;
+ 
+ 	ret = vpu_request_cmd(inst, id, data, &key, &sync);
+-	if (!ret && sync)
+-		ret = sync_session_response(inst, key);
++	if (ret)
++		goto exit;
++
++	/* workaround for a firmware issue,
++	 * firmware should be waked up by start or configure command,
++	 * but there is a very small change that firmware failed to wakeup.
++	 * in such case, try to wakeup firmware again by sending a noop command
++	 */
++	if (sync && (id == VPU_CMD_ID_CONFIGURE_CODEC || id == VPU_CMD_ID_START)) {
++		if (sync_session_response(inst, key, VPU_TIMEOUT_WAKEUP, 1))
++			vpu_core_keep_active(inst->core);
++		else
++			goto exit;
++	}
++
++	if (sync)
++		ret = sync_session_response(inst, key, VPU_TIMEOUT, 0);
+ 
++exit:
+ 	if (ret)
+ 		dev_err(inst->dev, "[%d] send cmd(0x%x) fail\n", inst->id, id);
+ 
+diff --git a/drivers/media/platform/amphion/vpu_drv.c b/drivers/media/platform/amphion/vpu_drv.c
+index 9d5a5075343d3..f01ce49d27e80 100644
+--- a/drivers/media/platform/amphion/vpu_drv.c
++++ b/drivers/media/platform/amphion/vpu_drv.c
+@@ -245,7 +245,11 @@ static int __init vpu_driver_init(void)
+ 	if (ret)
+ 		return ret;
+ 
+-	return vpu_core_driver_init();
++	ret = vpu_core_driver_init();
++	if (ret)
++		platform_driver_unregister(&amphion_vpu_driver);
++
++	return ret;
+ }
+ 
+ static void __exit vpu_driver_exit(void)
+diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
+index 51e0702f9ae17..9f2890730fd70 100644
+--- a/drivers/media/platform/amphion/vpu_malone.c
++++ b/drivers/media/platform/amphion/vpu_malone.c
+@@ -692,6 +692,7 @@ int vpu_malone_set_decode_params(struct vpu_shared_addr *shared,
+ }
+ 
+ static struct vpu_pair malone_cmds[] = {
++	{VPU_CMD_ID_NOOP, VID_API_CMD_NULL},
+ 	{VPU_CMD_ID_START, VID_API_CMD_START},
+ 	{VPU_CMD_ID_STOP, VID_API_CMD_STOP},
+ 	{VPU_CMD_ID_ABORT, VID_API_CMD_ABORT},
+diff --git a/drivers/media/platform/amphion/vpu_msgs.c b/drivers/media/platform/amphion/vpu_msgs.c
+index d8247f36d84ba..92672a802b492 100644
+--- a/drivers/media/platform/amphion/vpu_msgs.c
++++ b/drivers/media/platform/amphion/vpu_msgs.c
+@@ -43,6 +43,7 @@ static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc
+ 		  req_data.ref_frame_num,
+ 		  req_data.act_buf_size,
+ 		  req_data.act_buf_num);
++	vpu_inst_lock(inst);
+ 	call_void_vop(inst, mem_request,
+ 		      req_data.enc_frame_size,
+ 		      req_data.enc_frame_num,
+@@ -50,6 +51,7 @@ static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc
+ 		      req_data.ref_frame_num,
+ 		      req_data.act_buf_size,
+ 		      req_data.act_buf_num);
++	vpu_inst_unlock(inst);
+ }
+ 
+ static void vpu_session_handle_stop_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
+index b779e0ba916ca..590d1084e5a5d 100644
+--- a/drivers/media/platform/amphion/vpu_v4l2.c
++++ b/drivers/media/platform/amphion/vpu_v4l2.c
+@@ -65,18 +65,11 @@ unsigned int vpu_get_buffer_state(struct vb2_v4l2_buffer *vbuf)
+ 
+ void vpu_v4l2_set_error(struct vpu_inst *inst)
+ {
+-	struct vb2_queue *src_q;
+-	struct vb2_queue *dst_q;
+-
+ 	vpu_inst_lock(inst);
+ 	dev_err(inst->dev, "some error occurs in codec\n");
+ 	if (inst->fh.m2m_ctx) {
+-		src_q = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+-		dst_q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+-		src_q->error = 1;
+-		dst_q->error = 1;
+-		wake_up(&src_q->done_wq);
+-		wake_up(&dst_q->done_wq);
++		vb2_queue_error(v4l2_m2m_get_src_vq(inst->fh.m2m_ctx));
++		vb2_queue_error(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx));
+ 	}
+ 	vpu_inst_unlock(inst);
+ }
+@@ -249,8 +242,12 @@ int vpu_process_capture_buffer(struct vpu_inst *inst)
+ 
+ struct vb2_v4l2_buffer *vpu_next_src_buf(struct vpu_inst *inst)
+ {
+-	struct vb2_v4l2_buffer *src_buf = v4l2_m2m_next_src_buf(inst->fh.m2m_ctx);
++	struct vb2_v4l2_buffer *src_buf = NULL;
++
++	if (!inst->fh.m2m_ctx)
++		return NULL;
+ 
++	src_buf = v4l2_m2m_next_src_buf(inst->fh.m2m_ctx);
+ 	if (!src_buf || vpu_get_buffer_state(src_buf) == VPU_BUF_STATE_IDLE)
+ 		return NULL;
+ 
+@@ -273,7 +270,7 @@ void vpu_skip_frame(struct vpu_inst *inst, int count)
+ 	enum vb2_buffer_state state;
+ 	int i = 0;
+ 
+-	if (count <= 0)
++	if (count <= 0 || !inst->fh.m2m_ctx)
+ 		return;
+ 
+ 	while (i < count) {
+@@ -603,10 +600,6 @@ static int vpu_v4l2_release(struct vpu_inst *inst)
+ 		inst->workqueue = NULL;
+ 	}
+ 
+-	if (inst->fh.m2m_ctx) {
+-		v4l2_m2m_ctx_release(inst->fh.m2m_ctx);
+-		inst->fh.m2m_ctx = NULL;
+-	}
+ 	v4l2_ctrl_handler_free(&inst->ctrl_handler);
+ 	mutex_destroy(&inst->lock);
+ 	v4l2_fh_del(&inst->fh);
+@@ -689,6 +682,13 @@ int vpu_v4l2_close(struct file *file)
+ 
+ 	vpu_trace(vpu->dev, "tgid = %d, pid = %d, inst = %p\n", inst->tgid, inst->pid, inst);
+ 
++	vpu_inst_lock(inst);
++	if (inst->fh.m2m_ctx) {
++		v4l2_m2m_ctx_release(inst->fh.m2m_ctx);
++		inst->fh.m2m_ctx = NULL;
++	}
++	vpu_inst_unlock(inst);
++
+ 	call_void_vop(inst, release);
+ 	vpu_inst_unregister(inst);
+ 	vpu_inst_put(inst);
+diff --git a/drivers/media/platform/amphion/vpu_windsor.c b/drivers/media/platform/amphion/vpu_windsor.c
+index 1526af2ef9da4..b93c8cfdee7f5 100644
+--- a/drivers/media/platform/amphion/vpu_windsor.c
++++ b/drivers/media/platform/amphion/vpu_windsor.c
+@@ -658,6 +658,7 @@ int vpu_windsor_get_stream_buffer_size(struct vpu_shared_addr *shared)
+ }
+ 
+ static struct vpu_pair windsor_cmds[] = {
++	{VPU_CMD_ID_NOOP, GTB_ENC_CMD_NOOP},
+ 	{VPU_CMD_ID_CONFIGURE_CODEC, GTB_ENC_CMD_CONFIGURE_CODEC},
+ 	{VPU_CMD_ID_START, GTB_ENC_CMD_STREAM_START},
+ 	{VPU_CMD_ID_STOP, GTB_ENC_CMD_STREAM_STOP},
+diff --git a/drivers/media/platform/chips-media/coda-bit.c b/drivers/media/platform/chips-media/coda-bit.c
+index 2736a902e3df3..ed47d5bd8d61e 100644
+--- a/drivers/media/platform/chips-media/coda-bit.c
++++ b/drivers/media/platform/chips-media/coda-bit.c
+@@ -854,7 +854,7 @@ static void coda_setup_iram(struct coda_ctx *ctx)
+ 		/* Only H.264BP and H.263P3 are considered */
+ 		iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, w64);
+ 		iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, w64);
+-		if (!iram_info->buf_dbk_c_use)
++		if (!iram_info->buf_dbk_y_use || !iram_info->buf_dbk_c_use)
+ 			goto out;
+ 		iram_info->axi_sram_use |= dbk_bits;
+ 
+@@ -878,7 +878,7 @@ static void coda_setup_iram(struct coda_ctx *ctx)
+ 
+ 		iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, w128);
+ 		iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, w128);
+-		if (!iram_info->buf_dbk_c_use)
++		if (!iram_info->buf_dbk_y_use || !iram_info->buf_dbk_c_use)
+ 			goto out;
+ 		iram_info->axi_sram_use |= dbk_bits;
+ 
+@@ -1084,10 +1084,16 @@ static int coda_start_encoding(struct coda_ctx *ctx)
+ 	}
+ 
+ 	if (dst_fourcc == V4L2_PIX_FMT_JPEG) {
+-		if (!ctx->params.jpeg_qmat_tab[0])
++		if (!ctx->params.jpeg_qmat_tab[0]) {
+ 			ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL);
+-		if (!ctx->params.jpeg_qmat_tab[1])
++			if (!ctx->params.jpeg_qmat_tab[0])
++				return -ENOMEM;
++		}
++		if (!ctx->params.jpeg_qmat_tab[1]) {
+ 			ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL);
++			if (!ctx->params.jpeg_qmat_tab[1])
++				return -ENOMEM;
++		}
+ 		coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality);
+ 	}
+ 
+diff --git a/drivers/media/platform/chips-media/coda-jpeg.c b/drivers/media/platform/chips-media/coda-jpeg.c
+index a0b22b07f69ac..2284e04209348 100644
+--- a/drivers/media/platform/chips-media/coda-jpeg.c
++++ b/drivers/media/platform/chips-media/coda-jpeg.c
+@@ -1053,10 +1053,16 @@ static int coda9_jpeg_start_encoding(struct coda_ctx *ctx)
+ 		v4l2_err(&dev->v4l2_dev, "error loading Huffman tables\n");
+ 		return ret;
+ 	}
+-	if (!ctx->params.jpeg_qmat_tab[0])
++	if (!ctx->params.jpeg_qmat_tab[0]) {
+ 		ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL);
+-	if (!ctx->params.jpeg_qmat_tab[1])
++		if (!ctx->params.jpeg_qmat_tab[0])
++			return -ENOMEM;
++	}
++	if (!ctx->params.jpeg_qmat_tab[1]) {
+ 		ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL);
++		if (!ctx->params.jpeg_qmat_tab[1])
++			return -ENOMEM;
++	}
+ 	coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality);
+ 
+ 	return 0;
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
+index c45bd2599bb2d..ffbcee04dc26f 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_stateless.c
+@@ -138,10 +138,13 @@ static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx, int error
+ 		state = VB2_BUF_STATE_DONE;
+ 
+ 	vb2_dst = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+-	v4l2_m2m_buf_done(vb2_dst, state);
+-
+-	mtk_v4l2_debug(2, "free frame buffer id:%d to done list",
+-		       vb2_dst->vb2_buf.index);
++	if (vb2_dst) {
++		v4l2_m2m_buf_done(vb2_dst, state);
++		mtk_v4l2_debug(2, "free frame buffer id:%d to done list",
++			       vb2_dst->vb2_buf.index);
++	} else {
++		mtk_v4l2_err("dst buffer is NULL");
++	}
+ 
+ 	if (src_buf_req)
+ 		v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
+@@ -250,7 +253,7 @@ static void mtk_vdec_worker(struct work_struct *work)
+ 
+ 	state = ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE;
+ 	if (!IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch) ||
+-	    ctx->current_codec == V4L2_PIX_FMT_VP8_FRAME || ret) {
++	    ctx->current_codec == V4L2_PIX_FMT_VP8_FRAME) {
+ 		v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx, state);
+ 		if (src_buf_req)
+ 			v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
+index 4cc92700692b3..955b2d0c8f53f 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
++++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c
+@@ -471,14 +471,19 @@ static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf)
+ 	       sizeof(share_info->h264_slice_params));
+ 
+ 	fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
+-	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
+-	vdec_fb_va = (unsigned long)fb;
++	if (!fb) {
++		err = -EBUSY;
++		mtk_vcodec_err(inst, "fb buffer is NULL");
++		goto vdec_dec_end;
++	}
+ 
++	vdec_fb_va = (unsigned long)fb;
++	y_fb_dma = (u64)fb->base_y.dma_addr;
+ 	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
+ 		c_fb_dma =
+ 			y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
+ 	else
+-		c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
++		c_fb_dma = (u64)fb->base_c.dma_addr;
+ 
+ 	mtk_vcodec_debug(inst, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma,
+ 			 c_fb_dma);
+@@ -539,6 +544,29 @@ vdec_dec_end:
+ 	return 0;
+ }
+ 
++static void vdec_h264_insert_startcode(struct mtk_vcodec_dev *vcodec_dev, unsigned char *buf,
++				       size_t *bs_size, struct mtk_h264_pps_param *pps)
++{
++	struct device *dev = &vcodec_dev->plat_dev->dev;
++
++	/* Need to add pending data at the end of bitstream when bs_sz is small than
++	 * 20 bytes for cavlc bitstream, or lat will decode fail. This pending data is
++	 * useful for mt8192 and mt8195 platform.
++	 *
++	 * cavlc bitstream when entropy_coding_mode_flag is false.
++	 */
++	if (pps->entropy_coding_mode_flag || *bs_size > 20 ||
++	    !(of_device_is_compatible(dev->of_node, "mediatek,mt8192-vcodec-dec") ||
++	    of_device_is_compatible(dev->of_node, "mediatek,mt8195-vcodec-dec")))
++		return;
++
++	buf[*bs_size] = 0;
++	buf[*bs_size + 1] = 0;
++	buf[*bs_size + 2] = 1;
++	buf[*bs_size + 3] = 0xff;
++	(*bs_size) += 4;
++}
++
+ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ 				      struct vdec_fb *fb, bool *res_chg)
+ {
+@@ -582,9 +610,6 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ 	}
+ 
+ 	inst->vsi->dec.nal_info = buf[nal_start_idx];
+-	inst->vsi->dec.bs_buf_addr = (u64)bs->dma_addr;
+-	inst->vsi->dec.bs_buf_size = bs->size;
+-
+ 	lat_buf->src_buf_req = src_buf_info->m2m_buf.vb.vb2_buf.req_obj.req;
+ 	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb, &lat_buf->ts_info, true);
+ 
+@@ -592,6 +617,12 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ 	if (err)
+ 		goto err_free_fb_out;
+ 
++	vdec_h264_insert_startcode(inst->ctx->dev, buf, &bs->size,
++				   &share_info->h264_slice_params.pps);
++
++	inst->vsi->dec.bs_buf_addr = (uint64_t)bs->dma_addr;
++	inst->vsi->dec.bs_buf_size = bs->size;
++
+ 	*res_chg = inst->resolution_changed;
+ 	if (inst->resolution_changed) {
+ 		mtk_vcodec_debug(inst, "- resolution changed -");
+@@ -630,7 +661,7 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ 	err = vpu_dec_start(vpu, data, 2);
+ 	if (err) {
+ 		mtk_vcodec_debug(inst, "lat decode err: %d", err);
+-		goto err_scp_decode;
++		goto err_free_fb_out;
+ 	}
+ 
+ 	share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+@@ -647,12 +678,17 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ 	/* wait decoder done interrupt */
+ 	timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+ 					       WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
++	if (timeout)
++		mtk_vcodec_err(inst, "lat decode timeout: pic_%d", inst->slice_dec_num);
+ 	inst->vsi->dec.timeout = !!timeout;
+ 
+ 	err = vpu_dec_end(vpu);
+-	if (err == SLICE_HEADER_FULL || timeout || err == TRANS_BUFFER_FULL) {
+-		err = -EINVAL;
+-		goto err_scp_decode;
++	if (err == SLICE_HEADER_FULL || err == TRANS_BUFFER_FULL) {
++		if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability))
++			vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf);
++		inst->slice_dec_num++;
++		mtk_vcodec_err(inst, "lat dec fail: pic_%d err:%d", inst->slice_dec_num, err);
++		return -EINVAL;
+ 	}
+ 
+ 	share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+@@ -669,10 +705,6 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ 
+ 	inst->slice_dec_num++;
+ 	return 0;
+-
+-err_scp_decode:
+-	if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability))
+-		vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf);
+ err_free_fb_out:
+ 	vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf);
+ 	mtk_vcodec_err(inst, "slice dec number: %d err: %d", inst->slice_dec_num, err);
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c
+index fb1c36a3592d1..cbb6728b8a40b 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c
++++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c
+@@ -2073,21 +2073,23 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ 		return -EBUSY;
+ 	}
+ 	pfc = (struct vdec_vp9_slice_pfc *)lat_buf->private_data;
+-	if (!pfc)
+-		return -EINVAL;
++	if (!pfc) {
++		ret = -EINVAL;
++		goto err_free_fb_out;
++	}
+ 	vsi = &pfc->vsi;
+ 
+ 	ret = vdec_vp9_slice_setup_lat(instance, bs, lat_buf, pfc);
+ 	if (ret) {
+ 		mtk_vcodec_err(instance, "Failed to setup VP9 lat ret %d\n", ret);
+-		return ret;
++		goto err_free_fb_out;
+ 	}
+ 	vdec_vp9_slice_vsi_to_remote(vsi, instance->vsi);
+ 
+ 	ret = vpu_dec_start(&instance->vpu, NULL, 0);
+ 	if (ret) {
+ 		mtk_vcodec_err(instance, "Failed to dec VP9 ret %d\n", ret);
+-		return ret;
++		goto err_free_fb_out;
+ 	}
+ 
+ 	if (instance->irq) {
+@@ -2107,7 +2109,7 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ 	/* LAT trans full, no more UBE or decode timeout */
+ 	if (ret) {
+ 		mtk_vcodec_err(instance, "VP9 decode error: %d\n", ret);
+-		return ret;
++		goto err_free_fb_out;
+ 	}
+ 
+ 	mtk_vcodec_debug(instance, "lat dma addr: 0x%lx 0x%lx\n",
+@@ -2120,6 +2122,9 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+ 	vdec_msg_queue_qbuf(&ctx->dev->msg_queue_core_ctx, lat_buf);
+ 
+ 	return 0;
++err_free_fb_out:
++	vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
++	return ret;
+ }
+ 
+ static int vdec_vp9_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
+index ae500980ad45c..dc2004790a472 100644
+--- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
++++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c
+@@ -221,7 +221,7 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
+ 	mtk_vcodec_dec_disable_hardware(ctx, MTK_VDEC_CORE);
+ 	vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
+ 
+-	if (!list_empty(&ctx->msg_queue.lat_ctx.ready_queue)) {
++	if (!list_empty(&dev->msg_queue_core_ctx.ready_queue)) {
+ 		mtk_v4l2_debug(3, "re-schedule to decode for core: %d",
+ 			       dev->msg_queue_core_ctx.ready_num);
+ 		queue_work(dev->core_workqueue, &msg_queue->core_work);
+diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c
+index 9418fcf740a82..ef28122a5ed49 100644
+--- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c
++++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c
+@@ -76,12 +76,14 @@ void print_wrapper_info(struct device *dev, void __iomem *reg)
+ 
+ void mxc_jpeg_enable_irq(void __iomem *reg, int slot)
+ {
+-	writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
++	writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
++	writel(0xF0C, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
+ }
+ 
+ void mxc_jpeg_disable_irq(void __iomem *reg, int slot)
+ {
+ 	writel(0x0, reg + MXC_SLOT_OFFSET(slot, SLOT_IRQ_EN));
++	writel(0xFFFFFFFF, reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS));
+ }
+ 
+ void mxc_jpeg_sw_reset(void __iomem *reg)
+diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
+index 290df04c4d02c..a25fffb0b8ec5 100644
+--- a/drivers/media/platform/qcom/camss/camss-video.c
++++ b/drivers/media/platform/qcom/camss/camss-video.c
+@@ -495,7 +495,7 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count)
+ 
+ 	ret = media_pipeline_start(&vdev->entity, &video->pipe);
+ 	if (ret < 0)
+-		return ret;
++		goto flush_buffers;
+ 
+ 	ret = video_check_format(video);
+ 	if (ret < 0)
+@@ -524,6 +524,7 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count)
+ error:
+ 	media_pipeline_stop(&vdev->entity);
+ 
++flush_buffers:
+ 	video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
+ 
+ 	return ret;
+diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
+index 1118c40886d52..a157cac72e0ab 100644
+--- a/drivers/media/platform/qcom/camss/camss.c
++++ b/drivers/media/platform/qcom/camss/camss.c
+@@ -1465,6 +1465,14 @@ static int camss_configure_pd(struct camss *camss)
+ 		return camss->genpd_num;
+ 	}
+ 
++	/*
++	 * If a platform device has just one power domain, then it is attached
++	 * at platform_probe() level, thus there shall be no need and even no
++	 * option to attach it again, this is the case for CAMSS on MSM8916.
++	 */
++	if (camss->genpd_num == 1)
++		return 0;
++
+ 	camss->genpd = devm_kmalloc_array(dev, camss->genpd_num,
+ 					  sizeof(*camss->genpd), GFP_KERNEL);
+ 	if (!camss->genpd)
+@@ -1698,6 +1706,9 @@ void camss_delete(struct camss *camss)
+ 
+ 	pm_runtime_disable(camss->dev);
+ 
++	if (camss->genpd_num == 1)
++		return;
++
+ 	for (i = 0; i < camss->genpd_num; i++) {
+ 		device_link_del(camss->genpd_link[i]);
+ 		dev_pm_domain_detach(camss->genpd[i], true);
+diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
+index c93d2906e4c7d..48c9084bb4dba 100644
+--- a/drivers/media/platform/qcom/venus/pm_helpers.c
++++ b/drivers/media/platform/qcom/venus/pm_helpers.c
+@@ -869,8 +869,8 @@ static int vcodec_domains_get(struct venus_core *core)
+ 	for (i = 0; i < res->vcodec_pmdomains_num; i++) {
+ 		pd = dev_pm_domain_attach_by_name(dev,
+ 						  res->vcodec_pmdomains[i]);
+-		if (IS_ERR(pd))
+-			return PTR_ERR(pd);
++		if (IS_ERR_OR_NULL(pd))
++			return PTR_ERR(pd) ? : -ENODATA;
+ 		core->pmdomains[i] = pd;
+ 	}
+ 
+diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-core.c b/drivers/media/platform/samsung/exynos4-is/fimc-core.c
+index 91cc8d58a663b..1791100b69353 100644
+--- a/drivers/media/platform/samsung/exynos4-is/fimc-core.c
++++ b/drivers/media/platform/samsung/exynos4-is/fimc-core.c
+@@ -1173,7 +1173,7 @@ int __init fimc_register_driver(void)
+ 	return platform_driver_register(&fimc_driver);
+ }
+ 
+-void __exit fimc_unregister_driver(void)
++void fimc_unregister_driver(void)
+ {
+ 	platform_driver_unregister(&fimc_driver);
+ }
+diff --git a/drivers/media/platform/samsung/exynos4-is/media-dev.c b/drivers/media/platform/samsung/exynos4-is/media-dev.c
+index 52b43ea040302..2f3071acb9c97 100644
+--- a/drivers/media/platform/samsung/exynos4-is/media-dev.c
++++ b/drivers/media/platform/samsung/exynos4-is/media-dev.c
+@@ -1380,9 +1380,7 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
+ 
+ 	/* Find platform data for this sensor subdev */
+ 	for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
+-		if (fmd->sensor[i].asd &&
+-		    fmd->sensor[i].asd->match.fwnode ==
+-		    of_fwnode_handle(subdev->dev->of_node))
++		if (fmd->sensor[i].asd == asd)
+ 			si = &fmd->sensor[i];
+ 
+ 	if (si == NULL)
+@@ -1474,7 +1472,7 @@ static int fimc_md_probe(struct platform_device *pdev)
+ 	pinctrl = devm_pinctrl_get(dev);
+ 	if (IS_ERR(pinctrl)) {
+ 		ret = PTR_ERR(pinctrl);
+-		if (ret != EPROBE_DEFER)
++		if (ret != -EPROBE_DEFER)
+ 			dev_err(dev, "Failed to get pinctrl: %d\n", ret);
+ 		goto err_clk;
+ 	}
+@@ -1586,7 +1584,11 @@ static int __init fimc_md_init(void)
+ 	if (ret)
+ 		return ret;
+ 
+-	return platform_driver_register(&fimc_md_driver);
++	ret = platform_driver_register(&fimc_md_driver);
++	if (ret)
++		fimc_unregister_driver();
++
++	return ret;
+ }
+ 
+ static void __exit fimc_md_exit(void)
+diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+index f85d1eebaface..7bdbe767500e6 100644
+--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
++++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+@@ -1576,8 +1576,18 @@ static struct s5p_mfc_variant mfc_drvdata_v7 = {
+ 	.port_num	= MFC_NUM_PORTS_V7,
+ 	.buf_size	= &buf_size_v7,
+ 	.fw_name[0]     = "s5p-mfc-v7.fw",
+-	.clk_names	= {"mfc", "sclk_mfc"},
+-	.num_clocks	= 2,
++	.clk_names	= {"mfc"},
++	.num_clocks	= 1,
++};
++
++static struct s5p_mfc_variant mfc_drvdata_v7_3250 = {
++	.version        = MFC_VERSION_V7,
++	.version_bit    = MFC_V7_BIT,
++	.port_num       = MFC_NUM_PORTS_V7,
++	.buf_size       = &buf_size_v7,
++	.fw_name[0]     = "s5p-mfc-v7.fw",
++	.clk_names      = {"mfc", "sclk_mfc"},
++	.num_clocks     = 2,
+ };
+ 
+ static struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = {
+@@ -1647,6 +1657,9 @@ static const struct of_device_id exynos_mfc_match[] = {
+ 	}, {
+ 		.compatible = "samsung,mfc-v7",
+ 		.data = &mfc_drvdata_v7,
++	}, {
++		.compatible = "samsung,exynos3250-mfc",
++		.data = &mfc_drvdata_v7_3250,
+ 	}, {
+ 		.compatible = "samsung,mfc-v8",
+ 		.data = &mfc_drvdata_v8,
+diff --git a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c
+index cefe6b7bfdc4e..1dbb89f0ddb8c 100644
+--- a/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c
++++ b/drivers/media/platform/st/sti/c8sectpfe/c8sectpfe-core.c
+@@ -925,6 +925,7 @@ static int configure_channels(struct c8sectpfei *fei)
+ 		if (ret) {
+ 			dev_err(fei->dev,
+ 				"configure_memdma_and_inputblock failed\n");
++			of_node_put(child);
+ 			goto err_unmap;
+ 		}
+ 		index++;
+diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+index 30d6c0c5161f4..484ac5f054d53 100644
+--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
++++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+@@ -498,6 +498,7 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
+ 	struct v4l2_async_notifier *notifier = &bridge->notifier;
+ 	struct media_pad *pads = bridge->pads;
+ 	struct device *dev = csi2_dev->dev;
++	bool notifier_registered = false;
+ 	int ret;
+ 
+ 	mutex_init(&bridge->lock);
+@@ -519,8 +520,10 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
+ 
+ 	/* Media Pads */
+ 
+-	pads[SUN6I_MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+-	pads[SUN6I_MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
++	pads[SUN6I_MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
++					       MEDIA_PAD_FL_MUST_CONNECT;
++	pads[SUN6I_MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE |
++						 MEDIA_PAD_FL_MUST_CONNECT;
+ 
+ 	ret = media_entity_pads_init(&subdev->entity, SUN6I_MIPI_CSI2_PAD_COUNT,
+ 				     pads);
+@@ -533,12 +536,17 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
+ 	notifier->ops = &sun6i_mipi_csi2_notifier_ops;
+ 
+ 	ret = sun6i_mipi_csi2_bridge_source_setup(csi2_dev);
+-	if (ret)
++	if (ret && ret != -ENODEV)
+ 		goto error_v4l2_notifier_cleanup;
+ 
+-	ret = v4l2_async_subdev_nf_register(subdev, notifier);
+-	if (ret < 0)
+-		goto error_v4l2_notifier_cleanup;
++	/* Only register the notifier when a sensor is connected. */
++	if (ret != -ENODEV) {
++		ret = v4l2_async_subdev_nf_register(subdev, notifier);
++		if (ret < 0)
++			goto error_v4l2_notifier_cleanup;
++
++		notifier_registered = true;
++	}
+ 
+ 	/* V4L2 Subdev */
+ 
+@@ -549,7 +557,8 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
+ 	return 0;
+ 
+ error_v4l2_notifier_unregister:
+-	v4l2_async_nf_unregister(notifier);
++	if (notifier_registered)
++		v4l2_async_nf_unregister(notifier);
+ 
+ error_v4l2_notifier_cleanup:
+ 	v4l2_async_nf_cleanup(notifier);
+diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
+index b032ec13a683a..d993c09a48202 100644
+--- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
++++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
+@@ -536,6 +536,7 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
+ 	struct v4l2_async_notifier *notifier = &bridge->notifier;
+ 	struct media_pad *pads = bridge->pads;
+ 	struct device *dev = csi2_dev->dev;
++	bool notifier_registered = false;
+ 	int ret;
+ 
+ 	mutex_init(&bridge->lock);
+@@ -557,8 +558,10 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
+ 
+ 	/* Media Pads */
+ 
+-	pads[SUN8I_A83T_MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+-	pads[SUN8I_A83T_MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
++	pads[SUN8I_A83T_MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
++						    MEDIA_PAD_FL_MUST_CONNECT;
++	pads[SUN8I_A83T_MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE |
++						      MEDIA_PAD_FL_MUST_CONNECT;
+ 
+ 	ret = media_entity_pads_init(&subdev->entity,
+ 				     SUN8I_A83T_MIPI_CSI2_PAD_COUNT, pads);
+@@ -571,12 +574,17 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
+ 	notifier->ops = &sun8i_a83t_mipi_csi2_notifier_ops;
+ 
+ 	ret = sun8i_a83t_mipi_csi2_bridge_source_setup(csi2_dev);
+-	if (ret)
++	if (ret && ret != -ENODEV)
+ 		goto error_v4l2_notifier_cleanup;
+ 
+-	ret = v4l2_async_subdev_nf_register(subdev, notifier);
+-	if (ret < 0)
+-		goto error_v4l2_notifier_cleanup;
++	/* Only register the notifier when a sensor is connected. */
++	if (ret != -ENODEV) {
++		ret = v4l2_async_subdev_nf_register(subdev, notifier);
++		if (ret < 0)
++			goto error_v4l2_notifier_cleanup;
++
++		notifier_registered = true;
++	}
+ 
+ 	/* V4L2 Subdev */
+ 
+@@ -587,7 +595,8 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
+ 	return 0;
+ 
+ error_v4l2_notifier_unregister:
+-	v4l2_async_nf_unregister(notifier);
++	if (notifier_registered)
++		v4l2_async_nf_unregister(notifier);
+ 
+ error_v4l2_notifier_cleanup:
+ 	v4l2_async_nf_cleanup(notifier);
+diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
+index 6b2768623c883..aa7a580dbecc0 100644
+--- a/drivers/media/radio/si470x/radio-si470x-usb.c
++++ b/drivers/media/radio/si470x/radio-si470x-usb.c
+@@ -727,8 +727,10 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
+ 
+ 	/* start radio */
+ 	retval = si470x_start_usb(radio);
+-	if (retval < 0)
++	if (retval < 0 && !radio->int_in_running)
+ 		goto err_buf;
++	else if (retval < 0)	/* in case of radio->int_in_running == 1 */
++		goto err_all;
+ 
+ 	/* set initial frequency */
+ 	si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
+diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
+index 735b925da9984..91d8056666ec8 100644
+--- a/drivers/media/rc/imon.c
++++ b/drivers/media/rc/imon.c
+@@ -646,15 +646,14 @@ static int send_packet(struct imon_context *ictx)
+ 		pr_err_ratelimited("error submitting urb(%d)\n", retval);
+ 	} else {
+ 		/* Wait for transmission to complete (or abort) */
+-		mutex_unlock(&ictx->lock);
+ 		retval = wait_for_completion_interruptible(
+ 				&ictx->tx.finished);
+ 		if (retval) {
+ 			usb_kill_urb(ictx->tx_urb);
+ 			pr_err_ratelimited("task interrupted\n");
+ 		}
+-		mutex_lock(&ictx->lock);
+ 
++		ictx->tx.busy = false;
+ 		retval = ictx->tx.status;
+ 		if (retval)
+ 			pr_err_ratelimited("packet tx failed (%d)\n", retval);
+@@ -955,7 +954,8 @@ static ssize_t vfd_write(struct file *file, const char __user *buf,
+ 	if (ictx->disconnected)
+ 		return -ENODEV;
+ 
+-	mutex_lock(&ictx->lock);
++	if (mutex_lock_interruptible(&ictx->lock))
++		return -ERESTARTSYS;
+ 
+ 	if (!ictx->dev_present_intf0) {
+ 		pr_err_ratelimited("no iMON device present\n");
+diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
+index 82620613d56b8..dff7265a42ca2 100644
+--- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c
++++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c
+@@ -459,26 +459,20 @@ fail_dmx_conn:
+ 	for (j = j - 1; j >= 0; --j)
+ 		dvb->demux.dmx.remove_frontend(&dvb->demux.dmx,
+ 					       &dvb->dmx_fe[j]);
+-fail_dmx_dev:
+ 	dvb_dmxdev_release(&dvb->dmx_dev);
+-fail_dmx:
++fail_dmx_dev:
+ 	dvb_dmx_release(&dvb->demux);
++fail_dmx:
++fail_demod_probe:
++	for (i = i - 1; i >= 0; --i) {
++		dvb_unregister_frontend(dvb->fe[i]);
+ fail_fe:
+-	for (j = i; j >= 0; --j)
+-		dvb_unregister_frontend(dvb->fe[j]);
++		dvb_module_release(dvb->i2c_client_tuner[i]);
+ fail_tuner_probe:
+-	for (j = i; j >= 0; --j)
+-		if (dvb->i2c_client_tuner[j])
+-			dvb_module_release(dvb->i2c_client_tuner[j]);
+-
+-fail_demod_probe:
+-	for (j = i; j >= 0; --j)
+-		if (dvb->i2c_client_demod[j])
+-			dvb_module_release(dvb->i2c_client_demod[j]);
+-
++		dvb_module_release(dvb->i2c_client_demod[i]);
++	}
+ fail_adapter:
+ 	dvb_unregister_adapter(&dvb->adapter);
+-
+ fail_i2c:
+ 	i2c_del_adapter(&dvb->i2c_adapter);
+ 
+diff --git a/drivers/media/test-drivers/vimc/vimc-core.c b/drivers/media/test-drivers/vimc/vimc-core.c
+index 2ae7a0f11ebfc..e82cfa5ffbf47 100644
+--- a/drivers/media/test-drivers/vimc/vimc-core.c
++++ b/drivers/media/test-drivers/vimc/vimc-core.c
+@@ -433,7 +433,7 @@ static int __init vimc_init(void)
+ 	if (ret) {
+ 		dev_err(&vimc_pdev.dev,
+ 			"platform driver registration failed (err=%d)\n", ret);
+-		platform_driver_unregister(&vimc_pdrv);
++		platform_device_unregister(&vimc_pdev);
+ 		return ret;
+ 	}
+ 
+diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+index 99139a8cd4c4f..331a3f4286d2e 100644
+--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
++++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+@@ -961,6 +961,7 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
+ 			if (dev->has_compose_cap) {
+ 				v4l2_rect_set_min_size(compose, &min_rect);
+ 				v4l2_rect_set_max_size(compose, &max_rect);
++				v4l2_rect_map_inside(compose, &fmt);
+ 			}
+ 			dev->fmt_cap_rect = fmt;
+ 			tpg_s_buf_height(&dev->tpg, fmt.height);
+diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
+index cf15988dfb510..7d78ee09be5e1 100644
+--- a/drivers/media/usb/dvb-usb/az6027.c
++++ b/drivers/media/usb/dvb-usb/az6027.c
+@@ -975,6 +975,10 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
+ 		if (msg[i].addr == 0x99) {
+ 			req = 0xBE;
+ 			index = 0;
++			if (msg[i].len < 1) {
++				i = -EOPNOTSUPP;
++				break;
++			}
+ 			value = msg[i].buf[0] & 0x00ff;
+ 			length = 1;
+ 			az6027_usb_out_op(d, req, value, index, data, length);
+diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
+index 61439c8f33cab..58eea8ab54779 100644
+--- a/drivers/media/usb/dvb-usb/dvb-usb-init.c
++++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
+@@ -81,7 +81,7 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
+ 
+ 		ret = dvb_usb_adapter_stream_init(adap);
+ 		if (ret)
+-			return ret;
++			goto stream_init_err;
+ 
+ 		ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs);
+ 		if (ret)
+@@ -114,6 +114,8 @@ frontend_init_err:
+ 	dvb_usb_adapter_dvb_exit(adap);
+ dvb_init_err:
+ 	dvb_usb_adapter_stream_exit(adap);
++stream_init_err:
++	kfree(adap->priv);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c
+index 50d012ba3c02e..7781ebd7ee95f 100644
+--- a/drivers/media/v4l2-core/v4l2-ctrls-api.c
++++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c
+@@ -155,6 +155,7 @@ static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)
+ 			 * then return an error.
+ 			 */
+ 			if (strlen(ctrl->p_new.p_char) == ctrl->maximum && last)
++			ctrl->is_new = 1;
+ 				return -ERANGE;
+ 		}
+ 		return ret;
+diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
+index 1f85828d6694d..322f9f715b65b 100644
+--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
++++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
+@@ -1762,7 +1762,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
+ 	else if (type == V4L2_CTRL_TYPE_INTEGER_MENU)
+ 		qmenu_int = v4l2_ctrl_get_int_menu(id, &qmenu_int_len);
+ 
+-	if ((!qmenu && !qmenu_int) || (qmenu_int && max > qmenu_int_len)) {
++	if ((!qmenu && !qmenu_int) || (qmenu_int && max >= qmenu_int_len)) {
+ 		handler_set_err(hdl, -EINVAL);
+ 		return NULL;
+ 	}
+diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
+index e6fd355a2e92c..de83714f0d403 100644
+--- a/drivers/media/v4l2-core/v4l2-ioctl.c
++++ b/drivers/media/v4l2-core/v4l2-ioctl.c
+@@ -1347,23 +1347,23 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
+ 	case V4L2_PIX_FMT_YUV420:	descr = "Planar YUV 4:2:0"; break;
+ 	case V4L2_PIX_FMT_HI240:	descr = "8-bit Dithered RGB (BTTV)"; break;
+ 	case V4L2_PIX_FMT_M420:		descr = "YUV 4:2:0 (M420)"; break;
+-	case V4L2_PIX_FMT_NV12:		descr = "Y/CbCr 4:2:0"; break;
+-	case V4L2_PIX_FMT_NV21:		descr = "Y/CrCb 4:2:0"; break;
+-	case V4L2_PIX_FMT_NV16:		descr = "Y/CbCr 4:2:2"; break;
+-	case V4L2_PIX_FMT_NV61:		descr = "Y/CrCb 4:2:2"; break;
+-	case V4L2_PIX_FMT_NV24:		descr = "Y/CbCr 4:4:4"; break;
+-	case V4L2_PIX_FMT_NV42:		descr = "Y/CrCb 4:4:4"; break;
+-	case V4L2_PIX_FMT_P010:		descr = "10-bit Y/CbCr 4:2:0"; break;
+-	case V4L2_PIX_FMT_NV12_4L4:	descr = "Y/CbCr 4:2:0 (4x4 Linear)"; break;
+-	case V4L2_PIX_FMT_NV12_16L16:	descr = "Y/CbCr 4:2:0 (16x16 Linear)"; break;
+-	case V4L2_PIX_FMT_NV12_32L32:   descr = "Y/CbCr 4:2:0 (32x32 Linear)"; break;
+-	case V4L2_PIX_FMT_P010_4L4:	descr = "10-bit Y/CbCr 4:2:0 (4x4 Linear)"; break;
+-	case V4L2_PIX_FMT_NV12M:	descr = "Y/CbCr 4:2:0 (N-C)"; break;
+-	case V4L2_PIX_FMT_NV21M:	descr = "Y/CrCb 4:2:0 (N-C)"; break;
+-	case V4L2_PIX_FMT_NV16M:	descr = "Y/CbCr 4:2:2 (N-C)"; break;
+-	case V4L2_PIX_FMT_NV61M:	descr = "Y/CrCb 4:2:2 (N-C)"; break;
+-	case V4L2_PIX_FMT_NV12MT:	descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break;
+-	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break;
++	case V4L2_PIX_FMT_NV12:		descr = "Y/UV 4:2:0"; break;
++	case V4L2_PIX_FMT_NV21:		descr = "Y/VU 4:2:0"; break;
++	case V4L2_PIX_FMT_NV16:		descr = "Y/UV 4:2:2"; break;
++	case V4L2_PIX_FMT_NV61:		descr = "Y/VU 4:2:2"; break;
++	case V4L2_PIX_FMT_NV24:		descr = "Y/UV 4:4:4"; break;
++	case V4L2_PIX_FMT_NV42:		descr = "Y/VU 4:4:4"; break;
++	case V4L2_PIX_FMT_P010:		descr = "10-bit Y/UV 4:2:0"; break;
++	case V4L2_PIX_FMT_NV12_4L4:	descr = "Y/UV 4:2:0 (4x4 Linear)"; break;
++	case V4L2_PIX_FMT_NV12_16L16:	descr = "Y/UV 4:2:0 (16x16 Linear)"; break;
++	case V4L2_PIX_FMT_NV12_32L32:   descr = "Y/UV 4:2:0 (32x32 Linear)"; break;
++	case V4L2_PIX_FMT_P010_4L4:	descr = "10-bit Y/UV 4:2:0 (4x4 Linear)"; break;
++	case V4L2_PIX_FMT_NV12M:	descr = "Y/UV 4:2:0 (N-C)"; break;
++	case V4L2_PIX_FMT_NV21M:	descr = "Y/VU 4:2:0 (N-C)"; break;
++	case V4L2_PIX_FMT_NV16M:	descr = "Y/UV 4:2:2 (N-C)"; break;
++	case V4L2_PIX_FMT_NV61M:	descr = "Y/VU 4:2:2 (N-C)"; break;
++	case V4L2_PIX_FMT_NV12MT:	descr = "Y/UV 4:2:0 (64x32 MB, N-C)"; break;
++	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/UV 4:2:0 (16x16 MB, N-C)"; break;
+ 	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break;
+ 	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break;
+ 	case V4L2_PIX_FMT_YUV422M:	descr = "Planar YUV 4:2:2 (N-C)"; break;
+diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c
+index 52312ce2ba056..f2c4393595574 100644
+--- a/drivers/media/v4l2-core/videobuf-dma-contig.c
++++ b/drivers/media/v4l2-core/videobuf-dma-contig.c
+@@ -36,12 +36,11 @@ struct videobuf_dma_contig_memory {
+ 
+ static int __videobuf_dc_alloc(struct device *dev,
+ 			       struct videobuf_dma_contig_memory *mem,
+-			       unsigned long size, gfp_t flags)
++			       unsigned long size)
+ {
+ 	mem->size = size;
+-	mem->vaddr = dma_alloc_coherent(dev, mem->size,
+-					&mem->dma_handle, flags);
+-
++	mem->vaddr = dma_alloc_coherent(dev, mem->size, &mem->dma_handle,
++					GFP_KERNEL);
+ 	if (!mem->vaddr) {
+ 		dev_err(dev, "memory alloc size %ld failed\n", mem->size);
+ 		return -ENOMEM;
+@@ -258,8 +257,7 @@ static int __videobuf_iolock(struct videobuf_queue *q,
+ 			return videobuf_dma_contig_user_get(mem, vb);
+ 
+ 		/* allocate memory for the read() method */
+-		if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size),
+-					GFP_KERNEL))
++		if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size)))
+ 			return -ENOMEM;
+ 		break;
+ 	case V4L2_MEMORY_OVERLAY:
+@@ -295,22 +293,18 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
+ 	BUG_ON(!mem);
+ 	MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
+ 
+-	if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize),
+-				GFP_KERNEL | __GFP_COMP))
++	if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize)))
+ 		goto error;
+ 
+-	/* Try to remap memory */
+-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+-
+ 	/* the "vm_pgoff" is just used in v4l2 to find the
+ 	 * corresponding buffer data structure which is allocated
+ 	 * earlier and it does not mean the offset from the physical
+ 	 * buffer start address as usual. So set it to 0 to pass
+-	 * the sanity check in vm_iomap_memory().
++	 * the sanity check in dma_mmap_coherent().
+ 	 */
+ 	vma->vm_pgoff = 0;
+-
+-	retval = vm_iomap_memory(vma, mem->dma_handle, mem->size);
++	retval = dma_mmap_coherent(q->dev, vma, mem->vaddr, mem->dma_handle,
++				   mem->size);
+ 	if (retval) {
+ 		dev_err(q->dev, "mmap: remap failed with error %d. ",
+ 			retval);
+diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c
+index 4316988d791a5..61c288d403750 100644
+--- a/drivers/memory/renesas-rpc-if.c
++++ b/drivers/memory/renesas-rpc-if.c
+@@ -317,6 +317,9 @@ int rpcif_hw_init(struct rpcif *rpc, bool hyperflash)
+ 	regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_PHYMEM_MASK,
+ 			   RPCIF_PHYCNT_PHYMEM(hyperflash ? 3 : 0));
+ 
++	/* DMA Transfer is not supported */
++	regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_HS, 0);
++
+ 	if (rpc->type == RPCIF_RCAR_GEN3)
+ 		regmap_update_bits(rpc->regmap, RPCIF_PHYCNT,
+ 				   RPCIF_PHYCNT_STRTIM(7), RPCIF_PHYCNT_STRTIM(7));
+diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c
+index ba84145195158..04115cd92433b 100644
+--- a/drivers/memstick/core/ms_block.c
++++ b/drivers/memstick/core/ms_block.c
+@@ -2116,6 +2116,11 @@ static int msb_init_disk(struct memstick_dev *card)
+ 	dbg("Set total disk size to %lu sectors", capacity);
+ 
+ 	msb->io_queue = alloc_ordered_workqueue("ms_block", WQ_MEM_RECLAIM);
++	if (!msb->io_queue) {
++		rc = -ENOMEM;
++		goto out_cleanup_disk;
++	}
++
+ 	INIT_WORK(&msb->io_work, msb_io_work);
+ 	sg_init_table(msb->prealloc_sg, MS_BLOCK_MAX_SEGS+1);
+ 
+@@ -2125,10 +2130,12 @@ static int msb_init_disk(struct memstick_dev *card)
+ 	msb_start(card);
+ 	rc = device_add_disk(&card->dev, msb->disk, NULL);
+ 	if (rc)
+-		goto out_cleanup_disk;
++		goto out_destroy_workqueue;
+ 	dbg("Disk added");
+ 	return 0;
+ 
++out_destroy_workqueue:
++	destroy_workqueue(msb->io_queue);
+ out_cleanup_disk:
+ 	put_disk(msb->disk);
+ out_free_tag_set:
+diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
+index abb58ab1a1a4f..3e8becef3cb05 100644
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -1968,6 +1968,7 @@ config MFD_ROHM_BD957XMUF
+ 	depends on I2C=y
+ 	depends on OF
+ 	select REGMAP_I2C
++	select REGMAP_IRQ
+ 	select MFD_CORE
+ 	help
+ 	  Select this option to get support for the ROHM BD9576MUF and
+diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
+index 88a212a8168cf..880c41fa7021b 100644
+--- a/drivers/mfd/axp20x.c
++++ b/drivers/mfd/axp20x.c
+@@ -842,7 +842,7 @@ static void axp20x_power_off(void)
+ 		     AXP20X_OFF);
+ 
+ 	/* Give capacitors etc. time to drain to avoid kernel panic msg. */
+-	msleep(500);
++	mdelay(500);
+ }
+ 
+ int axp20x_match_device(struct axp20x_dev *axp20x)
+diff --git a/drivers/mfd/qcom-pm8008.c b/drivers/mfd/qcom-pm8008.c
+index 4b8ff947762f2..9f3c4a01b4c1c 100644
+--- a/drivers/mfd/qcom-pm8008.c
++++ b/drivers/mfd/qcom-pm8008.c
+@@ -215,8 +215,8 @@ static int pm8008_probe(struct i2c_client *client)
+ 
+ 	dev = &client->dev;
+ 	regmap = devm_regmap_init_i2c(client, &qcom_mfd_regmap_cfg);
+-	if (!regmap)
+-		return -ENODEV;
++	if (IS_ERR(regmap))
++		return PTR_ERR(regmap);
+ 
+ 	i2c_set_clientdata(client, regmap);
+ 
+diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c
+index 71bc34b74bc9c..8fea0e511550a 100644
+--- a/drivers/mfd/qcom_rpm.c
++++ b/drivers/mfd/qcom_rpm.c
+@@ -547,7 +547,7 @@ static int qcom_rpm_probe(struct platform_device *pdev)
+ 	init_completion(&rpm->ack);
+ 
+ 	/* Enable message RAM clock */
+-	rpm->ramclk = devm_clk_get(&pdev->dev, "ram");
++	rpm->ramclk = devm_clk_get_enabled(&pdev->dev, "ram");
+ 	if (IS_ERR(rpm->ramclk)) {
+ 		ret = PTR_ERR(rpm->ramclk);
+ 		if (ret == -EPROBE_DEFER)
+@@ -558,7 +558,6 @@ static int qcom_rpm_probe(struct platform_device *pdev)
+ 		 */
+ 		rpm->ramclk = NULL;
+ 	}
+-	clk_prepare_enable(rpm->ramclk); /* Accepts NULL */
+ 
+ 	irq_ack = platform_get_irq_byname(pdev, "ack");
+ 	if (irq_ack < 0)
+@@ -673,22 +672,11 @@ static int qcom_rpm_probe(struct platform_device *pdev)
+ 	if (ret)
+ 		dev_warn(&pdev->dev, "failed to mark wakeup irq as wakeup\n");
+ 
+-	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+-}
+-
+-static int qcom_rpm_remove(struct platform_device *pdev)
+-{
+-	struct qcom_rpm *rpm = dev_get_drvdata(&pdev->dev);
+-
+-	of_platform_depopulate(&pdev->dev);
+-	clk_disable_unprepare(rpm->ramclk);
+-
+-	return 0;
++	return devm_of_platform_populate(&pdev->dev);
+ }
+ 
+ static struct platform_driver qcom_rpm_driver = {
+ 	.probe = qcom_rpm_probe,
+-	.remove = qcom_rpm_remove,
+ 	.driver  = {
+ 		.name  = "qcom_rpm",
+ 		.of_match_table = qcom_rpm_of_match,
+diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c
+index 375f692ae9d68..fb95a2d5cef48 100644
+--- a/drivers/misc/cxl/guest.c
++++ b/drivers/misc/cxl/guest.c
+@@ -965,10 +965,10 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n
+ 	 * if it returns an error!
+ 	 */
+ 	if ((rc = cxl_register_afu(afu)))
+-		goto err_put1;
++		goto err_put_dev;
+ 
+ 	if ((rc = cxl_sysfs_afu_add(afu)))
+-		goto err_put1;
++		goto err_del_dev;
+ 
+ 	/*
+ 	 * pHyp doesn't expose the programming models supported by the
+@@ -984,7 +984,7 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n
+ 		afu->modes_supported = CXL_MODE_DIRECTED;
+ 
+ 	if ((rc = cxl_afu_select_best_mode(afu)))
+-		goto err_put2;
++		goto err_remove_sysfs;
+ 
+ 	adapter->afu[afu->slice] = afu;
+ 
+@@ -1004,10 +1004,12 @@ int cxl_guest_init_afu(struct cxl *adapter, int slice, struct device_node *afu_n
+ 
+ 	return 0;
+ 
+-err_put2:
++err_remove_sysfs:
+ 	cxl_sysfs_afu_remove(afu);
+-err_put1:
+-	device_unregister(&afu->dev);
++err_del_dev:
++	device_del(&afu->dev);
++err_put_dev:
++	put_device(&afu->dev);
+ 	free = false;
+ 	guest_release_serr_irq(afu);
+ err2:
+@@ -1141,18 +1143,20 @@ struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_devic
+ 	 * even if it returns an error!
+ 	 */
+ 	if ((rc = cxl_register_adapter(adapter)))
+-		goto err_put1;
++		goto err_put_dev;
+ 
+ 	if ((rc = cxl_sysfs_adapter_add(adapter)))
+-		goto err_put1;
++		goto err_del_dev;
+ 
+ 	/* release the context lock as the adapter is configured */
+ 	cxl_adapter_context_unlock(adapter);
+ 
+ 	return adapter;
+ 
+-err_put1:
+-	device_unregister(&adapter->dev);
++err_del_dev:
++	device_del(&adapter->dev);
++err_put_dev:
++	put_device(&adapter->dev);
+ 	free = false;
+ 	cxl_guest_remove_chardev(adapter);
+ err1:
+diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
+index 3de0aea62ade4..0ff944860dda9 100644
+--- a/drivers/misc/cxl/pci.c
++++ b/drivers/misc/cxl/pci.c
+@@ -387,6 +387,7 @@ int cxl_calc_capp_routing(struct pci_dev *dev, u64 *chipid,
+ 	rc = get_phb_index(np, phb_index);
+ 	if (rc) {
+ 		pr_err("cxl: invalid phb index\n");
++		of_node_put(np);
+ 		return rc;
+ 	}
+ 
+@@ -1164,10 +1165,10 @@ static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
+ 	 * if it returns an error!
+ 	 */
+ 	if ((rc = cxl_register_afu(afu)))
+-		goto err_put1;
++		goto err_put_dev;
+ 
+ 	if ((rc = cxl_sysfs_afu_add(afu)))
+-		goto err_put1;
++		goto err_del_dev;
+ 
+ 	adapter->afu[afu->slice] = afu;
+ 
+@@ -1176,10 +1177,12 @@ static int pci_init_afu(struct cxl *adapter, int slice, struct pci_dev *dev)
+ 
+ 	return 0;
+ 
+-err_put1:
++err_del_dev:
++	device_del(&afu->dev);
++err_put_dev:
+ 	pci_deconfigure_afu(afu);
+ 	cxl_debugfs_afu_remove(afu);
+-	device_unregister(&afu->dev);
++	put_device(&afu->dev);
+ 	return rc;
+ 
+ err_free_native:
+@@ -1667,23 +1670,25 @@ static struct cxl *cxl_pci_init_adapter(struct pci_dev *dev)
+ 	 * even if it returns an error!
+ 	 */
+ 	if ((rc = cxl_register_adapter(adapter)))
+-		goto err_put1;
++		goto err_put_dev;
+ 
+ 	if ((rc = cxl_sysfs_adapter_add(adapter)))
+-		goto err_put1;
++		goto err_del_dev;
+ 
+ 	/* Release the context lock as adapter is configured */
+ 	cxl_adapter_context_unlock(adapter);
+ 
+ 	return adapter;
+ 
+-err_put1:
++err_del_dev:
++	device_del(&adapter->dev);
++err_put_dev:
+ 	/* This should mirror cxl_remove_adapter, except without the
+ 	 * sysfs parts
+ 	 */
+ 	cxl_debugfs_adapter_remove(adapter);
+ 	cxl_deconfigure_adapter(adapter);
+-	device_unregister(&adapter->dev);
++	put_device(&adapter->dev);
+ 	return ERR_PTR(rc);
+ 
+ err_release:
+diff --git a/drivers/misc/lkdtm/cfi.c b/drivers/misc/lkdtm/cfi.c
+index 71483cb1e422a..f4fd30f7a9a0e 100644
+--- a/drivers/misc/lkdtm/cfi.c
++++ b/drivers/misc/lkdtm/cfi.c
+@@ -51,7 +51,11 @@ static void lkdtm_CFI_FORWARD_PROTO(void)
+ # ifdef CONFIG_ARM64_BTI_KERNEL
+ #  define __no_pac             "branch-protection=bti"
+ # else
+-#  define __no_pac             "branch-protection=none"
++#  ifdef CONFIG_CC_HAS_BRANCH_PROT_PAC_RET
++#   define __no_pac            "branch-protection=none"
++#  else
++#   define __no_pac            "sign-return-address=none"
++#  endif
+ # endif
+ # define __no_ret_protection   __noscs __attribute__((__target__(__no_pac)))
+ #else
+diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
+index e401a51596b9c..92ab49705f645 100644
+--- a/drivers/misc/ocxl/config.c
++++ b/drivers/misc/ocxl/config.c
+@@ -193,6 +193,18 @@ static int read_dvsec_vendor(struct pci_dev *dev)
+ 	return 0;
+ }
+ 
++/**
++ * get_dvsec_vendor0() - Find a related PCI device (function 0)
++ * @dev: PCI device to match
++ * @dev0: The PCI device (function 0) found
++ * @out_pos: The position of PCI device (function 0)
++ *
++ * Returns 0 on success, negative on failure.
++ *
++ * NOTE: If it's successful, the reference of dev0 is increased,
++ * so after using it, the callers must call pci_dev_put() to give
++ * up the reference.
++ */
+ static int get_dvsec_vendor0(struct pci_dev *dev, struct pci_dev **dev0,
+ 			     int *out_pos)
+ {
+@@ -202,10 +214,14 @@ static int get_dvsec_vendor0(struct pci_dev *dev, struct pci_dev **dev0,
+ 		dev = get_function_0(dev);
+ 		if (!dev)
+ 			return -1;
++	} else {
++		dev = pci_dev_get(dev);
+ 	}
+ 	pos = find_dvsec(dev, OCXL_DVSEC_VENDOR_ID);
+-	if (!pos)
++	if (!pos) {
++		pci_dev_put(dev);
+ 		return -1;
++	}
+ 	*dev0 = dev;
+ 	*out_pos = pos;
+ 	return 0;
+@@ -222,6 +238,7 @@ int ocxl_config_get_reset_reload(struct pci_dev *dev, int *val)
+ 
+ 	pci_read_config_dword(dev0, pos + OCXL_DVSEC_VENDOR_RESET_RELOAD,
+ 			      &reset_reload);
++	pci_dev_put(dev0);
+ 	*val = !!(reset_reload & BIT(0));
+ 	return 0;
+ }
+@@ -243,6 +260,7 @@ int ocxl_config_set_reset_reload(struct pci_dev *dev, int val)
+ 		reset_reload &= ~BIT(0);
+ 	pci_write_config_dword(dev0, pos + OCXL_DVSEC_VENDOR_RESET_RELOAD,
+ 			       reset_reload);
++	pci_dev_put(dev0);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c
+index d46dba2df5a10..452d5777a0e4c 100644
+--- a/drivers/misc/ocxl/file.c
++++ b/drivers/misc/ocxl/file.c
+@@ -541,8 +541,11 @@ int ocxl_file_register_afu(struct ocxl_afu *afu)
+ 		goto err_put;
+ 
+ 	rc = device_register(&info->dev);
+-	if (rc)
+-		goto err_put;
++	if (rc) {
++		free_minor(info);
++		put_device(&info->dev);
++		return rc;
++	}
+ 
+ 	rc = ocxl_sysfs_register_afu(info);
+ 	if (rc)
+diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
+index d7ef61e602ede..b836936e97471 100644
+--- a/drivers/misc/sgi-gru/grufault.c
++++ b/drivers/misc/sgi-gru/grufault.c
+@@ -648,6 +648,7 @@ int gru_handle_user_call_os(unsigned long cb)
+ 	if ((cb & (GRU_HANDLE_STRIDE - 1)) || ucbnum >= GRU_NUM_CB)
+ 		return -EINVAL;
+ 
++again:
+ 	gts = gru_find_lock_gts(cb);
+ 	if (!gts)
+ 		return -EINVAL;
+@@ -656,7 +657,11 @@ int gru_handle_user_call_os(unsigned long cb)
+ 	if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE)
+ 		goto exit;
+ 
+-	gru_check_context_placement(gts);
++	if (gru_check_context_placement(gts)) {
++		gru_unlock_gts(gts);
++		gru_unload_context(gts, 1);
++		goto again;
++	}
+ 
+ 	/*
+ 	 * CCH may contain stale data if ts_force_cch_reload is set.
+@@ -874,7 +879,11 @@ int gru_set_context_option(unsigned long arg)
+ 		} else {
+ 			gts->ts_user_blade_id = req.val1;
+ 			gts->ts_user_chiplet_id = req.val0;
+-			gru_check_context_placement(gts);
++			if (gru_check_context_placement(gts)) {
++				gru_unlock_gts(gts);
++				gru_unload_context(gts, 1);
++				return ret;
++			}
+ 		}
+ 		break;
+ 	case sco_gseg_owner:
+diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
+index 9afda47efbf2e..3a16eb8e03f73 100644
+--- a/drivers/misc/sgi-gru/grumain.c
++++ b/drivers/misc/sgi-gru/grumain.c
+@@ -716,9 +716,10 @@ static int gru_check_chiplet_assignment(struct gru_state *gru,
+  * chiplet. Misassignment can occur if the process migrates to a different
+  * blade or if the user changes the selected blade/chiplet.
+  */
+-void gru_check_context_placement(struct gru_thread_state *gts)
++int gru_check_context_placement(struct gru_thread_state *gts)
+ {
+ 	struct gru_state *gru;
++	int ret = 0;
+ 
+ 	/*
+ 	 * If the current task is the context owner, verify that the
+@@ -726,15 +727,23 @@ void gru_check_context_placement(struct gru_thread_state *gts)
+ 	 * references. Pthread apps use non-owner references to the CBRs.
+ 	 */
+ 	gru = gts->ts_gru;
++	/*
++	 * If gru or gts->ts_tgid_owner isn't initialized properly, return
++	 * success to indicate that the caller does not need to unload the
++	 * gru context.The caller is responsible for their inspection and
++	 * reinitialization if needed.
++	 */
+ 	if (!gru || gts->ts_tgid_owner != current->tgid)
+-		return;
++		return ret;
+ 
+ 	if (!gru_check_chiplet_assignment(gru, gts)) {
+ 		STAT(check_context_unload);
+-		gru_unload_context(gts, 1);
++		ret = -EINVAL;
+ 	} else if (gru_retarget_intr(gts)) {
+ 		STAT(check_context_retarget_intr);
+ 	}
++
++	return ret;
+ }
+ 
+ 
+@@ -934,7 +943,12 @@ again:
+ 	mutex_lock(&gts->ts_ctxlock);
+ 	preempt_disable();
+ 
+-	gru_check_context_placement(gts);
++	if (gru_check_context_placement(gts)) {
++		preempt_enable();
++		mutex_unlock(&gts->ts_ctxlock);
++		gru_unload_context(gts, 1);
++		return VM_FAULT_NOPAGE;
++	}
+ 
+ 	if (!gts->ts_gru) {
+ 		STAT(load_user_context);
+diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h
+index 5efc869fe59a0..f4a5a787685fb 100644
+--- a/drivers/misc/sgi-gru/grutables.h
++++ b/drivers/misc/sgi-gru/grutables.h
+@@ -632,7 +632,7 @@ extern int gru_user_flush_tlb(unsigned long arg);
+ extern int gru_user_unload_context(unsigned long arg);
+ extern int gru_get_exception_detail(unsigned long arg);
+ extern int gru_set_context_option(unsigned long address);
+-extern void gru_check_context_placement(struct gru_thread_state *gts);
++extern int gru_check_context_placement(struct gru_thread_state *gts);
+ extern int gru_cpu_fault_map_id(void);
+ extern struct vm_area_struct *gru_find_vma(unsigned long vaddr);
+ extern void gru_flush_all_tlb(struct gru_state *gru);
+diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
+index 017c2f7d62871..7dd86a9858aba 100644
+--- a/drivers/misc/tifm_7xx1.c
++++ b/drivers/misc/tifm_7xx1.c
+@@ -190,7 +190,7 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
+ 				spin_unlock_irqrestore(&fm->lock, flags);
+ 			}
+ 			if (sock)
+-				tifm_free_device(&sock->dev);
++				put_device(&sock->dev);
+ 		}
+ 		spin_lock_irqsave(&fm->lock, flags);
+ 	}
+diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
+index 3662bf5320ce5..72b664ed90cf6 100644
+--- a/drivers/mmc/core/sd.c
++++ b/drivers/mmc/core/sd.c
+@@ -1259,7 +1259,7 @@ static int sd_read_ext_regs(struct mmc_card *card)
+ 	 */
+ 	err = sd_read_ext_reg(card, 0, 0, 0, 512, gen_info_buf);
+ 	if (err) {
+-		pr_warn("%s: error %d reading general info of SD ext reg\n",
++		pr_err("%s: error %d reading general info of SD ext reg\n",
+ 			mmc_hostname(card->host), err);
+ 		goto out;
+ 	}
+@@ -1273,7 +1273,12 @@ static int sd_read_ext_regs(struct mmc_card *card)
+ 	/* Number of extensions to be find. */
+ 	num_ext = gen_info_buf[4];
+ 
+-	/* We support revision 0, but limit it to 512 bytes for simplicity. */
++	/*
++	 * We only support revision 0 and limit it to 512 bytes for simplicity.
++	 * No matter what, let's return zero to allow us to continue using the
++	 * card, even if we can't support the features from the SD function
++	 * extensions registers.
++	 */
+ 	if (rev != 0 || len > 512) {
+ 		pr_warn("%s: non-supported SD ext reg layout\n",
+ 			mmc_hostname(card->host));
+@@ -1288,7 +1293,7 @@ static int sd_read_ext_regs(struct mmc_card *card)
+ 	for (i = 0; i < num_ext; i++) {
+ 		err = sd_parse_ext_reg(card, gen_info_buf, &next_ext_addr);
+ 		if (err) {
+-			pr_warn("%s: error %d parsing SD ext reg\n",
++			pr_err("%s: error %d parsing SD ext reg\n",
+ 				mmc_hostname(card->host), err);
+ 			goto out;
+ 		}
+diff --git a/drivers/mmc/host/alcor.c b/drivers/mmc/host/alcor.c
+index bfb8efeb7eb80..d01df01d4b4d1 100644
+--- a/drivers/mmc/host/alcor.c
++++ b/drivers/mmc/host/alcor.c
+@@ -1114,7 +1114,10 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev)
+ 	alcor_hw_init(host);
+ 
+ 	dev_set_drvdata(&pdev->dev, host);
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret)
++		goto free_host;
++
+ 	return 0;
+ 
+ free_host:
+diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
+index 91d52ba7a39fc..bb9bbf1c927b6 100644
+--- a/drivers/mmc/host/atmel-mci.c
++++ b/drivers/mmc/host/atmel-mci.c
+@@ -2222,6 +2222,7 @@ static int atmci_init_slot(struct atmel_mci *host,
+ {
+ 	struct mmc_host			*mmc;
+ 	struct atmel_mci_slot		*slot;
++	int ret;
+ 
+ 	mmc = mmc_alloc_host(sizeof(struct atmel_mci_slot), &host->pdev->dev);
+ 	if (!mmc)
+@@ -2305,11 +2306,13 @@ static int atmci_init_slot(struct atmel_mci *host,
+ 
+ 	host->slot[id] = slot;
+ 	mmc_regulator_get_supply(mmc);
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret) {
++		mmc_free_host(mmc);
++		return ret;
++	}
+ 
+ 	if (gpio_is_valid(slot->detect_pin)) {
+-		int ret;
+-
+ 		timer_setup(&slot->detect_timer, atmci_detect_change, 0);
+ 
+ 		ret = request_irq(gpio_to_irq(slot->detect_pin),
+diff --git a/drivers/mmc/host/litex_mmc.c b/drivers/mmc/host/litex_mmc.c
+index 6ba0d63b8c078..39c6707fdfdbc 100644
+--- a/drivers/mmc/host/litex_mmc.c
++++ b/drivers/mmc/host/litex_mmc.c
+@@ -502,6 +502,7 @@ static int litex_mmc_irq_init(struct platform_device *pdev,
+ 
+ use_polling:
+ 	host->mmc->caps |= MMC_CAP_NEEDS_POLL;
++	host->irq = 0;
+ 	return 0;
+ }
+ 
+diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
+index fc462995cf94a..4fd3d545e4081 100644
+--- a/drivers/mmc/host/meson-gx-mmc.c
++++ b/drivers/mmc/host/meson-gx-mmc.c
+@@ -1291,7 +1291,9 @@ static int meson_mmc_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	mmc->ops = &meson_mmc_ops;
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret)
++		goto err_free_irq;
+ 
+ 	return 0;
+ 
+diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
+index 012aa85489d86..b9e5dfe74e5c7 100644
+--- a/drivers/mmc/host/mmci.c
++++ b/drivers/mmc/host/mmci.c
+@@ -2256,7 +2256,9 @@ static int mmci_probe(struct amba_device *dev,
+ 	pm_runtime_set_autosuspend_delay(&dev->dev, 50);
+ 	pm_runtime_use_autosuspend(&dev->dev);
+ 
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret)
++		goto clk_disable;
+ 
+ 	pm_runtime_put(&dev->dev);
+ 	return 0;
+diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c
+index dfc3ffd5b1f8c..52ed30f2d9f4f 100644
+--- a/drivers/mmc/host/moxart-mmc.c
++++ b/drivers/mmc/host/moxart-mmc.c
+@@ -665,7 +665,9 @@ static int moxart_probe(struct platform_device *pdev)
+ 		goto out;
+ 
+ 	dev_set_drvdata(dev, mmc);
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret)
++		goto out;
+ 
+ 	dev_dbg(dev, "IRQ=%d, FIFO is %d bytes\n", irq, host->fifo_width);
+ 
+diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
+index 2cf0413407ea2..668f865f3efb0 100644
+--- a/drivers/mmc/host/mxcmmc.c
++++ b/drivers/mmc/host/mxcmmc.c
+@@ -1143,7 +1143,9 @@ static int mxcmci_probe(struct platform_device *pdev)
+ 
+ 	timer_setup(&host->watchdog, mxcmci_watchdog, 0);
+ 
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret)
++		goto out_free_dma;
+ 
+ 	return 0;
+ 
+diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
+index fca30add563e9..4bd7447552055 100644
+--- a/drivers/mmc/host/omap_hsmmc.c
++++ b/drivers/mmc/host/omap_hsmmc.c
+@@ -1946,7 +1946,9 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
+ 	if (!ret)
+ 		mmc->caps |= MMC_CAP_SDIO_IRQ;
+ 
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret)
++		goto err_irq;
+ 
+ 	if (mmc_pdata(host)->name != NULL) {
+ 		ret = device_create_file(&mmc->class_dev, &dev_attr_slot_name);
+diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
+index e4003f6058eb5..2a988f942b6ca 100644
+--- a/drivers/mmc/host/pxamci.c
++++ b/drivers/mmc/host/pxamci.c
+@@ -763,7 +763,12 @@ static int pxamci_probe(struct platform_device *pdev)
+ 			dev_warn(dev, "gpio_ro and get_ro() both defined\n");
+ 	}
+ 
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret) {
++		if (host->pdata && host->pdata->exit)
++			host->pdata->exit(dev, mmc);
++		goto out;
++	}
+ 
+ 	return 0;
+ 
+diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
+index c4abfee1ebae1..e4c490729c98e 100644
+--- a/drivers/mmc/host/renesas_sdhi.h
++++ b/drivers/mmc/host/renesas_sdhi.h
+@@ -44,6 +44,7 @@ struct renesas_sdhi_quirks {
+ 	bool fixed_addr_mode;
+ 	bool dma_one_rx_only;
+ 	bool manual_tap_correction;
++	bool old_info1_layout;
+ 	u32 hs400_bad_taps;
+ 	const u8 (*hs400_calib_table)[SDHI_CALIB_TABLE_MAX];
+ };
+diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
+index b970699743e0a..e38d0e8b8e0ed 100644
+--- a/drivers/mmc/host/renesas_sdhi_core.c
++++ b/drivers/mmc/host/renesas_sdhi_core.c
+@@ -546,7 +546,7 @@ static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host,
+ 			 SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) &
+ 			sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2));
+ 
+-	if (priv->adjust_hs400_calib_table)
++	if (priv->quirks && (priv->quirks->hs400_calib_table || priv->quirks->hs400_bad_taps))
+ 		renesas_sdhi_adjust_hs400_mode_disable(host);
+ 
+ 	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
+@@ -1068,11 +1068,14 @@ int renesas_sdhi_probe(struct platform_device *pdev,
+ 	if (ver >= SDHI_VER_GEN3_SD)
+ 		host->get_timeout_cycles = renesas_sdhi_gen3_get_cycles;
+ 
++	/* Check for SCC so we can reset it if needed */
++	if (of_data && of_data->scc_offset && ver >= SDHI_VER_GEN2_SDR104)
++		priv->scc_ctl = host->ctl + of_data->scc_offset;
++
+ 	/* Enable tuning iff we have an SCC and a supported mode */
+-	if (of_data && of_data->scc_offset &&
+-	    (host->mmc->caps & MMC_CAP_UHS_SDR104 ||
+-	     host->mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR |
+-				 MMC_CAP2_HS400_1_8V))) {
++	if (priv->scc_ctl && (host->mmc->caps & MMC_CAP_UHS_SDR104 ||
++	    host->mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR |
++				MMC_CAP2_HS400_1_8V))) {
+ 		const struct renesas_sdhi_scc *taps = of_data->taps;
+ 		bool use_4tap = quirks && quirks->hs400_4taps;
+ 		bool hit = false;
+@@ -1092,7 +1095,6 @@ int renesas_sdhi_probe(struct platform_device *pdev,
+ 		if (!hit)
+ 			dev_warn(&host->pdev->dev, "Unknown clock rate for tuning\n");
+ 
+-		priv->scc_ctl = host->ctl + of_data->scc_offset;
+ 		host->check_retune = renesas_sdhi_check_scc_error;
+ 		host->ops.execute_tuning = renesas_sdhi_execute_tuning;
+ 		host->ops.prepare_hs400_tuning = renesas_sdhi_prepare_hs400_tuning;
+diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+index 42937596c4c41..7c81c2680701f 100644
+--- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
++++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+@@ -49,7 +49,8 @@
+ /* DM_CM_INFO1 and DM_CM_INFO1_MASK */
+ #define INFO1_CLEAR		0
+ #define INFO1_MASK_CLEAR	GENMASK_ULL(31, 0)
+-#define INFO1_DTRANEND1		BIT(17)
++#define INFO1_DTRANEND1		BIT(20)
++#define INFO1_DTRANEND1_OLD	BIT(17)
+ #define INFO1_DTRANEND0		BIT(16)
+ 
+ /* DM_CM_INFO2 and DM_CM_INFO2_MASK */
+@@ -165,6 +166,7 @@ static const struct renesas_sdhi_quirks sdhi_quirks_4tap_nohs400_one_rx = {
+ 	.hs400_disabled = true,
+ 	.hs400_4taps = true,
+ 	.dma_one_rx_only = true,
++	.old_info1_layout = true,
+ };
+ 
+ static const struct renesas_sdhi_quirks sdhi_quirks_4tap = {
+diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c
+index e1580f78c6b2d..8098726dcc0bf 100644
+--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
++++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
+@@ -1474,6 +1474,7 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
+ 	struct realtek_pci_sdmmc *host;
+ 	struct rtsx_pcr *pcr;
+ 	struct pcr_handle *handle = pdev->dev.platform_data;
++	int ret;
+ 
+ 	if (!handle)
+ 		return -ENXIO;
+@@ -1511,7 +1512,13 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev)
+ 	pm_runtime_mark_last_busy(&pdev->dev);
+ 	pm_runtime_use_autosuspend(&pdev->dev);
+ 
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret) {
++		pm_runtime_dont_use_autosuspend(&pdev->dev);
++		pm_runtime_disable(&pdev->dev);
++		mmc_free_host(mmc);
++		return ret;
++	}
+ 
+ 	return 0;
+ }
+diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
+index 5fe4528e296e6..1be3a355f10d5 100644
+--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
++++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
+@@ -1332,6 +1332,7 @@ static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
+ #ifdef RTSX_USB_USE_LEDS_CLASS
+ 	int err;
+ #endif
++	int ret;
+ 
+ 	ucr = usb_get_intfdata(to_usb_interface(pdev->dev.parent));
+ 	if (!ucr)
+@@ -1368,7 +1369,15 @@ static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
+ 	INIT_WORK(&host->led_work, rtsx_usb_update_led);
+ 
+ #endif
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret) {
++#ifdef RTSX_USB_USE_LEDS_CLASS
++		led_classdev_unregister(&host->led);
++#endif
++		mmc_free_host(mmc);
++		pm_runtime_disable(&pdev->dev);
++		return ret;
++	}
+ 
+ 	return 0;
+ }
+diff --git a/drivers/mmc/host/sdhci_f_sdh30.c b/drivers/mmc/host/sdhci_f_sdh30.c
+index 3f5977979cf25..6c4f43e112826 100644
+--- a/drivers/mmc/host/sdhci_f_sdh30.c
++++ b/drivers/mmc/host/sdhci_f_sdh30.c
+@@ -168,6 +168,9 @@ static int sdhci_f_sdh30_probe(struct platform_device *pdev)
+ 	if (reg & SDHCI_CAN_DO_8BIT)
+ 		priv->vendor_hs200 = F_SDH30_EMMC_HS200;
+ 
++	if (!(reg & SDHCI_TIMEOUT_CLK_MASK))
++		host->quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;
++
+ 	ret = sdhci_add_host(host);
+ 	if (ret)
+ 		goto err_add_host;
+diff --git a/drivers/mmc/host/toshsd.c b/drivers/mmc/host/toshsd.c
+index 8d037c2071abc..497791ffada6d 100644
+--- a/drivers/mmc/host/toshsd.c
++++ b/drivers/mmc/host/toshsd.c
+@@ -651,7 +651,9 @@ static int toshsd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	if (ret)
+ 		goto unmap;
+ 
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret)
++		goto free_irq;
+ 
+ 	base = pci_resource_start(pdev, 0);
+ 	dev_dbg(&pdev->dev, "MMIO %pa, IRQ %d\n", &base, pdev->irq);
+@@ -660,6 +662,8 @@ static int toshsd_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 
+ 	return 0;
+ 
++free_irq:
++	free_irq(pdev->irq, host);
+ unmap:
+ 	pci_iounmap(pdev, host->ioaddr);
+ release:
+diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
+index 88662a90ed960..a2b0d9461665b 100644
+--- a/drivers/mmc/host/via-sdmmc.c
++++ b/drivers/mmc/host/via-sdmmc.c
+@@ -1151,7 +1151,9 @@ static int via_sd_probe(struct pci_dev *pcidev,
+ 	    pcidev->subsystem_device == 0x3891)
+ 		sdhost->quirks = VIA_CRDR_QUIRK_300MS_PWRDELAY;
+ 
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret)
++		goto unmap;
+ 
+ 	return 0;
+ 
+diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
+index 97beece62fec4..ab36ec4797478 100644
+--- a/drivers/mmc/host/vub300.c
++++ b/drivers/mmc/host/vub300.c
+@@ -2299,14 +2299,14 @@ static int vub300_probe(struct usb_interface *interface,
+ 				0x0000, 0x0000, &vub300->system_port_status,
+ 				sizeof(vub300->system_port_status), 1000);
+ 	if (retval < 0) {
+-		goto error4;
++		goto error5;
+ 	} else if (sizeof(vub300->system_port_status) == retval) {
+ 		vub300->card_present =
+ 			(0x0001 & vub300->system_port_status.port_flags) ? 1 : 0;
+ 		vub300->read_only =
+ 			(0x0010 & vub300->system_port_status.port_flags) ? 1 : 0;
+ 	} else {
+-		goto error4;
++		goto error5;
+ 	}
+ 	usb_set_intfdata(interface, vub300);
+ 	INIT_DELAYED_WORK(&vub300->pollwork, vub300_pollwork_thread);
+@@ -2329,8 +2329,13 @@ static int vub300_probe(struct usb_interface *interface,
+ 			 "USB vub300 remote SDIO host controller[%d]"
+ 			 "connected with no SD/SDIO card inserted\n",
+ 			 interface_to_InterfaceNumber(interface));
+-	mmc_add_host(mmc);
++	retval = mmc_add_host(mmc);
++	if (retval)
++		goto error6;
++
+ 	return 0;
++error6:
++	del_timer_sync(&vub300->inactivity_timer);
+ error5:
+ 	mmc_free_host(mmc);
+ 	/*
+diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
+index 67ecd342fe5f1..7c7ec8d10232b 100644
+--- a/drivers/mmc/host/wbsd.c
++++ b/drivers/mmc/host/wbsd.c
+@@ -1698,7 +1698,17 @@ static int wbsd_init(struct device *dev, int base, int irq, int dma,
+ 	 */
+ 	wbsd_init_device(host);
+ 
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret) {
++		if (!pnp)
++			wbsd_chip_poweroff(host);
++
++		wbsd_release_resources(host);
++		wbsd_free_mmc(dev);
++
++		mmc_free_host(mmc);
++		return ret;
++	}
+ 
+ 	pr_info("%s: W83L51xD", mmc_hostname(mmc));
+ 	if (host->chip_id != 0)
+diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c
+index 9b5c503e3a3fc..9aa3027ca25e4 100644
+--- a/drivers/mmc/host/wmt-sdmmc.c
++++ b/drivers/mmc/host/wmt-sdmmc.c
+@@ -856,11 +856,15 @@ static int wmt_mci_probe(struct platform_device *pdev)
+ 	/* configure the controller to a known 'ready' state */
+ 	wmt_reset_hardware(mmc);
+ 
+-	mmc_add_host(mmc);
++	ret = mmc_add_host(mmc);
++	if (ret)
++		goto fail7;
+ 
+ 	dev_info(&pdev->dev, "WMT SDHC Controller initialized\n");
+ 
+ 	return 0;
++fail7:
++	clk_disable_unprepare(priv->clk_sdmmc);
+ fail6:
+ 	clk_put(priv->clk_sdmmc);
+ fail5_and_a_half:
+diff --git a/drivers/mtd/lpddr/lpddr2_nvm.c b/drivers/mtd/lpddr/lpddr2_nvm.c
+index 367e2d906de02..e71af4c490969 100644
+--- a/drivers/mtd/lpddr/lpddr2_nvm.c
++++ b/drivers/mtd/lpddr/lpddr2_nvm.c
+@@ -433,6 +433,8 @@ static int lpddr2_nvm_probe(struct platform_device *pdev)
+ 
+ 	/* lpddr2_nvm address range */
+ 	add_range = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!add_range)
++		return -ENODEV;
+ 
+ 	/* Populate map_info data structure */
+ 	*map = (struct map_info) {
+diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
+index 1749dbbacc135..62a5bf41a6d72 100644
+--- a/drivers/mtd/maps/pxa2xx-flash.c
++++ b/drivers/mtd/maps/pxa2xx-flash.c
+@@ -64,6 +64,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev)
+ 	if (!info->map.virt) {
+ 		printk(KERN_WARNING "Failed to ioremap %s\n",
+ 		       info->map.name);
++		kfree(info);
+ 		return -ENOMEM;
+ 	}
+ 	info->map.cached = ioremap_cache(info->map.phys, info->map.size);
+@@ -85,6 +86,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev)
+ 		iounmap((void *)info->map.virt);
+ 		if (info->map.cached)
+ 			iounmap(info->map.cached);
++		kfree(info);
+ 		return -EIO;
+ 	}
+ 	info->mtd->dev.parent = &pdev->dev;
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index 477707bcad972..c14196bbf008e 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -723,8 +723,10 @@ int add_mtd_device(struct mtd_info *mtd)
+ 	mtd_check_of_node(mtd);
+ 	of_node_get(mtd_get_of_node(mtd));
+ 	error = device_register(&mtd->dev);
+-	if (error)
++	if (error) {
++		put_device(&mtd->dev);
+ 		goto fail_added;
++	}
+ 
+ 	/* Add the nvmem provider */
+ 	error = mtd_nvmem_add(mtd);
+@@ -774,6 +776,7 @@ int del_mtd_device(struct mtd_info *mtd)
+ {
+ 	int ret;
+ 	struct mtd_notifier *not;
++	struct device_node *mtd_of_node;
+ 
+ 	mutex_lock(&mtd_table_mutex);
+ 
+@@ -792,6 +795,7 @@ int del_mtd_device(struct mtd_info *mtd)
+ 		       mtd->index, mtd->name, mtd->usecount);
+ 		ret = -EBUSY;
+ 	} else {
++		mtd_of_node = mtd_get_of_node(mtd);
+ 		debugfs_remove_recursive(mtd->dbg.dfs_dir);
+ 
+ 		/* Try to remove the NVMEM provider */
+@@ -803,7 +807,7 @@ int del_mtd_device(struct mtd_info *mtd)
+ 		memset(&mtd->dev, 0, sizeof(mtd->dev));
+ 
+ 		idr_remove(&mtd_idr, mtd->index);
+-		of_node_put(mtd_get_of_node(mtd));
++		of_node_put(mtd_of_node);
+ 
+ 		module_put(THIS_MODULE);
+ 		ret = 0;
+@@ -2450,6 +2454,7 @@ static int __init init_mtd(void)
+ out_procfs:
+ 	if (proc_mtd)
+ 		remove_proc_entry("mtd", NULL);
++	bdi_unregister(mtd_bdi);
+ 	bdi_put(mtd_bdi);
+ err_bdi:
+ 	class_unregister(&mtd_class);
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index bee8fc4c9f078..0cf1a1797ea32 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -1914,7 +1914,8 @@ static int spi_nor_spimem_check_readop(struct spi_nor *nor,
+ 	spi_nor_spimem_setup_op(nor, &op, read->proto);
+ 
+ 	/* convert the dummy cycles to the number of bytes */
+-	op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;
++	op.dummy.nbytes = (read->num_mode_clocks + read->num_wait_states) *
++			  op.dummy.buswidth / 8;
+ 	if (spi_nor_protocol_is_dtr(nor->read_proto))
+ 		op.dummy.nbytes *= 2;
+ 
+diff --git a/drivers/mtd/spi-nor/sysfs.c b/drivers/mtd/spi-nor/sysfs.c
+index 9aec9d8a98ada..4c3b351aef245 100644
+--- a/drivers/mtd/spi-nor/sysfs.c
++++ b/drivers/mtd/spi-nor/sysfs.c
+@@ -67,6 +67,19 @@ static struct bin_attribute *spi_nor_sysfs_bin_entries[] = {
+ 	NULL
+ };
+ 
++static umode_t spi_nor_sysfs_is_visible(struct kobject *kobj,
++					struct attribute *attr, int n)
++{
++	struct spi_device *spi = to_spi_device(kobj_to_dev(kobj));
++	struct spi_mem *spimem = spi_get_drvdata(spi);
++	struct spi_nor *nor = spi_mem_get_drvdata(spimem);
++
++	if (attr == &dev_attr_jedec_id.attr && !nor->info->id_len)
++		return 0;
++
++	return 0444;
++}
++
+ static umode_t spi_nor_sysfs_is_bin_visible(struct kobject *kobj,
+ 					    struct bin_attribute *attr, int n)
+ {
+@@ -82,6 +95,7 @@ static umode_t spi_nor_sysfs_is_bin_visible(struct kobject *kobj,
+ 
+ static const struct attribute_group spi_nor_sysfs_group = {
+ 	.name		= "spi-nor",
++	.is_visible	= spi_nor_sysfs_is_visible,
+ 	.is_bin_visible	= spi_nor_sysfs_is_bin_visible,
+ 	.attrs		= spi_nor_sysfs_entries,
+ 	.bin_attrs	= spi_nor_sysfs_bin_entries,
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index c2939621b683c..771f2a533d3f6 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -2531,12 +2531,21 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
+ /* called with rcu_read_lock() */
+ static int bond_miimon_inspect(struct bonding *bond)
+ {
++	bool ignore_updelay = false;
+ 	int link_state, commit = 0;
+ 	struct list_head *iter;
+ 	struct slave *slave;
+-	bool ignore_updelay;
+ 
+-	ignore_updelay = !rcu_dereference(bond->curr_active_slave);
++	if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) {
++		ignore_updelay = !rcu_dereference(bond->curr_active_slave);
++	} else {
++		struct bond_up_slave *usable_slaves;
++
++		usable_slaves = rcu_dereference(bond->usable_slaves);
++
++		if (usable_slaves && usable_slaves->count == 0)
++			ignore_updelay = true;
++	}
+ 
+ 	bond_for_each_slave_rcu(bond, slave, iter) {
+ 		bond_propose_link_state(slave, BOND_LINK_NOCHANGE);
+@@ -2644,8 +2653,9 @@ static void bond_miimon_link_change(struct bonding *bond,
+ 
+ static void bond_miimon_commit(struct bonding *bond)
+ {
+-	struct list_head *iter;
+ 	struct slave *slave, *primary;
++	bool do_failover = false;
++	struct list_head *iter;
+ 
+ 	bond_for_each_slave(bond, slave, iter) {
+ 		switch (slave->link_new_state) {
+@@ -2689,8 +2699,9 @@ static void bond_miimon_commit(struct bonding *bond)
+ 
+ 			bond_miimon_link_change(bond, slave, BOND_LINK_UP);
+ 
+-			if (!bond->curr_active_slave || slave == primary)
+-				goto do_failover;
++			if (!rcu_access_pointer(bond->curr_active_slave) || slave == primary ||
++			    slave->prio > rcu_dereference(bond->curr_active_slave)->prio)
++				do_failover = true;
+ 
+ 			continue;
+ 
+@@ -2711,7 +2722,7 @@ static void bond_miimon_commit(struct bonding *bond)
+ 			bond_miimon_link_change(bond, slave, BOND_LINK_DOWN);
+ 
+ 			if (slave == rcu_access_pointer(bond->curr_active_slave))
+-				goto do_failover;
++				do_failover = true;
+ 
+ 			continue;
+ 
+@@ -2722,8 +2733,9 @@ static void bond_miimon_commit(struct bonding *bond)
+ 
+ 			continue;
+ 		}
++	}
+ 
+-do_failover:
++	if (do_failover) {
+ 		block_netpoll_tx();
+ 		bond_select_active_slave(bond);
+ 		unblock_netpoll_tx();
+@@ -3521,6 +3533,7 @@ static int bond_ab_arp_inspect(struct bonding *bond)
+  */
+ static void bond_ab_arp_commit(struct bonding *bond)
+ {
++	bool do_failover = false;
+ 	struct list_head *iter;
+ 	unsigned long last_tx;
+ 	struct slave *slave;
+@@ -3550,8 +3563,9 @@ static void bond_ab_arp_commit(struct bonding *bond)
+ 				slave_info(bond->dev, slave->dev, "link status definitely up\n");
+ 
+ 				if (!rtnl_dereference(bond->curr_active_slave) ||
+-				    slave == rtnl_dereference(bond->primary_slave))
+-					goto do_failover;
++				    slave == rtnl_dereference(bond->primary_slave) ||
++				    slave->prio > rtnl_dereference(bond->curr_active_slave)->prio)
++					do_failover = true;
+ 
+ 			}
+ 
+@@ -3570,7 +3584,7 @@ static void bond_ab_arp_commit(struct bonding *bond)
+ 
+ 			if (slave == rtnl_dereference(bond->curr_active_slave)) {
+ 				RCU_INIT_POINTER(bond->current_arp_slave, NULL);
+-				goto do_failover;
++				do_failover = true;
+ 			}
+ 
+ 			continue;
+@@ -3594,8 +3608,9 @@ static void bond_ab_arp_commit(struct bonding *bond)
+ 				  slave->link_new_state);
+ 			continue;
+ 		}
++	}
+ 
+-do_failover:
++	if (do_failover) {
+ 		block_netpoll_tx();
+ 		bond_select_active_slave(bond);
+ 		unblock_netpoll_tx();
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index 153d8fd08bd88..a562f36a99f8a 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -1233,10 +1233,17 @@ static int m_can_set_bittiming(struct net_device *dev)
+  * - setup bittiming
+  * - configure timestamp generation
+  */
+-static void m_can_chip_config(struct net_device *dev)
++static int m_can_chip_config(struct net_device *dev)
+ {
+ 	struct m_can_classdev *cdev = netdev_priv(dev);
+ 	u32 cccr, test;
++	int err;
++
++	err = m_can_init_ram(cdev);
++	if (err) {
++		dev_err(cdev->dev, "Message RAM configuration failed\n");
++		return err;
++	}
+ 
+ 	m_can_config_endisable(cdev, true);
+ 
+@@ -1360,18 +1367,25 @@ static void m_can_chip_config(struct net_device *dev)
+ 
+ 	if (cdev->ops->init)
+ 		cdev->ops->init(cdev);
++
++	return 0;
+ }
+ 
+-static void m_can_start(struct net_device *dev)
++static int m_can_start(struct net_device *dev)
+ {
+ 	struct m_can_classdev *cdev = netdev_priv(dev);
++	int ret;
+ 
+ 	/* basic m_can configuration */
+-	m_can_chip_config(dev);
++	ret = m_can_chip_config(dev);
++	if (ret)
++		return ret;
+ 
+ 	cdev->can.state = CAN_STATE_ERROR_ACTIVE;
+ 
+ 	m_can_enable_all_interrupts(cdev);
++
++	return 0;
+ }
+ 
+ static int m_can_set_mode(struct net_device *dev, enum can_mode mode)
+@@ -1800,7 +1814,9 @@ static int m_can_open(struct net_device *dev)
+ 	}
+ 
+ 	/* start the m_can controller */
+-	m_can_start(dev);
++	err = m_can_start(dev);
++	if (err)
++		goto exit_irq_fail;
+ 
+ 	if (!cdev->is_peripheral)
+ 		napi_enable(&cdev->napi);
+@@ -2059,9 +2075,13 @@ int m_can_class_resume(struct device *dev)
+ 		ret = m_can_clk_start(cdev);
+ 		if (ret)
+ 			return ret;
++		ret  = m_can_start(ndev);
++		if (ret) {
++			m_can_clk_stop(cdev);
++
++			return ret;
++		}
+ 
+-		m_can_init_ram(cdev);
+-		m_can_start(ndev);
+ 		netif_device_attach(ndev);
+ 		netif_start_queue(ndev);
+ 	}
+diff --git a/drivers/net/can/m_can/m_can_platform.c b/drivers/net/can/m_can/m_can_platform.c
+index eee47bad05920..de6d8e01bf2e8 100644
+--- a/drivers/net/can/m_can/m_can_platform.c
++++ b/drivers/net/can/m_can/m_can_platform.c
+@@ -140,10 +140,6 @@ static int m_can_plat_probe(struct platform_device *pdev)
+ 
+ 	platform_set_drvdata(pdev, mcan_class);
+ 
+-	ret = m_can_init_ram(mcan_class);
+-	if (ret)
+-		goto probe_fail;
+-
+ 	pm_runtime_enable(mcan_class->dev);
+ 	ret = m_can_class_register(mcan_class);
+ 	if (ret)
+diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c
+index 41645a24384ce..2342aa011647c 100644
+--- a/drivers/net/can/m_can/tcan4x5x-core.c
++++ b/drivers/net/can/m_can/tcan4x5x-core.c
+@@ -10,7 +10,7 @@
+ #define TCAN4X5X_DEV_ID1 0x04
+ #define TCAN4X5X_REV 0x08
+ #define TCAN4X5X_STATUS 0x0C
+-#define TCAN4X5X_ERROR_STATUS 0x10
++#define TCAN4X5X_ERROR_STATUS_MASK 0x10
+ #define TCAN4X5X_CONTROL 0x14
+ 
+ #define TCAN4X5X_CONFIG 0x800
+@@ -204,17 +204,7 @@ static int tcan4x5x_clear_interrupts(struct m_can_classdev *cdev)
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_MCAN_INT_REG,
+-				      TCAN4X5X_ENABLE_MCAN_INT);
+-	if (ret)
+-		return ret;
+-
+-	ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_INT_FLAGS,
+-				      TCAN4X5X_CLEAR_ALL_INT);
+-	if (ret)
+-		return ret;
+-
+-	return tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_ERROR_STATUS,
++	return tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_INT_FLAGS,
+ 				       TCAN4X5X_CLEAR_ALL_INT);
+ }
+ 
+@@ -234,8 +224,8 @@ static int tcan4x5x_init(struct m_can_classdev *cdev)
+ 	if (ret)
+ 		return ret;
+ 
+-	/* Zero out the MCAN buffers */
+-	ret = m_can_init_ram(cdev);
++	ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_ERROR_STATUS_MASK,
++				      TCAN4X5X_CLEAR_ALL_INT);
+ 	if (ret)
+ 		return ret;
+ 
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+index f6c0938027ece..ff10b3790d844 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+@@ -76,6 +76,14 @@ struct kvaser_usb_tx_urb_context {
+ 	u32 echo_index;
+ };
+ 
++struct kvaser_usb_busparams {
++	__le32 bitrate;
++	u8 tseg1;
++	u8 tseg2;
++	u8 sjw;
++	u8 nsamples;
++} __packed;
++
+ struct kvaser_usb {
+ 	struct usb_device *udev;
+ 	struct usb_interface *intf;
+@@ -104,13 +112,19 @@ struct kvaser_usb_net_priv {
+ 	struct can_priv can;
+ 	struct can_berr_counter bec;
+ 
++	/* subdriver-specific data */
++	void *sub_priv;
++
+ 	struct kvaser_usb *dev;
+ 	struct net_device *netdev;
+ 	int channel;
+ 
+-	struct completion start_comp, stop_comp, flush_comp;
++	struct completion start_comp, stop_comp, flush_comp,
++			  get_busparams_comp;
+ 	struct usb_anchor tx_submitted;
+ 
++	struct kvaser_usb_busparams busparams_nominal, busparams_data;
++
+ 	spinlock_t tx_contexts_lock; /* lock for active_tx_contexts */
+ 	int active_tx_contexts;
+ 	struct kvaser_usb_tx_urb_context tx_contexts[];
+@@ -120,11 +134,15 @@ struct kvaser_usb_net_priv {
+  * struct kvaser_usb_dev_ops - Device specific functions
+  * @dev_set_mode:		used for can.do_set_mode
+  * @dev_set_bittiming:		used for can.do_set_bittiming
++ * @dev_get_busparams:		readback arbitration busparams
+  * @dev_set_data_bittiming:	used for can.do_set_data_bittiming
++ * @dev_get_data_busparams:	readback data busparams
+  * @dev_get_berr_counter:	used for can.do_get_berr_counter
+  *
+  * @dev_setup_endpoints:	setup USB in and out endpoints
+  * @dev_init_card:		initialize card
++ * @dev_init_channel:		initialize channel
++ * @dev_remove_channel:		uninitialize channel
+  * @dev_get_software_info:	get software info
+  * @dev_get_software_details:	get software details
+  * @dev_get_card_info:		get card info
+@@ -140,12 +158,18 @@ struct kvaser_usb_net_priv {
+  */
+ struct kvaser_usb_dev_ops {
+ 	int (*dev_set_mode)(struct net_device *netdev, enum can_mode mode);
+-	int (*dev_set_bittiming)(struct net_device *netdev);
+-	int (*dev_set_data_bittiming)(struct net_device *netdev);
++	int (*dev_set_bittiming)(const struct net_device *netdev,
++				 const struct kvaser_usb_busparams *busparams);
++	int (*dev_get_busparams)(struct kvaser_usb_net_priv *priv);
++	int (*dev_set_data_bittiming)(const struct net_device *netdev,
++				      const struct kvaser_usb_busparams *busparams);
++	int (*dev_get_data_busparams)(struct kvaser_usb_net_priv *priv);
+ 	int (*dev_get_berr_counter)(const struct net_device *netdev,
+ 				    struct can_berr_counter *bec);
+ 	int (*dev_setup_endpoints)(struct kvaser_usb *dev);
+ 	int (*dev_init_card)(struct kvaser_usb *dev);
++	int (*dev_init_channel)(struct kvaser_usb_net_priv *priv);
++	void (*dev_remove_channel)(struct kvaser_usb_net_priv *priv);
+ 	int (*dev_get_software_info)(struct kvaser_usb *dev);
+ 	int (*dev_get_software_details)(struct kvaser_usb *dev);
+ 	int (*dev_get_card_info)(struct kvaser_usb *dev);
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+index 802e27c0ecedb..3a2bfaad14065 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+@@ -440,10 +440,6 @@ static int kvaser_usb_open(struct net_device *netdev)
+ 	if (err)
+ 		return err;
+ 
+-	err = kvaser_usb_setup_rx_urbs(dev);
+-	if (err)
+-		goto error;
+-
+ 	err = ops->dev_set_opt_mode(priv);
+ 	if (err)
+ 		goto error;
+@@ -534,6 +530,93 @@ static int kvaser_usb_close(struct net_device *netdev)
+ 	return 0;
+ }
+ 
++static int kvaser_usb_set_bittiming(struct net_device *netdev)
++{
++	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
++	struct kvaser_usb *dev = priv->dev;
++	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
++	struct can_bittiming *bt = &priv->can.bittiming;
++
++	struct kvaser_usb_busparams busparams;
++	int tseg1 = bt->prop_seg + bt->phase_seg1;
++	int tseg2 = bt->phase_seg2;
++	int sjw = bt->sjw;
++	int err = -EOPNOTSUPP;
++
++	busparams.bitrate = cpu_to_le32(bt->bitrate);
++	busparams.sjw = (u8)sjw;
++	busparams.tseg1 = (u8)tseg1;
++	busparams.tseg2 = (u8)tseg2;
++	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
++		busparams.nsamples = 3;
++	else
++		busparams.nsamples = 1;
++
++	err = ops->dev_set_bittiming(netdev, &busparams);
++	if (err)
++		return err;
++
++	err = kvaser_usb_setup_rx_urbs(priv->dev);
++	if (err)
++		return err;
++
++	err = ops->dev_get_busparams(priv);
++	if (err) {
++		/* Treat EOPNOTSUPP as success */
++		if (err == -EOPNOTSUPP)
++			err = 0;
++		return err;
++	}
++
++	if (memcmp(&busparams, &priv->busparams_nominal,
++		   sizeof(priv->busparams_nominal)) != 0)
++		err = -EINVAL;
++
++	return err;
++}
++
++static int kvaser_usb_set_data_bittiming(struct net_device *netdev)
++{
++	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
++	struct kvaser_usb *dev = priv->dev;
++	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
++	struct can_bittiming *dbt = &priv->can.data_bittiming;
++
++	struct kvaser_usb_busparams busparams;
++	int tseg1 = dbt->prop_seg + dbt->phase_seg1;
++	int tseg2 = dbt->phase_seg2;
++	int sjw = dbt->sjw;
++	int err;
++
++	if (!ops->dev_set_data_bittiming ||
++	    !ops->dev_get_data_busparams)
++		return -EOPNOTSUPP;
++
++	busparams.bitrate = cpu_to_le32(dbt->bitrate);
++	busparams.sjw = (u8)sjw;
++	busparams.tseg1 = (u8)tseg1;
++	busparams.tseg2 = (u8)tseg2;
++	busparams.nsamples = 1;
++
++	err = ops->dev_set_data_bittiming(netdev, &busparams);
++	if (err)
++		return err;
++
++	err = kvaser_usb_setup_rx_urbs(priv->dev);
++	if (err)
++		return err;
++
++	err = ops->dev_get_data_busparams(priv);
++	if (err)
++		return err;
++
++	if (memcmp(&busparams, &priv->busparams_data,
++		   sizeof(priv->busparams_data)) != 0)
++		err = -EINVAL;
++
++	return err;
++}
++
+ static void kvaser_usb_write_bulk_callback(struct urb *urb)
+ {
+ 	struct kvaser_usb_tx_urb_context *context = urb->context;
+@@ -684,6 +767,7 @@ static const struct ethtool_ops kvaser_usb_ethtool_ops_hwts = {
+ 
+ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
+ {
++	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;
+ 	int i;
+ 
+ 	for (i = 0; i < dev->nchannels; i++) {
+@@ -699,6 +783,9 @@ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
+ 		if (!dev->nets[i])
+ 			continue;
+ 
++		if (ops->dev_remove_channel)
++			ops->dev_remove_channel(dev->nets[i]);
++
+ 		free_candev(dev->nets[i]->netdev);
+ 	}
+ }
+@@ -730,6 +817,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+ 	init_completion(&priv->start_comp);
+ 	init_completion(&priv->stop_comp);
+ 	init_completion(&priv->flush_comp);
++	init_completion(&priv->get_busparams_comp);
+ 	priv->can.ctrlmode_supported = 0;
+ 
+ 	priv->dev = dev;
+@@ -742,7 +830,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+ 	priv->can.state = CAN_STATE_STOPPED;
+ 	priv->can.clock.freq = dev->cfg->clock.freq;
+ 	priv->can.bittiming_const = dev->cfg->bittiming_const;
+-	priv->can.do_set_bittiming = ops->dev_set_bittiming;
++	priv->can.do_set_bittiming = kvaser_usb_set_bittiming;
+ 	priv->can.do_set_mode = ops->dev_set_mode;
+ 	if ((driver_info->quirks & KVASER_USB_QUIRK_HAS_TXRX_ERRORS) ||
+ 	    (priv->dev->card_data.capabilities & KVASER_USB_CAP_BERR_CAP))
+@@ -754,7 +842,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+ 
+ 	if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) {
+ 		priv->can.data_bittiming_const = dev->cfg->data_bittiming_const;
+-		priv->can.do_set_data_bittiming = ops->dev_set_data_bittiming;
++		priv->can.do_set_data_bittiming = kvaser_usb_set_data_bittiming;
+ 	}
+ 
+ 	netdev->flags |= IFF_ECHO;
+@@ -772,17 +860,26 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+ 
+ 	dev->nets[channel] = priv;
+ 
++	if (ops->dev_init_channel) {
++		err = ops->dev_init_channel(priv);
++		if (err)
++			goto err;
++	}
++
+ 	err = register_candev(netdev);
+ 	if (err) {
+ 		dev_err(&dev->intf->dev, "Failed to register CAN device\n");
+-		free_candev(netdev);
+-		dev->nets[channel] = NULL;
+-		return err;
++		goto err;
+ 	}
+ 
+ 	netdev_dbg(netdev, "device registered\n");
+ 
+ 	return 0;
++
++err:
++	free_candev(netdev);
++	dev->nets[channel] = NULL;
++	return err;
+ }
+ 
+ static int kvaser_usb_probe(struct usb_interface *intf,
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index 3abfaa77e8935..52ef76bd9bdb8 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -45,6 +45,8 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt;
+ 
+ /* Minihydra command IDs */
+ #define CMD_SET_BUSPARAMS_REQ			16
++#define CMD_GET_BUSPARAMS_REQ			17
++#define CMD_GET_BUSPARAMS_RESP			18
+ #define CMD_GET_CHIP_STATE_REQ			19
+ #define CMD_CHIP_STATE_EVENT			20
+ #define CMD_SET_DRIVERMODE_REQ			21
+@@ -196,21 +198,26 @@ struct kvaser_cmd_chip_state_event {
+ #define KVASER_USB_HYDRA_BUS_MODE_CANFD_ISO	0x01
+ #define KVASER_USB_HYDRA_BUS_MODE_NONISO	0x02
+ struct kvaser_cmd_set_busparams {
+-	__le32 bitrate;
+-	u8 tseg1;
+-	u8 tseg2;
+-	u8 sjw;
+-	u8 nsamples;
++	struct kvaser_usb_busparams busparams_nominal;
+ 	u8 reserved0[4];
+-	__le32 bitrate_d;
+-	u8 tseg1_d;
+-	u8 tseg2_d;
+-	u8 sjw_d;
+-	u8 nsamples_d;
++	struct kvaser_usb_busparams busparams_data;
+ 	u8 canfd_mode;
+ 	u8 reserved1[7];
+ } __packed;
+ 
++/* Busparam type */
++#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN	0x00
++#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD	0x01
++struct kvaser_cmd_get_busparams_req {
++	u8 type;
++	u8 reserved[27];
++} __packed;
++
++struct kvaser_cmd_get_busparams_res {
++	struct kvaser_usb_busparams busparams;
++	u8 reserved[20];
++} __packed;
++
+ /* Ctrl modes */
+ #define KVASER_USB_HYDRA_CTRLMODE_NORMAL	0x01
+ #define KVASER_USB_HYDRA_CTRLMODE_LISTEN	0x02
+@@ -281,6 +288,8 @@ struct kvaser_cmd {
+ 		struct kvaser_cmd_error_event error_event;
+ 
+ 		struct kvaser_cmd_set_busparams set_busparams_req;
++		struct kvaser_cmd_get_busparams_req get_busparams_req;
++		struct kvaser_cmd_get_busparams_res get_busparams_res;
+ 
+ 		struct kvaser_cmd_chip_state_event chip_state_event;
+ 
+@@ -363,6 +372,10 @@ struct kvaser_cmd_ext {
+ 	} __packed;
+ } __packed;
+ 
++struct kvaser_usb_net_hydra_priv {
++	int pending_get_busparams_type;
++};
++
+ static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c = {
+ 	.name = "kvaser_usb_kcan",
+ 	.tseg1_min = 1,
+@@ -840,6 +853,39 @@ static void kvaser_usb_hydra_flush_queue_reply(const struct kvaser_usb *dev,
+ 	complete(&priv->flush_comp);
+ }
+ 
++static void kvaser_usb_hydra_get_busparams_reply(const struct kvaser_usb *dev,
++						 const struct kvaser_cmd *cmd)
++{
++	struct kvaser_usb_net_priv *priv;
++	struct kvaser_usb_net_hydra_priv *hydra;
++
++	priv = kvaser_usb_hydra_net_priv_from_cmd(dev, cmd);
++	if (!priv)
++		return;
++
++	hydra = priv->sub_priv;
++	if (!hydra)
++		return;
++
++	switch (hydra->pending_get_busparams_type) {
++	case KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN:
++		memcpy(&priv->busparams_nominal, &cmd->get_busparams_res.busparams,
++		       sizeof(priv->busparams_nominal));
++		break;
++	case KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD:
++		memcpy(&priv->busparams_data, &cmd->get_busparams_res.busparams,
++		       sizeof(priv->busparams_nominal));
++		break;
++	default:
++		dev_warn(&dev->intf->dev, "Unknown get_busparams_type %d\n",
++			 hydra->pending_get_busparams_type);
++		break;
++	}
++	hydra->pending_get_busparams_type = -1;
++
++	complete(&priv->get_busparams_comp);
++}
++
+ static void
+ kvaser_usb_hydra_bus_status_to_can_state(const struct kvaser_usb_net_priv *priv,
+ 					 u8 bus_status,
+@@ -1326,6 +1372,10 @@ static void kvaser_usb_hydra_handle_cmd_std(const struct kvaser_usb *dev,
+ 		kvaser_usb_hydra_state_event(dev, cmd);
+ 		break;
+ 
++	case CMD_GET_BUSPARAMS_RESP:
++		kvaser_usb_hydra_get_busparams_reply(dev, cmd);
++		break;
++
+ 	case CMD_ERROR_EVENT:
+ 		kvaser_usb_hydra_error_event(dev, cmd);
+ 		break;
+@@ -1522,15 +1572,58 @@ static int kvaser_usb_hydra_set_mode(struct net_device *netdev,
+ 	return err;
+ }
+ 
+-static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev)
++static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv,
++					  int busparams_type)
++{
++	struct kvaser_usb *dev = priv->dev;
++	struct kvaser_usb_net_hydra_priv *hydra = priv->sub_priv;
++	struct kvaser_cmd *cmd;
++	int err;
++
++	if (!hydra)
++		return -EINVAL;
++
++	cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
++	if (!cmd)
++		return -ENOMEM;
++
++	cmd->header.cmd_no = CMD_GET_BUSPARAMS_REQ;
++	kvaser_usb_hydra_set_cmd_dest_he
++		(cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
++	kvaser_usb_hydra_set_cmd_transid
++				(cmd, kvaser_usb_hydra_get_next_transid(dev));
++	cmd->get_busparams_req.type = busparams_type;
++	hydra->pending_get_busparams_type = busparams_type;
++
++	reinit_completion(&priv->get_busparams_comp);
++
++	err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd));
++	if (err)
++		return err;
++
++	if (!wait_for_completion_timeout(&priv->get_busparams_comp,
++					 msecs_to_jiffies(KVASER_USB_TIMEOUT)))
++		return -ETIMEDOUT;
++
++	return err;
++}
++
++static int kvaser_usb_hydra_get_nominal_busparams(struct kvaser_usb_net_priv *priv)
++{
++	return kvaser_usb_hydra_get_busparams(priv, KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN);
++}
++
++static int kvaser_usb_hydra_get_data_busparams(struct kvaser_usb_net_priv *priv)
++{
++	return kvaser_usb_hydra_get_busparams(priv, KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD);
++}
++
++static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev,
++					  const struct kvaser_usb_busparams *busparams)
+ {
+ 	struct kvaser_cmd *cmd;
+ 	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+-	struct can_bittiming *bt = &priv->can.bittiming;
+ 	struct kvaser_usb *dev = priv->dev;
+-	int tseg1 = bt->prop_seg + bt->phase_seg1;
+-	int tseg2 = bt->phase_seg2;
+-	int sjw = bt->sjw;
+ 	int err;
+ 
+ 	cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
+@@ -1538,11 +1631,8 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev)
+ 		return -ENOMEM;
+ 
+ 	cmd->header.cmd_no = CMD_SET_BUSPARAMS_REQ;
+-	cmd->set_busparams_req.bitrate = cpu_to_le32(bt->bitrate);
+-	cmd->set_busparams_req.sjw = (u8)sjw;
+-	cmd->set_busparams_req.tseg1 = (u8)tseg1;
+-	cmd->set_busparams_req.tseg2 = (u8)tseg2;
+-	cmd->set_busparams_req.nsamples = 1;
++	memcpy(&cmd->set_busparams_req.busparams_nominal, busparams,
++	       sizeof(cmd->set_busparams_req.busparams_nominal));
+ 
+ 	kvaser_usb_hydra_set_cmd_dest_he
+ 		(cmd, dev->card_data.hydra.channel_to_he[priv->channel]);
+@@ -1556,15 +1646,12 @@ static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev)
+ 	return err;
+ }
+ 
+-static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev)
++static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev,
++					       const struct kvaser_usb_busparams *busparams)
+ {
+ 	struct kvaser_cmd *cmd;
+ 	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+-	struct can_bittiming *dbt = &priv->can.data_bittiming;
+ 	struct kvaser_usb *dev = priv->dev;
+-	int tseg1 = dbt->prop_seg + dbt->phase_seg1;
+-	int tseg2 = dbt->phase_seg2;
+-	int sjw = dbt->sjw;
+ 	int err;
+ 
+ 	cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL);
+@@ -1572,11 +1659,8 @@ static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev)
+ 		return -ENOMEM;
+ 
+ 	cmd->header.cmd_no = CMD_SET_BUSPARAMS_FD_REQ;
+-	cmd->set_busparams_req.bitrate_d = cpu_to_le32(dbt->bitrate);
+-	cmd->set_busparams_req.sjw_d = (u8)sjw;
+-	cmd->set_busparams_req.tseg1_d = (u8)tseg1;
+-	cmd->set_busparams_req.tseg2_d = (u8)tseg2;
+-	cmd->set_busparams_req.nsamples_d = 1;
++	memcpy(&cmd->set_busparams_req.busparams_data, busparams,
++	       sizeof(cmd->set_busparams_req.busparams_data));
+ 
+ 	if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
+ 		if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)
+@@ -1683,6 +1767,19 @@ static int kvaser_usb_hydra_init_card(struct kvaser_usb *dev)
+ 	return 0;
+ }
+ 
++static int kvaser_usb_hydra_init_channel(struct kvaser_usb_net_priv *priv)
++{
++	struct kvaser_usb_net_hydra_priv *hydra;
++
++	hydra = devm_kzalloc(&priv->dev->intf->dev, sizeof(*hydra), GFP_KERNEL);
++	if (!hydra)
++		return -ENOMEM;
++
++	priv->sub_priv = hydra;
++
++	return 0;
++}
++
+ static int kvaser_usb_hydra_get_software_info(struct kvaser_usb *dev)
+ {
+ 	struct kvaser_cmd cmd;
+@@ -2027,10 +2124,13 @@ kvaser_usb_hydra_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
+ const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops = {
+ 	.dev_set_mode = kvaser_usb_hydra_set_mode,
+ 	.dev_set_bittiming = kvaser_usb_hydra_set_bittiming,
++	.dev_get_busparams = kvaser_usb_hydra_get_nominal_busparams,
+ 	.dev_set_data_bittiming = kvaser_usb_hydra_set_data_bittiming,
++	.dev_get_data_busparams = kvaser_usb_hydra_get_data_busparams,
+ 	.dev_get_berr_counter = kvaser_usb_hydra_get_berr_counter,
+ 	.dev_setup_endpoints = kvaser_usb_hydra_setup_endpoints,
+ 	.dev_init_card = kvaser_usb_hydra_init_card,
++	.dev_init_channel = kvaser_usb_hydra_init_channel,
+ 	.dev_get_software_info = kvaser_usb_hydra_get_software_info,
+ 	.dev_get_software_details = kvaser_usb_hydra_get_software_details,
+ 	.dev_get_card_info = kvaser_usb_hydra_get_card_info,
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 19958037720f4..b423fd4c79890 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -21,6 +21,7 @@
+ #include <linux/types.h>
+ #include <linux/units.h>
+ #include <linux/usb.h>
++#include <linux/workqueue.h>
+ 
+ #include <linux/can.h>
+ #include <linux/can/dev.h>
+@@ -56,6 +57,9 @@
+ #define CMD_RX_EXT_MESSAGE		14
+ #define CMD_TX_EXT_MESSAGE		15
+ #define CMD_SET_BUS_PARAMS		16
++#define CMD_GET_BUS_PARAMS		17
++#define CMD_GET_BUS_PARAMS_REPLY	18
++#define CMD_GET_CHIP_STATE		19
+ #define CMD_CHIP_STATE_EVENT		20
+ #define CMD_SET_CTRL_MODE		21
+ #define CMD_RESET_CHIP			24
+@@ -70,10 +74,13 @@
+ #define CMD_GET_CARD_INFO_REPLY		35
+ #define CMD_GET_SOFTWARE_INFO		38
+ #define CMD_GET_SOFTWARE_INFO_REPLY	39
++#define CMD_ERROR_EVENT			45
+ #define CMD_FLUSH_QUEUE			48
+ #define CMD_TX_ACKNOWLEDGE		50
+ #define CMD_CAN_ERROR_EVENT		51
+ #define CMD_FLUSH_QUEUE_REPLY		68
++#define CMD_GET_CAPABILITIES_REQ	95
++#define CMD_GET_CAPABILITIES_RESP	96
+ 
+ #define CMD_LEAF_LOG_MESSAGE		106
+ 
+@@ -83,6 +90,8 @@
+ #define KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK BIT(5)
+ #define KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK BIT(6)
+ 
++#define KVASER_USB_LEAF_SWOPTION_EXT_CAP BIT(12)
++
+ /* error factors */
+ #define M16C_EF_ACKE			BIT(0)
+ #define M16C_EF_CRCE			BIT(1)
+@@ -157,11 +166,7 @@ struct usbcan_cmd_softinfo {
+ struct kvaser_cmd_busparams {
+ 	u8 tid;
+ 	u8 channel;
+-	__le32 bitrate;
+-	u8 tseg1;
+-	u8 tseg2;
+-	u8 sjw;
+-	u8 no_samp;
++	struct kvaser_usb_busparams busparams;
+ } __packed;
+ 
+ struct kvaser_cmd_tx_can {
+@@ -230,7 +235,7 @@ struct kvaser_cmd_tx_acknowledge_header {
+ 	u8 tid;
+ } __packed;
+ 
+-struct leaf_cmd_error_event {
++struct leaf_cmd_can_error_event {
+ 	u8 tid;
+ 	u8 flags;
+ 	__le16 time[3];
+@@ -242,7 +247,7 @@ struct leaf_cmd_error_event {
+ 	u8 error_factor;
+ } __packed;
+ 
+-struct usbcan_cmd_error_event {
++struct usbcan_cmd_can_error_event {
+ 	u8 tid;
+ 	u8 padding;
+ 	u8 tx_errors_count_ch0;
+@@ -254,6 +259,28 @@ struct usbcan_cmd_error_event {
+ 	__le16 time;
+ } __packed;
+ 
++/* CMD_ERROR_EVENT error codes */
++#define KVASER_USB_LEAF_ERROR_EVENT_TX_QUEUE_FULL 0x8
++#define KVASER_USB_LEAF_ERROR_EVENT_PARAM 0x9
++
++struct leaf_cmd_error_event {
++	u8 tid;
++	u8 error_code;
++	__le16 timestamp[3];
++	__le16 padding;
++	__le16 info1;
++	__le16 info2;
++} __packed;
++
++struct usbcan_cmd_error_event {
++	u8 tid;
++	u8 error_code;
++	__le16 info1;
++	__le16 info2;
++	__le16 timestamp;
++	__le16 padding;
++} __packed;
++
+ struct kvaser_cmd_ctrl_mode {
+ 	u8 tid;
+ 	u8 channel;
+@@ -278,6 +305,28 @@ struct leaf_cmd_log_message {
+ 	u8 data[8];
+ } __packed;
+ 
++/* Sub commands for cap_req and cap_res */
++#define KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE 0x02
++#define KVASER_USB_LEAF_CAP_CMD_ERR_REPORT 0x05
++struct kvaser_cmd_cap_req {
++	__le16 padding0;
++	__le16 cap_cmd;
++	__le16 padding1;
++	__le16 channel;
++} __packed;
++
++/* Status codes for cap_res */
++#define KVASER_USB_LEAF_CAP_STAT_OK 0x00
++#define KVASER_USB_LEAF_CAP_STAT_NOT_IMPL 0x01
++#define KVASER_USB_LEAF_CAP_STAT_UNAVAIL 0x02
++struct kvaser_cmd_cap_res {
++	__le16 padding;
++	__le16 cap_cmd;
++	__le16 status;
++	__le32 mask;
++	__le32 value;
++} __packed;
++
+ struct kvaser_cmd {
+ 	u8 len;
+ 	u8 id;
+@@ -293,14 +342,18 @@ struct kvaser_cmd {
+ 			struct leaf_cmd_softinfo softinfo;
+ 			struct leaf_cmd_rx_can rx_can;
+ 			struct leaf_cmd_chip_state_event chip_state_event;
+-			struct leaf_cmd_error_event error_event;
++			struct leaf_cmd_can_error_event can_error_event;
+ 			struct leaf_cmd_log_message log_message;
++			struct leaf_cmd_error_event error_event;
++			struct kvaser_cmd_cap_req cap_req;
++			struct kvaser_cmd_cap_res cap_res;
+ 		} __packed leaf;
+ 
+ 		union {
+ 			struct usbcan_cmd_softinfo softinfo;
+ 			struct usbcan_cmd_rx_can rx_can;
+ 			struct usbcan_cmd_chip_state_event chip_state_event;
++			struct usbcan_cmd_can_error_event can_error_event;
+ 			struct usbcan_cmd_error_event error_event;
+ 		} __packed usbcan;
+ 
+@@ -323,7 +376,10 @@ static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = {
+ 	[CMD_RX_EXT_MESSAGE]		= kvaser_fsize(u.leaf.rx_can),
+ 	[CMD_LEAF_LOG_MESSAGE]		= kvaser_fsize(u.leaf.log_message),
+ 	[CMD_CHIP_STATE_EVENT]		= kvaser_fsize(u.leaf.chip_state_event),
+-	[CMD_CAN_ERROR_EVENT]		= kvaser_fsize(u.leaf.error_event),
++	[CMD_CAN_ERROR_EVENT]		= kvaser_fsize(u.leaf.can_error_event),
++	[CMD_GET_CAPABILITIES_RESP]	= kvaser_fsize(u.leaf.cap_res),
++	[CMD_GET_BUS_PARAMS_REPLY]	= kvaser_fsize(u.busparams),
++	[CMD_ERROR_EVENT]		= kvaser_fsize(u.leaf.error_event),
+ 	/* ignored events: */
+ 	[CMD_FLUSH_QUEUE_REPLY]		= CMD_SIZE_ANY,
+ };
+@@ -337,7 +393,8 @@ static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = {
+ 	[CMD_RX_STD_MESSAGE]		= kvaser_fsize(u.usbcan.rx_can),
+ 	[CMD_RX_EXT_MESSAGE]		= kvaser_fsize(u.usbcan.rx_can),
+ 	[CMD_CHIP_STATE_EVENT]		= kvaser_fsize(u.usbcan.chip_state_event),
+-	[CMD_CAN_ERROR_EVENT]		= kvaser_fsize(u.usbcan.error_event),
++	[CMD_CAN_ERROR_EVENT]		= kvaser_fsize(u.usbcan.can_error_event),
++	[CMD_ERROR_EVENT]		= kvaser_fsize(u.usbcan.error_event),
+ 	/* ignored events: */
+ 	[CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY,
+ };
+@@ -365,6 +422,12 @@ struct kvaser_usb_err_summary {
+ 	};
+ };
+ 
++struct kvaser_usb_net_leaf_priv {
++	struct kvaser_usb_net_priv *net;
++
++	struct delayed_work chip_state_req_work;
++};
++
+ static const struct can_bittiming_const kvaser_usb_leaf_m16c_bittiming_const = {
+ 	.name = "kvaser_usb_ucii",
+ 	.tseg1_min = 4,
+@@ -606,6 +669,9 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev,
+ 	dev->fw_version = le32_to_cpu(softinfo->fw_version);
+ 	dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx);
+ 
++	if (sw_options & KVASER_USB_LEAF_SWOPTION_EXT_CAP)
++		dev->card_data.capabilities |= KVASER_USB_CAP_EXT_CAP;
++
+ 	if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) {
+ 		/* Firmware expects bittiming parameters calculated for 16MHz
+ 		 * clock, regardless of the actual clock
+@@ -693,6 +759,116 @@ static int kvaser_usb_leaf_get_card_info(struct kvaser_usb *dev)
+ 	return 0;
+ }
+ 
++static int kvaser_usb_leaf_get_single_capability(struct kvaser_usb *dev,
++						 u16 cap_cmd_req, u16 *status)
++{
++	struct kvaser_usb_dev_card_data *card_data = &dev->card_data;
++	struct kvaser_cmd *cmd;
++	u32 value = 0;
++	u32 mask = 0;
++	u16 cap_cmd_res;
++	int err;
++	int i;
++
++	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
++	if (!cmd)
++		return -ENOMEM;
++
++	cmd->id = CMD_GET_CAPABILITIES_REQ;
++	cmd->u.leaf.cap_req.cap_cmd = cpu_to_le16(cap_cmd_req);
++	cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_cap_req);
++
++	err = kvaser_usb_send_cmd(dev, cmd, cmd->len);
++	if (err)
++		goto end;
++
++	err = kvaser_usb_leaf_wait_cmd(dev, CMD_GET_CAPABILITIES_RESP, cmd);
++	if (err)
++		goto end;
++
++	*status = le16_to_cpu(cmd->u.leaf.cap_res.status);
++
++	if (*status != KVASER_USB_LEAF_CAP_STAT_OK)
++		goto end;
++
++	cap_cmd_res = le16_to_cpu(cmd->u.leaf.cap_res.cap_cmd);
++	switch (cap_cmd_res) {
++	case KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE:
++	case KVASER_USB_LEAF_CAP_CMD_ERR_REPORT:
++		value = le32_to_cpu(cmd->u.leaf.cap_res.value);
++		mask = le32_to_cpu(cmd->u.leaf.cap_res.mask);
++		break;
++	default:
++		dev_warn(&dev->intf->dev, "Unknown capability command %u\n",
++			 cap_cmd_res);
++		break;
++	}
++
++	for (i = 0; i < dev->nchannels; i++) {
++		if (BIT(i) & (value & mask)) {
++			switch (cap_cmd_res) {
++			case KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE:
++				card_data->ctrlmode_supported |=
++						CAN_CTRLMODE_LISTENONLY;
++				break;
++			case KVASER_USB_LEAF_CAP_CMD_ERR_REPORT:
++				card_data->capabilities |=
++						KVASER_USB_CAP_BERR_CAP;
++				break;
++			}
++		}
++	}
++
++end:
++	kfree(cmd);
++
++	return err;
++}
++
++static int kvaser_usb_leaf_get_capabilities_leaf(struct kvaser_usb *dev)
++{
++	int err;
++	u16 status;
++
++	if (!(dev->card_data.capabilities & KVASER_USB_CAP_EXT_CAP)) {
++		dev_info(&dev->intf->dev,
++			 "No extended capability support. Upgrade device firmware.\n");
++		return 0;
++	}
++
++	err = kvaser_usb_leaf_get_single_capability(dev,
++						    KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE,
++						    &status);
++	if (err)
++		return err;
++	if (status)
++		dev_info(&dev->intf->dev,
++			 "KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE failed %u\n",
++			 status);
++
++	err = kvaser_usb_leaf_get_single_capability(dev,
++						    KVASER_USB_LEAF_CAP_CMD_ERR_REPORT,
++						    &status);
++	if (err)
++		return err;
++	if (status)
++		dev_info(&dev->intf->dev,
++			 "KVASER_USB_LEAF_CAP_CMD_ERR_REPORT failed %u\n",
++			 status);
++
++	return 0;
++}
++
++static int kvaser_usb_leaf_get_capabilities(struct kvaser_usb *dev)
++{
++	int err = 0;
++
++	if (dev->driver_info->family == KVASER_LEAF)
++		err = kvaser_usb_leaf_get_capabilities_leaf(dev);
++
++	return err;
++}
++
+ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev,
+ 					   const struct kvaser_cmd *cmd)
+ {
+@@ -721,7 +897,7 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev,
+ 	context = &priv->tx_contexts[tid % dev->max_tx_urbs];
+ 
+ 	/* Sometimes the state change doesn't come after a bus-off event */
+-	if (priv->can.restart_ms && priv->can.state >= CAN_STATE_BUS_OFF) {
++	if (priv->can.restart_ms && priv->can.state == CAN_STATE_BUS_OFF) {
+ 		struct sk_buff *skb;
+ 		struct can_frame *cf;
+ 
+@@ -774,6 +950,16 @@ static int kvaser_usb_leaf_simple_cmd_async(struct kvaser_usb_net_priv *priv,
+ 	return err;
+ }
+ 
++static void kvaser_usb_leaf_chip_state_req_work(struct work_struct *work)
++{
++	struct kvaser_usb_net_leaf_priv *leaf =
++		container_of(work, struct kvaser_usb_net_leaf_priv,
++			     chip_state_req_work.work);
++	struct kvaser_usb_net_priv *priv = leaf->net;
++
++	kvaser_usb_leaf_simple_cmd_async(priv, CMD_GET_CHIP_STATE);
++}
++
+ static void
+ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
+ 					const struct kvaser_usb_err_summary *es,
+@@ -792,20 +978,16 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
+ 		new_state = CAN_STATE_BUS_OFF;
+ 	} else if (es->status & M16C_STATE_BUS_PASSIVE) {
+ 		new_state = CAN_STATE_ERROR_PASSIVE;
+-	} else if (es->status & M16C_STATE_BUS_ERROR) {
++	} else if ((es->status & M16C_STATE_BUS_ERROR) &&
++		   cur_state >= CAN_STATE_BUS_OFF) {
+ 		/* Guard against spurious error events after a busoff */
+-		if (cur_state < CAN_STATE_BUS_OFF) {
+-			if (es->txerr >= 128 || es->rxerr >= 128)
+-				new_state = CAN_STATE_ERROR_PASSIVE;
+-			else if (es->txerr >= 96 || es->rxerr >= 96)
+-				new_state = CAN_STATE_ERROR_WARNING;
+-			else if (cur_state > CAN_STATE_ERROR_ACTIVE)
+-				new_state = CAN_STATE_ERROR_ACTIVE;
+-		}
+-	}
+-
+-	if (!es->status)
++	} else if (es->txerr >= 128 || es->rxerr >= 128) {
++		new_state = CAN_STATE_ERROR_PASSIVE;
++	} else if (es->txerr >= 96 || es->rxerr >= 96) {
++		new_state = CAN_STATE_ERROR_WARNING;
++	} else {
+ 		new_state = CAN_STATE_ERROR_ACTIVE;
++	}
+ 
+ 	if (new_state != cur_state) {
+ 		tx_state = (es->txerr >= es->rxerr) ? new_state : 0;
+@@ -815,7 +997,7 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
+ 	}
+ 
+ 	if (priv->can.restart_ms &&
+-	    cur_state >= CAN_STATE_BUS_OFF &&
++	    cur_state == CAN_STATE_BUS_OFF &&
+ 	    new_state < CAN_STATE_BUS_OFF)
+ 		priv->can.can_stats.restarts++;
+ 
+@@ -849,6 +1031,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+ 	struct sk_buff *skb;
+ 	struct net_device_stats *stats;
+ 	struct kvaser_usb_net_priv *priv;
++	struct kvaser_usb_net_leaf_priv *leaf;
+ 	enum can_state old_state, new_state;
+ 
+ 	if (es->channel >= dev->nchannels) {
+@@ -858,8 +1041,13 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+ 	}
+ 
+ 	priv = dev->nets[es->channel];
++	leaf = priv->sub_priv;
+ 	stats = &priv->netdev->stats;
+ 
++	/* Ignore e.g. state change to bus-off reported just after stopping */
++	if (!netif_running(priv->netdev))
++		return;
++
+ 	/* Update all of the CAN interface's state and error counters before
+ 	 * trying any memory allocation that can actually fail with -ENOMEM.
+ 	 *
+@@ -874,6 +1062,14 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+ 	kvaser_usb_leaf_rx_error_update_can_state(priv, es, &tmp_cf);
+ 	new_state = priv->can.state;
+ 
++	/* If there are errors, request status updates periodically as we do
++	 * not get automatic notifications of improved state.
++	 */
++	if (new_state < CAN_STATE_BUS_OFF &&
++	    (es->rxerr || es->txerr || new_state == CAN_STATE_ERROR_PASSIVE))
++		schedule_delayed_work(&leaf->chip_state_req_work,
++				      msecs_to_jiffies(500));
++
+ 	skb = alloc_can_err_skb(priv->netdev, &cf);
+ 	if (!skb) {
+ 		stats->rx_dropped++;
+@@ -891,7 +1087,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
+ 		}
+ 
+ 		if (priv->can.restart_ms &&
+-		    old_state >= CAN_STATE_BUS_OFF &&
++		    old_state == CAN_STATE_BUS_OFF &&
+ 		    new_state < CAN_STATE_BUS_OFF) {
+ 			cf->can_id |= CAN_ERR_RESTARTED;
+ 			netif_carrier_on(priv->netdev);
+@@ -990,11 +1186,11 @@ static void kvaser_usb_leaf_usbcan_rx_error(const struct kvaser_usb *dev,
+ 
+ 	case CMD_CAN_ERROR_EVENT:
+ 		es.channel = 0;
+-		es.status = cmd->u.usbcan.error_event.status_ch0;
+-		es.txerr = cmd->u.usbcan.error_event.tx_errors_count_ch0;
+-		es.rxerr = cmd->u.usbcan.error_event.rx_errors_count_ch0;
++		es.status = cmd->u.usbcan.can_error_event.status_ch0;
++		es.txerr = cmd->u.usbcan.can_error_event.tx_errors_count_ch0;
++		es.rxerr = cmd->u.usbcan.can_error_event.rx_errors_count_ch0;
+ 		es.usbcan.other_ch_status =
+-			cmd->u.usbcan.error_event.status_ch1;
++			cmd->u.usbcan.can_error_event.status_ch1;
+ 		kvaser_usb_leaf_usbcan_conditionally_rx_error(dev, &es);
+ 
+ 		/* The USBCAN firmware supports up to 2 channels.
+@@ -1002,13 +1198,13 @@ static void kvaser_usb_leaf_usbcan_rx_error(const struct kvaser_usb *dev,
+ 		 */
+ 		if (dev->nchannels == MAX_USBCAN_NET_DEVICES) {
+ 			es.channel = 1;
+-			es.status = cmd->u.usbcan.error_event.status_ch1;
++			es.status = cmd->u.usbcan.can_error_event.status_ch1;
+ 			es.txerr =
+-				cmd->u.usbcan.error_event.tx_errors_count_ch1;
++				cmd->u.usbcan.can_error_event.tx_errors_count_ch1;
+ 			es.rxerr =
+-				cmd->u.usbcan.error_event.rx_errors_count_ch1;
++				cmd->u.usbcan.can_error_event.rx_errors_count_ch1;
+ 			es.usbcan.other_ch_status =
+-				cmd->u.usbcan.error_event.status_ch0;
++				cmd->u.usbcan.can_error_event.status_ch0;
+ 			kvaser_usb_leaf_usbcan_conditionally_rx_error(dev, &es);
+ 		}
+ 		break;
+@@ -1025,11 +1221,11 @@ static void kvaser_usb_leaf_leaf_rx_error(const struct kvaser_usb *dev,
+ 
+ 	switch (cmd->id) {
+ 	case CMD_CAN_ERROR_EVENT:
+-		es.channel = cmd->u.leaf.error_event.channel;
+-		es.status = cmd->u.leaf.error_event.status;
+-		es.txerr = cmd->u.leaf.error_event.tx_errors_count;
+-		es.rxerr = cmd->u.leaf.error_event.rx_errors_count;
+-		es.leaf.error_factor = cmd->u.leaf.error_event.error_factor;
++		es.channel = cmd->u.leaf.can_error_event.channel;
++		es.status = cmd->u.leaf.can_error_event.status;
++		es.txerr = cmd->u.leaf.can_error_event.tx_errors_count;
++		es.rxerr = cmd->u.leaf.can_error_event.rx_errors_count;
++		es.leaf.error_factor = cmd->u.leaf.can_error_event.error_factor;
+ 		break;
+ 	case CMD_LEAF_LOG_MESSAGE:
+ 		es.channel = cmd->u.leaf.log_message.channel;
+@@ -1162,6 +1358,74 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev,
+ 	netif_rx(skb);
+ }
+ 
++static void kvaser_usb_leaf_error_event_parameter(const struct kvaser_usb *dev,
++						  const struct kvaser_cmd *cmd)
++{
++	u16 info1 = 0;
++
++	switch (dev->driver_info->family) {
++	case KVASER_LEAF:
++		info1 = le16_to_cpu(cmd->u.leaf.error_event.info1);
++		break;
++	case KVASER_USBCAN:
++		info1 = le16_to_cpu(cmd->u.usbcan.error_event.info1);
++		break;
++	}
++
++	/* info1 will contain the offending cmd_no */
++	switch (info1) {
++	case CMD_SET_CTRL_MODE:
++		dev_warn(&dev->intf->dev,
++			 "CMD_SET_CTRL_MODE error in parameter\n");
++		break;
++
++	case CMD_SET_BUS_PARAMS:
++		dev_warn(&dev->intf->dev,
++			 "CMD_SET_BUS_PARAMS error in parameter\n");
++		break;
++
++	default:
++		dev_warn(&dev->intf->dev,
++			 "Unhandled parameter error event cmd_no (%u)\n",
++			 info1);
++		break;
++	}
++}
++
++static void kvaser_usb_leaf_error_event(const struct kvaser_usb *dev,
++					const struct kvaser_cmd *cmd)
++{
++	u8 error_code = 0;
++
++	switch (dev->driver_info->family) {
++	case KVASER_LEAF:
++		error_code = cmd->u.leaf.error_event.error_code;
++		break;
++	case KVASER_USBCAN:
++		error_code = cmd->u.usbcan.error_event.error_code;
++		break;
++	}
++
++	switch (error_code) {
++	case KVASER_USB_LEAF_ERROR_EVENT_TX_QUEUE_FULL:
++		/* Received additional CAN message, when firmware TX queue is
++		 * already full. Something is wrong with the driver.
++		 * This should never happen!
++		 */
++		dev_err(&dev->intf->dev,
++			"Received error event TX_QUEUE_FULL\n");
++		break;
++	case KVASER_USB_LEAF_ERROR_EVENT_PARAM:
++		kvaser_usb_leaf_error_event_parameter(dev, cmd);
++		break;
++
++	default:
++		dev_warn(&dev->intf->dev,
++			 "Unhandled error event (%d)\n", error_code);
++		break;
++	}
++}
++
+ static void kvaser_usb_leaf_start_chip_reply(const struct kvaser_usb *dev,
+ 					     const struct kvaser_cmd *cmd)
+ {
+@@ -1202,6 +1466,25 @@ static void kvaser_usb_leaf_stop_chip_reply(const struct kvaser_usb *dev,
+ 	complete(&priv->stop_comp);
+ }
+ 
++static void kvaser_usb_leaf_get_busparams_reply(const struct kvaser_usb *dev,
++						const struct kvaser_cmd *cmd)
++{
++	struct kvaser_usb_net_priv *priv;
++	u8 channel = cmd->u.busparams.channel;
++
++	if (channel >= dev->nchannels) {
++		dev_err(&dev->intf->dev,
++			"Invalid channel number (%d)\n", channel);
++		return;
++	}
++
++	priv = dev->nets[channel];
++	memcpy(&priv->busparams_nominal, &cmd->u.busparams.busparams,
++	       sizeof(priv->busparams_nominal));
++
++	complete(&priv->get_busparams_comp);
++}
++
+ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
+ 					   const struct kvaser_cmd *cmd)
+ {
+@@ -1240,6 +1523,14 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
+ 		kvaser_usb_leaf_tx_acknowledge(dev, cmd);
+ 		break;
+ 
++	case CMD_ERROR_EVENT:
++		kvaser_usb_leaf_error_event(dev, cmd);
++		break;
++
++	case CMD_GET_BUS_PARAMS_REPLY:
++		kvaser_usb_leaf_get_busparams_reply(dev, cmd);
++		break;
++
+ 	/* Ignored commands */
+ 	case CMD_USBCAN_CLOCK_OVERFLOW_EVENT:
+ 		if (dev->driver_info->family != KVASER_USBCAN)
+@@ -1336,10 +1627,13 @@ static int kvaser_usb_leaf_start_chip(struct kvaser_usb_net_priv *priv)
+ 
+ static int kvaser_usb_leaf_stop_chip(struct kvaser_usb_net_priv *priv)
+ {
++	struct kvaser_usb_net_leaf_priv *leaf = priv->sub_priv;
+ 	int err;
+ 
+ 	reinit_completion(&priv->stop_comp);
+ 
++	cancel_delayed_work(&leaf->chip_state_req_work);
++
+ 	err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP,
+ 					      priv->channel);
+ 	if (err)
+@@ -1386,10 +1680,35 @@ static int kvaser_usb_leaf_init_card(struct kvaser_usb *dev)
+ 	return 0;
+ }
+ 
+-static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
++static int kvaser_usb_leaf_init_channel(struct kvaser_usb_net_priv *priv)
++{
++	struct kvaser_usb_net_leaf_priv *leaf;
++
++	leaf = devm_kzalloc(&priv->dev->intf->dev, sizeof(*leaf), GFP_KERNEL);
++	if (!leaf)
++		return -ENOMEM;
++
++	leaf->net = priv;
++	INIT_DELAYED_WORK(&leaf->chip_state_req_work,
++			  kvaser_usb_leaf_chip_state_req_work);
++
++	priv->sub_priv = leaf;
++
++	return 0;
++}
++
++static void kvaser_usb_leaf_remove_channel(struct kvaser_usb_net_priv *priv)
++{
++	struct kvaser_usb_net_leaf_priv *leaf = priv->sub_priv;
++
++	if (leaf)
++		cancel_delayed_work_sync(&leaf->chip_state_req_work);
++}
++
++static int kvaser_usb_leaf_set_bittiming(const struct net_device *netdev,
++					 const struct kvaser_usb_busparams *busparams)
+ {
+ 	struct kvaser_usb_net_priv *priv = netdev_priv(netdev);
+-	struct can_bittiming *bt = &priv->can.bittiming;
+ 	struct kvaser_usb *dev = priv->dev;
+ 	struct kvaser_cmd *cmd;
+ 	int rc;
+@@ -1402,15 +1721,8 @@ static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
+ 	cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_busparams);
+ 	cmd->u.busparams.channel = priv->channel;
+ 	cmd->u.busparams.tid = 0xff;
+-	cmd->u.busparams.bitrate = cpu_to_le32(bt->bitrate);
+-	cmd->u.busparams.sjw = bt->sjw;
+-	cmd->u.busparams.tseg1 = bt->prop_seg + bt->phase_seg1;
+-	cmd->u.busparams.tseg2 = bt->phase_seg2;
+-
+-	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+-		cmd->u.busparams.no_samp = 3;
+-	else
+-		cmd->u.busparams.no_samp = 1;
++	memcpy(&cmd->u.busparams.busparams, busparams,
++	       sizeof(cmd->u.busparams.busparams));
+ 
+ 	rc = kvaser_usb_send_cmd(dev, cmd, cmd->len);
+ 
+@@ -1418,6 +1730,27 @@ static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev)
+ 	return rc;
+ }
+ 
++static int kvaser_usb_leaf_get_busparams(struct kvaser_usb_net_priv *priv)
++{
++	int err;
++
++	if (priv->dev->driver_info->family == KVASER_USBCAN)
++		return -EOPNOTSUPP;
++
++	reinit_completion(&priv->get_busparams_comp);
++
++	err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_GET_BUS_PARAMS,
++					      priv->channel);
++	if (err)
++		return err;
++
++	if (!wait_for_completion_timeout(&priv->get_busparams_comp,
++					 msecs_to_jiffies(KVASER_USB_TIMEOUT)))
++		return -ETIMEDOUT;
++
++	return 0;
++}
++
+ static int kvaser_usb_leaf_set_mode(struct net_device *netdev,
+ 				    enum can_mode mode)
+ {
+@@ -1479,14 +1812,18 @@ static int kvaser_usb_leaf_setup_endpoints(struct kvaser_usb *dev)
+ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = {
+ 	.dev_set_mode = kvaser_usb_leaf_set_mode,
+ 	.dev_set_bittiming = kvaser_usb_leaf_set_bittiming,
++	.dev_get_busparams = kvaser_usb_leaf_get_busparams,
+ 	.dev_set_data_bittiming = NULL,
++	.dev_get_data_busparams = NULL,
+ 	.dev_get_berr_counter = kvaser_usb_leaf_get_berr_counter,
+ 	.dev_setup_endpoints = kvaser_usb_leaf_setup_endpoints,
+ 	.dev_init_card = kvaser_usb_leaf_init_card,
++	.dev_init_channel = kvaser_usb_leaf_init_channel,
++	.dev_remove_channel = kvaser_usb_leaf_remove_channel,
+ 	.dev_get_software_info = kvaser_usb_leaf_get_software_info,
+ 	.dev_get_software_details = NULL,
+ 	.dev_get_card_info = kvaser_usb_leaf_get_card_info,
+-	.dev_get_capabilities = NULL,
++	.dev_get_capabilities = kvaser_usb_leaf_get_capabilities,
+ 	.dev_set_opt_mode = kvaser_usb_leaf_set_opt_mode,
+ 	.dev_start_chip = kvaser_usb_leaf_start_chip,
+ 	.dev_stop_chip = kvaser_usb_leaf_stop_chip,
+diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
+index 1de62604434d8..2ed64fa19d020 100644
+--- a/drivers/net/dsa/lan9303-core.c
++++ b/drivers/net/dsa/lan9303-core.c
+@@ -1003,9 +1003,11 @@ static void lan9303_get_ethtool_stats(struct dsa_switch *ds, int port,
+ 		ret = lan9303_read_switch_port(
+ 			chip, port, lan9303_mib[u].offset, &reg);
+ 
+-		if (ret)
++		if (ret) {
+ 			dev_warn(chip->dev, "Reading status port %d reg %u failed\n",
+ 				 port, lan9303_mib[u].offset);
++			reg = 0;
++		}
+ 		data[u] = reg;
+ 	}
+ }
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index 546d90dae9331..0fd978e3ce2de 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -689,13 +689,12 @@ static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
+ 
+ 	/* Port 4 supports automedia if the serdes is associated with it. */
+ 	if (port == 4) {
+-		mv88e6xxx_reg_lock(chip);
+ 		err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
+ 		if (err < 0)
+ 			dev_err(chip->dev, "p%d: failed to read scratch\n",
+ 				port);
+ 		if (err <= 0)
+-			goto unlock;
++			return;
+ 
+ 		cmode = mv88e6352_get_port4_serdes_cmode(chip);
+ 		if (cmode < 0)
+@@ -703,8 +702,6 @@ static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
+ 				port);
+ 		else
+ 			mv88e6xxx_translate_cmode(cmode, supported);
+-unlock:
+-		mv88e6xxx_reg_unlock(chip);
+ 	}
+ }
+ 
+@@ -823,7 +820,9 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
+ {
+ 	struct mv88e6xxx_chip *chip = ds->priv;
+ 
++	mv88e6xxx_reg_lock(chip);
+ 	chip->info->ops->phylink_get_caps(chip, port, config);
++	mv88e6xxx_reg_unlock(chip);
+ 
+ 	if (mv88e6xxx_phy_is_internal(ds, port)) {
+ 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
+@@ -3299,7 +3298,7 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
+ 		struct phylink_config pl_config = {};
+ 		unsigned long caps;
+ 
+-		mv88e6xxx_get_caps(ds, port, &pl_config);
++		chip->info->ops->phylink_get_caps(chip, port, &pl_config);
+ 
+ 		caps = pl_config.mac_capabilities;
+ 
+diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c
+index 27869164c6e62..ca12f9f488390 100644
+--- a/drivers/net/ethernet/amd/atarilance.c
++++ b/drivers/net/ethernet/amd/atarilance.c
+@@ -824,7 +824,7 @@ lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len );
+ 	head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP;
+ 	dev->stats.tx_bytes += skb->len;
+-	dev_kfree_skb( skb );
++	dev_consume_skb_irq(skb);
+ 	lp->cur_tx++;
+ 	while( lp->cur_tx >= TX_RING_SIZE && lp->dirty_tx >= TX_RING_SIZE ) {
+ 		lp->cur_tx -= TX_RING_SIZE;
+diff --git a/drivers/net/ethernet/amd/lance.c b/drivers/net/ethernet/amd/lance.c
+index 462016666752c..e3b8de9fc728f 100644
+--- a/drivers/net/ethernet/amd/lance.c
++++ b/drivers/net/ethernet/amd/lance.c
+@@ -1001,7 +1001,7 @@ static netdev_tx_t lance_start_xmit(struct sk_buff *skb,
+ 		skb_copy_from_linear_data(skb, &lp->tx_bounce_buffs[entry], skb->len);
+ 		lp->tx_ring[entry].base =
+ 			((u32)isa_virt_to_bus((lp->tx_bounce_buffs + entry)) & 0xffffff) | 0x83000000;
+-		dev_kfree_skb(skb);
++		dev_consume_skb_irq(skb);
+ 	} else {
+ 		lp->tx_skbuff[entry] = skb;
+ 		lp->tx_ring[entry].base = ((u32)isa_virt_to_bus(skb->data) & 0xffffff) | 0x83000000;
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+index 601a9f2fa9bfc..1ef04326a5727 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+@@ -189,6 +189,7 @@ enum xgbe_sfp_cable {
+ 	XGBE_SFP_CABLE_UNKNOWN = 0,
+ 	XGBE_SFP_CABLE_ACTIVE,
+ 	XGBE_SFP_CABLE_PASSIVE,
++	XGBE_SFP_CABLE_FIBER,
+ };
+ 
+ enum xgbe_sfp_base {
+@@ -236,10 +237,7 @@ enum xgbe_sfp_speed {
+ 
+ #define XGBE_SFP_BASE_BR			12
+ #define XGBE_SFP_BASE_BR_1GBE_MIN		0x0a
+-#define XGBE_SFP_BASE_BR_1GBE_MAX		0x0d
+ #define XGBE_SFP_BASE_BR_10GBE_MIN		0x64
+-#define XGBE_SFP_BASE_BR_10GBE_MAX		0x68
+-#define XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX	0x78
+ 
+ #define XGBE_SFP_BASE_CU_CABLE_LEN		18
+ 
+@@ -826,29 +824,22 @@ static void xgbe_phy_sfp_phy_settings(struct xgbe_prv_data *pdata)
+ static bool xgbe_phy_sfp_bit_rate(struct xgbe_sfp_eeprom *sfp_eeprom,
+ 				  enum xgbe_sfp_speed sfp_speed)
+ {
+-	u8 *sfp_base, min, max;
++	u8 *sfp_base, min;
+ 
+ 	sfp_base = sfp_eeprom->base;
+ 
+ 	switch (sfp_speed) {
+ 	case XGBE_SFP_SPEED_1000:
+ 		min = XGBE_SFP_BASE_BR_1GBE_MIN;
+-		max = XGBE_SFP_BASE_BR_1GBE_MAX;
+ 		break;
+ 	case XGBE_SFP_SPEED_10000:
+ 		min = XGBE_SFP_BASE_BR_10GBE_MIN;
+-		if (memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME],
+-			   XGBE_MOLEX_VENDOR, XGBE_SFP_BASE_VENDOR_NAME_LEN) == 0)
+-			max = XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX;
+-		else
+-			max = XGBE_SFP_BASE_BR_10GBE_MAX;
+ 		break;
+ 	default:
+ 		return false;
+ 	}
+ 
+-	return ((sfp_base[XGBE_SFP_BASE_BR] >= min) &&
+-		(sfp_base[XGBE_SFP_BASE_BR] <= max));
++	return sfp_base[XGBE_SFP_BASE_BR] >= min;
+ }
+ 
+ static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata)
+@@ -1149,16 +1140,18 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
+ 	phy_data->sfp_tx_fault = xgbe_phy_check_sfp_tx_fault(phy_data);
+ 	phy_data->sfp_rx_los = xgbe_phy_check_sfp_rx_los(phy_data);
+ 
+-	/* Assume ACTIVE cable unless told it is PASSIVE */
++	/* Assume FIBER cable unless told otherwise */
+ 	if (sfp_base[XGBE_SFP_BASE_CABLE] & XGBE_SFP_BASE_CABLE_PASSIVE) {
+ 		phy_data->sfp_cable = XGBE_SFP_CABLE_PASSIVE;
+ 		phy_data->sfp_cable_len = sfp_base[XGBE_SFP_BASE_CU_CABLE_LEN];
+-	} else {
++	} else if (sfp_base[XGBE_SFP_BASE_CABLE] & XGBE_SFP_BASE_CABLE_ACTIVE) {
+ 		phy_data->sfp_cable = XGBE_SFP_CABLE_ACTIVE;
++	} else {
++		phy_data->sfp_cable = XGBE_SFP_CABLE_FIBER;
+ 	}
+ 
+ 	/* Determine the type of SFP */
+-	if (phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE &&
++	if (phy_data->sfp_cable != XGBE_SFP_CABLE_FIBER &&
+ 	    xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000))
+ 		phy_data->sfp_base = XGBE_SFP_BASE_10000_CR;
+ 	else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR)
+diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c
+index 334de0d93c899..9e653e2925f78 100644
+--- a/drivers/net/ethernet/apple/bmac.c
++++ b/drivers/net/ethernet/apple/bmac.c
+@@ -1510,7 +1510,7 @@ static void bmac_tx_timeout(struct timer_list *t)
+ 	i = bp->tx_empty;
+ 	++dev->stats.tx_errors;
+ 	if (i != bp->tx_fill) {
+-		dev_kfree_skb(bp->tx_bufs[i]);
++		dev_kfree_skb_irq(bp->tx_bufs[i]);
+ 		bp->tx_bufs[i] = NULL;
+ 		if (++i >= N_TX_RING) i = 0;
+ 		bp->tx_empty = i;
+diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c
+index d0a771b65e888..fd1b008b7208c 100644
+--- a/drivers/net/ethernet/apple/mace.c
++++ b/drivers/net/ethernet/apple/mace.c
+@@ -846,7 +846,7 @@ static void mace_tx_timeout(struct timer_list *t)
+     if (mp->tx_bad_runt) {
+ 	mp->tx_bad_runt = 0;
+     } else if (i != mp->tx_fill) {
+-	dev_kfree_skb(mp->tx_bufs[i]);
++	dev_kfree_skb_irq(mp->tx_bufs[i]);
+ 	if (++i >= N_TX_RING)
+ 	    i = 0;
+ 	mp->tx_empty = i;
+diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c
+index 92462ed87bc43..d9f0c297ae2a0 100644
+--- a/drivers/net/ethernet/dnet.c
++++ b/drivers/net/ethernet/dnet.c
+@@ -550,11 +550,11 @@ static netdev_tx_t dnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 
+ 	skb_tx_timestamp(skb);
+ 
++	spin_unlock_irqrestore(&bp->lock, flags);
++
+ 	/* free the buffer */
+ 	dev_kfree_skb(skb);
+ 
+-	spin_unlock_irqrestore(&bp->lock, flags);
+-
+ 	return NETDEV_TX_OK;
+ }
+ 
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index 1d8ec1b120a13..525d506797fcf 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -1489,23 +1489,6 @@ static void enetc_xdp_drop(struct enetc_bdr *rx_ring, int rx_ring_first,
+ 	rx_ring->stats.xdp_drops++;
+ }
+ 
+-static void enetc_xdp_free(struct enetc_bdr *rx_ring, int rx_ring_first,
+-			   int rx_ring_last)
+-{
+-	while (rx_ring_first != rx_ring_last) {
+-		struct enetc_rx_swbd *rx_swbd = &rx_ring->rx_swbd[rx_ring_first];
+-
+-		if (rx_swbd->page) {
+-			dma_unmap_page(rx_ring->dev, rx_swbd->dma, PAGE_SIZE,
+-				       rx_swbd->dir);
+-			__free_page(rx_swbd->page);
+-			rx_swbd->page = NULL;
+-		}
+-		enetc_bdr_idx_inc(rx_ring, &rx_ring_first);
+-	}
+-	rx_ring->stats.xdp_redirect_failures++;
+-}
+-
+ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
+ 				   struct napi_struct *napi, int work_limit,
+ 				   struct bpf_prog *prog)
+@@ -1527,8 +1510,8 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
+ 		int orig_i, orig_cleaned_cnt;
+ 		struct xdp_buff xdp_buff;
+ 		struct sk_buff *skb;
+-		int tmp_orig_i, err;
+ 		u32 bd_status;
++		int err;
+ 
+ 		rxbd = enetc_rxbd(rx_ring, i);
+ 		bd_status = le32_to_cpu(rxbd->r.lstatus);
+@@ -1615,18 +1598,16 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
+ 				break;
+ 			}
+ 
+-			tmp_orig_i = orig_i;
+-
+-			while (orig_i != i) {
+-				enetc_flip_rx_buff(rx_ring,
+-						   &rx_ring->rx_swbd[orig_i]);
+-				enetc_bdr_idx_inc(rx_ring, &orig_i);
+-			}
+-
+ 			err = xdp_do_redirect(rx_ring->ndev, &xdp_buff, prog);
+ 			if (unlikely(err)) {
+-				enetc_xdp_free(rx_ring, tmp_orig_i, i);
++				enetc_xdp_drop(rx_ring, orig_i, i);
++				rx_ring->stats.xdp_redirect_failures++;
+ 			} else {
++				while (orig_i != i) {
++					enetc_flip_rx_buff(rx_ring,
++							   &rx_ring->rx_swbd[orig_i]);
++					enetc_bdr_idx_inc(rx_ring, &orig_i);
++				}
+ 				xdp_redirect_frm_cnt++;
+ 				rx_ring->stats.xdp_redirect++;
+ 			}
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index e53ea7ed0b1d2..8c07d92a6574c 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -3692,6 +3692,24 @@ static int i40e_vsi_configure_tx(struct i40e_vsi *vsi)
+ 	return err;
+ }
+ 
++/**
++ * i40e_calculate_vsi_rx_buf_len - Calculates buffer length
++ *
++ * @vsi: VSI to calculate rx_buf_len from
++ */
++static u16 i40e_calculate_vsi_rx_buf_len(struct i40e_vsi *vsi)
++{
++	if (!vsi->netdev || (vsi->back->flags & I40E_FLAG_LEGACY_RX))
++		return I40E_RXBUFFER_2048;
++
++#if (PAGE_SIZE < 8192)
++	if (!I40E_2K_TOO_SMALL_WITH_PADDING && vsi->netdev->mtu <= ETH_DATA_LEN)
++		return I40E_RXBUFFER_1536 - NET_IP_ALIGN;
++#endif
++
++	return PAGE_SIZE < 8192 ? I40E_RXBUFFER_3072 : I40E_RXBUFFER_2048;
++}
++
+ /**
+  * i40e_vsi_configure_rx - Configure the VSI for Rx
+  * @vsi: the VSI being configured
+@@ -3703,20 +3721,14 @@ static int i40e_vsi_configure_rx(struct i40e_vsi *vsi)
+ 	int err = 0;
+ 	u16 i;
+ 
+-	if (!vsi->netdev || (vsi->back->flags & I40E_FLAG_LEGACY_RX)) {
+-		vsi->max_frame = I40E_MAX_RXBUFFER;
+-		vsi->rx_buf_len = I40E_RXBUFFER_2048;
++	vsi->max_frame = I40E_MAX_RXBUFFER;
++	vsi->rx_buf_len = i40e_calculate_vsi_rx_buf_len(vsi);
++
+ #if (PAGE_SIZE < 8192)
+-	} else if (!I40E_2K_TOO_SMALL_WITH_PADDING &&
+-		   (vsi->netdev->mtu <= ETH_DATA_LEN)) {
++	if (vsi->netdev && !I40E_2K_TOO_SMALL_WITH_PADDING &&
++	    vsi->netdev->mtu <= ETH_DATA_LEN)
+ 		vsi->max_frame = I40E_RXBUFFER_1536 - NET_IP_ALIGN;
+-		vsi->rx_buf_len = I40E_RXBUFFER_1536 - NET_IP_ALIGN;
+ #endif
+-	} else {
+-		vsi->max_frame = I40E_MAX_RXBUFFER;
+-		vsi->rx_buf_len = (PAGE_SIZE < 8192) ? I40E_RXBUFFER_3072 :
+-						       I40E_RXBUFFER_2048;
+-	}
+ 
+ 	/* set up individual rings */
+ 	for (i = 0; i < vsi->num_queue_pairs && !err; i++)
+@@ -13290,7 +13302,7 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
+ 	int i;
+ 
+ 	/* Don't allow frames that span over multiple buffers */
+-	if (frame_size > vsi->rx_buf_len) {
++	if (frame_size > i40e_calculate_vsi_rx_buf_len(vsi)) {
+ 		NL_SET_ERR_MSG_MOD(extack, "MTU too large to enable XDP");
+ 		return -EINVAL;
+ 	}
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index ea46649b2ed3e..0e36894db9863 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -1202,8 +1202,12 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
+ 	if (!q_vector) {
+ 		q_vector = kzalloc(size, GFP_KERNEL);
+ 	} else if (size > ksize(q_vector)) {
+-		kfree_rcu(q_vector, rcu);
+-		q_vector = kzalloc(size, GFP_KERNEL);
++		struct igb_q_vector *new_q_vector;
++
++		new_q_vector = kzalloc(size, GFP_KERNEL);
++		if (new_q_vector)
++			kfree_rcu(q_vector, rcu);
++		q_vector = new_q_vector;
+ 	} else {
+ 		memset(q_vector, 0, size);
+ 	}
+diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
+index 1e7e7071f64d2..df3e26c0cf01a 100644
+--- a/drivers/net/ethernet/intel/igc/igc.h
++++ b/drivers/net/ethernet/intel/igc/igc.h
+@@ -94,6 +94,8 @@ struct igc_ring {
+ 	u8 queue_index;                 /* logical index of the ring*/
+ 	u8 reg_idx;                     /* physical index of the ring */
+ 	bool launchtime_enable;         /* true if LaunchTime is enabled */
++	ktime_t last_tx_cycle;          /* end of the cycle with a launchtime transmission */
++	ktime_t last_ff_cycle;          /* Last cycle with an active first flag */
+ 
+ 	u32 start_time;
+ 	u32 end_time;
+@@ -182,6 +184,7 @@ struct igc_adapter {
+ 
+ 	ktime_t base_time;
+ 	ktime_t cycle_time;
++	bool qbv_enable;
+ 
+ 	/* OS defined structs */
+ 	struct pci_dev *pdev;
+diff --git a/drivers/net/ethernet/intel/igc/igc_defines.h b/drivers/net/ethernet/intel/igc/igc_defines.h
+index 5c66b97c0cfac..4f2c446ace4d9 100644
+--- a/drivers/net/ethernet/intel/igc/igc_defines.h
++++ b/drivers/net/ethernet/intel/igc/igc_defines.h
+@@ -321,6 +321,8 @@
+ #define IGC_ADVTXD_L4LEN_SHIFT	8  /* Adv ctxt L4LEN shift */
+ #define IGC_ADVTXD_MSS_SHIFT	16 /* Adv ctxt MSS shift */
+ 
++#define IGC_ADVTXD_TSN_CNTX_FIRST	0x00000080
++
+ /* Transmit Control */
+ #define IGC_TCTL_EN		0x00000002 /* enable Tx */
+ #define IGC_TCTL_PSP		0x00000008 /* pad short packets */
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
+index ebff0e04045d6..76f015196fbf4 100644
+--- a/drivers/net/ethernet/intel/igc/igc_main.c
++++ b/drivers/net/ethernet/intel/igc/igc_main.c
+@@ -1000,25 +1000,118 @@ static int igc_write_mc_addr_list(struct net_device *netdev)
+ 	return netdev_mc_count(netdev);
+ }
+ 
+-static __le32 igc_tx_launchtime(struct igc_adapter *adapter, ktime_t txtime)
++static __le32 igc_tx_launchtime(struct igc_ring *ring, ktime_t txtime,
++				bool *first_flag, bool *insert_empty)
+ {
++	struct igc_adapter *adapter = netdev_priv(ring->netdev);
+ 	ktime_t cycle_time = adapter->cycle_time;
+ 	ktime_t base_time = adapter->base_time;
++	ktime_t now = ktime_get_clocktai();
++	ktime_t baset_est, end_of_cycle;
+ 	u32 launchtime;
++	s64 n;
+ 
+-	/* FIXME: when using ETF together with taprio, we may have a
+-	 * case where 'delta' is larger than the cycle_time, this may
+-	 * cause problems if we don't read the current value of
+-	 * IGC_BASET, as the value writen into the launchtime
+-	 * descriptor field may be misinterpreted.
++	n = div64_s64(ktime_sub_ns(now, base_time), cycle_time);
++
++	baset_est = ktime_add_ns(base_time, cycle_time * (n));
++	end_of_cycle = ktime_add_ns(baset_est, cycle_time);
++
++	if (ktime_compare(txtime, end_of_cycle) >= 0) {
++		if (baset_est != ring->last_ff_cycle) {
++			*first_flag = true;
++			ring->last_ff_cycle = baset_est;
++
++			if (ktime_compare(txtime, ring->last_tx_cycle) > 0)
++				*insert_empty = true;
++		}
++	}
++
++	/* Introducing a window at end of cycle on which packets
++	 * potentially not honor launchtime. Window of 5us chosen
++	 * considering software update the tail pointer and packets
++	 * are dma'ed to packet buffer.
+ 	 */
+-	div_s64_rem(ktime_sub_ns(txtime, base_time), cycle_time, &launchtime);
++	if ((ktime_sub_ns(end_of_cycle, now) < 5 * NSEC_PER_USEC))
++		netdev_warn(ring->netdev, "Packet with txtime=%llu may not be honoured\n",
++			    txtime);
++
++	ring->last_tx_cycle = end_of_cycle;
++
++	launchtime = ktime_sub_ns(txtime, baset_est);
++	if (launchtime > 0)
++		div_s64_rem(launchtime, cycle_time, &launchtime);
++	else
++		launchtime = 0;
+ 
+ 	return cpu_to_le32(launchtime);
+ }
+ 
++static int igc_init_empty_frame(struct igc_ring *ring,
++				struct igc_tx_buffer *buffer,
++				struct sk_buff *skb)
++{
++	unsigned int size;
++	dma_addr_t dma;
++
++	size = skb_headlen(skb);
++
++	dma = dma_map_single(ring->dev, skb->data, size, DMA_TO_DEVICE);
++	if (dma_mapping_error(ring->dev, dma)) {
++		netdev_err_once(ring->netdev, "Failed to map DMA for TX\n");
++		return -ENOMEM;
++	}
++
++	buffer->skb = skb;
++	buffer->protocol = 0;
++	buffer->bytecount = skb->len;
++	buffer->gso_segs = 1;
++	buffer->time_stamp = jiffies;
++	dma_unmap_len_set(buffer, len, skb->len);
++	dma_unmap_addr_set(buffer, dma, dma);
++
++	return 0;
++}
++
++static int igc_init_tx_empty_descriptor(struct igc_ring *ring,
++					struct sk_buff *skb,
++					struct igc_tx_buffer *first)
++{
++	union igc_adv_tx_desc *desc;
++	u32 cmd_type, olinfo_status;
++	int err;
++
++	if (!igc_desc_unused(ring))
++		return -EBUSY;
++
++	err = igc_init_empty_frame(ring, first, skb);
++	if (err)
++		return err;
++
++	cmd_type = IGC_ADVTXD_DTYP_DATA | IGC_ADVTXD_DCMD_DEXT |
++		   IGC_ADVTXD_DCMD_IFCS | IGC_TXD_DCMD |
++		   first->bytecount;
++	olinfo_status = first->bytecount << IGC_ADVTXD_PAYLEN_SHIFT;
++
++	desc = IGC_TX_DESC(ring, ring->next_to_use);
++	desc->read.cmd_type_len = cpu_to_le32(cmd_type);
++	desc->read.olinfo_status = cpu_to_le32(olinfo_status);
++	desc->read.buffer_addr = cpu_to_le64(dma_unmap_addr(first, dma));
++
++	netdev_tx_sent_queue(txring_txq(ring), skb->len);
++
++	first->next_to_watch = desc;
++
++	ring->next_to_use++;
++	if (ring->next_to_use == ring->count)
++		ring->next_to_use = 0;
++
++	return 0;
++}
++
++#define IGC_EMPTY_FRAME_SIZE 60
++
+ static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
+-			    struct igc_tx_buffer *first,
++			    __le32 launch_time, bool first_flag,
+ 			    u32 vlan_macip_lens, u32 type_tucmd,
+ 			    u32 mss_l4len_idx)
+ {
+@@ -1037,26 +1130,17 @@ static void igc_tx_ctxtdesc(struct igc_ring *tx_ring,
+ 	if (test_bit(IGC_RING_FLAG_TX_CTX_IDX, &tx_ring->flags))
+ 		mss_l4len_idx |= tx_ring->reg_idx << 4;
+ 
++	if (first_flag)
++		mss_l4len_idx |= IGC_ADVTXD_TSN_CNTX_FIRST;
++
+ 	context_desc->vlan_macip_lens	= cpu_to_le32(vlan_macip_lens);
+ 	context_desc->type_tucmd_mlhl	= cpu_to_le32(type_tucmd);
+ 	context_desc->mss_l4len_idx	= cpu_to_le32(mss_l4len_idx);
+-
+-	/* We assume there is always a valid Tx time available. Invalid times
+-	 * should have been handled by the upper layers.
+-	 */
+-	if (tx_ring->launchtime_enable) {
+-		struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
+-		ktime_t txtime = first->skb->tstamp;
+-
+-		skb_txtime_consumed(first->skb);
+-		context_desc->launch_time = igc_tx_launchtime(adapter,
+-							      txtime);
+-	} else {
+-		context_desc->launch_time = 0;
+-	}
++	context_desc->launch_time	= launch_time;
+ }
+ 
+-static void igc_tx_csum(struct igc_ring *tx_ring, struct igc_tx_buffer *first)
++static void igc_tx_csum(struct igc_ring *tx_ring, struct igc_tx_buffer *first,
++			__le32 launch_time, bool first_flag)
+ {
+ 	struct sk_buff *skb = first->skb;
+ 	u32 vlan_macip_lens = 0;
+@@ -1096,7 +1180,8 @@ no_csum:
+ 	vlan_macip_lens |= skb_network_offset(skb) << IGC_ADVTXD_MACLEN_SHIFT;
+ 	vlan_macip_lens |= first->tx_flags & IGC_TX_FLAGS_VLAN_MASK;
+ 
+-	igc_tx_ctxtdesc(tx_ring, first, vlan_macip_lens, type_tucmd, 0);
++	igc_tx_ctxtdesc(tx_ring, launch_time, first_flag,
++			vlan_macip_lens, type_tucmd, 0);
+ }
+ 
+ static int __igc_maybe_stop_tx(struct igc_ring *tx_ring, const u16 size)
+@@ -1320,6 +1405,7 @@ dma_error:
+ 
+ static int igc_tso(struct igc_ring *tx_ring,
+ 		   struct igc_tx_buffer *first,
++		   __le32 launch_time, bool first_flag,
+ 		   u8 *hdr_len)
+ {
+ 	u32 vlan_macip_lens, type_tucmd, mss_l4len_idx;
+@@ -1406,8 +1492,8 @@ static int igc_tso(struct igc_ring *tx_ring,
+ 	vlan_macip_lens |= (ip.hdr - skb->data) << IGC_ADVTXD_MACLEN_SHIFT;
+ 	vlan_macip_lens |= first->tx_flags & IGC_TX_FLAGS_VLAN_MASK;
+ 
+-	igc_tx_ctxtdesc(tx_ring, first, vlan_macip_lens,
+-			type_tucmd, mss_l4len_idx);
++	igc_tx_ctxtdesc(tx_ring, launch_time, first_flag,
++			vlan_macip_lens, type_tucmd, mss_l4len_idx);
+ 
+ 	return 1;
+ }
+@@ -1415,11 +1501,14 @@ static int igc_tso(struct igc_ring *tx_ring,
+ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+ 				       struct igc_ring *tx_ring)
+ {
++	bool first_flag = false, insert_empty = false;
+ 	u16 count = TXD_USE_COUNT(skb_headlen(skb));
+ 	__be16 protocol = vlan_get_protocol(skb);
+ 	struct igc_tx_buffer *first;
++	__le32 launch_time = 0;
+ 	u32 tx_flags = 0;
+ 	unsigned short f;
++	ktime_t txtime;
+ 	u8 hdr_len = 0;
+ 	int tso = 0;
+ 
+@@ -1433,11 +1522,40 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+ 		count += TXD_USE_COUNT(skb_frag_size(
+ 						&skb_shinfo(skb)->frags[f]));
+ 
+-	if (igc_maybe_stop_tx(tx_ring, count + 3)) {
++	if (igc_maybe_stop_tx(tx_ring, count + 5)) {
+ 		/* this is a hard error */
+ 		return NETDEV_TX_BUSY;
+ 	}
+ 
++	if (!tx_ring->launchtime_enable)
++		goto done;
++
++	txtime = skb->tstamp;
++	skb->tstamp = ktime_set(0, 0);
++	launch_time = igc_tx_launchtime(tx_ring, txtime, &first_flag, &insert_empty);
++
++	if (insert_empty) {
++		struct igc_tx_buffer *empty_info;
++		struct sk_buff *empty;
++		void *data;
++
++		empty_info = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
++		empty = alloc_skb(IGC_EMPTY_FRAME_SIZE, GFP_ATOMIC);
++		if (!empty)
++			goto done;
++
++		data = skb_put(empty, IGC_EMPTY_FRAME_SIZE);
++		memset(data, 0, IGC_EMPTY_FRAME_SIZE);
++
++		igc_tx_ctxtdesc(tx_ring, 0, false, 0, 0, 0);
++
++		if (igc_init_tx_empty_descriptor(tx_ring,
++						 empty,
++						 empty_info) < 0)
++			dev_kfree_skb_any(empty);
++	}
++
++done:
+ 	/* record the location of the first descriptor for this packet */
+ 	first = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
+ 	first->type = IGC_TX_BUFFER_TYPE_SKB;
+@@ -1474,11 +1592,11 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
+ 	first->tx_flags = tx_flags;
+ 	first->protocol = protocol;
+ 
+-	tso = igc_tso(tx_ring, first, &hdr_len);
++	tso = igc_tso(tx_ring, first, launch_time, first_flag, &hdr_len);
+ 	if (tso < 0)
+ 		goto out_drop;
+ 	else if (!tso)
+-		igc_tx_csum(tx_ring, first);
++		igc_tx_csum(tx_ring, first, launch_time, first_flag);
+ 
+ 	igc_tx_map(tx_ring, first, hdr_len);
+ 
+@@ -5881,10 +5999,16 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+ 	bool queue_configured[IGC_MAX_TX_QUEUES] = { };
+ 	u32 start_time = 0, end_time = 0;
+ 	size_t n;
++	int i;
++
++	adapter->qbv_enable = qopt->enable;
+ 
+ 	if (!qopt->enable)
+ 		return igc_tsn_clear_schedule(adapter);
+ 
++	if (qopt->base_time < 0)
++		return -ERANGE;
++
+ 	if (adapter->base_time)
+ 		return -EALREADY;
+ 
+@@ -5896,10 +6020,24 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+ 
+ 	for (n = 0; n < qopt->num_entries; n++) {
+ 		struct tc_taprio_sched_entry *e = &qopt->entries[n];
+-		int i;
+ 
+ 		end_time += e->interval;
+ 
++		/* If any of the conditions below are true, we need to manually
++		 * control the end time of the cycle.
++		 * 1. Qbv users can specify a cycle time that is not equal
++		 * to the total GCL intervals. Hence, recalculation is
++		 * necessary here to exclude the time interval that
++		 * exceeds the cycle time.
++		 * 2. According to IEEE Std. 802.1Q-2018 section 8.6.9.2,
++		 * once the end of the list is reached, it will switch
++		 * to the END_OF_CYCLE state and leave the gates in the
++		 * same state until the next cycle is started.
++		 */
++		if (end_time > adapter->cycle_time ||
++		    n + 1 == qopt->num_entries)
++			end_time = adapter->cycle_time;
++
+ 		for (i = 0; i < adapter->num_tx_queues; i++) {
+ 			struct igc_ring *ring = adapter->tx_ring[i];
+ 
+@@ -5920,6 +6058,18 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
+ 		start_time += e->interval;
+ 	}
+ 
++	/* Check whether a queue gets configured.
++	 * If not, set the start and end time to be end time.
++	 */
++	for (i = 0; i < adapter->num_tx_queues; i++) {
++		if (!queue_configured[i]) {
++			struct igc_ring *ring = adapter->tx_ring[i];
++
++			ring->start_time = end_time;
++			ring->end_time = end_time;
++		}
++	}
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c
+index 0fce22de2ab85..356c7455c5cee 100644
+--- a/drivers/net/ethernet/intel/igc/igc_tsn.c
++++ b/drivers/net/ethernet/intel/igc/igc_tsn.c
+@@ -36,7 +36,7 @@ static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)
+ {
+ 	unsigned int new_flags = adapter->flags & ~IGC_FLAG_TSN_ANY_ENABLED;
+ 
+-	if (adapter->base_time)
++	if (adapter->qbv_enable)
+ 		new_flags |= IGC_FLAG_TSN_QBV_ENABLED;
+ 
+ 	if (is_any_launchtime(adapter))
+@@ -110,15 +110,8 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
+ 		wr32(IGC_STQT(i), ring->start_time);
+ 		wr32(IGC_ENDQT(i), ring->end_time);
+ 
+-		if (adapter->base_time) {
+-			/* If we have a base_time we are in "taprio"
+-			 * mode and we need to be strict about the
+-			 * cycles: only transmit a packet if it can be
+-			 * completed during that cycle.
+-			 */
+-			txqctl |= IGC_TXQCTL_STRICT_CYCLE |
+-				IGC_TXQCTL_STRICT_END;
+-		}
++		txqctl |= IGC_TXQCTL_STRICT_CYCLE |
++			IGC_TXQCTL_STRICT_END;
+ 
+ 		if (ring->launchtime_enable)
+ 			txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 5380caf0acc2f..559c7a42c1c9c 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3209,6 +3209,30 @@ static void mtk_dim_tx(struct work_struct *work)
+ 	dim->state = DIM_START_MEASURE;
+ }
+ 
++static void mtk_set_mcr_max_rx(struct mtk_mac *mac, u32 val)
++{
++	struct mtk_eth *eth = mac->hw;
++	u32 mcr_cur, mcr_new;
++
++	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
++		return;
++
++	mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
++	mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK;
++
++	if (val <= 1518)
++		mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518);
++	else if (val <= 1536)
++		mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536);
++	else if (val <= 1552)
++		mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552);
++	else
++		mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048);
++
++	if (mcr_new != mcr_cur)
++		mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
++}
++
+ static int mtk_hw_init(struct mtk_eth *eth)
+ {
+ 	u32 dma_mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA |
+@@ -3248,16 +3272,17 @@ static int mtk_hw_init(struct mtk_eth *eth)
+ 		return 0;
+ 	}
+ 
+-	val = RSTCTRL_FE | RSTCTRL_PPE;
+ 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ 		regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
+-
+-		val |= RSTCTRL_ETH;
+-		if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+-			val |= RSTCTRL_PPE1;
++		val = RSTCTRL_PPE0_V2;
++	} else {
++		val = RSTCTRL_PPE0;
+ 	}
+ 
+-	ethsys_reset(eth, val);
++	if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++		val |= RSTCTRL_PPE1;
++
++	ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
+ 
+ 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+ 		regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
+@@ -3283,8 +3308,16 @@ static int mtk_hw_init(struct mtk_eth *eth)
+ 	 * up with the more appropriate value when mtk_mac_config call is being
+ 	 * invoked.
+ 	 */
+-	for (i = 0; i < MTK_MAC_COUNT; i++)
++	for (i = 0; i < MTK_MAC_COUNT; i++) {
++		struct net_device *dev = eth->netdev[i];
++
+ 		mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
++		if (dev) {
++			struct mtk_mac *mac = netdev_priv(dev);
++
++			mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN);
++		}
++	}
+ 
+ 	/* Indicates CDM to parse the MTK special tag from CPU
+ 	 * which also is working out for untag packets.
+@@ -3311,9 +3344,12 @@ static int mtk_hw_init(struct mtk_eth *eth)
+ 	mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
+ 
+ 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+-		/* PSE should not drop port8 and port9 packets */
++		/* PSE should not drop port8 and port9 packets from WDMA Tx */
+ 		mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
+ 
++		/* PSE should drop packets to port 8/9 on WDMA Rx ring full */
++		mtk_w32(eth, 0x00000300, PSE_PPE0_DROP);
++
+ 		/* PSE Free Queue Flow Control  */
+ 		mtk_w32(eth, 0x01fa01f4, PSE_FQFC_CFG2);
+ 
+@@ -3400,7 +3436,6 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)
+ 	int length = new_mtu + MTK_RX_ETH_HLEN;
+ 	struct mtk_mac *mac = netdev_priv(dev);
+ 	struct mtk_eth *eth = mac->hw;
+-	u32 mcr_cur, mcr_new;
+ 
+ 	if (rcu_access_pointer(eth->prog) &&
+ 	    length > MTK_PP_MAX_BUF_SIZE) {
+@@ -3408,23 +3443,7 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)
+ 		return -EINVAL;
+ 	}
+ 
+-	if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
+-		mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+-		mcr_new = mcr_cur & ~MAC_MCR_MAX_RX_MASK;
+-
+-		if (length <= 1518)
+-			mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1518);
+-		else if (length <= 1536)
+-			mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1536);
+-		else if (length <= 1552)
+-			mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_1552);
+-		else
+-			mcr_new |= MAC_MCR_MAX_RX(MAC_MCR_MAX_RX_2048);
+-
+-		if (mcr_new != mcr_cur)
+-			mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
+-	}
+-
++	mtk_set_mcr_max_rx(mac, length);
+ 	dev->mtu = new_mtu;
+ 
+ 	return 0;
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+index 0f9668a4079d9..df8e6e95254ec 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -121,6 +121,7 @@
+ #define PSE_FQFC_CFG1		0x100
+ #define PSE_FQFC_CFG2		0x104
+ #define PSE_DROP_CFG		0x108
++#define PSE_PPE0_DROP		0x110
+ 
+ /* PSE Input Queue Reservation Register*/
+ #define PSE_IQ_REV(x)		(0x140 + (((x) - 1) << 2))
+@@ -451,18 +452,14 @@
+ /* ethernet reset control register */
+ #define ETHSYS_RSTCTRL			0x34
+ #define RSTCTRL_FE			BIT(6)
+-#define RSTCTRL_PPE			BIT(31)
+-#define RSTCTRL_PPE1			BIT(30)
++#define RSTCTRL_PPE0			BIT(31)
++#define RSTCTRL_PPE0_V2			BIT(30)
++#define RSTCTRL_PPE1			BIT(31)
+ #define RSTCTRL_ETH			BIT(23)
+ 
+ /* ethernet reset check idle register */
+ #define ETHSYS_FE_RST_CHK_IDLE_EN	0x28
+ 
+-/* ethernet reset control register */
+-#define ETHSYS_RSTCTRL		0x34
+-#define RSTCTRL_FE		BIT(6)
+-#define RSTCTRL_PPE		BIT(31)
+-
+ /* ethernet dma channel agent map */
+ #define ETHSYS_DMA_AG_MAP	0x408
+ #define ETHSYS_DMA_AG_MAP_PDMA	BIT(0)
+diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+index 971dde8c32864..35410c9a3ecf0 100644
+--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
++++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+@@ -3913,6 +3913,7 @@ abort_with_slices:
+ 	myri10ge_free_slices(mgp);
+ 
+ abort_with_firmware:
++	kfree(mgp->msix_vectors);
+ 	myri10ge_dummy_rdma(mgp, 0);
+ 
+ abort_with_ioremap:
+diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
+index 8f74c039b3be2..29d39e5b9cf53 100644
+--- a/drivers/net/ethernet/neterion/s2io.c
++++ b/drivers/net/ethernet/neterion/s2io.c
+@@ -2386,7 +2386,7 @@ static void free_tx_buffers(struct s2io_nic *nic)
+ 			skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
+ 			if (skb) {
+ 				swstats->mem_freed += skb->truesize;
+-				dev_kfree_skb(skb);
++				dev_kfree_skb_irq(skb);
+ 				cnt++;
+ 			}
+ 		}
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+index 5250d1d1e49ca..86ecb080b1536 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_debug.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c
+@@ -1972,9 +1972,10 @@ static u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn,
+ 				   u8 split_id)
+ {
+ 	struct dbg_tools_data *dev_data = &p_hwfn->dbg_info;
+-	u8 port_id = 0, pf_id = 0, vf_id = 0, fid = 0;
++	u8 port_id = 0, pf_id = 0, vf_id = 0;
+ 	bool read_using_dmae = false;
+ 	u32 thresh;
++	u16 fid;
+ 
+ 	if (!dump)
+ 		return len;
+diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+index 9282321c2e7fb..f9dd50152b1e3 100644
+--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
++++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+@@ -221,6 +221,8 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs)
+ 	return 0;
+ 
+ qlcnic_destroy_async_wq:
++	while (i--)
++		kfree(sriov->vf_info[i].vp);
+ 	destroy_workqueue(bc->bc_async_wq);
+ 
+ qlcnic_destroy_trans_wq:
+diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c
+index a6bf7d5051786..322d4d72d2e05 100644
+--- a/drivers/net/ethernet/rdc/r6040.c
++++ b/drivers/net/ethernet/rdc/r6040.c
+@@ -1159,10 +1159,12 @@ static int r6040_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	err = register_netdev(dev);
+ 	if (err) {
+ 		dev_err(&pdev->dev, "Failed to register net device\n");
+-		goto err_out_mdio_unregister;
++		goto err_out_phy_disconnect;
+ 	}
+ 	return 0;
+ 
++err_out_phy_disconnect:
++	phy_disconnect(dev->phydev);
+ err_out_mdio_unregister:
+ 	mdiobus_unregister(lp->mii_bus);
+ err_out_mdio:
+@@ -1186,6 +1188,7 @@ static void r6040_remove_one(struct pci_dev *pdev)
+ 	struct r6040_private *lp = netdev_priv(dev);
+ 
+ 	unregister_netdev(dev);
++	phy_disconnect(dev->phydev);
+ 	mdiobus_unregister(lp->mii_bus);
+ 	mdiobus_free(lp->mii_bus);
+ 	netif_napi_del(&lp->napi);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
+index 764832f4dae1a..8b50f03056b7b 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
+@@ -47,7 +47,8 @@ static void config_sub_second_increment(void __iomem *ioaddr,
+ 	if (!(value & PTP_TCR_TSCTRLSSR))
+ 		data = (data * 1000) / 465;
+ 
+-	data &= PTP_SSIR_SSINC_MASK;
++	if (data > PTP_SSIR_SSINC_MAX)
++		data = PTP_SSIR_SSINC_MAX;
+ 
+ 	reg_value = data;
+ 	if (gmac4)
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 0f080bfe8b176..bc4be1157aba7 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -7115,7 +7115,8 @@ int stmmac_dvr_probe(struct device *device,
+ 	priv->wq = create_singlethread_workqueue("stmmac_wq");
+ 	if (!priv->wq) {
+ 		dev_err(priv->device, "failed to create workqueue\n");
+-		return -ENOMEM;
++		ret = -ENOMEM;
++		goto error_wq_init;
+ 	}
+ 
+ 	INIT_WORK(&priv->service_task, stmmac_service_task);
+@@ -7343,6 +7344,7 @@ error_mdio_register:
+ 	stmmac_napi_del(ndev);
+ error_hw_init:
+ 	destroy_workqueue(priv->wq);
++error_wq_init:
+ 	bitmap_free(priv->af_xdp_zc_qps);
+ 
+ 	return ret;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+index 53172a4398101..bf619295d079f 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+@@ -64,7 +64,7 @@
+ #define	PTP_TCR_TSENMACADDR	BIT(18)
+ 
+ /* SSIR defines */
+-#define	PTP_SSIR_SSINC_MASK		0xff
++#define	PTP_SSIR_SSINC_MAX		0xff
+ #define	GMAC4_PTP_SSIR_SSINC_SHIFT	16
+ 
+ /* Auxiliary Control defines */
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+index 49af7e78b7f59..687f43cd466c6 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+@@ -1654,12 +1654,16 @@ static int stmmac_test_arpoffload(struct stmmac_priv *priv)
+ 	}
+ 
+ 	ret = stmmac_set_arp_offload(priv, priv->hw, true, ip_addr);
+-	if (ret)
++	if (ret) {
++		kfree_skb(skb);
+ 		goto cleanup;
++	}
+ 
+ 	ret = dev_set_promiscuity(priv->dev, 1);
+-	if (ret)
++	if (ret) {
++		kfree_skb(skb);
+ 		goto cleanup;
++	}
+ 
+ 	ret = dev_direct_xmit(skb, 0);
+ 	if (ret)
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 47da11b9ac286..58678843d7948 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -562,13 +562,13 @@ static int am65_cpsw_nuss_ndo_slave_open(struct net_device *ndev)
+ 	ret = netif_set_real_num_tx_queues(ndev, common->tx_ch_num);
+ 	if (ret) {
+ 		dev_err(common->dev, "cannot set real number of tx queues\n");
+-		return ret;
++		goto runtime_put;
+ 	}
+ 
+ 	ret = netif_set_real_num_rx_queues(ndev, AM65_CPSW_MAX_RX_QUEUES);
+ 	if (ret) {
+ 		dev_err(common->dev, "cannot set real number of rx queues\n");
+-		return ret;
++		goto runtime_put;
+ 	}
+ 
+ 	for (i = 0; i < common->tx_ch_num; i++)
+@@ -576,7 +576,7 @@ static int am65_cpsw_nuss_ndo_slave_open(struct net_device *ndev)
+ 
+ 	ret = am65_cpsw_nuss_common_open(common, ndev->features);
+ 	if (ret)
+-		return ret;
++		goto runtime_put;
+ 
+ 	common->usage_count++;
+ 
+@@ -609,6 +609,10 @@ static int am65_cpsw_nuss_ndo_slave_open(struct net_device *ndev)
+ error_cleanup:
+ 	am65_cpsw_nuss_ndo_slave_stop(ndev);
+ 	return ret;
++
++runtime_put:
++	pm_runtime_put(common->dev);
++	return ret;
+ }
+ 
+ static void am65_cpsw_nuss_rx_cleanup(void *data, dma_addr_t desc_dma)
+diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c
+index b15d44261e766..2672525609425 100644
+--- a/drivers/net/ethernet/ti/netcp_core.c
++++ b/drivers/net/ethernet/ti/netcp_core.c
+@@ -1261,7 +1261,7 @@ out:
+ }
+ 
+ /* Submit the packet */
+-static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
++static netdev_tx_t netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ {
+ 	struct netcp_intf *netcp = netdev_priv(ndev);
+ 	struct netcp_stats *tx_stats = &netcp->stats;
+diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+index 016a9c4f2c6c7..ce0444b09664f 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c
++++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c
+@@ -536,7 +536,7 @@ static void xemaclite_tx_timeout(struct net_device *dev, unsigned int txqueue)
+ 	xemaclite_enable_interrupts(lp);
+ 
+ 	if (lp->deferred_skb) {
+-		dev_kfree_skb(lp->deferred_skb);
++		dev_kfree_skb_irq(lp->deferred_skb);
+ 		lp->deferred_skb = NULL;
+ 		dev->stats.tx_errors++;
+ 	}
+diff --git a/drivers/net/fddi/defxx.c b/drivers/net/fddi/defxx.c
+index b584ffe38ad68..1fef8a9b1a0fd 100644
+--- a/drivers/net/fddi/defxx.c
++++ b/drivers/net/fddi/defxx.c
+@@ -3831,10 +3831,24 @@ static int dfx_init(void)
+ 	int status;
+ 
+ 	status = pci_register_driver(&dfx_pci_driver);
+-	if (!status)
+-		status = eisa_driver_register(&dfx_eisa_driver);
+-	if (!status)
+-		status = tc_register_driver(&dfx_tc_driver);
++	if (status)
++		goto err_pci_register;
++
++	status = eisa_driver_register(&dfx_eisa_driver);
++	if (status)
++		goto err_eisa_register;
++
++	status = tc_register_driver(&dfx_tc_driver);
++	if (status)
++		goto err_tc_register;
++
++	return 0;
++
++err_tc_register:
++	eisa_driver_unregister(&dfx_eisa_driver);
++err_eisa_register:
++	pci_unregister_driver(&dfx_pci_driver);
++err_pci_register:
+ 	return status;
+ }
+ 
+diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
+index 3e69079ed694b..94720f8a8ba5e 100644
+--- a/drivers/net/hamradio/baycom_epp.c
++++ b/drivers/net/hamradio/baycom_epp.c
+@@ -758,7 +758,7 @@ static void epp_bh(struct work_struct *work)
+  * ===================== network driver interface =========================
+  */
+ 
+-static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t baycom_send_packet(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct baycom_state *bc = netdev_priv(dev);
+ 
+diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
+index f90830d3dfa69..a9184a78650b0 100644
+--- a/drivers/net/hamradio/scc.c
++++ b/drivers/net/hamradio/scc.c
+@@ -302,12 +302,12 @@ static inline void scc_discard_buffers(struct scc_channel *scc)
+ 	spin_lock_irqsave(&scc->lock, flags);	
+ 	if (scc->tx_buff != NULL)
+ 	{
+-		dev_kfree_skb(scc->tx_buff);
++		dev_kfree_skb_irq(scc->tx_buff);
+ 		scc->tx_buff = NULL;
+ 	}
+ 	
+ 	while (!skb_queue_empty(&scc->tx_queue))
+-		dev_kfree_skb(skb_dequeue(&scc->tx_queue));
++		dev_kfree_skb_irq(skb_dequeue(&scc->tx_queue));
+ 
+ 	spin_unlock_irqrestore(&scc->lock, flags);
+ }
+@@ -1668,7 +1668,7 @@ static netdev_tx_t scc_net_tx(struct sk_buff *skb, struct net_device *dev)
+ 	if (skb_queue_len(&scc->tx_queue) > scc->dev->tx_queue_len) {
+ 		struct sk_buff *skb_del;
+ 		skb_del = skb_dequeue(&scc->tx_queue);
+-		dev_kfree_skb(skb_del);
++		dev_kfree_skb_irq(skb_del);
+ 	}
+ 	skb_queue_tail(&scc->tx_queue, skb);
+ 	netif_trans_update(dev);
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 8dafc814282cb..022b2daabd74d 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -2621,7 +2621,7 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
+ 	const struct macsec_ops *ops;
+ 	struct macsec_context ctx;
+ 	struct macsec_dev *macsec;
+-	int ret;
++	int ret = 0;
+ 
+ 	if (!attrs[MACSEC_ATTR_IFINDEX])
+ 		return -EINVAL;
+@@ -2634,28 +2634,36 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
+ 					macsec_genl_offload_policy, NULL))
+ 		return -EINVAL;
+ 
++	rtnl_lock();
++
+ 	dev = get_dev_from_nl(genl_info_net(info), attrs);
+-	if (IS_ERR(dev))
+-		return PTR_ERR(dev);
++	if (IS_ERR(dev)) {
++		ret = PTR_ERR(dev);
++		goto out;
++	}
+ 	macsec = macsec_priv(dev);
+ 
+-	if (!tb_offload[MACSEC_OFFLOAD_ATTR_TYPE])
+-		return -EINVAL;
++	if (!tb_offload[MACSEC_OFFLOAD_ATTR_TYPE]) {
++		ret = -EINVAL;
++		goto out;
++	}
+ 
+ 	offload = nla_get_u8(tb_offload[MACSEC_OFFLOAD_ATTR_TYPE]);
+ 	if (macsec->offload == offload)
+-		return 0;
++		goto out;
+ 
+ 	/* Check if the offloading mode is supported by the underlying layers */
+ 	if (offload != MACSEC_OFFLOAD_OFF &&
+-	    !macsec_check_offload(offload, macsec))
+-		return -EOPNOTSUPP;
++	    !macsec_check_offload(offload, macsec)) {
++		ret = -EOPNOTSUPP;
++		goto out;
++	}
+ 
+ 	/* Check if the net device is busy. */
+-	if (netif_running(dev))
+-		return -EBUSY;
+-
+-	rtnl_lock();
++	if (netif_running(dev)) {
++		ret = -EBUSY;
++		goto out;
++	}
+ 
+ 	prev_offload = macsec->offload;
+ 	macsec->offload = offload;
+@@ -2690,7 +2698,7 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
+ 
+ rollback:
+ 	macsec->offload = prev_offload;
+-
++out:
+ 	rtnl_unlock();
+ 	return ret;
+ }
+diff --git a/drivers/net/mctp/mctp-serial.c b/drivers/net/mctp/mctp-serial.c
+index 7cd103fd34ef7..9f9eaf896047c 100644
+--- a/drivers/net/mctp/mctp-serial.c
++++ b/drivers/net/mctp/mctp-serial.c
+@@ -35,6 +35,8 @@
+ #define BYTE_FRAME		0x7e
+ #define BYTE_ESC		0x7d
+ 
++#define FCS_INIT		0xffff
++
+ static DEFINE_IDA(mctp_serial_ida);
+ 
+ enum mctp_serial_state {
+@@ -123,7 +125,7 @@ static void mctp_serial_tx_work(struct work_struct *work)
+ 		buf[2] = dev->txlen;
+ 
+ 		if (!dev->txpos)
+-			dev->txfcs = crc_ccitt(0, buf + 1, 2);
++			dev->txfcs = crc_ccitt(FCS_INIT, buf + 1, 2);
+ 
+ 		txlen = write_chunk(dev, buf + dev->txpos, 3 - dev->txpos);
+ 		if (txlen <= 0) {
+@@ -303,7 +305,7 @@ static void mctp_serial_push_header(struct mctp_serial *dev, unsigned char c)
+ 	case 1:
+ 		if (c == MCTP_SERIAL_VERSION) {
+ 			dev->rxpos++;
+-			dev->rxfcs = crc_ccitt_byte(0, c);
++			dev->rxfcs = crc_ccitt_byte(FCS_INIT, c);
+ 		} else {
+ 			dev->rxstate = STATE_ERR;
+ 		}
+diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c
+index dd7e273c90cbd..29b198472a2ca 100644
+--- a/drivers/net/ntb_netdev.c
++++ b/drivers/net/ntb_netdev.c
+@@ -137,7 +137,7 @@ static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data,
+ enqueue_again:
+ 	rc = ntb_transport_rx_enqueue(qp, skb, skb->data, ndev->mtu + ETH_HLEN);
+ 	if (rc) {
+-		dev_kfree_skb(skb);
++		dev_kfree_skb_any(skb);
+ 		ndev->stats.rx_errors++;
+ 		ndev->stats.rx_fifo_errors++;
+ 	}
+@@ -192,7 +192,7 @@ static void ntb_netdev_tx_handler(struct ntb_transport_qp *qp, void *qp_data,
+ 		ndev->stats.tx_aborted_errors++;
+ 	}
+ 
+-	dev_kfree_skb(skb);
++	dev_kfree_skb_any(skb);
+ 
+ 	if (ntb_transport_tx_free_entry(dev->qp) >= tx_start) {
+ 		/* Make sure anybody stopping the queue after this sees the new
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index 9206c660a72ed..d4c821c8cf57c 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -1743,6 +1743,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
+ 	int len;
+ 	unsigned char *cp;
+ 
++	skb->dev = ppp->dev;
++
+ 	if (proto < 0x8000) {
+ #ifdef CONFIG_PPP_FILTER
+ 		/* check if we should pass this packet */
+diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
+index 6a212c085435b..5b01642ca44e0 100644
+--- a/drivers/net/wan/farsync.c
++++ b/drivers/net/wan/farsync.c
+@@ -2545,6 +2545,7 @@ fst_remove_one(struct pci_dev *pdev)
+ 		struct net_device *dev = port_to_dev(&card->ports[i]);
+ 
+ 		unregister_hdlc_device(dev);
++		free_netdev(dev);
+ 	}
+ 
+ 	fst_disable_intr(card);
+@@ -2564,6 +2565,7 @@ fst_remove_one(struct pci_dev *pdev)
+ 				  card->tx_dma_handle_card);
+ 	}
+ 	fst_card_array[card->card_no] = NULL;
++	kfree(card);
+ }
+ 
+ static struct pci_driver fst_driver = {
+diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c
+index 6f937d2cc1263..ce3d613fa36c4 100644
+--- a/drivers/net/wireless/ath/ar5523/ar5523.c
++++ b/drivers/net/wireless/ath/ar5523/ar5523.c
+@@ -241,6 +241,11 @@ static void ar5523_cmd_tx_cb(struct urb *urb)
+ 	}
+ }
+ 
++static void ar5523_cancel_tx_cmd(struct ar5523 *ar)
++{
++	usb_kill_urb(ar->tx_cmd.urb_tx);
++}
++
+ static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata,
+ 		      int ilen, void *odata, int olen, int flags)
+ {
+@@ -280,6 +285,7 @@ static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata,
+ 	}
+ 
+ 	if (!wait_for_completion_timeout(&cmd->done, 2 * HZ)) {
++		ar5523_cancel_tx_cmd(ar);
+ 		cmd->odata = NULL;
+ 		ar5523_err(ar, "timeout waiting for command %02x reply\n",
+ 			   code);
+diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
+index d1ac64026cb31..9a8ea7231a9ee 100644
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -99,6 +99,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA988X_HW_2_0_VERSION,
+@@ -138,6 +139,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA9887_HW_1_0_VERSION,
+@@ -178,6 +180,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA6174_HW_3_2_VERSION,
+@@ -213,6 +216,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = true,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA6174_HW_2_1_VERSION,
+@@ -252,6 +256,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA6174_HW_2_1_VERSION,
+@@ -291,6 +296,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA6174_HW_3_0_VERSION,
+@@ -330,6 +336,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA6174_HW_3_2_VERSION,
+@@ -373,6 +380,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = true,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA99X0_HW_2_0_DEV_VERSION,
+@@ -418,6 +426,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA9984_HW_1_0_DEV_VERSION,
+@@ -470,6 +479,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA9888_HW_2_0_DEV_VERSION,
+@@ -519,6 +529,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA9377_HW_1_0_DEV_VERSION,
+@@ -558,6 +569,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA9377_HW_1_1_DEV_VERSION,
+@@ -599,6 +611,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA9377_HW_1_1_DEV_VERSION,
+@@ -631,6 +644,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = QCA4019_HW_1_0_DEV_VERSION,
+@@ -677,6 +691,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
+ 		.use_fw_tx_credits = true,
++		.delay_unmap_buffer = false,
+ 	},
+ 	{
+ 		.id = WCN3990_HW_1_0_DEV_VERSION,
+@@ -709,6 +724,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.dynamic_sar_support = true,
+ 		.hw_restart_disconnect = true,
+ 		.use_fw_tx_credits = false,
++		.delay_unmap_buffer = true,
+ 	},
+ };
+ 
+diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
+index 6d1784f74bea4..5bfeecb95fca2 100644
+--- a/drivers/net/wireless/ath/ath10k/htc.c
++++ b/drivers/net/wireless/ath/ath10k/htc.c
+@@ -56,6 +56,15 @@ void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
+ 	ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %pK\n", __func__,
+ 		   ep->eid, skb);
+ 
++	/* A corner case where the copy completion is reaching to host but still
++	 * copy engine is processing it due to which host unmaps corresponding
++	 * memory and causes SMMU fault, hence as workaround adding delay
++	 * the unmapping memory to avoid SMMU faults.
++	 */
++	if (ar->hw_params.delay_unmap_buffer &&
++	    ep->ul_pipe_id == 3)
++		mdelay(2);
++
+ 	hdr = (struct ath10k_htc_hdr *)skb->data;
+ 	ath10k_htc_restore_tx_skb(ep->htc, skb);
+ 
+diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
+index 1b99f3a39a113..9643031a4427a 100644
+--- a/drivers/net/wireless/ath/ath10k/hw.h
++++ b/drivers/net/wireless/ath/ath10k/hw.h
+@@ -637,6 +637,8 @@ struct ath10k_hw_params {
+ 	bool hw_restart_disconnect;
+ 
+ 	bool use_fw_tx_credits;
++
++	bool delay_unmap_buffer;
+ };
+ 
+ struct htt_resp;
+diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
+index bf1c938be7d0a..8015b457a870f 100644
+--- a/drivers/net/wireless/ath/ath10k/pci.c
++++ b/drivers/net/wireless/ath/ath10k/pci.c
+@@ -3793,18 +3793,22 @@ static struct pci_driver ath10k_pci_driver = {
+ 
+ static int __init ath10k_pci_init(void)
+ {
+-	int ret;
++	int ret1, ret2;
+ 
+-	ret = pci_register_driver(&ath10k_pci_driver);
+-	if (ret)
++	ret1 = pci_register_driver(&ath10k_pci_driver);
++	if (ret1)
+ 		printk(KERN_ERR "failed to register ath10k pci driver: %d\n",
+-		       ret);
++		       ret1);
+ 
+-	ret = ath10k_ahb_init();
+-	if (ret)
+-		printk(KERN_ERR "ahb init failed: %d\n", ret);
++	ret2 = ath10k_ahb_init();
++	if (ret2)
++		printk(KERN_ERR "ahb init failed: %d\n", ret2);
+ 
+-	return ret;
++	if (ret1 && ret2)
++		return ret1;
++
++	/* registered to at least one bus */
++	return 0;
+ }
+ module_init(ath10k_pci_init);
+ 
+diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
+index 9df6aaae8a443..1e9e4eae7a1e0 100644
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -535,6 +535,52 @@ static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base
+ 	return &ab->pdevs[0];
+ }
+ 
++void ath11k_fw_stats_pdevs_free(struct list_head *head)
++{
++	struct ath11k_fw_stats_pdev *i, *tmp;
++
++	list_for_each_entry_safe(i, tmp, head, list) {
++		list_del(&i->list);
++		kfree(i);
++	}
++}
++
++void ath11k_fw_stats_vdevs_free(struct list_head *head)
++{
++	struct ath11k_fw_stats_vdev *i, *tmp;
++
++	list_for_each_entry_safe(i, tmp, head, list) {
++		list_del(&i->list);
++		kfree(i);
++	}
++}
++
++void ath11k_fw_stats_bcn_free(struct list_head *head)
++{
++	struct ath11k_fw_stats_bcn *i, *tmp;
++
++	list_for_each_entry_safe(i, tmp, head, list) {
++		list_del(&i->list);
++		kfree(i);
++	}
++}
++
++void ath11k_fw_stats_init(struct ath11k *ar)
++{
++	INIT_LIST_HEAD(&ar->fw_stats.pdevs);
++	INIT_LIST_HEAD(&ar->fw_stats.vdevs);
++	INIT_LIST_HEAD(&ar->fw_stats.bcn);
++
++	init_completion(&ar->fw_stats_complete);
++}
++
++void ath11k_fw_stats_free(struct ath11k_fw_stats *stats)
++{
++	ath11k_fw_stats_pdevs_free(&stats->pdevs);
++	ath11k_fw_stats_vdevs_free(&stats->vdevs);
++	ath11k_fw_stats_bcn_free(&stats->bcn);
++}
++
+ int ath11k_core_suspend(struct ath11k_base *ab)
+ {
+ 	int ret;
+diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h
+index afad8f55e4331..8edc1f4e5694d 100644
+--- a/drivers/net/wireless/ath/ath11k/core.h
++++ b/drivers/net/wireless/ath/ath11k/core.h
+@@ -498,6 +498,8 @@ struct ath11k_sta {
+ 
+ 	bool use_4addr_set;
+ 	u16 tcl_metadata;
++
++	u32 bw_prev;
+ };
+ 
+ #define ATH11K_MIN_5G_FREQ 4150
+@@ -545,9 +547,6 @@ struct ath11k_debug {
+ 	struct dentry *debugfs_pdev;
+ 	struct ath11k_dbg_htt_stats htt_stats;
+ 	u32 extd_tx_stats;
+-	struct ath11k_fw_stats fw_stats;
+-	struct completion fw_stats_complete;
+-	bool fw_stats_done;
+ 	u32 extd_rx_stats;
+ 	u32 pktlog_filter;
+ 	u32 pktlog_mode;
+@@ -710,6 +709,9 @@ struct ath11k {
+ 	u8 twt_enabled;
+ 	bool nlo_enabled;
+ 	u8 alpha2[REG_ALPHA2_LEN + 1];
++	struct ath11k_fw_stats fw_stats;
++	struct completion fw_stats_complete;
++	bool fw_stats_done;
+ };
+ 
+ struct ath11k_band_cap {
+@@ -1112,6 +1114,12 @@ struct ath11k_fw_stats_bcn {
+ 	u32 tx_bcn_outage_cnt;
+ };
+ 
++void ath11k_fw_stats_init(struct ath11k *ar);
++void ath11k_fw_stats_pdevs_free(struct list_head *head);
++void ath11k_fw_stats_vdevs_free(struct list_head *head);
++void ath11k_fw_stats_bcn_free(struct list_head *head);
++void ath11k_fw_stats_free(struct ath11k_fw_stats *stats);
++
+ extern const struct ce_pipe_config ath11k_target_ce_config_wlan_ipq8074[];
+ extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq8074[];
+ extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq6018[];
+diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c
+index 9648e00173936..649bf4495e4ac 100644
+--- a/drivers/net/wireless/ath/ath11k/debugfs.c
++++ b/drivers/net/wireless/ath/ath11k/debugfs.c
+@@ -91,91 +91,35 @@ void ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
+ 	spin_unlock_bh(&dbr_data->lock);
+ }
+ 
+-static void ath11k_fw_stats_pdevs_free(struct list_head *head)
+-{
+-	struct ath11k_fw_stats_pdev *i, *tmp;
+-
+-	list_for_each_entry_safe(i, tmp, head, list) {
+-		list_del(&i->list);
+-		kfree(i);
+-	}
+-}
+-
+-static void ath11k_fw_stats_vdevs_free(struct list_head *head)
+-{
+-	struct ath11k_fw_stats_vdev *i, *tmp;
+-
+-	list_for_each_entry_safe(i, tmp, head, list) {
+-		list_del(&i->list);
+-		kfree(i);
+-	}
+-}
+-
+-static void ath11k_fw_stats_bcn_free(struct list_head *head)
+-{
+-	struct ath11k_fw_stats_bcn *i, *tmp;
+-
+-	list_for_each_entry_safe(i, tmp, head, list) {
+-		list_del(&i->list);
+-		kfree(i);
+-	}
+-}
+-
+ static void ath11k_debugfs_fw_stats_reset(struct ath11k *ar)
+ {
+ 	spin_lock_bh(&ar->data_lock);
+-	ar->debug.fw_stats_done = false;
+-	ath11k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
+-	ath11k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
++	ar->fw_stats_done = false;
++	ath11k_fw_stats_pdevs_free(&ar->fw_stats.pdevs);
++	ath11k_fw_stats_vdevs_free(&ar->fw_stats.vdevs);
+ 	spin_unlock_bh(&ar->data_lock);
+ }
+ 
+-void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb)
++void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats)
+ {
+-	struct ath11k_fw_stats stats = {};
+-	struct ath11k *ar;
++	struct ath11k_base *ab = ar->ab;
+ 	struct ath11k_pdev *pdev;
+ 	bool is_end;
+ 	static unsigned int num_vdev, num_bcn;
+ 	size_t total_vdevs_started = 0;
+-	int i, ret;
+-
+-	INIT_LIST_HEAD(&stats.pdevs);
+-	INIT_LIST_HEAD(&stats.vdevs);
+-	INIT_LIST_HEAD(&stats.bcn);
+-
+-	ret = ath11k_wmi_pull_fw_stats(ab, skb, &stats);
+-	if (ret) {
+-		ath11k_warn(ab, "failed to pull fw stats: %d\n", ret);
+-		goto free;
+-	}
+-
+-	rcu_read_lock();
+-	ar = ath11k_mac_get_ar_by_pdev_id(ab, stats.pdev_id);
+-	if (!ar) {
+-		rcu_read_unlock();
+-		ath11k_warn(ab, "failed to get ar for pdev_id %d: %d\n",
+-			    stats.pdev_id, ret);
+-		goto free;
+-	}
++	int i;
+ 
+-	spin_lock_bh(&ar->data_lock);
++	/* WMI_REQUEST_PDEV_STAT request has been already processed */
+ 
+-	if (stats.stats_id == WMI_REQUEST_PDEV_STAT) {
+-		list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs);
+-		ar->debug.fw_stats_done = true;
+-		goto complete;
+-	}
+-
+-	if (stats.stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
+-		ar->debug.fw_stats_done = true;
+-		goto complete;
++	if (stats->stats_id == WMI_REQUEST_RSSI_PER_CHAIN_STAT) {
++		ar->fw_stats_done = true;
++		return;
+ 	}
+ 
+-	if (stats.stats_id == WMI_REQUEST_VDEV_STAT) {
+-		if (list_empty(&stats.vdevs)) {
++	if (stats->stats_id == WMI_REQUEST_VDEV_STAT) {
++		if (list_empty(&stats->vdevs)) {
+ 			ath11k_warn(ab, "empty vdev stats");
+-			goto complete;
++			return;
+ 		}
+ 		/* FW sends all the active VDEV stats irrespective of PDEV,
+ 		 * hence limit until the count of all VDEVs started
+@@ -188,43 +132,34 @@ void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb
+ 
+ 		is_end = ((++num_vdev) == total_vdevs_started);
+ 
+-		list_splice_tail_init(&stats.vdevs,
+-				      &ar->debug.fw_stats.vdevs);
++		list_splice_tail_init(&stats->vdevs,
++				      &ar->fw_stats.vdevs);
+ 
+ 		if (is_end) {
+-			ar->debug.fw_stats_done = true;
++			ar->fw_stats_done = true;
+ 			num_vdev = 0;
+ 		}
+-		goto complete;
++		return;
+ 	}
+ 
+-	if (stats.stats_id == WMI_REQUEST_BCN_STAT) {
+-		if (list_empty(&stats.bcn)) {
++	if (stats->stats_id == WMI_REQUEST_BCN_STAT) {
++		if (list_empty(&stats->bcn)) {
+ 			ath11k_warn(ab, "empty bcn stats");
+-			goto complete;
++			return;
+ 		}
+ 		/* Mark end until we reached the count of all started VDEVs
+ 		 * within the PDEV
+ 		 */
+ 		is_end = ((++num_bcn) == ar->num_started_vdevs);
+ 
+-		list_splice_tail_init(&stats.bcn,
+-				      &ar->debug.fw_stats.bcn);
++		list_splice_tail_init(&stats->bcn,
++				      &ar->fw_stats.bcn);
+ 
+ 		if (is_end) {
+-			ar->debug.fw_stats_done = true;
++			ar->fw_stats_done = true;
+ 			num_bcn = 0;
+ 		}
+ 	}
+-complete:
+-	complete(&ar->debug.fw_stats_complete);
+-	rcu_read_unlock();
+-	spin_unlock_bh(&ar->data_lock);
+-
+-free:
+-	ath11k_fw_stats_pdevs_free(&stats.pdevs);
+-	ath11k_fw_stats_vdevs_free(&stats.vdevs);
+-	ath11k_fw_stats_bcn_free(&stats.bcn);
+ }
+ 
+ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
+@@ -245,7 +180,7 @@ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
+ 
+ 	ath11k_debugfs_fw_stats_reset(ar);
+ 
+-	reinit_completion(&ar->debug.fw_stats_complete);
++	reinit_completion(&ar->fw_stats_complete);
+ 
+ 	ret = ath11k_wmi_send_stats_request_cmd(ar, req_param);
+ 
+@@ -255,9 +190,8 @@ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
+ 		return ret;
+ 	}
+ 
+-	time_left =
+-	wait_for_completion_timeout(&ar->debug.fw_stats_complete,
+-				    1 * HZ);
++	time_left = wait_for_completion_timeout(&ar->fw_stats_complete, 1 * HZ);
++
+ 	if (!time_left)
+ 		return -ETIMEDOUT;
+ 
+@@ -266,7 +200,7 @@ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,
+ 			break;
+ 
+ 		spin_lock_bh(&ar->data_lock);
+-		if (ar->debug.fw_stats_done) {
++		if (ar->fw_stats_done) {
+ 			spin_unlock_bh(&ar->data_lock);
+ 			break;
+ 		}
+@@ -338,8 +272,7 @@ static int ath11k_open_pdev_stats(struct inode *inode, struct file *file)
+ 		goto err_free;
+ 	}
+ 
+-	ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
+-				 buf);
++	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
+ 
+ 	file->private_data = buf;
+ 
+@@ -410,8 +343,7 @@ static int ath11k_open_vdev_stats(struct inode *inode, struct file *file)
+ 		goto err_free;
+ 	}
+ 
+-	ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
+-				 buf);
++	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
+ 
+ 	file->private_data = buf;
+ 
+@@ -488,14 +420,13 @@ static int ath11k_open_bcn_stats(struct inode *inode, struct file *file)
+ 		}
+ 	}
+ 
+-	ath11k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, req_param.stats_id,
+-				 buf);
++	ath11k_wmi_fw_stats_fill(ar, &ar->fw_stats, req_param.stats_id, buf);
+ 
+ 	/* since beacon stats request is looped for all active VDEVs, saved fw
+ 	 * stats is not freed for each request until done for all active VDEVs
+ 	 */
+ 	spin_lock_bh(&ar->data_lock);
+-	ath11k_fw_stats_bcn_free(&ar->debug.fw_stats.bcn);
++	ath11k_fw_stats_bcn_free(&ar->fw_stats.bcn);
+ 	spin_unlock_bh(&ar->data_lock);
+ 
+ 	file->private_data = buf;
+@@ -1025,7 +956,7 @@ void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
+ 	struct dentry *fwstats_dir = debugfs_create_dir("fw_stats",
+ 							ar->debug.debugfs_pdev);
+ 
+-	ar->debug.fw_stats.debugfs_fwstats = fwstats_dir;
++	ar->fw_stats.debugfs_fwstats = fwstats_dir;
+ 
+ 	/* all stats debugfs files created are under "fw_stats" directory
+ 	 * created per PDEV
+@@ -1036,12 +967,6 @@ void ath11k_debugfs_fw_stats_init(struct ath11k *ar)
+ 			    &fops_vdev_stats);
+ 	debugfs_create_file("beacon_stats", 0600, fwstats_dir, ar,
+ 			    &fops_bcn_stats);
+-
+-	INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
+-	INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
+-	INIT_LIST_HEAD(&ar->debug.fw_stats.bcn);
+-
+-	init_completion(&ar->debug.fw_stats_complete);
+ }
+ 
+ static ssize_t ath11k_write_pktlog_filter(struct file *file,
+diff --git a/drivers/net/wireless/ath/ath11k/debugfs.h b/drivers/net/wireless/ath/ath11k/debugfs.h
+index 30c00cb283118..0a84645e2e063 100644
+--- a/drivers/net/wireless/ath/ath11k/debugfs.h
++++ b/drivers/net/wireless/ath/ath11k/debugfs.h
+@@ -269,7 +269,7 @@ int ath11k_debugfs_pdev_create(struct ath11k_base *ab);
+ void ath11k_debugfs_pdev_destroy(struct ath11k_base *ab);
+ int ath11k_debugfs_register(struct ath11k *ar);
+ void ath11k_debugfs_unregister(struct ath11k *ar);
+-void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb);
++void ath11k_debugfs_fw_stats_process(struct ath11k *ar, struct ath11k_fw_stats *stats);
+ 
+ void ath11k_debugfs_fw_stats_init(struct ath11k *ar);
+ int ath11k_debugfs_get_fw_stats(struct ath11k *ar, u32 pdev_id,
+@@ -341,8 +341,8 @@ static inline void ath11k_debugfs_unregister(struct ath11k *ar)
+ {
+ }
+ 
+-static inline void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab,
+-						   struct sk_buff *skb)
++static inline void ath11k_debugfs_fw_stats_process(struct ath11k *ar,
++						   struct ath11k_fw_stats *stats)
+ {
+ }
+ 
+diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
+index 7f6521314b2d4..475ed20b495d0 100644
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -4209,10 +4209,11 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
+ 	const u8 *ht_mcs_mask;
+ 	const u16 *vht_mcs_mask;
+ 	const u16 *he_mcs_mask;
+-	u32 changed, bw, nss, smps;
++	u32 changed, bw, nss, smps, bw_prev;
+ 	int err, num_vht_rates, num_he_rates;
+ 	const struct cfg80211_bitrate_mask *mask;
+ 	struct peer_assoc_params peer_arg;
++	enum wmi_phy_mode peer_phymode;
+ 
+ 	arsta = container_of(wk, struct ath11k_sta, update_wk);
+ 	sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
+@@ -4233,6 +4234,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
+ 	arsta->changed = 0;
+ 
+ 	bw = arsta->bw;
++	bw_prev = arsta->bw_prev;
+ 	nss = arsta->nss;
+ 	smps = arsta->smps;
+ 
+@@ -4246,26 +4248,57 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
+ 			   ath11k_mac_max_he_nss(he_mcs_mask)));
+ 
+ 	if (changed & IEEE80211_RC_BW_CHANGED) {
+-		/* Send peer assoc command before set peer bandwidth param to
+-		 * avoid the mismatch between the peer phymode and the peer
+-		 * bandwidth.
+-		 */
+-		ath11k_peer_assoc_prepare(ar, arvif->vif, sta, &peer_arg, true);
+-
+-		peer_arg.is_assoc = false;
+-		err = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg);
+-		if (err) {
+-			ath11k_warn(ar->ab, "failed to send peer assoc for STA %pM vdev %i: %d\n",
+-				    sta->addr, arvif->vdev_id, err);
+-		} else if (wait_for_completion_timeout(&ar->peer_assoc_done, 1 * HZ)) {
++		/* Get the peer phymode */
++		ath11k_peer_assoc_h_phymode(ar, arvif->vif, sta, &peer_arg);
++		peer_phymode = peer_arg.peer_phymode;
++
++		ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac update sta %pM peer bw %d phymode %d\n",
++			   sta->addr, bw, peer_phymode);
++
++		if (bw > bw_prev) {
++			/* BW is upgraded. In this case we send WMI_PEER_PHYMODE
++			 * followed by WMI_PEER_CHWIDTH
++			 */
++			ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac BW upgrade for sta %pM new BW %d, old BW %d\n",
++				   sta->addr, bw, bw_prev);
++
++			err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
++							WMI_PEER_PHYMODE, peer_phymode);
++
++			if (err) {
++				ath11k_warn(ar->ab, "failed to update STA %pM peer phymode %d: %d\n",
++					    sta->addr, peer_phymode, err);
++				goto err_rc_bw_changed;
++			}
++
+ 			err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
+ 							WMI_PEER_CHWIDTH, bw);
++
+ 			if (err)
+ 				ath11k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n",
+ 					    sta->addr, bw, err);
+ 		} else {
+-			ath11k_warn(ar->ab, "failed to get peer assoc conf event for %pM vdev %i\n",
+-				    sta->addr, arvif->vdev_id);
++			/* BW is downgraded. In this case we send WMI_PEER_CHWIDTH
++			 * followed by WMI_PEER_PHYMODE
++			 */
++			ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac BW downgrade for sta %pM new BW %d,old BW %d\n",
++				   sta->addr, bw, bw_prev);
++
++			err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
++							WMI_PEER_CHWIDTH, bw);
++
++			if (err) {
++				ath11k_warn(ar->ab, "failed to update STA %pM peer bw %d: %d\n",
++					    sta->addr, bw, err);
++				goto err_rc_bw_changed;
++			}
++
++			err = ath11k_wmi_set_peer_param(ar, sta->addr, arvif->vdev_id,
++							WMI_PEER_PHYMODE, peer_phymode);
++
++			if (err)
++				ath11k_warn(ar->ab, "failed to update STA %pM peer phymode %d: %d\n",
++					    sta->addr, peer_phymode, err);
+ 		}
+ 	}
+ 
+@@ -4346,6 +4379,7 @@ static void ath11k_sta_rc_update_wk(struct work_struct *wk)
+ 		}
+ 	}
+ 
++err_rc_bw_changed:
+ 	mutex_unlock(&ar->conf_mutex);
+ }
+ 
+@@ -4499,6 +4533,34 @@ exit:
+ 	return ret;
+ }
+ 
++static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar,
++					      struct ieee80211_sta *sta)
++{
++	u32 bw = WMI_PEER_CHWIDTH_20MHZ;
++
++	switch (sta->deflink.bandwidth) {
++	case IEEE80211_STA_RX_BW_20:
++		bw = WMI_PEER_CHWIDTH_20MHZ;
++		break;
++	case IEEE80211_STA_RX_BW_40:
++		bw = WMI_PEER_CHWIDTH_40MHZ;
++		break;
++	case IEEE80211_STA_RX_BW_80:
++		bw = WMI_PEER_CHWIDTH_80MHZ;
++		break;
++	case IEEE80211_STA_RX_BW_160:
++		bw = WMI_PEER_CHWIDTH_160MHZ;
++		break;
++	default:
++		ath11k_warn(ar->ab, "Invalid bandwidth %d for %pM\n",
++			    sta->deflink.bandwidth, sta->addr);
++		bw = WMI_PEER_CHWIDTH_20MHZ;
++		break;
++	}
++
++	return bw;
++}
++
+ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
+ 				   struct ieee80211_vif *vif,
+ 				   struct ieee80211_sta *sta,
+@@ -4583,6 +4645,12 @@ static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
+ 		if (ret)
+ 			ath11k_warn(ar->ab, "Failed to associate station: %pM\n",
+ 				    sta->addr);
++
++		spin_lock_bh(&ar->data_lock);
++		/* Set arsta bw and prev bw */
++		arsta->bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta);
++		arsta->bw_prev = arsta->bw;
++		spin_unlock_bh(&ar->data_lock);
+ 	} else if (old_state == IEEE80211_STA_ASSOC &&
+ 		   new_state == IEEE80211_STA_AUTHORIZED) {
+ 		spin_lock_bh(&ar->ab->base_lock);
+@@ -4706,28 +4774,8 @@ static void ath11k_mac_op_sta_rc_update(struct ieee80211_hw *hw,
+ 	spin_lock_bh(&ar->data_lock);
+ 
+ 	if (changed & IEEE80211_RC_BW_CHANGED) {
+-		bw = WMI_PEER_CHWIDTH_20MHZ;
+-
+-		switch (sta->deflink.bandwidth) {
+-		case IEEE80211_STA_RX_BW_20:
+-			bw = WMI_PEER_CHWIDTH_20MHZ;
+-			break;
+-		case IEEE80211_STA_RX_BW_40:
+-			bw = WMI_PEER_CHWIDTH_40MHZ;
+-			break;
+-		case IEEE80211_STA_RX_BW_80:
+-			bw = WMI_PEER_CHWIDTH_80MHZ;
+-			break;
+-		case IEEE80211_STA_RX_BW_160:
+-			bw = WMI_PEER_CHWIDTH_160MHZ;
+-			break;
+-		default:
+-			ath11k_warn(ar->ab, "Invalid bandwidth %d in rc update for %pM\n",
+-				    sta->deflink.bandwidth, sta->addr);
+-			bw = WMI_PEER_CHWIDTH_20MHZ;
+-			break;
+-		}
+-
++		bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta);
++		arsta->bw_prev = arsta->bw;
+ 		arsta->bw = bw;
+ 	}
+ 
+diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
+index e6ced8597e1d6..539134a6e9d98 100644
+--- a/drivers/net/wireless/ath/ath11k/qmi.c
++++ b/drivers/net/wireless/ath/ath11k/qmi.c
+@@ -3083,6 +3083,9 @@ static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
+ 			sizeof(struct qmi_wlfw_fw_init_done_ind_msg_v01),
+ 		.fn = ath11k_qmi_msg_fw_init_done_cb,
+ 	},
++
++	/* end of list */
++	{},
+ };
+ 
+ static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
+index b658ea60dcf7d..ec9b7e954dfc8 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -7409,7 +7409,53 @@ static void ath11k_peer_assoc_conf_event(struct ath11k_base *ab, struct sk_buff
+ 
+ static void ath11k_update_stats_event(struct ath11k_base *ab, struct sk_buff *skb)
+ {
+-	ath11k_debugfs_fw_stats_process(ab, skb);
++	struct ath11k_fw_stats stats = {};
++	struct ath11k *ar;
++	int ret;
++
++	INIT_LIST_HEAD(&stats.pdevs);
++	INIT_LIST_HEAD(&stats.vdevs);
++	INIT_LIST_HEAD(&stats.bcn);
++
++	ret = ath11k_wmi_pull_fw_stats(ab, skb, &stats);
++	if (ret) {
++		ath11k_warn(ab, "failed to pull fw stats: %d\n", ret);
++		goto free;
++	}
++
++	rcu_read_lock();
++	ar = ath11k_mac_get_ar_by_pdev_id(ab, stats.pdev_id);
++	if (!ar) {
++		rcu_read_unlock();
++		ath11k_warn(ab, "failed to get ar for pdev_id %d: %d\n",
++			    stats.pdev_id, ret);
++		goto free;
++	}
++
++	spin_lock_bh(&ar->data_lock);
++
++	/* WMI_REQUEST_PDEV_STAT can be requested via .get_txpower mac ops or via
++	 * debugfs fw stats. Therefore, processing it separately.
++	 */
++	if (stats.stats_id == WMI_REQUEST_PDEV_STAT) {
++		list_splice_tail_init(&stats.pdevs, &ar->fw_stats.pdevs);
++		ar->fw_stats_done = true;
++		goto complete;
++	}
++
++	/* WMI_REQUEST_VDEV_STAT, WMI_REQUEST_BCN_STAT and WMI_REQUEST_RSSI_PER_CHAIN_STAT
++	 * are currently requested only via debugfs fw stats. Hence, processing these
++	 * in debugfs context
++	 */
++	ath11k_debugfs_fw_stats_process(ar, &stats);
++
++complete:
++	complete(&ar->fw_stats_complete);
++	rcu_read_unlock();
++	spin_unlock_bh(&ar->data_lock);
++
++free:
++	ath11k_fw_stats_free(&stats);
+ }
+ 
+ /* PDEV_CTL_FAILSAFE_CHECK_EVENT is received from FW when the frequency scanned
+diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
+index 4d9002a9d082c..1a2e0c7eeb023 100644
+--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
+@@ -708,14 +708,13 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
+ 	struct rx_buf *rx_buf = (struct rx_buf *)urb->context;
+ 	struct hif_device_usb *hif_dev = rx_buf->hif_dev;
+ 	struct sk_buff *skb = rx_buf->skb;
+-	struct sk_buff *nskb;
+ 	int ret;
+ 
+ 	if (!skb)
+ 		return;
+ 
+ 	if (!hif_dev)
+-		goto free;
++		goto free_skb;
+ 
+ 	switch (urb->status) {
+ 	case 0:
+@@ -724,7 +723,7 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
+ 	case -ECONNRESET:
+ 	case -ENODEV:
+ 	case -ESHUTDOWN:
+-		goto free;
++		goto free_skb;
+ 	default:
+ 		skb_reset_tail_pointer(skb);
+ 		skb_trim(skb, 0);
+@@ -735,25 +734,27 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
+ 	if (likely(urb->actual_length != 0)) {
+ 		skb_put(skb, urb->actual_length);
+ 
+-		/* Process the command first */
++		/*
++		 * Process the command first.
++		 * skb is either freed here or passed to be
++		 * managed to another callback function.
++		 */
+ 		ath9k_htc_rx_msg(hif_dev->htc_handle, skb,
+ 				 skb->len, USB_REG_IN_PIPE);
+ 
+-
+-		nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
+-		if (!nskb) {
++		skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
++		if (!skb) {
+ 			dev_err(&hif_dev->udev->dev,
+ 				"ath9k_htc: REG_IN memory allocation failure\n");
+-			urb->context = NULL;
+-			return;
++			goto free_rx_buf;
+ 		}
+ 
+-		rx_buf->skb = nskb;
++		rx_buf->skb = skb;
+ 
+ 		usb_fill_int_urb(urb, hif_dev->udev,
+ 				 usb_rcvintpipe(hif_dev->udev,
+ 						 USB_REG_IN_PIPE),
+-				 nskb->data, MAX_REG_IN_BUF_SIZE,
++				 skb->data, MAX_REG_IN_BUF_SIZE,
+ 				 ath9k_hif_usb_reg_in_cb, rx_buf, 1);
+ 	}
+ 
+@@ -762,12 +763,13 @@ resubmit:
+ 	ret = usb_submit_urb(urb, GFP_ATOMIC);
+ 	if (ret) {
+ 		usb_unanchor_urb(urb);
+-		goto free;
++		goto free_skb;
+ 	}
+ 
+ 	return;
+-free:
++free_skb:
+ 	kfree_skb(skb);
++free_rx_buf:
+ 	kfree(rx_buf);
+ 	urb->context = NULL;
+ }
+@@ -780,14 +782,10 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
+ 	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
+ 	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
+ 				 &hif_dev->tx.tx_buf, list) {
+-		usb_get_urb(tx_buf->urb);
+-		spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
+-		usb_kill_urb(tx_buf->urb);
+ 		list_del(&tx_buf->list);
+ 		usb_free_urb(tx_buf->urb);
+ 		kfree(tx_buf->buf);
+ 		kfree(tx_buf);
+-		spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
+ 	}
+ 	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
+ 
+@@ -1329,10 +1327,24 @@ static int send_eject_command(struct usb_interface *interface)
+ static int ath9k_hif_usb_probe(struct usb_interface *interface,
+ 			       const struct usb_device_id *id)
+ {
++	struct usb_endpoint_descriptor *bulk_in, *bulk_out, *int_in, *int_out;
+ 	struct usb_device *udev = interface_to_usbdev(interface);
++	struct usb_host_interface *alt;
+ 	struct hif_device_usb *hif_dev;
+ 	int ret = 0;
+ 
++	/* Verify the expected endpoints are present */
++	alt = interface->cur_altsetting;
++	if (usb_find_common_endpoints(alt, &bulk_in, &bulk_out, &int_in, &int_out) < 0 ||
++	    usb_endpoint_num(bulk_in) != USB_WLAN_RX_PIPE ||
++	    usb_endpoint_num(bulk_out) != USB_WLAN_TX_PIPE ||
++	    usb_endpoint_num(int_in) != USB_REG_IN_PIPE ||
++	    usb_endpoint_num(int_out) != USB_REG_OUT_PIPE) {
++		dev_err(&udev->dev,
++			"ath9k_htc: Device endpoint numbers are not the expected ones\n");
++		return -ENODEV;
++	}
++
+ 	if (id->driver_info == STORAGE_DEVICE)
+ 		return send_eject_command(interface);
+ 
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+index b8379e4034a4c..55d538978e9c1 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+@@ -737,6 +737,11 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev,
+ 	u32 i, j;
+ 	char end = '\0';
+ 
++	if (chiprev >= BITS_PER_TYPE(u32)) {
++		brcmf_err("Invalid chip revision %u\n", chiprev);
++		return NULL;
++	}
++
+ 	for (i = 0; i < table_size; i++) {
+ 		if (mapping_table[i].chipid == chip &&
+ 		    mapping_table[i].revmask & BIT(chiprev))
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+index 97f0f13dfe505..5b1813c024113 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -626,7 +626,7 @@ static int brcmf_pcie_exit_download_state(struct brcmf_pciedev_info *devinfo,
+ 	}
+ 
+ 	if (!brcmf_chip_set_active(devinfo->ci, resetintr))
+-		return -EINVAL;
++		return -EIO;
+ 	return 0;
+ }
+ 
+@@ -1120,6 +1120,10 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
+ 				BRCMF_NROF_H2D_COMMON_MSGRINGS;
+ 		max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS;
+ 	}
++	if (max_flowrings > 256) {
++		brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings);
++		return -EIO;
++	}
+ 
+ 	if (devinfo->dma_idx_sz != 0) {
+ 		bufsz = (max_submissionrings + max_completionrings) *
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index 8968809399c7a..2e4cd8096f037 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -3412,6 +3412,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
+ 	/* Take arm out of reset */
+ 	if (!brcmf_chip_set_active(bus->ci, rstvec)) {
+ 		brcmf_err("error getting out of ARM core reset\n");
++		bcmerror = -EIO;
+ 		goto err;
+ 	}
+ 
+diff --git a/drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h b/drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h
+index 67122cfa22920..5409699c9a1fd 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h
++++ b/drivers/net/wireless/intel/iwlwifi/mei/iwl-mei.h
+@@ -446,9 +446,10 @@ void iwl_mei_host_associated(const struct iwl_mei_conn_info *conn_info,
+ void iwl_mei_host_disassociated(void);
+ 
+ /**
+- * iwl_mei_device_down() - must be called when the device is down
++ * iwl_mei_device_state() - must be called when the device changes up/down state
++ * @up: true if the device is up, false otherwise.
+  */
+-void iwl_mei_device_down(void);
++void iwl_mei_device_state(bool up);
+ 
+ #else
+ 
+@@ -497,7 +498,7 @@ static inline void iwl_mei_host_associated(const struct iwl_mei_conn_info *conn_
+ static inline void iwl_mei_host_disassociated(void)
+ {}
+ 
+-static inline void iwl_mei_device_down(void)
++static inline void iwl_mei_device_state(bool up)
+ {}
+ 
+ #endif /* CONFIG_IWLMEI */
+diff --git a/drivers/net/wireless/intel/iwlwifi/mei/main.c b/drivers/net/wireless/intel/iwlwifi/mei/main.c
+index 357f14626cf43..c0142093c7682 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mei/main.c
++++ b/drivers/net/wireless/intel/iwlwifi/mei/main.c
+@@ -147,9 +147,13 @@ struct iwl_mei_filters {
+  *	to send CSME_OWNERSHIP_CONFIRMED when the driver completes its down
+  *	flow.
+  * @link_prot_state: true when we are in link protection PASSIVE
++ * @device_down: true if the device is down. Used to remember to send
++ *	CSME_OWNERSHIP_CONFIRMED when the driver is already down.
+  * @csa_throttle_end_wk: used when &csa_throttled is true
+  * @data_q_lock: protects the access to the data queues which are
+  *	accessed without the mutex.
++ * @netdev_work: used to defer registering and unregistering of the netdev to
++ *	avoid taking the rtnl lock in the SAP messages handlers.
+  * @sap_seq_no: the sequence number for the SAP messages
+  * @seq_no: the sequence number for the SAP messages
+  * @dbgfs_dir: the debugfs dir entry
+@@ -167,8 +171,10 @@ struct iwl_mei {
+ 	bool csa_throttled;
+ 	bool csme_taking_ownership;
+ 	bool link_prot_state;
++	bool device_down;
+ 	struct delayed_work csa_throttle_end_wk;
+ 	spinlock_t data_q_lock;
++	struct work_struct netdev_work;
+ 
+ 	atomic_t sap_seq_no;
+ 	atomic_t seq_no;
+@@ -588,13 +594,38 @@ static rx_handler_result_t iwl_mei_rx_handler(struct sk_buff **pskb)
+ 	return res;
+ }
+ 
++static void iwl_mei_netdev_work(struct work_struct *wk)
++{
++	struct iwl_mei *mei =
++		container_of(wk, struct iwl_mei, netdev_work);
++	struct net_device *netdev;
++
++	/*
++	 * First take rtnl and only then the mutex to avoid an ABBA
++	 * with iwl_mei_set_netdev()
++	 */
++	rtnl_lock();
++	mutex_lock(&iwl_mei_mutex);
++
++	netdev = rcu_dereference_protected(iwl_mei_cache.netdev,
++					   lockdep_is_held(&iwl_mei_mutex));
++	if (netdev) {
++		if (mei->amt_enabled)
++			netdev_rx_handler_register(netdev, iwl_mei_rx_handler,
++						   mei);
++		else
++			netdev_rx_handler_unregister(netdev);
++	}
++
++	mutex_unlock(&iwl_mei_mutex);
++	rtnl_unlock();
++}
++
+ static void
+ iwl_mei_handle_rx_start_ok(struct mei_cl_device *cldev,
+ 			   const struct iwl_sap_me_msg_start_ok *rsp,
+ 			   ssize_t len)
+ {
+-	struct iwl_mei *mei = mei_cldev_get_drvdata(cldev);
+-
+ 	if (len != sizeof(*rsp)) {
+ 		dev_err(&cldev->dev,
+ 			"got invalid SAP_ME_MSG_START_OK from CSME firmware\n");
+@@ -613,13 +644,10 @@ iwl_mei_handle_rx_start_ok(struct mei_cl_device *cldev,
+ 
+ 	mutex_lock(&iwl_mei_mutex);
+ 	set_bit(IWL_MEI_STATUS_SAP_CONNECTED, &iwl_mei_status);
+-	/* wifi driver has registered already */
+-	if (iwl_mei_cache.ops) {
+-		iwl_mei_send_sap_msg(mei->cldev,
+-				     SAP_MSG_NOTIF_WIFIDR_UP);
+-		iwl_mei_cache.ops->sap_connected(iwl_mei_cache.priv);
+-	}
+-
++	/*
++	 * We'll receive AMT_STATE SAP message in a bit and
++	 * that will continue the flow
++	 */
+ 	mutex_unlock(&iwl_mei_mutex);
+ }
+ 
+@@ -712,6 +740,13 @@ static void iwl_mei_set_init_conf(struct iwl_mei *mei)
+ 		.val = cpu_to_le32(iwl_mei_cache.rf_kill),
+ 	};
+ 
++	/* wifi driver has registered already */
++	if (iwl_mei_cache.ops) {
++		iwl_mei_send_sap_msg(mei->cldev,
++				     SAP_MSG_NOTIF_WIFIDR_UP);
++		iwl_mei_cache.ops->sap_connected(iwl_mei_cache.priv);
++	}
++
+ 	iwl_mei_send_sap_msg(mei->cldev, SAP_MSG_NOTIF_WHO_OWNS_NIC);
+ 
+ 	if (iwl_mei_cache.conn_info) {
+@@ -738,38 +773,23 @@ static void iwl_mei_handle_amt_state(struct mei_cl_device *cldev,
+ 				     const struct iwl_sap_msg_dw *dw)
+ {
+ 	struct iwl_mei *mei = mei_cldev_get_drvdata(cldev);
+-	struct net_device *netdev;
+ 
+-	/*
+-	 * First take rtnl and only then the mutex to avoid an ABBA
+-	 * with iwl_mei_set_netdev()
+-	 */
+-	rtnl_lock();
+ 	mutex_lock(&iwl_mei_mutex);
+ 
+-	netdev = rcu_dereference_protected(iwl_mei_cache.netdev,
+-					   lockdep_is_held(&iwl_mei_mutex));
+-
+ 	if (mei->amt_enabled == !!le32_to_cpu(dw->val))
+ 		goto out;
+ 
+ 	mei->amt_enabled = dw->val;
+ 
+-	if (mei->amt_enabled) {
+-		if (netdev)
+-			netdev_rx_handler_register(netdev, iwl_mei_rx_handler, mei);
+-
++	if (mei->amt_enabled)
+ 		iwl_mei_set_init_conf(mei);
+-	} else {
+-		if (iwl_mei_cache.ops)
+-			iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, false);
+-		if (netdev)
+-			netdev_rx_handler_unregister(netdev);
+-	}
++	else if (iwl_mei_cache.ops)
++		iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, false, false);
++
++	schedule_work(&mei->netdev_work);
+ 
+ out:
+ 	mutex_unlock(&iwl_mei_mutex);
+-	rtnl_unlock();
+ }
+ 
+ static void iwl_mei_handle_nic_owner(struct mei_cl_device *cldev,
+@@ -798,14 +818,18 @@ static void iwl_mei_handle_csme_taking_ownership(struct mei_cl_device *cldev,
+ 
+ 	mei->got_ownership = false;
+ 
+-	/*
+-	 * Remember to send CSME_OWNERSHIP_CONFIRMED when the wifi driver
+-	 * is finished taking the device down.
+-	 */
+-	mei->csme_taking_ownership = true;
++	if (iwl_mei_cache.ops && !mei->device_down) {
++		/*
++		 * Remember to send CSME_OWNERSHIP_CONFIRMED when the wifi
++		 * driver is finished taking the device down.
++		 */
++		mei->csme_taking_ownership = true;
+ 
+-	if (iwl_mei_cache.ops)
+-		iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, true);
++		iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, true, true);
++	} else {
++		iwl_mei_send_sap_msg(cldev,
++				     SAP_MSG_NOTIF_CSME_OWNERSHIP_CONFIRMED);
++	}
+ }
+ 
+ static void iwl_mei_handle_nvm(struct mei_cl_device *cldev,
+@@ -1413,10 +1437,7 @@ void iwl_mei_host_associated(const struct iwl_mei_conn_info *conn_info,
+ 
+ 	mei = mei_cldev_get_drvdata(iwl_mei_global_cldev);
+ 
+-	if (!mei)
+-		goto out;
+-
+-	if (!mei->amt_enabled)
++	if (!mei && !mei->amt_enabled)
+ 		goto out;
+ 
+ 	iwl_mei_send_sap_msg_payload(mei->cldev, &msg.hdr);
+@@ -1445,7 +1466,7 @@ void iwl_mei_host_disassociated(void)
+ 
+ 	mei = mei_cldev_get_drvdata(iwl_mei_global_cldev);
+ 
+-	if (!mei)
++	if (!mei && !mei->amt_enabled)
+ 		goto out;
+ 
+ 	iwl_mei_send_sap_msg_payload(mei->cldev, &msg.hdr);
+@@ -1481,7 +1502,7 @@ void iwl_mei_set_rfkill_state(bool hw_rfkill, bool sw_rfkill)
+ 
+ 	mei = mei_cldev_get_drvdata(iwl_mei_global_cldev);
+ 
+-	if (!mei)
++	if (!mei && !mei->amt_enabled)
+ 		goto out;
+ 
+ 	iwl_mei_send_sap_msg_payload(mei->cldev, &msg.hdr);
+@@ -1510,7 +1531,7 @@ void iwl_mei_set_nic_info(const u8 *mac_address, const u8 *nvm_address)
+ 
+ 	mei = mei_cldev_get_drvdata(iwl_mei_global_cldev);
+ 
+-	if (!mei)
++	if (!mei && !mei->amt_enabled)
+ 		goto out;
+ 
+ 	iwl_mei_send_sap_msg_payload(mei->cldev, &msg.hdr);
+@@ -1538,7 +1559,7 @@ void iwl_mei_set_country_code(u16 mcc)
+ 
+ 	mei = mei_cldev_get_drvdata(iwl_mei_global_cldev);
+ 
+-	if (!mei)
++	if (!mei && !mei->amt_enabled)
+ 		goto out;
+ 
+ 	iwl_mei_send_sap_msg_payload(mei->cldev, &msg.hdr);
+@@ -1564,7 +1585,7 @@ void iwl_mei_set_power_limit(const __le16 *power_limit)
+ 
+ 	mei = mei_cldev_get_drvdata(iwl_mei_global_cldev);
+ 
+-	if (!mei)
++	if (!mei && !mei->amt_enabled)
+ 		goto out;
+ 
+ 	memcpy(msg.sar_chain_info_table, power_limit, sizeof(msg.sar_chain_info_table));
+@@ -1616,7 +1637,7 @@ out:
+ }
+ EXPORT_SYMBOL_GPL(iwl_mei_set_netdev);
+ 
+-void iwl_mei_device_down(void)
++void iwl_mei_device_state(bool up)
+ {
+ 	struct iwl_mei *mei;
+ 
+@@ -1630,7 +1651,9 @@ void iwl_mei_device_down(void)
+ 	if (!mei)
+ 		goto out;
+ 
+-	if (!mei->csme_taking_ownership)
++	mei->device_down = !up;
++
++	if (up || !mei->csme_taking_ownership)
+ 		goto out;
+ 
+ 	iwl_mei_send_sap_msg(mei->cldev,
+@@ -1639,7 +1662,7 @@ void iwl_mei_device_down(void)
+ out:
+ 	mutex_unlock(&iwl_mei_mutex);
+ }
+-EXPORT_SYMBOL_GPL(iwl_mei_device_down);
++EXPORT_SYMBOL_GPL(iwl_mei_device_state);
+ 
+ int iwl_mei_register(void *priv, const struct iwl_mei_ops *ops)
+ {
+@@ -1669,9 +1692,10 @@ int iwl_mei_register(void *priv, const struct iwl_mei_ops *ops)
+ 
+ 		/* we have already a SAP connection */
+ 		if (iwl_mei_is_connected()) {
+-			iwl_mei_send_sap_msg(mei->cldev,
+-					     SAP_MSG_NOTIF_WIFIDR_UP);
+-			ops->rfkill(priv, mei->link_prot_state);
++			if (mei->amt_enabled)
++				iwl_mei_send_sap_msg(mei->cldev,
++						     SAP_MSG_NOTIF_WIFIDR_UP);
++			ops->rfkill(priv, mei->link_prot_state, false);
+ 		}
+ 	}
+ 	ret = 0;
+@@ -1818,9 +1842,11 @@ static int iwl_mei_probe(struct mei_cl_device *cldev,
+ 			  iwl_mei_csa_throttle_end_wk);
+ 	init_waitqueue_head(&mei->get_ownership_wq);
+ 	spin_lock_init(&mei->data_q_lock);
++	INIT_WORK(&mei->netdev_work, iwl_mei_netdev_work);
+ 
+ 	mei_cldev_set_drvdata(cldev, mei);
+ 	mei->cldev = cldev;
++	mei->device_down = true;
+ 
+ 	do {
+ 		ret = iwl_mei_alloc_shared_mem(cldev);
+@@ -1921,29 +1947,32 @@ static void iwl_mei_remove(struct mei_cl_device *cldev)
+ 
+ 	mutex_lock(&iwl_mei_mutex);
+ 
+-	/*
+-	 * Tell CSME that we are going down so that it won't access the
+-	 * memory anymore, make sure this message goes through immediately.
+-	 */
+-	mei->csa_throttled = false;
+-	iwl_mei_send_sap_msg(mei->cldev,
+-			     SAP_MSG_NOTIF_HOST_GOES_DOWN);
++	if (mei->amt_enabled) {
++		/*
++		 * Tell CSME that we are going down so that it won't access the
++		 * memory anymore, make sure this message goes through immediately.
++		 */
++		mei->csa_throttled = false;
++		iwl_mei_send_sap_msg(mei->cldev,
++				     SAP_MSG_NOTIF_HOST_GOES_DOWN);
+ 
+-	for (i = 0; i < SEND_SAP_MAX_WAIT_ITERATION; i++) {
+-		if (!iwl_mei_host_to_me_data_pending(mei))
+-			break;
++		for (i = 0; i < SEND_SAP_MAX_WAIT_ITERATION; i++) {
++			if (!iwl_mei_host_to_me_data_pending(mei))
++				break;
+ 
+-		msleep(5);
+-	}
++			msleep(20);
++		}
+ 
+-	/*
+-	 * If we couldn't make sure that CSME saw the HOST_GOES_DOWN message,
+-	 * it means that it will probably keep reading memory that we are going
+-	 * to unmap and free, expect IOMMU error messages.
+-	 */
+-	if (i == SEND_SAP_MAX_WAIT_ITERATION)
+-		dev_err(&mei->cldev->dev,
+-			"Couldn't get ACK from CSME on HOST_GOES_DOWN message\n");
++		/*
++		 * If we couldn't make sure that CSME saw the HOST_GOES_DOWN
++		 * message, it means that it will probably keep reading memory
++		 * that we are going to unmap and free, expect IOMMU error
++		 * messages.
++		 */
++		if (i == SEND_SAP_MAX_WAIT_ITERATION)
++			dev_err(&mei->cldev->dev,
++				"Couldn't get ACK from CSME on HOST_GOES_DOWN message\n");
++	}
+ 
+ 	mutex_unlock(&iwl_mei_mutex);
+ 
+@@ -1976,6 +2005,7 @@ static void iwl_mei_remove(struct mei_cl_device *cldev)
+ 	 */
+ 	cancel_work_sync(&mei->send_csa_msg_wk);
+ 	cancel_delayed_work_sync(&mei->csa_throttle_end_wk);
++	cancel_work_sync(&mei->netdev_work);
+ 
+ 	/*
+ 	 * If someone waits for the ownership, let him know that we are going
+diff --git a/drivers/net/wireless/intel/iwlwifi/mei/net.c b/drivers/net/wireless/intel/iwlwifi/mei/net.c
+index 3472167c83707..eac46d1a397a8 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mei/net.c
++++ b/drivers/net/wireless/intel/iwlwifi/mei/net.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+ /*
+- * Copyright (C) 2021 Intel Corporation
++ * Copyright (C) 2021-2022 Intel Corporation
+  */
+ 
+ #include <uapi/linux/if_ether.h>
+@@ -337,10 +337,14 @@ rx_handler_result_t iwl_mei_rx_filter(struct sk_buff *orig_skb,
+ 	if (!*pass_to_csme)
+ 		return RX_HANDLER_PASS;
+ 
+-	if (ret == RX_HANDLER_PASS)
++	if (ret == RX_HANDLER_PASS) {
+ 		skb = skb_copy(orig_skb, GFP_ATOMIC);
+-	else
++
++		if (!skb)
++			return RX_HANDLER_PASS;
++	} else {
+ 		skb = orig_skb;
++	}
+ 
+ 	/* CSME wants the MAC header as well, push it back */
+ 	skb_push(skb, skb->data - skb_mac_header(skb));
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+index f041e77af059e..5de34edc51fe9 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+@@ -1665,6 +1665,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
+ 			iwl_rfi_send_config_cmd(mvm, NULL);
+ 	}
+ 
++	iwl_mvm_mei_device_state(mvm, true);
++
+ 	IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
+ 	return 0;
+  error:
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+index bf35e130c8765..cc71049bd9b39 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+@@ -2201,10 +2201,10 @@ static inline void iwl_mvm_mei_host_disassociated(struct iwl_mvm *mvm)
+ 		iwl_mei_host_disassociated();
+ }
+ 
+-static inline void iwl_mvm_mei_device_down(struct iwl_mvm *mvm)
++static inline void iwl_mvm_mei_device_state(struct iwl_mvm *mvm, bool up)
+ {
+ 	if (mvm->mei_registered)
+-		iwl_mei_device_down();
++		iwl_mei_device_state(up);
+ }
+ 
+ static inline void iwl_mvm_mei_set_sw_rfkill_state(struct iwl_mvm *mvm)
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+index db43c8a83a319..3fec87fb6b7b6 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+@@ -1370,7 +1370,7 @@ void iwl_mvm_stop_device(struct iwl_mvm *mvm)
+ 	iwl_trans_stop_device(mvm->trans);
+ 	iwl_free_fw_paging(&mvm->fwrt);
+ 	iwl_fw_dump_conf_clear(&mvm->fwrt);
+-	iwl_mvm_mei_device_down(mvm);
++	iwl_mvm_mei_device_state(mvm, false);
+ }
+ 
+ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+index f9e08b339e0c4..0dd35344e64a8 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+@@ -1171,9 +1171,15 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
+ 	/* From now on, we cannot access info->control */
+ 	iwl_mvm_skb_prepare_status(skb, dev_cmd);
+ 
++	/*
++	 * The IV is introduced by the HW for new tx api, and it is not present
++	 * in the skb, hence, don't tell iwl_mvm_mei_tx_copy_to_csme about the
++	 * IV for those devices.
++	 */
+ 	if (ieee80211_is_data(fc))
+ 		iwl_mvm_mei_tx_copy_to_csme(mvm, skb,
+-					    info->control.hw_key ?
++					    info->control.hw_key &&
++					    !iwl_mvm_has_new_tx_api(mvm) ?
+ 					    info->control.hw_key->iv_len : 0);
+ 
+ 	if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id))
+@@ -1206,6 +1212,7 @@ int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
+ 	struct sk_buff_head mpdus_skbs;
+ 	unsigned int payload_len;
+ 	int ret;
++	struct sk_buff *orig_skb = skb;
+ 
+ 	if (WARN_ON_ONCE(!mvmsta))
+ 		return -1;
+@@ -1238,8 +1245,17 @@ int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
+ 
+ 		ret = iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
+ 		if (ret) {
++			/* Free skbs created as part of TSO logic that have not yet been dequeued */
+ 			__skb_queue_purge(&mpdus_skbs);
+-			return ret;
++			/* skb here is not necessarily same as skb that entered this method,
++			 * so free it explicitly.
++			 */
++			if (skb == orig_skb)
++				ieee80211_free_txskb(mvm->hw, skb);
++			else
++				kfree_skb(skb);
++			/* there was error, but we consumed skb one way or another, so return 0 */
++			return 0;
+ 		}
+ 	}
+ 
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
+index 4da77d47b0a67..1f8da524a3056 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76.h
++++ b/drivers/net/wireless/mediatek/mt76/mt76.h
+@@ -1101,8 +1101,9 @@ static inline bool mt76_is_skb_pktid(u8 pktid)
+ static inline u8 mt76_tx_power_nss_delta(u8 nss)
+ {
+ 	static const u8 nss_delta[4] = { 0, 6, 9, 12 };
++	u8 idx = nss - 1;
+ 
+-	return nss_delta[nss - 1];
++	return (idx < ARRAY_SIZE(nss_delta)) ? nss_delta[idx] : 0;
+ }
+ 
+ static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+index 4b1a9811646fd..0bce0ce51be00 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+@@ -173,60 +173,50 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
+ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
+ 				struct mt7915_phy *phy)
+ {
+-	u8 nss, nss_band, nss_band_max, *eeprom = dev->mt76.eeprom.data;
++	u8 path, nss, nss_max = 4, *eeprom = dev->mt76.eeprom.data;
+ 	struct mt76_phy *mphy = phy->mt76;
+-	bool ext_phy = phy != &dev->phy;
+ 
+ 	mt7915_eeprom_parse_band_config(phy);
+ 
+-	/* read tx/rx mask from eeprom */
++	/* read tx/rx path from eeprom */
+ 	if (is_mt7915(&dev->mt76)) {
+-		nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
+-				eeprom[MT_EE_WIFI_CONF]);
++		path = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
++				 eeprom[MT_EE_WIFI_CONF]);
+ 	} else {
+-		nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
+-				eeprom[MT_EE_WIFI_CONF + phy->band_idx]);
++		path = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
++				 eeprom[MT_EE_WIFI_CONF + phy->band_idx]);
+ 	}
+ 
+-	if (!nss || nss > 4)
+-		nss = 4;
++	if (!path || path > 4)
++		path = 4;
+ 
+ 	/* read tx/rx stream */
+-	nss_band = nss;
+-
++	nss = path;
+ 	if (dev->dbdc_support) {
+ 		if (is_mt7915(&dev->mt76)) {
+-			nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0,
+-					     eeprom[MT_EE_WIFI_CONF + 3]);
++			path = min_t(u8, path, 2);
++			nss = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0,
++					eeprom[MT_EE_WIFI_CONF + 3]);
+ 			if (phy->band_idx)
+-				nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1,
+-						     eeprom[MT_EE_WIFI_CONF + 3]);
++				nss = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1,
++						eeprom[MT_EE_WIFI_CONF + 3]);
+ 		} else {
+-			nss_band = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM,
+-					     eeprom[MT_EE_WIFI_CONF + 2 + phy->band_idx]);
++			nss = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM,
++					eeprom[MT_EE_WIFI_CONF + 2 + phy->band_idx]);
+ 		}
+ 
+-		nss_band_max = is_mt7986(&dev->mt76) ?
+-			       MT_EE_NSS_MAX_DBDC_MA7986 : MT_EE_NSS_MAX_DBDC_MA7915;
+-	} else {
+-		nss_band_max = is_mt7986(&dev->mt76) ?
+-			       MT_EE_NSS_MAX_MA7986 : MT_EE_NSS_MAX_MA7915;
++		if (!is_mt7986(&dev->mt76))
++			nss_max = 2;
+ 	}
+ 
+-	if (!nss_band || nss_band > nss_band_max)
+-		nss_band = nss_band_max;
+-
+-	if (nss_band > nss) {
+-		dev_warn(dev->mt76.dev,
+-			 "nss mismatch, nss(%d) nss_band(%d) band(%d) ext_phy(%d)\n",
+-			 nss, nss_band, phy->band_idx, ext_phy);
+-		nss = nss_band;
+-	}
++	if (!nss)
++		nss = nss_max;
++	nss = min_t(u8, min_t(u8, nss_max, nss), path);
+ 
+-	mphy->chainmask = BIT(nss) - 1;
+-	if (ext_phy)
++	mphy->chainmask = BIT(path) - 1;
++	if (phy->band_idx)
+ 		mphy->chainmask <<= dev->chainshift;
+-	mphy->antenna_mask = BIT(nss_band) - 1;
++	mphy->antenna_mask = BIT(nss) - 1;
+ 	dev->chainmask |= mphy->chainmask;
+ 	dev->chainshift = hweight8(dev->mphy.chainmask);
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
+index 7578ac6d0be62..f3e56817d36e9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
+@@ -58,11 +58,6 @@ enum mt7915_eeprom_field {
+ #define MT_EE_RATE_DELTA_SIGN			BIT(6)
+ #define MT_EE_RATE_DELTA_EN			BIT(7)
+ 
+-#define MT_EE_NSS_MAX_MA7915			4
+-#define MT_EE_NSS_MAX_DBDC_MA7915		2
+-#define MT_EE_NSS_MAX_MA7986			4
+-#define MT_EE_NSS_MAX_DBDC_MA7986		4
+-
+ enum mt7915_adie_sku {
+ 	MT7976_ONE_ADIE_DBDC = 0x7,
+ 	MT7975_ONE_ADIE	= 0x8,
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+index 49aa5c056063e..853d857b17579 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+@@ -1146,7 +1146,7 @@ void mt7915_mac_set_timing(struct mt7915_phy *phy)
+ 		  FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48);
+ 	u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) |
+ 		   FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28);
+-	int offset;
++	int eifs_ofdm = 360, sifs = 10, offset;
+ 	bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ);
+ 
+ 	if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
+@@ -1164,17 +1164,26 @@ void mt7915_mac_set_timing(struct mt7915_phy *phy)
+ 	reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) |
+ 		     FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset);
+ 
++	if (!is_mt7915(&dev->mt76)) {
++		if (!a_band) {
++			mt76_wr(dev, MT_TMAC_ICR1(phy->band_idx),
++				FIELD_PREP(MT_IFS_EIFS_CCK, 314));
++			eifs_ofdm = 78;
++		} else {
++			eifs_ofdm = 84;
++		}
++	} else if (a_band) {
++		sifs = 16;
++	}
++
+ 	mt76_wr(dev, MT_TMAC_CDTR(phy->band_idx), cck + reg_offset);
+ 	mt76_wr(dev, MT_TMAC_ODTR(phy->band_idx), ofdm + reg_offset);
+ 	mt76_wr(dev, MT_TMAC_ICR0(phy->band_idx),
+-		FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) |
++		FIELD_PREP(MT_IFS_EIFS_OFDM, eifs_ofdm) |
+ 		FIELD_PREP(MT_IFS_RIFS, 2) |
+-		FIELD_PREP(MT_IFS_SIFS, 10) |
++		FIELD_PREP(MT_IFS_SIFS, sifs) |
+ 		FIELD_PREP(MT_IFS_SLOT, phy->slottime));
+ 
+-	mt76_wr(dev, MT_TMAC_ICR1(phy->band_idx),
+-		FIELD_PREP(MT_IFS_EIFS_CCK, 314));
+-
+ 	if (phy->slottime < 20 || a_band)
+ 		val = MT7915_CFEND_RATE_DEFAULT;
+ 	else
+@@ -1595,7 +1604,7 @@ void mt7915_mac_update_stats(struct mt7915_phy *phy)
+ 
+ 	aggr0 = phy->band_idx ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
+ 	if (is_mt7915(&dev->mt76)) {
+-		for (i = 0, aggr1 = aggr0 + 4; i < 4; i++) {
++		for (i = 0, aggr1 = aggr0 + 8; i < 4; i++) {
+ 			val = mt76_rr(dev, MT_MIB_MB_SDR1(phy->band_idx, (i << 4)));
+ 			mib->ba_miss_cnt +=
+ 				FIELD_GET(MT_MIB_BA_MISS_COUNT_MASK, val);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
+index d74f609775d3b..7a44a4f88ccb6 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
+@@ -65,10 +65,17 @@ static void mt7915_put_hif2(struct mt7915_hif *hif)
+ 
+ static struct mt7915_hif *mt7915_pci_init_hif2(struct pci_dev *pdev)
+ {
++	struct pci_dev *tmp_pdev;
++
+ 	hif_idx++;
+-	if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL) &&
+-	    !pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x790a, NULL))
+-		return NULL;
++
++	tmp_pdev = pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL);
++	if (!tmp_pdev) {
++		tmp_pdev = pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x790a, NULL);
++		if (!tmp_pdev)
++			return NULL;
++	}
++	pci_dev_put(tmp_pdev);
+ 
+ 	writel(hif_idx | MT_PCIE_RECOG_ID_SEM,
+ 	       pcim_iomap_table(pdev)[0] + MT_PCIE_RECOG_ID);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index e8a7a58317822..5b0eba4cb4219 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -394,6 +394,27 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
+ 		if (v0 & MT_PRXV_HT_AD_CODE)
+ 			status->enc_flags |= RX_ENC_FLAG_LDPC;
+ 
++		ret = mt76_connac2_mac_fill_rx_rate(&dev->mt76, status, sband,
++						    rxv, &mode);
++		if (ret < 0)
++			return ret;
++
++		if (rxd1 & MT_RXD1_NORMAL_GROUP_5) {
++			rxd += 6;
++			if ((u8 *)rxd - skb->data >= skb->len)
++				return -EINVAL;
++
++			rxv = rxd;
++			/* Monitor mode would use RCPI described in GROUP 5
++			 * instead.
++			 */
++			v1 = le32_to_cpu(rxv[0]);
++
++			rxd += 12;
++			if ((u8 *)rxd - skb->data >= skb->len)
++				return -EINVAL;
++		}
++
+ 		status->chains = mphy->antenna_mask;
+ 		status->chain_signal[0] = to_rssi(MT_PRXV_RCPI0, v1);
+ 		status->chain_signal[1] = to_rssi(MT_PRXV_RCPI1, v1);
+@@ -408,17 +429,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
+ 			status->signal = max(status->signal,
+ 					     status->chain_signal[i]);
+ 		}
+-
+-		ret = mt76_connac2_mac_fill_rx_rate(&dev->mt76, status, sband,
+-						    rxv, &mode);
+-		if (ret < 0)
+-			return ret;
+-
+-		if (rxd1 & MT_RXD1_NORMAL_GROUP_5) {
+-			rxd += 18;
+-			if ((u8 *)rxd - skb->data >= skb->len)
+-				return -EINVAL;
+-		}
+ 	}
+ 
+ 	amsdu_info = FIELD_GET(MT_RXD4_NORMAL_PAYLOAD_FORMAT, rxd4);
+@@ -842,7 +852,7 @@ void mt7921_mac_update_mib_stats(struct mt7921_phy *phy)
+ 		mib->tx_amsdu_cnt += val;
+ 	}
+ 
+-	for (i = 0, aggr1 = aggr0 + 4; i < 4; i++) {
++	for (i = 0, aggr1 = aggr0 + 8; i < 4; i++) {
+ 		u32 val2;
+ 
+ 		val = mt76_rr(dev, MT_TX_AGG_CNT(0, i));
+diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
+index 6b8964c19f50d..446429f4d9442 100644
+--- a/drivers/net/wireless/mediatek/mt76/usb.c
++++ b/drivers/net/wireless/mediatek/mt76/usb.c
+@@ -761,6 +761,9 @@ static void mt76u_status_worker(struct mt76_worker *w)
+ 	struct mt76_queue *q;
+ 	int i;
+ 
++	if (!test_bit(MT76_STATE_RUNNING, &dev->phy.state))
++		return;
++
+ 	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+ 		q = dev->phy.q_tx[i];
+ 		if (!q)
+@@ -780,11 +783,11 @@ static void mt76u_status_worker(struct mt76_worker *w)
+ 			wake_up(&dev->tx_wait);
+ 
+ 		mt76_worker_schedule(&dev->tx_worker);
+-
+-		if (dev->drv->tx_status_data &&
+-		    !test_and_set_bit(MT76_READING_STATS, &dev->phy.state))
+-			queue_work(dev->wq, &dev->usb.stat_work);
+ 	}
++
++	if (dev->drv->tx_status_data &&
++	    !test_and_set_bit(MT76_READING_STATS, &dev->phy.state))
++		queue_work(dev->wq, &dev->usb.stat_work);
+ }
+ 
+ static void mt76u_tx_status_data(struct work_struct *work)
+diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.c b/drivers/net/wireless/purelifi/plfxlc/usb.c
+index 39e54b3787d6a..76d0a778636a4 100644
+--- a/drivers/net/wireless/purelifi/plfxlc/usb.c
++++ b/drivers/net/wireless/purelifi/plfxlc/usb.c
+@@ -247,6 +247,7 @@ error:
+ 		for (i = 0; i < RX_URBS_COUNT; i++)
+ 			free_rx_urb(urbs[i]);
+ 	}
++	kfree(urbs);
+ 	return r;
+ }
+ 
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+index 782b089a2e1ba..1ba66b8f70c95 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+@@ -1190,7 +1190,7 @@ struct rtl8723bu_c2h {
+ 			u8 bw;
+ 		} __packed ra_report;
+ 	};
+-};
++} __packed;
+ 
+ struct rtl8xxxu_fileops;
+ 
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+index 08f9d17dce12e..955fcf97b9dc1 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -1608,18 +1608,18 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+ {
+ 	struct device *dev = &priv->udev->dev;
+ 	struct ieee80211_hw *hw = priv->hw;
+-	u32 val32, bonding;
++	u32 val32, bonding, sys_cfg;
+ 	u16 val16;
+ 
+-	val32 = rtl8xxxu_read32(priv, REG_SYS_CFG);
+-	priv->chip_cut = (val32 & SYS_CFG_CHIP_VERSION_MASK) >>
++	sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG);
++	priv->chip_cut = (sys_cfg & SYS_CFG_CHIP_VERSION_MASK) >>
+ 		SYS_CFG_CHIP_VERSION_SHIFT;
+-	if (val32 & SYS_CFG_TRP_VAUX_EN) {
++	if (sys_cfg & SYS_CFG_TRP_VAUX_EN) {
+ 		dev_info(dev, "Unsupported test chip\n");
+ 		return -ENOTSUPP;
+ 	}
+ 
+-	if (val32 & SYS_CFG_BT_FUNC) {
++	if (sys_cfg & SYS_CFG_BT_FUNC) {
+ 		if (priv->chip_cut >= 3) {
+ 			sprintf(priv->chip_name, "8723BU");
+ 			priv->rtl_chip = RTL8723B;
+@@ -1641,7 +1641,7 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+ 		if (val32 & MULTI_GPS_FUNC_EN)
+ 			priv->has_gps = 1;
+ 		priv->is_multi_func = 1;
+-	} else if (val32 & SYS_CFG_TYPE_ID) {
++	} else if (sys_cfg & SYS_CFG_TYPE_ID) {
+ 		bonding = rtl8xxxu_read32(priv, REG_HPON_FSM);
+ 		bonding &= HPON_FSM_BONDING_MASK;
+ 		if (priv->fops->tx_desc_size ==
+@@ -1692,7 +1692,7 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+ 	case RTL8188E:
+ 	case RTL8192E:
+ 	case RTL8723B:
+-		switch (val32 & SYS_CFG_VENDOR_EXT_MASK) {
++		switch (sys_cfg & SYS_CFG_VENDOR_EXT_MASK) {
+ 		case SYS_CFG_VENDOR_ID_TSMC:
+ 			sprintf(priv->chip_vendor, "TSMC");
+ 			break;
+@@ -1709,7 +1709,7 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
+ 		}
+ 		break;
+ 	default:
+-		if (val32 & SYS_CFG_VENDOR_ID) {
++		if (sys_cfg & SYS_CFG_VENDOR_ID) {
+ 			sprintf(priv->chip_vendor, "UMC");
+ 			priv->vendor_umc = 1;
+ 		} else {
+@@ -4654,7 +4654,6 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 			if (sta->deflink.ht_cap.cap &
+ 			    (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20))
+ 				sgi = 1;
+-			rcu_read_unlock();
+ 
+ 			highest_rate = fls(ramask) - 1;
+ 			if (highest_rate < DESC_RATE_MCS0) {
+@@ -4679,6 +4678,7 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 				else
+ 					rarpt->txrate.bw = RATE_INFO_BW_20;
+ 			}
++			rcu_read_unlock();
+ 			bit_rate = cfg80211_calculate_bitrate(&rarpt->txrate);
+ 			rarpt->bit_rate = bit_rate;
+ 			rarpt->desc_rate = highest_rate;
+@@ -5575,7 +5575,6 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
+ 			rarpt->txrate.flags = 0;
+ 			rate = c2h->ra_report.rate;
+ 			sgi = c2h->ra_report.sgi;
+-			bw = c2h->ra_report.bw;
+ 
+ 			if (rate < DESC_RATE_MCS0) {
+ 				rarpt->txrate.legacy =
+@@ -5592,8 +5591,13 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
+ 						RATE_INFO_FLAGS_SHORT_GI;
+ 				}
+ 
+-				if (bw == RATE_INFO_BW_20)
+-					rarpt->txrate.bw |= RATE_INFO_BW_20;
++				if (skb->len >= offsetofend(typeof(*c2h), ra_report.bw)) {
++					if (c2h->ra_report.bw == RTL8XXXU_CHANNEL_WIDTH_40)
++						bw = RATE_INFO_BW_40;
++					else
++						bw = RATE_INFO_BW_20;
++					rarpt->txrate.bw = bw;
++				}
+ 			}
+ 			bit_rate = cfg80211_calculate_bitrate(&rarpt->txrate);
+ 			rarpt->bit_rate = bit_rate;
+diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
+index 8b338e5ce364e..732015228bd30 100644
+--- a/drivers/net/wireless/realtek/rtw89/core.c
++++ b/drivers/net/wireless/realtek/rtw89/core.c
+@@ -2500,7 +2500,7 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
+ 	}
+ 
+ 	/* update cam aid mac_id net_type */
+-	rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
++	ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
+ 	if (ret) {
+ 		rtw89_warn(rtwdev, "failed to send h2c cam\n");
+ 		return ret;
+diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
+index 93124b815825f..1afc14531194a 100644
+--- a/drivers/net/wireless/realtek/rtw89/mac.c
++++ b/drivers/net/wireless/realtek/rtw89/mac.c
+@@ -1387,10 +1387,8 @@ static int dle_mix_cfg(struct rtw89_dev *rtwdev, const struct rtw89_dle_mem *cfg
+ #define INVALID_QT_WCPU U16_MAX
+ #define SET_QUOTA_VAL(_min_x, _max_x, _module, _idx)			\
+ 	do {								\
+-		val = ((_min_x) &					\
+-		       B_AX_ ## _module ## _MIN_SIZE_MASK) |		\
+-		      (((_max_x) << 16) &				\
+-		       B_AX_ ## _module ## _MAX_SIZE_MASK);		\
++		val = u32_encode_bits(_min_x, B_AX_ ## _module ## _MIN_SIZE_MASK) | \
++		      u32_encode_bits(_max_x, B_AX_ ## _module ## _MAX_SIZE_MASK);  \
+ 		rtw89_write32(rtwdev,					\
+ 			      R_AX_ ## _module ## _QTA ## _idx ## _CFG,	\
+ 			      val);					\
+diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
+index 1532c0a6bbc44..2925179f508c9 100644
+--- a/drivers/net/wireless/realtek/rtw89/phy.c
++++ b/drivers/net/wireless/realtek/rtw89/phy.c
+@@ -3045,7 +3045,7 @@ void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev)
+ 
+ static bool rtw89_physts_ie_page_valid(enum rtw89_phy_status_bitmap *ie_page)
+ {
+-	if (*ie_page > RTW89_PHYSTS_BITMAP_NUM ||
++	if (*ie_page >= RTW89_PHYSTS_BITMAP_NUM ||
+ 	    *ie_page == RTW89_RSVD_9)
+ 		return false;
+ 	else if (*ie_page > RTW89_RSVD_9)
+diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c
+index 0f3a80f66b61c..ead4d4e043280 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_core.c
++++ b/drivers/net/wireless/rsi/rsi_91x_core.c
+@@ -466,7 +466,9 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
+ 							      tid, 0);
+ 			}
+ 		}
+-		if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
++
++		if (IEEE80211_SKB_CB(skb)->control.flags &
++		    IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
+ 			q_num = MGMT_SOFT_Q;
+ 			skb->priority = q_num;
+ 		}
+diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
+index c61f83a7333b6..c7460fbba0142 100644
+--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
++++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
+@@ -162,12 +162,16 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
+ 	u8 header_size;
+ 	u8 vap_id = 0;
+ 	u8 dword_align_bytes;
++	bool tx_eapol;
+ 	u16 seq_num;
+ 
+ 	info = IEEE80211_SKB_CB(skb);
+ 	vif = info->control.vif;
+ 	tx_params = (struct skb_info *)info->driver_data;
+ 
++	tx_eapol = IEEE80211_SKB_CB(skb)->control.flags &
++		   IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
++
+ 	header_size = FRAME_DESC_SZ + sizeof(struct rsi_xtended_desc);
+ 	if (header_size > skb_headroom(skb)) {
+ 		rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
+@@ -231,7 +235,7 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb)
+ 		}
+ 	}
+ 
+-	if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
++	if (tx_eapol) {
+ 		rsi_dbg(INFO_ZONE, "*** Tx EAPOL ***\n");
+ 
+ 		data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE);
+diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c
+index d9f6367b9993d..f0cac19005527 100644
+--- a/drivers/nfc/pn533/pn533.c
++++ b/drivers/nfc/pn533/pn533.c
+@@ -1295,6 +1295,8 @@ static int pn533_poll_dep_complete(struct pn533 *dev, void *arg,
+ 	if (IS_ERR(resp))
+ 		return PTR_ERR(resp);
+ 
++	memset(&nfc_target, 0, sizeof(struct nfc_target));
++
+ 	rsp = (struct pn533_cmd_jump_dep_response *)resp->data;
+ 
+ 	rc = rsp->status & PN533_CMD_RET_MASK;
+@@ -1926,6 +1928,8 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg,
+ 
+ 		dev_dbg(dev->dev, "Creating new target\n");
+ 
++		memset(&nfc_target, 0, sizeof(struct nfc_target));
++
+ 		nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK;
+ 		nfc_target.nfcid1_len = 10;
+ 		memcpy(nfc_target.nfcid1, rsp->nfcid3t, nfc_target.nfcid1_len);
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index aca50bb937506..3582a28a1dcec 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -3043,7 +3043,7 @@ static int nvme_init_non_mdts_limits(struct nvme_ctrl *ctrl)
+ 
+ 	id = kzalloc(sizeof(*id), GFP_KERNEL);
+ 	if (!id)
+-		return 0;
++		return -ENOMEM;
+ 
+ 	c.identify.opcode = nvme_admin_identify;
+ 	c.identify.cns = NVME_ID_CNS_CS_CTRL;
+@@ -3739,13 +3739,17 @@ static ssize_t nvme_ctrl_dhchap_secret_store(struct device *dev,
+ 	memcpy(dhchap_secret, buf, count);
+ 	nvme_auth_stop(ctrl);
+ 	if (strcmp(dhchap_secret, opts->dhchap_secret)) {
++		struct nvme_dhchap_key *key, *host_key;
+ 		int ret;
+ 
+-		ret = nvme_auth_generate_key(dhchap_secret, &ctrl->host_key);
++		ret = nvme_auth_generate_key(dhchap_secret, &key);
+ 		if (ret)
+ 			return ret;
+ 		kfree(opts->dhchap_secret);
+ 		opts->dhchap_secret = dhchap_secret;
++		host_key = ctrl->host_key;
++		ctrl->host_key = key;
++		nvme_auth_free_key(host_key);
+ 		/* Key has changed; re-authentication with new key */
+ 		nvme_auth_reset(ctrl);
+ 	}
+@@ -3789,13 +3793,17 @@ static ssize_t nvme_ctrl_dhchap_ctrl_secret_store(struct device *dev,
+ 	memcpy(dhchap_secret, buf, count);
+ 	nvme_auth_stop(ctrl);
+ 	if (strcmp(dhchap_secret, opts->dhchap_ctrl_secret)) {
++		struct nvme_dhchap_key *key, *ctrl_key;
+ 		int ret;
+ 
+-		ret = nvme_auth_generate_key(dhchap_secret, &ctrl->ctrl_key);
++		ret = nvme_auth_generate_key(dhchap_secret, &key);
+ 		if (ret)
+ 			return ret;
+ 		kfree(opts->dhchap_ctrl_secret);
+ 		opts->dhchap_ctrl_secret = dhchap_secret;
++		ctrl_key = ctrl->ctrl_key;
++		ctrl->ctrl_key = key;
++		nvme_auth_free_key(ctrl_key);
+ 		/* Key has changed; re-authentication with new key */
+ 		nvme_auth_reset(ctrl);
+ 	}
+diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
+index aecb5853f8da4..683b75a992b3d 100644
+--- a/drivers/nvme/target/core.c
++++ b/drivers/nvme/target/core.c
+@@ -15,6 +15,7 @@
+ 
+ #include "nvmet.h"
+ 
++struct kmem_cache *nvmet_bvec_cache;
+ struct workqueue_struct *buffered_io_wq;
+ struct workqueue_struct *zbd_wq;
+ static const struct nvmet_fabrics_ops *nvmet_transports[NVMF_TRTYPE_MAX];
+@@ -1631,26 +1632,28 @@ void nvmet_subsys_put(struct nvmet_subsys *subsys)
+ 
+ static int __init nvmet_init(void)
+ {
+-	int error;
++	int error = -ENOMEM;
+ 
+ 	nvmet_ana_group_enabled[NVMET_DEFAULT_ANA_GRPID] = 1;
+ 
++	nvmet_bvec_cache = kmem_cache_create("nvmet-bvec",
++			NVMET_MAX_MPOOL_BVEC * sizeof(struct bio_vec), 0,
++			SLAB_HWCACHE_ALIGN, NULL);
++	if (!nvmet_bvec_cache)
++		return -ENOMEM;
++
+ 	zbd_wq = alloc_workqueue("nvmet-zbd-wq", WQ_MEM_RECLAIM, 0);
+ 	if (!zbd_wq)
+-		return -ENOMEM;
++		goto out_destroy_bvec_cache;
+ 
+ 	buffered_io_wq = alloc_workqueue("nvmet-buffered-io-wq",
+ 			WQ_MEM_RECLAIM, 0);
+-	if (!buffered_io_wq) {
+-		error = -ENOMEM;
++	if (!buffered_io_wq)
+ 		goto out_free_zbd_work_queue;
+-	}
+ 
+ 	nvmet_wq = alloc_workqueue("nvmet-wq", WQ_MEM_RECLAIM, 0);
+-	if (!nvmet_wq) {
+-		error = -ENOMEM;
++	if (!nvmet_wq)
+ 		goto out_free_buffered_work_queue;
+-	}
+ 
+ 	error = nvmet_init_discovery();
+ 	if (error)
+@@ -1669,6 +1672,8 @@ out_free_buffered_work_queue:
+ 	destroy_workqueue(buffered_io_wq);
+ out_free_zbd_work_queue:
+ 	destroy_workqueue(zbd_wq);
++out_destroy_bvec_cache:
++	kmem_cache_destroy(nvmet_bvec_cache);
+ 	return error;
+ }
+ 
+@@ -1680,6 +1685,7 @@ static void __exit nvmet_exit(void)
+ 	destroy_workqueue(nvmet_wq);
+ 	destroy_workqueue(buffered_io_wq);
+ 	destroy_workqueue(zbd_wq);
++	kmem_cache_destroy(nvmet_bvec_cache);
+ 
+ 	BUILD_BUG_ON(sizeof(struct nvmf_disc_rsp_page_entry) != 1024);
+ 	BUILD_BUG_ON(sizeof(struct nvmf_disc_rsp_page_hdr) != 1024);
+diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c
+index 64b47e2a46330..e55ec6fefd7f4 100644
+--- a/drivers/nvme/target/io-cmd-file.c
++++ b/drivers/nvme/target/io-cmd-file.c
+@@ -11,7 +11,6 @@
+ #include <linux/fs.h>
+ #include "nvmet.h"
+ 
+-#define NVMET_MAX_MPOOL_BVEC		16
+ #define NVMET_MIN_MPOOL_OBJ		16
+ 
+ void nvmet_file_ns_revalidate(struct nvmet_ns *ns)
+@@ -26,8 +25,6 @@ void nvmet_file_ns_disable(struct nvmet_ns *ns)
+ 			flush_workqueue(buffered_io_wq);
+ 		mempool_destroy(ns->bvec_pool);
+ 		ns->bvec_pool = NULL;
+-		kmem_cache_destroy(ns->bvec_cache);
+-		ns->bvec_cache = NULL;
+ 		fput(ns->file);
+ 		ns->file = NULL;
+ 	}
+@@ -59,16 +56,8 @@ int nvmet_file_ns_enable(struct nvmet_ns *ns)
+ 	ns->blksize_shift = min_t(u8,
+ 			file_inode(ns->file)->i_blkbits, 12);
+ 
+-	ns->bvec_cache = kmem_cache_create("nvmet-bvec",
+-			NVMET_MAX_MPOOL_BVEC * sizeof(struct bio_vec),
+-			0, SLAB_HWCACHE_ALIGN, NULL);
+-	if (!ns->bvec_cache) {
+-		ret = -ENOMEM;
+-		goto err;
+-	}
+-
+ 	ns->bvec_pool = mempool_create(NVMET_MIN_MPOOL_OBJ, mempool_alloc_slab,
+-			mempool_free_slab, ns->bvec_cache);
++			mempool_free_slab, nvmet_bvec_cache);
+ 
+ 	if (!ns->bvec_pool) {
+ 		ret = -ENOMEM;
+@@ -77,9 +66,10 @@ int nvmet_file_ns_enable(struct nvmet_ns *ns)
+ 
+ 	return ret;
+ err:
++	fput(ns->file);
++	ns->file = NULL;
+ 	ns->size = 0;
+ 	ns->blksize_shift = 0;
+-	nvmet_file_ns_disable(ns);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
+index dfe3894205aa7..bda1c1f71f394 100644
+--- a/drivers/nvme/target/nvmet.h
++++ b/drivers/nvme/target/nvmet.h
+@@ -77,7 +77,6 @@ struct nvmet_ns {
+ 
+ 	struct completion	disable_done;
+ 	mempool_t		*bvec_pool;
+-	struct kmem_cache	*bvec_cache;
+ 
+ 	int			use_p2pmem;
+ 	struct pci_dev		*p2p_dev;
+@@ -393,6 +392,8 @@ struct nvmet_req {
+ 	u64			error_slba;
+ };
+ 
++#define NVMET_MAX_MPOOL_BVEC		16
++extern struct kmem_cache *nvmet_bvec_cache;
+ extern struct workqueue_struct *buffered_io_wq;
+ extern struct workqueue_struct *zbd_wq;
+ extern struct workqueue_struct *nvmet_wq;
+diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
+index bd8ff4df723da..ed4e6c144a681 100644
+--- a/drivers/of/overlay.c
++++ b/drivers/of/overlay.c
+@@ -545,7 +545,7 @@ static int find_dup_cset_node_entry(struct overlay_changeset *ovcs,
+ 
+ 		fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np);
+ 		fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np);
+-		node_path_match = !strcmp(fn_1, fn_2);
++		node_path_match = !fn_1 || !fn_2 || !strcmp(fn_1, fn_2);
+ 		kfree(fn_1);
+ 		kfree(fn_2);
+ 		if (node_path_match) {
+@@ -580,7 +580,7 @@ static int find_dup_cset_prop(struct overlay_changeset *ovcs,
+ 
+ 		fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np);
+ 		fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np);
+-		node_path_match = !strcmp(fn_1, fn_2);
++		node_path_match = !fn_1 || !fn_2 || !strcmp(fn_1, fn_2);
+ 		kfree(fn_1);
+ 		kfree(fn_2);
+ 		if (node_path_match &&
+diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
+index 6e5debdbc55b9..6ffe95d68ae72 100644
+--- a/drivers/pci/controller/dwc/pci-imx6.c
++++ b/drivers/pci/controller/dwc/pci-imx6.c
+@@ -942,12 +942,6 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
+ 		}
+ 	}
+ 
+-	ret = imx6_pcie_deassert_core_reset(imx6_pcie);
+-	if (ret < 0) {
+-		dev_err(dev, "pcie deassert core reset failed: %d\n", ret);
+-		goto err_phy_off;
+-	}
+-
+ 	if (imx6_pcie->phy) {
+ 		ret = phy_init(imx6_pcie->phy);
+ 		if (ret) {
+@@ -955,6 +949,13 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
+ 			goto err_phy_off;
+ 		}
+ 	}
++
++	ret = imx6_pcie_deassert_core_reset(imx6_pcie);
++	if (ret < 0) {
++		dev_err(dev, "pcie deassert core reset failed: %d\n", ret);
++		goto err_phy_off;
++	}
++
+ 	imx6_setup_phy_mpll(imx6_pcie);
+ 
+ 	return 0;
+diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
+index c6725c519a479..9e4d96e5a3f5a 100644
+--- a/drivers/pci/controller/dwc/pcie-designware.c
++++ b/drivers/pci/controller/dwc/pcie-designware.c
+@@ -641,7 +641,7 @@ void dw_pcie_setup(struct dw_pcie *pci)
+ 	if (pci->n_fts[1]) {
+ 		val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
+ 		val &= ~PORT_LOGIC_N_FTS_MASK;
+-		val |= pci->n_fts[pci->link_gen - 1];
++		val |= pci->n_fts[1];
+ 		dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
+ 	}
+ 
+diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
+index e06e9f4fc50f7..769eedeb8802a 100644
+--- a/drivers/pci/controller/vmd.c
++++ b/drivers/pci/controller/vmd.c
+@@ -719,6 +719,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
+ 	resource_size_t offset[2] = {0};
+ 	resource_size_t membar2_offset = 0x2000;
+ 	struct pci_bus *child;
++	struct pci_dev *dev;
+ 	int ret;
+ 
+ 	/*
+@@ -859,8 +860,25 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
+ 
+ 	pci_scan_child_bus(vmd->bus);
+ 	vmd_domain_reset(vmd);
+-	list_for_each_entry(child, &vmd->bus->children, node)
+-		pci_reset_bus(child->self);
++
++	/* When Intel VMD is enabled, the OS does not discover the Root Ports
++	 * owned by Intel VMD within the MMCFG space. pci_reset_bus() applies
++	 * a reset to the parent of the PCI device supplied as argument. This
++	 * is why we pass a child device, so the reset can be triggered at
++	 * the Intel bridge level and propagated to all the children in the
++	 * hierarchy.
++	 */
++	list_for_each_entry(child, &vmd->bus->children, node) {
++		if (!list_empty(&child->devices)) {
++			dev = list_first_entry(&child->devices,
++					       struct pci_dev, bus_list);
++			if (pci_reset_bus(dev))
++				pci_warn(dev, "can't reset device: %d\n", ret);
++
++			break;
++		}
++	}
++
+ 	pci_assign_unassigned_bus_resources(vmd->bus);
+ 
+ 	/*
+@@ -980,6 +998,11 @@ static int vmd_resume(struct device *dev)
+ 	struct vmd_dev *vmd = pci_get_drvdata(pdev);
+ 	int err, i;
+ 
++       if (vmd->irq_domain)
++               vmd_set_msi_remapping(vmd, true);
++       else
++               vmd_set_msi_remapping(vmd, false);
++
+ 	for (i = 0; i < vmd->msix_count; i++) {
+ 		err = devm_request_irq(dev, vmd->irqs[i].virq,
+ 				       vmd_irq, IRQF_NO_THREAD,
+diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
+index 36b1801a061b7..55283d2379a6a 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-test.c
++++ b/drivers/pci/endpoint/functions/pci-epf-test.c
+@@ -979,7 +979,7 @@ static int pci_epf_test_bind(struct pci_epf *epf)
+ 	if (ret)
+ 		epf_test->dma_supported = false;
+ 
+-	if (linkup_notifier) {
++	if (linkup_notifier || core_init_notifier) {
+ 		epf->nb.notifier_call = pci_epf_test_notifier;
+ 		pci_epc_register_notifier(epc, &epf->nb);
+ 	} else {
+diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+index 0ea85e1d292ec..fba0179939b8f 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
++++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
+@@ -557,7 +557,7 @@ static int epf_ntb_db_bar_init(struct epf_ntb *ntb)
+ 	return ret;
+ 
+ err_alloc_peer_mem:
+-	pci_epc_mem_free_addr(ntb->epf->epc, epf_bar->phys_addr, mw_addr, epf_bar->size);
++	pci_epf_free_space(ntb->epf, mw_addr, barno, 0);
+ 	return -1;
+ }
+ 
+diff --git a/drivers/pci/irq.c b/drivers/pci/irq.c
+index 12ecd0aaa28d6..0050e8f6814ed 100644
+--- a/drivers/pci/irq.c
++++ b/drivers/pci/irq.c
+@@ -44,6 +44,8 @@ int pci_request_irq(struct pci_dev *dev, unsigned int nr, irq_handler_t handler,
+ 	va_start(ap, fmt);
+ 	devname = kvasprintf(GFP_KERNEL, fmt, ap);
+ 	va_end(ap);
++	if (!devname)
++		return -ENOMEM;
+ 
+ 	ret = request_threaded_irq(pci_irq_vector(dev, nr), handler, thread_fn,
+ 				   irqflags, devname, dev_id);
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index c5286b027f00d..bdcad5e0f057f 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -1890,9 +1890,6 @@ int pci_setup_device(struct pci_dev *dev)
+ 
+ 	dev->broken_intx_masking = pci_intx_mask_broken(dev);
+ 
+-	/* Clear errors left from system firmware */
+-	pci_write_config_word(dev, PCI_STATUS, 0xffff);
+-
+ 	switch (dev->hdr_type) {		    /* header type */
+ 	case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
+ 		if (class == PCI_CLASS_BRIDGE_PCI)
+diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c
+index 280a6ae3e27cf..54aa4658fb36e 100644
+--- a/drivers/perf/arm_dmc620_pmu.c
++++ b/drivers/perf/arm_dmc620_pmu.c
+@@ -725,6 +725,8 @@ static struct platform_driver dmc620_pmu_driver = {
+ 
+ static int __init dmc620_pmu_init(void)
+ {
++	int ret;
++
+ 	cpuhp_state_num = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
+ 				      DMC620_DRVNAME,
+ 				      NULL,
+@@ -732,7 +734,11 @@ static int __init dmc620_pmu_init(void)
+ 	if (cpuhp_state_num < 0)
+ 		return cpuhp_state_num;
+ 
+-	return platform_driver_register(&dmc620_pmu_driver);
++	ret = platform_driver_register(&dmc620_pmu_driver);
++	if (ret)
++		cpuhp_remove_multi_state(cpuhp_state_num);
++
++	return ret;
+ }
+ 
+ static void __exit dmc620_pmu_exit(void)
+diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
+index a36698a90d2f2..54b8ba032c787 100644
+--- a/drivers/perf/arm_dsu_pmu.c
++++ b/drivers/perf/arm_dsu_pmu.c
+@@ -858,7 +858,11 @@ static int __init dsu_pmu_init(void)
+ 	if (ret < 0)
+ 		return ret;
+ 	dsu_pmu_cpuhp_state = ret;
+-	return platform_driver_register(&dsu_pmu_driver);
++	ret = platform_driver_register(&dsu_pmu_driver);
++	if (ret)
++		cpuhp_remove_multi_state(dsu_pmu_cpuhp_state);
++
++	return ret;
+ }
+ 
+ static void __exit dsu_pmu_exit(void)
+diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
+index 00d4c45a8017d..25a269d431e45 100644
+--- a/drivers/perf/arm_smmuv3_pmu.c
++++ b/drivers/perf/arm_smmuv3_pmu.c
+@@ -959,6 +959,8 @@ static struct platform_driver smmu_pmu_driver = {
+ 
+ static int __init arm_smmu_pmu_init(void)
+ {
++	int ret;
++
+ 	cpuhp_state_num = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
+ 						  "perf/arm/pmcg:online",
+ 						  NULL,
+@@ -966,7 +968,11 @@ static int __init arm_smmu_pmu_init(void)
+ 	if (cpuhp_state_num < 0)
+ 		return cpuhp_state_num;
+ 
+-	return platform_driver_register(&smmu_pmu_driver);
++	ret = platform_driver_register(&smmu_pmu_driver);
++	if (ret)
++		cpuhp_remove_multi_state(cpuhp_state_num);
++
++	return ret;
+ }
+ module_init(arm_smmu_pmu_init);
+ 
+diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
+index 21771708597db..071e63d9a9ac6 100644
+--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
++++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
+@@ -693,10 +693,10 @@ static struct attribute *hisi_pcie_pmu_events_attr[] = {
+ 	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_cnt, 0x10210),
+ 	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_latency, 0x0011),
+ 	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_cnt, 0x10011),
+-	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x1005),
+-	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x11005),
+-	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x2004),
+-	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x12004),
++	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x0804),
++	HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x10804),
++	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x0405),
++	HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x10405),
+ 	NULL
+ };
+ 
+diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
+index 69c3050a4348b..a1166afb37024 100644
+--- a/drivers/perf/marvell_cn10k_tad_pmu.c
++++ b/drivers/perf/marvell_cn10k_tad_pmu.c
+@@ -408,7 +408,11 @@ static int __init tad_pmu_init(void)
+ 	if (ret < 0)
+ 		return ret;
+ 	tad_pmu_cpuhp_state = ret;
+-	return platform_driver_register(&tad_pmu_driver);
++	ret = platform_driver_register(&tad_pmu_driver);
++	if (ret)
++		cpuhp_remove_multi_state(tad_pmu_cpuhp_state);
++
++	return ret;
+ }
+ 
+ static void __exit tad_pmu_exit(void)
+diff --git a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
+index d2524b70ea161..3b374b37b965b 100644
+--- a/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
++++ b/drivers/phy/broadcom/phy-brcm-usb-init-synopsys.c
+@@ -331,13 +331,12 @@ static void usb_uninit_common_7216(struct brcm_usb_init_params *params)
+ 
+ 	pr_debug("%s\n", __func__);
+ 
+-	if (!params->wake_enabled) {
+-		USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
+-
++	if (params->wake_enabled) {
+ 		/* Switch to using slower clock during suspend to save power */
+ 		USB_CTRL_SET(ctrl, USB_PM, XHC_S2_CLK_SWITCH_EN);
+-	} else {
+ 		usb_wake_enable_7216(params, true);
++	} else {
++		USB_CTRL_SET(ctrl, USB_PM, USB_PWRDN);
+ 	}
+ }
+ 
+@@ -425,7 +424,6 @@ void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params)
+ 
+ 	params->family_name = "7216";
+ 	params->ops = &bcm7216_ops;
+-	params->suspend_with_clocks = true;
+ }
+ 
+ void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params)
+@@ -435,5 +433,4 @@ void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params)
+ 
+ 	params->family_name = "7211";
+ 	params->ops = &bcm7211b0_ops;
+-	params->suspend_with_clocks = true;
+ }
+diff --git a/drivers/phy/broadcom/phy-brcm-usb-init.h b/drivers/phy/broadcom/phy-brcm-usb-init.h
+index 1ccb5ddab865c..3236e94988428 100644
+--- a/drivers/phy/broadcom/phy-brcm-usb-init.h
++++ b/drivers/phy/broadcom/phy-brcm-usb-init.h
+@@ -61,7 +61,6 @@ struct  brcm_usb_init_params {
+ 	const struct brcm_usb_init_ops *ops;
+ 	struct regmap *syscon_piarbctl;
+ 	bool wake_enabled;
+-	bool suspend_with_clocks;
+ };
+ 
+ void brcm_usb_dvr_init_4908(struct brcm_usb_init_params *params);
+diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c
+index 2cb3779fcdf82..2bfd78e2d8fd6 100644
+--- a/drivers/phy/broadcom/phy-brcm-usb.c
++++ b/drivers/phy/broadcom/phy-brcm-usb.c
+@@ -102,9 +102,9 @@ static int brcm_pm_notifier(struct notifier_block *notifier,
+ 
+ static irqreturn_t brcm_usb_phy_wake_isr(int irq, void *dev_id)
+ {
+-	struct phy *gphy = dev_id;
++	struct device *dev = dev_id;
+ 
+-	pm_wakeup_event(&gphy->dev, 0);
++	pm_wakeup_event(dev, 0);
+ 
+ 	return IRQ_HANDLED;
+ }
+@@ -451,7 +451,7 @@ static int brcm_usb_phy_dvr_init(struct platform_device *pdev,
+ 	if (priv->wake_irq >= 0) {
+ 		err = devm_request_irq(dev, priv->wake_irq,
+ 				       brcm_usb_phy_wake_isr, 0,
+-				       dev_name(dev), gphy);
++				       dev_name(dev), dev);
+ 		if (err < 0)
+ 			return err;
+ 		device_set_wakeup_capable(dev, 1);
+@@ -598,7 +598,7 @@ static int brcm_usb_phy_suspend(struct device *dev)
+ 		 * and newer XHCI->2.0-clks/3.0-clks.
+ 		 */
+ 
+-		if (!priv->ini.suspend_with_clocks) {
++		if (!priv->ini.wake_enabled) {
+ 			if (priv->phys[BRCM_USB_PHY_3_0].inited)
+ 				clk_disable_unprepare(priv->usb_30_clk);
+ 			if (priv->phys[BRCM_USB_PHY_2_0].inited ||
+@@ -615,8 +615,10 @@ static int brcm_usb_phy_resume(struct device *dev)
+ {
+ 	struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
+ 
+-	clk_prepare_enable(priv->usb_20_clk);
+-	clk_prepare_enable(priv->usb_30_clk);
++	if (!priv->ini.wake_enabled) {
++		clk_prepare_enable(priv->usb_20_clk);
++		clk_prepare_enable(priv->usb_30_clk);
++	}
+ 	brcm_usb_init_ipp(&priv->ini);
+ 
+ 	/*
+diff --git a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
+index 67712c77d806f..d641b345afa35 100644
+--- a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
++++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c
+@@ -826,6 +826,9 @@ mvebu_a3700_comphy_usb3_power_on(struct mvebu_a3700_comphy_lane *lane)
+ 	if (ret)
+ 		return ret;
+ 
++	/* COMPHY register reset (cleared automatically) */
++	comphy_lane_reg_set(lane, COMPHY_SFT_RESET, SFT_RST, SFT_RST);
++
+ 	/*
+ 	 * 0. Set PHY OTG Control(0x5d034), bit 4, Power up OTG module The
+ 	 * register belong to UTMI module, so it is set in UTMI phy driver.
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+index 2d65e1f56bfc3..51dc4f2de1063 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+@@ -1329,10 +1329,10 @@ static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_rx_tbl[] = {
+ };
+ 
+ static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_tbl[] = {
+-	QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG2, 0x16),
+-	QMP_PHY_INIT_CFG(QPHY_V5_PCS_EQ_CONFIG3, 0x22),
+-	QMP_PHY_INIT_CFG(QPHY_V5_PCS_G3S2_PRE_GAIN, 0x2e),
+-	QMP_PHY_INIT_CFG(QPHY_V5_PCS_RX_SIGDET_LVL, 0x99),
++	QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_EQ_CONFIG4, 0x16),
++	QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_EQ_CONFIG5, 0x22),
++	QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_G3S2_PRE_GAIN, 0x2e),
++	QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_RX_SIGDET_LVL, 0x99),
+ };
+ 
+ static const struct qmp_phy_init_tbl sm8450_qmp_gen4x2_pcie_pcs_misc_tbl[] = {
+@@ -1564,6 +1564,7 @@ static const struct qmp_phy_cfg ipq8074_pciephy_gen3_cfg = {
+ 
+ 	.start_ctrl		= SERDES_START | PCS_START,
+ 	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
++	.phy_status		= PHYSTATUS,
+ 
+ 	.has_pwrdn_delay	= true,
+ 	.pwrdn_delay_min	= 995,		/* us */
+@@ -2077,12 +2078,6 @@ static int qcom_qmp_phy_pcie_power_on(struct phy *phy)
+ 		qcom_qmp_phy_pcie_configure(pcs_misc, cfg->regs, cfg->pcs_misc_tbl_sec,
+ 				       cfg->pcs_misc_tbl_num_sec);
+ 
+-	/*
+-	 * Pull out PHY from POWER DOWN state.
+-	 * This is active low enable signal to power-down PHY.
+-	 */
+-	qphy_setbits(pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL, cfg->pwrdn_ctrl);
+-
+ 	if (cfg->has_pwrdn_delay)
+ 		usleep_range(cfg->pwrdn_delay_min, cfg->pwrdn_delay_max);
+ 
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5_20.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5_20.h
+new file mode 100644
+index 0000000000000..9a5a20daf62cd
+--- /dev/null
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5_20.h
+@@ -0,0 +1,14 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (c) 2022, Linaro Ltd.
++ */
++
++#ifndef QCOM_PHY_QMP_PCS_V5_20_H_
++#define QCOM_PHY_QMP_PCS_V5_20_H_
++
++#define QPHY_V5_20_PCS_G3S2_PRE_GAIN			0x170
++#define QPHY_V5_20_PCS_RX_SIGDET_LVL			0x188
++#define QPHY_V5_20_PCS_EQ_CONFIG4			0x1e0
++#define QPHY_V5_20_PCS_EQ_CONFIG5			0x1e4
++
++#endif
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h
+index b139c8af5e8b1..1a0c6c3026e37 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp.h
++++ b/drivers/phy/qualcomm/phy-qcom-qmp.h
+@@ -37,6 +37,7 @@
+ #include "phy-qcom-qmp-pcs-pcie-v4_20.h"
+ 
+ #include "phy-qcom-qmp-pcs-v5.h"
++#include "phy-qcom-qmp-pcs-v5_20.h"
+ #include "phy-qcom-qmp-pcs-pcie-v5.h"
+ #include "phy-qcom-qmp-pcs-usb-v5.h"
+ #include "phy-qcom-qmp-pcs-ufs-v5.h"
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
+index f26869f1a367b..5cb255455a548 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mt7986.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c
+@@ -316,10 +316,10 @@ static const struct mtk_pin_field_calc mt7986_pin_pupd_range[] = {
+ 	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x30, 0x10, 9, 1),
+ 	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x60, 0x10, 18, 1),
+ 	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x60, 0x10, 12, 1),
+-	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x60, 0x10, 22, 1),
+-	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x60, 0x10, 20, 1),
+-	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x60, 0x10, 26, 1),
+-	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x60, 0x10, 24, 1),
++	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x60, 0x10, 23, 1),
++	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x60, 0x10, 21, 1),
++	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x60, 0x10, 27, 1),
++	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x60, 0x10, 25, 1),
+ 	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x40, 0x10, 2, 1),
+ 	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x40, 0x10, 1, 1),
+ 	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x40, 0x10, 0, 1),
+@@ -354,10 +354,10 @@ static const struct mtk_pin_field_calc mt7986_pin_r0_range[] = {
+ 	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x40, 0x10, 9, 1),
+ 	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x70, 0x10, 18, 1),
+ 	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x70, 0x10, 12, 1),
+-	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x70, 0x10, 22, 1),
+-	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x70, 0x10, 20, 1),
+-	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x70, 0x10, 26, 1),
+-	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x70, 0x10, 24, 1),
++	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x70, 0x10, 23, 1),
++	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x70, 0x10, 21, 1),
++	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x70, 0x10, 27, 1),
++	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x70, 0x10, 25, 1),
+ 	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x50, 0x10, 2, 1),
+ 	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x50, 0x10, 1, 1),
+ 	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x50, 0x10, 0, 1),
+@@ -392,10 +392,10 @@ static const struct mtk_pin_field_calc mt7986_pin_r1_range[] = {
+ 	PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x50, 0x10, 9, 1),
+ 	PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x80, 0x10, 18, 1),
+ 	PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x80, 0x10, 12, 1),
+-	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x80, 0x10, 22, 1),
+-	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x80, 0x10, 20, 1),
+-	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x80, 0x10, 26, 1),
+-	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x80, 0x10, 24, 1),
++	PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x80, 0x10, 23, 1),
++	PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x80, 0x10, 21, 1),
++	PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x80, 0x10, 27, 1),
++	PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x80, 0x10, 25, 1),
+ 	PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x60, 0x10, 2, 1),
+ 	PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x60, 0x10, 1, 1),
+ 	PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x60, 0x10, 0, 1),
+diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
+index 415d1df8f46a5..365c4b0ca4654 100644
+--- a/drivers/pinctrl/pinconf-generic.c
++++ b/drivers/pinctrl/pinconf-generic.c
+@@ -395,8 +395,10 @@ int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev,
+ 	for_each_available_child_of_node(np_config, np) {
+ 		ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map,
+ 					&reserved_maps, num_maps, type);
+-		if (ret < 0)
++		if (ret < 0) {
++			of_node_put(np);
+ 			goto exit;
++		}
+ 	}
+ 	return 0;
+ 
+diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c
+index ecab6bf63dc6d..ad4db99094a79 100644
+--- a/drivers/pinctrl/pinctrl-k210.c
++++ b/drivers/pinctrl/pinctrl-k210.c
+@@ -862,8 +862,10 @@ static int k210_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+ 	for_each_available_child_of_node(np_config, np) {
+ 		ret = k210_pinctrl_dt_subnode_to_map(pctldev, np, map,
+ 						     &reserved_maps, num_maps);
+-		if (ret < 0)
++		if (ret < 0) {
++			of_node_put(np);
+ 			goto err;
++		}
+ 	}
+ 	return 0;
+ 
+diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
+index 105771ff82e62..19a61f697e99c 100644
+--- a/drivers/pinctrl/pinctrl-ocelot.c
++++ b/drivers/pinctrl/pinctrl-ocelot.c
+@@ -2046,6 +2046,11 @@ static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev,
+ 	return devm_regmap_init_mmio(&pdev->dev, base, &regmap_config);
+ }
+ 
++static void ocelot_destroy_workqueue(void *data)
++{
++	destroy_workqueue(data);
++}
++
+ static int ocelot_pinctrl_probe(struct platform_device *pdev)
+ {
+ 	const struct ocelot_match_data *data;
+@@ -2078,6 +2083,11 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
+ 	if (!info->wq)
+ 		return -ENOMEM;
+ 
++	ret = devm_add_action_or_reset(dev, ocelot_destroy_workqueue,
++				       info->wq);
++	if (ret)
++		return ret;
++
+ 	info->pincfg_data = &data->pincfg_data;
+ 
+ 	reset = devm_reset_control_get_optional_shared(dev, "switch");
+@@ -2125,15 +2135,6 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
+-static int ocelot_pinctrl_remove(struct platform_device *pdev)
+-{
+-	struct ocelot_pinctrl *info = platform_get_drvdata(pdev);
+-
+-	destroy_workqueue(info->wq);
+-
+-	return 0;
+-}
+-
+ static struct platform_driver ocelot_pinctrl_driver = {
+ 	.driver = {
+ 		.name = "pinctrl-ocelot",
+@@ -2141,7 +2142,6 @@ static struct platform_driver ocelot_pinctrl_driver = {
+ 		.suppress_bind_attrs = true,
+ 	},
+ 	.probe = ocelot_pinctrl_probe,
+-	.remove = ocelot_pinctrl_remove,
+ };
+ module_platform_driver(ocelot_pinctrl_driver);
+ MODULE_LICENSE("Dual MIT/GPL");
+diff --git a/drivers/pinctrl/pinctrl-thunderbay.c b/drivers/pinctrl/pinctrl-thunderbay.c
+index 9328b17485cf0..590bbbf619afc 100644
+--- a/drivers/pinctrl/pinctrl-thunderbay.c
++++ b/drivers/pinctrl/pinctrl-thunderbay.c
+@@ -808,7 +808,7 @@ static int thunderbay_add_functions(struct thunderbay_pinctrl *tpc, struct funct
+ 					    funcs[i].num_group_names,
+ 					    funcs[i].data);
+ 	}
+-	kfree(funcs);
++
+ 	return 0;
+ }
+ 
+@@ -817,6 +817,7 @@ static int thunderbay_build_functions(struct thunderbay_pinctrl *tpc)
+ 	struct function_desc *thunderbay_funcs;
+ 	void *ptr;
+ 	int pin;
++	int ret;
+ 
+ 	/*
+ 	 * Allocate maximum possible number of functions. Assume every pin
+@@ -860,7 +861,10 @@ static int thunderbay_build_functions(struct thunderbay_pinctrl *tpc)
+ 		return -ENOMEM;
+ 
+ 	thunderbay_funcs = ptr;
+-	return thunderbay_add_functions(tpc, thunderbay_funcs);
++	ret = thunderbay_add_functions(tpc, thunderbay_funcs);
++
++	kfree(thunderbay_funcs);
++	return ret;
+ }
+ 
+ static int thunderbay_pinconf_set_tristate(struct thunderbay_pinctrl *tpc,
+diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
+index dc5722db20661..a54bf964521fb 100644
+--- a/drivers/platform/chrome/cros_ec_typec.c
++++ b/drivers/platform/chrome/cros_ec_typec.c
+@@ -20,6 +20,7 @@
+ #include <linux/usb/typec_altmode.h>
+ #include <linux/usb/typec_dp.h>
+ #include <linux/usb/typec_mux.h>
++#include <linux/usb/typec_retimer.h>
+ #include <linux/usb/typec_tbt.h>
+ #include <linux/usb/role.h>
+ 
+@@ -56,6 +57,7 @@ struct cros_typec_port {
+ 	struct usb_pd_identity c_identity;
+ 	struct typec_switch *ori_sw;
+ 	struct typec_mux *mux;
++	struct typec_retimer *retimer;
+ 	struct usb_role_switch *role_sw;
+ 
+ 	/* Variables keeping track of switch state. */
+@@ -144,6 +146,12 @@ static int cros_typec_get_switch_handles(struct cros_typec_port *port,
+ 		goto mux_err;
+ 	}
+ 
++	port->retimer = fwnode_typec_retimer_get(fwnode);
++	if (IS_ERR(port->retimer)) {
++		dev_dbg(dev, "Retimer handle not found.\n");
++		goto retimer_sw_err;
++	}
++
+ 	port->ori_sw = fwnode_typec_switch_get(fwnode);
+ 	if (IS_ERR(port->ori_sw)) {
+ 		dev_dbg(dev, "Orientation switch handle not found.\n");
+@@ -159,12 +167,15 @@ static int cros_typec_get_switch_handles(struct cros_typec_port *port,
+ 	return 0;
+ 
+ role_sw_err:
+-	usb_role_switch_put(port->role_sw);
+-ori_sw_err:
+ 	typec_switch_put(port->ori_sw);
+-mux_err:
++	port->ori_sw = NULL;
++ori_sw_err:
++	typec_retimer_put(port->retimer);
++	port->retimer = NULL;
++retimer_sw_err:
+ 	typec_mux_put(port->mux);
+-
++	port->mux = NULL;
++mux_err:
+ 	return -ENODEV;
+ }
+ 
+@@ -207,6 +218,21 @@ static void cros_typec_unregister_altmodes(struct cros_typec_data *typec, int po
+ 	}
+ }
+ 
++/*
++ * Map the Type-C Mux state to retimer state and call the retimer set function. We need this
++ * because we re-use the Type-C mux state for retimers.
++ */
++static int cros_typec_retimer_set(struct typec_retimer *retimer, struct typec_mux_state state)
++{
++	struct typec_retimer_state rstate = {
++		.alt = state.alt,
++		.mode = state.mode,
++		.data = state.data,
++	};
++
++	return typec_retimer_set(retimer, &rstate);
++}
++
+ static int cros_typec_usb_disconnect_state(struct cros_typec_port *port)
+ {
+ 	port->state.alt = NULL;
+@@ -215,6 +241,7 @@ static int cros_typec_usb_disconnect_state(struct cros_typec_port *port)
+ 
+ 	usb_role_switch_set_role(port->role_sw, USB_ROLE_NONE);
+ 	typec_switch_set(port->ori_sw, TYPEC_ORIENTATION_NONE);
++	cros_typec_retimer_set(port->retimer, port->state);
+ 
+ 	return typec_mux_set(port->mux, &port->state);
+ }
+@@ -412,9 +439,14 @@ unregister_ports:
+ 
+ static int cros_typec_usb_safe_state(struct cros_typec_port *port)
+ {
++	int ret;
+ 	port->state.mode = TYPEC_STATE_SAFE;
+ 
+-	return typec_mux_set(port->mux, &port->state);
++	ret = cros_typec_retimer_set(port->retimer, port->state);
++	if (!ret)
++		ret = typec_mux_set(port->mux, &port->state);
++
++	return ret;
+ }
+ 
+ /*
+@@ -511,7 +543,11 @@ static int cros_typec_enable_dp(struct cros_typec_data *typec,
+ 	port->state.data = &dp_data;
+ 	port->state.mode = TYPEC_MODAL_STATE(ffs(pd_ctrl->dp_mode));
+ 
+-	return typec_mux_set(port->mux, &port->state);
++	ret = cros_typec_retimer_set(port->retimer, port->state);
++	if (!ret)
++		ret = typec_mux_set(port->mux, &port->state);
++
++	return ret;
+ }
+ 
+ static int cros_typec_enable_usb4(struct cros_typec_data *typec,
+@@ -600,7 +636,10 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
+ 	} else if (port->mux_flags & USB_PD_MUX_USB_ENABLED) {
+ 		port->state.alt = NULL;
+ 		port->state.mode = TYPEC_STATE_USB;
+-		ret = typec_mux_set(port->mux, &port->state);
++
++		ret = cros_typec_retimer_set(port->retimer, port->state);
++		if (!ret)
++			ret = typec_mux_set(port->mux, &port->state);
+ 	} else {
+ 		dev_dbg(typec->dev,
+ 			"Unrecognized mode requested, mux flags: %x\n",
+diff --git a/drivers/platform/chrome/cros_usbpd_notify.c b/drivers/platform/chrome/cros_usbpd_notify.c
+index 4b5a81c9dc6da..10670b6588e3e 100644
+--- a/drivers/platform/chrome/cros_usbpd_notify.c
++++ b/drivers/platform/chrome/cros_usbpd_notify.c
+@@ -239,7 +239,11 @@ static int __init cros_usbpd_notify_init(void)
+ 		return ret;
+ 
+ #ifdef CONFIG_ACPI
+-	platform_driver_register(&cros_usbpd_notify_acpi_driver);
++	ret = platform_driver_register(&cros_usbpd_notify_acpi_driver);
++	if (ret) {
++		platform_driver_unregister(&cros_usbpd_notify_plat_driver);
++		return ret;
++	}
+ #endif
+ 	return 0;
+ }
+diff --git a/drivers/platform/mellanox/mlxbf-pmc.c b/drivers/platform/mellanox/mlxbf-pmc.c
+index 65b4a819f1bdf..c2c9b0d3244cb 100644
+--- a/drivers/platform/mellanox/mlxbf-pmc.c
++++ b/drivers/platform/mellanox/mlxbf-pmc.c
+@@ -358,7 +358,7 @@ static const struct mlxbf_pmc_events mlxbf_pmc_hnfnet_events[] = {
+ 	{ 0x32, "DDN_DIAG_W_INGRESS" },
+ 	{ 0x33, "DDN_DIAG_C_INGRESS" },
+ 	{ 0x34, "DDN_DIAG_CORE_SENT" },
+-	{ 0x35, "NDN_DIAG_S_OUT_OF_CRED" },
++	{ 0x35, "NDN_DIAG_N_OUT_OF_CRED" },
+ 	{ 0x36, "NDN_DIAG_S_OUT_OF_CRED" },
+ 	{ 0x37, "NDN_DIAG_E_OUT_OF_CRED" },
+ 	{ 0x38, "NDN_DIAG_W_OUT_OF_CRED" },
+diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c
+index eac3e6b4ea113..935562c870c3d 100644
+--- a/drivers/platform/x86/huawei-wmi.c
++++ b/drivers/platform/x86/huawei-wmi.c
+@@ -760,6 +760,9 @@ static int huawei_wmi_input_setup(struct device *dev,
+ 		const char *guid,
+ 		struct input_dev **idev)
+ {
++	acpi_status status;
++	int err;
++
+ 	*idev = devm_input_allocate_device(dev);
+ 	if (!*idev)
+ 		return -ENOMEM;
+@@ -769,10 +772,19 @@ static int huawei_wmi_input_setup(struct device *dev,
+ 	(*idev)->id.bustype = BUS_HOST;
+ 	(*idev)->dev.parent = dev;
+ 
+-	return sparse_keymap_setup(*idev, huawei_wmi_keymap, NULL) ||
+-		input_register_device(*idev) ||
+-		wmi_install_notify_handler(guid, huawei_wmi_input_notify,
+-				*idev);
++	err = sparse_keymap_setup(*idev, huawei_wmi_keymap, NULL);
++	if (err)
++		return err;
++
++	err = input_register_device(*idev);
++	if (err)
++		return err;
++
++	status = wmi_install_notify_handler(guid, huawei_wmi_input_notify, *idev);
++	if (ACPI_FAILURE(status))
++		return -EIO;
++
++	return 0;
+ }
+ 
+ static void huawei_wmi_input_exit(struct device *dev, const char *guid)
+diff --git a/drivers/platform/x86/intel/int3472/clk_and_regulator.c b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
+index 1cf958983e868..b2342b3d78c72 100644
+--- a/drivers/platform/x86/intel/int3472/clk_and_regulator.c
++++ b/drivers/platform/x86/intel/int3472/clk_and_regulator.c
+@@ -185,7 +185,8 @@ int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,
+ 	cfg.init_data = &init_data;
+ 	cfg.ena_gpiod = int3472->regulator.gpio;
+ 
+-	int3472->regulator.rdev = regulator_register(&int3472->regulator.rdesc,
++	int3472->regulator.rdev = regulator_register(int3472->dev,
++						     &int3472->regulator.rdesc,
+ 						     &cfg);
+ 	if (IS_ERR(int3472->regulator.rdev)) {
+ 		ret = PTR_ERR(int3472->regulator.rdev);
+diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
+index 7cc9089d1e14f..e7a3e34028178 100644
+--- a/drivers/platform/x86/intel_scu_ipc.c
++++ b/drivers/platform/x86/intel_scu_ipc.c
+@@ -583,7 +583,6 @@ __intel_scu_ipc_register(struct device *parent,
+ 	scu->dev.parent = parent;
+ 	scu->dev.class = &intel_scu_ipc_class;
+ 	scu->dev.release = intel_scu_ipc_release;
+-	dev_set_name(&scu->dev, "intel_scu_ipc");
+ 
+ 	if (!request_mem_region(scu_data->mem.start, resource_size(&scu_data->mem),
+ 				"intel_scu_ipc")) {
+@@ -612,6 +611,7 @@ __intel_scu_ipc_register(struct device *parent,
+ 	 * After this point intel_scu_ipc_release() takes care of
+ 	 * releasing the SCU IPC resources once refcount drops to zero.
+ 	 */
++	dev_set_name(&scu->dev, "intel_scu_ipc");
+ 	err = device_register(&scu->dev);
+ 	if (err) {
+ 		put_device(&scu->dev);
+diff --git a/drivers/platform/x86/mxm-wmi.c b/drivers/platform/x86/mxm-wmi.c
+index 9a19fbd2f7341..9a457956025a5 100644
+--- a/drivers/platform/x86/mxm-wmi.c
++++ b/drivers/platform/x86/mxm-wmi.c
+@@ -35,13 +35,11 @@ int mxm_wmi_call_mxds(int adapter)
+ 		.xarg = 1,
+ 	};
+ 	struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
+-	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ 	acpi_status status;
+ 
+ 	printk("calling mux switch %d\n", adapter);
+ 
+-	status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input,
+-				     &output);
++	status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, NULL);
+ 
+ 	if (ACPI_FAILURE(status))
+ 		return status;
+@@ -60,13 +58,11 @@ int mxm_wmi_call_mxmx(int adapter)
+ 		.xarg = 1,
+ 	};
+ 	struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
+-	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ 	acpi_status status;
+ 
+ 	printk("calling mux switch %d\n", adapter);
+ 
+-	status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input,
+-				     &output);
++	status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, NULL);
+ 
+ 	if (ACPI_FAILURE(status))
+ 		return status;
+diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
+index 4df5aa6a309c3..6a60c5d83383b 100644
+--- a/drivers/pnp/core.c
++++ b/drivers/pnp/core.c
+@@ -148,14 +148,14 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id,
+ 	dev->dev.coherent_dma_mask = dev->dma_mask;
+ 	dev->dev.release = &pnp_release_device;
+ 
+-	dev_set_name(&dev->dev, "%02x:%02x", dev->protocol->number, dev->number);
+-
+ 	dev_id = pnp_add_id(dev, pnpid);
+ 	if (!dev_id) {
+ 		kfree(dev);
+ 		return NULL;
+ 	}
+ 
++	dev_set_name(&dev->dev, "%02x:%02x", dev->protocol->number, dev->number);
++
+ 	return dev;
+ }
+ 
+diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c
+index c19c50442761d..58757a5799f8b 100644
+--- a/drivers/power/supply/ab8500_charger.c
++++ b/drivers/power/supply/ab8500_charger.c
+@@ -3719,7 +3719,14 @@ static int __init ab8500_charger_init(void)
+ 	if (ret)
+ 		return ret;
+ 
+-	return platform_driver_register(&ab8500_charger_driver);
++	ret = platform_driver_register(&ab8500_charger_driver);
++	if (ret) {
++		platform_unregister_drivers(ab8500_charger_component_drivers,
++				ARRAY_SIZE(ab8500_charger_component_drivers));
++		return ret;
++	}
++
++	return 0;
+ }
+ 
+ static void __exit ab8500_charger_exit(void)
+diff --git a/drivers/power/supply/bq25890_charger.c b/drivers/power/supply/bq25890_charger.c
+index 852a6fec4339b..92fab662a51d4 100644
+--- a/drivers/power/supply/bq25890_charger.c
++++ b/drivers/power/supply/bq25890_charger.c
+@@ -1019,6 +1019,36 @@ static const struct regulator_desc bq25890_vbus_desc = {
+ 	.fixed_uV = 5000000,
+ 	.n_voltages = 1,
+ };
++
++static int bq25890_register_regulator(struct bq25890_device *bq)
++{
++	struct bq25890_platform_data *pdata = dev_get_platdata(bq->dev);
++	struct regulator_config cfg = {
++		.dev = bq->dev,
++		.driver_data = bq,
++	};
++	struct regulator_dev *reg;
++
++	if (!IS_ERR_OR_NULL(bq->usb_phy))
++		return 0;
++
++	if (pdata)
++		cfg.init_data = pdata->regulator_init_data;
++
++	reg = devm_regulator_register(bq->dev, &bq25890_vbus_desc, &cfg);
++	if (IS_ERR(reg)) {
++		return dev_err_probe(bq->dev, PTR_ERR(reg),
++				     "registering vbus regulator");
++	}
++
++	return 0;
++}
++#else
++static inline int
++bq25890_register_regulator(struct bq25890_device *bq)
++{
++	return 0;
++}
+ #endif
+ 
+ static int bq25890_get_chip_version(struct bq25890_device *bq)
+@@ -1159,8 +1189,14 @@ static int bq25890_fw_probe(struct bq25890_device *bq)
+ 	return 0;
+ }
+ 
+-static int bq25890_probe(struct i2c_client *client,
+-			 const struct i2c_device_id *id)
++static void bq25890_non_devm_cleanup(void *data)
++{
++	struct bq25890_device *bq = data;
++
++	cancel_delayed_work_sync(&bq->pump_express_work);
++}
++
++static int bq25890_probe(struct i2c_client *client)
+ {
+ 	struct device *dev = &client->dev;
+ 	struct bq25890_device *bq;
+@@ -1214,27 +1250,24 @@ static int bq25890_probe(struct i2c_client *client,
+ 
+ 	/* OTG reporting */
+ 	bq->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
++
++	/*
++	 * This must be before bq25890_power_supply_init(), so that it runs
++	 * after devm unregisters the power_supply.
++	 */
++	ret = devm_add_action_or_reset(dev, bq25890_non_devm_cleanup, bq);
++	if (ret)
++		return ret;
++
++	ret = bq25890_register_regulator(bq);
++	if (ret)
++		return ret;
++
+ 	if (!IS_ERR_OR_NULL(bq->usb_phy)) {
+ 		INIT_WORK(&bq->usb_work, bq25890_usb_work);
+ 		bq->usb_nb.notifier_call = bq25890_usb_notifier;
+ 		usb_register_notifier(bq->usb_phy, &bq->usb_nb);
+ 	}
+-#ifdef CONFIG_REGULATOR
+-	else {
+-		struct bq25890_platform_data *pdata = dev_get_platdata(dev);
+-		struct regulator_config cfg = { };
+-		struct regulator_dev *reg;
+-
+-		cfg.dev = dev;
+-		cfg.driver_data = bq;
+-		if (pdata)
+-			cfg.init_data = pdata->regulator_init_data;
+-
+-		reg = devm_regulator_register(dev, &bq25890_vbus_desc, &cfg);
+-		if (IS_ERR(reg))
+-			return dev_err_probe(dev, PTR_ERR(reg), "registering regulator");
+-	}
+-#endif
+ 
+ 	ret = bq25890_power_supply_init(bq);
+ 	if (ret < 0) {
+@@ -1372,7 +1405,7 @@ static struct i2c_driver bq25890_driver = {
+ 		.acpi_match_table = ACPI_PTR(bq25890_acpi_match),
+ 		.pm = &bq25890_pm,
+ 	},
+-	.probe = bq25890_probe,
++	.probe_new = bq25890_probe,
+ 	.remove = bq25890_remove,
+ 	.shutdown = bq25890_shutdown,
+ 	.id_table = bq25890_i2c_ids,
+diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c
+index 728e2a6cc9c31..473522b4326ad 100644
+--- a/drivers/power/supply/cw2015_battery.c
++++ b/drivers/power/supply/cw2015_battery.c
+@@ -21,6 +21,7 @@
+ #include <linux/regmap.h>
+ #include <linux/time.h>
+ #include <linux/workqueue.h>
++#include <linux/devm-helpers.h>
+ 
+ #define CW2015_SIZE_BATINFO		64
+ 
+@@ -698,7 +699,11 @@ static int cw_bat_probe(struct i2c_client *client)
+ 	}
+ 
+ 	cw_bat->battery_workqueue = create_singlethread_workqueue("rk_battery");
+-	INIT_DELAYED_WORK(&cw_bat->battery_delay_work, cw_bat_work);
++	if (!cw_bat->battery_workqueue)
++		return -ENOMEM;
++
++	devm_delayed_work_autocancel(&client->dev,
++							  &cw_bat->battery_delay_work, cw_bat_work);
+ 	queue_delayed_work(cw_bat->battery_workqueue,
+ 			   &cw_bat->battery_delay_work, msecs_to_jiffies(10));
+ 	return 0;
+@@ -725,15 +730,6 @@ static int __maybe_unused cw_bat_resume(struct device *dev)
+ 
+ static SIMPLE_DEV_PM_OPS(cw_bat_pm_ops, cw_bat_suspend, cw_bat_resume);
+ 
+-static int cw_bat_remove(struct i2c_client *client)
+-{
+-	struct cw_battery *cw_bat = i2c_get_clientdata(client);
+-
+-	cancel_delayed_work_sync(&cw_bat->battery_delay_work);
+-	power_supply_put_battery_info(cw_bat->rk_bat, cw_bat->battery);
+-	return 0;
+-}
+-
+ static const struct i2c_device_id cw_bat_id_table[] = {
+ 	{ "cw2015", 0 },
+ 	{ }
+@@ -752,7 +748,6 @@ static struct i2c_driver cw_bat_driver = {
+ 		.pm = &cw_bat_pm_ops,
+ 	},
+ 	.probe_new = cw_bat_probe,
+-	.remove = cw_bat_remove,
+ 	.id_table = cw_bat_id_table,
+ };
+ 
+diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
+index 4b5fb172fa994..01d1ac79d982e 100644
+--- a/drivers/power/supply/power_supply_core.c
++++ b/drivers/power/supply/power_supply_core.c
+@@ -750,6 +750,11 @@ int power_supply_get_battery_info(struct power_supply *psy,
+ 		int i, tab_len, size;
+ 
+ 		propname = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", index);
++		if (!propname) {
++			power_supply_put_battery_info(psy, info);
++			err = -ENOMEM;
++			goto out_put_node;
++		}
+ 		list = of_get_property(battery_np, propname, &size);
+ 		if (!list || !size) {
+ 			dev_err(&psy->dev, "failed to get %s\n", propname);
+@@ -1387,8 +1392,8 @@ create_triggers_failed:
+ register_cooler_failed:
+ 	psy_unregister_thermal(psy);
+ register_thermal_failed:
+-	device_del(dev);
+ wakeup_init_failed:
++	device_del(dev);
+ device_add_failed:
+ check_supplies_failed:
+ dev_set_name_failed:
+diff --git a/drivers/power/supply/z2_battery.c b/drivers/power/supply/z2_battery.c
+index 7ed4e4bb26eca..fd33cdf9cf12c 100644
+--- a/drivers/power/supply/z2_battery.c
++++ b/drivers/power/supply/z2_battery.c
+@@ -206,10 +206,12 @@ static int z2_batt_probe(struct i2c_client *client,
+ 
+ 	charger->charge_gpiod = devm_gpiod_get_optional(&client->dev,
+ 							NULL, GPIOD_IN);
+-	if (IS_ERR(charger->charge_gpiod))
+-		return dev_err_probe(&client->dev,
++	if (IS_ERR(charger->charge_gpiod)) {
++		ret = dev_err_probe(&client->dev,
+ 				     PTR_ERR(charger->charge_gpiod),
+ 				     "failed to get charge GPIO\n");
++		goto err;
++	}
+ 
+ 	if (charger->charge_gpiod) {
+ 		gpiod_set_consumer_name(charger->charge_gpiod, "BATT CHRG");
+diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
+index 6901a44dc428d..a337b47dc2f7d 100644
+--- a/drivers/pwm/pwm-mediatek.c
++++ b/drivers/pwm/pwm-mediatek.c
+@@ -296,7 +296,7 @@ static const struct pwm_mediatek_of_data mt6795_pwm_data = {
+ static const struct pwm_mediatek_of_data mt7622_pwm_data = {
+ 	.num_pwms = 6,
+ 	.pwm45_fixup = false,
+-	.has_ck_26m_sel = false,
++	.has_ck_26m_sel = true,
+ };
+ 
+ static const struct pwm_mediatek_of_data mt7623_pwm_data = {
+diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
+index c605013e4114c..3fbb4bae93a4e 100644
+--- a/drivers/pwm/pwm-mtk-disp.c
++++ b/drivers/pwm/pwm-mtk-disp.c
+@@ -178,7 +178,7 @@ static void mtk_disp_pwm_get_state(struct pwm_chip *chip,
+ {
+ 	struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
+ 	u64 rate, period, high_width;
+-	u32 clk_div, con0, con1;
++	u32 clk_div, pwm_en, con0, con1;
+ 	int err;
+ 
+ 	err = clk_prepare_enable(mdp->clk_main);
+@@ -197,7 +197,8 @@ static void mtk_disp_pwm_get_state(struct pwm_chip *chip,
+ 	rate = clk_get_rate(mdp->clk_main);
+ 	con0 = readl(mdp->base + mdp->data->con0);
+ 	con1 = readl(mdp->base + mdp->data->con1);
+-	state->enabled = !!(con0 & BIT(0));
++	pwm_en = readl(mdp->base + DISP_PWM_EN);
++	state->enabled = !!(pwm_en & mdp->data->enable_mask);
+ 	clk_div = FIELD_GET(PWM_CLKDIV_MASK, con0);
+ 	period = FIELD_GET(PWM_PERIOD_MASK, con1);
+ 	/*
+diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c
+index 2d4fa5e5fdd46..bb72393134016 100644
+--- a/drivers/pwm/pwm-sifive.c
++++ b/drivers/pwm/pwm-sifive.c
+@@ -204,8 +204,11 @@ static int pwm_sifive_clock_notifier(struct notifier_block *nb,
+ 	struct pwm_sifive_ddata *ddata =
+ 		container_of(nb, struct pwm_sifive_ddata, notifier);
+ 
+-	if (event == POST_RATE_CHANGE)
++	if (event == POST_RATE_CHANGE) {
++		mutex_lock(&ddata->lock);
+ 		pwm_sifive_update_clock(ddata, ndata->new_rate);
++		mutex_unlock(&ddata->lock);
++	}
+ 
+ 	return NOTIFY_OK;
+ }
+diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
+index dad9978c91861..249dc01932979 100644
+--- a/drivers/pwm/pwm-tegra.c
++++ b/drivers/pwm/pwm-tegra.c
+@@ -145,8 +145,19 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ 		 * source clock rate as required_clk_rate, PWM controller will
+ 		 * be able to configure the requested period.
+ 		 */
+-		required_clk_rate =
+-			(NSEC_PER_SEC / period_ns) << PWM_DUTY_WIDTH;
++		required_clk_rate = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC << PWM_DUTY_WIDTH,
++						     period_ns);
++
++		if (required_clk_rate > clk_round_rate(pc->clk, required_clk_rate))
++			/*
++			 * required_clk_rate is a lower bound for the input
++			 * rate; for lower rates there is no value for PWM_SCALE
++			 * that yields a period less than or equal to the
++			 * requested period. Hence, for lower rates, double the
++			 * required_clk_rate to get a clock rate that can meet
++			 * the requested period.
++			 */
++			required_clk_rate *= 2;
+ 
+ 		err = dev_pm_opp_set_rate(pc->dev, required_clk_rate);
+ 		if (err < 0)
+diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c
+index 2cdc054e53a53..43db495f19861 100644
+--- a/drivers/rapidio/devices/rio_mport_cdev.c
++++ b/drivers/rapidio/devices/rio_mport_cdev.c
+@@ -1804,8 +1804,11 @@ static int rio_mport_add_riodev(struct mport_cdev_priv *priv,
+ 		rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
+ 				   0, 0xffff);
+ 	err = rio_add_device(rdev);
+-	if (err)
+-		goto cleanup;
++	if (err) {
++		put_device(&rdev->dev);
++		return err;
++	}
++
+ 	rio_dev_get(rdev);
+ 
+ 	return 0;
+@@ -1901,10 +1904,6 @@ static int mport_cdev_open(struct inode *inode, struct file *filp)
+ 
+ 	priv->md = chdev;
+ 
+-	mutex_lock(&chdev->file_mutex);
+-	list_add_tail(&priv->list, &chdev->file_list);
+-	mutex_unlock(&chdev->file_mutex);
+-
+ 	INIT_LIST_HEAD(&priv->db_filters);
+ 	INIT_LIST_HEAD(&priv->pw_filters);
+ 	spin_lock_init(&priv->fifo_lock);
+@@ -1913,6 +1912,7 @@ static int mport_cdev_open(struct inode *inode, struct file *filp)
+ 			  sizeof(struct rio_event) * MPORT_EVENT_DEPTH,
+ 			  GFP_KERNEL);
+ 	if (ret < 0) {
++		put_device(&chdev->dev);
+ 		dev_err(&chdev->dev, DRV_NAME ": kfifo_alloc failed\n");
+ 		ret = -ENOMEM;
+ 		goto err_fifo;
+@@ -1923,6 +1923,9 @@ static int mport_cdev_open(struct inode *inode, struct file *filp)
+ 	spin_lock_init(&priv->req_lock);
+ 	mutex_init(&priv->dma_lock);
+ #endif
++	mutex_lock(&chdev->file_mutex);
++	list_add_tail(&priv->list, &chdev->file_list);
++	mutex_unlock(&chdev->file_mutex);
+ 
+ 	filp->private_data = priv;
+ 	goto out;
+diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
+index 19b0c33f4a62a..fdcf742b2adbc 100644
+--- a/drivers/rapidio/rio-scan.c
++++ b/drivers/rapidio/rio-scan.c
+@@ -454,8 +454,12 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
+ 				   0, 0xffff);
+ 
+ 	ret = rio_add_device(rdev);
+-	if (ret)
+-		goto cleanup;
++	if (ret) {
++		if (rswitch)
++			kfree(rswitch->route_table);
++		put_device(&rdev->dev);
++		return NULL;
++	}
+ 
+ 	rio_dev_get(rdev);
+ 
+diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
+index e74cf09eeff07..9544b8ee0c963 100644
+--- a/drivers/rapidio/rio.c
++++ b/drivers/rapidio/rio.c
+@@ -2186,11 +2186,16 @@ int rio_register_mport(struct rio_mport *port)
+ 	atomic_set(&port->state, RIO_DEVICE_RUNNING);
+ 
+ 	res = device_register(&port->dev);
+-	if (res)
++	if (res) {
+ 		dev_err(&port->dev, "RIO: mport%d registration failed ERR=%d\n",
+ 			port->id, res);
+-	else
++		mutex_lock(&rio_mport_list_lock);
++		list_del(&port->node);
++		mutex_unlock(&rio_mport_list_lock);
++		put_device(&port->dev);
++	} else {
+ 		dev_dbg(&port->dev, "RIO: registered mport%d\n", port->id);
++	}
+ 
+ 	return res;
+ }
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index c0f368f1b49f7..6829f7d8e24c8 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -987,7 +987,7 @@ static int drms_uA_update(struct regulator_dev *rdev)
+ 		/* get input voltage */
+ 		input_uV = 0;
+ 		if (rdev->supply)
+-			input_uV = regulator_get_voltage(rdev->supply);
++			input_uV = regulator_get_voltage_rdev(rdev->supply->rdev);
+ 		if (input_uV <= 0)
+ 			input_uV = rdev->constraints->input_uV;
+ 		if (input_uV <= 0) {
+@@ -1578,7 +1578,13 @@ static int set_machine_constraints(struct regulator_dev *rdev)
+ 		if (rdev->supply_name && !rdev->supply)
+ 			return -EPROBE_DEFER;
+ 
+-		if (rdev->supply) {
++		/* If supplying regulator has already been enabled,
++		 * it's not intended to have use_count increment
++		 * when rdev is only boot-on.
++		 */
++		if (rdev->supply &&
++		    (rdev->constraints->always_on ||
++		     !regulator_is_enabled(rdev->supply))) {
+ 			ret = regulator_enable(rdev->supply);
+ 			if (ret < 0) {
+ 				_regulator_put(rdev->supply);
+@@ -1622,6 +1628,7 @@ static int set_supply(struct regulator_dev *rdev,
+ 
+ 	rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY");
+ 	if (rdev->supply == NULL) {
++		module_put(supply_rdev->owner);
+ 		err = -ENOMEM;
+ 		return err;
+ 	}
+@@ -1795,7 +1802,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
+ 
+ 	regulator = kzalloc(sizeof(*regulator), GFP_KERNEL);
+ 	if (regulator == NULL) {
+-		kfree(supply_name);
++		kfree_const(supply_name);
+ 		return NULL;
+ 	}
+ 
+@@ -1925,6 +1932,7 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
+ 		node = of_get_regulator(dev, supply);
+ 		if (node) {
+ 			r = of_find_regulator_by_node(node);
++			of_node_put(node);
+ 			if (r)
+ 				return r;
+ 
+@@ -5380,6 +5388,7 @@ static struct regulator_coupler generic_regulator_coupler = {
+ 
+ /**
+  * regulator_register - register regulator
++ * @dev: the device that drive the regulator
+  * @regulator_desc: regulator to register
+  * @cfg: runtime configuration for regulator
+  *
+@@ -5388,7 +5397,8 @@ static struct regulator_coupler generic_regulator_coupler = {
+  * or an ERR_PTR() on error.
+  */
+ struct regulator_dev *
+-regulator_register(const struct regulator_desc *regulator_desc,
++regulator_register(struct device *dev,
++		   const struct regulator_desc *regulator_desc,
+ 		   const struct regulator_config *cfg)
+ {
+ 	const struct regulator_init_data *init_data;
+@@ -5397,7 +5407,6 @@ regulator_register(const struct regulator_desc *regulator_desc,
+ 	struct regulator_dev *rdev;
+ 	bool dangling_cfg_gpiod = false;
+ 	bool dangling_of_gpiod = false;
+-	struct device *dev;
+ 	int ret, i;
+ 
+ 	if (cfg == NULL)
+@@ -5409,8 +5418,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
+ 		goto rinse;
+ 	}
+ 
+-	dev = cfg->dev;
+-	WARN_ON(!dev);
++	WARN_ON(!dev || !cfg->dev);
+ 
+ 	if (regulator_desc->name == NULL || regulator_desc->ops == NULL) {
+ 		ret = -EINVAL;
+@@ -5523,7 +5531,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
+ 
+ 	/* register with sysfs */
+ 	rdev->dev.class = &regulator_class;
+-	rdev->dev.parent = dev;
++	rdev->dev.parent = config->dev;
+ 	dev_set_name(&rdev->dev, "regulator.%lu",
+ 		    (unsigned long) atomic_inc_return(&regulator_no));
+ 	dev_set_drvdata(&rdev->dev, rdev);
+@@ -5613,6 +5621,7 @@ unset_supplies:
+ 	regulator_remove_coupling(rdev);
+ 	mutex_unlock(&regulator_list_mutex);
+ wash:
++	regulator_put(rdev->supply);
+ 	kfree(rdev->coupling_desc.coupled_rdevs);
+ 	mutex_lock(&regulator_list_mutex);
+ 	regulator_ena_gpio_free(rdev);
+diff --git a/drivers/regulator/devres.c b/drivers/regulator/devres.c
+index 32823a87fd409..d94db64cd490c 100644
+--- a/drivers/regulator/devres.c
++++ b/drivers/regulator/devres.c
+@@ -221,7 +221,7 @@ struct regulator_dev *devm_regulator_register(struct device *dev,
+ 	if (!ptr)
+ 		return ERR_PTR(-ENOMEM);
+ 
+-	rdev = regulator_register(regulator_desc, config);
++	rdev = regulator_register(dev, regulator_desc, config);
+ 	if (!IS_ERR(rdev)) {
+ 		*ptr = rdev;
+ 		devres_add(dev, ptr);
+diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
+index e12b681c72e5e..bd0c5d1fd647c 100644
+--- a/drivers/regulator/of_regulator.c
++++ b/drivers/regulator/of_regulator.c
+@@ -505,7 +505,7 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
+ 	struct device_node *child;
+ 	struct regulator_init_data *init_data = NULL;
+ 
+-	child = regulator_of_get_init_node(dev, desc);
++	child = regulator_of_get_init_node(config->dev, desc);
+ 	if (!child)
+ 		return NULL;
+ 
+diff --git a/drivers/regulator/qcom-labibb-regulator.c b/drivers/regulator/qcom-labibb-regulator.c
+index 639b71eb41ffe..bcf7140f3bc98 100644
+--- a/drivers/regulator/qcom-labibb-regulator.c
++++ b/drivers/regulator/qcom-labibb-regulator.c
+@@ -822,6 +822,7 @@ static int qcom_labibb_regulator_probe(struct platform_device *pdev)
+ 			if (irq == 0)
+ 				irq = -EINVAL;
+ 
++			of_node_put(reg_node);
+ 			return dev_err_probe(vreg->dev, irq,
+ 					     "Short-circuit irq not found.\n");
+ 		}
+diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c
+index 561de6b2e6e36..5839e47323360 100644
+--- a/drivers/regulator/qcom-rpmh-regulator.c
++++ b/drivers/regulator/qcom-rpmh-regulator.c
+@@ -1188,7 +1188,7 @@ static const struct rpmh_vreg_init_data pm7325_vreg_data[] = {
+ static const struct rpmh_vreg_init_data pmr735a_vreg_data[] = {
+ 	RPMH_VREG("smps1",  "smp%s1",  &pmic5_ftsmps520, "vdd-s1"),
+ 	RPMH_VREG("smps2",  "smp%s2",  &pmic5_ftsmps520, "vdd-s2"),
+-	RPMH_VREG("smps3",  "smp%s3",  &pmic5_hfsmps510, "vdd-s3"),
++	RPMH_VREG("smps3",  "smp%s3",  &pmic5_hfsmps515, "vdd-s3"),
+ 	RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_nldo,      "vdd-l1-l2"),
+ 	RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_nldo,      "vdd-l1-l2"),
+ 	RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l3"),
+diff --git a/drivers/regulator/stm32-vrefbuf.c b/drivers/regulator/stm32-vrefbuf.c
+index 30ea3bc8ca192..7a454b7b6eab9 100644
+--- a/drivers/regulator/stm32-vrefbuf.c
++++ b/drivers/regulator/stm32-vrefbuf.c
+@@ -210,7 +210,7 @@ static int stm32_vrefbuf_probe(struct platform_device *pdev)
+ 						      pdev->dev.of_node,
+ 						      &stm32_vrefbuf_regu);
+ 
+-	rdev = regulator_register(&stm32_vrefbuf_regu, &config);
++	rdev = regulator_register(&pdev->dev, &stm32_vrefbuf_regu, &config);
+ 	if (IS_ERR(rdev)) {
+ 		ret = PTR_ERR(rdev);
+ 		dev_err(&pdev->dev, "register failed with error %d\n", ret);
+diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c
+index 6afd0941e5524..dc6f07ca83410 100644
+--- a/drivers/remoteproc/qcom_q6v5_pas.c
++++ b/drivers/remoteproc/qcom_q6v5_pas.c
+@@ -449,6 +449,7 @@ static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
+ 	}
+ 
+ 	ret = of_address_to_resource(node, 0, &r);
++	of_node_put(node);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -556,6 +557,7 @@ static int adsp_probe(struct platform_device *pdev)
+ detach_proxy_pds:
+ 	adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
+ free_rproc:
++	device_init_wakeup(adsp->dev, false);
+ 	rproc_free(rproc);
+ 
+ 	return ret;
+@@ -572,6 +574,8 @@ static int adsp_remove(struct platform_device *pdev)
+ 	qcom_remove_sysmon_subdev(adsp->sysmon);
+ 	qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
+ 	qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
++	adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
++	device_init_wakeup(adsp->dev, false);
+ 	rproc_free(adsp->rproc);
+ 
+ 	return 0;
+diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
+index bb0947f7770ea..ba24d745b2d65 100644
+--- a/drivers/remoteproc/qcom_q6v5_wcss.c
++++ b/drivers/remoteproc/qcom_q6v5_wcss.c
+@@ -351,7 +351,7 @@ static int q6v5_wcss_qcs404_power_on(struct q6v5_wcss *wcss)
+ 	if (ret) {
+ 		dev_err(wcss->dev,
+ 			"xo cbcr enabling timed out (rc:%d)\n", ret);
+-		return ret;
++		goto disable_xo_cbcr_clk;
+ 	}
+ 
+ 	writel(0, wcss->reg_base + Q6SS_CGC_OVERRIDE);
+@@ -417,6 +417,7 @@ disable_sleep_cbcr_clk:
+ 	val = readl(wcss->reg_base + Q6SS_SLEEP_CBCR);
+ 	val &= ~Q6SS_CLK_ENABLE;
+ 	writel(val, wcss->reg_base + Q6SS_SLEEP_CBCR);
++disable_xo_cbcr_clk:
+ 	val = readl(wcss->reg_base + Q6SS_XO_CBCR);
+ 	val &= ~Q6SS_CLK_ENABLE;
+ 	writel(val, wcss->reg_base + Q6SS_XO_CBCR);
+@@ -827,6 +828,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss,
+ 	int ret;
+ 
+ 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6");
++	if (!res)
++		return -EINVAL;
++
+ 	wcss->reg_base = devm_ioremap(&pdev->dev, res->start,
+ 				      resource_size(res));
+ 	if (!wcss->reg_base)
+diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c
+index 57dde2a69b9dd..15af52f8499eb 100644
+--- a/drivers/remoteproc/qcom_sysmon.c
++++ b/drivers/remoteproc/qcom_sysmon.c
+@@ -652,7 +652,9 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
+ 		if (sysmon->shutdown_irq != -ENODATA) {
+ 			dev_err(sysmon->dev,
+ 				"failed to retrieve shutdown-ack IRQ\n");
+-			return ERR_PTR(sysmon->shutdown_irq);
++			ret = sysmon->shutdown_irq;
++			kfree(sysmon);
++			return ERR_PTR(ret);
+ 		}
+ 	} else {
+ 		ret = devm_request_threaded_irq(sysmon->dev,
+@@ -663,6 +665,7 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
+ 		if (ret) {
+ 			dev_err(sysmon->dev,
+ 				"failed to acquire shutdown-ack IRQ\n");
++			kfree(sysmon);
+ 			return ERR_PTR(ret);
+ 		}
+ 	}
+diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
+index e48223c00c672..e5b7b48cffac0 100644
+--- a/drivers/rtc/class.c
++++ b/drivers/rtc/class.c
+@@ -374,11 +374,11 @@ struct rtc_device *devm_rtc_allocate_device(struct device *dev)
+ 
+ 	rtc->id = id;
+ 	rtc->dev.parent = dev;
+-	err = dev_set_name(&rtc->dev, "rtc%d", id);
++	err = devm_add_action_or_reset(dev, devm_rtc_release_device, rtc);
+ 	if (err)
+ 		return ERR_PTR(err);
+ 
+-	err = devm_add_action_or_reset(dev, devm_rtc_release_device, rtc);
++	err = dev_set_name(&rtc->dev, "rtc%d", id);
+ 	if (err)
+ 		return ERR_PTR(err);
+ 
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index 58cc2bae2f8a0..00e2ca7374ecf 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -744,6 +744,168 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
+ 		return IRQ_NONE;
+ }
+ 
++#ifdef	CONFIG_ACPI
++
++#include <linux/acpi.h>
++
++static u32 rtc_handler(void *context)
++{
++	struct device *dev = context;
++	struct cmos_rtc *cmos = dev_get_drvdata(dev);
++	unsigned char rtc_control = 0;
++	unsigned char rtc_intr;
++	unsigned long flags;
++
++
++	/*
++	 * Always update rtc irq when ACPI is used as RTC Alarm.
++	 * Or else, ACPI SCI is enabled during suspend/resume only,
++	 * update rtc irq in that case.
++	 */
++	if (cmos_use_acpi_alarm())
++		cmos_interrupt(0, (void *)cmos->rtc);
++	else {
++		/* Fix me: can we use cmos_interrupt() here as well? */
++		spin_lock_irqsave(&rtc_lock, flags);
++		if (cmos_rtc.suspend_ctrl)
++			rtc_control = CMOS_READ(RTC_CONTROL);
++		if (rtc_control & RTC_AIE) {
++			cmos_rtc.suspend_ctrl &= ~RTC_AIE;
++			CMOS_WRITE(rtc_control, RTC_CONTROL);
++			rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
++			rtc_update_irq(cmos->rtc, 1, rtc_intr);
++		}
++		spin_unlock_irqrestore(&rtc_lock, flags);
++	}
++
++	pm_wakeup_hard_event(dev);
++	acpi_clear_event(ACPI_EVENT_RTC);
++	acpi_disable_event(ACPI_EVENT_RTC, 0);
++	return ACPI_INTERRUPT_HANDLED;
++}
++
++static void acpi_rtc_event_setup(struct device *dev)
++{
++	if (acpi_disabled)
++		return;
++
++	acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);
++	/*
++	 * After the RTC handler is installed, the Fixed_RTC event should
++	 * be disabled. Only when the RTC alarm is set will it be enabled.
++	 */
++	acpi_clear_event(ACPI_EVENT_RTC);
++	acpi_disable_event(ACPI_EVENT_RTC, 0);
++}
++
++static void acpi_rtc_event_cleanup(void)
++{
++	if (acpi_disabled)
++		return;
++
++	acpi_remove_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler);
++}
++
++static void rtc_wake_on(struct device *dev)
++{
++	acpi_clear_event(ACPI_EVENT_RTC);
++	acpi_enable_event(ACPI_EVENT_RTC, 0);
++}
++
++static void rtc_wake_off(struct device *dev)
++{
++	acpi_disable_event(ACPI_EVENT_RTC, 0);
++}
++
++#ifdef CONFIG_X86
++/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
++static void use_acpi_alarm_quirks(void)
++{
++	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
++		return;
++
++	if (!is_hpet_enabled())
++		return;
++
++	if (dmi_get_bios_year() < 2015)
++		return;
++
++	use_acpi_alarm = true;
++}
++#else
++static inline void use_acpi_alarm_quirks(void) { }
++#endif
++
++static void acpi_cmos_wake_setup(struct device *dev)
++{
++	if (acpi_disabled)
++		return;
++
++	use_acpi_alarm_quirks();
++
++	cmos_rtc.wake_on = rtc_wake_on;
++	cmos_rtc.wake_off = rtc_wake_off;
++
++	/* ACPI tables bug workaround. */
++	if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
++		dev_dbg(dev, "bogus FADT month_alarm (%d)\n",
++			acpi_gbl_FADT.month_alarm);
++		acpi_gbl_FADT.month_alarm = 0;
++	}
++
++	cmos_rtc.day_alrm = acpi_gbl_FADT.day_alarm;
++	cmos_rtc.mon_alrm = acpi_gbl_FADT.month_alarm;
++	cmos_rtc.century = acpi_gbl_FADT.century;
++
++	if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
++		dev_info(dev, "RTC can wake from S4\n");
++
++	/* RTC always wakes from S1/S2/S3, and often S4/STD */
++	device_init_wakeup(dev, 1);
++}
++
++static void cmos_check_acpi_rtc_status(struct device *dev,
++					      unsigned char *rtc_control)
++{
++	struct cmos_rtc *cmos = dev_get_drvdata(dev);
++	acpi_event_status rtc_status;
++	acpi_status status;
++
++	if (acpi_gbl_FADT.flags & ACPI_FADT_FIXED_RTC)
++		return;
++
++	status = acpi_get_event_status(ACPI_EVENT_RTC, &rtc_status);
++	if (ACPI_FAILURE(status)) {
++		dev_err(dev, "Could not get RTC status\n");
++	} else if (rtc_status & ACPI_EVENT_FLAG_SET) {
++		unsigned char mask;
++		*rtc_control &= ~RTC_AIE;
++		CMOS_WRITE(*rtc_control, RTC_CONTROL);
++		mask = CMOS_READ(RTC_INTR_FLAGS);
++		rtc_update_irq(cmos->rtc, 1, mask);
++	}
++}
++
++#else /* !CONFIG_ACPI */
++
++static inline void acpi_rtc_event_setup(struct device *dev)
++{
++}
++
++static inline void acpi_rtc_event_cleanup(void)
++{
++}
++
++static inline void acpi_cmos_wake_setup(struct device *dev)
++{
++}
++
++static inline void cmos_check_acpi_rtc_status(struct device *dev,
++					      unsigned char *rtc_control)
++{
++}
++#endif /* CONFIG_ACPI */
++
+ #ifdef	CONFIG_PNP
+ #define	INITSECTION
+ 
+@@ -827,19 +989,27 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
+ 		if (info->address_space)
+ 			address_space = info->address_space;
+ 
+-		if (info->rtc_day_alarm && info->rtc_day_alarm < 128)
+-			cmos_rtc.day_alrm = info->rtc_day_alarm;
+-		if (info->rtc_mon_alarm && info->rtc_mon_alarm < 128)
+-			cmos_rtc.mon_alrm = info->rtc_mon_alarm;
+-		if (info->rtc_century && info->rtc_century < 128)
+-			cmos_rtc.century = info->rtc_century;
++		cmos_rtc.day_alrm = info->rtc_day_alarm;
++		cmos_rtc.mon_alrm = info->rtc_mon_alarm;
++		cmos_rtc.century = info->rtc_century;
+ 
+ 		if (info->wake_on && info->wake_off) {
+ 			cmos_rtc.wake_on = info->wake_on;
+ 			cmos_rtc.wake_off = info->wake_off;
+ 		}
++	} else {
++		acpi_cmos_wake_setup(dev);
+ 	}
+ 
++	if (cmos_rtc.day_alrm >= 128)
++		cmos_rtc.day_alrm = 0;
++
++	if (cmos_rtc.mon_alrm >= 128)
++		cmos_rtc.mon_alrm = 0;
++
++	if (cmos_rtc.century >= 128)
++		cmos_rtc.century = 0;
++
+ 	cmos_rtc.dev = dev;
+ 	dev_set_drvdata(dev, &cmos_rtc);
+ 
+@@ -928,6 +1098,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
+ 	nvmem_cfg.size = address_space - NVRAM_OFFSET;
+ 	devm_rtc_nvmem_register(cmos_rtc.rtc, &nvmem_cfg);
+ 
++	/*
++	 * Everything has gone well so far, so by default register a handler for
++	 * the ACPI RTC fixed event.
++	 */
++	if (!info)
++		acpi_rtc_event_setup(dev);
++
+ 	dev_info(dev, "%s%s, %d bytes nvram%s\n",
+ 		 !is_valid_irq(rtc_irq) ? "no alarms" :
+ 		 cmos_rtc.mon_alrm ? "alarms up to one year" :
+@@ -973,6 +1150,9 @@ static void cmos_do_remove(struct device *dev)
+ 			hpet_unregister_irq_handler(cmos_interrupt);
+ 	}
+ 
++	if (!dev_get_platdata(dev))
++		acpi_rtc_event_cleanup();
++
+ 	cmos->rtc = NULL;
+ 
+ 	ports = cmos->iomem;
+@@ -1122,9 +1302,6 @@ static void cmos_check_wkalrm(struct device *dev)
+ 	}
+ }
+ 
+-static void cmos_check_acpi_rtc_status(struct device *dev,
+-				       unsigned char *rtc_control);
+-
+ static int __maybe_unused cmos_resume(struct device *dev)
+ {
+ 	struct cmos_rtc	*cmos = dev_get_drvdata(dev);
+@@ -1191,175 +1368,13 @@ static SIMPLE_DEV_PM_OPS(cmos_pm_ops, cmos_suspend, cmos_resume);
+  * predate even PNPBIOS should set up platform_bus devices.
+  */
+ 
+-#ifdef	CONFIG_ACPI
+-
+-#include <linux/acpi.h>
+-
+-static u32 rtc_handler(void *context)
+-{
+-	struct device *dev = context;
+-	struct cmos_rtc *cmos = dev_get_drvdata(dev);
+-	unsigned char rtc_control = 0;
+-	unsigned char rtc_intr;
+-	unsigned long flags;
+-
+-
+-	/*
+-	 * Always update rtc irq when ACPI is used as RTC Alarm.
+-	 * Or else, ACPI SCI is enabled during suspend/resume only,
+-	 * update rtc irq in that case.
+-	 */
+-	if (cmos_use_acpi_alarm())
+-		cmos_interrupt(0, (void *)cmos->rtc);
+-	else {
+-		/* Fix me: can we use cmos_interrupt() here as well? */
+-		spin_lock_irqsave(&rtc_lock, flags);
+-		if (cmos_rtc.suspend_ctrl)
+-			rtc_control = CMOS_READ(RTC_CONTROL);
+-		if (rtc_control & RTC_AIE) {
+-			cmos_rtc.suspend_ctrl &= ~RTC_AIE;
+-			CMOS_WRITE(rtc_control, RTC_CONTROL);
+-			rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
+-			rtc_update_irq(cmos->rtc, 1, rtc_intr);
+-		}
+-		spin_unlock_irqrestore(&rtc_lock, flags);
+-	}
+-
+-	pm_wakeup_hard_event(dev);
+-	acpi_clear_event(ACPI_EVENT_RTC);
+-	acpi_disable_event(ACPI_EVENT_RTC, 0);
+-	return ACPI_INTERRUPT_HANDLED;
+-}
+-
+-static inline void rtc_wake_setup(struct device *dev)
+-{
+-	if (acpi_disabled)
+-		return;
+-
+-	acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);
+-	/*
+-	 * After the RTC handler is installed, the Fixed_RTC event should
+-	 * be disabled. Only when the RTC alarm is set will it be enabled.
+-	 */
+-	acpi_clear_event(ACPI_EVENT_RTC);
+-	acpi_disable_event(ACPI_EVENT_RTC, 0);
+-}
+-
+-static void rtc_wake_on(struct device *dev)
+-{
+-	acpi_clear_event(ACPI_EVENT_RTC);
+-	acpi_enable_event(ACPI_EVENT_RTC, 0);
+-}
+-
+-static void rtc_wake_off(struct device *dev)
+-{
+-	acpi_disable_event(ACPI_EVENT_RTC, 0);
+-}
+-
+-#ifdef CONFIG_X86
+-/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
+-static void use_acpi_alarm_quirks(void)
+-{
+-	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+-		return;
+-
+-	if (!is_hpet_enabled())
+-		return;
+-
+-	if (dmi_get_bios_year() < 2015)
+-		return;
+-
+-	use_acpi_alarm = true;
+-}
+-#else
+-static inline void use_acpi_alarm_quirks(void) { }
+-#endif
+-
+-/* Every ACPI platform has a mc146818 compatible "cmos rtc".  Here we find
+- * its device node and pass extra config data.  This helps its driver use
+- * capabilities that the now-obsolete mc146818 didn't have, and informs it
+- * that this board's RTC is wakeup-capable (per ACPI spec).
+- */
+-static struct cmos_rtc_board_info acpi_rtc_info;
+-
+-static void cmos_wake_setup(struct device *dev)
+-{
+-	if (acpi_disabled)
+-		return;
+-
+-	use_acpi_alarm_quirks();
+-
+-	acpi_rtc_info.wake_on = rtc_wake_on;
+-	acpi_rtc_info.wake_off = rtc_wake_off;
+-
+-	/* workaround bug in some ACPI tables */
+-	if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
+-		dev_dbg(dev, "bogus FADT month_alarm (%d)\n",
+-			acpi_gbl_FADT.month_alarm);
+-		acpi_gbl_FADT.month_alarm = 0;
+-	}
+-
+-	acpi_rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
+-	acpi_rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
+-	acpi_rtc_info.rtc_century = acpi_gbl_FADT.century;
+-
+-	/* NOTE:  S4_RTC_WAKE is NOT currently useful to Linux */
+-	if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
+-		dev_info(dev, "RTC can wake from S4\n");
+-
+-	dev->platform_data = &acpi_rtc_info;
+-
+-	/* RTC always wakes from S1/S2/S3, and often S4/STD */
+-	device_init_wakeup(dev, 1);
+-}
+-
+-static void cmos_check_acpi_rtc_status(struct device *dev,
+-				       unsigned char *rtc_control)
+-{
+-	struct cmos_rtc *cmos = dev_get_drvdata(dev);
+-	acpi_event_status rtc_status;
+-	acpi_status status;
+-
+-	if (acpi_gbl_FADT.flags & ACPI_FADT_FIXED_RTC)
+-		return;
+-
+-	status = acpi_get_event_status(ACPI_EVENT_RTC, &rtc_status);
+-	if (ACPI_FAILURE(status)) {
+-		dev_err(dev, "Could not get RTC status\n");
+-	} else if (rtc_status & ACPI_EVENT_FLAG_SET) {
+-		unsigned char mask;
+-		*rtc_control &= ~RTC_AIE;
+-		CMOS_WRITE(*rtc_control, RTC_CONTROL);
+-		mask = CMOS_READ(RTC_INTR_FLAGS);
+-		rtc_update_irq(cmos->rtc, 1, mask);
+-	}
+-}
+-
+-#else
+-
+-static void cmos_wake_setup(struct device *dev)
+-{
+-}
+-
+-static void cmos_check_acpi_rtc_status(struct device *dev,
+-				       unsigned char *rtc_control)
+-{
+-}
+-
+-static void rtc_wake_setup(struct device *dev)
+-{
+-}
+-#endif
+-
+ #ifdef	CONFIG_PNP
+ 
+ #include <linux/pnp.h>
+ 
+ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+ {
+-	int irq, ret;
+-
+-	cmos_wake_setup(&pnp->dev);
++	int irq;
+ 
+ 	if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
+ 		irq = 0;
+@@ -1375,13 +1390,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+ 		irq = pnp_irq(pnp, 0);
+ 	}
+ 
+-	ret = cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
+-	if (ret)
+-		return ret;
+-
+-	rtc_wake_setup(&pnp->dev);
+-
+-	return 0;
++	return cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
+ }
+ 
+ static void cmos_pnp_remove(struct pnp_dev *pnp)
+@@ -1465,10 +1474,9 @@ static inline void cmos_of_init(struct platform_device *pdev) {}
+ static int __init cmos_platform_probe(struct platform_device *pdev)
+ {
+ 	struct resource *resource;
+-	int irq, ret;
++	int irq;
+ 
+ 	cmos_of_init(pdev);
+-	cmos_wake_setup(&pdev->dev);
+ 
+ 	if (RTC_IOMAPPED)
+ 		resource = platform_get_resource(pdev, IORESOURCE_IO, 0);
+@@ -1478,13 +1486,7 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
+ 	if (irq < 0)
+ 		irq = -1;
+ 
+-	ret = cmos_do_probe(&pdev->dev, resource, irq);
+-	if (ret)
+-		return ret;
+-
+-	rtc_wake_setup(&pdev->dev);
+-
+-	return 0;
++	return cmos_do_probe(&pdev->dev, resource, irq);
+ }
+ 
+ static int cmos_platform_remove(struct platform_device *pdev)
+diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c
+index 5e03834016294..f6d2ad91ff7a9 100644
+--- a/drivers/rtc/rtc-mxc_v2.c
++++ b/drivers/rtc/rtc-mxc_v2.c
+@@ -336,8 +336,10 @@ static int mxc_rtc_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
+-	if (IS_ERR(pdata->rtc))
++	if (IS_ERR(pdata->rtc)) {
++		clk_disable_unprepare(pdata->clk);
+ 		return PTR_ERR(pdata->rtc);
++	}
+ 
+ 	pdata->rtc->ops = &mxc_rtc_ops;
+ 	pdata->rtc->range_max = U32_MAX;
+diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c
+index 095891999da11..754e03984f986 100644
+--- a/drivers/rtc/rtc-pcf85063.c
++++ b/drivers/rtc/rtc-pcf85063.c
+@@ -169,10 +169,10 @@ static int pcf85063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+ 	if (ret)
+ 		return ret;
+ 
+-	alrm->time.tm_sec = bcd2bin(buf[0]);
+-	alrm->time.tm_min = bcd2bin(buf[1]);
+-	alrm->time.tm_hour = bcd2bin(buf[2]);
+-	alrm->time.tm_mday = bcd2bin(buf[3]);
++	alrm->time.tm_sec = bcd2bin(buf[0] & 0x7f);
++	alrm->time.tm_min = bcd2bin(buf[1] & 0x7f);
++	alrm->time.tm_hour = bcd2bin(buf[2] & 0x3f);
++	alrm->time.tm_mday = bcd2bin(buf[3] & 0x3f);
+ 
+ 	ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &val);
+ 	if (ret)
+@@ -424,7 +424,7 @@ static int pcf85063_clkout_control(struct clk_hw *hw, bool enable)
+ 	unsigned int buf;
+ 	int ret;
+ 
+-	ret = regmap_read(pcf85063->regmap, PCF85063_REG_OFFSET, &buf);
++	ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &buf);
+ 	if (ret < 0)
+ 		return ret;
+ 	buf &= PCF85063_REG_CLKO_F_MASK;
+diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c
+index 7fb9145c43bd5..fa351ac201587 100644
+--- a/drivers/rtc/rtc-pic32.c
++++ b/drivers/rtc/rtc-pic32.c
+@@ -324,16 +324,16 @@ static int pic32_rtc_probe(struct platform_device *pdev)
+ 
+ 	spin_lock_init(&pdata->alarm_lock);
+ 
++	pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
++	if (IS_ERR(pdata->rtc))
++		return PTR_ERR(pdata->rtc);
++
+ 	clk_prepare_enable(pdata->clk);
+ 
+ 	pic32_rtc_enable(pdata, 1);
+ 
+ 	device_init_wakeup(&pdev->dev, 1);
+ 
+-	pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
+-	if (IS_ERR(pdata->rtc))
+-		return PTR_ERR(pdata->rtc);
+-
+ 	pdata->rtc->ops = &pic32_rtcops;
+ 	pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+ 	pdata->rtc->range_max = RTC_TIMESTAMP_END_2099;
+diff --git a/drivers/rtc/rtc-rzn1.c b/drivers/rtc/rtc-rzn1.c
+index ac788799c8e3e..0d36bc50197c1 100644
+--- a/drivers/rtc/rtc-rzn1.c
++++ b/drivers/rtc/rtc-rzn1.c
+@@ -355,7 +355,9 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
+ 	set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtcdev->features);
+ 	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtcdev->features);
+ 
+-	devm_pm_runtime_enable(&pdev->dev);
++	ret = devm_pm_runtime_enable(&pdev->dev);
++	if (ret < 0)
++		return ret;
+ 	ret = pm_runtime_resume_and_get(&pdev->dev);
+ 	if (ret < 0)
+ 		return ret;
+diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
+index bd929b0e7d7de..d82acf1af1fae 100644
+--- a/drivers/rtc/rtc-snvs.c
++++ b/drivers/rtc/rtc-snvs.c
+@@ -32,6 +32,14 @@
+ #define SNVS_LPPGDR_INIT	0x41736166
+ #define CNTR_TO_SECS_SH		15
+ 
++/* The maximum RTC clock cycles that are allowed to pass between two
++ * consecutive clock counter register reads. If the values are corrupted a
++ * bigger difference is expected. The RTC frequency is 32kHz. With 320 cycles
++ * we end at 10ms which should be enough for most cases. If it once takes
++ * longer than expected we do a retry.
++ */
++#define MAX_RTC_READ_DIFF_CYCLES	320
++
+ struct snvs_rtc_data {
+ 	struct rtc_device *rtc;
+ 	struct regmap *regmap;
+@@ -56,6 +64,7 @@ static u64 rtc_read_lpsrt(struct snvs_rtc_data *data)
+ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
+ {
+ 	u64 read1, read2;
++	s64 diff;
+ 	unsigned int timeout = 100;
+ 
+ 	/* As expected, the registers might update between the read of the LSB
+@@ -66,7 +75,8 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
+ 	do {
+ 		read2 = read1;
+ 		read1 = rtc_read_lpsrt(data);
+-	} while (read1 != read2 && --timeout);
++		diff = read1 - read2;
++	} while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout);
+ 	if (!timeout)
+ 		dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
+ 
+@@ -78,13 +88,15 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data)
+ static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb)
+ {
+ 	u32 count1, count2;
++	s32 diff;
+ 	unsigned int timeout = 100;
+ 
+ 	regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
+ 	do {
+ 		count2 = count1;
+ 		regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1);
+-	} while (count1 != count2 && --timeout);
++		diff = count1 - count2;
++	} while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout);
+ 	if (!timeout) {
+ 		dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n");
+ 		return -ETIMEDOUT;
+diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c
+index bdb20f63254e2..0f8e4231098ef 100644
+--- a/drivers/rtc/rtc-st-lpc.c
++++ b/drivers/rtc/rtc-st-lpc.c
+@@ -238,6 +238,7 @@ static int st_rtc_probe(struct platform_device *pdev)
+ 
+ 	rtc->clkrate = clk_get_rate(rtc->clk);
+ 	if (!rtc->clkrate) {
++		clk_disable_unprepare(rtc->clk);
+ 		dev_err(&pdev->dev, "Unable to fetch clock rate\n");
+ 		return -EINVAL;
+ 	}
+diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
+index e0fdd54bfeb70..f672c610cb24a 100644
+--- a/drivers/s390/net/ctcm_main.c
++++ b/drivers/s390/net/ctcm_main.c
+@@ -825,16 +825,9 @@ done:
+ /*
+  * Start transmission of a packet.
+  * Called from generic network device layer.
+- *
+- *  skb		Pointer to buffer containing the packet.
+- *  dev		Pointer to interface struct.
+- *
+- * returns 0 if packet consumed, !0 if packet rejected.
+- *         Note: If we return !0, then the packet is free'd by
+- *               the generic network layer.
+  */
+ /* first merge version - leaving both functions separated */
+-static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t ctcm_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct ctcm_priv *priv = dev->ml_priv;
+ 
+@@ -877,7 +870,7 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
+ }
+ 
+ /* unmerged MPC variant of ctcm_tx */
+-static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t ctcmpc_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	int len = 0;
+ 	struct ctcm_priv *priv = dev->ml_priv;
+diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
+index 84c8981317b46..38f312664ce72 100644
+--- a/drivers/s390/net/lcs.c
++++ b/drivers/s390/net/lcs.c
+@@ -1519,9 +1519,8 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer)
+ /*
+  * Packet transmit function called by network stack
+  */
+-static int
+-__lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
+-		 struct net_device *dev)
++static netdev_tx_t __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
++				    struct net_device *dev)
+ {
+ 	struct lcs_header *header;
+ 	int rc = NETDEV_TX_OK;
+@@ -1582,8 +1581,7 @@ out:
+ 	return rc;
+ }
+ 
+-static int
+-lcs_start_xmit(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t lcs_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct lcs_card *card;
+ 	int rc;
+diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
+index 65aa0a96c21de..66076cada8ae4 100644
+--- a/drivers/s390/net/netiucv.c
++++ b/drivers/s390/net/netiucv.c
+@@ -1248,15 +1248,8 @@ static int netiucv_close(struct net_device *dev)
+ /*
+  * Start transmission of a packet.
+  * Called from generic network device layer.
+- *
+- * @param skb Pointer to buffer containing the packet.
+- * @param dev Pointer to interface struct.
+- *
+- * @return 0 if packet consumed, !0 if packet rejected.
+- *         Note: If we return !0, then the packet is free'd by
+- *               the generic network layer.
+  */
+-static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
++static netdev_tx_t netiucv_tx(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct netiucv_priv *privptr = netdev_priv(dev);
+ 	int rc;
+diff --git a/drivers/scsi/elx/efct/efct_driver.c b/drivers/scsi/elx/efct/efct_driver.c
+index b08fc8839808d..49fd2cfed70c7 100644
+--- a/drivers/scsi/elx/efct/efct_driver.c
++++ b/drivers/scsi/elx/efct/efct_driver.c
+@@ -42,6 +42,7 @@ efct_device_init(void)
+ 
+ 	rc = efct_scsi_reg_fc_transport();
+ 	if (rc) {
++		efct_scsi_tgt_driver_exit();
+ 		pr_err("failed to register to FC host\n");
+ 		return rc;
+ 	}
+diff --git a/drivers/scsi/elx/libefc/efclib.h b/drivers/scsi/elx/libefc/efclib.h
+index dde20891c2dd7..57e3386128127 100644
+--- a/drivers/scsi/elx/libefc/efclib.h
++++ b/drivers/scsi/elx/libefc/efclib.h
+@@ -58,10 +58,12 @@ enum efc_node_send_ls_acc {
+ #define EFC_LINK_STATUS_UP		0
+ #define EFC_LINK_STATUS_DOWN		1
+ 
++enum efc_sm_event;
++
+ /* State machine context header  */
+ struct efc_sm_ctx {
+ 	void (*current_state)(struct efc_sm_ctx *ctx,
+-			      u32 evt, void *arg);
++			      enum efc_sm_event evt, void *arg);
+ 
+ 	const char	*description;
+ 	void		*app;
+@@ -365,7 +367,7 @@ struct efc_node {
+ 	int			prev_evt;
+ 
+ 	void (*nodedb_state)(struct efc_sm_ctx *ctx,
+-			     u32 evt, void *arg);
++			     enum efc_sm_event evt, void *arg);
+ 	struct timer_list	gidpt_delay_timer;
+ 	u64			time_last_gidpt_msec;
+ 
+diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
+index 6ec296321ffc1..38774a272e627 100644
+--- a/drivers/scsi/fcoe/fcoe.c
++++ b/drivers/scsi/fcoe/fcoe.c
+@@ -2491,6 +2491,7 @@ static int __init fcoe_init(void)
+ 
+ out_free:
+ 	mutex_unlock(&fcoe_config_mutex);
++	fcoe_transport_detach(&fcoe_sw_transport);
+ out_destroy:
+ 	destroy_workqueue(fcoe_wq);
+ 	return rc;
+diff --git a/drivers/scsi/fcoe/fcoe_sysfs.c b/drivers/scsi/fcoe/fcoe_sysfs.c
+index af658aa38fedf..6260aa5ea6af8 100644
+--- a/drivers/scsi/fcoe/fcoe_sysfs.c
++++ b/drivers/scsi/fcoe/fcoe_sysfs.c
+@@ -830,14 +830,15 @@ struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent,
+ 
+ 	dev_set_name(&ctlr->dev, "ctlr_%d", ctlr->id);
+ 	error = device_register(&ctlr->dev);
+-	if (error)
+-		goto out_del_q2;
++	if (error) {
++		destroy_workqueue(ctlr->devloss_work_q);
++		destroy_workqueue(ctlr->work_q);
++		put_device(&ctlr->dev);
++		return NULL;
++	}
+ 
+ 	return ctlr;
+ 
+-out_del_q2:
+-	destroy_workqueue(ctlr->devloss_work_q);
+-	ctlr->devloss_work_q = NULL;
+ out_del_q:
+ 	destroy_workqueue(ctlr->work_q);
+ 	ctlr->work_q = NULL;
+@@ -1036,16 +1037,16 @@ struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *ctlr,
+ 	fcf->selected = new_fcf->selected;
+ 
+ 	error = device_register(&fcf->dev);
+-	if (error)
+-		goto out_del;
++	if (error) {
++		put_device(&fcf->dev);
++		goto out;
++	}
+ 
+ 	fcf->state = FCOE_FCF_STATE_CONNECTED;
+ 	list_add_tail(&fcf->peers, &ctlr->fcfs);
+ 
+ 	return fcf;
+ 
+-out_del:
+-	kfree(fcf);
+ out:
+ 	return NULL;
+ }
+diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
+index 33af5b8dede20..f4f9e5abee76d 100644
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1701,13 +1701,15 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
+ 		return rc;
+ 	}
+ 
++	/* Remote phy */
+ 	if (rc)
+ 		return rc;
+ 
+-	/* Remote phy */
+ 	if (dev_is_sata(device)) {
+-		rc = sas_ata_wait_after_reset(device,
+-					HISI_SAS_WAIT_PHYUP_TIMEOUT);
++		struct ata_link *link = &device->sata_dev.ap->link;
++
++		rc = ata_wait_after_reset(link, HISI_SAS_WAIT_PHYUP_TIMEOUT,
++					  smp_ata_check_ready_type);
+ 	} else {
+ 		msleep(2000);
+ 	}
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index a47bcce3c9c78..796bc7aa6c8e4 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -8929,7 +8929,7 @@ clean1:	/* wq/aer/h */
+ 		destroy_workqueue(h->monitor_ctlr_wq);
+ 		h->monitor_ctlr_wq = NULL;
+ 	}
+-	kfree(h);
++	hpda_free_ctlr_info(h);
+ 	return rc;
+ }
+ 
+@@ -9790,7 +9790,8 @@ static int hpsa_add_sas_host(struct ctlr_info *h)
+ 	return 0;
+ 
+ free_sas_phy:
+-	hpsa_free_sas_phy(hpsa_sas_phy);
++	sas_phy_free(hpsa_sas_phy->phy);
++	kfree(hpsa_sas_phy);
+ free_sas_port:
+ 	hpsa_free_sas_port(hpsa_sas_port);
+ free_sas_node:
+@@ -9826,10 +9827,12 @@ static int hpsa_add_sas_device(struct hpsa_sas_node *hpsa_sas_node,
+ 
+ 	rc = hpsa_sas_port_add_rphy(hpsa_sas_port, rphy);
+ 	if (rc)
+-		goto free_sas_port;
++		goto free_sas_rphy;
+ 
+ 	return 0;
+ 
++free_sas_rphy:
++	sas_rphy_free(rphy);
+ free_sas_port:
+ 	hpsa_free_sas_port(hpsa_sas_port);
+ 	device->sas_port = NULL;
+diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
+index 9d01a3e3c26aa..2022ffb450417 100644
+--- a/drivers/scsi/ipr.c
++++ b/drivers/scsi/ipr.c
+@@ -10872,11 +10872,19 @@ static struct notifier_block ipr_notifier = {
+  **/
+ static int __init ipr_init(void)
+ {
++	int rc;
++
+ 	ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n",
+ 		 IPR_DRIVER_VERSION, IPR_DRIVER_DATE);
+ 
+ 	register_reboot_notifier(&ipr_notifier);
+-	return pci_register_driver(&ipr_driver);
++	rc = pci_register_driver(&ipr_driver);
++	if (rc) {
++		unregister_reboot_notifier(&ipr_notifier);
++		return rc;
++	}
++
++	return 0;
+ }
+ 
+ /**
+diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
+index d35c9296f7388..2fd55ef9ffca5 100644
+--- a/drivers/scsi/libsas/sas_ata.c
++++ b/drivers/scsi/libsas/sas_ata.c
+@@ -287,6 +287,31 @@ static int sas_ata_clear_pending(struct domain_device *dev, struct ex_phy *phy)
+ 		return 1;
+ }
+ 
++int smp_ata_check_ready_type(struct ata_link *link)
++{
++	struct domain_device *dev = link->ap->private_data;
++	struct sas_phy *phy = sas_get_local_phy(dev);
++	struct domain_device *ex_dev = dev->parent;
++	enum sas_device_type type = SAS_PHY_UNUSED;
++	u8 sas_addr[SAS_ADDR_SIZE];
++	int res;
++
++	res = sas_get_phy_attached_dev(ex_dev, phy->number, sas_addr, &type);
++	sas_put_local_phy(phy);
++	if (res)
++		return res;
++
++	switch (type) {
++	case SAS_SATA_PENDING:
++		return 0;
++	case SAS_END_DEVICE:
++		return 1;
++	default:
++		return -ENODEV;
++	}
++}
++EXPORT_SYMBOL_GPL(smp_ata_check_ready_type);
++
+ static int smp_ata_check_ready(struct ata_link *link)
+ {
+ 	int res;
+diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
+index 5ce2518301040..63a23251fb1d8 100644
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -1693,8 +1693,8 @@ static int sas_get_phy_change_count(struct domain_device *dev,
+ 	return res;
+ }
+ 
+-static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
+-				    u8 *sas_addr, enum sas_device_type *type)
++int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
++			     u8 *sas_addr, enum sas_device_type *type)
+ {
+ 	int res;
+ 	struct smp_disc_resp *disc_resp;
+diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
+index 8d0ad3abc7b5c..a94bd0790b055 100644
+--- a/drivers/scsi/libsas/sas_internal.h
++++ b/drivers/scsi/libsas/sas_internal.h
+@@ -84,6 +84,8 @@ struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id);
+ int sas_ex_phy_discover(struct domain_device *dev, int single);
+ int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
+ 			    struct smp_rps_resp *rps_resp);
++int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
++			     u8 *sas_addr, enum sas_device_type *type);
+ int sas_try_ata_reset(struct asd_sas_phy *phy);
+ void sas_hae_reset(struct work_struct *work);
+ 
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 03c21167fc854..c4960da4c1c40 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -8076,10 +8076,10 @@ u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
+ 					"IO_cnt", "Info", "BWutil(ms)");
+ 	}
+ 
+-	/* Needs to be _bh because record is called from timer interrupt
++	/* Needs to be _irq because record is called from timer interrupt
+ 	 * context
+ 	 */
+-	spin_lock_bh(ring_lock);
++	spin_lock_irq(ring_lock);
+ 	while (*head_idx != *tail_idx) {
+ 		entry = &ring[*head_idx];
+ 
+@@ -8123,7 +8123,7 @@ u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
+ 		if (cnt >= max_read_entries)
+ 			break;
+ 	}
+-	spin_unlock_bh(ring_lock);
++	spin_unlock_irq(ring_lock);
+ 
+ 	return cnt;
+ }
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c
+index 0681daee6c149..e5ecd6ada6cdd 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
+@@ -829,6 +829,8 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle,
+ 	if ((sas_rphy_add(rphy))) {
+ 		ioc_err(ioc, "failure at %s:%d/%s()!\n",
+ 			__FILE__, __LINE__, __func__);
++		sas_rphy_free(rphy);
++		rphy = NULL;
+ 	}
+ 
+ 	if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) {
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index 3ec6a200942ee..01ca440ce6203 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -5129,17 +5129,17 @@ struct secure_flash_update_block_pk {
+ 		(test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || \
+ 			 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags))
+ 
+-#define QLA_VHA_MARK_BUSY(__vha, __bail) do {		\
+-	atomic_inc(&__vha->vref_count);			\
+-	mb();						\
+-	if (__vha->flags.delete_progress) {		\
+-		atomic_dec(&__vha->vref_count);		\
+-		wake_up(&__vha->vref_waitq);		\
+-		__bail = 1;				\
+-	} else {					\
+-		__bail = 0;				\
+-	}						\
+-} while (0)
++static inline bool qla_vha_mark_busy(scsi_qla_host_t *vha)
++{
++	atomic_inc(&vha->vref_count);
++	mb();
++	if (vha->flags.delete_progress) {
++		atomic_dec(&vha->vref_count);
++		wake_up(&vha->vref_waitq);
++		return true;
++	}
++	return false;
++}
+ 
+ #define QLA_VHA_MARK_NOT_BUSY(__vha) do {		\
+ 	atomic_dec(&__vha->vref_count);			\
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index e7fe0e52c11d4..97cf9c25adf09 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -110,6 +110,7 @@ static void qla24xx_abort_iocb_timeout(void *data)
+ 	struct qla_qpair *qpair = sp->qpair;
+ 	u32 handle;
+ 	unsigned long flags;
++	int sp_found = 0, cmdsp_found = 0;
+ 
+ 	if (sp->cmd_sp)
+ 		ql_dbg(ql_dbg_async, sp->vha, 0x507c,
+@@ -124,18 +125,21 @@ static void qla24xx_abort_iocb_timeout(void *data)
+ 	spin_lock_irqsave(qpair->qp_lock_ptr, flags);
+ 	for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
+ 		if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] ==
+-		    sp->cmd_sp))
++		    sp->cmd_sp)) {
+ 			qpair->req->outstanding_cmds[handle] = NULL;
++			cmdsp_found = 1;
++		}
+ 
+ 		/* removing the abort */
+ 		if (qpair->req->outstanding_cmds[handle] == sp) {
+ 			qpair->req->outstanding_cmds[handle] = NULL;
++			sp_found = 1;
+ 			break;
+ 		}
+ 	}
+ 	spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
+ 
+-	if (sp->cmd_sp) {
++	if (cmdsp_found && sp->cmd_sp) {
+ 		/*
+ 		 * This done function should take care of
+ 		 * original command ref: INIT
+@@ -143,8 +147,10 @@ static void qla24xx_abort_iocb_timeout(void *data)
+ 		sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
+ 	}
+ 
+-	abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
+-	sp->done(sp, QLA_OS_TIMER_EXPIRED);
++	if (sp_found) {
++		abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
++		sp->done(sp, QLA_OS_TIMER_EXPIRED);
++	}
+ }
+ 
+ static void qla24xx_abort_sp_done(srb_t *sp, int res)
+@@ -168,7 +174,6 @@ int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
+ 	struct srb_iocb *abt_iocb;
+ 	srb_t *sp;
+ 	int rval = QLA_FUNCTION_FAILED;
+-	uint8_t bail;
+ 
+ 	/* ref: INIT for ABTS command */
+ 	sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport,
+@@ -176,7 +181,7 @@ int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
+ 	if (!sp)
+ 		return QLA_MEMORY_ALLOC_FAILED;
+ 
+-	QLA_VHA_MARK_BUSY(vha, bail);
++	qla_vha_mark_busy(vha);
+ 	abt_iocb = &sp->u.iocb_cmd;
+ 	sp->type = SRB_ABT_CMD;
+ 	sp->name = "abort";
+@@ -2020,14 +2025,13 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
+ 	struct srb_iocb *tm_iocb;
+ 	srb_t *sp;
+ 	int rval = QLA_FUNCTION_FAILED;
+-	uint8_t bail;
+ 
+ 	/* ref: INIT */
+ 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
+ 	if (!sp)
+ 		goto done;
+ 
+-	QLA_VHA_MARK_BUSY(vha, bail);
++	qla_vha_mark_busy(vha);
+ 	sp->type = SRB_TM_CMD;
+ 	sp->name = "tmf";
+ 	qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha),
+diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
+index db17f7f410cdd..5185dc5daf80d 100644
+--- a/drivers/scsi/qla2xxx/qla_inline.h
++++ b/drivers/scsi/qla2xxx/qla_inline.h
+@@ -225,11 +225,9 @@ static inline srb_t *
+ qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag)
+ {
+ 	srb_t *sp = NULL;
+-	uint8_t bail;
+ 	struct qla_qpair *qpair;
+ 
+-	QLA_VHA_MARK_BUSY(vha, bail);
+-	if (unlikely(bail))
++	if (unlikely(qla_vha_mark_busy(vha)))
+ 		return NULL;
+ 
+ 	qpair = vha->hw->base_qpair;
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 1c7fb6484db20..5e5d1a6c51d52 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -5039,13 +5039,11 @@ struct qla_work_evt *
+ qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type)
+ {
+ 	struct qla_work_evt *e;
+-	uint8_t bail;
+ 
+ 	if (test_bit(UNLOADING, &vha->dpc_flags))
+ 		return NULL;
+ 
+-	QLA_VHA_MARK_BUSY(vha, bail);
+-	if (bail)
++	if (qla_vha_mark_busy(vha))
+ 		return NULL;
+ 
+ 	e = kzalloc(sizeof(struct qla_work_evt), GFP_ATOMIC);
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index 7346098c1c68f..34eb0a9355bca 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -3785,7 +3785,7 @@ static int resp_write_scat(struct scsi_cmnd *scp,
+ 		mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0);
+ 		return illegal_condition_result;
+ 	}
+-	lrdp = kzalloc(lbdof_blen, GFP_ATOMIC);
++	lrdp = kzalloc(lbdof_blen, GFP_ATOMIC | __GFP_NOWARN);
+ 	if (lrdp == NULL)
+ 		return SCSI_MLQUEUE_HOST_BUSY;
+ 	if (sdebug_verbose)
+@@ -4436,7 +4436,7 @@ static int resp_verify(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
+ 	if (ret)
+ 		return ret;
+ 
+-	arr = kcalloc(lb_size, vnum, GFP_ATOMIC);
++	arr = kcalloc(lb_size, vnum, GFP_ATOMIC | __GFP_NOWARN);
+ 	if (!arr) {
+ 		mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC,
+ 				INSUFF_RES_ASCQ);
+@@ -4504,7 +4504,7 @@ static int resp_report_zones(struct scsi_cmnd *scp,
+ 
+ 	rep_max_zones = (alloc_len - 64) >> ilog2(RZONES_DESC_HD);
+ 
+-	arr = kzalloc(alloc_len, GFP_ATOMIC);
++	arr = kzalloc(alloc_len, GFP_ATOMIC | __GFP_NOWARN);
+ 	if (!arr) {
+ 		mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC,
+ 				INSUFF_RES_ASCQ);
+@@ -7340,7 +7340,10 @@ clean:
+ 		kfree(sdbg_devinfo->zstate);
+ 		kfree(sdbg_devinfo);
+ 	}
+-	kfree(sdbg_host);
++	if (sdbg_host->dev.release)
++		put_device(&sdbg_host->dev);
++	else
++		kfree(sdbg_host);
+ 	pr_warn("%s: failed, errno=%d\n", __func__, -error);
+ 	return error;
+ }
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index 448748e3fba5e..f00212777f82c 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -342,19 +342,11 @@ enum blk_eh_timer_return scsi_timeout(struct request *req)
+ 
+ 	if (rtn == BLK_EH_DONE) {
+ 		/*
+-		 * Set the command to complete first in order to prevent a real
+-		 * completion from releasing the command while error handling
+-		 * is using it. If the command was already completed, then the
+-		 * lower level driver beat the timeout handler, and it is safe
+-		 * to return without escalating error recovery.
+-		 *
+-		 * If timeout handling lost the race to a real completion, the
+-		 * block layer may ignore that due to a fake timeout injection,
+-		 * so return RESET_TIMER to allow error handling another shot
+-		 * at this command.
++		 * If scsi_done() has already set SCMD_STATE_COMPLETE, do not
++		 * modify *scmd.
+ 		 */
+ 		if (test_and_set_bit(SCMD_STATE_COMPLETE, &scmd->state))
+-			return BLK_EH_RESET_TIMER;
++			return BLK_EH_DONE;
+ 		if (scsi_abort_command(scmd) != SUCCESS) {
+ 			set_host_byte(scmd, DID_TIME_OUT);
+ 			scsi_eh_scmd_add(scmd);
+diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
+index e550b12e525a1..c8235f15728bb 100644
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -1130,7 +1130,7 @@ struct pqi_scsi_dev {
+ 	u8	phy_id;
+ 	u8	ncq_prio_enable;
+ 	u8	ncq_prio_support;
+-	u8	multi_lun_device_lun_count;
++	u8	lun_count;
+ 	bool	raid_bypass_configured;	/* RAID bypass configured */
+ 	bool	raid_bypass_enabled;	/* RAID bypass enabled */
+ 	u32	next_bypass_group[RAID_MAP_MAX_DATA_DISKS_PER_ROW];
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 7a8c2c75acbaf..e011d82172d53 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -1610,9 +1610,7 @@ static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info,
+ 		&id_phys->alternate_paths_phys_connector,
+ 		sizeof(device->phys_connector));
+ 	device->bay = id_phys->phys_bay_in_box;
+-	device->multi_lun_device_lun_count = id_phys->multi_lun_device_lun_count;
+-	if (!device->multi_lun_device_lun_count)
+-		device->multi_lun_device_lun_count = 1;
++	device->lun_count = id_phys->multi_lun_device_lun_count;
+ 	if ((id_phys->even_more_flags & PQI_DEVICE_PHY_MAP_SUPPORTED) &&
+ 		id_phys->phy_count)
+ 		device->phy_id =
+@@ -1746,7 +1744,7 @@ out:
+ 	return offline;
+ }
+ 
+-static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
++static int pqi_get_device_info_phys_logical(struct pqi_ctrl_info *ctrl_info,
+ 	struct pqi_scsi_dev *device,
+ 	struct bmic_identify_physical_device *id_phys)
+ {
+@@ -1763,6 +1761,20 @@ static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
+ 	return rc;
+ }
+ 
++static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
++	struct pqi_scsi_dev *device,
++	struct bmic_identify_physical_device *id_phys)
++{
++	int rc;
++
++	rc = pqi_get_device_info_phys_logical(ctrl_info, device, id_phys);
++
++	if (rc == 0 && device->lun_count == 0)
++		device->lun_count = 1;
++
++	return rc;
++}
++
+ static void pqi_show_volume_status(struct pqi_ctrl_info *ctrl_info,
+ 	struct pqi_scsi_dev *device)
+ {
+@@ -1897,7 +1909,7 @@ static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, struct pqi
+ 	int rc;
+ 	int lun;
+ 
+-	for (lun = 0; lun < device->multi_lun_device_lun_count; lun++) {
++	for (lun = 0; lun < device->lun_count; lun++) {
+ 		rc = pqi_device_wait_for_pending_io(ctrl_info, device, lun,
+ 			PQI_REMOVE_DEVICE_PENDING_IO_TIMEOUT_MSECS);
+ 		if (rc)
+@@ -2076,6 +2088,7 @@ static void pqi_scsi_update_device(struct pqi_ctrl_info *ctrl_info,
+ 	existing_device->sas_address = new_device->sas_address;
+ 	existing_device->queue_depth = new_device->queue_depth;
+ 	existing_device->device_offline = false;
++	existing_device->lun_count = new_device->lun_count;
+ 
+ 	if (pqi_is_logical_device(existing_device)) {
+ 		existing_device->is_external_raid_device = new_device->is_external_raid_device;
+@@ -2108,10 +2121,6 @@ static void pqi_scsi_update_device(struct pqi_ctrl_info *ctrl_info,
+ 		existing_device->phy_connected_dev_type = new_device->phy_connected_dev_type;
+ 		memcpy(existing_device->box, new_device->box, sizeof(existing_device->box));
+ 		memcpy(existing_device->phys_connector, new_device->phys_connector, sizeof(existing_device->phys_connector));
+-
+-		existing_device->multi_lun_device_lun_count = new_device->multi_lun_device_lun_count;
+-		if (existing_device->multi_lun_device_lun_count == 0)
+-			existing_device->multi_lun_device_lun_count = 1;
+ 	}
+ }
+ 
+@@ -6484,6 +6493,12 @@ static void pqi_slave_destroy(struct scsi_device *sdev)
+ 		return;
+ 	}
+ 
++	device->lun_count--;
++	if (device->lun_count > 0) {
++		mutex_unlock(&ctrl_info->scan_mutex);
++		return;
++	}
++
+ 	spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
+ 	list_del(&device->scsi_device_list_entry);
+ 	spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+@@ -9302,6 +9317,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 			       0x193d, 0x1109)
+ 	},
++	{
++		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++			       0x193d, 0x110b)
++	},
+ 	{
+ 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 			       0x193d, 0x8460)
+@@ -9402,6 +9421,22 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 			       0x1bd4, 0x0072)
+ 	},
++	{
++		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++			       0x1bd4, 0x0086)
++	},
++	{
++		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++			       0x1bd4, 0x0087)
++	},
++	{
++		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++			       0x1bd4, 0x0088)
++	},
++	{
++		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++			       0x1bd4, 0x0089)
++	},
+ 	{
+ 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 			       0x19e5, 0xd227)
+@@ -9650,6 +9685,10 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 			       PCI_VENDOR_ID_ADAPTEC2, 0x1474)
+ 	},
++	{
++		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++			       PCI_VENDOR_ID_ADAPTEC2, 0x1475)
++	},
+ 	{
+ 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 			       PCI_VENDOR_ID_ADAPTEC2, 0x1480)
+@@ -9706,6 +9745,14 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 			       PCI_VENDOR_ID_ADAPTEC2, 0x14c2)
+ 	},
++	{
++		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++			       PCI_VENDOR_ID_ADAPTEC2, 0x14c3)
++	},
++	{
++		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++			       PCI_VENDOR_ID_ADAPTEC2, 0x14c4)
++	},
+ 	{
+ 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 			       PCI_VENDOR_ID_ADAPTEC2, 0x14d0)
+@@ -9942,6 +9989,18 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 			       PCI_VENDOR_ID_LENOVO, 0x0623)
+ 	},
++	{
++		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++				0x1e93, 0x1000)
++	},
++	{
++		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++				0x1e93, 0x1001)
++	},
++	{
++		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++				0x1e93, 0x1002)
++	},
+ 	{
+ 		PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 			       PCI_ANY_ID, PCI_ANY_ID)
+diff --git a/drivers/scsi/snic/snic_disc.c b/drivers/scsi/snic/snic_disc.c
+index 9b2b5f8c23b9a..8fbf3c1b1311d 100644
+--- a/drivers/scsi/snic/snic_disc.c
++++ b/drivers/scsi/snic/snic_disc.c
+@@ -304,6 +304,9 @@ snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid)
+ 			      ret);
+ 
+ 		put_device(&snic->shost->shost_gendev);
++		spin_lock_irqsave(snic->shost->host_lock, flags);
++		list_del(&tgt->list);
++		spin_unlock_irqrestore(snic->shost->host_lock, flags);
+ 		kfree(tgt);
+ 		tgt = NULL;
+ 
+diff --git a/drivers/soc/apple/rtkit.c b/drivers/soc/apple/rtkit.c
+index cf1129e9f76b1..d9329b4d8e1b8 100644
+--- a/drivers/soc/apple/rtkit.c
++++ b/drivers/soc/apple/rtkit.c
+@@ -920,8 +920,10 @@ int apple_rtkit_wake(struct apple_rtkit *rtk)
+ }
+ EXPORT_SYMBOL_GPL(apple_rtkit_wake);
+ 
+-static void apple_rtkit_free(struct apple_rtkit *rtk)
++static void apple_rtkit_free(void *data)
+ {
++	struct apple_rtkit *rtk = data;
++
+ 	mbox_free_channel(rtk->mbox_chan);
+ 	destroy_workqueue(rtk->wq);
+ 
+@@ -944,8 +946,7 @@ struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie,
+ 	if (IS_ERR(rtk))
+ 		return rtk;
+ 
+-	ret = devm_add_action_or_reset(dev, (void (*)(void *))apple_rtkit_free,
+-				       rtk);
++	ret = devm_add_action_or_reset(dev, apple_rtkit_free, rtk);
+ 	if (ret)
+ 		return ERR_PTR(ret);
+ 
+diff --git a/drivers/soc/apple/sart.c b/drivers/soc/apple/sart.c
+index 83804b16ad03d..afa1117368997 100644
+--- a/drivers/soc/apple/sart.c
++++ b/drivers/soc/apple/sart.c
+@@ -164,6 +164,11 @@ static int apple_sart_probe(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
++static void apple_sart_put_device(void *dev)
++{
++	put_device(dev);
++}
++
+ struct apple_sart *devm_apple_sart_get(struct device *dev)
+ {
+ 	struct device_node *sart_node;
+@@ -187,7 +192,7 @@ struct apple_sart *devm_apple_sart_get(struct device *dev)
+ 		return ERR_PTR(-EPROBE_DEFER);
+ 	}
+ 
+-	ret = devm_add_action_or_reset(dev, (void (*)(void *))put_device,
++	ret = devm_add_action_or_reset(dev, apple_sart_put_device,
+ 				       &sart_pdev->dev);
+ 	if (ret)
+ 		return ERR_PTR(ret);
+diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c
+index 9734f1091c695..4b2046c37e6f6 100644
+--- a/drivers/soc/mediatek/mtk-pm-domains.c
++++ b/drivers/soc/mediatek/mtk-pm-domains.c
+@@ -275,9 +275,9 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
+ 	clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks);
+ 
+ 	/* subsys power off */
+-	regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
+ 	regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT);
+ 	regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT);
++	regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
+ 	regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT);
+ 	regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
+ 
+diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c
+index b4046f393575e..cd44f17dad3d0 100644
+--- a/drivers/soc/qcom/apr.c
++++ b/drivers/soc/qcom/apr.c
+@@ -454,11 +454,19 @@ static int apr_add_device(struct device *dev, struct device_node *np,
+ 	adev->dev.driver = NULL;
+ 
+ 	spin_lock(&apr->svcs_lock);
+-	idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC);
++	ret = idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC);
+ 	spin_unlock(&apr->svcs_lock);
++	if (ret < 0) {
++		dev_err(dev, "idr_alloc failed: %d\n", ret);
++		goto out;
++	}
+ 
+-	of_property_read_string_index(np, "qcom,protection-domain",
+-				      1, &adev->service_path);
++	ret = of_property_read_string_index(np, "qcom,protection-domain",
++					    1, &adev->service_path);
++	if (ret < 0) {
++		dev_err(dev, "Failed to read second value of qcom,protection-domain\n");
++		goto out;
++	}
+ 
+ 	dev_info(dev, "Adding APR/GPR dev: %s\n", dev_name(&adev->dev));
+ 
+@@ -468,6 +476,7 @@ static int apr_add_device(struct device *dev, struct device_node *np,
+ 		put_device(&adev->dev);
+ 	}
+ 
++out:
+ 	return ret;
+ }
+ 
+diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
+index 38d7296315a25..5942417c7c20d 100644
+--- a/drivers/soc/qcom/llcc-qcom.c
++++ b/drivers/soc/qcom/llcc-qcom.c
+@@ -781,7 +781,7 @@ static int qcom_llcc_probe(struct platform_device *pdev)
+ 	if (ret)
+ 		goto err;
+ 
+-	drv_data->ecc_irq = platform_get_irq(pdev, 0);
++	drv_data->ecc_irq = platform_get_irq_optional(pdev, 0);
+ 	if (drv_data->ecc_irq >= 0) {
+ 		llcc_edac = platform_device_register_data(&pdev->dev,
+ 						"qcom_llcc_edac", -1, drv_data,
+diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
+index 92af7d1b6f5bd..8fb76908be704 100644
+--- a/drivers/soc/ti/knav_qmss_queue.c
++++ b/drivers/soc/ti/knav_qmss_queue.c
+@@ -67,7 +67,7 @@ static DEFINE_MUTEX(knav_dev_lock);
+  * Newest followed by older ones. Search is done from start of the array
+  * until a firmware file is found.
+  */
+-const char *knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"};
++static const char * const knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"};
+ 
+ static bool device_ready;
+ bool knav_qmss_device_ready(void)
+@@ -1785,6 +1785,7 @@ static int knav_queue_probe(struct platform_device *pdev)
+ 	pm_runtime_enable(&pdev->dev);
+ 	ret = pm_runtime_resume_and_get(&pdev->dev);
+ 	if (ret < 0) {
++		pm_runtime_disable(&pdev->dev);
+ 		dev_err(dev, "Failed to enable QMSS\n");
+ 		return ret;
+ 	}
+diff --git a/drivers/soc/ti/smartreflex.c b/drivers/soc/ti/smartreflex.c
+index ad2bb72e640c8..6a389a6444f36 100644
+--- a/drivers/soc/ti/smartreflex.c
++++ b/drivers/soc/ti/smartreflex.c
+@@ -932,6 +932,7 @@ static int omap_sr_probe(struct platform_device *pdev)
+ err_debugfs:
+ 	debugfs_remove_recursive(sr_info->dbg_dir);
+ err_list_del:
++	pm_runtime_disable(&pdev->dev);
+ 	list_del(&sr_info->node);
+ 	clk_unprepare(sr_info->fck);
+ 
+diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
+index 4b12c4964a664..9c8c7948044ed 100644
+--- a/drivers/spi/spi-gpio.c
++++ b/drivers/spi/spi-gpio.c
+@@ -268,9 +268,19 @@ static int spi_gpio_set_direction(struct spi_device *spi, bool output)
+ 	if (output)
+ 		return gpiod_direction_output(spi_gpio->mosi, 1);
+ 
+-	ret = gpiod_direction_input(spi_gpio->mosi);
+-	if (ret)
+-		return ret;
++	/*
++	 * Only change MOSI to an input if using 3WIRE mode.
++	 * Otherwise, MOSI could be left floating if there is
++	 * no pull resistor connected to the I/O pin, or could
++	 * be left logic high if there is a pull-up. Transmitting
++	 * logic high when only clocking MISO data in can put some
++	 * SPI devices in to a bad state.
++	 */
++	if (spi->mode & SPI_3WIRE) {
++		ret = gpiod_direction_input(spi_gpio->mosi);
++		if (ret)
++			return ret;
++	}
+ 	/*
+ 	 * Send a turnaround high impedance cycle when switching
+ 	 * from output to input. Theoretically there should be
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index a7cc96aeb5903..d6aff909fc365 100644
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -1187,6 +1187,11 @@ static int mtk_spi_probe(struct platform_device *pdev)
+ 	if (!dev->dma_mask)
+ 		dev->dma_mask = &dev->coherent_dma_mask;
+ 
++	if (mdata->dev_comp->ipm_design)
++		dma_set_max_seg_size(dev, SZ_16M);
++	else
++		dma_set_max_seg_size(dev, SZ_256K);
++
+ 	ret = devm_request_irq(dev, irq, mtk_spi_interrupt,
+ 			       IRQF_TRIGGER_NONE, dev_name(dev), master);
+ 	if (ret)
+diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
+index b2775d82d2d7b..6313e7d0cdf87 100644
+--- a/drivers/spi/spidev.c
++++ b/drivers/spi/spidev.c
+@@ -377,12 +377,23 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ 	switch (cmd) {
+ 	/* read requests */
+ 	case SPI_IOC_RD_MODE:
+-		retval = put_user(spi->mode & SPI_MODE_MASK,
+-					(__u8 __user *)arg);
+-		break;
+ 	case SPI_IOC_RD_MODE32:
+-		retval = put_user(spi->mode & SPI_MODE_MASK,
+-					(__u32 __user *)arg);
++		tmp = spi->mode;
++
++		{
++			struct spi_controller *ctlr = spi->controller;
++
++			if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods &&
++			    ctlr->cs_gpiods[spi->chip_select])
++				tmp &= ~SPI_CS_HIGH;
++		}
++
++		if (cmd == SPI_IOC_RD_MODE)
++			retval = put_user(tmp & SPI_MODE_MASK,
++					  (__u8 __user *)arg);
++		else
++			retval = put_user(tmp & SPI_MODE_MASK,
++					  (__u32 __user *)arg);
+ 		break;
+ 	case SPI_IOC_RD_LSB_FIRST:
+ 		retval = put_user((spi->mode & SPI_LSB_FIRST) ?  1 : 0,
+diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
+index a0553c24cce4b..7eee2f8dca47e 100644
+--- a/drivers/staging/media/imx/imx7-media-csi.c
++++ b/drivers/staging/media/imx/imx7-media-csi.c
+@@ -521,9 +521,9 @@ static void imx7_csi_configure(struct imx7_csi *csi)
+ 	cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
+ 
+ 	cr18 &= ~(BIT_CSI_HW_ENABLE | BIT_MIPI_DATA_FORMAT_MASK |
+-		  BIT_DATA_FROM_MIPI | BIT_BASEADDR_CHG_ERR_EN |
+-		  BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL |
+-		  BIT_DEINTERLACE_EN);
++		  BIT_DATA_FROM_MIPI | BIT_MIPI_DOUBLE_CMPNT |
++		  BIT_BASEADDR_CHG_ERR_EN | BIT_BASEADDR_SWITCH_SEL |
++		  BIT_BASEADDR_SWITCH_EN | BIT_DEINTERLACE_EN);
+ 
+ 	if (out_pix->field == V4L2_FIELD_INTERLACED) {
+ 		cr18 |= BIT_DEINTERLACE_EN;
+diff --git a/drivers/staging/media/rkvdec/rkvdec-vp9.c b/drivers/staging/media/rkvdec/rkvdec-vp9.c
+index d8c1c0db15c70..cfae99b40ccb4 100644
+--- a/drivers/staging/media/rkvdec/rkvdec-vp9.c
++++ b/drivers/staging/media/rkvdec/rkvdec-vp9.c
+@@ -84,6 +84,8 @@ struct rkvdec_vp9_probs {
+ 		struct rkvdec_vp9_inter_frame_probs inter;
+ 		struct rkvdec_vp9_intra_only_frame_probs intra_only;
+ 	};
++	/* 128 bit alignment */
++	u8 padding1[11];
+ };
+ 
+ /* Data structure describing auxiliary buffer format. */
+@@ -1006,6 +1008,7 @@ static int rkvdec_vp9_start(struct rkvdec_ctx *ctx)
+ 
+ 	ctx->priv = vp9_ctx;
+ 
++	BUILD_BUG_ON(sizeof(priv_tbl->probs) % 16); /* ensure probs size is 128-bit aligned */
+ 	priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl),
+ 				      &vp9_ctx->priv_tbl.dma, GFP_KERNEL);
+ 	if (!priv_tbl) {
+diff --git a/drivers/staging/media/stkwebcam/Kconfig b/drivers/staging/media/stkwebcam/Kconfig
+index 4450403dff41f..7234498e634ac 100644
+--- a/drivers/staging/media/stkwebcam/Kconfig
++++ b/drivers/staging/media/stkwebcam/Kconfig
+@@ -2,7 +2,7 @@
+ config VIDEO_STKWEBCAM
+ 	tristate "USB Syntek DC1125 Camera support (DEPRECATED)"
+ 	depends on VIDEO_DEV
+-	depends on USB
++	depends on MEDIA_USB_SUPPORT && MEDIA_CAMERA_SUPPORT
+ 	help
+ 	  Say Y here if you want to use this type of camera.
+ 	  Supported devices are typically found in some Asus laptops,
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index 095b8464f37a0..a07fd28e1fcfd 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -242,6 +242,18 @@ static void cedrus_h265_skip_bits(struct cedrus_dev *dev, int num)
+ 	}
+ }
+ 
++static u32 cedrus_h265_show_bits(struct cedrus_dev *dev, int num)
++{
++	cedrus_write(dev, VE_DEC_H265_TRIGGER,
++		     VE_DEC_H265_TRIGGER_SHOW_BITS |
++		     VE_DEC_H265_TRIGGER_TYPE_N_BITS(num));
++
++	cedrus_wait_for(dev, VE_DEC_H265_STATUS,
++			VE_DEC_H265_STATUS_VLD_BUSY);
++
++	return cedrus_read(dev, VE_DEC_H265_BITS_READ);
++}
++
+ static void cedrus_h265_write_scaling_list(struct cedrus_ctx *ctx,
+ 					   struct cedrus_run *run)
+ {
+@@ -406,7 +418,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+ 	u32 num_entry_point_offsets;
+ 	u32 output_pic_list_index;
+ 	u32 pic_order_cnt[2];
+-	u8 *padding;
++	u8 padding;
+ 	int count;
+ 	u32 reg;
+ 
+@@ -520,21 +532,22 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
+ 	if (slice_params->data_byte_offset == 0)
+ 		return -EOPNOTSUPP;
+ 
+-	padding = (u8 *)vb2_plane_vaddr(&run->src->vb2_buf, 0) +
+-		slice_params->data_byte_offset - 1;
++	cedrus_h265_skip_bits(dev, (slice_params->data_byte_offset - 1) * 8);
++
++	padding = cedrus_h265_show_bits(dev, 8);
+ 
+ 	/* at least one bit must be set in that byte */
+-	if (*padding == 0)
++	if (padding == 0)
+ 		return -EINVAL;
+ 
+ 	for (count = 0; count < 8; count++)
+-		if (*padding & (1 << count))
++		if (padding & (1 << count))
+ 			break;
+ 
+ 	/* Include the one bit. */
+ 	count++;
+ 
+-	cedrus_h265_skip_bits(dev, slice_params->data_byte_offset * 8 - count);
++	cedrus_h265_skip_bits(dev, 8 - count);
+ 
+ 	/* Bitstream parameters. */
+ 
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
+index d81f7513ade0d..655c05b389cf5 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
+@@ -505,6 +505,8 @@
+ #define VE_DEC_H265_LOW_ADDR_ENTRY_POINTS_BUF(a) \
+ 	SHIFT_AND_MASK_BITS(a, 7, 0)
+ 
++#define VE_DEC_H265_BITS_READ			(VE_ENGINE_DEC_H265 + 0xdc)
++
+ #define VE_DEC_H265_SRAM_OFFSET			(VE_ENGINE_DEC_H265 + 0xe0)
+ 
+ #define VE_DEC_H265_SRAM_OFFSET_PRED_WEIGHT_LUMA_L0	0x00
+diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c
+index d5c6c5e296215..1993c3993b3d6 100644
+--- a/drivers/staging/r8188eu/core/rtw_led.c
++++ b/drivers/staging/r8188eu/core/rtw_led.c
+@@ -34,40 +34,19 @@ static void ResetLedStatus(struct led_priv *pLed)
+ 
+ static void SwLedOn(struct adapter *padapter, struct led_priv *pLed)
+ {
+-	u8	LedCfg;
+-	int res;
+-
+-	if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
+-		return;
+-
+-	res = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);
+-	if (res)
++	if (padapter->bDriverStopped)
+ 		return;
+ 
+-	rtw_write8(padapter, REG_LEDCFG2, (LedCfg & 0xf0) | BIT(5) | BIT(6)); /*  SW control led0 on. */
++	rtw_write8(padapter, REG_LEDCFG2, BIT(5)); /*  SW control led0 on. */
+ 	pLed->bLedOn = true;
+ }
+ 
+ static void SwLedOff(struct adapter *padapter, struct led_priv *pLed)
+ {
+-	u8	LedCfg;
+-	int res;
+-
+-	if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
+-		goto exit;
+-
+-	res = rtw_read8(padapter, REG_LEDCFG2, &LedCfg);/* 0x4E */
+-	if (res)
+-		goto exit;
+-
+-	LedCfg &= 0x90; /*  Set to software control. */
+-	rtw_write8(padapter, REG_LEDCFG2, (LedCfg | BIT(3)));
+-	res = rtw_read8(padapter, REG_MAC_PINMUX_CFG, &LedCfg);
+-	if (res)
++	if (padapter->bDriverStopped)
+ 		goto exit;
+ 
+-	LedCfg &= 0xFE;
+-	rtw_write8(padapter, REG_MAC_PINMUX_CFG, LedCfg);
++	rtw_write8(padapter, REG_LEDCFG2, BIT(5) | BIT(3));
+ exit:
+ 	pLed->bLedOn = false;
+ }
+diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
+index 10550bd2c16db..abfd14bfd5fb8 100644
+--- a/drivers/staging/r8188eu/core/rtw_pwrctrl.c
++++ b/drivers/staging/r8188eu/core/rtw_pwrctrl.c
+@@ -273,7 +273,7 @@ static s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms)
+ 			err = -1;
+ 			break;
+ 		}
+-		msleep(1);
++		mdelay(1);
+ 	}
+ 
+ 	return err;
+diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c
+index abe5c153f74e8..b0ef9da43bc4e 100644
+--- a/drivers/staging/rtl8192e/rtllib_rx.c
++++ b/drivers/staging/rtl8192e/rtllib_rx.c
+@@ -1489,9 +1489,9 @@ static int rtllib_rx_Monitor(struct rtllib_device *ieee, struct sk_buff *skb,
+ 		hdrlen += 4;
+ 	}
+ 
+-	rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen);
+ 	ieee->stats.rx_packets++;
+ 	ieee->stats.rx_bytes += skb->len;
++	rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen);
+ 
+ 	return 1;
+ }
+diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+index b58e75932ecd5..3686b3c599ce7 100644
+--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
++++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
+@@ -951,9 +951,11 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+ #endif
+ 
+ 	if (ieee->iw_mode == IW_MODE_MONITOR) {
++		unsigned int len = skb->len;
++
+ 		ieee80211_monitor_rx(ieee, skb, rx_stats);
+ 		stats->rx_packets++;
+-		stats->rx_bytes += skb->len;
++		stats->rx_bytes += len;
+ 		return 1;
+ 	}
+ 
+diff --git a/drivers/staging/vme_user/vme_fake.c b/drivers/staging/vme_user/vme_fake.c
+index dd646b0c531d4..1ee432c223e2b 100644
+--- a/drivers/staging/vme_user/vme_fake.c
++++ b/drivers/staging/vme_user/vme_fake.c
+@@ -1073,6 +1073,8 @@ static int __init fake_init(void)
+ 
+ 	/* We need a fake parent device */
+ 	vme_root = __root_device_register("vme", THIS_MODULE);
++	if (IS_ERR(vme_root))
++		return PTR_ERR(vme_root);
+ 
+ 	/* If we want to support more than one bridge at some point, we need to
+ 	 * dynamically allocate this so we get one per device.
+diff --git a/drivers/staging/vme_user/vme_tsi148.c b/drivers/staging/vme_user/vme_tsi148.c
+index 9564762132415..b741514e938bd 100644
+--- a/drivers/staging/vme_user/vme_tsi148.c
++++ b/drivers/staging/vme_user/vme_tsi148.c
+@@ -1765,6 +1765,7 @@ static int tsi148_dma_list_add(struct vme_dma_list *list,
+ 	return 0;
+ 
+ err_dma:
++	list_del(&entry->list);
+ err_dest:
+ err_source:
+ err_align:
+diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
+index f2919319ad383..ff49c8f3fe241 100644
+--- a/drivers/target/iscsi/iscsi_target_nego.c
++++ b/drivers/target/iscsi/iscsi_target_nego.c
+@@ -1018,6 +1018,13 @@ static int iscsi_target_handle_csg_one(struct iscsit_conn *conn, struct iscsi_lo
+ 	return 0;
+ }
+ 
++/*
++ * RETURN VALUE:
++ *
++ *  1 = Login successful
++ * -1 = Login failed
++ *  0 = More PDU exchanges required
++ */
+ static int iscsi_target_do_login(struct iscsit_conn *conn, struct iscsi_login *login)
+ {
+ 	int pdu_count = 0;
+@@ -1363,12 +1370,13 @@ int iscsi_target_start_negotiation(
+ 		ret = -1;
+ 
+ 	if (ret < 0) {
+-		cancel_delayed_work_sync(&conn->login_work);
+ 		iscsi_target_restore_sock_callbacks(conn);
+ 		iscsi_remove_failed_auth_entry(conn);
+ 	}
+-	if (ret != 0)
++	if (ret != 0) {
++		cancel_delayed_work_sync(&conn->login_work);
+ 		iscsi_target_nego_release(conn);
++	}
+ 
+ 	return ret;
+ }
+diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c
+index af666bd9e8d4d..c5cd873c6e016 100644
+--- a/drivers/thermal/imx8mm_thermal.c
++++ b/drivers/thermal/imx8mm_thermal.c
+@@ -65,8 +65,14 @@ static int imx8mm_tmu_get_temp(void *data, int *temp)
+ 	u32 val;
+ 
+ 	val = readl_relaxed(tmu->base + TRITSR) & TRITSR_TEMP0_VAL_MASK;
++
++	/*
++	 * Do not validate against the V bit (bit 31) due to errata
++	 * ERR051272: TMU: Bit 31 of registers TMU_TSCR/TMU_TRITSR/TMU_TRATSR invalid
++	 */
++
+ 	*temp = val * 1000;
+-	if (*temp < VER1_TEMP_LOW_LIMIT)
++	if (*temp < VER1_TEMP_LOW_LIMIT || *temp > VER2_TEMP_HIGH_LIMIT)
+ 		return -EAGAIN;
+ 
+ 	return 0;
+diff --git a/drivers/thermal/k3_j72xx_bandgap.c b/drivers/thermal/k3_j72xx_bandgap.c
+index 115a44eb4fbfb..4eb4926bbdc78 100644
+--- a/drivers/thermal/k3_j72xx_bandgap.c
++++ b/drivers/thermal/k3_j72xx_bandgap.c
+@@ -439,7 +439,7 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev)
+ 		workaround_needed = false;
+ 
+ 	dev_dbg(bgp->dev, "Work around %sneeded\n",
+-		workaround_needed ? "not " : "");
++		workaround_needed ? "" : "not ");
+ 
+ 	if (!workaround_needed)
+ 		init_table(5, ref_table, golden_factors);
+diff --git a/drivers/thermal/qcom/lmh.c b/drivers/thermal/qcom/lmh.c
+index d3d9b9fa49e81..4122a51e98741 100644
+--- a/drivers/thermal/qcom/lmh.c
++++ b/drivers/thermal/qcom/lmh.c
+@@ -45,7 +45,7 @@ static irqreturn_t lmh_handle_irq(int hw_irq, void *data)
+ 	if (irq)
+ 		generic_handle_irq(irq);
+ 
+-	return 0;
++	return IRQ_HANDLED;
+ }
+ 
+ static void lmh_enable_interrupt(struct irq_data *d)
+diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
+index 770f82cc9bca8..247b39d57fa7c 100644
+--- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
++++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
+@@ -252,7 +252,8 @@ static int qpnp_tm_update_critical_trip_temp(struct qpnp_tm_chip *chip,
+ 			disable_s2_shutdown = true;
+ 		else
+ 			dev_warn(chip->dev,
+-				 "No ADC is configured and critical temperature is above the maximum stage 2 threshold of 140 C! Configuring stage 2 shutdown at 140 C.\n");
++				 "No ADC is configured and critical temperature %d mC is above the maximum stage 2 threshold of %ld mC! Configuring stage 2 shutdown at %ld mC.\n",
++				 temp, stage2_threshold_max, stage2_threshold_max);
+ 	}
+ 
+ skip:
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 50d50cec77740..15fb5fa1b0f2c 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -903,10 +903,6 @@ __thermal_cooling_device_register(struct device_node *np,
+ 	cdev->id = ret;
+ 	id = ret;
+ 
+-	ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
+-	if (ret)
+-		goto out_ida_remove;
+-
+ 	cdev->type = kstrdup(type ? type : "", GFP_KERNEL);
+ 	if (!cdev->type) {
+ 		ret = -ENOMEM;
+@@ -921,6 +917,11 @@ __thermal_cooling_device_register(struct device_node *np,
+ 	cdev->device.class = &thermal_class;
+ 	cdev->devdata = devdata;
+ 	thermal_cooling_device_setup_sysfs(cdev);
++	ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
++	if (ret) {
++		thermal_cooling_device_destroy_sysfs(cdev);
++		goto out_kfree_type;
++	}
+ 	ret = device_register(&cdev->device);
+ 	if (ret)
+ 		goto out_kfree_type;
+@@ -1241,10 +1242,6 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
+ 	tz->id = id;
+ 	strlcpy(tz->type, type, sizeof(tz->type));
+ 
+-	result = dev_set_name(&tz->device, "thermal_zone%d", tz->id);
+-	if (result)
+-		goto remove_id;
+-
+ 	if (!ops->critical)
+ 		ops->critical = thermal_zone_device_critical;
+ 
+@@ -1267,6 +1264,11 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
+ 	/* A new thermal zone needs to be updated anyway. */
+ 	atomic_set(&tz->need_update, 1);
+ 
++	result = dev_set_name(&tz->device, "thermal_zone%d", tz->id);
++	if (result) {
++		thermal_zone_destroy_device_groups(tz);
++		goto remove_id;
++	}
+ 	result = device_register(&tz->device);
+ 	if (result)
+ 		goto release_device;
+diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c
+index 8efdc271eb75f..5e0ffd6c47892 100644
+--- a/drivers/tty/serial/8250/8250_bcm7271.c
++++ b/drivers/tty/serial/8250/8250_bcm7271.c
+@@ -1212,9 +1212,17 @@ static struct platform_driver brcmuart_platform_driver = {
+ 
+ static int __init brcmuart_init(void)
+ {
++	int ret;
++
+ 	brcmuart_debugfs_root = debugfs_create_dir(
+ 		brcmuart_platform_driver.driver.name, NULL);
+-	return platform_driver_register(&brcmuart_platform_driver);
++	ret = platform_driver_register(&brcmuart_platform_driver);
++	if (ret) {
++		debugfs_remove_recursive(brcmuart_debugfs_root);
++		return ret;
++	}
++
++	return 0;
+ }
+ module_init(brcmuart_init);
+ 
+diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c
+index 8b749ed557c67..191d737ea5632 100644
+--- a/drivers/tty/serial/altera_uart.c
++++ b/drivers/tty/serial/altera_uart.c
+@@ -199,9 +199,8 @@ static void altera_uart_set_termios(struct uart_port *port,
+ 	 */
+ }
+ 
+-static void altera_uart_rx_chars(struct altera_uart *pp)
++static void altera_uart_rx_chars(struct uart_port *port)
+ {
+-	struct uart_port *port = &pp->port;
+ 	unsigned char ch, flag;
+ 	unsigned short status;
+ 
+@@ -246,9 +245,8 @@ static void altera_uart_rx_chars(struct altera_uart *pp)
+ 	tty_flip_buffer_push(&port->state->port);
+ }
+ 
+-static void altera_uart_tx_chars(struct altera_uart *pp)
++static void altera_uart_tx_chars(struct uart_port *port)
+ {
+-	struct uart_port *port = &pp->port;
+ 	struct circ_buf *xmit = &port->state->xmit;
+ 
+ 	if (port->x_char) {
+@@ -272,26 +270,25 @@ static void altera_uart_tx_chars(struct altera_uart *pp)
+ 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ 		uart_write_wakeup(port);
+ 
+-	if (xmit->head == xmit->tail) {
+-		pp->imr &= ~ALTERA_UART_CONTROL_TRDY_MSK;
+-		altera_uart_update_ctrl_reg(pp);
+-	}
++	if (uart_circ_empty(xmit))
++		altera_uart_stop_tx(port);
+ }
+ 
+ static irqreturn_t altera_uart_interrupt(int irq, void *data)
+ {
+ 	struct uart_port *port = data;
+ 	struct altera_uart *pp = container_of(port, struct altera_uart, port);
++	unsigned long flags;
+ 	unsigned int isr;
+ 
+ 	isr = altera_uart_readl(port, ALTERA_UART_STATUS_REG) & pp->imr;
+ 
+-	spin_lock(&port->lock);
++	spin_lock_irqsave(&port->lock, flags);
+ 	if (isr & ALTERA_UART_STATUS_RRDY_MSK)
+-		altera_uart_rx_chars(pp);
++		altera_uart_rx_chars(port);
+ 	if (isr & ALTERA_UART_STATUS_TRDY_MSK)
+-		altera_uart_tx_chars(pp);
+-	spin_unlock(&port->lock);
++		altera_uart_tx_chars(port);
++	spin_unlock_irqrestore(&port->lock, flags);
+ 
+ 	return IRQ_RETVAL(isr);
+ }
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
+index 15f0e4d88c5a0..c211a1e92db7f 100644
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -1045,6 +1045,9 @@ static void pl011_dma_rx_callback(void *data)
+  */
+ static inline void pl011_dma_rx_stop(struct uart_amba_port *uap)
+ {
++	if (!uap->using_rx_dma)
++		return;
++
+ 	/* FIXME.  Just disable the DMA enable */
+ 	uap->dmacr &= ~UART011_RXDMAE;
+ 	pl011_write(uap->dmacr, uap, REG_DMACR);
+@@ -1828,8 +1831,17 @@ static void pl011_enable_interrupts(struct uart_amba_port *uap)
+ static void pl011_unthrottle_rx(struct uart_port *port)
+ {
+ 	struct uart_amba_port *uap = container_of(port, struct uart_amba_port, port);
++	unsigned long flags;
+ 
+-	pl011_enable_interrupts(uap);
++	spin_lock_irqsave(&uap->port.lock, flags);
++
++	uap->im = UART011_RTIM;
++	if (!pl011_dma_rx_running(uap))
++		uap->im |= UART011_RXIM;
++
++	pl011_write(uap->im, uap, REG_IMSC);
++
++	spin_unlock_irqrestore(&uap->port.lock, flags);
+ }
+ 
+ static int pl011_startup(struct uart_port *port)
+diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
+index 8a9065e4a903b..ec501c3ce033b 100644
+--- a/drivers/tty/serial/pch_uart.c
++++ b/drivers/tty/serial/pch_uart.c
+@@ -694,6 +694,7 @@ static void pch_request_dma(struct uart_port *port)
+ 	if (!chan) {
+ 		dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Tx)\n",
+ 			__func__);
++		pci_dev_put(dma_dev);
+ 		return;
+ 	}
+ 	priv->chan_tx = chan;
+@@ -710,6 +711,7 @@ static void pch_request_dma(struct uart_port *port)
+ 			__func__);
+ 		dma_release_channel(priv->chan_tx);
+ 		priv->chan_tx = NULL;
++		pci_dev_put(dma_dev);
+ 		return;
+ 	}
+ 
+@@ -717,6 +719,8 @@ static void pch_request_dma(struct uart_port *port)
+ 	priv->rx_buf_virt = dma_alloc_coherent(port->dev, port->fifosize,
+ 				    &priv->rx_buf_dma, GFP_KERNEL);
+ 	priv->chan_rx = chan;
++
++	pci_dev_put(dma_dev);
+ }
+ 
+ static void pch_dma_rx_complete(void *arg)
+diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c
+index a5748e41483ba..ab549b79fde90 100644
+--- a/drivers/tty/serial/serial-tegra.c
++++ b/drivers/tty/serial/serial-tegra.c
+@@ -619,8 +619,9 @@ static void tegra_uart_stop_tx(struct uart_port *u)
+ 	if (tup->tx_in_progress != TEGRA_UART_TX_DMA)
+ 		return;
+ 
+-	dmaengine_terminate_all(tup->tx_dma_chan);
++	dmaengine_pause(tup->tx_dma_chan);
+ 	dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state);
++	dmaengine_terminate_all(tup->tx_dma_chan);
+ 	count = tup->tx_bytes_requested - state.residue;
+ 	async_tx_ack(tup->tx_dma_desc);
+ 	uart_xmit_advance(&tup->uport, count);
+@@ -763,8 +764,9 @@ static void tegra_uart_terminate_rx_dma(struct tegra_uart_port *tup)
+ 		return;
+ 	}
+ 
+-	dmaengine_terminate_all(tup->rx_dma_chan);
++	dmaengine_pause(tup->rx_dma_chan);
+ 	dmaengine_tx_status(tup->rx_dma_chan, tup->rx_cookie, &state);
++	dmaengine_terminate_all(tup->rx_dma_chan);
+ 
+ 	tegra_uart_rx_buffer_push(tup, state.residue);
+ 	tup->rx_dma_active = false;
+diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
+index 9a875558f5ef6..1f8aad186908f 100644
+--- a/drivers/tty/serial/stm32-usart.c
++++ b/drivers/tty/serial/stm32-usart.c
+@@ -1681,22 +1681,10 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)
+ 	if (!stm32port->info)
+ 		return -EINVAL;
+ 
+-	ret = stm32_usart_init_port(stm32port, pdev);
+-	if (ret)
+-		return ret;
+-
+-	if (stm32port->wakeup_src) {
+-		device_set_wakeup_capable(&pdev->dev, true);
+-		ret = dev_pm_set_wake_irq(&pdev->dev, stm32port->port.irq);
+-		if (ret)
+-			goto err_deinit_port;
+-	}
+-
+ 	stm32port->rx_ch = dma_request_chan(&pdev->dev, "rx");
+-	if (PTR_ERR(stm32port->rx_ch) == -EPROBE_DEFER) {
+-		ret = -EPROBE_DEFER;
+-		goto err_wakeirq;
+-	}
++	if (PTR_ERR(stm32port->rx_ch) == -EPROBE_DEFER)
++		return -EPROBE_DEFER;
++
+ 	/* Fall back in interrupt mode for any non-deferral error */
+ 	if (IS_ERR(stm32port->rx_ch))
+ 		stm32port->rx_ch = NULL;
+@@ -1710,6 +1698,17 @@ static int stm32_usart_serial_probe(struct platform_device *pdev)
+ 	if (IS_ERR(stm32port->tx_ch))
+ 		stm32port->tx_ch = NULL;
+ 
++	ret = stm32_usart_init_port(stm32port, pdev);
++	if (ret)
++		goto err_dma_tx;
++
++	if (stm32port->wakeup_src) {
++		device_set_wakeup_capable(&pdev->dev, true);
++		ret = dev_pm_set_wake_irq(&pdev->dev, stm32port->port.irq);
++		if (ret)
++			goto err_deinit_port;
++	}
++
+ 	if (stm32port->rx_ch && stm32_usart_of_dma_rx_probe(stm32port, pdev)) {
+ 		/* Fall back in interrupt mode */
+ 		dma_release_channel(stm32port->rx_ch);
+@@ -1746,19 +1745,11 @@ err_port:
+ 	pm_runtime_set_suspended(&pdev->dev);
+ 	pm_runtime_put_noidle(&pdev->dev);
+ 
+-	if (stm32port->tx_ch) {
++	if (stm32port->tx_ch)
+ 		stm32_usart_of_dma_tx_remove(stm32port, pdev);
+-		dma_release_channel(stm32port->tx_ch);
+-	}
+-
+ 	if (stm32port->rx_ch)
+ 		stm32_usart_of_dma_rx_remove(stm32port, pdev);
+ 
+-err_dma_rx:
+-	if (stm32port->rx_ch)
+-		dma_release_channel(stm32port->rx_ch);
+-
+-err_wakeirq:
+ 	if (stm32port->wakeup_src)
+ 		dev_pm_clear_wake_irq(&pdev->dev);
+ 
+@@ -1768,6 +1759,14 @@ err_deinit_port:
+ 
+ 	stm32_usart_deinit_port(stm32port);
+ 
++err_dma_tx:
++	if (stm32port->tx_ch)
++		dma_release_channel(stm32port->tx_ch);
++
++err_dma_rx:
++	if (stm32port->rx_ch)
++		dma_release_channel(stm32port->rx_ch);
++
+ 	return ret;
+ }
+ 
+diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c
+index 6ea52293d9f35..7c10715dace88 100644
+--- a/drivers/tty/serial/sunsab.c
++++ b/drivers/tty/serial/sunsab.c
+@@ -1137,7 +1137,13 @@ static int __init sunsab_init(void)
+ 		}
+ 	}
+ 
+-	return platform_driver_register(&sab_driver);
++	err = platform_driver_register(&sab_driver);
++	if (err) {
++		kfree(sunsab_ports);
++		sunsab_ports = NULL;
++	}
++
++	return err;
+ }
+ 
+ static void __exit sunsab_exit(void)
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index a202d7d5240d8..bda89f988859e 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -5378,6 +5378,26 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
+ 	}
+ }
+ 
++/* Any value that is not an existing queue number is fine for this constant. */
++enum {
++	UFSHCD_POLL_FROM_INTERRUPT_CONTEXT = -1
++};
++
++static void ufshcd_clear_polled(struct ufs_hba *hba,
++				unsigned long *completed_reqs)
++{
++	int tag;
++
++	for_each_set_bit(tag, completed_reqs, hba->nutrs) {
++		struct scsi_cmnd *cmd = hba->lrb[tag].cmd;
++
++		if (!cmd)
++			continue;
++		if (scsi_cmd_to_rq(cmd)->cmd_flags & REQ_POLLED)
++			__clear_bit(tag, completed_reqs);
++	}
++}
++
+ /*
+  * Returns > 0 if one or more commands have been completed or 0 if no
+  * requests have been completed.
+@@ -5394,13 +5414,17 @@ static int ufshcd_poll(struct Scsi_Host *shost, unsigned int queue_num)
+ 	WARN_ONCE(completed_reqs & ~hba->outstanding_reqs,
+ 		  "completed: %#lx; outstanding: %#lx\n", completed_reqs,
+ 		  hba->outstanding_reqs);
++	if (queue_num == UFSHCD_POLL_FROM_INTERRUPT_CONTEXT) {
++		/* Do not complete polled requests from interrupt context. */
++		ufshcd_clear_polled(hba, &completed_reqs);
++	}
+ 	hba->outstanding_reqs &= ~completed_reqs;
+ 	spin_unlock_irqrestore(&hba->outstanding_lock, flags);
+ 
+ 	if (completed_reqs)
+ 		__ufshcd_transfer_req_compl(hba, completed_reqs);
+ 
+-	return completed_reqs;
++	return completed_reqs != 0;
+ }
+ 
+ /**
+@@ -5431,7 +5455,7 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba)
+ 	 * Ignore the ufshcd_poll() return value and return IRQ_HANDLED since we
+ 	 * do not want polling to trigger spurious interrupt complaints.
+ 	 */
+-	ufshcd_poll(hba->host, 0);
++	ufshcd_poll(hba->host, UFSHCD_POLL_FROM_INTERRUPT_CONTEXT);
+ 
+ 	return IRQ_HANDLED;
+ }
+@@ -8741,8 +8765,6 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba,
+ 	struct scsi_device *sdp;
+ 	unsigned long flags;
+ 	int ret, retries;
+-	unsigned long deadline;
+-	int32_t remaining;
+ 
+ 	spin_lock_irqsave(hba->host->host_lock, flags);
+ 	sdp = hba->ufs_device_wlun;
+@@ -8775,14 +8797,9 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba,
+ 	 * callbacks hence set the RQF_PM flag so that it doesn't resume the
+ 	 * already suspended childs.
+ 	 */
+-	deadline = jiffies + 10 * HZ;
+ 	for (retries = 3; retries > 0; --retries) {
+-		ret = -ETIMEDOUT;
+-		remaining = deadline - jiffies;
+-		if (remaining <= 0)
+-			break;
+ 		ret = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
+-				   remaining / HZ, 0, 0, RQF_PM, NULL);
++				   HZ, 0, 0, RQF_PM, NULL);
+ 		if (!scsi_status_is_check_condition(ret) ||
+ 				!scsi_sense_valid(&sshdr) ||
+ 				sshdr.sense_key != UNIT_ATTENTION)
+diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
+index 1106f33764047..792c3e9c9ce53 100644
+--- a/drivers/uio/uio_dmem_genirq.c
++++ b/drivers/uio/uio_dmem_genirq.c
+@@ -110,8 +110,10 @@ static irqreturn_t uio_dmem_genirq_handler(int irq, struct uio_info *dev_info)
+ 	 * remember the state so we can allow user space to enable it later.
+ 	 */
+ 
++	spin_lock(&priv->lock);
+ 	if (!test_and_set_bit(0, &priv->flags))
+ 		disable_irq_nosync(irq);
++	spin_unlock(&priv->lock);
+ 
+ 	return IRQ_HANDLED;
+ }
+@@ -125,20 +127,19 @@ static int uio_dmem_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on)
+ 	 * in the interrupt controller, but keep track of the
+ 	 * state to prevent per-irq depth damage.
+ 	 *
+-	 * Serialize this operation to support multiple tasks.
++	 * Serialize this operation to support multiple tasks and concurrency
++	 * with irq handler on SMP systems.
+ 	 */
+ 
+ 	spin_lock_irqsave(&priv->lock, flags);
+ 	if (irq_on) {
+ 		if (test_and_clear_bit(0, &priv->flags))
+ 			enable_irq(dev_info->irq);
+-		spin_unlock_irqrestore(&priv->lock, flags);
+ 	} else {
+-		if (!test_and_set_bit(0, &priv->flags)) {
+-			spin_unlock_irqrestore(&priv->lock, flags);
+-			disable_irq(dev_info->irq);
+-		}
++		if (!test_and_set_bit(0, &priv->flags))
++			disable_irq_nosync(dev_info->irq);
+ 	}
++	spin_unlock_irqrestore(&priv->lock, flags);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c
+index 2f29431f612e0..b23e543b3a3d5 100644
+--- a/drivers/usb/cdns3/cdnsp-ring.c
++++ b/drivers/usb/cdns3/cdnsp-ring.c
+@@ -2006,10 +2006,11 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+ 
+ int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+ {
+-	u32 field, length_field, remainder;
++	u32 field, length_field, zlp = 0;
+ 	struct cdnsp_ep *pep = preq->pep;
+ 	struct cdnsp_ring *ep_ring;
+ 	int num_trbs;
++	u32 maxp;
+ 	int ret;
+ 
+ 	ep_ring = cdnsp_request_to_transfer_ring(pdev, preq);
+@@ -2019,26 +2020,33 @@ int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+ 	/* 1 TRB for data, 1 for status */
+ 	num_trbs = (pdev->three_stage_setup) ? 2 : 1;
+ 
++	maxp = usb_endpoint_maxp(pep->endpoint.desc);
++
++	if (preq->request.zero && preq->request.length &&
++	    (preq->request.length % maxp == 0)) {
++		num_trbs++;
++		zlp = 1;
++	}
++
+ 	ret = cdnsp_prepare_transfer(pdev, preq, num_trbs);
+ 	if (ret)
+ 		return ret;
+ 
+ 	/* If there's data, queue data TRBs */
+-	if (pdev->ep0_expect_in)
+-		field = TRB_TYPE(TRB_DATA) | TRB_IOC;
+-	else
+-		field = TRB_ISP | TRB_TYPE(TRB_DATA) | TRB_IOC;
+-
+ 	if (preq->request.length > 0) {
+-		remainder = cdnsp_td_remainder(pdev, 0, preq->request.length,
+-					       preq->request.length, preq, 1, 0);
++		field = TRB_TYPE(TRB_DATA);
+ 
+-		length_field = TRB_LEN(preq->request.length) |
+-				TRB_TD_SIZE(remainder) | TRB_INTR_TARGET(0);
++		if (zlp)
++			field |= TRB_CHAIN;
++		else
++			field |= TRB_IOC | (pdev->ep0_expect_in ? 0 : TRB_ISP);
+ 
+ 		if (pdev->ep0_expect_in)
+ 			field |= TRB_DIR_IN;
+ 
++		length_field = TRB_LEN(preq->request.length) |
++			       TRB_TD_SIZE(zlp) | TRB_INTR_TARGET(0);
++
+ 		cdnsp_queue_trb(pdev, ep_ring, true,
+ 				lower_32_bits(preq->request.dma),
+ 				upper_32_bits(preq->request.dma), length_field,
+@@ -2046,6 +2054,20 @@ int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+ 				TRB_SETUPID(pdev->setup_id) |
+ 				pdev->setup_speed);
+ 
++		if (zlp) {
++			field = TRB_TYPE(TRB_NORMAL) | TRB_IOC;
++
++			if (!pdev->ep0_expect_in)
++				field = TRB_ISP;
++
++			cdnsp_queue_trb(pdev, ep_ring, true,
++					lower_32_bits(preq->request.dma),
++					upper_32_bits(preq->request.dma), 0,
++					field | ep_ring->cycle_state |
++					TRB_SETUPID(pdev->setup_id) |
++					pdev->setup_speed);
++		}
++
+ 		pdev->ep0_stage = CDNSP_DATA_STAGE;
+ 	}
+ 
+diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
+index 94b305bbd621b..4bd9d799f1b97 100644
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -3140,8 +3140,12 @@ int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr,
+ 					     GFP_KERNEL,
+ 					     DMA_ATTR_WRITE_COMBINE);
+ 
+-	if (IS_ERR(local_mem))
++	if (IS_ERR_OR_NULL(local_mem)) {
++		if (!local_mem)
++			return -ENOMEM;
++
+ 		return PTR_ERR(local_mem);
++	}
+ 
+ 	/*
+ 	 * Here we pass a dma_addr_t but the arg type is a phys_addr_t.
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 038140b1de37b..07780148ebedb 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -122,21 +122,25 @@ static void __dwc3_set_mode(struct work_struct *work)
+ 	unsigned long flags;
+ 	int ret;
+ 	u32 reg;
++	u32 desired_dr_role;
+ 
+ 	mutex_lock(&dwc->mutex);
++	spin_lock_irqsave(&dwc->lock, flags);
++	desired_dr_role = dwc->desired_dr_role;
++	spin_unlock_irqrestore(&dwc->lock, flags);
+ 
+ 	pm_runtime_get_sync(dwc->dev);
+ 
+ 	if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
+ 		dwc3_otg_update(dwc, 0);
+ 
+-	if (!dwc->desired_dr_role)
++	if (!desired_dr_role)
+ 		goto out;
+ 
+-	if (dwc->desired_dr_role == dwc->current_dr_role)
++	if (desired_dr_role == dwc->current_dr_role)
+ 		goto out;
+ 
+-	if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
++	if (desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
+ 		goto out;
+ 
+ 	switch (dwc->current_dr_role) {
+@@ -164,7 +168,7 @@ static void __dwc3_set_mode(struct work_struct *work)
+ 	 */
+ 	if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) ||
+ 			DWC3_VER_IS_PRIOR(DWC31, 190A)) &&
+-			dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
++			desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) {
+ 		reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+ 		reg |= DWC3_GCTL_CORESOFTRESET;
+ 		dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+@@ -184,11 +188,11 @@ static void __dwc3_set_mode(struct work_struct *work)
+ 
+ 	spin_lock_irqsave(&dwc->lock, flags);
+ 
+-	dwc3_set_prtcap(dwc, dwc->desired_dr_role);
++	dwc3_set_prtcap(dwc, desired_dr_role);
+ 
+ 	spin_unlock_irqrestore(&dwc->lock, flags);
+ 
+-	switch (dwc->desired_dr_role) {
++	switch (desired_dr_role) {
+ 	case DWC3_GCTL_PRTCAP_HOST:
+ 		ret = dwc3_host_init(dwc);
+ 		if (ret) {
+@@ -1096,8 +1100,13 @@ static int dwc3_core_init(struct dwc3 *dwc)
+ 
+ 	if (!dwc->ulpi_ready) {
+ 		ret = dwc3_core_ulpi_init(dwc);
+-		if (ret)
++		if (ret) {
++			if (ret == -ETIMEDOUT) {
++				dwc3_core_soft_reset(dwc);
++				ret = -EPROBE_DEFER;
++			}
+ 			goto err0;
++		}
+ 		dwc->ulpi_ready = true;
+ 	}
+ 
+diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
+index ca0a7d9eaa34e..6be6009f911e1 100644
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -71,7 +71,7 @@ struct f_hidg {
+ 	wait_queue_head_t		write_queue;
+ 	struct usb_request		*req;
+ 
+-	int				minor;
++	struct device			dev;
+ 	struct cdev			cdev;
+ 	struct usb_function		func;
+ 
+@@ -84,6 +84,14 @@ static inline struct f_hidg *func_to_hidg(struct usb_function *f)
+ 	return container_of(f, struct f_hidg, func);
+ }
+ 
++static void hidg_release(struct device *dev)
++{
++	struct f_hidg *hidg = container_of(dev, struct f_hidg, dev);
++
++	kfree(hidg->set_report_buf);
++	kfree(hidg);
++}
++
+ /*-------------------------------------------------------------------------*/
+ /*                           Static descriptors                            */
+ 
+@@ -904,9 +912,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
+ 	struct usb_ep		*ep;
+ 	struct f_hidg		*hidg = func_to_hidg(f);
+ 	struct usb_string	*us;
+-	struct device		*device;
+ 	int			status;
+-	dev_t			dev;
+ 
+ 	/* maybe allocate device-global string IDs, and patch descriptors */
+ 	us = usb_gstrings_attach(c->cdev, ct_func_strings,
+@@ -999,21 +1005,11 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
+ 
+ 	/* create char device */
+ 	cdev_init(&hidg->cdev, &f_hidg_fops);
+-	dev = MKDEV(major, hidg->minor);
+-	status = cdev_add(&hidg->cdev, dev, 1);
++	status = cdev_device_add(&hidg->cdev, &hidg->dev);
+ 	if (status)
+ 		goto fail_free_descs;
+ 
+-	device = device_create(hidg_class, NULL, dev, NULL,
+-			       "%s%d", "hidg", hidg->minor);
+-	if (IS_ERR(device)) {
+-		status = PTR_ERR(device);
+-		goto del;
+-	}
+-
+ 	return 0;
+-del:
+-	cdev_del(&hidg->cdev);
+ fail_free_descs:
+ 	usb_free_all_descriptors(f);
+ fail:
+@@ -1244,9 +1240,7 @@ static void hidg_free(struct usb_function *f)
+ 
+ 	hidg = func_to_hidg(f);
+ 	opts = container_of(f->fi, struct f_hid_opts, func_inst);
+-	kfree(hidg->report_desc);
+-	kfree(hidg->set_report_buf);
+-	kfree(hidg);
++	put_device(&hidg->dev);
+ 	mutex_lock(&opts->lock);
+ 	--opts->refcnt;
+ 	mutex_unlock(&opts->lock);
+@@ -1256,8 +1250,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f)
+ {
+ 	struct f_hidg *hidg = func_to_hidg(f);
+ 
+-	device_destroy(hidg_class, MKDEV(major, hidg->minor));
+-	cdev_del(&hidg->cdev);
++	cdev_device_del(&hidg->cdev, &hidg->dev);
+ 
+ 	usb_free_all_descriptors(f);
+ }
+@@ -1266,6 +1259,7 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
+ {
+ 	struct f_hidg *hidg;
+ 	struct f_hid_opts *opts;
++	int ret;
+ 
+ 	/* allocate and initialize one new instance */
+ 	hidg = kzalloc(sizeof(*hidg), GFP_KERNEL);
+@@ -1277,17 +1271,28 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
+ 	mutex_lock(&opts->lock);
+ 	++opts->refcnt;
+ 
+-	hidg->minor = opts->minor;
++	device_initialize(&hidg->dev);
++	hidg->dev.release = hidg_release;
++	hidg->dev.class = hidg_class;
++	hidg->dev.devt = MKDEV(major, opts->minor);
++	ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor);
++	if (ret) {
++		--opts->refcnt;
++		mutex_unlock(&opts->lock);
++		return ERR_PTR(ret);
++	}
++
+ 	hidg->bInterfaceSubClass = opts->subclass;
+ 	hidg->bInterfaceProtocol = opts->protocol;
+ 	hidg->report_length = opts->report_length;
+ 	hidg->report_desc_length = opts->report_desc_length;
+ 	if (opts->report_desc) {
+-		hidg->report_desc = kmemdup(opts->report_desc,
+-					    opts->report_desc_length,
+-					    GFP_KERNEL);
++		hidg->report_desc = devm_kmemdup(&hidg->dev, opts->report_desc,
++						 opts->report_desc_length,
++						 GFP_KERNEL);
+ 		if (!hidg->report_desc) {
+-			kfree(hidg);
++			put_device(&hidg->dev);
++			--opts->refcnt;
+ 			mutex_unlock(&opts->lock);
+ 			return ERR_PTR(-ENOMEM);
+ 		}
+diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
+index c63c0c2cf649d..bf9878e1a72a8 100644
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -734,13 +734,13 @@ int usb_gadget_disconnect(struct usb_gadget *gadget)
+ 	}
+ 
+ 	ret = gadget->ops->pullup(gadget, 0);
+-	if (!ret) {
++	if (!ret)
+ 		gadget->connected = 0;
+-		mutex_lock(&udc_lock);
+-		if (gadget->udc->driver)
+-			gadget->udc->driver->disconnect(gadget);
+-		mutex_unlock(&udc_lock);
+-	}
++
++	mutex_lock(&udc_lock);
++	if (gadget->udc->driver)
++		gadget->udc->driver->disconnect(gadget);
++	mutex_unlock(&udc_lock);
+ 
+ out:
+ 	trace_usb_gadget_disconnect(gadget, ret);
+diff --git a/drivers/usb/gadget/udc/fotg210-udc.c b/drivers/usb/gadget/udc/fotg210-udc.c
+index fdca28e72a3b4..d0e051beb3af9 100644
+--- a/drivers/usb/gadget/udc/fotg210-udc.c
++++ b/drivers/usb/gadget/udc/fotg210-udc.c
+@@ -629,10 +629,10 @@ static void fotg210_request_error(struct fotg210_udc *fotg210)
+ static void fotg210_set_address(struct fotg210_udc *fotg210,
+ 				struct usb_ctrlrequest *ctrl)
+ {
+-	if (ctrl->wValue >= 0x0100) {
++	if (le16_to_cpu(ctrl->wValue) >= 0x0100) {
+ 		fotg210_request_error(fotg210);
+ 	} else {
+-		fotg210_set_dev_addr(fotg210, ctrl->wValue);
++		fotg210_set_dev_addr(fotg210, le16_to_cpu(ctrl->wValue));
+ 		fotg210_set_cxdone(fotg210);
+ 	}
+ }
+@@ -713,17 +713,17 @@ static void fotg210_get_status(struct fotg210_udc *fotg210,
+ 
+ 	switch (ctrl->bRequestType & USB_RECIP_MASK) {
+ 	case USB_RECIP_DEVICE:
+-		fotg210->ep0_data = 1 << USB_DEVICE_SELF_POWERED;
++		fotg210->ep0_data = cpu_to_le16(1 << USB_DEVICE_SELF_POWERED);
+ 		break;
+ 	case USB_RECIP_INTERFACE:
+-		fotg210->ep0_data = 0;
++		fotg210->ep0_data = cpu_to_le16(0);
+ 		break;
+ 	case USB_RECIP_ENDPOINT:
+ 		epnum = ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK;
+ 		if (epnum)
+ 			fotg210->ep0_data =
+-				fotg210_is_epnstall(fotg210->ep[epnum])
+-				<< USB_ENDPOINT_HALT;
++				cpu_to_le16(fotg210_is_epnstall(fotg210->ep[epnum])
++					    << USB_ENDPOINT_HALT);
+ 		else
+ 			fotg210_request_error(fotg210);
+ 		break;
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index 01705e559c422..c61fc19ef1154 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -639,7 +639,6 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+ 
+ dealloc_usb3_hcd:
+ 	usb_remove_hcd(xhci->shared_hcd);
+-	xhci->shared_hcd = NULL;
+ 
+ dealloc_usb2_hcd:
+ 	usb_remove_hcd(hcd);
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index ad81e9a508b14..343709af4c16f 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2458,7 +2458,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
+ 
+ 	switch (trb_comp_code) {
+ 	case COMP_SUCCESS:
+-		ep_ring->err_count = 0;
++		ep->err_count = 0;
+ 		/* handle success with untransferred data as short packet */
+ 		if (ep_trb != td->last_trb || remaining) {
+ 			xhci_warn(xhci, "WARN Successful completion on short TX\n");
+@@ -2484,7 +2484,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep,
+ 		break;
+ 	case COMP_USB_TRANSACTION_ERROR:
+ 		if (xhci->quirks & XHCI_NO_SOFT_RETRY ||
+-		    (ep_ring->err_count++ > MAX_SOFT_RETRY) ||
++		    (ep->err_count++ > MAX_SOFT_RETRY) ||
+ 		    le32_to_cpu(slot_ctx->tt_info) & TT_SLOT)
+ 			break;
+ 
+@@ -2565,8 +2565,14 @@ static int handle_tx_event(struct xhci_hcd *xhci,
+ 		case COMP_USB_TRANSACTION_ERROR:
+ 		case COMP_INVALID_STREAM_TYPE_ERROR:
+ 		case COMP_INVALID_STREAM_ID_ERROR:
+-			xhci_handle_halted_endpoint(xhci, ep, 0, NULL,
+-						    EP_SOFT_RESET);
++			xhci_dbg(xhci, "Stream transaction error ep %u no id\n",
++				 ep_index);
++			if (ep->err_count++ > MAX_SOFT_RETRY)
++				xhci_handle_halted_endpoint(xhci, ep, 0, NULL,
++							    EP_HARD_RESET);
++			else
++				xhci_handle_halted_endpoint(xhci, ep, 0, NULL,
++							    EP_SOFT_RESET);
+ 			goto cleanup;
+ 		case COMP_RING_UNDERRUN:
+ 		case COMP_RING_OVERRUN:
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index a6daf37ff4bf7..38941554ec55c 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -933,6 +933,7 @@ struct xhci_virt_ep {
+ 	 * have to restore the device state to the previous state
+ 	 */
+ 	struct xhci_ring		*new_ring;
++	unsigned int			err_count;
+ 	unsigned int			ep_state;
+ #define SET_DEQ_PENDING		(1 << 0)
+ #define EP_HALTED		(1 << 1)	/* For stall handling */
+@@ -1627,7 +1628,6 @@ struct xhci_ring {
+ 	 * if we own the TRB (if we are the consumer).  See section 4.9.1.
+ 	 */
+ 	u32			cycle_state;
+-	unsigned int            err_count;
+ 	unsigned int		stream_id;
+ 	unsigned int		num_segs;
+ 	unsigned int		num_trbs_free;
+diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
+index 6704a62a16659..ba20272d22215 100644
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -1628,8 +1628,6 @@ static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
+ {
+ 	struct musb	*musb = gadget_to_musb(gadget);
+ 
+-	if (!musb->xceiv->set_power)
+-		return -EOPNOTSUPP;
+ 	return usb_phy_set_power(musb->xceiv, mA);
+ }
+ 
+diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
+index f571a65ae6ee2..476f55d1fec30 100644
+--- a/drivers/usb/musb/omap2430.c
++++ b/drivers/usb/musb/omap2430.c
+@@ -15,6 +15,7 @@
+ #include <linux/list.h>
+ #include <linux/io.h>
+ #include <linux/of.h>
++#include <linux/of_irq.h>
+ #include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/pm_runtime.h>
+@@ -310,6 +311,7 @@ static int omap2430_probe(struct platform_device *pdev)
+ 	struct device_node		*control_node;
+ 	struct platform_device		*control_pdev;
+ 	int				ret = -ENOMEM, val;
++	bool				populate_irqs = false;
+ 
+ 	if (!np)
+ 		return -ENODEV;
+@@ -328,6 +330,18 @@ static int omap2430_probe(struct platform_device *pdev)
+ 	musb->dev.dma_mask		= &omap2430_dmamask;
+ 	musb->dev.coherent_dma_mask	= omap2430_dmamask;
+ 
++	/*
++	 * Legacy SoCs using omap_device get confused if node is moved
++	 * because of interconnect properties mixed into the node.
++	 */
++	if (of_get_property(np, "ti,hwmods", NULL)) {
++		dev_warn(&pdev->dev, "please update to probe with ti-sysc\n");
++		populate_irqs = true;
++	} else {
++		device_set_of_node_from_dev(&musb->dev, &pdev->dev);
++	}
++	of_node_put(np);
++
+ 	glue->dev			= &pdev->dev;
+ 	glue->musb			= musb;
+ 	glue->status			= MUSB_UNKNOWN;
+@@ -389,6 +403,46 @@ static int omap2430_probe(struct platform_device *pdev)
+ 		goto err2;
+ 	}
+ 
++	if (populate_irqs) {
++		struct resource musb_res[3];
++		struct resource *res;
++		int i = 0;
++
++		memset(musb_res, 0, sizeof(*musb_res) * ARRAY_SIZE(musb_res));
++
++		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++		if (!res)
++			goto err2;
++
++		musb_res[i].start = res->start;
++		musb_res[i].end = res->end;
++		musb_res[i].flags = res->flags;
++		musb_res[i].name = res->name;
++		i++;
++
++		ret = of_irq_get_byname(np, "mc");
++		if (ret > 0) {
++			musb_res[i].start = ret;
++			musb_res[i].flags = IORESOURCE_IRQ;
++			musb_res[i].name = "mc";
++			i++;
++		}
++
++		ret = of_irq_get_byname(np, "dma");
++		if (ret > 0) {
++			musb_res[i].start = ret;
++			musb_res[i].flags = IORESOURCE_IRQ;
++			musb_res[i].name = "dma";
++			i++;
++		}
++
++		ret = platform_device_add_resources(musb, musb_res, i);
++		if (ret) {
++			dev_err(&pdev->dev, "failed to add IRQ resources\n");
++			goto err2;
++		}
++	}
++
+ 	ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
+ 	if (ret) {
+ 		dev_err(&pdev->dev, "failed to add platform_data\n");
+diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c
+index dfaed7eee94fc..32e6d19f7011a 100644
+--- a/drivers/usb/roles/class.c
++++ b/drivers/usb/roles/class.c
+@@ -106,10 +106,13 @@ usb_role_switch_is_parent(struct fwnode_handle *fwnode)
+ 	struct fwnode_handle *parent = fwnode_get_parent(fwnode);
+ 	struct device *dev;
+ 
+-	if (!parent || !fwnode_property_present(parent, "usb-role-switch"))
++	if (!fwnode_property_present(parent, "usb-role-switch")) {
++		fwnode_handle_put(parent);
+ 		return NULL;
++	}
+ 
+ 	dev = class_find_device_by_fwnode(role_class, parent);
++	fwnode_handle_put(parent);
+ 	return dev ? to_role_switch(dev) : ERR_PTR(-EPROBE_DEFER);
+ }
+ 
+diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
+index 747be69e5e699..5e912dd29b4c9 100644
+--- a/drivers/usb/storage/alauda.c
++++ b/drivers/usb/storage/alauda.c
+@@ -438,6 +438,8 @@ static int alauda_init_media(struct us_data *us)
+ 		+ MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift);
+ 	MEDIA_INFO(us).pba_to_lba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
+ 	MEDIA_INFO(us).lba_to_pba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
++	if (MEDIA_INFO(us).pba_to_lba == NULL || MEDIA_INFO(us).lba_to_pba == NULL)
++		return USB_STOR_TRANSPORT_ERROR;
+ 
+ 	if (alauda_reset_media(us) != USB_STOR_XFER_GOOD)
+ 		return USB_STOR_TRANSPORT_ERROR;
+diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c
+index 26ea2fdec17dc..31c2a3130cadb 100644
+--- a/drivers/usb/typec/bus.c
++++ b/drivers/usb/typec/bus.c
+@@ -134,7 +134,7 @@ int typec_altmode_exit(struct typec_altmode *adev)
+ 	if (!adev || !adev->active)
+ 		return 0;
+ 
+-	if (!pdev->ops || !pdev->ops->enter)
++	if (!pdev->ops || !pdev->ops->exit)
+ 		return -EOPNOTSUPP;
+ 
+ 	/* Moving to USB Safe State */
+diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c
+index 812784702d539..592bd4c854822 100644
+--- a/drivers/usb/typec/tcpm/tcpci.c
++++ b/drivers/usb/typec/tcpm/tcpci.c
+@@ -816,8 +816,10 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data)
+ 		return ERR_PTR(err);
+ 
+ 	tcpci->port = tcpm_register_port(tcpci->dev, &tcpci->tcpc);
+-	if (IS_ERR(tcpci->port))
++	if (IS_ERR(tcpci->port)) {
++		fwnode_handle_put(tcpci->tcpc.fwnode);
+ 		return ERR_CAST(tcpci->port);
++	}
+ 
+ 	return tcpci;
+ }
+@@ -826,6 +828,7 @@ EXPORT_SYMBOL_GPL(tcpci_register_port);
+ void tcpci_unregister_port(struct tcpci *tcpci)
+ {
+ 	tcpm_unregister_port(tcpci->port);
++	fwnode_handle_put(tcpci->tcpc.fwnode);
+ }
+ EXPORT_SYMBOL_GPL(tcpci_unregister_port);
+ 
+diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
+index 92e35e62e78c2..513ac7e141a4b 100644
+--- a/drivers/usb/typec/tipd/core.c
++++ b/drivers/usb/typec/tipd/core.c
+@@ -814,20 +814,19 @@ static int tps6598x_probe(struct i2c_client *client)
+ 
+ 	ret = devm_tps6598_psy_register(tps);
+ 	if (ret)
+-		return ret;
++		goto err_role_put;
+ 
+ 	tps->port = typec_register_port(&client->dev, &typec_cap);
+ 	if (IS_ERR(tps->port)) {
+ 		ret = PTR_ERR(tps->port);
+ 		goto err_role_put;
+ 	}
+-	fwnode_handle_put(fwnode);
+ 
+ 	if (status & TPS_STATUS_PLUG_PRESENT) {
+ 		ret = tps6598x_read16(tps, TPS_REG_POWER_STATUS, &tps->pwr_status);
+ 		if (ret < 0) {
+ 			dev_err(tps->dev, "failed to read power status: %d\n", ret);
+-			goto err_role_put;
++			goto err_unregister_port;
+ 		}
+ 		ret = tps6598x_connect(tps, status);
+ 		if (ret)
+@@ -840,14 +839,16 @@ static int tps6598x_probe(struct i2c_client *client)
+ 					dev_name(&client->dev), tps);
+ 	if (ret) {
+ 		tps6598x_disconnect(tps, 0);
+-		typec_unregister_port(tps->port);
+-		goto err_role_put;
++		goto err_unregister_port;
+ 	}
+ 
+ 	i2c_set_clientdata(client, tps);
++	fwnode_handle_put(fwnode);
+ 
+ 	return 0;
+ 
++err_unregister_port:
++	typec_unregister_port(tps->port);
+ err_role_put:
+ 	usb_role_switch_put(tps->role_sw);
+ err_fwnode_put:
+diff --git a/drivers/usb/typec/wusb3801.c b/drivers/usb/typec/wusb3801.c
+index e63509f8b01ed..8e38f5d2ec896 100644
+--- a/drivers/usb/typec/wusb3801.c
++++ b/drivers/usb/typec/wusb3801.c
+@@ -364,7 +364,7 @@ static int wusb3801_probe(struct i2c_client *client)
+ 	/* Initialize the hardware with the devicetree settings. */
+ 	ret = wusb3801_hw_init(wusb3801);
+ 	if (ret)
+-		return ret;
++		goto err_put_connector;
+ 
+ 	wusb3801->cap.revision		= USB_TYPEC_REV_1_2;
+ 	wusb3801->cap.accessory[0]	= TYPEC_ACCESSORY_AUDIO;
+diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c
+index 256f55b84e70a..a8d374205a0e0 100644
+--- a/drivers/vfio/platform/vfio_platform_common.c
++++ b/drivers/vfio/platform/vfio_platform_common.c
+@@ -72,12 +72,11 @@ static int vfio_platform_acpi_call_reset(struct vfio_platform_device *vdev,
+ 				  const char **extra_dbg)
+ {
+ #ifdef CONFIG_ACPI
+-	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ 	struct device *dev = vdev->device;
+ 	acpi_handle handle = ACPI_HANDLE(dev);
+ 	acpi_status acpi_ret;
+ 
+-	acpi_ret = acpi_evaluate_object(handle, "_RST", NULL, &buffer);
++	acpi_ret = acpi_evaluate_object(handle, "_RST", NULL, NULL);
+ 	if (ACPI_FAILURE(acpi_ret)) {
+ 		if (extra_dbg)
+ 			*extra_dbg = acpi_format_exception(acpi_ret);
+diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
+index cfc55273dc5d1..974e862cd20d6 100644
+--- a/drivers/video/fbdev/Kconfig
++++ b/drivers/video/fbdev/Kconfig
+@@ -601,6 +601,7 @@ config FB_TGA
+ config FB_UVESA
+ 	tristate "Userspace VESA VGA graphics support"
+ 	depends on FB && CONNECTOR
++	depends on !UML
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+@@ -2217,7 +2218,6 @@ config FB_SSD1307
+ 	select FB_SYS_COPYAREA
+ 	select FB_SYS_IMAGEBLIT
+ 	select FB_DEFERRED_IO
+-	select PWM
+ 	select FB_BACKLIGHT
+ 	help
+ 	  This driver implements support for the Solomon SSD1307
+diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
+index c0143d38df83a..14a7d404062c3 100644
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -2450,7 +2450,8 @@ err_out:
+ 
+ 	if (userfont) {
+ 		p->userfont = old_userfont;
+-		REFCOUNT(data)--;
++		if (--REFCOUNT(data) == 0)
++			kfree(data - FONT_EXTRA_WORDS * sizeof(int));
+ 	}
+ 
+ 	vc->vc_font.width = old_width;
+diff --git a/drivers/video/fbdev/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c
+index 2398b3d48fedf..305f1587bd898 100644
+--- a/drivers/video/fbdev/ep93xx-fb.c
++++ b/drivers/video/fbdev/ep93xx-fb.c
+@@ -552,12 +552,14 @@ static int ep93xxfb_probe(struct platform_device *pdev)
+ 
+ 	err = register_framebuffer(info);
+ 	if (err)
+-		goto failed_check;
++		goto failed_framebuffer;
+ 
+ 	dev_info(info->dev, "registered. Mode = %dx%d-%d\n",
+ 		 info->var.xres, info->var.yres, info->var.bits_per_pixel);
+ 	return 0;
+ 
++failed_framebuffer:
++	clk_disable_unprepare(fbi->clk);
+ failed_check:
+ 	if (fbi->mach_info->teardown)
+ 		fbi->mach_info->teardown(pdev);
+diff --git a/drivers/video/fbdev/geode/Kconfig b/drivers/video/fbdev/geode/Kconfig
+index ac9c860592aaf..85bc14b6faf64 100644
+--- a/drivers/video/fbdev/geode/Kconfig
++++ b/drivers/video/fbdev/geode/Kconfig
+@@ -5,6 +5,7 @@
+ config FB_GEODE
+ 	bool "AMD Geode family framebuffer support"
+ 	depends on FB && PCI && (X86_32 || (X86 && COMPILE_TEST))
++	depends on !UML
+ 	help
+ 	  Say 'Y' here to allow you to select framebuffer drivers for
+ 	  the AMD Geode family of processors.
+diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
+index b58b445bb529b..0839ba7d3a345 100644
+--- a/drivers/video/fbdev/hyperv_fb.c
++++ b/drivers/video/fbdev/hyperv_fb.c
+@@ -779,12 +779,18 @@ static void hvfb_ondemand_refresh_throttle(struct hvfb_par *par,
+ static int hvfb_on_panic(struct notifier_block *nb,
+ 			 unsigned long e, void *p)
+ {
++	struct hv_device *hdev;
+ 	struct hvfb_par *par;
+ 	struct fb_info *info;
+ 
+ 	par = container_of(nb, struct hvfb_par, hvfb_panic_nb);
+-	par->synchronous_fb = true;
+ 	info = par->info;
++	hdev = device_to_hv_device(info->device);
++
++	if (hv_ringbuffer_spinlock_busy(hdev->channel))
++		return NOTIFY_DONE;
++
++	par->synchronous_fb = true;
+ 	if (par->need_docopy)
+ 		hvfb_docopy(par, 0, dio_fb_size);
+ 	synthvid_update(info, 0, 0, INT_MAX, INT_MAX);
+diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c
+index 8fd79deb1e2ae..94f1f33f88f99 100644
+--- a/drivers/video/fbdev/pm2fb.c
++++ b/drivers/video/fbdev/pm2fb.c
+@@ -1528,8 +1528,10 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ 	}
+ 
+ 	info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev);
+-	if (!info)
+-		return -ENOMEM;
++	if (!info) {
++		err = -ENOMEM;
++		goto err_exit_disable;
++	}
+ 	default_par = info->par;
+ 
+ 	switch (pdev->device) {
+@@ -1710,6 +1712,8 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ 	release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
+  err_exit_neither:
+ 	framebuffer_release(info);
++ err_exit_disable:
++	pci_disable_device(pdev);
+ 	return retval;
+ }
+ 
+@@ -1734,6 +1738,7 @@ static void pm2fb_remove(struct pci_dev *pdev)
+ 	fb_dealloc_cmap(&info->cmap);
+ 	kfree(info->pixmap.addr);
+ 	framebuffer_release(info);
++	pci_disable_device(pdev);
+ }
+ 
+ static const struct pci_device_id pm2fb_id_table[] = {
+diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
+index 4df6772802d78..1f3b7e013568c 100644
+--- a/drivers/video/fbdev/uvesafb.c
++++ b/drivers/video/fbdev/uvesafb.c
+@@ -1758,6 +1758,7 @@ static int uvesafb_probe(struct platform_device *dev)
+ out_unmap:
+ 	iounmap(info->screen_base);
+ out_mem:
++	arch_phys_wc_del(par->mtrr_handle);
+ 	release_mem_region(info->fix.smem_start, info->fix.smem_len);
+ out_reg:
+ 	release_region(0x3c0, 32);
+diff --git a/drivers/video/fbdev/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c
+index ff61605b8764f..a543643ce014d 100644
+--- a/drivers/video/fbdev/vermilion/vermilion.c
++++ b/drivers/video/fbdev/vermilion/vermilion.c
+@@ -277,8 +277,10 @@ static int vmlfb_get_gpu(struct vml_par *par)
+ 
+ 	mutex_unlock(&vml_mutex);
+ 
+-	if (pci_enable_device(par->gpu) < 0)
++	if (pci_enable_device(par->gpu) < 0) {
++		pci_dev_put(par->gpu);
+ 		return -ENODEV;
++	}
+ 
+ 	return 0;
+ }
+diff --git a/drivers/video/fbdev/via/via-core.c b/drivers/video/fbdev/via/via-core.c
+index 89d75079b7307..0363b478fa3ef 100644
+--- a/drivers/video/fbdev/via/via-core.c
++++ b/drivers/video/fbdev/via/via-core.c
+@@ -725,7 +725,14 @@ static int __init via_core_init(void)
+ 		return ret;
+ 	viafb_i2c_init();
+ 	viafb_gpio_init();
+-	return pci_register_driver(&via_driver);
++	ret = pci_register_driver(&via_driver);
++	if (ret) {
++		viafb_gpio_exit();
++		viafb_i2c_exit();
++		return ret;
++	}
++
++	return 0;
+ }
+ 
+ static void __exit via_core_exit(void)
+diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c
+index 1ea6d2e5b2187..99d6062afe72f 100644
+--- a/drivers/virt/coco/sev-guest/sev-guest.c
++++ b/drivers/virt/coco/sev-guest/sev-guest.c
+@@ -800,3 +800,4 @@ MODULE_AUTHOR("Brijesh Singh <brijesh.singh@amd.com>");
+ MODULE_LICENSE("GPL");
+ MODULE_VERSION("1.0.0");
+ MODULE_DESCRIPTION("AMD SEV Guest Driver");
++MODULE_ALIAS("platform:sev-guest");
+diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
+index 34693f11385f6..e937b4dd28be7 100644
+--- a/drivers/watchdog/iTCO_wdt.c
++++ b/drivers/watchdog/iTCO_wdt.c
+@@ -423,14 +423,18 @@ static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev)
+ 	return time_left;
+ }
+ 
+-static void iTCO_wdt_set_running(struct iTCO_wdt_private *p)
++/* Returns true if the watchdog was running */
++static bool iTCO_wdt_set_running(struct iTCO_wdt_private *p)
+ {
+ 	u16 val;
+ 
+-	/* Bit 11: TCO Timer Halt -> 0 = The TCO timer is * enabled */
++	/* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled */
+ 	val = inw(TCO1_CNT(p));
+-	if (!(val & BIT(11)))
++	if (!(val & BIT(11))) {
+ 		set_bit(WDOG_HW_RUNNING, &p->wddev.status);
++		return true;
++	}
++	return false;
+ }
+ 
+ /*
+@@ -518,9 +522,6 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
+ 		return -ENODEV;	/* Cannot reset NO_REBOOT bit */
+ 	}
+ 
+-	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
+-	p->update_no_reboot_bit(p->no_reboot_priv, true);
+-
+ 	if (turn_SMI_watchdog_clear_off >= p->iTCO_version) {
+ 		/*
+ 		 * Bit 13: TCO_EN -> 0
+@@ -572,7 +573,13 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
+ 	watchdog_set_drvdata(&p->wddev, p);
+ 	platform_set_drvdata(pdev, p);
+ 
+-	iTCO_wdt_set_running(p);
++	if (!iTCO_wdt_set_running(p)) {
++		/*
++		 * If the watchdog was not running set NO_REBOOT now to
++		 * prevent later reboots.
++		 */
++		p->update_no_reboot_bit(p->no_reboot_priv, true);
++	}
+ 
+ 	/* Check that the heartbeat value is within it's range;
+ 	   if not reset to the default */
+diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
+index e88e8f6f0a334..719c5d1dda274 100644
+--- a/drivers/xen/privcmd.c
++++ b/drivers/xen/privcmd.c
+@@ -760,7 +760,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file,
+ 		goto out;
+ 	}
+ 
+-	pfns = kcalloc(kdata.num, sizeof(*pfns), GFP_KERNEL);
++	pfns = kcalloc(kdata.num, sizeof(*pfns), GFP_KERNEL | __GFP_NOWARN);
+ 	if (!pfns) {
+ 		rc = -ENOMEM;
+ 		goto out;
+diff --git a/fs/afs/fs_probe.c b/fs/afs/fs_probe.c
+index 3ac5fcf98d0d6..daaf3810cc925 100644
+--- a/fs/afs/fs_probe.c
++++ b/fs/afs/fs_probe.c
+@@ -366,12 +366,15 @@ void afs_fs_probe_dispatcher(struct work_struct *work)
+ 	unsigned long nowj, timer_at, poll_at;
+ 	bool first_pass = true, set_timer = false;
+ 
+-	if (!net->live)
++	if (!net->live) {
++		afs_dec_servers_outstanding(net);
+ 		return;
++	}
+ 
+ 	_enter("");
+ 
+ 	if (list_empty(&net->fs_probe_fast) && list_empty(&net->fs_probe_slow)) {
++		afs_dec_servers_outstanding(net);
+ 		_leave(" [none]");
+ 		return;
+ 	}
+diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
+index e1eae7ea823ae..bb202ad369d53 100644
+--- a/fs/binfmt_misc.c
++++ b/fs/binfmt_misc.c
+@@ -44,10 +44,10 @@ static LIST_HEAD(entries);
+ static int enabled = 1;
+ 
+ enum {Enabled, Magic};
+-#define MISC_FMT_PRESERVE_ARGV0 (1 << 31)
+-#define MISC_FMT_OPEN_BINARY (1 << 30)
+-#define MISC_FMT_CREDENTIALS (1 << 29)
+-#define MISC_FMT_OPEN_FILE (1 << 28)
++#define MISC_FMT_PRESERVE_ARGV0 (1UL << 31)
++#define MISC_FMT_OPEN_BINARY (1UL << 30)
++#define MISC_FMT_CREDENTIALS (1UL << 29)
++#define MISC_FMT_OPEN_FILE (1UL << 28)
+ 
+ typedef struct {
+ 	struct list_head list;
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index db7c6d22190de..3f6c355356044 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -880,7 +880,10 @@ next_slot:
+ 						args->start - extent_offset,
+ 						0, false);
+ 				ret = btrfs_inc_extent_ref(trans, &ref);
+-				BUG_ON(ret); /* -ENOMEM */
++				if (ret) {
++					btrfs_abort_transaction(trans, ret);
++					break;
++				}
+ 			}
+ 			key.offset = args->start;
+ 		}
+@@ -967,7 +970,10 @@ delete_extent_item:
+ 						key.offset - extent_offset, 0,
+ 						false);
+ 				ret = btrfs_free_extent(trans, &ref);
+-				BUG_ON(ret); /* -ENOMEM */
++				if (ret) {
++					btrfs_abort_transaction(trans, ret);
++					break;
++				}
+ 				args->bytes_found += extent_end - key.offset;
+ 			}
+ 
+diff --git a/fs/char_dev.c b/fs/char_dev.c
+index ba0ded7842a77..3f667292608c0 100644
+--- a/fs/char_dev.c
++++ b/fs/char_dev.c
+@@ -547,7 +547,7 @@ int cdev_device_add(struct cdev *cdev, struct device *dev)
+ 	}
+ 
+ 	rc = device_add(dev);
+-	if (rc)
++	if (rc && dev->devt)
+ 		cdev_del(cdev);
+ 
+ 	return rc;
+diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
+index 46f5718754f94..d848bc0aac274 100644
+--- a/fs/cifs/cifsencrypt.c
++++ b/fs/cifs/cifsencrypt.c
+@@ -679,7 +679,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
+ unlock:
+ 	cifs_server_unlock(ses->server);
+ setup_ntlmv2_rsp_ret:
+-	kfree(tiblob);
++	kfree_sensitive(tiblob);
+ 
+ 	return rc;
+ }
+@@ -753,14 +753,14 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server)
+ 		server->secmech.ccmaesdecrypt = NULL;
+ 	}
+ 
+-	kfree(server->secmech.sdesccmacaes);
++	kfree_sensitive(server->secmech.sdesccmacaes);
+ 	server->secmech.sdesccmacaes = NULL;
+-	kfree(server->secmech.sdeschmacsha256);
++	kfree_sensitive(server->secmech.sdeschmacsha256);
+ 	server->secmech.sdeschmacsha256 = NULL;
+-	kfree(server->secmech.sdeschmacmd5);
++	kfree_sensitive(server->secmech.sdeschmacmd5);
+ 	server->secmech.sdeschmacmd5 = NULL;
+-	kfree(server->secmech.sdescmd5);
++	kfree_sensitive(server->secmech.sdescmd5);
+ 	server->secmech.sdescmd5 = NULL;
+-	kfree(server->secmech.sdescsha512);
++	kfree_sensitive(server->secmech.sdescsha512);
+ 	server->secmech.sdescsha512 = NULL;
+ }
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index ccad85feb24e8..712a431614480 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -396,6 +396,7 @@ cifs_alloc_inode(struct super_block *sb)
+ 	cifs_inode->epoch = 0;
+ 	spin_lock_init(&cifs_inode->open_file_lock);
+ 	generate_random_uuid(cifs_inode->lease_key);
++	cifs_inode->symlink_target = NULL;
+ 
+ 	/*
+ 	 * Can not set i_flags here - they get immediately overwritten to zero
+@@ -412,7 +413,11 @@ cifs_alloc_inode(struct super_block *sb)
+ static void
+ cifs_free_inode(struct inode *inode)
+ {
+-	kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
++	struct cifsInodeInfo *cinode = CIFS_I(inode);
++
++	if (S_ISLNK(inode->i_mode))
++		kfree(cinode->symlink_target);
++	kmem_cache_free(cifs_inode_cachep, cinode);
+ }
+ 
+ static void
+@@ -1138,6 +1143,30 @@ const struct inode_operations cifs_file_inode_ops = {
+ 	.fiemap = cifs_fiemap,
+ };
+ 
++const char *cifs_get_link(struct dentry *dentry, struct inode *inode,
++			    struct delayed_call *done)
++{
++	char *target_path;
++
++	target_path = kmalloc(PATH_MAX, GFP_KERNEL);
++	if (!target_path)
++		return ERR_PTR(-ENOMEM);
++
++	spin_lock(&inode->i_lock);
++	if (likely(CIFS_I(inode)->symlink_target)) {
++		strscpy(target_path, CIFS_I(inode)->symlink_target, PATH_MAX);
++	} else {
++		kfree(target_path);
++		target_path = ERR_PTR(-EOPNOTSUPP);
++	}
++	spin_unlock(&inode->i_lock);
++
++	if (!IS_ERR(target_path))
++		set_delayed_call(done, kfree_link, target_path);
++
++	return target_path;
++}
++
+ const struct inode_operations cifs_symlink_inode_ops = {
+ 	.get_link = cifs_get_link,
+ 	.permission = cifs_permission,
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index ae7f571a7dba2..b52dca800eac5 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -13,6 +13,8 @@
+ #include <linux/in6.h>
+ #include <linux/inet.h>
+ #include <linux/slab.h>
++#include <linux/scatterlist.h>
++#include <linux/mm.h>
+ #include <linux/mempool.h>
+ #include <linux/workqueue.h>
+ #include <linux/utsname.h>
+@@ -195,6 +197,19 @@ struct cifs_cred {
+ 	struct cifs_ace *aces;
+ };
+ 
++struct cifs_open_info_data {
++	char *symlink_target;
++	union {
++		struct smb2_file_all_info fi;
++		struct smb311_posix_qinfo posix_fi;
++	};
++};
++
++static inline void cifs_free_open_info(struct cifs_open_info_data *data)
++{
++	kfree(data->symlink_target);
++}
++
+ /*
+  *****************************************************************
+  * Except the CIFS PDUs themselves all the
+@@ -317,20 +332,20 @@ struct smb_version_operations {
+ 	int (*is_path_accessible)(const unsigned int, struct cifs_tcon *,
+ 				  struct cifs_sb_info *, const char *);
+ 	/* query path data from the server */
+-	int (*query_path_info)(const unsigned int, struct cifs_tcon *,
+-			       struct cifs_sb_info *, const char *,
+-			       FILE_ALL_INFO *, bool *, bool *);
++	int (*query_path_info)(const unsigned int xid, struct cifs_tcon *tcon,
++			       struct cifs_sb_info *cifs_sb, const char *full_path,
++			       struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse);
+ 	/* query file data from the server */
+-	int (*query_file_info)(const unsigned int, struct cifs_tcon *,
+-			       struct cifs_fid *, FILE_ALL_INFO *);
++	int (*query_file_info)(const unsigned int xid, struct cifs_tcon *tcon,
++			       struct cifsFileInfo *cfile, struct cifs_open_info_data *data);
+ 	/* query reparse tag from srv to determine which type of special file */
+ 	int (*query_reparse_tag)(const unsigned int xid, struct cifs_tcon *tcon,
+ 				struct cifs_sb_info *cifs_sb, const char *path,
+ 				__u32 *reparse_tag);
+ 	/* get server index number */
+-	int (*get_srv_inum)(const unsigned int, struct cifs_tcon *,
+-			    struct cifs_sb_info *, const char *,
+-			    u64 *uniqueid, FILE_ALL_INFO *);
++	int (*get_srv_inum)(const unsigned int xid, struct cifs_tcon *tcon,
++			    struct cifs_sb_info *cifs_sb, const char *full_path, u64 *uniqueid,
++			    struct cifs_open_info_data *data);
+ 	/* set size by path */
+ 	int (*set_path_size)(const unsigned int, struct cifs_tcon *,
+ 			     const char *, __u64, struct cifs_sb_info *, bool);
+@@ -379,8 +394,8 @@ struct smb_version_operations {
+ 			     struct cifs_sb_info *, const char *,
+ 			     char **, bool);
+ 	/* open a file for non-posix mounts */
+-	int (*open)(const unsigned int, struct cifs_open_parms *,
+-		    __u32 *, FILE_ALL_INFO *);
++	int (*open)(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
++		    void *buf);
+ 	/* set fid protocol-specific info */
+ 	void (*set_fid)(struct cifsFileInfo *, struct cifs_fid *, __u32);
+ 	/* close a file */
+@@ -1133,6 +1148,7 @@ struct cifs_fattr {
+ 	struct timespec64 cf_mtime;
+ 	struct timespec64 cf_ctime;
+ 	u32             cf_cifstag;
++	char            *cf_symlink_target;
+ };
+ 
+ /*
+@@ -1395,6 +1411,7 @@ struct cifsFileInfo {
+ 	struct work_struct put; /* work for the final part of _put */
+ 	struct delayed_work deferred;
+ 	bool deferred_close_scheduled; /* Flag to indicate close is scheduled */
++	char *symlink_target;
+ };
+ 
+ struct cifs_io_parms {
+@@ -1553,6 +1570,7 @@ struct cifsInodeInfo {
+ 	struct list_head deferred_closes; /* list of deferred closes */
+ 	spinlock_t deferred_lock; /* protection on deferred list */
+ 	bool lease_granted; /* Flag to indicate whether lease or oplock is granted. */
++	char *symlink_target;
+ };
+ 
+ static inline struct cifsInodeInfo *
+@@ -2121,4 +2139,80 @@ static inline size_t ntlmssp_workstation_name_size(const struct cifs_ses *ses)
+ 	return sizeof(ses->workstation_name);
+ }
+ 
++static inline void move_cifs_info_to_smb2(struct smb2_file_all_info *dst, const FILE_ALL_INFO *src)
++{
++	memcpy(dst, src, (size_t)((u8 *)&src->AccessFlags - (u8 *)src));
++	dst->AccessFlags = src->AccessFlags;
++	dst->CurrentByteOffset = src->CurrentByteOffset;
++	dst->Mode = src->Mode;
++	dst->AlignmentRequirement = src->AlignmentRequirement;
++	dst->FileNameLength = src->FileNameLength;
++}
++
++static inline unsigned int cifs_get_num_sgs(const struct smb_rqst *rqst,
++					    int num_rqst,
++					    const u8 *sig)
++{
++	unsigned int len, skip;
++	unsigned int nents = 0;
++	unsigned long addr;
++	int i, j;
++
++	/* Assumes the first rqst has a transform header as the first iov.
++	 * I.e.
++	 * rqst[0].rq_iov[0]  is transform header
++	 * rqst[0].rq_iov[1+] data to be encrypted/decrypted
++	 * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
++	 */
++	for (i = 0; i < num_rqst; i++) {
++		/*
++		 * The first rqst has a transform header where the
++		 * first 20 bytes are not part of the encrypted blob.
++		 */
++		for (j = 0; j < rqst[i].rq_nvec; j++) {
++			struct kvec *iov = &rqst[i].rq_iov[j];
++
++			skip = (i == 0) && (j == 0) ? 20 : 0;
++			addr = (unsigned long)iov->iov_base + skip;
++			if (unlikely(is_vmalloc_addr((void *)addr))) {
++				len = iov->iov_len - skip;
++				nents += DIV_ROUND_UP(offset_in_page(addr) + len,
++						      PAGE_SIZE);
++			} else {
++				nents++;
++			}
++		}
++		nents += rqst[i].rq_npages;
++	}
++	nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
++	return nents;
++}
++
++/* We can not use the normal sg_set_buf() as we will sometimes pass a
++ * stack object as buf.
++ */
++static inline struct scatterlist *cifs_sg_set_buf(struct scatterlist *sg,
++						  const void *buf,
++						  unsigned int buflen)
++{
++	unsigned long addr = (unsigned long)buf;
++	unsigned int off = offset_in_page(addr);
++
++	addr &= PAGE_MASK;
++	if (unlikely(is_vmalloc_addr((void *)addr))) {
++		do {
++			unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
++
++			sg_set_page(sg++, vmalloc_to_page((void *)addr), len, off);
++
++			off = 0;
++			addr += PAGE_SIZE;
++			buflen -= len;
++		} while (buflen);
++	} else {
++		sg_set_page(sg++, virt_to_page(addr), buflen, off);
++	}
++	return sg;
++}
++
+ #endif	/* _CIFS_GLOB_H */
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+index 71386978858eb..edf6f18ec8b73 100644
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -182,10 +182,9 @@ extern int cifs_unlock_range(struct cifsFileInfo *cfile,
+ extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile);
+ 
+ extern void cifs_down_write(struct rw_semaphore *sem);
+-extern struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid,
+-					      struct file *file,
+-					      struct tcon_link *tlink,
+-					      __u32 oplock);
++struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
++				       struct tcon_link *tlink, __u32 oplock,
++				       const char *symlink_target);
+ extern int cifs_posix_open(const char *full_path, struct inode **inode,
+ 			   struct super_block *sb, int mode,
+ 			   unsigned int f_flags, __u32 *oplock, __u16 *netfid,
+@@ -200,9 +199,9 @@ extern int cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
+ extern struct inode *cifs_iget(struct super_block *sb,
+ 			       struct cifs_fattr *fattr);
+ 
+-extern int cifs_get_inode_info(struct inode **inode, const char *full_path,
+-			       FILE_ALL_INFO *data, struct super_block *sb,
+-			       int xid, const struct cifs_fid *fid);
++int cifs_get_inode_info(struct inode **inode, const char *full_path,
++			struct cifs_open_info_data *data, struct super_block *sb, int xid,
++			const struct cifs_fid *fid);
+ extern int smb311_posix_get_inode_info(struct inode **pinode, const char *search_path,
+ 			struct super_block *sb, unsigned int xid);
+ extern int cifs_get_inode_info_unix(struct inode **pinode,
+@@ -602,8 +601,8 @@ int cifs_alloc_hash(const char *name, struct crypto_shash **shash,
+ 		    struct sdesc **sdesc);
+ void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc);
+ 
+-extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
+-				unsigned int *len, unsigned int *offset);
++void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page,
++			  unsigned int *len, unsigned int *offset);
+ struct cifs_chan *
+ cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server);
+ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses);
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 317ca1be9c4c0..816161f51b29d 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -311,7 +311,7 @@ cifs_abort_connection(struct TCP_Server_Info *server)
+ 	}
+ 	server->sequence_number = 0;
+ 	server->session_estab = false;
+-	kfree(server->session_key.response);
++	kfree_sensitive(server->session_key.response);
+ 	server->session_key.response = NULL;
+ 	server->session_key.len = 0;
+ 	server->lstrp = jiffies;
+@@ -1580,7 +1580,7 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
+ 
+ 	cifs_crypto_secmech_release(server);
+ 
+-	kfree(server->session_key.response);
++	kfree_sensitive(server->session_key.response);
+ 	server->session_key.response = NULL;
+ 	server->session_key.len = 0;
+ 	kfree(server->hostname);
+@@ -4141,7 +4141,7 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
+ 		if (ses->auth_key.response) {
+ 			cifs_dbg(FYI, "Free previous auth_key.response = %p\n",
+ 				 ses->auth_key.response);
+-			kfree(ses->auth_key.response);
++			kfree_sensitive(ses->auth_key.response);
+ 			ses->auth_key.response = NULL;
+ 			ses->auth_key.len = 0;
+ 		}
+diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
+index 05c78a18ade07..c85816cf2d9b3 100644
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -165,10 +165,9 @@ check_name(struct dentry *direntry, struct cifs_tcon *tcon)
+ 
+ /* Inode operations in similar order to how they appear in Linux file fs.h */
+ 
+-static int
+-cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
+-	       struct tcon_link *tlink, unsigned oflags, umode_t mode,
+-	       __u32 *oplock, struct cifs_fid *fid)
++static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
++			  struct tcon_link *tlink, unsigned int oflags, umode_t mode, __u32 *oplock,
++			  struct cifs_fid *fid, struct cifs_open_info_data *buf)
+ {
+ 	int rc = -ENOENT;
+ 	int create_options = CREATE_NOT_DIR;
+@@ -177,7 +176,6 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
+ 	struct cifs_tcon *tcon = tlink_tcon(tlink);
+ 	const char *full_path;
+ 	void *page = alloc_dentry_path();
+-	FILE_ALL_INFO *buf = NULL;
+ 	struct inode *newinode = NULL;
+ 	int disposition;
+ 	struct TCP_Server_Info *server = tcon->ses->server;
+@@ -290,12 +288,6 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
+ 		goto out;
+ 	}
+ 
+-	buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+-	if (buf == NULL) {
+-		rc = -ENOMEM;
+-		goto out;
+-	}
+-
+ 	/*
+ 	 * if we're not using unix extensions, see if we need to set
+ 	 * ATTR_READONLY on the create call
+@@ -364,8 +356,7 @@ cifs_create_get_file_info:
+ 	{
+ #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
+ 		/* TODO: Add support for calling POSIX query info here, but passing in fid */
+-		rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb,
+-					 xid, fid);
++		rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, xid, fid);
+ 		if (newinode) {
+ 			if (server->ops->set_lease_key)
+ 				server->ops->set_lease_key(newinode, fid);
+@@ -402,7 +393,6 @@ cifs_create_set_dentry:
+ 	d_add(direntry, newinode);
+ 
+ out:
+-	kfree(buf);
+ 	free_dentry_path(page);
+ 	return rc;
+ 
+@@ -427,6 +417,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
+ 	struct cifs_pending_open open;
+ 	__u32 oplock;
+ 	struct cifsFileInfo *file_info;
++	struct cifs_open_info_data buf = {};
+ 
+ 	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
+ 		return -EIO;
+@@ -484,8 +475,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
+ 	cifs_add_pending_open(&fid, tlink, &open);
+ 
+ 	rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
+-			    &oplock, &fid);
+-
++			    &oplock, &fid, &buf);
+ 	if (rc) {
+ 		cifs_del_pending_open(&open);
+ 		goto out;
+@@ -510,7 +500,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
+ 			file->f_op = &cifs_file_direct_ops;
+ 		}
+ 
+-	file_info = cifs_new_fileinfo(&fid, file, tlink, oplock);
++	file_info = cifs_new_fileinfo(&fid, file, tlink, oplock, buf.symlink_target);
+ 	if (file_info == NULL) {
+ 		if (server->ops->close)
+ 			server->ops->close(xid, tcon, &fid);
+@@ -526,6 +516,7 @@ out:
+ 	cifs_put_tlink(tlink);
+ out_free_xid:
+ 	free_xid(xid);
++	cifs_free_open_info(&buf);
+ 	return rc;
+ }
+ 
+@@ -547,6 +538,7 @@ int cifs_create(struct user_namespace *mnt_userns, struct inode *inode,
+ 	struct TCP_Server_Info *server;
+ 	struct cifs_fid fid;
+ 	__u32 oplock;
++	struct cifs_open_info_data buf = {};
+ 
+ 	cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n",
+ 		 inode, direntry, direntry);
+@@ -567,11 +559,11 @@ int cifs_create(struct user_namespace *mnt_userns, struct inode *inode,
+ 	if (server->ops->new_lease_key)
+ 		server->ops->new_lease_key(&fid);
+ 
+-	rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
+-			    &oplock, &fid);
++	rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, &buf);
+ 	if (!rc && server->ops->close)
+ 		server->ops->close(xid, tcon, &fid);
+ 
++	cifs_free_open_info(&buf);
+ 	cifs_put_tlink(tlink);
+ out_free_xid:
+ 	free_xid(xid);
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 5c045dd697846..391fd2580dabb 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -209,16 +209,14 @@ posix_open_ret:
+ }
+ #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
+ 
+-static int
+-cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
+-	     struct cifs_tcon *tcon, unsigned int f_flags, __u32 *oplock,
+-	     struct cifs_fid *fid, unsigned int xid)
++static int cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
++			struct cifs_tcon *tcon, unsigned int f_flags, __u32 *oplock,
++			struct cifs_fid *fid, unsigned int xid, struct cifs_open_info_data *buf)
+ {
+ 	int rc;
+ 	int desired_access;
+ 	int disposition;
+ 	int create_options = CREATE_NOT_DIR;
+-	FILE_ALL_INFO *buf;
+ 	struct TCP_Server_Info *server = tcon->ses->server;
+ 	struct cifs_open_parms oparms;
+ 
+@@ -255,10 +253,6 @@ cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *ci
+ 
+ 	/* BB pass O_SYNC flag through on file attributes .. BB */
+ 
+-	buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+-	if (!buf)
+-		return -ENOMEM;
+-
+ 	/* O_SYNC also has bit for O_DSYNC so following check picks up either */
+ 	if (f_flags & O_SYNC)
+ 		create_options |= CREATE_WRITE_THROUGH;
+@@ -276,9 +270,8 @@ cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *ci
+ 	oparms.reconnect = false;
+ 
+ 	rc = server->ops->open(xid, &oparms, oplock, buf);
+-
+ 	if (rc)
+-		goto out;
++		return rc;
+ 
+ 	/* TODO: Add support for calling posix query info but with passing in fid */
+ 	if (tcon->unix_ext)
+@@ -294,8 +287,6 @@ cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_sb_info *ci
+ 			rc = -EOPENSTALE;
+ 	}
+ 
+-out:
+-	kfree(buf);
+ 	return rc;
+ }
+ 
+@@ -325,9 +316,9 @@ cifs_down_write(struct rw_semaphore *sem)
+ 
+ static void cifsFileInfo_put_work(struct work_struct *work);
+ 
+-struct cifsFileInfo *
+-cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
+-		  struct tcon_link *tlink, __u32 oplock)
++struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
++				       struct tcon_link *tlink, __u32 oplock,
++				       const char *symlink_target)
+ {
+ 	struct dentry *dentry = file_dentry(file);
+ 	struct inode *inode = d_inode(dentry);
+@@ -347,6 +338,15 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
+ 		return NULL;
+ 	}
+ 
++	if (symlink_target) {
++		cfile->symlink_target = kstrdup(symlink_target, GFP_KERNEL);
++		if (!cfile->symlink_target) {
++			kfree(fdlocks);
++			kfree(cfile);
++			return NULL;
++		}
++	}
++
+ 	INIT_LIST_HEAD(&fdlocks->locks);
+ 	fdlocks->cfile = cfile;
+ 	cfile->llist = fdlocks;
+@@ -440,6 +440,7 @@ static void cifsFileInfo_put_final(struct cifsFileInfo *cifs_file)
+ 	cifs_put_tlink(cifs_file->tlink);
+ 	dput(cifs_file->dentry);
+ 	cifs_sb_deactive(sb);
++	kfree(cifs_file->symlink_target);
+ 	kfree(cifs_file);
+ }
+ 
+@@ -572,6 +573,7 @@ int cifs_open(struct inode *inode, struct file *file)
+ 	bool posix_open_ok = false;
+ 	struct cifs_fid fid;
+ 	struct cifs_pending_open open;
++	struct cifs_open_info_data data = {};
+ 
+ 	xid = get_xid();
+ 
+@@ -662,15 +664,15 @@ int cifs_open(struct inode *inode, struct file *file)
+ 		if (server->ops->get_lease_key)
+ 			server->ops->get_lease_key(inode, &fid);
+ 
+-		rc = cifs_nt_open(full_path, inode, cifs_sb, tcon,
+-				  file->f_flags, &oplock, &fid, xid);
++		rc = cifs_nt_open(full_path, inode, cifs_sb, tcon, file->f_flags, &oplock, &fid,
++				  xid, &data);
+ 		if (rc) {
+ 			cifs_del_pending_open(&open);
+ 			goto out;
+ 		}
+ 	}
+ 
+-	cfile = cifs_new_fileinfo(&fid, file, tlink, oplock);
++	cfile = cifs_new_fileinfo(&fid, file, tlink, oplock, data.symlink_target);
+ 	if (cfile == NULL) {
+ 		if (server->ops->close)
+ 			server->ops->close(xid, tcon, &fid);
+@@ -712,6 +714,7 @@ out:
+ 	free_dentry_path(page);
+ 	free_xid(xid);
+ 	cifs_put_tlink(tlink);
++	cifs_free_open_info(&data);
+ 	return rc;
+ }
+ 
+diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
+index 0e13dec86b252..45119597c7655 100644
+--- a/fs/cifs/fs_context.c
++++ b/fs/cifs/fs_context.c
+@@ -791,6 +791,13 @@ do {									\
+ 	cifs_sb->ctx->field = NULL;					\
+ } while (0)
+ 
++#define STEAL_STRING_SENSITIVE(cifs_sb, ctx, field)			\
++do {									\
++	kfree_sensitive(ctx->field);					\
++	ctx->field = cifs_sb->ctx->field;				\
++	cifs_sb->ctx->field = NULL;					\
++} while (0)
++
+ static int smb3_reconfigure(struct fs_context *fc)
+ {
+ 	struct smb3_fs_context *ctx = smb3_fc2context(fc);
+@@ -811,7 +818,7 @@ static int smb3_reconfigure(struct fs_context *fc)
+ 	STEAL_STRING(cifs_sb, ctx, UNC);
+ 	STEAL_STRING(cifs_sb, ctx, source);
+ 	STEAL_STRING(cifs_sb, ctx, username);
+-	STEAL_STRING(cifs_sb, ctx, password);
++	STEAL_STRING_SENSITIVE(cifs_sb, ctx, password);
+ 	STEAL_STRING(cifs_sb, ctx, domainname);
+ 	STEAL_STRING(cifs_sb, ctx, nodename);
+ 	STEAL_STRING(cifs_sb, ctx, iocharset);
+@@ -1162,7 +1169,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
+ 		}
+ 		break;
+ 	case Opt_pass:
+-		kfree(ctx->password);
++		kfree_sensitive(ctx->password);
+ 		ctx->password = NULL;
+ 		if (strlen(param->string) == 0)
+ 			break;
+@@ -1470,6 +1477,7 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
+ 	return 0;
+ 
+  cifs_parse_mount_err:
++	kfree_sensitive(ctx->password);
+ 	return -EINVAL;
+ }
+ 
+diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
+index bac08c20f559b..b4555f6e327f1 100644
+--- a/fs/cifs/inode.c
++++ b/fs/cifs/inode.c
+@@ -210,6 +210,12 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
+ 		 */
+ 		inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
+ 	}
++
++	if (S_ISLNK(fattr->cf_mode)) {
++		kfree(cifs_i->symlink_target);
++		cifs_i->symlink_target = fattr->cf_symlink_target;
++		fattr->cf_symlink_target = NULL;
++	}
+ 	spin_unlock(&inode->i_lock);
+ 
+ 	if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL)
+@@ -347,13 +353,22 @@ cifs_get_file_info_unix(struct file *filp)
+ 	int rc;
+ 	unsigned int xid;
+ 	FILE_UNIX_BASIC_INFO find_data;
+-	struct cifs_fattr fattr;
++	struct cifs_fattr fattr = {};
+ 	struct inode *inode = file_inode(filp);
+ 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+ 	struct cifsFileInfo *cfile = filp->private_data;
+ 	struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
+ 
+ 	xid = get_xid();
++
++	if (cfile->symlink_target) {
++		fattr.cf_symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
++		if (!fattr.cf_symlink_target) {
++			rc = -ENOMEM;
++			goto cifs_gfiunix_out;
++		}
++	}
++
+ 	rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->fid.netfid, &find_data);
+ 	if (!rc) {
+ 		cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
+@@ -378,6 +393,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
+ 	FILE_UNIX_BASIC_INFO find_data;
+ 	struct cifs_fattr fattr;
+ 	struct cifs_tcon *tcon;
++	struct TCP_Server_Info *server;
+ 	struct tcon_link *tlink;
+ 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ 
+@@ -387,10 +403,12 @@ int cifs_get_inode_info_unix(struct inode **pinode,
+ 	if (IS_ERR(tlink))
+ 		return PTR_ERR(tlink);
+ 	tcon = tlink_tcon(tlink);
++	server = tcon->ses->server;
+ 
+ 	/* could have done a find first instead but this returns more info */
+ 	rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
+ 				  cifs_sb->local_nls, cifs_remap(cifs_sb));
++	cifs_dbg(FYI, "%s: query path info: rc = %d\n", __func__, rc);
+ 	cifs_put_tlink(tlink);
+ 
+ 	if (!rc) {
+@@ -410,6 +428,17 @@ int cifs_get_inode_info_unix(struct inode **pinode,
+ 			cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc);
+ 	}
+ 
++	if (S_ISLNK(fattr.cf_mode) && !fattr.cf_symlink_target) {
++		if (!server->ops->query_symlink)
++			return -EOPNOTSUPP;
++		rc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path,
++						&fattr.cf_symlink_target, false);
++		if (rc) {
++			cifs_dbg(FYI, "%s: query_symlink: %d\n", __func__, rc);
++			goto cgiiu_exit;
++		}
++	}
++
+ 	if (*pinode == NULL) {
+ 		/* get new inode */
+ 		cifs_fill_uniqueid(sb, &fattr);
+@@ -432,6 +461,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
+ 	}
+ 
+ cgiiu_exit:
++	kfree(fattr.cf_symlink_target);
+ 	return rc;
+ }
+ #else
+@@ -601,10 +631,10 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
+ }
+ 
+ /* Fill a cifs_fattr struct with info from POSIX info struct */
+-static void
+-smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo *info,
+-			   struct super_block *sb, bool adjust_tz, bool symlink)
++static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_info_data *data,
++				       struct super_block *sb, bool adjust_tz, bool symlink)
+ {
++	struct smb311_posix_qinfo *info = &data->posix_fi;
+ 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ 	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+ 
+@@ -639,6 +669,8 @@ smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo *
+ 	if (symlink) {
+ 		fattr->cf_mode |= S_IFLNK;
+ 		fattr->cf_dtype = DT_LNK;
++		fattr->cf_symlink_target = data->symlink_target;
++		data->symlink_target = NULL;
+ 	} else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
+ 		fattr->cf_mode |= S_IFDIR;
+ 		fattr->cf_dtype = DT_DIR;
+@@ -655,13 +687,11 @@ smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo *
+ 		fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink);
+ }
+ 
+-
+-/* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
+-static void
+-cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
+-		       struct super_block *sb, bool adjust_tz,
+-		       bool symlink, u32 reparse_tag)
++static void cifs_open_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_info_data *data,
++				    struct super_block *sb, bool adjust_tz, bool symlink,
++				    u32 reparse_tag)
+ {
++	struct smb2_file_all_info *info = &data->fi;
+ 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ 	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+ 
+@@ -703,7 +733,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
+ 	} else if (reparse_tag == IO_REPARSE_TAG_LX_BLK) {
+ 		fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode;
+ 		fattr->cf_dtype = DT_BLK;
+-	} else if (symlink) { /* TODO add more reparse tag checks */
++	} else if (symlink || reparse_tag == IO_REPARSE_TAG_SYMLINK ||
++		   reparse_tag == IO_REPARSE_TAG_NFS) {
+ 		fattr->cf_mode = S_IFLNK;
+ 		fattr->cf_dtype = DT_LNK;
+ 	} else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
+@@ -735,6 +766,11 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
+ 		}
+ 	}
+ 
++	if (S_ISLNK(fattr->cf_mode)) {
++		fattr->cf_symlink_target = data->symlink_target;
++		data->symlink_target = NULL;
++	}
++
+ 	fattr->cf_uid = cifs_sb->ctx->linux_uid;
+ 	fattr->cf_gid = cifs_sb->ctx->linux_gid;
+ }
+@@ -744,23 +780,28 @@ cifs_get_file_info(struct file *filp)
+ {
+ 	int rc;
+ 	unsigned int xid;
+-	FILE_ALL_INFO find_data;
++	struct cifs_open_info_data data = {};
+ 	struct cifs_fattr fattr;
+ 	struct inode *inode = file_inode(filp);
+ 	struct cifsFileInfo *cfile = filp->private_data;
+ 	struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
+ 	struct TCP_Server_Info *server = tcon->ses->server;
++	bool symlink = false;
++	u32 tag = 0;
+ 
+ 	if (!server->ops->query_file_info)
+ 		return -ENOSYS;
+ 
+ 	xid = get_xid();
+-	rc = server->ops->query_file_info(xid, tcon, &cfile->fid, &find_data);
++	rc = server->ops->query_file_info(xid, tcon, cfile, &data);
+ 	switch (rc) {
+ 	case 0:
+ 		/* TODO: add support to query reparse tag */
+-		cifs_all_info_to_fattr(&fattr, &find_data, inode->i_sb, false,
+-				       false, 0 /* no reparse tag */);
++		if (data.symlink_target) {
++			symlink = true;
++			tag = IO_REPARSE_TAG_SYMLINK;
++		}
++		cifs_open_info_to_fattr(&fattr, &data, inode->i_sb, false, symlink, tag);
+ 		break;
+ 	case -EREMOTE:
+ 		cifs_create_dfs_fattr(&fattr, inode->i_sb);
+@@ -789,6 +830,7 @@ cifs_get_file_info(struct file *filp)
+ 	/* if filetype is different, return error */
+ 	rc = cifs_fattr_to_inode(inode, &fattr);
+ cgfi_exit:
++	cifs_free_open_info(&data);
+ 	free_xid(xid);
+ 	return rc;
+ }
+@@ -860,14 +902,9 @@ cifs_backup_query_path_info(int xid,
+ }
+ #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
+ 
+-static void
+-cifs_set_fattr_ino(int xid,
+-		   struct cifs_tcon *tcon,
+-		   struct super_block *sb,
+-		   struct inode **inode,
+-		   const char *full_path,
+-		   FILE_ALL_INFO *data,
+-		   struct cifs_fattr *fattr)
++static void cifs_set_fattr_ino(int xid, struct cifs_tcon *tcon, struct super_block *sb,
++			       struct inode **inode, const char *full_path,
++			       struct cifs_open_info_data *data, struct cifs_fattr *fattr)
+ {
+ 	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
+ 	struct TCP_Server_Info *server = tcon->ses->server;
+@@ -885,11 +922,8 @@ cifs_set_fattr_ino(int xid,
+ 	 * If we have an inode pass a NULL tcon to ensure we don't
+ 	 * make a round trip to the server. This only works for SMB2+.
+ 	 */
+-	rc = server->ops->get_srv_inum(xid,
+-				       *inode ? NULL : tcon,
+-				       cifs_sb, full_path,
+-				       &fattr->cf_uniqueid,
+-				       data);
++	rc = server->ops->get_srv_inum(xid, *inode ? NULL : tcon, cifs_sb, full_path,
++				       &fattr->cf_uniqueid, data);
+ 	if (rc) {
+ 		/*
+ 		 * If that fails reuse existing ino or generate one
+@@ -923,14 +957,10 @@ static inline bool is_inode_cache_good(struct inode *ino)
+ 	return ino && CIFS_CACHE_READ(CIFS_I(ino)) && CIFS_I(ino)->time != 0;
+ }
+ 
+-int
+-cifs_get_inode_info(struct inode **inode,
+-		    const char *full_path,
+-		    FILE_ALL_INFO *in_data,
+-		    struct super_block *sb, int xid,
+-		    const struct cifs_fid *fid)
++int cifs_get_inode_info(struct inode **inode, const char *full_path,
++			struct cifs_open_info_data *data, struct super_block *sb, int xid,
++			const struct cifs_fid *fid)
+ {
+-
+ 	struct cifs_tcon *tcon;
+ 	struct TCP_Server_Info *server;
+ 	struct tcon_link *tlink;
+@@ -938,8 +968,7 @@ cifs_get_inode_info(struct inode **inode,
+ 	bool adjust_tz = false;
+ 	struct cifs_fattr fattr = {0};
+ 	bool is_reparse_point = false;
+-	FILE_ALL_INFO *data = in_data;
+-	FILE_ALL_INFO *tmp_data = NULL;
++	struct cifs_open_info_data tmp_data = {};
+ 	void *smb1_backup_rsp_buf = NULL;
+ 	int rc = 0;
+ 	int tmprc = 0;
+@@ -960,21 +989,15 @@ cifs_get_inode_info(struct inode **inode,
+ 			cifs_dbg(FYI, "No need to revalidate cached inode sizes\n");
+ 			goto out;
+ 		}
+-		tmp_data = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+-		if (!tmp_data) {
+-			rc = -ENOMEM;
+-			goto out;
+-		}
+-		rc = server->ops->query_path_info(xid, tcon, cifs_sb,
+-						 full_path, tmp_data,
+-						 &adjust_tz, &is_reparse_point);
++		rc = server->ops->query_path_info(xid, tcon, cifs_sb, full_path, &tmp_data,
++						  &adjust_tz, &is_reparse_point);
+ #ifdef CONFIG_CIFS_DFS_UPCALL
+ 		if (rc == -ENOENT && is_tcon_dfs(tcon))
+ 			rc = cifs_dfs_query_info_nonascii_quirk(xid, tcon,
+ 								cifs_sb,
+ 								full_path);
+ #endif
+-		data = tmp_data;
++		data = &tmp_data;
+ 	}
+ 
+ 	/*
+@@ -988,14 +1011,24 @@ cifs_get_inode_info(struct inode **inode,
+ 		 * since we have to check if its reparse tag matches a known
+ 		 * special file type e.g. symlink or fifo or char etc.
+ 		 */
+-		if ((le32_to_cpu(data->Attributes) & ATTR_REPARSE) &&
+-		    server->ops->query_reparse_tag) {
+-			rc = server->ops->query_reparse_tag(xid, tcon, cifs_sb,
+-						full_path, &reparse_tag);
+-			cifs_dbg(FYI, "reparse tag 0x%x\n", reparse_tag);
++		if (is_reparse_point && data->symlink_target) {
++			reparse_tag = IO_REPARSE_TAG_SYMLINK;
++		} else if ((le32_to_cpu(data->fi.Attributes) & ATTR_REPARSE) &&
++			   server->ops->query_reparse_tag) {
++			tmprc = server->ops->query_reparse_tag(xid, tcon, cifs_sb, full_path,
++							    &reparse_tag);
++			if (tmprc)
++				cifs_dbg(FYI, "%s: query_reparse_tag: rc = %d\n", __func__, tmprc);
++			if (server->ops->query_symlink) {
++				tmprc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path,
++								   &data->symlink_target,
++								   is_reparse_point);
++				if (tmprc)
++					cifs_dbg(FYI, "%s: query_symlink: rc = %d\n", __func__,
++						 tmprc);
++			}
+ 		}
+-		cifs_all_info_to_fattr(&fattr, data, sb, adjust_tz,
+-				       is_reparse_point, reparse_tag);
++		cifs_open_info_to_fattr(&fattr, data, sb, adjust_tz, is_reparse_point, reparse_tag);
+ 		break;
+ 	case -EREMOTE:
+ 		/* DFS link, no metadata available on this server */
+@@ -1014,18 +1047,20 @@ cifs_get_inode_info(struct inode **inode,
+ 		 */
+ 		if (backup_cred(cifs_sb) && is_smb1_server(server)) {
+ 			/* for easier reading */
++			FILE_ALL_INFO *fi;
+ 			FILE_DIRECTORY_INFO *fdi;
+ 			SEARCH_ID_FULL_DIR_INFO *si;
+ 
+ 			rc = cifs_backup_query_path_info(xid, tcon, sb,
+ 							 full_path,
+ 							 &smb1_backup_rsp_buf,
+-							 &data);
++							 &fi);
+ 			if (rc)
+ 				goto out;
+ 
+-			fdi = (FILE_DIRECTORY_INFO *)data;
+-			si = (SEARCH_ID_FULL_DIR_INFO *)data;
++			move_cifs_info_to_smb2(&data->fi, fi);
++			fdi = (FILE_DIRECTORY_INFO *)fi;
++			si = (SEARCH_ID_FULL_DIR_INFO *)fi;
+ 
+ 			cifs_dir_info_to_fattr(&fattr, fdi, cifs_sb);
+ 			fattr.cf_uniqueid = le64_to_cpu(si->UniqueId);
+@@ -1123,7 +1158,8 @@ handle_mnt_opt:
+ out:
+ 	cifs_buf_release(smb1_backup_rsp_buf);
+ 	cifs_put_tlink(tlink);
+-	kfree(tmp_data);
++	cifs_free_open_info(&tmp_data);
++	kfree(fattr.cf_symlink_target);
+ 	return rc;
+ }
+ 
+@@ -1138,7 +1174,7 @@ smb311_posix_get_inode_info(struct inode **inode,
+ 	bool adjust_tz = false;
+ 	struct cifs_fattr fattr = {0};
+ 	bool symlink = false;
+-	struct smb311_posix_qinfo *data = NULL;
++	struct cifs_open_info_data data = {};
+ 	int rc = 0;
+ 	int tmprc = 0;
+ 
+@@ -1155,15 +1191,9 @@ smb311_posix_get_inode_info(struct inode **inode,
+ 		cifs_dbg(FYI, "No need to revalidate cached inode sizes\n");
+ 		goto out;
+ 	}
+-	data = kmalloc(sizeof(struct smb311_posix_qinfo), GFP_KERNEL);
+-	if (!data) {
+-		rc = -ENOMEM;
+-		goto out;
+-	}
+ 
+-	rc = smb311_posix_query_path_info(xid, tcon, cifs_sb,
+-						  full_path, data,
+-						  &adjust_tz, &symlink);
++	rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, full_path, &data, &adjust_tz,
++					  &symlink);
+ 
+ 	/*
+ 	 * 2. Convert it to internal cifs metadata (fattr)
+@@ -1171,7 +1201,7 @@ smb311_posix_get_inode_info(struct inode **inode,
+ 
+ 	switch (rc) {
+ 	case 0:
+-		smb311_posix_info_to_fattr(&fattr, data, sb, adjust_tz, symlink);
++		smb311_posix_info_to_fattr(&fattr, &data, sb, adjust_tz, symlink);
+ 		break;
+ 	case -EREMOTE:
+ 		/* DFS link, no metadata available on this server */
+@@ -1228,7 +1258,8 @@ smb311_posix_get_inode_info(struct inode **inode,
+ 	}
+ out:
+ 	cifs_put_tlink(tlink);
+-	kfree(data);
++	cifs_free_open_info(&data);
++	kfree(fattr.cf_symlink_target);
+ 	return rc;
+ }
+ 
+diff --git a/fs/cifs/link.c b/fs/cifs/link.c
+index 6803cb27eecc3..8042dbdd182bc 100644
+--- a/fs/cifs/link.c
++++ b/fs/cifs/link.c
+@@ -202,40 +202,6 @@ out:
+ 	return rc;
+ }
+ 
+-static int
+-query_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon,
+-		 struct cifs_sb_info *cifs_sb, const unsigned char *path,
+-		 char **symlinkinfo)
+-{
+-	int rc;
+-	u8 *buf = NULL;
+-	unsigned int link_len = 0;
+-	unsigned int bytes_read = 0;
+-
+-	buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
+-	if (!buf)
+-		return -ENOMEM;
+-
+-	if (tcon->ses->server->ops->query_mf_symlink)
+-		rc = tcon->ses->server->ops->query_mf_symlink(xid, tcon,
+-					      cifs_sb, path, buf, &bytes_read);
+-	else
+-		rc = -ENOSYS;
+-
+-	if (rc)
+-		goto out;
+-
+-	if (bytes_read == 0) { /* not a symlink */
+-		rc = -EINVAL;
+-		goto out;
+-	}
+-
+-	rc = parse_mf_symlink(buf, bytes_read, &link_len, symlinkinfo);
+-out:
+-	kfree(buf);
+-	return rc;
+-}
+-
+ int
+ check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+ 		 struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
+@@ -245,6 +211,7 @@ check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+ 	u8 *buf = NULL;
+ 	unsigned int link_len = 0;
+ 	unsigned int bytes_read = 0;
++	char *symlink = NULL;
+ 
+ 	if (!couldbe_mf_symlink(fattr))
+ 		/* it's not a symlink */
+@@ -266,7 +233,7 @@ check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+ 	if (bytes_read == 0) /* not a symlink */
+ 		goto out;
+ 
+-	rc = parse_mf_symlink(buf, bytes_read, &link_len, NULL);
++	rc = parse_mf_symlink(buf, bytes_read, &link_len, &symlink);
+ 	if (rc == -EINVAL) {
+ 		/* it's not a symlink */
+ 		rc = 0;
+@@ -281,6 +248,7 @@ check_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+ 	fattr->cf_mode &= ~S_IFMT;
+ 	fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
+ 	fattr->cf_dtype = DT_LNK;
++	fattr->cf_symlink_target = symlink;
+ out:
+ 	kfree(buf);
+ 	return rc;
+@@ -600,75 +568,6 @@ cifs_hl_exit:
+ 	return rc;
+ }
+ 
+-const char *
+-cifs_get_link(struct dentry *direntry, struct inode *inode,
+-	      struct delayed_call *done)
+-{
+-	int rc = -ENOMEM;
+-	unsigned int xid;
+-	const char *full_path;
+-	void *page;
+-	char *target_path = NULL;
+-	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+-	struct tcon_link *tlink = NULL;
+-	struct cifs_tcon *tcon;
+-	struct TCP_Server_Info *server;
+-
+-	if (!direntry)
+-		return ERR_PTR(-ECHILD);
+-
+-	xid = get_xid();
+-
+-	tlink = cifs_sb_tlink(cifs_sb);
+-	if (IS_ERR(tlink)) {
+-		free_xid(xid);
+-		return ERR_CAST(tlink);
+-	}
+-	tcon = tlink_tcon(tlink);
+-	server = tcon->ses->server;
+-
+-	page = alloc_dentry_path();
+-	full_path = build_path_from_dentry(direntry, page);
+-	if (IS_ERR(full_path)) {
+-		free_xid(xid);
+-		cifs_put_tlink(tlink);
+-		free_dentry_path(page);
+-		return ERR_CAST(full_path);
+-	}
+-
+-	cifs_dbg(FYI, "Full path: %s inode = 0x%p\n", full_path, inode);
+-
+-	rc = -EACCES;
+-	/*
+-	 * First try Minshall+French Symlinks, if configured
+-	 * and fallback to UNIX Extensions Symlinks.
+-	 */
+-	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
+-		rc = query_mf_symlink(xid, tcon, cifs_sb, full_path,
+-				      &target_path);
+-
+-	if (rc != 0 && server->ops->query_symlink) {
+-		struct cifsInodeInfo *cifsi = CIFS_I(inode);
+-		bool reparse_point = false;
+-
+-		if (cifsi->cifsAttrs & ATTR_REPARSE)
+-			reparse_point = true;
+-
+-		rc = server->ops->query_symlink(xid, tcon, cifs_sb, full_path,
+-						&target_path, reparse_point);
+-	}
+-
+-	free_dentry_path(page);
+-	free_xid(xid);
+-	cifs_put_tlink(tlink);
+-	if (rc != 0) {
+-		kfree(target_path);
+-		return ERR_PTR(rc);
+-	}
+-	set_delayed_call(done, kfree_link, target_path);
+-	return target_path;
+-}
+-
+ int
+ cifs_symlink(struct user_namespace *mnt_userns, struct inode *inode,
+ 	     struct dentry *direntry, const char *symname)
+diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
+index 35085fa866367..1efb5ca9fd804 100644
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -1123,7 +1123,7 @@ cifs_alloc_hash(const char *name,
+ void
+ cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc)
+ {
+-	kfree(*sdesc);
++	kfree_sensitive(*sdesc);
+ 	*sdesc = NULL;
+ 	if (*shash)
+ 		crypto_free_shash(*shash);
+@@ -1137,8 +1137,8 @@ cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc)
+  * @len: Where to store the length for this page:
+  * @offset: Where to store the offset for this page
+  */
+-void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
+-				unsigned int *len, unsigned int *offset)
++void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page,
++			  unsigned int *len, unsigned int *offset)
+ {
+ 	*len = rqst->rq_pagesz;
+ 	*offset = (page == 0) ? rqst->rq_offset : 0;
+diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
+index 8e060c00c9690..6a78bcc51e816 100644
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -994,6 +994,8 @@ static int cifs_filldir(char *find_entry, struct file *file,
+ 		cifs_unix_basic_to_fattr(&fattr,
+ 					 &((FILE_UNIX_INFO *)find_entry)->basic,
+ 					 cifs_sb);
++		if (S_ISLNK(fattr.cf_mode))
++			fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
+ 		break;
+ 	case SMB_FIND_FILE_INFO_STANDARD:
+ 		cifs_std_info_to_fattr(&fattr,
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index 6a85136da27ce..5d93154572c01 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -1214,10 +1214,18 @@ out_free_smb_buf:
+ static void
+ sess_free_buffer(struct sess_data *sess_data)
+ {
++	struct kvec *iov = sess_data->iov;
+ 
+-	free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base);
++	/*
++	 * Zero the session data before freeing, as it might contain sensitive info (keys, etc).
++	 * Note that iov[1] is already freed by caller.
++	 */
++	if (sess_data->buf0_type != CIFS_NO_BUFFER && iov[0].iov_base)
++		memzero_explicit(iov[0].iov_base, iov[0].iov_len);
++
++	free_rsp_buf(sess_data->buf0_type, iov[0].iov_base);
+ 	sess_data->buf0_type = CIFS_NO_BUFFER;
+-	kfree(sess_data->iov[2].iov_base);
++	kfree_sensitive(iov[2].iov_base);
+ }
+ 
+ static int
+@@ -1375,7 +1383,7 @@ out:
+ 	sess_data->result = rc;
+ 	sess_data->func = NULL;
+ 	sess_free_buffer(sess_data);
+-	kfree(ses->auth_key.response);
++	kfree_sensitive(ses->auth_key.response);
+ 	ses->auth_key.response = NULL;
+ }
+ 
+@@ -1514,7 +1522,7 @@ out:
+ 	sess_data->result = rc;
+ 	sess_data->func = NULL;
+ 	sess_free_buffer(sess_data);
+-	kfree(ses->auth_key.response);
++	kfree_sensitive(ses->auth_key.response);
+ 	ses->auth_key.response = NULL;
+ }
+ 
+@@ -1649,7 +1657,7 @@ sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
+ 	rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
+ 
+ out_free_ntlmsspblob:
+-	kfree(ntlmsspblob);
++	kfree_sensitive(ntlmsspblob);
+ out:
+ 	sess_free_buffer(sess_data);
+ 
+@@ -1659,9 +1667,9 @@ out:
+ 	}
+ 
+ 	/* Else error. Cleanup */
+-	kfree(ses->auth_key.response);
++	kfree_sensitive(ses->auth_key.response);
+ 	ses->auth_key.response = NULL;
+-	kfree(ses->ntlmssp);
++	kfree_sensitive(ses->ntlmssp);
+ 	ses->ntlmssp = NULL;
+ 
+ 	sess_data->func = NULL;
+@@ -1760,7 +1768,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
+ 	}
+ 
+ out_free_ntlmsspblob:
+-	kfree(ntlmsspblob);
++	kfree_sensitive(ntlmsspblob);
+ out:
+ 	sess_free_buffer(sess_data);
+ 
+@@ -1768,9 +1776,9 @@ out:
+ 		rc = sess_establish_session(sess_data);
+ 
+ 	/* Cleanup */
+-	kfree(ses->auth_key.response);
++	kfree_sensitive(ses->auth_key.response);
+ 	ses->auth_key.response = NULL;
+-	kfree(ses->ntlmssp);
++	kfree_sensitive(ses->ntlmssp);
+ 	ses->ntlmssp = NULL;
+ 
+ 	sess_data->func = NULL;
+@@ -1846,7 +1854,7 @@ int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
+ 	rc = sess_data->result;
+ 
+ out:
+-	kfree(sess_data);
++	kfree_sensitive(sess_data);
+ 	return rc;
+ }
+ #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
+diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
+index f36b2d2d40ca3..50480751e521c 100644
+--- a/fs/cifs/smb1ops.c
++++ b/fs/cifs/smb1ops.c
+@@ -542,31 +542,32 @@ cifs_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
+ 	return rc;
+ }
+ 
+-static int
+-cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+-		     struct cifs_sb_info *cifs_sb, const char *full_path,
+-		     FILE_ALL_INFO *data, bool *adjustTZ, bool *symlink)
++static int cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
++				struct cifs_sb_info *cifs_sb, const char *full_path,
++				struct cifs_open_info_data *data, bool *adjustTZ, bool *symlink)
+ {
+ 	int rc;
++	FILE_ALL_INFO fi = {};
+ 
+ 	*symlink = false;
+ 
+ 	/* could do find first instead but this returns more info */
+-	rc = CIFSSMBQPathInfo(xid, tcon, full_path, data, 0 /* not legacy */,
+-			      cifs_sb->local_nls, cifs_remap(cifs_sb));
++	rc = CIFSSMBQPathInfo(xid, tcon, full_path, &fi, 0 /* not legacy */, cifs_sb->local_nls,
++			      cifs_remap(cifs_sb));
+ 	/*
+ 	 * BB optimize code so we do not make the above call when server claims
+ 	 * no NT SMB support and the above call failed at least once - set flag
+ 	 * in tcon or mount.
+ 	 */
+ 	if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
+-		rc = SMBQueryInformation(xid, tcon, full_path, data,
+-					 cifs_sb->local_nls,
++		rc = SMBQueryInformation(xid, tcon, full_path, &fi, cifs_sb->local_nls,
+ 					 cifs_remap(cifs_sb));
++		if (!rc)
++			move_cifs_info_to_smb2(&data->fi, &fi);
+ 		*adjustTZ = true;
+ 	}
+ 
+-	if (!rc && (le32_to_cpu(data->Attributes) & ATTR_REPARSE)) {
++	if (!rc && (le32_to_cpu(fi.Attributes) & ATTR_REPARSE)) {
+ 		int tmprc;
+ 		int oplock = 0;
+ 		struct cifs_fid fid;
+@@ -592,10 +593,9 @@ cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+ 	return rc;
+ }
+ 
+-static int
+-cifs_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
+-		  struct cifs_sb_info *cifs_sb, const char *full_path,
+-		  u64 *uniqueid, FILE_ALL_INFO *data)
++static int cifs_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
++			     struct cifs_sb_info *cifs_sb, const char *full_path,
++			     u64 *uniqueid, struct cifs_open_info_data *unused)
+ {
+ 	/*
+ 	 * We can not use the IndexNumber field by default from Windows or
+@@ -613,11 +613,22 @@ cifs_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
+ 				     cifs_remap(cifs_sb));
+ }
+ 
+-static int
+-cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
+-		     struct cifs_fid *fid, FILE_ALL_INFO *data)
++static int cifs_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
++				struct cifsFileInfo *cfile, struct cifs_open_info_data *data)
+ {
+-	return CIFSSMBQFileInfo(xid, tcon, fid->netfid, data);
++	int rc;
++	FILE_ALL_INFO fi = {};
++
++	if (cfile->symlink_target) {
++		data->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
++		if (!data->symlink_target)
++			return -ENOMEM;
++	}
++
++	rc = CIFSSMBQFileInfo(xid, tcon, cfile->fid.netfid, &fi);
++	if (!rc)
++		move_cifs_info_to_smb2(&data->fi, &fi);
++	return rc;
+ }
+ 
+ static void
+@@ -702,19 +713,20 @@ cifs_mkdir_setinfo(struct inode *inode, const char *full_path,
+ 		cifsInode->cifsAttrs = dosattrs;
+ }
+ 
+-static int
+-cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
+-	       __u32 *oplock, FILE_ALL_INFO *buf)
++static int cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
++			  void *buf)
+ {
++	FILE_ALL_INFO *fi = buf;
++
+ 	if (!(oparms->tcon->ses->capabilities & CAP_NT_SMBS))
+ 		return SMBLegacyOpen(xid, oparms->tcon, oparms->path,
+ 				     oparms->disposition,
+ 				     oparms->desired_access,
+ 				     oparms->create_options,
+-				     &oparms->fid->netfid, oplock, buf,
++				     &oparms->fid->netfid, oplock, fi,
+ 				     oparms->cifs_sb->local_nls,
+ 				     cifs_remap(oparms->cifs_sb));
+-	return CIFS_open(xid, oparms, oplock, buf);
++	return CIFS_open(xid, oparms, oplock, fi);
+ }
+ 
+ static void
+diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
+index 9dfd2dd612c25..4992b43616a7a 100644
+--- a/fs/cifs/smb2file.c
++++ b/fs/cifs/smb2file.c
+@@ -20,40 +20,125 @@
+ #include "cifs_unicode.h"
+ #include "fscache.h"
+ #include "smb2proto.h"
++#include "smb2status.h"
+ 
+-int
+-smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
+-	       __u32 *oplock, FILE_ALL_INFO *buf)
++static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov)
++{
++	struct smb2_err_rsp *err = iov->iov_base;
++	struct smb2_symlink_err_rsp *sym = ERR_PTR(-EINVAL);
++	u32 len;
++
++	if (err->ErrorContextCount) {
++		struct smb2_error_context_rsp *p, *end;
++
++		len = (u32)err->ErrorContextCount * (offsetof(struct smb2_error_context_rsp,
++							      ErrorContextData) +
++						     sizeof(struct smb2_symlink_err_rsp));
++		if (le32_to_cpu(err->ByteCount) < len || iov->iov_len < len + sizeof(*err))
++			return ERR_PTR(-EINVAL);
++
++		p = (struct smb2_error_context_rsp *)err->ErrorData;
++		end = (struct smb2_error_context_rsp *)((u8 *)err + iov->iov_len);
++		do {
++			if (le32_to_cpu(p->ErrorId) == SMB2_ERROR_ID_DEFAULT) {
++				sym = (struct smb2_symlink_err_rsp *)&p->ErrorContextData;
++				break;
++			}
++			cifs_dbg(FYI, "%s: skipping unhandled error context: 0x%x\n",
++				 __func__, le32_to_cpu(p->ErrorId));
++
++			len = ALIGN(le32_to_cpu(p->ErrorDataLength), 8);
++			p = (struct smb2_error_context_rsp *)((u8 *)&p->ErrorContextData + len);
++		} while (p < end);
++	} else if (le32_to_cpu(err->ByteCount) >= sizeof(*sym) &&
++		   iov->iov_len >= SMB2_SYMLINK_STRUCT_SIZE) {
++		sym = (struct smb2_symlink_err_rsp *)err->ErrorData;
++	}
++
++	if (!IS_ERR(sym) && (le32_to_cpu(sym->SymLinkErrorTag) != SYMLINK_ERROR_TAG ||
++			     le32_to_cpu(sym->ReparseTag) != IO_REPARSE_TAG_SYMLINK))
++		sym = ERR_PTR(-EINVAL);
++
++	return sym;
++}
++
++int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov, char **path)
++{
++	struct smb2_symlink_err_rsp *sym;
++	unsigned int sub_offs, sub_len;
++	unsigned int print_offs, print_len;
++	char *s;
++
++	if (!cifs_sb || !iov || !iov->iov_base || !iov->iov_len || !path)
++		return -EINVAL;
++
++	sym = symlink_data(iov);
++	if (IS_ERR(sym))
++		return PTR_ERR(sym);
++
++	sub_len = le16_to_cpu(sym->SubstituteNameLength);
++	sub_offs = le16_to_cpu(sym->SubstituteNameOffset);
++	print_len = le16_to_cpu(sym->PrintNameLength);
++	print_offs = le16_to_cpu(sym->PrintNameOffset);
++
++	if (iov->iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offs + sub_len ||
++	    iov->iov_len < SMB2_SYMLINK_STRUCT_SIZE + print_offs + print_len)
++		return -EINVAL;
++
++	s = cifs_strndup_from_utf16((char *)sym->PathBuffer + sub_offs, sub_len, true,
++				    cifs_sb->local_nls);
++	if (!s)
++		return -ENOMEM;
++	convert_delimiter(s, '/');
++	cifs_dbg(FYI, "%s: symlink target: %s\n", __func__, s);
++
++	*path = s;
++	return 0;
++}
++
++int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock, void *buf)
+ {
+ 	int rc;
+ 	__le16 *smb2_path;
+-	struct smb2_file_all_info *smb2_data = NULL;
+ 	__u8 smb2_oplock;
++	struct cifs_open_info_data *data = buf;
++	struct smb2_file_all_info file_info = {};
++	struct smb2_file_all_info *smb2_data = data ? &file_info : NULL;
++	struct kvec err_iov = {};
++	int err_buftype = CIFS_NO_BUFFER;
+ 	struct cifs_fid *fid = oparms->fid;
+ 	struct network_resiliency_req nr_ioctl_req;
+ 
+ 	smb2_path = cifs_convert_path_to_utf16(oparms->path, oparms->cifs_sb);
+-	if (smb2_path == NULL) {
+-		rc = -ENOMEM;
+-		goto out;
+-	}
+-
+-	smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
+-			    GFP_KERNEL);
+-	if (smb2_data == NULL) {
+-		rc = -ENOMEM;
+-		goto out;
+-	}
++	if (smb2_path == NULL)
++		return -ENOMEM;
+ 
+ 	oparms->desired_access |= FILE_READ_ATTRIBUTES;
+ 	smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH;
+ 
+-	rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL,
+-		       NULL, NULL);
++	rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov,
++		       &err_buftype);
++	if (rc && data) {
++		struct smb2_hdr *hdr = err_iov.iov_base;
++
++		if (unlikely(!err_iov.iov_base || err_buftype == CIFS_NO_BUFFER))
++			rc = -ENOMEM;
++		else if (hdr->Status == STATUS_STOPPED_ON_SYMLINK && oparms->cifs_sb) {
++			rc = smb2_parse_symlink_response(oparms->cifs_sb, &err_iov,
++							 &data->symlink_target);
++			if (!rc) {
++				memset(smb2_data, 0, sizeof(*smb2_data));
++				oparms->create_options |= OPEN_REPARSE_POINT;
++				rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data,
++					       NULL, NULL, NULL);
++				oparms->create_options &= ~OPEN_REPARSE_POINT;
++			}
++		}
++	}
++
+ 	if (rc)
+ 		goto out;
+ 
+-
+ 	if (oparms->tcon->use_resilient) {
+ 		/* default timeout is 0, servers pick default (120 seconds) */
+ 		nr_ioctl_req.Timeout =
+@@ -73,7 +158,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
+ 		rc = 0;
+ 	}
+ 
+-	if (buf) {
++	if (smb2_data) {
+ 		/* if open response does not have IndexNumber field - get it */
+ 		if (smb2_data->IndexNumber == 0) {
+ 			rc = SMB2_get_srv_num(xid, oparms->tcon,
+@@ -89,12 +174,12 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
+ 				rc = 0;
+ 			}
+ 		}
+-		move_smb2_info_to_cifs(buf, smb2_data);
++		memcpy(&data->fi, smb2_data, sizeof(data->fi));
+ 	}
+ 
+ 	*oplock = smb2_oplock;
+ out:
+-	kfree(smb2_data);
++	free_rsp_buf(err_buftype, err_iov.iov_base);
+ 	kfree(smb2_path);
+ 	return rc;
+ }
+diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
+index b83f59051b26f..fc5776e7a7824 100644
+--- a/fs/cifs/smb2inode.c
++++ b/fs/cifs/smb2inode.c
+@@ -24,6 +24,7 @@
+ #include "smb2pdu.h"
+ #include "smb2proto.h"
+ #include "cached_dir.h"
++#include "smb2status.h"
+ 
+ static void
+ free_set_inf_compound(struct smb_rqst *rqst)
+@@ -50,13 +51,15 @@ struct cop_vars {
+ /*
+  * note: If cfile is passed, the reference to it is dropped here.
+  * So make sure that you do not reuse cfile after return from this func.
++ *
++ * If passing @err_iov and @err_buftype, ensure to make them both large enough (>= 3) to hold all
++ * error responses.  Caller is also responsible for freeing them up.
+  */
+-static int
+-smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+-		 struct cifs_sb_info *cifs_sb, const char *full_path,
+-		 __u32 desired_access, __u32 create_disposition,
+-		 __u32 create_options, umode_t mode, void *ptr, int command,
+-		 struct cifsFileInfo *cfile)
++static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
++			    struct cifs_sb_info *cifs_sb, const char *full_path,
++			    __u32 desired_access, __u32 create_disposition, __u32 create_options,
++			    umode_t mode, void *ptr, int command, struct cifsFileInfo *cfile,
++			    struct kvec *err_iov, int *err_buftype)
+ {
+ 	struct cop_vars *vars = NULL;
+ 	struct kvec *rsp_iov;
+@@ -70,6 +73,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+ 	int num_rqst = 0;
+ 	int resp_buftype[3];
+ 	struct smb2_query_info_rsp *qi_rsp = NULL;
++	struct cifs_open_info_data *idata;
+ 	int flags = 0;
+ 	__u8 delete_pending[8] = {1, 0, 0, 0, 0, 0, 0, 0};
+ 	unsigned int size[2];
+@@ -385,14 +389,19 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+ 
+ 	switch (command) {
+ 	case SMB2_OP_QUERY_INFO:
++		idata = ptr;
++		if (rc == 0 && cfile && cfile->symlink_target) {
++			idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
++			if (!idata->symlink_target)
++				rc = -ENOMEM;
++		}
+ 		if (rc == 0) {
+ 			qi_rsp = (struct smb2_query_info_rsp *)
+ 				rsp_iov[1].iov_base;
+ 			rc = smb2_validate_and_copy_iov(
+ 				le16_to_cpu(qi_rsp->OutputBufferOffset),
+ 				le32_to_cpu(qi_rsp->OutputBufferLength),
+-				&rsp_iov[1], sizeof(struct smb2_file_all_info),
+-				ptr);
++				&rsp_iov[1], sizeof(idata->fi), (char *)&idata->fi);
+ 		}
+ 		if (rqst[1].rq_iov)
+ 			SMB2_query_info_free(&rqst[1]);
+@@ -406,13 +415,20 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+ 						tcon->tid);
+ 		break;
+ 	case SMB2_OP_POSIX_QUERY_INFO:
++		idata = ptr;
++		if (rc == 0 && cfile && cfile->symlink_target) {
++			idata->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
++			if (!idata->symlink_target)
++				rc = -ENOMEM;
++		}
+ 		if (rc == 0) {
+ 			qi_rsp = (struct smb2_query_info_rsp *)
+ 				rsp_iov[1].iov_base;
+ 			rc = smb2_validate_and_copy_iov(
+ 				le16_to_cpu(qi_rsp->OutputBufferOffset),
+ 				le32_to_cpu(qi_rsp->OutputBufferLength),
+-				&rsp_iov[1], sizeof(struct smb311_posix_qinfo) /* add SIDs */, ptr);
++				&rsp_iov[1], sizeof(idata->posix_fi) /* add SIDs */,
++				(char *)&idata->posix_fi);
+ 		}
+ 		if (rqst[1].rq_iov)
+ 			SMB2_query_info_free(&rqst[1]);
+@@ -477,42 +493,33 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
+ 		free_set_inf_compound(rqst);
+ 		break;
+ 	}
+-	free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
+-	free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
+-	free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
++
++	if (rc && err_iov && err_buftype) {
++		memcpy(err_iov, rsp_iov, 3 * sizeof(*err_iov));
++		memcpy(err_buftype, resp_buftype, 3 * sizeof(*err_buftype));
++	} else {
++		free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
++		free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
++		free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
++	}
+ 	kfree(vars);
+ 	return rc;
+ }
+ 
+-void
+-move_smb2_info_to_cifs(FILE_ALL_INFO *dst, struct smb2_file_all_info *src)
+-{
+-	memcpy(dst, src, (size_t)(&src->CurrentByteOffset) - (size_t)src);
+-	dst->CurrentByteOffset = src->CurrentByteOffset;
+-	dst->Mode = src->Mode;
+-	dst->AlignmentRequirement = src->AlignmentRequirement;
+-	dst->IndexNumber1 = 0; /* we don't use it */
+-}
+-
+-int
+-smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+-		     struct cifs_sb_info *cifs_sb, const char *full_path,
+-		     FILE_ALL_INFO *data, bool *adjust_tz, bool *reparse)
++int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
++			 struct cifs_sb_info *cifs_sb, const char *full_path,
++			 struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse)
+ {
+ 	int rc;
+-	struct smb2_file_all_info *smb2_data;
+ 	__u32 create_options = 0;
+ 	struct cifsFileInfo *cfile;
+ 	struct cached_fid *cfid = NULL;
++	struct kvec err_iov[3] = {};
++	int err_buftype[3] = {};
+ 
+ 	*adjust_tz = false;
+ 	*reparse = false;
+ 
+-	smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
+-			    GFP_KERNEL);
+-	if (smb2_data == NULL)
+-		return -ENOMEM;
+-
+ 	if (strcmp(full_path, ""))
+ 		rc = -ENOENT;
+ 	else
+@@ -520,63 +527,58 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+ 	/* If it is a root and its handle is cached then use it */
+ 	if (!rc) {
+ 		if (cfid->file_all_info_is_valid) {
+-			move_smb2_info_to_cifs(data,
+-					       &cfid->file_all_info);
++			memcpy(&data->fi, &cfid->file_all_info, sizeof(data->fi));
+ 		} else {
+-			rc = SMB2_query_info(xid, tcon,
+-					     cfid->fid.persistent_fid,
+-					     cfid->fid.volatile_fid, smb2_data);
+-			if (!rc)
+-				move_smb2_info_to_cifs(data, smb2_data);
++			rc = SMB2_query_info(xid, tcon, cfid->fid.persistent_fid,
++					     cfid->fid.volatile_fid, &data->fi);
+ 		}
+ 		close_cached_dir(cfid);
+-		goto out;
++		return rc;
+ 	}
+ 
+ 	cifs_get_readable_path(tcon, full_path, &cfile);
+-	rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+-			      FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
+-			      ACL_NO_MODE, smb2_data, SMB2_OP_QUERY_INFO, cfile);
++	rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN,
++			      create_options, ACL_NO_MODE, data, SMB2_OP_QUERY_INFO, cfile,
++			      err_iov, err_buftype);
+ 	if (rc == -EOPNOTSUPP) {
++		if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER &&
++		    ((struct smb2_hdr *)err_iov[0].iov_base)->Command == SMB2_CREATE &&
++		    ((struct smb2_hdr *)err_iov[0].iov_base)->Status == STATUS_STOPPED_ON_SYMLINK) {
++			rc = smb2_parse_symlink_response(cifs_sb, err_iov, &data->symlink_target);
++			if (rc)
++				goto out;
++		}
+ 		*reparse = true;
+ 		create_options |= OPEN_REPARSE_POINT;
+ 
+ 		/* Failed on a symbolic link - query a reparse point info */
+ 		cifs_get_readable_path(tcon, full_path, &cfile);
+-		rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+-				      FILE_READ_ATTRIBUTES, FILE_OPEN,
+-				      create_options, ACL_NO_MODE,
+-				      smb2_data, SMB2_OP_QUERY_INFO, cfile);
++		rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES,
++				      FILE_OPEN, create_options, ACL_NO_MODE, data,
++				      SMB2_OP_QUERY_INFO, cfile, NULL, NULL);
+ 	}
+-	if (rc)
+-		goto out;
+ 
+-	move_smb2_info_to_cifs(data, smb2_data);
+ out:
+-	kfree(smb2_data);
++	free_rsp_buf(err_buftype[0], err_iov[0].iov_base);
++	free_rsp_buf(err_buftype[1], err_iov[1].iov_base);
++	free_rsp_buf(err_buftype[2], err_iov[2].iov_base);
+ 	return rc;
+ }
+ 
+ 
+-int
+-smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+-		     struct cifs_sb_info *cifs_sb, const char *full_path,
+-		     struct smb311_posix_qinfo *data, bool *adjust_tz, bool *reparse)
++int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
++				 struct cifs_sb_info *cifs_sb, const char *full_path,
++				 struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse)
+ {
+ 	int rc;
+ 	__u32 create_options = 0;
+ 	struct cifsFileInfo *cfile;
+-	struct smb311_posix_qinfo *smb2_data;
++	struct kvec err_iov[3] = {};
++	int err_buftype[3] = {};
+ 
+ 	*adjust_tz = false;
+ 	*reparse = false;
+ 
+-	/* BB TODO: Make struct larger when add support for parsing owner SIDs */
+-	smb2_data = kzalloc(sizeof(struct smb311_posix_qinfo),
+-			    GFP_KERNEL);
+-	if (smb2_data == NULL)
+-		return -ENOMEM;
+-
+ 	/*
+ 	 * BB TODO: Add support for using the cached root handle.
+ 	 * Create SMB2_query_posix_info worker function to do non-compounded query
+@@ -585,29 +587,32 @@ smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+ 	 */
+ 
+ 	cifs_get_readable_path(tcon, full_path, &cfile);
+-	rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+-			      FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
+-			      ACL_NO_MODE, smb2_data, SMB2_OP_POSIX_QUERY_INFO, cfile);
++	rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN,
++			      create_options, ACL_NO_MODE, data, SMB2_OP_POSIX_QUERY_INFO, cfile,
++			      err_iov, err_buftype);
+ 	if (rc == -EOPNOTSUPP) {
+ 		/* BB TODO: When support for special files added to Samba re-verify this path */
++		if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER &&
++		    ((struct smb2_hdr *)err_iov[0].iov_base)->Command == SMB2_CREATE &&
++		    ((struct smb2_hdr *)err_iov[0].iov_base)->Status == STATUS_STOPPED_ON_SYMLINK) {
++			rc = smb2_parse_symlink_response(cifs_sb, err_iov, &data->symlink_target);
++			if (rc)
++				goto out;
++		}
+ 		*reparse = true;
+ 		create_options |= OPEN_REPARSE_POINT;
+ 
+ 		/* Failed on a symbolic link - query a reparse point info */
+ 		cifs_get_readable_path(tcon, full_path, &cfile);
+-		rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+-				      FILE_READ_ATTRIBUTES, FILE_OPEN,
+-				      create_options, ACL_NO_MODE,
+-				      smb2_data, SMB2_OP_POSIX_QUERY_INFO, cfile);
++		rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES,
++				      FILE_OPEN, create_options, ACL_NO_MODE, data,
++				      SMB2_OP_POSIX_QUERY_INFO, cfile, NULL, NULL);
+ 	}
+-	if (rc)
+-		goto out;
+-
+-	 /* TODO: will need to allow for the 2 SIDs when add support for getting owner UID/GID */
+-	memcpy(data, smb2_data, sizeof(struct smb311_posix_qinfo));
+ 
+ out:
+-	kfree(smb2_data);
++	free_rsp_buf(err_buftype[0], err_iov[0].iov_base);
++	free_rsp_buf(err_buftype[1], err_iov[1].iov_base);
++	free_rsp_buf(err_buftype[2], err_iov[2].iov_base);
+ 	return rc;
+ }
+ 
+@@ -619,7 +624,7 @@ smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode,
+ 	return smb2_compound_op(xid, tcon, cifs_sb, name,
+ 				FILE_WRITE_ATTRIBUTES, FILE_CREATE,
+ 				CREATE_NOT_FILE, mode, NULL, SMB2_OP_MKDIR,
+-				NULL);
++				NULL, NULL, NULL);
+ }
+ 
+ void
+@@ -641,7 +646,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name,
+ 	tmprc = smb2_compound_op(xid, tcon, cifs_sb, name,
+ 				 FILE_WRITE_ATTRIBUTES, FILE_CREATE,
+ 				 CREATE_NOT_FILE, ACL_NO_MODE,
+-				 &data, SMB2_OP_SET_INFO, cfile);
++				 &data, SMB2_OP_SET_INFO, cfile, NULL, NULL);
+ 	if (tmprc == 0)
+ 		cifs_i->cifsAttrs = dosattrs;
+ }
+@@ -652,7 +657,7 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
+ {
+ 	return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
+ 				CREATE_NOT_FILE, ACL_NO_MODE,
+-				NULL, SMB2_OP_RMDIR, NULL);
++				NULL, SMB2_OP_RMDIR, NULL, NULL, NULL);
+ }
+ 
+ int
+@@ -661,7 +666,7 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
+ {
+ 	return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
+ 				CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT,
+-				ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL);
++				ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL, NULL, NULL);
+ }
+ 
+ static int
+@@ -680,7 +685,7 @@ smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon,
+ 	}
+ 	rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access,
+ 			      FILE_OPEN, 0, ACL_NO_MODE, smb2_to_name,
+-			      command, cfile);
++			      command, cfile, NULL, NULL);
+ smb2_rename_path:
+ 	kfree(smb2_to_name);
+ 	return rc;
+@@ -720,7 +725,7 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
+ 	cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
+ 	return smb2_compound_op(xid, tcon, cifs_sb, full_path,
+ 				FILE_WRITE_DATA, FILE_OPEN, 0, ACL_NO_MODE,
+-				&eof, SMB2_OP_SET_EOF, cfile);
++				&eof, SMB2_OP_SET_EOF, cfile, NULL, NULL);
+ }
+ 
+ int
+@@ -746,7 +751,8 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
+ 	cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
+ 	rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
+ 			      FILE_WRITE_ATTRIBUTES, FILE_OPEN,
+-			      0, ACL_NO_MODE, buf, SMB2_OP_SET_INFO, cfile);
++			      0, ACL_NO_MODE, buf, SMB2_OP_SET_INFO, cfile,
++			      NULL, NULL);
+ 	cifs_put_tlink(tlink);
+ 	return rc;
+ }
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index b724bf42b5401..74052b51655ec 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -831,33 +831,25 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
+ 	return rc;
+ }
+ 
+-static int
+-smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
+-		  struct cifs_sb_info *cifs_sb, const char *full_path,
+-		  u64 *uniqueid, FILE_ALL_INFO *data)
++static int smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
++			     struct cifs_sb_info *cifs_sb, const char *full_path,
++			     u64 *uniqueid, struct cifs_open_info_data *data)
+ {
+-	*uniqueid = le64_to_cpu(data->IndexNumber);
++	*uniqueid = le64_to_cpu(data->fi.IndexNumber);
+ 	return 0;
+ }
+ 
+-static int
+-smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
+-		     struct cifs_fid *fid, FILE_ALL_INFO *data)
++static int smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
++				struct cifsFileInfo *cfile, struct cifs_open_info_data *data)
+ {
+-	int rc;
+-	struct smb2_file_all_info *smb2_data;
++	struct cifs_fid *fid = &cfile->fid;
+ 
+-	smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
+-			    GFP_KERNEL);
+-	if (smb2_data == NULL)
+-		return -ENOMEM;
+-
+-	rc = SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid,
+-			     smb2_data);
+-	if (!rc)
+-		move_smb2_info_to_cifs(data, smb2_data);
+-	kfree(smb2_data);
+-	return rc;
++	if (cfile->symlink_target) {
++		data->symlink_target = kstrdup(cfile->symlink_target, GFP_KERNEL);
++		if (!data->symlink_target)
++			return -ENOMEM;
++	}
++	return SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid, &data->fi);
+ }
+ 
+ #ifdef CONFIG_CIFS_XATTR
+@@ -2836,9 +2828,6 @@ parse_reparse_point(struct reparse_data_buffer *buf,
+ 	}
+ }
+ 
+-#define SMB2_SYMLINK_STRUCT_SIZE \
+-	(sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp))
+-
+ static int
+ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
+ 		   struct cifs_sb_info *cifs_sb, const char *full_path,
+@@ -2850,13 +2839,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
+ 	struct cifs_open_parms oparms;
+ 	struct cifs_fid fid;
+ 	struct kvec err_iov = {NULL, 0};
+-	struct smb2_err_rsp *err_buf = NULL;
+-	struct smb2_symlink_err_rsp *symlink;
+ 	struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
+-	unsigned int sub_len;
+-	unsigned int sub_offset;
+-	unsigned int print_len;
+-	unsigned int print_offset;
+ 	int flags = CIFS_CP_CREATE_CLOSE_OP;
+ 	struct smb_rqst rqst[3];
+ 	int resp_buftype[3];
+@@ -2973,47 +2956,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
+ 		goto querty_exit;
+ 	}
+ 
+-	err_buf = err_iov.iov_base;
+-	if (le32_to_cpu(err_buf->ByteCount) < sizeof(struct smb2_symlink_err_rsp) ||
+-	    err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE) {
+-		rc = -EINVAL;
+-		goto querty_exit;
+-	}
+-
+-	symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
+-	if (le32_to_cpu(symlink->SymLinkErrorTag) != SYMLINK_ERROR_TAG ||
+-	    le32_to_cpu(symlink->ReparseTag) != IO_REPARSE_TAG_SYMLINK) {
+-		rc = -EINVAL;
+-		goto querty_exit;
+-	}
+-
+-	/* open must fail on symlink - reset rc */
+-	rc = 0;
+-	sub_len = le16_to_cpu(symlink->SubstituteNameLength);
+-	sub_offset = le16_to_cpu(symlink->SubstituteNameOffset);
+-	print_len = le16_to_cpu(symlink->PrintNameLength);
+-	print_offset = le16_to_cpu(symlink->PrintNameOffset);
+-
+-	if (err_iov.iov_len < SMB2_SYMLINK_STRUCT_SIZE + sub_offset + sub_len) {
+-		rc = -EINVAL;
+-		goto querty_exit;
+-	}
+-
+-	if (err_iov.iov_len <
+-	    SMB2_SYMLINK_STRUCT_SIZE + print_offset + print_len) {
+-		rc = -EINVAL;
+-		goto querty_exit;
+-	}
+-
+-	*target_path = cifs_strndup_from_utf16(
+-				(char *)symlink->PathBuffer + sub_offset,
+-				sub_len, true, cifs_sb->local_nls);
+-	if (!(*target_path)) {
+-		rc = -ENOMEM;
+-		goto querty_exit;
+-	}
+-	convert_delimiter(*target_path, '/');
+-	cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
++	rc = smb2_parse_symlink_response(cifs_sb, &err_iov, target_path);
+ 
+  querty_exit:
+ 	cifs_dbg(FYI, "query symlink rc %d\n", rc);
+@@ -4239,69 +4182,82 @@ fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len,
+ 	memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8);
+ }
+ 
+-/* We can not use the normal sg_set_buf() as we will sometimes pass a
+- * stack object as buf.
+- */
+-static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
+-				   unsigned int buflen)
++static void *smb2_aead_req_alloc(struct crypto_aead *tfm, const struct smb_rqst *rqst,
++				 int num_rqst, const u8 *sig, u8 **iv,
++				 struct aead_request **req, struct scatterlist **sgl,
++				 unsigned int *num_sgs)
+ {
+-	void *addr;
+-	/*
+-	 * VMAP_STACK (at least) puts stack into the vmalloc address space
+-	 */
+-	if (is_vmalloc_addr(buf))
+-		addr = vmalloc_to_page(buf);
+-	else
+-		addr = virt_to_page(buf);
+-	sg_set_page(sg, addr, buflen, offset_in_page(buf));
++	unsigned int req_size = sizeof(**req) + crypto_aead_reqsize(tfm);
++	unsigned int iv_size = crypto_aead_ivsize(tfm);
++	unsigned int len;
++	u8 *p;
++
++	*num_sgs = cifs_get_num_sgs(rqst, num_rqst, sig);
++
++	len = iv_size;
++	len += crypto_aead_alignmask(tfm) & ~(crypto_tfm_ctx_alignment() - 1);
++	len = ALIGN(len, crypto_tfm_ctx_alignment());
++	len += req_size;
++	len = ALIGN(len, __alignof__(struct scatterlist));
++	len += *num_sgs * sizeof(**sgl);
++
++	p = kmalloc(len, GFP_ATOMIC);
++	if (!p)
++		return NULL;
++
++	*iv = (u8 *)PTR_ALIGN(p, crypto_aead_alignmask(tfm) + 1);
++	*req = (struct aead_request *)PTR_ALIGN(*iv + iv_size,
++						crypto_tfm_ctx_alignment());
++	*sgl = (struct scatterlist *)PTR_ALIGN((u8 *)*req + req_size,
++					       __alignof__(struct scatterlist));
++	return p;
+ }
+ 
+-/* Assumes the first rqst has a transform header as the first iov.
+- * I.e.
+- * rqst[0].rq_iov[0]  is transform header
+- * rqst[0].rq_iov[1+] data to be encrypted/decrypted
+- * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
+- */
+-static struct scatterlist *
+-init_sg(int num_rqst, struct smb_rqst *rqst, u8 *sign)
++static void *smb2_get_aead_req(struct crypto_aead *tfm, const struct smb_rqst *rqst,
++			       int num_rqst, const u8 *sig, u8 **iv,
++			       struct aead_request **req, struct scatterlist **sgl)
+ {
+-	unsigned int sg_len;
++	unsigned int off, len, skip;
+ 	struct scatterlist *sg;
+-	unsigned int i;
+-	unsigned int j;
+-	unsigned int idx = 0;
+-	int skip;
+-
+-	sg_len = 1;
+-	for (i = 0; i < num_rqst; i++)
+-		sg_len += rqst[i].rq_nvec + rqst[i].rq_npages;
++	unsigned int num_sgs;
++	unsigned long addr;
++	int i, j;
++	void *p;
+ 
+-	sg = kmalloc_array(sg_len, sizeof(struct scatterlist), GFP_KERNEL);
+-	if (!sg)
++	p = smb2_aead_req_alloc(tfm, rqst, num_rqst, sig, iv, req, sgl, &num_sgs);
++	if (!p)
+ 		return NULL;
+ 
+-	sg_init_table(sg, sg_len);
++	sg_init_table(*sgl, num_sgs);
++	sg = *sgl;
++
++	/* Assumes the first rqst has a transform header as the first iov.
++	 * I.e.
++	 * rqst[0].rq_iov[0]  is transform header
++	 * rqst[0].rq_iov[1+] data to be encrypted/decrypted
++	 * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
++	 */
+ 	for (i = 0; i < num_rqst; i++) {
++		/*
++		 * The first rqst has a transform header where the
++		 * first 20 bytes are not part of the encrypted blob.
++		 */
+ 		for (j = 0; j < rqst[i].rq_nvec; j++) {
+-			/*
+-			 * The first rqst has a transform header where the
+-			 * first 20 bytes are not part of the encrypted blob
+-			 */
+-			skip = (i == 0) && (j == 0) ? 20 : 0;
+-			smb2_sg_set_buf(&sg[idx++],
+-					rqst[i].rq_iov[j].iov_base + skip,
+-					rqst[i].rq_iov[j].iov_len - skip);
+-			}
++			struct kvec *iov = &rqst[i].rq_iov[j];
+ 
++			skip = (i == 0) && (j == 0) ? 20 : 0;
++			addr = (unsigned long)iov->iov_base + skip;
++			len = iov->iov_len - skip;
++			sg = cifs_sg_set_buf(sg, (void *)addr, len);
++		}
+ 		for (j = 0; j < rqst[i].rq_npages; j++) {
+-			unsigned int len, offset;
+-
+-			rqst_page_get_length(&rqst[i], j, &len, &offset);
+-			sg_set_page(&sg[idx++], rqst[i].rq_pages[j], len, offset);
++			rqst_page_get_length(&rqst[i], j, &len, &off);
++			sg_set_page(sg++, rqst[i].rq_pages[j], len, off);
+ 		}
+ 	}
+-	smb2_sg_set_buf(&sg[idx], sign, SMB2_SIGNATURE_SIZE);
+-	return sg;
++	cifs_sg_set_buf(sg, sig, SMB2_SIGNATURE_SIZE);
++
++	return p;
+ }
+ 
+ static int
+@@ -4347,11 +4303,11 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
+ 	u8 sign[SMB2_SIGNATURE_SIZE] = {};
+ 	u8 key[SMB3_ENC_DEC_KEY_SIZE];
+ 	struct aead_request *req;
+-	char *iv;
+-	unsigned int iv_len;
++	u8 *iv;
+ 	DECLARE_CRYPTO_WAIT(wait);
+ 	struct crypto_aead *tfm;
+ 	unsigned int crypt_len = le32_to_cpu(tr_hdr->OriginalMessageSize);
++	void *creq;
+ 
+ 	rc = smb2_get_enc_key(server, le64_to_cpu(tr_hdr->SessionId), enc, key);
+ 	if (rc) {
+@@ -4386,32 +4342,15 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
+ 		return rc;
+ 	}
+ 
+-	req = aead_request_alloc(tfm, GFP_KERNEL);
+-	if (!req) {
+-		cifs_server_dbg(VFS, "%s: Failed to alloc aead request\n", __func__);
++	creq = smb2_get_aead_req(tfm, rqst, num_rqst, sign, &iv, &req, &sg);
++	if (unlikely(!creq))
+ 		return -ENOMEM;
+-	}
+ 
+ 	if (!enc) {
+ 		memcpy(sign, &tr_hdr->Signature, SMB2_SIGNATURE_SIZE);
+ 		crypt_len += SMB2_SIGNATURE_SIZE;
+ 	}
+ 
+-	sg = init_sg(num_rqst, rqst, sign);
+-	if (!sg) {
+-		cifs_server_dbg(VFS, "%s: Failed to init sg\n", __func__);
+-		rc = -ENOMEM;
+-		goto free_req;
+-	}
+-
+-	iv_len = crypto_aead_ivsize(tfm);
+-	iv = kzalloc(iv_len, GFP_KERNEL);
+-	if (!iv) {
+-		cifs_server_dbg(VFS, "%s: Failed to alloc iv\n", __func__);
+-		rc = -ENOMEM;
+-		goto free_sg;
+-	}
+-
+ 	if ((server->cipher_type == SMB2_ENCRYPTION_AES128_GCM) ||
+ 	    (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
+ 		memcpy(iv, (char *)tr_hdr->Nonce, SMB3_AES_GCM_NONCE);
+@@ -4420,6 +4359,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
+ 		memcpy(iv + 1, (char *)tr_hdr->Nonce, SMB3_AES_CCM_NONCE);
+ 	}
+ 
++	aead_request_set_tfm(req, tfm);
+ 	aead_request_set_crypt(req, sg, sg, crypt_len, iv);
+ 	aead_request_set_ad(req, assoc_data_len);
+ 
+@@ -4432,11 +4372,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
+ 	if (!rc && enc)
+ 		memcpy(&tr_hdr->Signature, sign, SMB2_SIGNATURE_SIZE);
+ 
+-	kfree(iv);
+-free_sg:
+-	kfree(sg);
+-free_req:
+-	kfree(req);
++	kfree_sensitive(creq);
+ 	return rc;
+ }
+ 
+@@ -5124,7 +5060,7 @@ smb2_make_node(unsigned int xid, struct inode *inode,
+ {
+ 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+ 	int rc = -EPERM;
+-	FILE_ALL_INFO *buf = NULL;
++	struct cifs_open_info_data buf = {};
+ 	struct cifs_io_parms io_parms = {0};
+ 	__u32 oplock = 0;
+ 	struct cifs_fid fid;
+@@ -5140,7 +5076,7 @@ smb2_make_node(unsigned int xid, struct inode *inode,
+ 	 * and was used by default in earlier versions of Windows
+ 	 */
+ 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
+-		goto out;
++		return rc;
+ 
+ 	/*
+ 	 * TODO: Add ability to create instead via reparse point. Windows (e.g.
+@@ -5149,16 +5085,10 @@ smb2_make_node(unsigned int xid, struct inode *inode,
+ 	 */
+ 
+ 	if (!S_ISCHR(mode) && !S_ISBLK(mode))
+-		goto out;
++		return rc;
+ 
+ 	cifs_dbg(FYI, "sfu compat create special file\n");
+ 
+-	buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
+-	if (buf == NULL) {
+-		rc = -ENOMEM;
+-		goto out;
+-	}
+-
+ 	oparms.tcon = tcon;
+ 	oparms.cifs_sb = cifs_sb;
+ 	oparms.desired_access = GENERIC_WRITE;
+@@ -5173,21 +5103,21 @@ smb2_make_node(unsigned int xid, struct inode *inode,
+ 		oplock = REQ_OPLOCK;
+ 	else
+ 		oplock = 0;
+-	rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, buf);
++	rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, &buf);
+ 	if (rc)
+-		goto out;
++		return rc;
+ 
+ 	/*
+ 	 * BB Do not bother to decode buf since no local inode yet to put
+ 	 * timestamps in, but we can reuse it safely.
+ 	 */
+ 
+-	pdev = (struct win_dev *)buf;
++	pdev = (struct win_dev *)&buf.fi;
+ 	io_parms.pid = current->tgid;
+ 	io_parms.tcon = tcon;
+ 	io_parms.offset = 0;
+ 	io_parms.length = sizeof(struct win_dev);
+-	iov[1].iov_base = buf;
++	iov[1].iov_base = &buf.fi;
+ 	iov[1].iov_len = sizeof(struct win_dev);
+ 	if (S_ISCHR(mode)) {
+ 		memcpy(pdev->type, "IntxCHR", 8);
+@@ -5206,8 +5136,8 @@ smb2_make_node(unsigned int xid, struct inode *inode,
+ 	d_drop(dentry);
+ 
+ 	/* FIXME: add code here to set EAs */
+-out:
+-	kfree(buf);
++
++	cifs_free_open_info(&buf);
+ 	return rc;
+ }
+ 
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 92a1d0695ebdf..aa0245268d40e 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -1345,7 +1345,13 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data)
+ static void
+ SMB2_sess_free_buffer(struct SMB2_sess_data *sess_data)
+ {
+-	free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base);
++	struct kvec *iov = sess_data->iov;
++
++	/* iov[1] is already freed by caller */
++	if (sess_data->buf0_type != CIFS_NO_BUFFER && iov[0].iov_base)
++		memzero_explicit(iov[0].iov_base, iov[0].iov_len);
++
++	free_rsp_buf(sess_data->buf0_type, iov[0].iov_base);
+ 	sess_data->buf0_type = CIFS_NO_BUFFER;
+ }
+ 
+@@ -1477,6 +1483,8 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data)
+ out_put_spnego_key:
+ 	key_invalidate(spnego_key);
+ 	key_put(spnego_key);
++	if (rc)
++		kfree_sensitive(ses->auth_key.response);
+ out:
+ 	sess_data->result = rc;
+ 	sess_data->func = NULL;
+@@ -1573,7 +1581,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
+ 	}
+ 
+ out:
+-	kfree(ntlmssp_blob);
++	kfree_sensitive(ntlmssp_blob);
+ 	SMB2_sess_free_buffer(sess_data);
+ 	if (!rc) {
+ 		sess_data->result = 0;
+@@ -1581,7 +1589,7 @@ out:
+ 		return;
+ 	}
+ out_err:
+-	kfree(ses->ntlmssp);
++	kfree_sensitive(ses->ntlmssp);
+ 	ses->ntlmssp = NULL;
+ 	sess_data->result = rc;
+ 	sess_data->func = NULL;
+@@ -1657,9 +1665,9 @@ SMB2_sess_auth_rawntlmssp_authenticate(struct SMB2_sess_data *sess_data)
+ 	}
+ #endif
+ out:
+-	kfree(ntlmssp_blob);
++	kfree_sensitive(ntlmssp_blob);
+ 	SMB2_sess_free_buffer(sess_data);
+-	kfree(ses->ntlmssp);
++	kfree_sensitive(ses->ntlmssp);
+ 	ses->ntlmssp = NULL;
+ 	sess_data->result = rc;
+ 	sess_data->func = NULL;
+@@ -1737,7 +1745,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
+ 		cifs_server_dbg(VFS, "signing requested but authenticated as guest\n");
+ 	rc = sess_data->result;
+ out:
+-	kfree(sess_data);
++	kfree_sensitive(sess_data);
+ 	return rc;
+ }
+ 
+diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
+index f57881b8464fb..1237bb86e93a8 100644
+--- a/fs/cifs/smb2pdu.h
++++ b/fs/cifs/smb2pdu.h
+@@ -56,6 +56,9 @@ struct smb2_rdma_crypto_transform {
+ 
+ #define COMPOUND_FID 0xFFFFFFFFFFFFFFFFULL
+ 
++#define SMB2_SYMLINK_STRUCT_SIZE \
++	(sizeof(struct smb2_err_rsp) - 1 + sizeof(struct smb2_symlink_err_rsp))
++
+ #define SYMLINK_ERROR_TAG 0x4c4d5953
+ 
+ struct smb2_symlink_err_rsp {
+diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
+index 3f740f24b96a7..7818d0b835672 100644
+--- a/fs/cifs/smb2proto.h
++++ b/fs/cifs/smb2proto.h
+@@ -53,16 +53,12 @@ extern bool smb2_is_valid_oplock_break(char *buffer,
+ 				       struct TCP_Server_Info *srv);
+ extern int smb3_handle_read_data(struct TCP_Server_Info *server,
+ 				 struct mid_q_entry *mid);
+-
+-extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst,
+-				   struct smb2_file_all_info *src);
+ extern int smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
+ 				struct cifs_sb_info *cifs_sb, const char *path,
+ 				__u32 *reparse_tag);
+-extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+-				struct cifs_sb_info *cifs_sb,
+-				const char *full_path, FILE_ALL_INFO *data,
+-				bool *adjust_tz, bool *symlink);
++int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
++			 struct cifs_sb_info *cifs_sb, const char *full_path,
++			 struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse);
+ extern int smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
+ 			      const char *full_path, __u64 size,
+ 			      struct cifs_sb_info *cifs_sb, bool set_alloc);
+@@ -95,9 +91,9 @@ extern int smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
+ 			  struct cifs_sb_info *cifs_sb,
+ 			  const unsigned char *path, char *pbuf,
+ 			  unsigned int *pbytes_read);
+-extern int smb2_open_file(const unsigned int xid,
+-			  struct cifs_open_parms *oparms,
+-			  __u32 *oplock, FILE_ALL_INFO *buf);
++int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov, char **path);
++int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __u32 *oplock,
++		   void *buf);
+ extern int smb2_unlock_range(struct cifsFileInfo *cfile,
+ 			     struct file_lock *flock, const unsigned int xid);
+ extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile);
+@@ -278,9 +274,9 @@ extern int smb2_query_info_compound(const unsigned int xid,
+ 				    struct kvec *rsp, int *buftype,
+ 				    struct cifs_sb_info *cifs_sb);
+ /* query path info from the server using SMB311 POSIX extensions*/
+-extern int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
+-			struct cifs_sb_info *sb, const char *path, struct smb311_posix_qinfo *qinf,
+-			bool *adjust_tx, bool *symlink);
++int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
++				 struct cifs_sb_info *cifs_sb, const char *full_path,
++				 struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse);
+ int posix_info_parse(const void *beg, const void *end,
+ 		     struct smb2_posix_info_parsed *out);
+ int posix_info_sid_size(const void *beg, const void *end);
+diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
+index d1f9d26322027..ec6519e1ca3bf 100644
+--- a/fs/configfs/dir.c
++++ b/fs/configfs/dir.c
+@@ -316,6 +316,7 @@ static int configfs_create_dir(struct config_item *item, struct dentry *dentry,
+ 	return 0;
+ 
+ out_remove:
++	configfs_put(dentry->d_fsdata);
+ 	configfs_remove_dirent(dentry);
+ 	return PTR_ERR(inode);
+ }
+@@ -382,6 +383,7 @@ int configfs_create_link(struct configfs_dirent *target, struct dentry *parent,
+ 	return 0;
+ 
+ out_remove:
++	configfs_put(dentry->d_fsdata);
+ 	configfs_remove_dirent(dentry);
+ 	return PTR_ERR(inode);
+ }
+diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
+index 950c63fa4d0b2..38930d9b0bb73 100644
+--- a/fs/debugfs/file.c
++++ b/fs/debugfs/file.c
+@@ -378,8 +378,8 @@ ssize_t debugfs_attr_read(struct file *file, char __user *buf,
+ }
+ EXPORT_SYMBOL_GPL(debugfs_attr_read);
+ 
+-ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+-			 size_t len, loff_t *ppos)
++static ssize_t debugfs_attr_write_xsigned(struct file *file, const char __user *buf,
++			 size_t len, loff_t *ppos, bool is_signed)
+ {
+ 	struct dentry *dentry = F_DENTRY(file);
+ 	ssize_t ret;
+@@ -387,12 +387,28 @@ ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+ 	ret = debugfs_file_get(dentry);
+ 	if (unlikely(ret))
+ 		return ret;
+-	ret = simple_attr_write(file, buf, len, ppos);
++	if (is_signed)
++		ret = simple_attr_write_signed(file, buf, len, ppos);
++	else
++		ret = simple_attr_write(file, buf, len, ppos);
+ 	debugfs_file_put(dentry);
+ 	return ret;
+ }
++
++ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
++			 size_t len, loff_t *ppos)
++{
++	return debugfs_attr_write_xsigned(file, buf, len, ppos, false);
++}
+ EXPORT_SYMBOL_GPL(debugfs_attr_write);
+ 
++ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf,
++			 size_t len, loff_t *ppos)
++{
++	return debugfs_attr_write_xsigned(file, buf, len, ppos, true);
++}
++EXPORT_SYMBOL_GPL(debugfs_attr_write_signed);
++
+ static struct dentry *debugfs_create_mode_unsafe(const char *name, umode_t mode,
+ 					struct dentry *parent, void *value,
+ 					const struct file_operations *fops,
+@@ -738,11 +754,11 @@ static int debugfs_atomic_t_get(void *data, u64 *val)
+ 	*val = atomic_read((atomic_t *)data);
+ 	return 0;
+ }
+-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t, debugfs_atomic_t_get,
++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t, debugfs_atomic_t_get,
+ 			debugfs_atomic_t_set, "%lld\n");
+-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_ro, debugfs_atomic_t_get, NULL,
++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t_ro, debugfs_atomic_t_get, NULL,
+ 			"%lld\n");
+-DEFINE_DEBUGFS_ATTRIBUTE(fops_atomic_t_wo, NULL, debugfs_atomic_t_set,
++DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(fops_atomic_t_wo, NULL, debugfs_atomic_t_set,
+ 			"%lld\n");
+ 
+ /**
+diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
+index 2d55569f96ace..51b7ac7166d96 100644
+--- a/fs/erofs/decompressor.c
++++ b/fs/erofs/decompressor.c
+@@ -317,52 +317,61 @@ dstmap_out:
+ 	return ret;
+ }
+ 
+-static int z_erofs_shifted_transform(struct z_erofs_decompress_req *rq,
+-				     struct page **pagepool)
++static int z_erofs_transform_plain(struct z_erofs_decompress_req *rq,
++				   struct page **pagepool)
+ {
+-	const unsigned int nrpages_out =
++	const unsigned int inpages = PAGE_ALIGN(rq->inputsize) >> PAGE_SHIFT;
++	const unsigned int outpages =
+ 		PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT;
+ 	const unsigned int righthalf = min_t(unsigned int, rq->outputsize,
+ 					     PAGE_SIZE - rq->pageofs_out);
+ 	const unsigned int lefthalf = rq->outputsize - righthalf;
++	const unsigned int interlaced_offset =
++		rq->alg == Z_EROFS_COMPRESSION_SHIFTED ? 0 : rq->pageofs_out;
+ 	unsigned char *src, *dst;
+ 
+-	if (nrpages_out > 2) {
++	if (outpages > 2 && rq->alg == Z_EROFS_COMPRESSION_SHIFTED) {
+ 		DBG_BUGON(1);
+-		return -EIO;
++		return -EFSCORRUPTED;
+ 	}
+ 
+ 	if (rq->out[0] == *rq->in) {
+-		DBG_BUGON(nrpages_out != 1);
++		DBG_BUGON(rq->pageofs_out);
+ 		return 0;
+ 	}
+ 
+-	src = kmap_atomic(*rq->in) + rq->pageofs_in;
++	src = kmap_local_page(rq->in[inpages - 1]) + rq->pageofs_in;
+ 	if (rq->out[0]) {
+-		dst = kmap_atomic(rq->out[0]);
+-		memcpy(dst + rq->pageofs_out, src, righthalf);
+-		kunmap_atomic(dst);
++		dst = kmap_local_page(rq->out[0]);
++		memcpy(dst + rq->pageofs_out, src + interlaced_offset,
++		       righthalf);
++		kunmap_local(dst);
+ 	}
+ 
+-	if (nrpages_out == 2) {
+-		DBG_BUGON(!rq->out[1]);
+-		if (rq->out[1] == *rq->in) {
++	if (outpages > inpages) {
++		DBG_BUGON(!rq->out[outpages - 1]);
++		if (rq->out[outpages - 1] != rq->in[inpages - 1]) {
++			dst = kmap_local_page(rq->out[outpages - 1]);
++			memcpy(dst, interlaced_offset ? src :
++					(src + righthalf), lefthalf);
++			kunmap_local(dst);
++		} else if (!interlaced_offset) {
+ 			memmove(src, src + righthalf, lefthalf);
+-		} else {
+-			dst = kmap_atomic(rq->out[1]);
+-			memcpy(dst, src + righthalf, lefthalf);
+-			kunmap_atomic(dst);
+ 		}
+ 	}
+-	kunmap_atomic(src);
++	kunmap_local(src);
+ 	return 0;
+ }
+ 
+ static struct z_erofs_decompressor decompressors[] = {
+ 	[Z_EROFS_COMPRESSION_SHIFTED] = {
+-		.decompress = z_erofs_shifted_transform,
++		.decompress = z_erofs_transform_plain,
+ 		.name = "shifted"
+ 	},
++	[Z_EROFS_COMPRESSION_INTERLACED] = {
++		.decompress = z_erofs_transform_plain,
++		.name = "interlaced"
++	},
+ 	[Z_EROFS_COMPRESSION_LZ4] = {
+ 		.decompress = z_erofs_lz4_decompress,
+ 		.name = "lz4"
+diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h
+index 2b48373f690b6..5c1de6d7ad71f 100644
+--- a/fs/erofs/erofs_fs.h
++++ b/fs/erofs/erofs_fs.h
+@@ -295,11 +295,13 @@ struct z_erofs_lzma_cfgs {
+  * bit 1 : HEAD1 big pcluster (0 - off; 1 - on)
+  * bit 2 : HEAD2 big pcluster (0 - off; 1 - on)
+  * bit 3 : tailpacking inline pcluster (0 - off; 1 - on)
++ * bit 4 : interlaced plain pcluster (0 - off; 1 - on)
+  */
+ #define Z_EROFS_ADVISE_COMPACTED_2B		0x0001
+ #define Z_EROFS_ADVISE_BIG_PCLUSTER_1		0x0002
+ #define Z_EROFS_ADVISE_BIG_PCLUSTER_2		0x0004
+ #define Z_EROFS_ADVISE_INLINE_PCLUSTER		0x0008
++#define Z_EROFS_ADVISE_INTERLACED_PCLUSTER	0x0010
+ 
+ struct z_erofs_map_header {
+ 	__le16	h_reserved1;
+diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
+index a01cc82795a25..12d075dfb964b 100644
+--- a/fs/erofs/internal.h
++++ b/fs/erofs/internal.h
+@@ -407,6 +407,7 @@ struct erofs_map_blocks {
+ 
+ enum {
+ 	Z_EROFS_COMPRESSION_SHIFTED = Z_EROFS_COMPRESSION_MAX,
++	Z_EROFS_COMPRESSION_INTERLACED,
+ 	Z_EROFS_COMPRESSION_RUNTIME_MAX
+ };
+ 
+diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
+index c7511b4317763..f19875d96cc1f 100644
+--- a/fs/erofs/zdata.c
++++ b/fs/erofs/zdata.c
+@@ -487,7 +487,8 @@ static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe)
+ 	struct erofs_workgroup *grp;
+ 	int err;
+ 
+-	if (!(map->m_flags & EROFS_MAP_ENCODED)) {
++	if (!(map->m_flags & EROFS_MAP_ENCODED) ||
++	    (!ztailpacking && !(map->m_pa >> PAGE_SHIFT))) {
+ 		DBG_BUGON(1);
+ 		return -EFSCORRUPTED;
+ 	}
+diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
+index 63fd2f1460265..720d74b5c699d 100644
+--- a/fs/erofs/zmap.c
++++ b/fs/erofs/zmap.c
+@@ -673,15 +673,26 @@ static int z_erofs_do_map_blocks(struct inode *inode,
+ 		map->m_pa = blknr_to_addr(m.pblk);
+ 		err = z_erofs_get_extent_compressedlen(&m, initial_lcn);
+ 		if (err)
+-			goto out;
++			goto unmap_out;
+ 	}
+ 
+-	if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN)
+-		map->m_algorithmformat = Z_EROFS_COMPRESSION_SHIFTED;
+-	else if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2)
++	if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_PLAIN) {
++		if (map->m_llen > map->m_plen) {
++			DBG_BUGON(1);
++			err = -EFSCORRUPTED;
++			goto unmap_out;
++		}
++		if (vi->z_advise & Z_EROFS_ADVISE_INTERLACED_PCLUSTER)
++			map->m_algorithmformat =
++				Z_EROFS_COMPRESSION_INTERLACED;
++		else
++			map->m_algorithmformat =
++				Z_EROFS_COMPRESSION_SHIFTED;
++	} else if (m.headtype == Z_EROFS_VLE_CLUSTER_TYPE_HEAD2) {
+ 		map->m_algorithmformat = vi->z_algorithmtype[1];
+-	else
++	} else {
+ 		map->m_algorithmformat = vi->z_algorithmtype[0];
++	}
+ 
+ 	if ((flags & EROFS_GET_BLOCKS_FIEMAP) ||
+ 	    ((flags & EROFS_GET_BLOCKS_READMORE) &&
+@@ -691,14 +702,12 @@ static int z_erofs_do_map_blocks(struct inode *inode,
+ 		if (!err)
+ 			map->m_flags |= EROFS_MAP_FULL_MAPPED;
+ 	}
++
+ unmap_out:
+ 	erofs_unmap_metabuf(&m.map->buf);
+-
+-out:
+ 	erofs_dbg("%s, m_la %llu m_pa %llu m_llen %llu m_plen %llu m_flags 0%o",
+ 		  __func__, map->m_la, map->m_pa,
+ 		  map->m_llen, map->m_plen, map->m_flags);
+-
+ 	return err;
+ }
+ 
+diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c
+index 70e97075e535e..e70928e92b2cd 100644
+--- a/fs/f2fs/compress.c
++++ b/fs/f2fs/compress.c
+@@ -346,7 +346,7 @@ static int zstd_init_compress_ctx(struct compress_ctx *cc)
+ 	if (!level)
+ 		level = F2FS_ZSTD_DEFAULT_CLEVEL;
+ 
+-	params = zstd_get_params(F2FS_ZSTD_DEFAULT_CLEVEL, cc->rlen);
++	params = zstd_get_params(level, cc->rlen);
+ 	workspace_size = zstd_cstream_workspace_bound(&params.cParams);
+ 
+ 	workspace = f2fs_kvmalloc(F2FS_I_SB(cc->inode),
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 1e57b11ffe2a6..a7227640fbdf2 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -2966,7 +2966,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr)
+ /* Flags that should be inherited by new inodes from their parent. */
+ #define F2FS_FL_INHERITED (F2FS_SYNC_FL | F2FS_NODUMP_FL | F2FS_NOATIME_FL | \
+ 			   F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \
+-			   F2FS_CASEFOLD_FL | F2FS_COMPR_FL | F2FS_NOCOMP_FL)
++			   F2FS_CASEFOLD_FL)
+ 
+ /* Flags that are appropriate for regular files (all but dir-specific ones). */
+ #define F2FS_REG_FLMASK		(~(F2FS_DIRSYNC_FL | F2FS_PROJINHERIT_FL | \
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index ce4905a073b3c..74337edcbbb09 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -1866,6 +1866,10 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
+ 			if (!f2fs_disable_compressed_file(inode))
+ 				return -EINVAL;
+ 		} else {
++			/* try to convert inline_data to support compression */
++			int err = f2fs_convert_inline_inode(inode);
++			if (err)
++				return err;
+ 			if (!f2fs_may_compress(inode))
+ 				return -EINVAL;
+ 			if (S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode))
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 73881314bdda8..68eb1d33128be 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -1738,8 +1738,9 @@ freed:
+ 				get_valid_blocks(sbi, segno, false) == 0)
+ 			seg_freed++;
+ 
+-		if (__is_large_section(sbi) && segno + 1 < end_segno)
+-			sbi->next_victim_seg[gc_type] = segno + 1;
++		if (__is_large_section(sbi))
++			sbi->next_victim_seg[gc_type] =
++				(segno + 1 < end_segno) ? segno + 1 : NULL_SEGNO;
+ skip:
+ 		f2fs_put_page(sum_page, 0);
+ 	}
+@@ -2127,8 +2128,6 @@ out_unlock:
+ 	if (err)
+ 		return err;
+ 
+-	set_sbi_flag(sbi, SBI_IS_RESIZEFS);
+-
+ 	freeze_super(sbi->sb);
+ 	f2fs_down_write(&sbi->gc_lock);
+ 	f2fs_down_write(&sbi->cp_global_sem);
+@@ -2144,6 +2143,7 @@ out_unlock:
+ 	if (err)
+ 		goto out_err;
+ 
++	set_sbi_flag(sbi, SBI_IS_RESIZEFS);
+ 	err = free_segment_range(sbi, secs, false);
+ 	if (err)
+ 		goto recover_out;
+@@ -2167,6 +2167,7 @@ out_unlock:
+ 		f2fs_commit_super(sbi, false);
+ 	}
+ recover_out:
++	clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
+ 	if (err) {
+ 		set_sbi_flag(sbi, SBI_NEED_FSCK);
+ 		f2fs_err(sbi, "resize_fs failed, should run fsck to repair!");
+@@ -2179,6 +2180,5 @@ out_err:
+ 	f2fs_up_write(&sbi->cp_global_sem);
+ 	f2fs_up_write(&sbi->gc_lock);
+ 	thaw_super(sbi->sb);
+-	clear_sbi_flag(sbi, SBI_IS_RESIZEFS);
+ 	return err;
+ }
+diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
+index bf00d5057abb8..0073e3511b2ad 100644
+--- a/fs/f2fs/namei.c
++++ b/fs/f2fs/namei.c
+@@ -22,8 +22,163 @@
+ #include "acl.h"
+ #include <trace/events/f2fs.h>
+ 
++static inline int is_extension_exist(const unsigned char *s, const char *sub,
++						bool tmp_ext)
++{
++	size_t slen = strlen(s);
++	size_t sublen = strlen(sub);
++	int i;
++
++	if (sublen == 1 && *sub == '*')
++		return 1;
++
++	/*
++	 * filename format of multimedia file should be defined as:
++	 * "filename + '.' + extension + (optional: '.' + temp extension)".
++	 */
++	if (slen < sublen + 2)
++		return 0;
++
++	if (!tmp_ext) {
++		/* file has no temp extension */
++		if (s[slen - sublen - 1] != '.')
++			return 0;
++		return !strncasecmp(s + slen - sublen, sub, sublen);
++	}
++
++	for (i = 1; i < slen - sublen; i++) {
++		if (s[i] != '.')
++			continue;
++		if (!strncasecmp(s + i + 1, sub, sublen))
++			return 1;
++	}
++
++	return 0;
++}
++
++int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
++							bool hot, bool set)
++{
++	__u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
++	int cold_count = le32_to_cpu(sbi->raw_super->extension_count);
++	int hot_count = sbi->raw_super->hot_ext_count;
++	int total_count = cold_count + hot_count;
++	int start, count;
++	int i;
++
++	if (set) {
++		if (total_count == F2FS_MAX_EXTENSION)
++			return -EINVAL;
++	} else {
++		if (!hot && !cold_count)
++			return -EINVAL;
++		if (hot && !hot_count)
++			return -EINVAL;
++	}
++
++	if (hot) {
++		start = cold_count;
++		count = total_count;
++	} else {
++		start = 0;
++		count = cold_count;
++	}
++
++	for (i = start; i < count; i++) {
++		if (strcmp(name, extlist[i]))
++			continue;
++
++		if (set)
++			return -EINVAL;
++
++		memcpy(extlist[i], extlist[i + 1],
++				F2FS_EXTENSION_LEN * (total_count - i - 1));
++		memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN);
++		if (hot)
++			sbi->raw_super->hot_ext_count = hot_count - 1;
++		else
++			sbi->raw_super->extension_count =
++						cpu_to_le32(cold_count - 1);
++		return 0;
++	}
++
++	if (!set)
++		return -EINVAL;
++
++	if (hot) {
++		memcpy(extlist[count], name, strlen(name));
++		sbi->raw_super->hot_ext_count = hot_count + 1;
++	} else {
++		char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN];
++
++		memcpy(buf, &extlist[cold_count],
++				F2FS_EXTENSION_LEN * hot_count);
++		memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN);
++		memcpy(extlist[cold_count], name, strlen(name));
++		memcpy(&extlist[cold_count + 1], buf,
++				F2FS_EXTENSION_LEN * hot_count);
++		sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1);
++	}
++	return 0;
++}
++
++static void set_compress_new_inode(struct f2fs_sb_info *sbi, struct inode *dir,
++				struct inode *inode, const unsigned char *name)
++{
++	__u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
++	unsigned char (*noext)[F2FS_EXTENSION_LEN] =
++						F2FS_OPTION(sbi).noextensions;
++	unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions;
++	unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt;
++	unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt;
++	int i, cold_count, hot_count;
++
++	if (!f2fs_sb_has_compression(sbi))
++		return;
++
++	if (S_ISDIR(inode->i_mode))
++		goto inherit_comp;
++
++	/* This name comes only from normal files. */
++	if (!name)
++		return;
++
++	/* Don't compress hot files. */
++	f2fs_down_read(&sbi->sb_lock);
++	cold_count = le32_to_cpu(sbi->raw_super->extension_count);
++	hot_count = sbi->raw_super->hot_ext_count;
++	for (i = cold_count; i < cold_count + hot_count; i++)
++		if (is_extension_exist(name, extlist[i], false))
++			break;
++	f2fs_up_read(&sbi->sb_lock);
++	if (i < (cold_count + hot_count))
++		return;
++
++	/* Don't compress unallowed extension. */
++	for (i = 0; i < noext_cnt; i++)
++		if (is_extension_exist(name, noext[i], false))
++			return;
++
++	/* Compress wanting extension. */
++	for (i = 0; i < ext_cnt; i++) {
++		if (is_extension_exist(name, ext[i], false)) {
++			set_compress_context(inode);
++			return;
++		}
++	}
++inherit_comp:
++	/* Inherit the {no-}compression flag in directory */
++	if (F2FS_I(dir)->i_flags & F2FS_NOCOMP_FL) {
++		F2FS_I(inode)->i_flags |= F2FS_NOCOMP_FL;
++		f2fs_mark_inode_dirty_sync(inode, true);
++	} else if (F2FS_I(dir)->i_flags & F2FS_COMPR_FL) {
++		set_compress_context(inode);
++	}
++}
++
+ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns,
+-						struct inode *dir, umode_t mode)
++						struct inode *dir, umode_t mode,
++						const char *name)
+ {
+ 	struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
+ 	nid_t ino;
+@@ -114,12 +269,8 @@ static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns,
+ 	if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL)
+ 		set_inode_flag(inode, FI_PROJ_INHERIT);
+ 
+-	if (f2fs_sb_has_compression(sbi)) {
+-		/* Inherit the compression flag in directory */
+-		if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) &&
+-					f2fs_may_compress(inode))
+-			set_compress_context(inode);
+-	}
++	/* Check compression first. */
++	set_compress_new_inode(sbi, dir, inode, name);
+ 
+ 	/* Should enable inline_data after compression set */
+ 	if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode))
+@@ -153,40 +304,6 @@ fail_drop:
+ 	return ERR_PTR(err);
+ }
+ 
+-static inline int is_extension_exist(const unsigned char *s, const char *sub,
+-						bool tmp_ext)
+-{
+-	size_t slen = strlen(s);
+-	size_t sublen = strlen(sub);
+-	int i;
+-
+-	if (sublen == 1 && *sub == '*')
+-		return 1;
+-
+-	/*
+-	 * filename format of multimedia file should be defined as:
+-	 * "filename + '.' + extension + (optional: '.' + temp extension)".
+-	 */
+-	if (slen < sublen + 2)
+-		return 0;
+-
+-	if (!tmp_ext) {
+-		/* file has no temp extension */
+-		if (s[slen - sublen - 1] != '.')
+-			return 0;
+-		return !strncasecmp(s + slen - sublen, sub, sublen);
+-	}
+-
+-	for (i = 1; i < slen - sublen; i++) {
+-		if (s[i] != '.')
+-			continue;
+-		if (!strncasecmp(s + i + 1, sub, sublen))
+-			return 1;
+-	}
+-
+-	return 0;
+-}
+-
+ /*
+  * Set file's temperature for hot/cold data separation
+  */
+@@ -217,124 +334,6 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode *
+ 		file_set_hot(inode);
+ }
+ 
+-int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
+-							bool hot, bool set)
+-{
+-	__u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
+-	int cold_count = le32_to_cpu(sbi->raw_super->extension_count);
+-	int hot_count = sbi->raw_super->hot_ext_count;
+-	int total_count = cold_count + hot_count;
+-	int start, count;
+-	int i;
+-
+-	if (set) {
+-		if (total_count == F2FS_MAX_EXTENSION)
+-			return -EINVAL;
+-	} else {
+-		if (!hot && !cold_count)
+-			return -EINVAL;
+-		if (hot && !hot_count)
+-			return -EINVAL;
+-	}
+-
+-	if (hot) {
+-		start = cold_count;
+-		count = total_count;
+-	} else {
+-		start = 0;
+-		count = cold_count;
+-	}
+-
+-	for (i = start; i < count; i++) {
+-		if (strcmp(name, extlist[i]))
+-			continue;
+-
+-		if (set)
+-			return -EINVAL;
+-
+-		memcpy(extlist[i], extlist[i + 1],
+-				F2FS_EXTENSION_LEN * (total_count - i - 1));
+-		memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN);
+-		if (hot)
+-			sbi->raw_super->hot_ext_count = hot_count - 1;
+-		else
+-			sbi->raw_super->extension_count =
+-						cpu_to_le32(cold_count - 1);
+-		return 0;
+-	}
+-
+-	if (!set)
+-		return -EINVAL;
+-
+-	if (hot) {
+-		memcpy(extlist[count], name, strlen(name));
+-		sbi->raw_super->hot_ext_count = hot_count + 1;
+-	} else {
+-		char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN];
+-
+-		memcpy(buf, &extlist[cold_count],
+-				F2FS_EXTENSION_LEN * hot_count);
+-		memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN);
+-		memcpy(extlist[cold_count], name, strlen(name));
+-		memcpy(&extlist[cold_count + 1], buf,
+-				F2FS_EXTENSION_LEN * hot_count);
+-		sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1);
+-	}
+-	return 0;
+-}
+-
+-static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode,
+-						const unsigned char *name)
+-{
+-	__u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
+-	unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions;
+-	unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions;
+-	unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt;
+-	unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt;
+-	int i, cold_count, hot_count;
+-
+-	if (!f2fs_sb_has_compression(sbi) ||
+-			F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL ||
+-			!f2fs_may_compress(inode) ||
+-			(!ext_cnt && !noext_cnt))
+-		return;
+-
+-	f2fs_down_read(&sbi->sb_lock);
+-
+-	cold_count = le32_to_cpu(sbi->raw_super->extension_count);
+-	hot_count = sbi->raw_super->hot_ext_count;
+-
+-	for (i = cold_count; i < cold_count + hot_count; i++) {
+-		if (is_extension_exist(name, extlist[i], false)) {
+-			f2fs_up_read(&sbi->sb_lock);
+-			return;
+-		}
+-	}
+-
+-	f2fs_up_read(&sbi->sb_lock);
+-
+-	for (i = 0; i < noext_cnt; i++) {
+-		if (is_extension_exist(name, noext[i], false)) {
+-			f2fs_disable_compressed_file(inode);
+-			return;
+-		}
+-	}
+-
+-	if (is_inode_flag_set(inode, FI_COMPRESSED_FILE))
+-		return;
+-
+-	for (i = 0; i < ext_cnt; i++) {
+-		if (!is_extension_exist(name, ext[i], false))
+-			continue;
+-
+-		/* Do not use inline_data with compression */
+-		stat_dec_inline_inode(inode);
+-		clear_inode_flag(inode, FI_INLINE_DATA);
+-		set_compress_context(inode);
+-		return;
+-	}
+-}
+-
+ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir,
+ 		       struct dentry *dentry, umode_t mode, bool excl)
+ {
+@@ -352,15 +351,13 @@ static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir,
+ 	if (err)
+ 		return err;
+ 
+-	inode = f2fs_new_inode(mnt_userns, dir, mode);
++	inode = f2fs_new_inode(mnt_userns, dir, mode, dentry->d_name.name);
+ 	if (IS_ERR(inode))
+ 		return PTR_ERR(inode);
+ 
+ 	if (!test_opt(sbi, DISABLE_EXT_IDENTIFY))
+ 		set_file_temperature(sbi, inode, dentry->d_name.name);
+ 
+-	set_compress_inode(sbi, inode, dentry->d_name.name);
+-
+ 	inode->i_op = &f2fs_file_inode_operations;
+ 	inode->i_fop = &f2fs_file_operations;
+ 	inode->i_mapping->a_ops = &f2fs_dblock_aops;
+@@ -689,7 +686,7 @@ static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
+ 	if (err)
+ 		return err;
+ 
+-	inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO);
++	inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO, NULL);
+ 	if (IS_ERR(inode))
+ 		return PTR_ERR(inode);
+ 
+@@ -760,7 +757,7 @@ static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
+ 	if (err)
+ 		return err;
+ 
+-	inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode);
++	inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode, NULL);
+ 	if (IS_ERR(inode))
+ 		return PTR_ERR(inode);
+ 
+@@ -817,7 +814,7 @@ static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
+ 	if (err)
+ 		return err;
+ 
+-	inode = f2fs_new_inode(mnt_userns, dir, mode);
++	inode = f2fs_new_inode(mnt_userns, dir, mode, NULL);
+ 	if (IS_ERR(inode))
+ 		return PTR_ERR(inode);
+ 
+@@ -856,7 +853,7 @@ static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
+ 	if (err)
+ 		return err;
+ 
+-	inode = f2fs_new_inode(mnt_userns, dir, mode);
++	inode = f2fs_new_inode(mnt_userns, dir, mode, NULL);
+ 	if (IS_ERR(inode))
+ 		return PTR_ERR(inode);
+ 
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 84bad18ce13d5..2afed479160b8 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -1171,7 +1171,7 @@ submit:
+ 
+ 		atomic_inc(&dcc->issued_discard);
+ 
+-		f2fs_update_iostat(sbi, FS_DISCARD, 1);
++		f2fs_update_iostat(sbi, FS_DISCARD, len * F2FS_BLKSIZE);
+ 
+ 		lstart += len;
+ 		start += len;
+@@ -1449,7 +1449,7 @@ retry:
+ 		if (i + 1 < dpolicy->granularity)
+ 			break;
+ 
+-		if (i < DEFAULT_DISCARD_GRANULARITY && dpolicy->ordered)
++		if (i + 1 < DEFAULT_DISCARD_GRANULARITY && dpolicy->ordered)
+ 			return __issue_discard_cmd_orderly(sbi, dpolicy);
+ 
+ 		pend_list = &dcc->pend_list[i];
+@@ -2026,8 +2026,10 @@ int f2fs_start_discard_thread(struct f2fs_sb_info *sbi)
+ 
+ 	dcc->f2fs_issue_discard = kthread_run(issue_discard_thread, sbi,
+ 				"f2fs_discard-%u:%u", MAJOR(dev), MINOR(dev));
+-	if (IS_ERR(dcc->f2fs_issue_discard))
++	if (IS_ERR(dcc->f2fs_issue_discard)) {
+ 		err = PTR_ERR(dcc->f2fs_issue_discard);
++		dcc->f2fs_issue_discard = NULL;
++	}
+ 
+ 	return err;
+ }
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 5415c06d8246f..1187f29dc8e0a 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -4460,9 +4460,9 @@ free_nm:
+ 	f2fs_destroy_node_manager(sbi);
+ free_sm:
+ 	f2fs_destroy_segment_manager(sbi);
+-	f2fs_destroy_post_read_wq(sbi);
+ stop_ckpt_thread:
+ 	f2fs_stop_ckpt_thread(sbi);
++	f2fs_destroy_post_read_wq(sbi);
+ free_devices:
+ 	destroy_device_list(sbi);
+ 	kvfree(sbi->ckpt);
+diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
+index c4526f16355d5..a0746be3c1de7 100644
+--- a/fs/hfs/inode.c
++++ b/fs/hfs/inode.c
+@@ -458,6 +458,8 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
+ 		/* panic? */
+ 		return -EIO;
+ 
++	if (HFS_I(main_inode)->cat_key.CName.len > HFS_NAMELEN)
++		return -EIO;
+ 	fd.search_key->cat = HFS_I(main_inode)->cat_key;
+ 	if (hfs_brec_find(&fd))
+ 		/* panic? */
+diff --git a/fs/hfs/trans.c b/fs/hfs/trans.c
+index 39f5e343bf4d4..fdb0edb8a607d 100644
+--- a/fs/hfs/trans.c
++++ b/fs/hfs/trans.c
+@@ -109,7 +109,7 @@ void hfs_asc2mac(struct super_block *sb, struct hfs_name *out, const struct qstr
+ 	if (nls_io) {
+ 		wchar_t ch;
+ 
+-		while (srclen > 0) {
++		while (srclen > 0 && dstlen > 0) {
+ 			size = nls_io->char2uni(src, srclen, &ch);
+ 			if (size < 0) {
+ 				ch = '?';
+diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
+index fbcfa6bfee805..26169d75f6cf7 100644
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -1256,7 +1256,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
+ 
+ 	case Opt_size:
+ 		/* memparse() will accept a K/M/G without a digit */
+-		if (!isdigit(param->string[0]))
++		if (!param->string || !isdigit(param->string[0]))
+ 			goto bad_val;
+ 		ctx->max_size_opt = memparse(param->string, &rest);
+ 		ctx->max_val_type = SIZE_STD;
+@@ -1266,7 +1266,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
+ 
+ 	case Opt_nr_inodes:
+ 		/* memparse() will accept a K/M/G without a digit */
+-		if (!isdigit(param->string[0]))
++		if (!param->string || !isdigit(param->string[0]))
+ 			goto bad_val;
+ 		ctx->nr_inodes = memparse(param->string, &rest);
+ 		return 0;
+@@ -1282,7 +1282,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
+ 
+ 	case Opt_min_size:
+ 		/* memparse() will accept a K/M/G without a digit */
+-		if (!isdigit(param->string[0]))
++		if (!param->string || !isdigit(param->string[0]))
+ 			goto bad_val;
+ 		ctx->min_size_opt = memparse(param->string, &rest);
+ 		ctx->min_val_type = SIZE_STD;
+diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
+index 6b838d3ae7c2e..765838578a722 100644
+--- a/fs/jfs/jfs_dmap.c
++++ b/fs/jfs/jfs_dmap.c
+@@ -155,7 +155,7 @@ int dbMount(struct inode *ipbmap)
+ 	struct bmap *bmp;
+ 	struct dbmap_disk *dbmp_le;
+ 	struct metapage *mp;
+-	int i;
++	int i, err;
+ 
+ 	/*
+ 	 * allocate/initialize the in-memory bmap descriptor
+@@ -170,8 +170,8 @@ int dbMount(struct inode *ipbmap)
+ 			   BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage,
+ 			   PSIZE, 0);
+ 	if (mp == NULL) {
+-		kfree(bmp);
+-		return -EIO;
++		err = -EIO;
++		goto err_kfree_bmp;
+ 	}
+ 
+ 	/* copy the on-disk bmap descriptor to its in-memory version. */
+@@ -181,9 +181,8 @@ int dbMount(struct inode *ipbmap)
+ 	bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
+ 	bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag);
+ 	if (!bmp->db_numag) {
+-		release_metapage(mp);
+-		kfree(bmp);
+-		return -EINVAL;
++		err = -EINVAL;
++		goto err_release_metapage;
+ 	}
+ 
+ 	bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
+@@ -194,6 +193,16 @@ int dbMount(struct inode *ipbmap)
+ 	bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
+ 	bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
+ 	bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
++	if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) {
++		err = -EINVAL;
++		goto err_release_metapage;
++	}
++
++	if (((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) {
++		err = -EINVAL;
++		goto err_release_metapage;
++	}
++
+ 	for (i = 0; i < MAXAG; i++)
+ 		bmp->db_agfree[i] = le64_to_cpu(dbmp_le->dn_agfree[i]);
+ 	bmp->db_agsize = le64_to_cpu(dbmp_le->dn_agsize);
+@@ -214,6 +223,12 @@ int dbMount(struct inode *ipbmap)
+ 	BMAP_LOCK_INIT(bmp);
+ 
+ 	return (0);
++
++err_release_metapage:
++	release_metapage(mp);
++err_kfree_bmp:
++	kfree(bmp);
++	return err;
+ }
+ 
+ 
+diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
+index 9db4f5789c0ec..4fbbf88435e69 100644
+--- a/fs/jfs/namei.c
++++ b/fs/jfs/namei.c
+@@ -946,7 +946,7 @@ static int jfs_symlink(struct user_namespace *mnt_userns, struct inode *dip,
+ 	if (ssize <= IDATASIZE) {
+ 		ip->i_op = &jfs_fast_symlink_inode_operations;
+ 
+-		ip->i_link = JFS_IP(ip)->i_inline;
++		ip->i_link = JFS_IP(ip)->i_inline_all;
+ 		memcpy(ip->i_link, name, ssize);
+ 		ip->i_size = ssize - 1;
+ 
+diff --git a/fs/ksmbd/mgmt/user_session.c b/fs/ksmbd/mgmt/user_session.c
+index 3fa2139a0b309..92b1603b5abeb 100644
+--- a/fs/ksmbd/mgmt/user_session.c
++++ b/fs/ksmbd/mgmt/user_session.c
+@@ -108,15 +108,17 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
+ 	entry->method = method;
+ 	entry->id = ksmbd_ipc_id_alloc();
+ 	if (entry->id < 0)
+-		goto error;
++		goto free_entry;
+ 
+ 	resp = ksmbd_rpc_open(sess, entry->id);
+ 	if (!resp)
+-		goto error;
++		goto free_id;
+ 
+ 	kvfree(resp);
+ 	return entry->id;
+-error:
++free_id:
++	ksmbd_rpc_id_free(entry->id);
++free_entry:
+ 	list_del(&entry->list);
+ 	kfree(entry);
+ 	return -EINVAL;
+diff --git a/fs/libfs.c b/fs/libfs.c
+index 31b0ddf01c31d..76fb29a103a2f 100644
+--- a/fs/libfs.c
++++ b/fs/libfs.c
+@@ -994,8 +994,8 @@ out:
+ EXPORT_SYMBOL_GPL(simple_attr_read);
+ 
+ /* interpret the buffer as a number to call the set function with */
+-ssize_t simple_attr_write(struct file *file, const char __user *buf,
+-			  size_t len, loff_t *ppos)
++static ssize_t simple_attr_write_xsigned(struct file *file, const char __user *buf,
++			  size_t len, loff_t *ppos, bool is_signed)
+ {
+ 	struct simple_attr *attr;
+ 	unsigned long long val;
+@@ -1016,7 +1016,10 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
+ 		goto out;
+ 
+ 	attr->set_buf[size] = '\0';
+-	ret = kstrtoull(attr->set_buf, 0, &val);
++	if (is_signed)
++		ret = kstrtoll(attr->set_buf, 0, &val);
++	else
++		ret = kstrtoull(attr->set_buf, 0, &val);
+ 	if (ret)
+ 		goto out;
+ 	ret = attr->set(attr->data, val);
+@@ -1026,8 +1029,21 @@ out:
+ 	mutex_unlock(&attr->mutex);
+ 	return ret;
+ }
++
++ssize_t simple_attr_write(struct file *file, const char __user *buf,
++			  size_t len, loff_t *ppos)
++{
++	return simple_attr_write_xsigned(file, buf, len, ppos, false);
++}
+ EXPORT_SYMBOL_GPL(simple_attr_write);
+ 
++ssize_t simple_attr_write_signed(struct file *file, const char __user *buf,
++			  size_t len, loff_t *ppos)
++{
++	return simple_attr_write_xsigned(file, buf, len, ppos, true);
++}
++EXPORT_SYMBOL_GPL(simple_attr_write_signed);
++
+ /**
+  * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
+  * @sb:		filesystem to do the file handle conversion on
+diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
+index e1c4617de7714..3515f17eaf3fb 100644
+--- a/fs/lockd/svcsubs.c
++++ b/fs/lockd/svcsubs.c
+@@ -176,7 +176,7 @@ nlm_delete_file(struct nlm_file *file)
+ 	}
+ }
+ 
+-static int nlm_unlock_files(struct nlm_file *file, fl_owner_t owner)
++static int nlm_unlock_files(struct nlm_file *file, const struct file_lock *fl)
+ {
+ 	struct file_lock lock;
+ 
+@@ -184,12 +184,15 @@ static int nlm_unlock_files(struct nlm_file *file, fl_owner_t owner)
+ 	lock.fl_type  = F_UNLCK;
+ 	lock.fl_start = 0;
+ 	lock.fl_end   = OFFSET_MAX;
+-	lock.fl_owner = owner;
+-	if (file->f_file[O_RDONLY] &&
+-	    vfs_lock_file(file->f_file[O_RDONLY], F_SETLK, &lock, NULL))
++	lock.fl_owner = fl->fl_owner;
++	lock.fl_pid   = fl->fl_pid;
++	lock.fl_flags = FL_POSIX;
++
++	lock.fl_file = file->f_file[O_RDONLY];
++	if (lock.fl_file && vfs_lock_file(lock.fl_file, F_SETLK, &lock, NULL))
+ 		goto out_err;
+-	if (file->f_file[O_WRONLY] &&
+-	    vfs_lock_file(file->f_file[O_WRONLY], F_SETLK, &lock, NULL))
++	lock.fl_file = file->f_file[O_WRONLY];
++	if (lock.fl_file && vfs_lock_file(lock.fl_file, F_SETLK, &lock, NULL))
+ 		goto out_err;
+ 	return 0;
+ out_err:
+@@ -226,7 +229,7 @@ again:
+ 		if (match(lockhost, host)) {
+ 
+ 			spin_unlock(&flctx->flc_lock);
+-			if (nlm_unlock_files(file, fl->fl_owner))
++			if (nlm_unlock_files(file, fl))
+ 				return 1;
+ 			goto again;
+ 		}
+diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c
+index 4da701fd1424f..0c330bc13ef20 100644
+--- a/fs/nfs/fs_context.c
++++ b/fs/nfs/fs_context.c
+@@ -684,6 +684,8 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
+ 			return ret;
+ 		break;
+ 	case Opt_vers:
++		if (!param->string)
++			goto out_invalid_value;
+ 		trace_nfs_mount_assign(param->key, param->string);
+ 		ret = nfs_parse_version_string(fc, param->string);
+ 		if (ret < 0)
+@@ -696,6 +698,8 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
+ 		break;
+ 
+ 	case Opt_proto:
++		if (!param->string)
++			goto out_invalid_value;
+ 		trace_nfs_mount_assign(param->key, param->string);
+ 		protofamily = AF_INET;
+ 		switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) {
+@@ -732,6 +736,8 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
+ 		break;
+ 
+ 	case Opt_mountproto:
++		if (!param->string)
++			goto out_invalid_value;
+ 		trace_nfs_mount_assign(param->key, param->string);
+ 		mountfamily = AF_INET;
+ 		switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) {
+diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
+index 898dd95bc7a7c..c194a1e50f0bc 100644
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -741,12 +741,10 @@ unsigned long nfs_io_size(unsigned long iosize, enum xprt_transports proto)
+ 		iosize = NFS_DEF_FILE_IO_SIZE;
+ 	else if (iosize >= NFS_MAX_FILE_IO_SIZE)
+ 		iosize = NFS_MAX_FILE_IO_SIZE;
+-	else
+-		iosize = iosize & PAGE_MASK;
+ 
+-	if (proto == XPRT_TRANSPORT_UDP)
++	if (proto == XPRT_TRANSPORT_UDP || iosize < PAGE_SIZE)
+ 		return nfs_block_bits(iosize, NULL);
+-	return iosize;
++	return iosize & PAGE_MASK;
+ }
+ 
+ /*
+diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
+index 3295af4110f1b..c7363d9e11bf2 100644
+--- a/fs/nfs/namespace.c
++++ b/fs/nfs/namespace.c
+@@ -147,7 +147,7 @@ struct vfsmount *nfs_d_automount(struct path *path)
+ 	struct nfs_fs_context *ctx;
+ 	struct fs_context *fc;
+ 	struct vfsmount *mnt = ERR_PTR(-ENOMEM);
+-	struct nfs_server *server = NFS_SERVER(d_inode(path->dentry));
++	struct nfs_server *server = NFS_SB(path->dentry->d_sb);
+ 	struct nfs_client *client = server->nfs_client;
+ 	int timeout = READ_ONCE(nfs_mountpoint_expiry_timeout);
+ 	int ret;
+diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
+index b56f05113d367..f742c7a5745e0 100644
+--- a/fs/nfs/nfs42xdr.c
++++ b/fs/nfs/nfs42xdr.c
+@@ -1134,7 +1134,7 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
+ 	if (!segs)
+ 		return -ENOMEM;
+ 
+-	xdr_set_scratch_buffer(xdr, &scratch_buf, 32);
++	xdr_set_scratch_buffer(xdr, &scratch_buf, sizeof(scratch_buf));
+ 	status = -EIO;
+ 	for (i = 0; i < segments; i++) {
+ 		status = decode_read_plus_segment(xdr, &segs[i]);
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 313e9145b6c9f..6e247647a5fb6 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -122,6 +122,11 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
+ 	if (nfs_server_capable(dir, NFS_CAP_SECURITY_LABEL) == 0)
+ 		return NULL;
+ 
++	label->lfs = 0;
++	label->pi = 0;
++	label->len = 0;
++	label->label = NULL;
++
+ 	err = security_dentry_init_security(dentry, sattr->ia_mode,
+ 				&dentry->d_name, NULL,
+ 				(void **)&label->label, &label->len);
+@@ -2125,18 +2130,18 @@ static struct nfs4_opendata *nfs4_open_recoverdata_alloc(struct nfs_open_context
+ }
+ 
+ static int nfs4_open_recover_helper(struct nfs4_opendata *opendata,
+-		fmode_t fmode)
++				    fmode_t fmode)
+ {
+ 	struct nfs4_state *newstate;
++	struct nfs_server *server = NFS_SB(opendata->dentry->d_sb);
++	int openflags = opendata->o_arg.open_flags;
+ 	int ret;
+ 
+ 	if (!nfs4_mode_match_open_stateid(opendata->state, fmode))
+ 		return 0;
+-	opendata->o_arg.open_flags = 0;
+ 	opendata->o_arg.fmode = fmode;
+-	opendata->o_arg.share_access = nfs4_map_atomic_open_share(
+-			NFS_SB(opendata->dentry->d_sb),
+-			fmode, 0);
++	opendata->o_arg.share_access =
++		nfs4_map_atomic_open_share(server, fmode, openflags);
+ 	memset(&opendata->o_res, 0, sizeof(opendata->o_res));
+ 	memset(&opendata->c_res, 0, sizeof(opendata->c_res));
+ 	nfs4_init_opendata_res(opendata);
+@@ -2718,10 +2723,15 @@ static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *s
+ 	struct nfs4_opendata *opendata;
+ 	int ret;
+ 
+-	opendata = nfs4_open_recoverdata_alloc(ctx, state,
+-			NFS4_OPEN_CLAIM_FH);
++	opendata = nfs4_open_recoverdata_alloc(ctx, state, NFS4_OPEN_CLAIM_FH);
+ 	if (IS_ERR(opendata))
+ 		return PTR_ERR(opendata);
++	/*
++	 * We're not recovering a delegation, so ask for no delegation.
++	 * Otherwise the recovery thread could deadlock with an outstanding
++	 * delegation return.
++	 */
++	opendata->o_arg.open_flags = O_DIRECT;
+ 	ret = nfs4_open_recover(opendata, state);
+ 	if (ret == -ESTALE)
+ 		d_drop(ctx->dentry);
+@@ -3795,7 +3805,7 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx,
+ 		int open_flags, struct iattr *attr, int *opened)
+ {
+ 	struct nfs4_state *state;
+-	struct nfs4_label l = {0, 0, 0, NULL}, *label = NULL;
++	struct nfs4_label l, *label;
+ 
+ 	label = nfs4_label_init_security(dir, ctx->dentry, attr, &l);
+ 
+@@ -4012,7 +4022,7 @@ static int _nfs4_discover_trunking(struct nfs_server *server,
+ 
+ 	page = alloc_page(GFP_KERNEL);
+ 	if (!page)
+-		return -ENOMEM;
++		goto out_put_cred;
+ 	locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
+ 	if (!locations)
+ 		goto out_free;
+@@ -4034,6 +4044,8 @@ out_free_2:
+ 	kfree(locations);
+ out_free:
+ 	__free_page(page);
++out_put_cred:
++	put_cred(cred);
+ 	return status;
+ }
+ 
+@@ -4681,7 +4693,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
+ 		 int flags)
+ {
+ 	struct nfs_server *server = NFS_SERVER(dir);
+-	struct nfs4_label l, *ilabel = NULL;
++	struct nfs4_label l, *ilabel;
+ 	struct nfs_open_context *ctx;
+ 	struct nfs4_state *state;
+ 	int status = 0;
+@@ -5032,7 +5044,7 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
+ 	struct nfs4_exception exception = {
+ 		.interruptible = true,
+ 	};
+-	struct nfs4_label l, *label = NULL;
++	struct nfs4_label l, *label;
+ 	int err;
+ 
+ 	label = nfs4_label_init_security(dir, dentry, sattr, &l);
+@@ -5073,7 +5085,7 @@ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
+ 	struct nfs4_exception exception = {
+ 		.interruptible = true,
+ 	};
+-	struct nfs4_label l, *label = NULL;
++	struct nfs4_label l, *label;
+ 	int err;
+ 
+ 	label = nfs4_label_init_security(dir, dentry, sattr, &l);
+@@ -5192,7 +5204,7 @@ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
+ 	struct nfs4_exception exception = {
+ 		.interruptible = true,
+ 	};
+-	struct nfs4_label l, *label = NULL;
++	struct nfs4_label l, *label;
+ 	int err;
+ 
+ 	label = nfs4_label_init_security(dir, dentry, sattr, &l);
+diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
+index a629d7db9420a..0774355249c93 100644
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -1232,6 +1232,8 @@ void nfs4_schedule_state_manager(struct nfs_client *clp)
+ 	if (IS_ERR(task)) {
+ 		printk(KERN_ERR "%s: kthread_run: %ld\n",
+ 			__func__, PTR_ERR(task));
++		if (!nfs_client_init_is_complete(clp))
++			nfs_mark_client_ready(clp, PTR_ERR(task));
+ 		nfs4_clear_state_manager_bit(clp);
+ 		clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state);
+ 		nfs_put_client(clp);
+diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
+index acfe5f4bda480..deec76cf5afea 100644
+--- a/fs/nfs/nfs4xdr.c
++++ b/fs/nfs/nfs4xdr.c
+@@ -4234,19 +4234,17 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
+ 		p = xdr_inline_decode(xdr, len);
+ 		if (unlikely(!p))
+ 			return -EIO;
++		bitmap[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
+ 		if (len < NFS4_MAXLABELLEN) {
+-			if (label) {
+-				if (label->len) {
+-					if (label->len < len)
+-						return -ERANGE;
+-					memcpy(label->label, p, len);
+-				}
++			if (label && label->len) {
++				if (label->len < len)
++					return -ERANGE;
++				memcpy(label->label, p, len);
+ 				label->len = len;
+ 				label->pi = pi;
+ 				label->lfs = lfs;
+ 				status = NFS_ATTR_FATTR_V4_SECURITY_LABEL;
+ 			}
+-			bitmap[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
+ 		} else
+ 			printk(KERN_WARNING "%s: label too long (%u)!\n",
+ 					__func__, len);
+@@ -4755,12 +4753,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
+ 	if (status < 0)
+ 		goto xdr_error;
+ 
+-	if (fattr->label) {
+-		status = decode_attr_security_label(xdr, bitmap, fattr->label);
+-		if (status < 0)
+-			goto xdr_error;
+-		fattr->valid |= status;
+-	}
++	status = decode_attr_security_label(xdr, bitmap, fattr->label);
++	if (status < 0)
++		goto xdr_error;
++	fattr->valid |= status;
+ 
+ xdr_error:
+ 	dprintk("%s: xdr returned %d\n", __func__, -status);
+diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
+index 9edd3c1a30fb1..87f224cd30a85 100644
+--- a/fs/nfsd/nfs2acl.c
++++ b/fs/nfsd/nfs2acl.c
+@@ -246,7 +246,6 @@ nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
+ 	struct nfsd3_getaclres *resp = rqstp->rq_resp;
+ 	struct dentry *dentry = resp->fh.fh_dentry;
+ 	struct inode *inode;
+-	int w;
+ 
+ 	if (!svcxdr_encode_stat(xdr, resp->status))
+ 		return false;
+@@ -260,15 +259,6 @@ nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
+ 	if (xdr_stream_encode_u32(xdr, resp->mask) < 0)
+ 		return false;
+ 
+-	rqstp->rq_res.page_len = w = nfsacl_size(
+-		(resp->mask & NFS_ACL)   ? resp->acl_access  : NULL,
+-		(resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
+-	while (w > 0) {
+-		if (!*(rqstp->rq_next_page++))
+-			return true;
+-		w -= PAGE_SIZE;
+-	}
+-
+ 	if (!nfs_stream_encode_acl(xdr, inode, resp->acl_access,
+ 				   resp->mask & NFS_ACL, 0))
+ 		return false;
+diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
+index 9446c67436649..7c798b5f4ec68 100644
+--- a/fs/nfsd/nfs3acl.c
++++ b/fs/nfsd/nfs3acl.c
+@@ -171,11 +171,7 @@ nfs3svc_encode_getaclres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
+ {
+ 	struct nfsd3_getaclres *resp = rqstp->rq_resp;
+ 	struct dentry *dentry = resp->fh.fh_dentry;
+-	struct kvec *head = rqstp->rq_res.head;
+ 	struct inode *inode;
+-	unsigned int base;
+-	int n;
+-	int w;
+ 
+ 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
+ 		return false;
+@@ -187,26 +183,12 @@ nfs3svc_encode_getaclres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
+ 		if (xdr_stream_encode_u32(xdr, resp->mask) < 0)
+ 			return false;
+ 
+-		base = (char *)xdr->p - (char *)head->iov_base;
+-
+-		rqstp->rq_res.page_len = w = nfsacl_size(
+-			(resp->mask & NFS_ACL)   ? resp->acl_access  : NULL,
+-			(resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
+-		while (w > 0) {
+-			if (!*(rqstp->rq_next_page++))
+-				return false;
+-			w -= PAGE_SIZE;
+-		}
+-
+-		n = nfsacl_encode(&rqstp->rq_res, base, inode,
+-				  resp->acl_access,
+-				  resp->mask & NFS_ACL, 0);
+-		if (n > 0)
+-			n = nfsacl_encode(&rqstp->rq_res, base + n, inode,
+-					  resp->acl_default,
+-					  resp->mask & NFS_DFACL,
+-					  NFS_ACL_DEFAULT);
+-		if (n <= 0)
++		if (!nfs_stream_encode_acl(xdr, inode, resp->acl_access,
++					   resp->mask & NFS_ACL, 0))
++			return false;
++		if (!nfs_stream_encode_acl(xdr, inode, resp->acl_default,
++					   resp->mask & NFS_DFACL,
++					   NFS_ACL_DEFAULT))
+ 			return false;
+ 		break;
+ 	default:
+diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
+index 4ce328209f614..775d38dc00fef 100644
+--- a/fs/nfsd/nfs4callback.c
++++ b/fs/nfsd/nfs4callback.c
+@@ -916,7 +916,6 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
+ 	} else {
+ 		if (!conn->cb_xprt)
+ 			return -EINVAL;
+-		clp->cl_cb_conn.cb_xprt = conn->cb_xprt;
+ 		clp->cl_cb_session = ses;
+ 		args.bc_xprt = conn->cb_xprt;
+ 		args.prognumber = clp->cl_cb_session->se_cb_prog;
+@@ -936,6 +935,9 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
+ 		rpc_shutdown_client(client);
+ 		return -ENOMEM;
+ 	}
++
++	if (clp->cl_minorversion != 0)
++		clp->cl_cb_conn.cb_xprt = conn->cb_xprt;
+ 	clp->cl_cb_client = client;
+ 	clp->cl_cb_cred = cred;
+ 	rcu_read_lock();
+diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
+index 6ba25a5b76e17..cfc2da4456587 100644
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1141,6 +1141,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ 				0, (time64_t)0);
+ 	if (!status)
+ 		status = nfserrno(attrs.na_labelerr);
++	if (!status)
++		status = nfserrno(attrs.na_aclerr);
+ out:
+ 	nfsd_attrs_free(&attrs);
+ 	fh_drop_write(&cstate->current_fh);
+@@ -1648,6 +1650,7 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy,
+ 	u64 src_pos = copy->cp_src_pos;
+ 	u64 dst_pos = copy->cp_dst_pos;
+ 	int status;
++	loff_t end;
+ 
+ 	/* See RFC 7862 p.67: */
+ 	if (bytes_total == 0)
+@@ -1667,8 +1670,8 @@ static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy,
+ 	/* for a non-zero asynchronous copy do a commit of data */
+ 	if (nfsd4_copy_is_async(copy) && copy->cp_res.wr_bytes_written > 0) {
+ 		since = READ_ONCE(dst->f_wb_err);
+-		status = vfs_fsync_range(dst, copy->cp_dst_pos,
+-					 copy->cp_res.wr_bytes_written, 0);
++		end = copy->cp_dst_pos + copy->cp_res.wr_bytes_written - 1;
++		status = vfs_fsync_range(dst, copy->cp_dst_pos, end, 0);
+ 		if (!status)
+ 			status = filemap_check_wb_err(dst->f_mapping, since);
+ 		if (!status)
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index ddb2bf078fdaf..94420fad4c410 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -664,15 +664,26 @@ find_any_file(struct nfs4_file *f)
+ 	return ret;
+ }
+ 
+-static struct nfsd_file *find_deleg_file(struct nfs4_file *f)
++static struct nfsd_file *find_any_file_locked(struct nfs4_file *f)
+ {
+-	struct nfsd_file *ret = NULL;
++	lockdep_assert_held(&f->fi_lock);
++
++	if (f->fi_fds[O_RDWR])
++		return f->fi_fds[O_RDWR];
++	if (f->fi_fds[O_WRONLY])
++		return f->fi_fds[O_WRONLY];
++	if (f->fi_fds[O_RDONLY])
++		return f->fi_fds[O_RDONLY];
++	return NULL;
++}
++
++static struct nfsd_file *find_deleg_file_locked(struct nfs4_file *f)
++{
++	lockdep_assert_held(&f->fi_lock);
+ 
+-	spin_lock(&f->fi_lock);
+ 	if (f->fi_deleg_file)
+-		ret = nfsd_file_get(f->fi_deleg_file);
+-	spin_unlock(&f->fi_lock);
+-	return ret;
++		return f->fi_deleg_file;
++	return NULL;
+ }
+ 
+ static atomic_long_t num_delegations;
+@@ -2606,9 +2617,11 @@ static int nfs4_show_open(struct seq_file *s, struct nfs4_stid *st)
+ 	ols = openlockstateid(st);
+ 	oo = ols->st_stateowner;
+ 	nf = st->sc_file;
+-	file = find_any_file(nf);
++
++	spin_lock(&nf->fi_lock);
++	file = find_any_file_locked(nf);
+ 	if (!file)
+-		return 0;
++		goto out;
+ 
+ 	seq_printf(s, "- ");
+ 	nfs4_show_stateid(s, &st->sc_stateid);
+@@ -2630,8 +2643,8 @@ static int nfs4_show_open(struct seq_file *s, struct nfs4_stid *st)
+ 	seq_printf(s, ", ");
+ 	nfs4_show_owner(s, oo);
+ 	seq_printf(s, " }\n");
+-	nfsd_file_put(file);
+-
++out:
++	spin_unlock(&nf->fi_lock);
+ 	return 0;
+ }
+ 
+@@ -2645,9 +2658,10 @@ static int nfs4_show_lock(struct seq_file *s, struct nfs4_stid *st)
+ 	ols = openlockstateid(st);
+ 	oo = ols->st_stateowner;
+ 	nf = st->sc_file;
+-	file = find_any_file(nf);
++	spin_lock(&nf->fi_lock);
++	file = find_any_file_locked(nf);
+ 	if (!file)
+-		return 0;
++		goto out;
+ 
+ 	seq_printf(s, "- ");
+ 	nfs4_show_stateid(s, &st->sc_stateid);
+@@ -2667,8 +2681,8 @@ static int nfs4_show_lock(struct seq_file *s, struct nfs4_stid *st)
+ 	seq_printf(s, ", ");
+ 	nfs4_show_owner(s, oo);
+ 	seq_printf(s, " }\n");
+-	nfsd_file_put(file);
+-
++out:
++	spin_unlock(&nf->fi_lock);
+ 	return 0;
+ }
+ 
+@@ -2680,9 +2694,10 @@ static int nfs4_show_deleg(struct seq_file *s, struct nfs4_stid *st)
+ 
+ 	ds = delegstateid(st);
+ 	nf = st->sc_file;
+-	file = find_deleg_file(nf);
++	spin_lock(&nf->fi_lock);
++	file = find_deleg_file_locked(nf);
+ 	if (!file)
+-		return 0;
++		goto out;
+ 
+ 	seq_printf(s, "- ");
+ 	nfs4_show_stateid(s, &st->sc_stateid);
+@@ -2698,8 +2713,8 @@ static int nfs4_show_deleg(struct seq_file *s, struct nfs4_stid *st)
+ 	seq_printf(s, ", ");
+ 	nfs4_show_fname(s, file);
+ 	seq_printf(s, " }\n");
+-	nfsd_file_put(file);
+-
++out:
++	spin_unlock(&nf->fi_lock);
+ 	return 0;
+ }
+ 
+diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
+index c8b89b4f94e0e..2064e6473d304 100644
+--- a/fs/nilfs2/the_nilfs.c
++++ b/fs/nilfs2/the_nilfs.c
+@@ -13,6 +13,7 @@
+ #include <linux/blkdev.h>
+ #include <linux/backing-dev.h>
+ #include <linux/random.h>
++#include <linux/log2.h>
+ #include <linux/crc32.h>
+ #include "nilfs.h"
+ #include "segment.h"
+@@ -192,6 +193,34 @@ static int nilfs_store_log_cursor(struct the_nilfs *nilfs,
+ 	return ret;
+ }
+ 
++/**
++ * nilfs_get_blocksize - get block size from raw superblock data
++ * @sb: super block instance
++ * @sbp: superblock raw data buffer
++ * @blocksize: place to store block size
++ *
++ * nilfs_get_blocksize() calculates the block size from the block size
++ * exponent information written in @sbp and stores it in @blocksize,
++ * or aborts with an error message if it's too large.
++ *
++ * Return Value: On success, 0 is returned. If the block size is too
++ * large, -EINVAL is returned.
++ */
++static int nilfs_get_blocksize(struct super_block *sb,
++			       struct nilfs_super_block *sbp, int *blocksize)
++{
++	unsigned int shift_bits = le32_to_cpu(sbp->s_log_block_size);
++
++	if (unlikely(shift_bits >
++		     ilog2(NILFS_MAX_BLOCK_SIZE) - BLOCK_SIZE_BITS)) {
++		nilfs_err(sb, "too large filesystem blocksize: 2 ^ %u KiB",
++			  shift_bits);
++		return -EINVAL;
++	}
++	*blocksize = BLOCK_SIZE << shift_bits;
++	return 0;
++}
++
+ /**
+  * load_nilfs - load and recover the nilfs
+  * @nilfs: the_nilfs structure to be released
+@@ -245,11 +274,15 @@ int load_nilfs(struct the_nilfs *nilfs, struct super_block *sb)
+ 		nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
+ 
+ 		/* verify consistency between two super blocks */
+-		blocksize = BLOCK_SIZE << le32_to_cpu(sbp[0]->s_log_block_size);
++		err = nilfs_get_blocksize(sb, sbp[0], &blocksize);
++		if (err)
++			goto scan_error;
++
+ 		if (blocksize != nilfs->ns_blocksize) {
+ 			nilfs_warn(sb,
+ 				   "blocksize differs between two super blocks (%d != %d)",
+ 				   blocksize, nilfs->ns_blocksize);
++			err = -EINVAL;
+ 			goto scan_error;
+ 		}
+ 
+@@ -443,11 +476,33 @@ static int nilfs_valid_sb(struct nilfs_super_block *sbp)
+ 	return crc == le32_to_cpu(sbp->s_sum);
+ }
+ 
+-static int nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
++/**
++ * nilfs_sb2_bad_offset - check the location of the second superblock
++ * @sbp: superblock raw data buffer
++ * @offset: byte offset of second superblock calculated from device size
++ *
++ * nilfs_sb2_bad_offset() checks if the position on the second
++ * superblock is valid or not based on the filesystem parameters
++ * stored in @sbp.  If @offset points to a location within the segment
++ * area, or if the parameters themselves are not normal, it is
++ * determined to be invalid.
++ *
++ * Return Value: true if invalid, false if valid.
++ */
++static bool nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
+ {
+-	return offset < ((le64_to_cpu(sbp->s_nsegments) *
+-			  le32_to_cpu(sbp->s_blocks_per_segment)) <<
+-			 (le32_to_cpu(sbp->s_log_block_size) + 10));
++	unsigned int shift_bits = le32_to_cpu(sbp->s_log_block_size);
++	u32 blocks_per_segment = le32_to_cpu(sbp->s_blocks_per_segment);
++	u64 nsegments = le64_to_cpu(sbp->s_nsegments);
++	u64 index;
++
++	if (blocks_per_segment < NILFS_SEG_MIN_BLOCKS ||
++	    shift_bits > ilog2(NILFS_MAX_BLOCK_SIZE) - BLOCK_SIZE_BITS)
++		return true;
++
++	index = offset >> (shift_bits + BLOCK_SIZE_BITS);
++	do_div(index, blocks_per_segment);
++	return index < nsegments;
+ }
+ 
+ static void nilfs_release_super_block(struct the_nilfs *nilfs)
+@@ -586,9 +641,11 @@ int init_nilfs(struct the_nilfs *nilfs, struct super_block *sb, char *data)
+ 	if (err)
+ 		goto failed_sbh;
+ 
+-	blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
+-	if (blocksize < NILFS_MIN_BLOCK_SIZE ||
+-	    blocksize > NILFS_MAX_BLOCK_SIZE) {
++	err = nilfs_get_blocksize(sb, sbp, &blocksize);
++	if (err)
++		goto failed_sbh;
++
++	if (blocksize < NILFS_MIN_BLOCK_SIZE) {
+ 		nilfs_err(sb,
+ 			  "couldn't mount because of unsupported filesystem blocksize %d",
+ 			  blocksize);
+diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c
+index 5d44ceac855b7..087282cb130b7 100644
+--- a/fs/ntfs3/bitmap.c
++++ b/fs/ntfs3/bitmap.c
+@@ -1424,7 +1424,7 @@ int ntfs_trim_fs(struct ntfs_sb_info *sbi, struct fstrim_range *range)
+ 
+ 	down_read_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS);
+ 
+-	for (; iw < wnd->nbits; iw++, wbit = 0) {
++	for (; iw < wnd->nwnd; iw++, wbit = 0) {
+ 		CLST lcn_wnd = iw * wbits;
+ 		struct buffer_head *bh;
+ 
+diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c
+index 47012c9bf505e..adc4f73722b7c 100644
+--- a/fs/ntfs3/super.c
++++ b/fs/ntfs3/super.c
+@@ -672,7 +672,7 @@ static u32 true_sectors_per_clst(const struct NTFS_BOOT *boot)
+ 	if (boot->sectors_per_clusters <= 0x80)
+ 		return boot->sectors_per_clusters;
+ 	if (boot->sectors_per_clusters >= 0xf4) /* limit shift to 2MB max */
+-		return 1U << (0 - boot->sectors_per_clusters);
++		return 1U << -(s8)boot->sectors_per_clusters;
+ 	return -EINVAL;
+ }
+ 
+diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c
+index 7de8718c68a90..ea582b4fe1d9d 100644
+--- a/fs/ntfs3/xattr.c
++++ b/fs/ntfs3/xattr.c
+@@ -107,7 +107,7 @@ static int ntfs_read_ea(struct ntfs_inode *ni, struct EA_FULL **ea,
+ 		return -EFBIG;
+ 
+ 	/* Allocate memory for packed Ea. */
+-	ea_p = kmalloc(size + add_bytes, GFP_NOFS);
++	ea_p = kmalloc(size_add(size, add_bytes), GFP_NOFS);
+ 	if (!ea_p)
+ 		return -ENOMEM;
+ 
+diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
+index fa87d89cf7542..1be7d440eff37 100644
+--- a/fs/ocfs2/journal.c
++++ b/fs/ocfs2/journal.c
+@@ -157,7 +157,7 @@ static void ocfs2_queue_replay_slots(struct ocfs2_super *osb,
+ 	replay_map->rm_state = REPLAY_DONE;
+ }
+ 
+-static void ocfs2_free_replay_slots(struct ocfs2_super *osb)
++void ocfs2_free_replay_slots(struct ocfs2_super *osb)
+ {
+ 	struct ocfs2_replay_map *replay_map = osb->replay_map;
+ 
+diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
+index 969d0aa287187..41c382f68529e 100644
+--- a/fs/ocfs2/journal.h
++++ b/fs/ocfs2/journal.h
+@@ -150,6 +150,7 @@ int ocfs2_recovery_init(struct ocfs2_super *osb);
+ void ocfs2_recovery_exit(struct ocfs2_super *osb);
+ 
+ int ocfs2_compute_replay_slots(struct ocfs2_super *osb);
++void ocfs2_free_replay_slots(struct ocfs2_super *osb);
+ /*
+  *  Journal Control:
+  *  Initialize, Load, Shutdown, Wipe a journal.
+diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c
+index dd77b7aaabf5c..3633da5f71179 100644
+--- a/fs/ocfs2/stackglue.c
++++ b/fs/ocfs2/stackglue.c
+@@ -669,6 +669,8 @@ static struct ctl_table_header *ocfs2_table_header;
+ 
+ static int __init ocfs2_stack_glue_init(void)
+ {
++	int ret;
++
+ 	strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB);
+ 
+ 	ocfs2_table_header = register_sysctl("fs/ocfs2/nm", ocfs2_nm_table);
+@@ -678,7 +680,11 @@ static int __init ocfs2_stack_glue_init(void)
+ 		return -ENOMEM; /* or something. */
+ 	}
+ 
+-	return ocfs2_sysfs_init();
++	ret = ocfs2_sysfs_init();
++	if (ret)
++		unregister_sysctl_table(ocfs2_table_header);
++
++	return ret;
+ }
+ 
+ static void __exit ocfs2_stack_glue_exit(void)
+diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
+index e2cc9eec287c9..78441e466e6fd 100644
+--- a/fs/ocfs2/super.c
++++ b/fs/ocfs2/super.c
+@@ -1159,6 +1159,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+ out_dismount:
+ 	atomic_set(&osb->vol_state, VOLUME_DISABLED);
+ 	wake_up(&osb->osb_mount_event);
++	ocfs2_free_replay_slots(osb);
+ 	ocfs2_dismount_volume(sb, 1);
+ 	goto out;
+ 
+@@ -1824,12 +1825,14 @@ static int ocfs2_mount_volume(struct super_block *sb)
+ 	status = ocfs2_truncate_log_init(osb);
+ 	if (status < 0) {
+ 		mlog_errno(status);
+-		goto out_system_inodes;
++		goto out_check_volume;
+ 	}
+ 
+ 	ocfs2_super_unlock(osb, 1);
+ 	return 0;
+ 
++out_check_volume:
++	ocfs2_free_replay_slots(osb);
+ out_system_inodes:
+ 	if (osb->local_alloc_state == OCFS2_LA_ENABLED)
+ 		ocfs2_shutdown_local_alloc(osb);
+diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c
+index 29eaa45443727..1b508f5433846 100644
+--- a/fs/orangefs/orangefs-debugfs.c
++++ b/fs/orangefs/orangefs-debugfs.c
+@@ -194,15 +194,10 @@ void orangefs_debugfs_init(int debug_mask)
+  */
+ static void orangefs_kernel_debug_init(void)
+ {
+-	int rc = -ENOMEM;
+-	char *k_buffer = NULL;
++	static char k_buffer[ORANGEFS_MAX_DEBUG_STRING_LEN] = { };
+ 
+ 	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__);
+ 
+-	k_buffer = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
+-	if (!k_buffer)
+-		goto out;
+-
+ 	if (strlen(kernel_debug_string) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN) {
+ 		strcpy(k_buffer, kernel_debug_string);
+ 		strcat(k_buffer, "\n");
+@@ -213,15 +208,14 @@ static void orangefs_kernel_debug_init(void)
+ 
+ 	debugfs_create_file(ORANGEFS_KMOD_DEBUG_FILE, 0444, debug_dir, k_buffer,
+ 			    &kernel_debug_fops);
+-
+-out:
+-	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc);
+ }
+ 
+ 
+ void orangefs_debugfs_cleanup(void)
+ {
+ 	debugfs_remove_recursive(debug_dir);
++	kfree(debug_help_string);
++	debug_help_string = NULL;
+ }
+ 
+ /* open ORANGEFS_KMOD_DEBUG_HELP_FILE */
+@@ -297,18 +291,13 @@ static int help_show(struct seq_file *m, void *v)
+ /*
+  * initialize the client-debug file.
+  */
+-static int orangefs_client_debug_init(void)
++static void orangefs_client_debug_init(void)
+ {
+ 
+-	int rc = -ENOMEM;
+-	char *c_buffer = NULL;
++	static char c_buffer[ORANGEFS_MAX_DEBUG_STRING_LEN] = { };
+ 
+ 	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: start\n", __func__);
+ 
+-	c_buffer = kzalloc(ORANGEFS_MAX_DEBUG_STRING_LEN, GFP_KERNEL);
+-	if (!c_buffer)
+-		goto out;
+-
+ 	if (strlen(client_debug_string) + 1 < ORANGEFS_MAX_DEBUG_STRING_LEN) {
+ 		strcpy(c_buffer, client_debug_string);
+ 		strcat(c_buffer, "\n");
+@@ -322,13 +311,6 @@ static int orangefs_client_debug_init(void)
+ 						  debug_dir,
+ 						  c_buffer,
+ 						  &kernel_debug_fops);
+-
+-	rc = 0;
+-
+-out:
+-
+-	gossip_debug(GOSSIP_DEBUGFS_DEBUG, "%s: rc:%d:\n", __func__, rc);
+-	return rc;
+ }
+ 
+ /* open ORANGEFS_KMOD_DEBUG_FILE or ORANGEFS_CLIENT_DEBUG_FILE.*/
+@@ -671,6 +653,7 @@ int orangefs_prepare_debugfs_help_string(int at_boot)
+ 		memset(debug_help_string, 0, DEBUG_HELP_STRING_SIZE);
+ 		strlcat(debug_help_string, new, string_size);
+ 		mutex_unlock(&orangefs_help_file_lock);
++		kfree(new);
+ 	}
+ 
+ 	rc = 0;
+diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c
+index cd7297815f91e..5ab741c60b7e2 100644
+--- a/fs/orangefs/orangefs-mod.c
++++ b/fs/orangefs/orangefs-mod.c
+@@ -141,7 +141,7 @@ static int __init orangefs_init(void)
+ 		gossip_err("%s: could not initialize device subsystem %d!\n",
+ 			   __func__,
+ 			   ret);
+-		goto cleanup_device;
++		goto cleanup_sysfs;
+ 	}
+ 
+ 	ret = register_filesystem(&orangefs_fs_type);
+@@ -152,11 +152,11 @@ static int __init orangefs_init(void)
+ 		goto out;
+ 	}
+ 
+-	orangefs_sysfs_exit();
+-
+-cleanup_device:
+ 	orangefs_dev_cleanup();
+ 
++cleanup_sysfs:
++	orangefs_sysfs_exit();
++
+ sysfs_init_failed:
+ 	orangefs_debugfs_cleanup();
+ 
+diff --git a/fs/orangefs/orangefs-sysfs.c b/fs/orangefs/orangefs-sysfs.c
+index de80b62553bb1..be4ba03a01a0f 100644
+--- a/fs/orangefs/orangefs-sysfs.c
++++ b/fs/orangefs/orangefs-sysfs.c
+@@ -896,9 +896,18 @@ static struct attribute *orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(orangefs_default);
+ 
++static struct kobject *orangefs_obj;
++
++static void orangefs_obj_release(struct kobject *kobj)
++{
++	kfree(orangefs_obj);
++	orangefs_obj = NULL;
++}
++
+ static struct kobj_type orangefs_ktype = {
+ 	.sysfs_ops = &orangefs_sysfs_ops,
+ 	.default_groups = orangefs_default_groups,
++	.release = orangefs_obj_release,
+ };
+ 
+ static struct orangefs_attribute acache_hard_limit_attribute =
+@@ -934,9 +943,18 @@ static struct attribute *acache_orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(acache_orangefs_default);
+ 
++static struct kobject *acache_orangefs_obj;
++
++static void acache_orangefs_obj_release(struct kobject *kobj)
++{
++	kfree(acache_orangefs_obj);
++	acache_orangefs_obj = NULL;
++}
++
+ static struct kobj_type acache_orangefs_ktype = {
+ 	.sysfs_ops = &orangefs_sysfs_ops,
+ 	.default_groups = acache_orangefs_default_groups,
++	.release = acache_orangefs_obj_release,
+ };
+ 
+ static struct orangefs_attribute capcache_hard_limit_attribute =
+@@ -972,9 +990,18 @@ static struct attribute *capcache_orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(capcache_orangefs_default);
+ 
++static struct kobject *capcache_orangefs_obj;
++
++static void capcache_orangefs_obj_release(struct kobject *kobj)
++{
++	kfree(capcache_orangefs_obj);
++	capcache_orangefs_obj = NULL;
++}
++
+ static struct kobj_type capcache_orangefs_ktype = {
+ 	.sysfs_ops = &orangefs_sysfs_ops,
+ 	.default_groups = capcache_orangefs_default_groups,
++	.release = capcache_orangefs_obj_release,
+ };
+ 
+ static struct orangefs_attribute ccache_hard_limit_attribute =
+@@ -1010,9 +1037,18 @@ static struct attribute *ccache_orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(ccache_orangefs_default);
+ 
++static struct kobject *ccache_orangefs_obj;
++
++static void ccache_orangefs_obj_release(struct kobject *kobj)
++{
++	kfree(ccache_orangefs_obj);
++	ccache_orangefs_obj = NULL;
++}
++
+ static struct kobj_type ccache_orangefs_ktype = {
+ 	.sysfs_ops = &orangefs_sysfs_ops,
+ 	.default_groups = ccache_orangefs_default_groups,
++	.release = ccache_orangefs_obj_release,
+ };
+ 
+ static struct orangefs_attribute ncache_hard_limit_attribute =
+@@ -1048,9 +1084,18 @@ static struct attribute *ncache_orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(ncache_orangefs_default);
+ 
++static struct kobject *ncache_orangefs_obj;
++
++static void ncache_orangefs_obj_release(struct kobject *kobj)
++{
++	kfree(ncache_orangefs_obj);
++	ncache_orangefs_obj = NULL;
++}
++
+ static struct kobj_type ncache_orangefs_ktype = {
+ 	.sysfs_ops = &orangefs_sysfs_ops,
+ 	.default_groups = ncache_orangefs_default_groups,
++	.release = ncache_orangefs_obj_release,
+ };
+ 
+ static struct orangefs_attribute pc_acache_attribute =
+@@ -1079,9 +1124,18 @@ static struct attribute *pc_orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(pc_orangefs_default);
+ 
++static struct kobject *pc_orangefs_obj;
++
++static void pc_orangefs_obj_release(struct kobject *kobj)
++{
++	kfree(pc_orangefs_obj);
++	pc_orangefs_obj = NULL;
++}
++
+ static struct kobj_type pc_orangefs_ktype = {
+ 	.sysfs_ops = &orangefs_sysfs_ops,
+ 	.default_groups = pc_orangefs_default_groups,
++	.release = pc_orangefs_obj_release,
+ };
+ 
+ static struct orangefs_attribute stats_reads_attribute =
+@@ -1103,19 +1157,20 @@ static struct attribute *stats_orangefs_default_attrs[] = {
+ };
+ ATTRIBUTE_GROUPS(stats_orangefs_default);
+ 
++static struct kobject *stats_orangefs_obj;
++
++static void stats_orangefs_obj_release(struct kobject *kobj)
++{
++	kfree(stats_orangefs_obj);
++	stats_orangefs_obj = NULL;
++}
++
+ static struct kobj_type stats_orangefs_ktype = {
+ 	.sysfs_ops = &orangefs_sysfs_ops,
+ 	.default_groups = stats_orangefs_default_groups,
++	.release = stats_orangefs_obj_release,
+ };
+ 
+-static struct kobject *orangefs_obj;
+-static struct kobject *acache_orangefs_obj;
+-static struct kobject *capcache_orangefs_obj;
+-static struct kobject *ccache_orangefs_obj;
+-static struct kobject *ncache_orangefs_obj;
+-static struct kobject *pc_orangefs_obj;
+-static struct kobject *stats_orangefs_obj;
+-
+ int orangefs_sysfs_init(void)
+ {
+ 	int rc = -EINVAL;
+diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
+index daff601b5c410..a34f8042724ce 100644
+--- a/fs/overlayfs/file.c
++++ b/fs/overlayfs/file.c
+@@ -517,9 +517,16 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len
+ 	const struct cred *old_cred;
+ 	int ret;
+ 
++	inode_lock(inode);
++	/* Update mode */
++	ovl_copyattr(inode);
++	ret = file_remove_privs(file);
++	if (ret)
++		goto out_unlock;
++
+ 	ret = ovl_real_fdget(file, &real);
+ 	if (ret)
+-		return ret;
++		goto out_unlock;
+ 
+ 	old_cred = ovl_override_creds(file_inode(file)->i_sb);
+ 	ret = vfs_fallocate(real.file, mode, offset, len);
+@@ -530,6 +537,9 @@ static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len
+ 
+ 	fdput(real);
+ 
++out_unlock:
++	inode_unlock(inode);
++
+ 	return ret;
+ }
+ 
+@@ -567,14 +577,23 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
+ 	const struct cred *old_cred;
+ 	loff_t ret;
+ 
++	inode_lock(inode_out);
++	if (op != OVL_DEDUPE) {
++		/* Update mode */
++		ovl_copyattr(inode_out);
++		ret = file_remove_privs(file_out);
++		if (ret)
++			goto out_unlock;
++	}
++
+ 	ret = ovl_real_fdget(file_out, &real_out);
+ 	if (ret)
+-		return ret;
++		goto out_unlock;
+ 
+ 	ret = ovl_real_fdget(file_in, &real_in);
+ 	if (ret) {
+ 		fdput(real_out);
+-		return ret;
++		goto out_unlock;
+ 	}
+ 
+ 	old_cred = ovl_override_creds(file_inode(file_out)->i_sb);
+@@ -603,6 +622,9 @@ static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
+ 	fdput(real_in);
+ 	fdput(real_out);
+ 
++out_unlock:
++	inode_unlock(inode_out);
++
+ 	return ret;
+ }
+ 
+diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
+index ec746d447f1bb..79a77aa6892cb 100644
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -138,11 +138,16 @@ static int ovl_dentry_revalidate_common(struct dentry *dentry,
+ 					unsigned int flags, bool weak)
+ {
+ 	struct ovl_entry *oe = dentry->d_fsdata;
++	struct inode *inode = d_inode_rcu(dentry);
+ 	struct dentry *upper;
+ 	unsigned int i;
+ 	int ret = 1;
+ 
+-	upper = ovl_dentry_upper(dentry);
++	/* Careful in RCU mode */
++	if (!inode)
++		return -ECHILD;
++
++	upper = ovl_i_dentry_upper(inode);
+ 	if (upper)
+ 		ret = ovl_revalidate_real(upper, flags, weak);
+ 
+diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
+index 8adabde685f13..c49d554cc9ae9 100644
+--- a/fs/pstore/Kconfig
++++ b/fs/pstore/Kconfig
+@@ -126,6 +126,7 @@ config PSTORE_CONSOLE
+ config PSTORE_PMSG
+ 	bool "Log user space messages"
+ 	depends on PSTORE
++	select RT_MUTEXES
+ 	help
+ 	  When the option is enabled, pstore will export a character
+ 	  interface /dev/pmsg0 to log user space messages. On reboot
+diff --git a/fs/pstore/pmsg.c b/fs/pstore/pmsg.c
+index d8542ec2f38c6..18cf94b597e05 100644
+--- a/fs/pstore/pmsg.c
++++ b/fs/pstore/pmsg.c
+@@ -7,9 +7,10 @@
+ #include <linux/device.h>
+ #include <linux/fs.h>
+ #include <linux/uaccess.h>
++#include <linux/rtmutex.h>
+ #include "internal.h"
+ 
+-static DEFINE_MUTEX(pmsg_lock);
++static DEFINE_RT_MUTEX(pmsg_lock);
+ 
+ static ssize_t write_pmsg(struct file *file, const char __user *buf,
+ 			  size_t count, loff_t *ppos)
+@@ -28,9 +29,9 @@ static ssize_t write_pmsg(struct file *file, const char __user *buf,
+ 	if (!access_ok(buf, count))
+ 		return -EFAULT;
+ 
+-	mutex_lock(&pmsg_lock);
++	rt_mutex_lock(&pmsg_lock);
+ 	ret = psinfo->write_user(&record, buf);
+-	mutex_unlock(&pmsg_lock);
++	rt_mutex_unlock(&pmsg_lock);
+ 	return ret ? ret : count;
+ }
+ 
+diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
+index fefe3d391d3af..74e4d93f3e08d 100644
+--- a/fs/pstore/ram.c
++++ b/fs/pstore/ram.c
+@@ -735,6 +735,7 @@ static int ramoops_probe(struct platform_device *pdev)
+ 	/* Make sure we didn't get bogus platform data pointer. */
+ 	if (!pdata) {
+ 		pr_err("NULL platform data\n");
++		err = -EINVAL;
+ 		goto fail_out;
+ 	}
+ 
+@@ -742,6 +743,7 @@ static int ramoops_probe(struct platform_device *pdev)
+ 			!pdata->ftrace_size && !pdata->pmsg_size)) {
+ 		pr_err("The memory size and the record/console size must be "
+ 			"non-zero\n");
++		err = -EINVAL;
+ 		goto fail_out;
+ 	}
+ 
+diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
+index a89e33719fcf2..8bf09886e7e66 100644
+--- a/fs/pstore/ram_core.c
++++ b/fs/pstore/ram_core.c
+@@ -439,7 +439,11 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size,
+ 		phys_addr_t addr = page_start + i * PAGE_SIZE;
+ 		pages[i] = pfn_to_page(addr >> PAGE_SHIFT);
+ 	}
+-	vaddr = vmap(pages, page_count, VM_MAP, prot);
++	/*
++	 * VM_IOREMAP used here to bypass this region during vread()
++	 * and kmap_atomic() (i.e. kcore) to avoid __va() failures.
++	 */
++	vaddr = vmap(pages, page_count, VM_MAP | VM_IOREMAP, prot);
+ 	kfree(pages);
+ 
+ 	/*
+diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
+index 3d7a35d6a18bc..b916859992ec8 100644
+--- a/fs/reiserfs/namei.c
++++ b/fs/reiserfs/namei.c
+@@ -696,6 +696,7 @@ static int reiserfs_create(struct user_namespace *mnt_userns, struct inode *dir,
+ 
+ out_failed:
+ 	reiserfs_write_unlock(dir->i_sb);
++	reiserfs_security_free(&security);
+ 	return retval;
+ }
+ 
+@@ -779,6 +780,7 @@ static int reiserfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
+ 
+ out_failed:
+ 	reiserfs_write_unlock(dir->i_sb);
++	reiserfs_security_free(&security);
+ 	return retval;
+ }
+ 
+@@ -878,6 +880,7 @@ static int reiserfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
+ 	retval = journal_end(&th);
+ out_failed:
+ 	reiserfs_write_unlock(dir->i_sb);
++	reiserfs_security_free(&security);
+ 	return retval;
+ }
+ 
+@@ -1194,6 +1197,7 @@ static int reiserfs_symlink(struct user_namespace *mnt_userns,
+ 	retval = journal_end(&th);
+ out_failed:
+ 	reiserfs_write_unlock(parent_dir->i_sb);
++	reiserfs_security_free(&security);
+ 	return retval;
+ }
+ 
+diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
+index 8965c8e5e172b..857a65b057264 100644
+--- a/fs/reiserfs/xattr_security.c
++++ b/fs/reiserfs/xattr_security.c
+@@ -50,6 +50,7 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
+ 	int error;
+ 
+ 	sec->name = NULL;
++	sec->value = NULL;
+ 
+ 	/* Don't add selinux attributes on xattrs - they'll never get used */
+ 	if (IS_PRIVATE(dir))
+@@ -95,7 +96,6 @@ int reiserfs_security_write(struct reiserfs_transaction_handle *th,
+ 
+ void reiserfs_security_free(struct reiserfs_security_handle *sec)
+ {
+-	kfree(sec->name);
+ 	kfree(sec->value);
+ 	sec->name = NULL;
+ 	sec->value = NULL;
+diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c
+index d4ec9bb97de95..3b8567564e7e4 100644
+--- a/fs/sysv/itree.c
++++ b/fs/sysv/itree.c
+@@ -438,7 +438,7 @@ static unsigned sysv_nblocks(struct super_block *s, loff_t size)
+ 		res += blocks;
+ 		direct = 1;
+ 	}
+-	return blocks;
++	return res;
+ }
+ 
+ int sysv_getattr(struct user_namespace *mnt_userns, const struct path *path,
+diff --git a/fs/udf/namei.c b/fs/udf/namei.c
+index 865e658535b11..0e30a50060d9d 100644
+--- a/fs/udf/namei.c
++++ b/fs/udf/namei.c
+@@ -1091,8 +1091,9 @@ static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
+ 		return -EINVAL;
+ 
+ 	ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi);
+-	if (IS_ERR(ofi)) {
+-		retval = PTR_ERR(ofi);
++	if (!ofi || IS_ERR(ofi)) {
++		if (IS_ERR(ofi))
++			retval = PTR_ERR(ofi);
+ 		goto end_rename;
+ 	}
+ 
+@@ -1101,8 +1102,7 @@ static int udf_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
+ 
+ 	brelse(ofibh.sbh);
+ 	tloc = lelb_to_cpu(ocfi.icb.extLocation);
+-	if (!ofi || udf_get_lb_pblock(old_dir->i_sb, &tloc, 0)
+-	    != old_inode->i_ino)
++	if (udf_get_lb_pblock(old_dir->i_sb, &tloc, 0) != old_inode->i_ino)
+ 		goto end_rename;
+ 
+ 	nfi = udf_find_entry(new_dir, &new_dentry->d_name, &nfibh, &ncfi);
+diff --git a/fs/xattr.c b/fs/xattr.c
+index a1f4998bc6be3..8ea6b104b1063 100644
+--- a/fs/xattr.c
++++ b/fs/xattr.c
+@@ -1147,7 +1147,7 @@ static int xattr_list_one(char **buffer, ssize_t *remaining_size,
+ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
+ 			  char *buffer, size_t size)
+ {
+-	bool trusted = capable(CAP_SYS_ADMIN);
++	bool trusted = ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN);
+ 	struct simple_xattr *xattr;
+ 	ssize_t remaining_size = size;
+ 	int err = 0;
+diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
+index 7df7876b2ad56..d9879fc9ceb17 100644
+--- a/include/drm/drm_connector.h
++++ b/include/drm/drm_connector.h
+@@ -635,6 +635,12 @@ struct drm_display_info {
+ 	 * @mso_pixel_overlap: eDP MSO segment pixel overlap, 0-8 pixels.
+ 	 */
+ 	u8 mso_pixel_overlap;
++
++	/**
++	 * @max_dsc_bpp: Maximum DSC target bitrate, if it is set to 0 the
++	 * monitor's default value is used instead.
++	 */
++	u32 max_dsc_bpp;
+ };
+ 
+ int drm_display_info_set_bus_formats(struct drm_display_info *info,
+diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h
+index 17a0310e8aaaf..b7d3f3843f1e6 100644
+--- a/include/drm/ttm/ttm_tt.h
++++ b/include/drm/ttm/ttm_tt.h
+@@ -88,7 +88,7 @@ struct ttm_tt {
+ #define TTM_TT_FLAG_EXTERNAL		(1 << 2)
+ #define TTM_TT_FLAG_EXTERNAL_MAPPABLE	(1 << 3)
+ 
+-#define TTM_TT_FLAG_PRIV_POPULATED  (1 << 31)
++#define TTM_TT_FLAG_PRIV_POPULATED  (1U << 31)
+ 	uint32_t page_flags;
+ 	/** @num_pages: Number of pages in the page array. */
+ 	uint32_t num_pages;
+diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h
+index 07b8a282c2682..04809edab33cf 100644
+--- a/include/dt-bindings/clock/imx8mn-clock.h
++++ b/include/dt-bindings/clock/imx8mn-clock.h
+@@ -16,40 +16,48 @@
+ #define IMX8MN_CLK_EXT4				7
+ #define IMX8MN_AUDIO_PLL1_REF_SEL		8
+ #define IMX8MN_AUDIO_PLL2_REF_SEL		9
+-#define IMX8MN_VIDEO_PLL1_REF_SEL		10
++#define IMX8MN_VIDEO_PLL_REF_SEL		10
++#define IMX8MN_VIDEO_PLL1_REF_SEL		IMX8MN_VIDEO_PLL_REF_SEL
+ #define IMX8MN_DRAM_PLL_REF_SEL			11
+ #define IMX8MN_GPU_PLL_REF_SEL			12
+-#define IMX8MN_VPU_PLL_REF_SEL			13
++#define IMX8MN_M7_ALT_PLL_REF_SEL		13
++#define IMX8MN_VPU_PLL_REF_SEL			IMX8MN_M7_ALT_PLL_REF_SEL
+ #define IMX8MN_ARM_PLL_REF_SEL			14
+ #define IMX8MN_SYS_PLL1_REF_SEL			15
+ #define IMX8MN_SYS_PLL2_REF_SEL			16
+ #define IMX8MN_SYS_PLL3_REF_SEL			17
+ #define IMX8MN_AUDIO_PLL1			18
+ #define IMX8MN_AUDIO_PLL2			19
+-#define IMX8MN_VIDEO_PLL1			20
++#define IMX8MN_VIDEO_PLL			20
++#define IMX8MN_VIDEO_PLL1			IMX8MN_VIDEO_PLL
+ #define IMX8MN_DRAM_PLL				21
+ #define IMX8MN_GPU_PLL				22
+-#define IMX8MN_VPU_PLL				23
++#define IMX8MN_M7_ALT_PLL			23
++#define IMX8MN_VPU_PLL				IMX8MN_M7_ALT_PLL
+ #define IMX8MN_ARM_PLL				24
+ #define IMX8MN_SYS_PLL1				25
+ #define IMX8MN_SYS_PLL2				26
+ #define IMX8MN_SYS_PLL3				27
+ #define IMX8MN_AUDIO_PLL1_BYPASS		28
+ #define IMX8MN_AUDIO_PLL2_BYPASS		29
+-#define IMX8MN_VIDEO_PLL1_BYPASS		30
++#define IMX8MN_VIDEO_PLL_BYPASS			30
++#define IMX8MN_VIDEO_PLL1_BYPASS		IMX8MN_VIDEO_PLL_BYPASS
+ #define IMX8MN_DRAM_PLL_BYPASS			31
+ #define IMX8MN_GPU_PLL_BYPASS			32
+-#define IMX8MN_VPU_PLL_BYPASS			33
++#define IMX8MN_M7_ALT_PLL_BYPASS		33
++#define IMX8MN_VPU_PLL_BYPASS			IMX8MN_M7_ALT_PLL_BYPASS
+ #define IMX8MN_ARM_PLL_BYPASS			34
+ #define IMX8MN_SYS_PLL1_BYPASS			35
+ #define IMX8MN_SYS_PLL2_BYPASS			36
+ #define IMX8MN_SYS_PLL3_BYPASS			37
+ #define IMX8MN_AUDIO_PLL1_OUT			38
+ #define IMX8MN_AUDIO_PLL2_OUT			39
+-#define IMX8MN_VIDEO_PLL1_OUT			40
++#define IMX8MN_VIDEO_PLL_OUT			40
++#define IMX8MN_VIDEO_PLL1_OUT			IMX8MN_VIDEO_PLL_OUT
+ #define IMX8MN_DRAM_PLL_OUT			41
+ #define IMX8MN_GPU_PLL_OUT			42
+-#define IMX8MN_VPU_PLL_OUT			43
++#define IMX8MN_M7_ALT_PLL_OUT			43
++#define IMX8MN_VPU_PLL_OUT			IMX8MN_M7_ALT_PLL_OUT
+ #define IMX8MN_ARM_PLL_OUT			44
+ #define IMX8MN_SYS_PLL1_OUT			45
+ #define IMX8MN_SYS_PLL2_OUT			46
+diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h
+index 9d5cc2ddde896..1417b7b1b7dfe 100644
+--- a/include/dt-bindings/clock/imx8mp-clock.h
++++ b/include/dt-bindings/clock/imx8mp-clock.h
+@@ -324,8 +324,9 @@
+ #define IMX8MP_CLK_CLKOUT2_SEL			317
+ #define IMX8MP_CLK_CLKOUT2_DIV			318
+ #define IMX8MP_CLK_CLKOUT2			319
++#define IMX8MP_CLK_USB_SUSP			320
+ 
+-#define IMX8MP_CLK_END				320
++#define IMX8MP_CLK_END				321
+ 
+ #define IMX8MP_CLK_AUDIOMIX_SAI1_IPG		0
+ #define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1		1
+diff --git a/include/dt-bindings/clock/qcom,lpassaudiocc-sc7280.h b/include/dt-bindings/clock/qcom,lpassaudiocc-sc7280.h
+index 20ef2ea673f3b..22dcd47d45139 100644
+--- a/include/dt-bindings/clock/qcom,lpassaudiocc-sc7280.h
++++ b/include/dt-bindings/clock/qcom,lpassaudiocc-sc7280.h
+@@ -24,6 +24,11 @@
+ #define LPASS_AUDIO_CC_RX_MCLK_CLK			14
+ #define LPASS_AUDIO_CC_RX_MCLK_CLK_SRC			15
+ 
++/* LPASS AUDIO CC CSR */
++#define LPASS_AUDIO_SWR_RX_CGCR				0
++#define LPASS_AUDIO_SWR_TX_CGCR				1
++#define LPASS_AUDIO_SWR_WSA_CGCR			2
++
+ /* LPASS_AON_CC clocks */
+ #define LPASS_AON_CC_PLL				0
+ #define LPASS_AON_CC_PLL_OUT_EVEN			1
+diff --git a/include/dt-bindings/clock/qcom,lpasscorecc-sc7280.h b/include/dt-bindings/clock/qcom,lpasscorecc-sc7280.h
+index 28ed2a07aacc3..0324c69ce9686 100644
+--- a/include/dt-bindings/clock/qcom,lpasscorecc-sc7280.h
++++ b/include/dt-bindings/clock/qcom,lpasscorecc-sc7280.h
+@@ -19,6 +19,8 @@
+ #define LPASS_CORE_CC_LPM_CORE_CLK			9
+ #define LPASS_CORE_CC_LPM_MEM0_CORE_CLK			10
+ #define LPASS_CORE_CC_SYSNOC_MPORT_CORE_CLK		11
++#define LPASS_CORE_CC_EXT_MCLK0_CLK			12
++#define LPASS_CORE_CC_EXT_MCLK0_CLK_SRC			13
+ 
+ /* LPASS_CORE_CC power domains */
+ #define LPASS_CORE_CC_LPASS_CORE_HM_GDSC		0
+diff --git a/include/linux/btf_ids.h b/include/linux/btf_ids.h
+index 2aea877d644f8..2b98720084285 100644
+--- a/include/linux/btf_ids.h
++++ b/include/linux/btf_ids.h
+@@ -204,7 +204,7 @@ extern struct btf_id_set8 name;
+ 
+ #else
+ 
+-#define BTF_ID_LIST(name) static u32 __maybe_unused name[5];
++#define BTF_ID_LIST(name) static u32 __maybe_unused name[16];
+ #define BTF_ID(prefix, name)
+ #define BTF_ID_FLAGS(prefix, name, ...)
+ #define BTF_ID_UNUSED
+diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
+index f60674692d365..ea2d919fd9c79 100644
+--- a/include/linux/debugfs.h
++++ b/include/linux/debugfs.h
+@@ -45,7 +45,7 @@ struct debugfs_u32_array {
+ 
+ extern struct dentry *arch_debugfs_dir;
+ 
+-#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)		\
++#define DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, __is_signed)	\
+ static int __fops ## _open(struct inode *inode, struct file *file)	\
+ {									\
+ 	__simple_attr_check_format(__fmt, 0ull);			\
+@@ -56,10 +56,16 @@ static const struct file_operations __fops = {				\
+ 	.open	 = __fops ## _open,					\
+ 	.release = simple_attr_release,					\
+ 	.read	 = debugfs_attr_read,					\
+-	.write	 = debugfs_attr_write,					\
++	.write	 = (__is_signed) ? debugfs_attr_write_signed : debugfs_attr_write,	\
+ 	.llseek  = no_llseek,						\
+ }
+ 
++#define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)		\
++	DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, false)
++
++#define DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt)	\
++	DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, true)
++
+ typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *);
+ 
+ #if defined(CONFIG_DEBUG_FS)
+@@ -102,6 +108,8 @@ ssize_t debugfs_attr_read(struct file *file, char __user *buf,
+ 			size_t len, loff_t *ppos);
+ ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
+ 			size_t len, loff_t *ppos);
++ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf,
++			size_t len, loff_t *ppos);
+ 
+ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+                 struct dentry *new_dir, const char *new_name);
+@@ -254,6 +262,13 @@ static inline ssize_t debugfs_attr_write(struct file *file,
+ 	return -ENODEV;
+ }
+ 
++static inline ssize_t debugfs_attr_write_signed(struct file *file,
++					const char __user *buf,
++					size_t len, loff_t *ppos)
++{
++	return -ENODEV;
++}
++
+ static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
+                 struct dentry *new_dir, char *new_name)
+ {
+diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h
+index 30eb30d6909b0..3cd202d3eefb3 100644
+--- a/include/linux/eventfd.h
++++ b/include/linux/eventfd.h
+@@ -61,7 +61,7 @@ static inline struct eventfd_ctx *eventfd_ctx_fdget(int fd)
+ 	return ERR_PTR(-ENOSYS);
+ }
+ 
+-static inline int eventfd_signal(struct eventfd_ctx *ctx, int n)
++static inline int eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
+ {
+ 	return -ENOSYS;
+ }
+diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h
+index fce2fb2fc9626..c26160fe2e34e 100644
+--- a/include/linux/fortify-string.h
++++ b/include/linux/fortify-string.h
+@@ -3,6 +3,7 @@
+ #define _LINUX_FORTIFY_STRING_H_
+ 
+ #include <linux/const.h>
++#include <linux/limits.h>
+ 
+ #define __FORTIFY_INLINE extern __always_inline __gnu_inline __overloadable
+ #define __RENAME(x) __asm__(#x)
+@@ -16,10 +17,10 @@ void __write_overflow_field(size_t avail, size_t wanted) __compiletime_warning("
+ 
+ #define __compiletime_strlen(p)					\
+ ({								\
+-	unsigned char *__p = (unsigned char *)(p);		\
+-	size_t __ret = (size_t)-1;				\
++	char *__p = (char *)(p);				\
++	size_t __ret = SIZE_MAX;				\
+ 	size_t __p_size = __builtin_object_size(p, 1);		\
+-	if (__p_size != (size_t)-1 &&				\
++	if (__p_size != SIZE_MAX &&				\
+ 	    __builtin_constant_p(*__p)) {			\
+ 		size_t __p_len = __p_size - 1;			\
+ 		if (__builtin_constant_p(__p[__p_len]) &&	\
+@@ -95,7 +96,7 @@ char *strcat(char * const POS p, const char *q)
+ {
+ 	size_t p_size = __builtin_object_size(p, 1);
+ 
+-	if (p_size == (size_t)-1)
++	if (p_size == SIZE_MAX)
+ 		return __underlying_strcat(p, q);
+ 	if (strlcat(p, q, p_size) >= p_size)
+ 		fortify_panic(__func__);
+@@ -110,7 +111,7 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size
+ 	size_t ret;
+ 
+ 	/* We can take compile-time actions when maxlen is const. */
+-	if (__builtin_constant_p(maxlen) && p_len != (size_t)-1) {
++	if (__builtin_constant_p(maxlen) && p_len != SIZE_MAX) {
+ 		/* If p is const, we can use its compile-time-known len. */
+ 		if (maxlen >= p_size)
+ 			return p_len;
+@@ -138,7 +139,7 @@ __kernel_size_t __fortify_strlen(const char * const POS p)
+ 	size_t p_size = __builtin_object_size(p, 1);
+ 
+ 	/* Give up if we don't know how large p is. */
+-	if (p_size == (size_t)-1)
++	if (p_size == SIZE_MAX)
+ 		return __underlying_strlen(p);
+ 	ret = strnlen(p, p_size);
+ 	if (p_size <= ret)
+@@ -155,7 +156,7 @@ __FORTIFY_INLINE size_t strlcpy(char * const POS p, const char * const POS q, si
+ 	size_t q_len;	/* Full count of source string length. */
+ 	size_t len;	/* Count of characters going into destination. */
+ 
+-	if (p_size == (size_t)-1 && q_size == (size_t)-1)
++	if (p_size == SIZE_MAX && q_size == SIZE_MAX)
+ 		return __real_strlcpy(p, q, size);
+ 	q_len = strlen(q);
+ 	len = (q_len >= size) ? size - 1 : q_len;
+@@ -183,7 +184,7 @@ __FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, s
+ 	size_t q_size = __builtin_object_size(q, 1);
+ 
+ 	/* If we cannot get size of p and q default to call strscpy. */
+-	if (p_size == (size_t) -1 && q_size == (size_t) -1)
++	if (p_size == SIZE_MAX && q_size == SIZE_MAX)
+ 		return __real_strscpy(p, q, size);
+ 
+ 	/*
+@@ -228,7 +229,7 @@ char *strncat(char * const POS p, const char * const POS q, __kernel_size_t coun
+ 	size_t p_size = __builtin_object_size(p, 1);
+ 	size_t q_size = __builtin_object_size(q, 1);
+ 
+-	if (p_size == (size_t)-1 && q_size == (size_t)-1)
++	if (p_size == SIZE_MAX && q_size == SIZE_MAX)
+ 		return __underlying_strncat(p, q, count);
+ 	p_len = strlen(p);
+ 	copy_len = strnlen(q, count);
+@@ -269,10 +270,10 @@ __FORTIFY_INLINE void fortify_memset_chk(__kernel_size_t size,
+ 	/*
+ 	 * Always stop accesses beyond the struct that contains the
+ 	 * field, when the buffer's remaining size is known.
+-	 * (The -1 test is to optimize away checks where the buffer
++	 * (The SIZE_MAX test is to optimize away checks where the buffer
+ 	 * lengths are unknown.)
+ 	 */
+-	if (p_size != (size_t)(-1) && p_size < size)
++	if (p_size != SIZE_MAX && p_size < size)
+ 		fortify_panic("memset");
+ }
+ 
+@@ -363,11 +364,11 @@ __FORTIFY_INLINE void fortify_memcpy_chk(__kernel_size_t size,
+ 	/*
+ 	 * Always stop accesses beyond the struct that contains the
+ 	 * field, when the buffer's remaining size is known.
+-	 * (The -1 test is to optimize away checks where the buffer
++	 * (The SIZE_MAX test is to optimize away checks where the buffer
+ 	 * lengths are unknown.)
+ 	 */
+-	if ((p_size != (size_t)(-1) && p_size < size) ||
+-	    (q_size != (size_t)(-1) && q_size < size))
++	if ((p_size != SIZE_MAX && p_size < size) ||
++	    (q_size != SIZE_MAX && q_size < size))
+ 		fortify_panic(func);
+ }
+ 
+@@ -466,7 +467,7 @@ char *strcpy(char * const POS p, const char * const POS q)
+ 	size_t size;
+ 
+ 	/* If neither buffer size is known, immediately give up. */
+-	if (p_size == (size_t)-1 && q_size == (size_t)-1)
++	if (p_size == SIZE_MAX && q_size == SIZE_MAX)
+ 		return __underlying_strcpy(p, q);
+ 	size = strlen(q) + 1;
+ 	/* Compile-time check for const size overflow. */
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index be074b6895b97..8e79a761c56c5 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -3480,7 +3480,7 @@ void simple_transaction_set(struct file *file, size_t n);
+  * All attributes contain a text representation of a numeric value
+  * that are accessed with the get() and set() functions.
+  */
+-#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)		\
++#define DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, __is_signed)	\
+ static int __fops ## _open(struct inode *inode, struct file *file)	\
+ {									\
+ 	__simple_attr_check_format(__fmt, 0ull);			\
+@@ -3491,10 +3491,16 @@ static const struct file_operations __fops = {				\
+ 	.open	 = __fops ## _open,					\
+ 	.release = simple_attr_release,					\
+ 	.read	 = simple_attr_read,					\
+-	.write	 = simple_attr_write,					\
++	.write	 = (__is_signed) ? simple_attr_write_signed : simple_attr_write,	\
+ 	.llseek	 = generic_file_llseek,					\
+ }
+ 
++#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)		\
++	DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, false)
++
++#define DEFINE_SIMPLE_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt)	\
++	DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, true)
++
+ static inline __printf(1, 2)
+ void __simple_attr_check_format(const char *fmt, ...)
+ {
+@@ -3509,6 +3515,8 @@ ssize_t simple_attr_read(struct file *file, char __user *buf,
+ 			 size_t len, loff_t *ppos);
+ ssize_t simple_attr_write(struct file *file, const char __user *buf,
+ 			  size_t len, loff_t *ppos);
++ssize_t simple_attr_write_signed(struct file *file, const char __user *buf,
++				 size_t len, loff_t *ppos);
+ 
+ struct ctl_table;
+ int __init list_bdev_fs_names(char *buf, size_t size);
+diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h
+index 116e8bd68c999..ce0c3ed67a5f4 100644
+--- a/include/linux/hisi_acc_qm.h
++++ b/include/linux/hisi_acc_qm.h
+@@ -168,6 +168,15 @@ enum qm_vf_state {
+ 	QM_NOT_READY,
+ };
+ 
++enum qm_cap_bits {
++	QM_SUPPORT_DB_ISOLATION = 0x0,
++	QM_SUPPORT_FUNC_QOS,
++	QM_SUPPORT_STOP_QP,
++	QM_SUPPORT_MB_COMMAND,
++	QM_SUPPORT_SVA_PREFETCH,
++	QM_SUPPORT_RPM,
++};
++
+ struct dfx_diff_registers {
+ 	u32 *regs;
+ 	u32 reg_offset;
+@@ -258,6 +267,18 @@ struct hisi_qm_err_ini {
+ 	void (*err_info_init)(struct hisi_qm *qm);
+ };
+ 
++struct hisi_qm_cap_info {
++	u32 type;
++	/* Register offset */
++	u32 offset;
++	/* Bit offset in register */
++	u32 shift;
++	u32 mask;
++	u32 v1_val;
++	u32 v2_val;
++	u32 v3_val;
++};
++
+ struct hisi_qm_list {
+ 	struct mutex lock;
+ 	struct list_head list;
+@@ -278,6 +299,9 @@ struct hisi_qm {
+ 	struct pci_dev *pdev;
+ 	void __iomem *io_base;
+ 	void __iomem *db_io_base;
++
++	/* Capbility version, 0: not supports */
++	u32 cap_ver;
+ 	u32 sqe_size;
+ 	u32 qp_base;
+ 	u32 qp_num;
+@@ -304,6 +328,8 @@ struct hisi_qm {
+ 	struct hisi_qm_err_info err_info;
+ 	struct hisi_qm_err_status err_status;
+ 	unsigned long misc_ctl; /* driver removing and reset sched */
++	/* Device capability bit */
++	unsigned long caps;
+ 
+ 	struct rw_semaphore qps_lock;
+ 	struct idr qp_idr;
+@@ -326,8 +352,6 @@ struct hisi_qm {
+ 	bool use_sva;
+ 	bool is_frozen;
+ 
+-	/* doorbell isolation enable */
+-	bool use_db_isolation;
+ 	resource_size_t phys_base;
+ 	resource_size_t db_phys_base;
+ 	struct uacce_device *uacce;
+@@ -376,14 +400,14 @@ struct hisi_qp {
+ static inline int q_num_set(const char *val, const struct kernel_param *kp,
+ 			    unsigned int device)
+ {
+-	struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI,
+-					      device, NULL);
++	struct pci_dev *pdev;
+ 	u32 n, q_num;
+ 	int ret;
+ 
+ 	if (!val)
+ 		return -EINVAL;
+ 
++	pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI, device, NULL);
+ 	if (!pdev) {
+ 		q_num = min_t(u32, QM_QNUM_V1, QM_QNUM_V2);
+ 		pr_info("No device found currently, suppose queue number is %u\n",
+@@ -393,6 +417,8 @@ static inline int q_num_set(const char *val, const struct kernel_param *kp,
+ 			q_num = QM_QNUM_V1;
+ 		else
+ 			q_num = QM_QNUM_V2;
++
++		pci_dev_put(pdev);
+ 	}
+ 
+ 	ret = kstrtou32(val, 10, &n);
+@@ -501,6 +527,9 @@ void hisi_qm_pm_init(struct hisi_qm *qm);
+ int hisi_qm_get_dfx_access(struct hisi_qm *qm);
+ void hisi_qm_put_dfx_access(struct hisi_qm *qm);
+ void hisi_qm_regs_dump(struct seq_file *s, struct debugfs_regset32 *regset);
++u32 hisi_qm_get_hw_info(struct hisi_qm *qm,
++			const struct hisi_qm_cap_info *info_table,
++			u32 index, bool is_read);
+ 
+ /* Used by VFIO ACC live migration driver */
+ struct pci_driver *hisi_sec_get_pf_driver(void);
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index 3b42264333ef8..646f1da9f27e0 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -1341,6 +1341,8 @@ struct hv_ring_buffer_debug_info {
+ int hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
+ 				struct hv_ring_buffer_debug_info *debug_info);
+ 
++bool hv_ringbuffer_spinlock_busy(struct vmbus_channel *channel);
++
+ /* Vmbus interface */
+ #define vmbus_driver_register(driver)	\
+ 	__vmbus_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
+diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
+index b6e6d5b407747..181e758c70c12 100644
+--- a/include/linux/ieee80211.h
++++ b/include/linux/ieee80211.h
+@@ -4588,7 +4588,7 @@ static inline u8 ieee80211_mle_common_size(const u8 *data)
+ 		return 0;
+ 	}
+ 
+-	return common + mle->variable[0];
++	return sizeof(*mle) + common + mle->variable[0];
+ }
+ 
+ /**
+diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h
+index 515ca09764fe4..bcbefb7574751 100644
+--- a/include/linux/iio/imu/adis.h
++++ b/include/linux/iio/imu/adis.h
+@@ -402,9 +402,20 @@ static inline int adis_update_bits_base(struct adis *adis, unsigned int reg,
+ 	__adis_update_bits_base(adis, reg, mask, val, sizeof(val));	\
+ })
+ 
+-int adis_enable_irq(struct adis *adis, bool enable);
+ int __adis_check_status(struct adis *adis);
+ int __adis_initial_startup(struct adis *adis);
++int __adis_enable_irq(struct adis *adis, bool enable);
++
++static inline int adis_enable_irq(struct adis *adis, bool enable)
++{
++	int ret;
++
++	mutex_lock(&adis->state_lock);
++	ret = __adis_enable_irq(adis, enable);
++	mutex_unlock(&adis->state_lock);
++
++	return ret;
++}
+ 
+ static inline int adis_check_status(struct adis *adis)
+ {
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 05d6f3facd5a5..47b8b0ab76946 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -171,31 +171,38 @@ static inline bool dev_xmit_complete(int rc)
+  *	(unsigned long) so they can be read and written atomically.
+  */
+ 
++#define NET_DEV_STAT(FIELD)			\
++	union {					\
++		unsigned long FIELD;		\
++		atomic_long_t __##FIELD;	\
++	}
++
+ struct net_device_stats {
+-	unsigned long	rx_packets;
+-	unsigned long	tx_packets;
+-	unsigned long	rx_bytes;
+-	unsigned long	tx_bytes;
+-	unsigned long	rx_errors;
+-	unsigned long	tx_errors;
+-	unsigned long	rx_dropped;
+-	unsigned long	tx_dropped;
+-	unsigned long	multicast;
+-	unsigned long	collisions;
+-	unsigned long	rx_length_errors;
+-	unsigned long	rx_over_errors;
+-	unsigned long	rx_crc_errors;
+-	unsigned long	rx_frame_errors;
+-	unsigned long	rx_fifo_errors;
+-	unsigned long	rx_missed_errors;
+-	unsigned long	tx_aborted_errors;
+-	unsigned long	tx_carrier_errors;
+-	unsigned long	tx_fifo_errors;
+-	unsigned long	tx_heartbeat_errors;
+-	unsigned long	tx_window_errors;
+-	unsigned long	rx_compressed;
+-	unsigned long	tx_compressed;
++	NET_DEV_STAT(rx_packets);
++	NET_DEV_STAT(tx_packets);
++	NET_DEV_STAT(rx_bytes);
++	NET_DEV_STAT(tx_bytes);
++	NET_DEV_STAT(rx_errors);
++	NET_DEV_STAT(tx_errors);
++	NET_DEV_STAT(rx_dropped);
++	NET_DEV_STAT(tx_dropped);
++	NET_DEV_STAT(multicast);
++	NET_DEV_STAT(collisions);
++	NET_DEV_STAT(rx_length_errors);
++	NET_DEV_STAT(rx_over_errors);
++	NET_DEV_STAT(rx_crc_errors);
++	NET_DEV_STAT(rx_frame_errors);
++	NET_DEV_STAT(rx_fifo_errors);
++	NET_DEV_STAT(rx_missed_errors);
++	NET_DEV_STAT(tx_aborted_errors);
++	NET_DEV_STAT(tx_carrier_errors);
++	NET_DEV_STAT(tx_fifo_errors);
++	NET_DEV_STAT(tx_heartbeat_errors);
++	NET_DEV_STAT(tx_window_errors);
++	NET_DEV_STAT(rx_compressed);
++	NET_DEV_STAT(tx_compressed);
+ };
++#undef NET_DEV_STAT
+ 
+ /* per-cpu stats, allocated on demand.
+  * Try to fit them in a single cache line, for dev_get_stats() sake.
+@@ -5143,4 +5150,9 @@ extern struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
+ 
+ extern struct net_device *blackhole_netdev;
+ 
++/* Note: Avoid these macros in fast path, prefer per-cpu or per-queue counters. */
++#define DEV_STATS_INC(DEV, FIELD) atomic_long_inc(&(DEV)->stats.__##FIELD)
++#define DEV_STATS_ADD(DEV, FIELD, VAL) 	\
++		atomic_long_add((VAL), &(DEV)->stats.__##FIELD)
++
+ #endif	/* _LINUX_NETDEVICE_H */
+diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
+index 81d6e4ec2294b..0260f5ea98fe1 100644
+--- a/include/linux/proc_fs.h
++++ b/include/linux/proc_fs.h
+@@ -208,8 +208,10 @@ static inline void proc_remove(struct proc_dir_entry *de) {}
+ static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) { return 0; }
+ 
+ #define proc_create_net_data(name, mode, parent, ops, state_size, data) ({NULL;})
++#define proc_create_net_data_write(name, mode, parent, ops, write, state_size, data) ({NULL;})
+ #define proc_create_net(name, mode, parent, state_size, ops) ({NULL;})
+ #define proc_create_net_single(name, mode, parent, show, data) ({NULL;})
++#define proc_create_net_single_write(name, mode, parent, show, write, data) ({NULL;})
+ 
+ static inline struct pid *tgid_pidfd_to_pid(const struct file *file)
+ {
+diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
+index f9a7461e72b80..d3b4a3d4514ab 100644
+--- a/include/linux/regulator/driver.h
++++ b/include/linux/regulator/driver.h
+@@ -687,7 +687,8 @@ static inline int regulator_err2notif(int err)
+ 
+ 
+ struct regulator_dev *
+-regulator_register(const struct regulator_desc *regulator_desc,
++regulator_register(struct device *dev,
++		   const struct regulator_desc *regulator_desc,
+ 		   const struct regulator_config *config);
+ struct regulator_dev *
+ devm_regulator_register(struct device *dev,
+diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h
+index 70d6cb94e5802..84f787416a54d 100644
+--- a/include/linux/skmsg.h
++++ b/include/linux/skmsg.h
+@@ -82,6 +82,7 @@ struct sk_psock {
+ 	u32				apply_bytes;
+ 	u32				cork_bytes;
+ 	u32				eval;
++	bool				redir_ingress; /* undefined if sk_redir is null */
+ 	struct sk_msg			*cork;
+ 	struct sk_psock_progs		progs;
+ #if IS_ENABLED(CONFIG_BPF_STREAM_PARSER)
+diff --git a/include/linux/timerqueue.h b/include/linux/timerqueue.h
+index 93884086f3924..adc80e29168ea 100644
+--- a/include/linux/timerqueue.h
++++ b/include/linux/timerqueue.h
+@@ -35,7 +35,7 @@ struct timerqueue_node *timerqueue_getnext(struct timerqueue_head *head)
+ {
+ 	struct rb_node *leftmost = rb_first_cached(&head->rb_root);
+ 
+-	return rb_entry(leftmost, struct timerqueue_node, node);
++	return rb_entry_safe(leftmost, struct timerqueue_node, node);
+ }
+ 
+ static inline void timerqueue_init(struct timerqueue_node *node)
+diff --git a/include/media/dvbdev.h b/include/media/dvbdev.h
+index 2f6b0861322ae..ac60c9fcfe9a6 100644
+--- a/include/media/dvbdev.h
++++ b/include/media/dvbdev.h
+@@ -126,6 +126,7 @@ struct dvb_adapter {
+  * struct dvb_device - represents a DVB device node
+  *
+  * @list_head:	List head with all DVB devices
++ * @ref:	reference counter
+  * @fops:	pointer to struct file_operations
+  * @adapter:	pointer to the adapter that holds this device node
+  * @type:	type of the device, as defined by &enum dvb_device_type.
+@@ -156,6 +157,7 @@ struct dvb_adapter {
+  */
+ struct dvb_device {
+ 	struct list_head list_head;
++	struct kref ref;
+ 	const struct file_operations *fops;
+ 	struct dvb_adapter *adapter;
+ 	enum dvb_device_type type;
+@@ -187,6 +189,20 @@ struct dvb_device {
+ 	void *priv;
+ };
+ 
++/**
++ * dvb_device_get - Increase dvb_device reference
++ *
++ * @dvbdev:	pointer to struct dvb_device
++ */
++struct dvb_device *dvb_device_get(struct dvb_device *dvbdev);
++
++/**
++ * dvb_device_put - Decrease dvb_device reference
++ *
++ * @dvbdev:	pointer to struct dvb_device
++ */
++void dvb_device_put(struct dvb_device *dvbdev);
++
+ /**
+  * dvb_register_adapter - Registers a new DVB adapter
+  *
+@@ -231,29 +247,17 @@ int dvb_register_device(struct dvb_adapter *adap,
+ /**
+  * dvb_remove_device - Remove a registered DVB device
+  *
+- * This does not free memory.  To do that, call dvb_free_device().
++ * This does not free memory. dvb_free_device() will do that when
++ * reference counter is empty
+  *
+  * @dvbdev:	pointer to struct dvb_device
+  */
+ void dvb_remove_device(struct dvb_device *dvbdev);
+ 
+-/**
+- * dvb_free_device - Free memory occupied by a DVB device.
+- *
+- * Call dvb_unregister_device() before calling this function.
+- *
+- * @dvbdev:	pointer to struct dvb_device
+- */
+-void dvb_free_device(struct dvb_device *dvbdev);
+ 
+ /**
+  * dvb_unregister_device - Unregisters a DVB device
+  *
+- * This is a combination of dvb_remove_device() and dvb_free_device().
+- * Using this function is usually a mistake, and is often an indicator
+- * for a use-after-free bug (when a userspace process keeps a file
+- * handle to a detached device).
+- *
+  * @dvbdev:	pointer to struct dvb_device
+  */
+ void dvb_unregister_device(struct dvb_device *dvbdev);
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index 4518c63e9d179..dd455ce067701 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -274,6 +274,26 @@ enum {
+ 	 * during the hdev->setup vendor callback.
+ 	 */
+ 	HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN,
++
++	/*
++	 * When this quirk is set, the HCI_OP_LE_SET_EXT_SCAN_ENABLE command is
++	 * disabled. This is required for some Broadcom controllers which
++	 * erroneously claim to support extended scanning.
++	 *
++	 * This quirk can be set before hci_register_dev is called or
++	 * during the hdev->setup vendor callback.
++	 */
++	HCI_QUIRK_BROKEN_EXT_SCAN,
++
++	/*
++	 * When this quirk is set, the HCI_OP_GET_MWS_TRANSPORT_CONFIG command is
++	 * disabled. This is required for some Broadcom controllers which
++	 * erroneously claim to support MWS Transport Layer Configuration.
++	 *
++	 * This quirk can be set before hci_register_dev is called or
++	 * during the hdev->setup vendor callback.
++	 */
++	HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG,
+ };
+ 
+ /* HCI device flags */
+diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
+index e7862903187d8..6afb4771ce355 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -1681,7 +1681,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
+ 
+ /* Use ext scanning if set ext scan param and ext scan enable is supported */
+ #define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \
+-			   ((dev)->commands[37] & 0x40))
++			   ((dev)->commands[37] & 0x40) && \
++			   !test_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &(dev)->quirks))
++
+ /* Use ext create connection if command is supported */
+ #define use_ext_conn(dev) ((dev)->commands[37] & 0x80)
+ 
+@@ -1709,6 +1711,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
+ 	((dev)->le_features[3] & HCI_LE_CIS_PERIPHERAL)
+ #define bis_capable(dev) ((dev)->le_features[3] & HCI_LE_ISO_BROADCASTER)
+ 
++#define mws_transport_config_capable(dev) (((dev)->commands[30] & 0x08) && \
++	(!test_bit(HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG, &(dev)->quirks)))
++
+ /* ----- HCI protocols ----- */
+ #define HCI_PROTO_DEFER             0x01
+ 
+diff --git a/include/net/dst.h b/include/net/dst.h
+index 6aa252c3fc55c..19af7a2713ccb 100644
+--- a/include/net/dst.h
++++ b/include/net/dst.h
+@@ -362,9 +362,8 @@ static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
+ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
+ 				 struct net *net)
+ {
+-	/* TODO : stats should be SMP safe */
+-	dev->stats.rx_packets++;
+-	dev->stats.rx_bytes += skb->len;
++	DEV_STATS_INC(dev, rx_packets);
++	DEV_STATS_ADD(dev, rx_bytes, skb->len);
+ 	__skb_tunnel_rx(skb, dev, net);
+ }
+ 
+diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
+index ff1804a0c4692..1fca6a88114ad 100644
+--- a/include/net/ip_vs.h
++++ b/include/net/ip_vs.h
+@@ -351,11 +351,11 @@ struct ip_vs_seq {
+ 
+ /* counters per cpu */
+ struct ip_vs_counters {
+-	__u64		conns;		/* connections scheduled */
+-	__u64		inpkts;		/* incoming packets */
+-	__u64		outpkts;	/* outgoing packets */
+-	__u64		inbytes;	/* incoming bytes */
+-	__u64		outbytes;	/* outgoing bytes */
++	u64_stats_t	conns;		/* connections scheduled */
++	u64_stats_t	inpkts;		/* incoming packets */
++	u64_stats_t	outpkts;	/* outgoing packets */
++	u64_stats_t	inbytes;	/* incoming bytes */
++	u64_stats_t	outbytes;	/* outgoing bytes */
+ };
+ /* Stats per cpu */
+ struct ip_vs_cpu_stats {
+diff --git a/include/net/mrp.h b/include/net/mrp.h
+index 92cd3fb6cf9da..b28915ffea284 100644
+--- a/include/net/mrp.h
++++ b/include/net/mrp.h
+@@ -124,6 +124,7 @@ struct mrp_applicant {
+ 	struct sk_buff		*pdu;
+ 	struct rb_root		mad;
+ 	struct rcu_head		rcu;
++	bool			active;
+ };
+ 
+ struct mrp_port {
+diff --git a/include/net/sock_reuseport.h b/include/net/sock_reuseport.h
+index efc9085c68927..6ec140b0a61bf 100644
+--- a/include/net/sock_reuseport.h
++++ b/include/net/sock_reuseport.h
+@@ -16,6 +16,7 @@ struct sock_reuseport {
+ 	u16			max_socks;		/* length of socks */
+ 	u16			num_socks;		/* elements in socks */
+ 	u16			num_closed_socks;	/* closed elements in socks */
++	u16			incoming_cpu;
+ 	/* The last synq overflow event timestamp of this
+ 	 * reuse->socks[] group.
+ 	 */
+@@ -58,5 +59,6 @@ static inline bool reuseport_has_conns(struct sock *sk)
+ }
+ 
+ void reuseport_has_conns_set(struct sock *sk);
++void reuseport_update_incoming_cpu(struct sock *sk, int val);
+ 
+ #endif  /* _SOCK_REUSEPORT_H */
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 95c1d51393ac4..3cde7b4a401f2 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -2284,8 +2284,8 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore);
+ void tcp_bpf_clone(const struct sock *sk, struct sock *newsk);
+ #endif /* CONFIG_BPF_SYSCALL */
+ 
+-int tcp_bpf_sendmsg_redir(struct sock *sk, struct sk_msg *msg, u32 bytes,
+-			  int flags);
++int tcp_bpf_sendmsg_redir(struct sock *sk, bool ingress,
++			  struct sk_msg *msg, u32 bytes, int flags);
+ #endif /* CONFIG_NET_SOCK_MSG */
+ 
+ #if !defined(CONFIG_BPF_SYSCALL) || !defined(CONFIG_NET_SOCK_MSG)
+diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h
+index a1df4f9d57a31..ec646217e7f6e 100644
+--- a/include/scsi/sas_ata.h
++++ b/include/scsi/sas_ata.h
+@@ -35,6 +35,7 @@ void sas_ata_end_eh(struct ata_port *ap);
+ int sas_execute_ata_cmd(struct domain_device *device, u8 *fis,
+ 			int force_phy_id);
+ int sas_ata_wait_after_reset(struct domain_device *dev, unsigned long deadline);
++int smp_ata_check_ready_type(struct ata_link *link);
+ #else
+ 
+ 
+@@ -98,6 +99,11 @@ static inline int sas_ata_wait_after_reset(struct domain_device *dev,
+ {
+ 	return -ETIMEDOUT;
+ }
++
++static inline int smp_ata_check_ready_type(struct ata_link *link)
++{
++	return 0;
++}
+ #endif
+ 
+ #endif /* _SAS_ATA_H_ */
+diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h
+index 6d3c82c4b6acd..ec2a2ba21cc39 100644
+--- a/include/sound/hda_codec.h
++++ b/include/sound/hda_codec.h
+@@ -258,7 +258,7 @@ struct hda_codec {
+ 	unsigned int link_down_at_suspend:1; /* link down at runtime suspend */
+ 	unsigned int relaxed_resume:1;	/* don't resume forcibly for jack */
+ 	unsigned int forced_resume:1; /* forced resume for jack */
+-	unsigned int mst_no_extra_pcms:1; /* no backup PCMs for DP-MST */
++	unsigned int no_stream_clean_at_suspend:1; /* do not clean streams at suspend */
+ 
+ #ifdef CONFIG_PM
+ 	unsigned long power_on_acct;
+diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
+index 797bf67a164db..ceaa7b7cfdc30 100644
+--- a/include/sound/hdaudio.h
++++ b/include/sound/hdaudio.h
+@@ -562,6 +562,7 @@ int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
+ void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start);
+ void snd_hdac_stream_clear(struct hdac_stream *azx_dev);
+ void snd_hdac_stream_stop(struct hdac_stream *azx_dev);
++void snd_hdac_stop_streams(struct hdac_bus *bus);
+ void snd_hdac_stop_streams_and_chip(struct hdac_bus *bus);
+ void snd_hdac_stream_reset(struct hdac_stream *azx_dev);
+ void snd_hdac_stream_sync_trigger(struct hdac_stream *azx_dev, bool set,
+diff --git a/include/sound/pcm.h b/include/sound/pcm.h
+index 8c48a5bce88c1..25695f5f795a1 100644
+--- a/include/sound/pcm.h
++++ b/include/sound/pcm.h
+@@ -106,24 +106,24 @@ struct snd_pcm_ops {
+ #define SNDRV_PCM_POS_XRUN		((snd_pcm_uframes_t)-1)
+ 
+ /* If you change this don't forget to change rates[] table in pcm_native.c */
+-#define SNDRV_PCM_RATE_5512		(1<<0)		/* 5512Hz */
+-#define SNDRV_PCM_RATE_8000		(1<<1)		/* 8000Hz */
+-#define SNDRV_PCM_RATE_11025		(1<<2)		/* 11025Hz */
+-#define SNDRV_PCM_RATE_16000		(1<<3)		/* 16000Hz */
+-#define SNDRV_PCM_RATE_22050		(1<<4)		/* 22050Hz */
+-#define SNDRV_PCM_RATE_32000		(1<<5)		/* 32000Hz */
+-#define SNDRV_PCM_RATE_44100		(1<<6)		/* 44100Hz */
+-#define SNDRV_PCM_RATE_48000		(1<<7)		/* 48000Hz */
+-#define SNDRV_PCM_RATE_64000		(1<<8)		/* 64000Hz */
+-#define SNDRV_PCM_RATE_88200		(1<<9)		/* 88200Hz */
+-#define SNDRV_PCM_RATE_96000		(1<<10)		/* 96000Hz */
+-#define SNDRV_PCM_RATE_176400		(1<<11)		/* 176400Hz */
+-#define SNDRV_PCM_RATE_192000		(1<<12)		/* 192000Hz */
+-#define SNDRV_PCM_RATE_352800		(1<<13)		/* 352800Hz */
+-#define SNDRV_PCM_RATE_384000		(1<<14)		/* 384000Hz */
+-
+-#define SNDRV_PCM_RATE_CONTINUOUS	(1<<30)		/* continuous range */
+-#define SNDRV_PCM_RATE_KNOT		(1<<31)		/* supports more non-continuos rates */
++#define SNDRV_PCM_RATE_5512		(1U<<0)		/* 5512Hz */
++#define SNDRV_PCM_RATE_8000		(1U<<1)		/* 8000Hz */
++#define SNDRV_PCM_RATE_11025		(1U<<2)		/* 11025Hz */
++#define SNDRV_PCM_RATE_16000		(1U<<3)		/* 16000Hz */
++#define SNDRV_PCM_RATE_22050		(1U<<4)		/* 22050Hz */
++#define SNDRV_PCM_RATE_32000		(1U<<5)		/* 32000Hz */
++#define SNDRV_PCM_RATE_44100		(1U<<6)		/* 44100Hz */
++#define SNDRV_PCM_RATE_48000		(1U<<7)		/* 48000Hz */
++#define SNDRV_PCM_RATE_64000		(1U<<8)		/* 64000Hz */
++#define SNDRV_PCM_RATE_88200		(1U<<9)		/* 88200Hz */
++#define SNDRV_PCM_RATE_96000		(1U<<10)	/* 96000Hz */
++#define SNDRV_PCM_RATE_176400		(1U<<11)	/* 176400Hz */
++#define SNDRV_PCM_RATE_192000		(1U<<12)	/* 192000Hz */
++#define SNDRV_PCM_RATE_352800		(1U<<13)	/* 352800Hz */
++#define SNDRV_PCM_RATE_384000		(1U<<14)	/* 384000Hz */
++
++#define SNDRV_PCM_RATE_CONTINUOUS	(1U<<30)	/* continuous range */
++#define SNDRV_PCM_RATE_KNOT		(1U<<31)	/* supports more non-continuos rates */
+ 
+ #define SNDRV_PCM_RATE_8000_44100	(SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
+ 					 SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|\
+diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
+index f1e9222377368..f4556911c2347 100644
+--- a/include/trace/events/f2fs.h
++++ b/include/trace/events/f2fs.h
+@@ -322,7 +322,7 @@ TRACE_EVENT(f2fs_unlink_enter,
+ 		__field(ino_t,	ino)
+ 		__field(loff_t,	size)
+ 		__field(blkcnt_t, blocks)
+-		__field(const char *,	name)
++		__string(name,  dentry->d_name.name)
+ 	),
+ 
+ 	TP_fast_assign(
+@@ -330,7 +330,7 @@ TRACE_EVENT(f2fs_unlink_enter,
+ 		__entry->ino	= dir->i_ino;
+ 		__entry->size	= dir->i_size;
+ 		__entry->blocks	= dir->i_blocks;
+-		__entry->name	= dentry->d_name.name;
++		__assign_str(name, dentry->d_name.name);
+ 	),
+ 
+ 	TP_printk("dev = (%d,%d), dir ino = %lu, i_size = %lld, "
+@@ -338,7 +338,7 @@ TRACE_EVENT(f2fs_unlink_enter,
+ 		show_dev_ino(__entry),
+ 		__entry->size,
+ 		(unsigned long long)__entry->blocks,
+-		__entry->name)
++		__get_str(name))
+ );
+ 
+ DEFINE_EVENT(f2fs__inode_exit, f2fs_unlink_exit,
+@@ -940,25 +940,29 @@ TRACE_EVENT(f2fs_direct_IO_enter,
+ 	TP_STRUCT__entry(
+ 		__field(dev_t,	dev)
+ 		__field(ino_t,	ino)
+-		__field(struct kiocb *,	iocb)
++		__field(loff_t,	ki_pos)
++		__field(int,	ki_flags)
++		__field(u16,	ki_ioprio)
+ 		__field(unsigned long,	len)
+ 		__field(int,	rw)
+ 	),
+ 
+ 	TP_fast_assign(
+-		__entry->dev	= inode->i_sb->s_dev;
+-		__entry->ino	= inode->i_ino;
+-		__entry->iocb	= iocb;
+-		__entry->len	= len;
+-		__entry->rw	= rw;
++		__entry->dev		= inode->i_sb->s_dev;
++		__entry->ino		= inode->i_ino;
++		__entry->ki_pos		= iocb->ki_pos;
++		__entry->ki_flags	= iocb->ki_flags;
++		__entry->ki_ioprio	= iocb->ki_ioprio;
++		__entry->len		= len;
++		__entry->rw		= rw;
+ 	),
+ 
+ 	TP_printk("dev = (%d,%d), ino = %lu pos = %lld len = %lu ki_flags = %x ki_ioprio = %x rw = %d",
+ 		show_dev_ino(__entry),
+-		__entry->iocb->ki_pos,
++		__entry->ki_pos,
+ 		__entry->len,
+-		__entry->iocb->ki_flags,
+-		__entry->iocb->ki_ioprio,
++		__entry->ki_flags,
++		__entry->ki_ioprio,
+ 		__entry->rw)
+ );
+ 
+@@ -1407,19 +1411,19 @@ TRACE_EVENT(f2fs_write_checkpoint,
+ 	TP_STRUCT__entry(
+ 		__field(dev_t,	dev)
+ 		__field(int,	reason)
+-		__field(char *,	msg)
++		__string(dest_msg, msg)
+ 	),
+ 
+ 	TP_fast_assign(
+ 		__entry->dev		= sb->s_dev;
+ 		__entry->reason		= reason;
+-		__entry->msg		= msg;
++		__assign_str(dest_msg, msg);
+ 	),
+ 
+ 	TP_printk("dev = (%d,%d), checkpoint for %s, state = %s",
+ 		show_dev(__entry->dev),
+ 		show_cpreason(__entry->reason),
+-		__entry->msg)
++		__get_str(dest_msg))
+ );
+ 
+ DECLARE_EVENT_CLASS(f2fs_discard,
+diff --git a/include/trace/events/ib_mad.h b/include/trace/events/ib_mad.h
+index 59363a083ecb9..d92691c78cff6 100644
+--- a/include/trace/events/ib_mad.h
++++ b/include/trace/events/ib_mad.h
+@@ -49,7 +49,6 @@ DECLARE_EVENT_CLASS(ib_mad_send_template,
+ 		__field(int,            retries_left)
+ 		__field(int,            max_retries)
+ 		__field(int,            retry)
+-		__field(u16,            pkey)
+ 	),
+ 
+ 	TP_fast_assign(
+@@ -89,7 +88,7 @@ DECLARE_EVENT_CLASS(ib_mad_send_template,
+ 		  "hdr : base_ver 0x%x class 0x%x class_ver 0x%x " \
+ 		  "method 0x%x status 0x%x class_specific 0x%x tid 0x%llx " \
+ 		  "attr_id 0x%x attr_mod 0x%x  => dlid 0x%08x sl %d "\
+-		  "pkey 0x%x rpqn 0x%x rqpkey 0x%x",
++		  "rpqn 0x%x rqpkey 0x%x",
+ 		__entry->dev_index, __entry->port_num, __entry->qp_num,
+ 		__entry->agent_priv, be64_to_cpu(__entry->wrtid),
+ 		__entry->retries_left, __entry->max_retries,
+@@ -100,7 +99,7 @@ DECLARE_EVENT_CLASS(ib_mad_send_template,
+ 		be16_to_cpu(__entry->class_specific),
+ 		be64_to_cpu(__entry->tid), be16_to_cpu(__entry->attr_id),
+ 		be32_to_cpu(__entry->attr_mod),
+-		be32_to_cpu(__entry->dlid), __entry->sl, __entry->pkey,
++		be32_to_cpu(__entry->dlid), __entry->sl,
+ 		__entry->rqpn, __entry->rqkey
+ 	)
+ );
+@@ -204,7 +203,6 @@ TRACE_EVENT(ib_mad_recv_done_handler,
+ 		__field(u16,            wc_status)
+ 		__field(u32,            slid)
+ 		__field(u32,            dev_index)
+-		__field(u16,            pkey)
+ 	),
+ 
+ 	TP_fast_assign(
+@@ -224,9 +222,6 @@ TRACE_EVENT(ib_mad_recv_done_handler,
+ 		__entry->slid = wc->slid;
+ 		__entry->src_qp = wc->src_qp;
+ 		__entry->sl = wc->sl;
+-		ib_query_pkey(qp_info->port_priv->device,
+-			      qp_info->port_priv->port_num,
+-			      wc->pkey_index, &__entry->pkey);
+ 		__entry->wc_status = wc->status;
+ 	),
+ 
+@@ -234,7 +229,7 @@ TRACE_EVENT(ib_mad_recv_done_handler,
+ 		  "base_ver 0x%02x class 0x%02x class_ver 0x%02x " \
+ 		  "method 0x%02x status 0x%04x class_specific 0x%04x " \
+ 		  "tid 0x%016llx attr_id 0x%04x attr_mod 0x%08x " \
+-		  "slid 0x%08x src QP%d, sl %d pkey 0x%04x",
++		  "slid 0x%08x src QP%d, sl %d",
+ 		__entry->dev_index, __entry->port_num, __entry->qp_num,
+ 		__entry->wc_status,
+ 		__entry->length,
+@@ -244,7 +239,7 @@ TRACE_EVENT(ib_mad_recv_done_handler,
+ 		be16_to_cpu(__entry->class_specific),
+ 		be64_to_cpu(__entry->tid), be16_to_cpu(__entry->attr_id),
+ 		be32_to_cpu(__entry->attr_mod),
+-		__entry->slid, __entry->src_qp, __entry->sl, __entry->pkey
++		__entry->slid, __entry->src_qp, __entry->sl
+ 	)
+ );
+ 
+diff --git a/include/uapi/linux/idxd.h b/include/uapi/linux/idxd.h
+index 2b9e7feba3f32..1d553bedbdb51 100644
+--- a/include/uapi/linux/idxd.h
++++ b/include/uapi/linux/idxd.h
+@@ -295,7 +295,7 @@ struct dsa_completion_record {
+ 		};
+ 
+ 		uint32_t	delta_rec_size;
+-		uint32_t	crc_val;
++		uint64_t	crc_val;
+ 
+ 		/* DIF check & strip */
+ 		struct {
+diff --git a/include/uapi/linux/swab.h b/include/uapi/linux/swab.h
+index 0723a9cce747c..01717181339eb 100644
+--- a/include/uapi/linux/swab.h
++++ b/include/uapi/linux/swab.h
+@@ -3,7 +3,7 @@
+ #define _UAPI_LINUX_SWAB_H
+ 
+ #include <linux/types.h>
+-#include <linux/compiler.h>
++#include <linux/stddef.h>
+ #include <asm/bitsperlong.h>
+ #include <asm/swab.h>
+ 
+diff --git a/include/uapi/rdma/hns-abi.h b/include/uapi/rdma/hns-abi.h
+index f6fde06db4b4e..745790ce3c261 100644
+--- a/include/uapi/rdma/hns-abi.h
++++ b/include/uapi/rdma/hns-abi.h
+@@ -85,11 +85,26 @@ struct hns_roce_ib_create_qp_resp {
+ 	__aligned_u64 dwqe_mmap_key;
+ };
+ 
++enum {
++	HNS_ROCE_EXSGE_FLAGS = 1 << 0,
++};
++
++enum {
++	HNS_ROCE_RSP_EXSGE_FLAGS = 1 << 0,
++};
++
+ struct hns_roce_ib_alloc_ucontext_resp {
+ 	__u32	qp_tab_size;
+ 	__u32	cqe_size;
+ 	__u32	srq_tab_size;
+ 	__u32	reserved;
++	__u32	config;
++	__u32	max_inline_data;
++};
++
++struct hns_roce_ib_alloc_ucontext {
++	__u32 config;
++	__u32 reserved;
+ };
+ 
+ struct hns_roce_ib_alloc_pd_resp {
+diff --git a/include/uapi/sound/asequencer.h b/include/uapi/sound/asequencer.h
+index a75e14edc957e..dbd60f48b4b01 100644
+--- a/include/uapi/sound/asequencer.h
++++ b/include/uapi/sound/asequencer.h
+@@ -344,10 +344,10 @@ typedef int __bitwise snd_seq_client_type_t;
+ #define	KERNEL_CLIENT	((__force snd_seq_client_type_t) 2)
+                         
+ 	/* event filter flags */
+-#define SNDRV_SEQ_FILTER_BROADCAST	(1<<0)	/* accept broadcast messages */
+-#define SNDRV_SEQ_FILTER_MULTICAST	(1<<1)	/* accept multicast messages */
+-#define SNDRV_SEQ_FILTER_BOUNCE		(1<<2)	/* accept bounce event in error */
+-#define SNDRV_SEQ_FILTER_USE_EVENT	(1<<31)	/* use event filter */
++#define SNDRV_SEQ_FILTER_BROADCAST	(1U<<0)	/* accept broadcast messages */
++#define SNDRV_SEQ_FILTER_MULTICAST	(1U<<1)	/* accept multicast messages */
++#define SNDRV_SEQ_FILTER_BOUNCE		(1U<<2)	/* accept bounce event in error */
++#define SNDRV_SEQ_FILTER_USE_EVENT	(1U<<31)	/* use event filter */
+ 
+ struct snd_seq_client_info {
+ 	int client;			/* client number to inquire */
+diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c
+index 90d2fc6fd80e4..080867143f287 100644
+--- a/io_uring/msg_ring.c
++++ b/io_uring/msg_ring.c
+@@ -164,6 +164,8 @@ int io_msg_ring(struct io_kiocb *req, unsigned int issue_flags)
+ 	}
+ 
+ done:
++	if (ret == -EAGAIN)
++		return -EAGAIN;
+ 	if (ret < 0)
+ 		req_set_fail(req);
+ 	io_req_set_res(req, ret, 0);
+diff --git a/io_uring/net.c b/io_uring/net.c
+index 8205cfecd647c..eaaacee91a1ff 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -772,10 +772,10 @@ retry_multishot:
+ 		goto retry_multishot;
+ 
+ 	if (mshot_finished) {
+-		io_netmsg_recycle(req, issue_flags);
+ 		/* fast path, check for non-NULL to avoid function call */
+ 		if (kmsg->free_iov)
+ 			kfree(kmsg->free_iov);
++		io_netmsg_recycle(req, issue_flags);
+ 		req->flags &= ~REQ_F_NEED_CLEANUP;
+ 	}
+ 
+diff --git a/io_uring/timeout.c b/io_uring/timeout.c
+index 78ea2c64b70e0..535ecaee5a0bb 100644
+--- a/io_uring/timeout.c
++++ b/io_uring/timeout.c
+@@ -72,10 +72,12 @@ static bool io_kill_timeout(struct io_kiocb *req, int status)
+ __cold void io_flush_timeouts(struct io_ring_ctx *ctx)
+ 	__must_hold(&ctx->completion_lock)
+ {
+-	u32 seq = ctx->cached_cq_tail - atomic_read(&ctx->cq_timeouts);
++	u32 seq;
+ 	struct io_timeout *timeout, *tmp;
+ 
+ 	spin_lock_irq(&ctx->timeout_lock);
++	seq = ctx->cached_cq_tail - atomic_read(&ctx->cq_timeouts);
++
+ 	list_for_each_entry_safe(timeout, tmp, &ctx->timeout_list, list) {
+ 		struct io_kiocb *req = cmd_to_io_kiocb(timeout);
+ 		u32 events_needed, events_got;
+diff --git a/ipc/mqueue.c b/ipc/mqueue.c
+index 9cf314b3f079f..b258f24555534 100644
+--- a/ipc/mqueue.c
++++ b/ipc/mqueue.c
+@@ -1727,7 +1727,8 @@ static int __init init_mqueue_fs(void)
+ 
+ 	if (!setup_mq_sysctls(&init_ipc_ns)) {
+ 		pr_warn("sysctl registration failed\n");
+-		return -ENOMEM;
++		error = -ENOMEM;
++		goto out_kmem;
+ 	}
+ 
+ 	error = register_filesystem(&mqueue_fs_type);
+@@ -1745,8 +1746,9 @@ static int __init init_mqueue_fs(void)
+ out_filesystem:
+ 	unregister_filesystem(&mqueue_fs_type);
+ out_sysctl:
+-	kmem_cache_destroy(mqueue_inode_cachep);
+ 	retire_mq_sysctls(&init_ipc_ns);
++out_kmem:
++	kmem_cache_destroy(mqueue_inode_cachep);
+ 	return error;
+ }
+ 
+diff --git a/kernel/acct.c b/kernel/acct.c
+index 13706356ec54d..67bde1633d8f9 100644
+--- a/kernel/acct.c
++++ b/kernel/acct.c
+@@ -350,6 +350,8 @@ static comp_t encode_comp_t(unsigned long value)
+ 		exp++;
+ 	}
+ 
++	if (exp > (((comp_t) ~0U) >> MANTSIZE))
++		return (comp_t) ~0U;
+ 	/*
+ 	 * Clean it up and polish it off.
+ 	 */
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 0d23d4bcd81cc..44e93c3abebde 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -4481,6 +4481,11 @@ static int btf_func_proto_check(struct btf_verifier_env *env,
+ 			break;
+ 		}
+ 
++		if (btf_type_is_resolve_source_only(arg_type)) {
++			btf_verifier_log_type(env, t, "Invalid arg#%u", i + 1);
++			return -EINVAL;
++		}
++
+ 		if (args[i].name_off &&
+ 		    (!btf_name_offset_valid(btf, args[i].name_off) ||
+ 		     !btf_name_valid_identifier(btf, args[i].name_off))) {
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index 0e758911d963f..6b6fb7237ebea 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -3505,9 +3505,9 @@ static int bpf_prog_attach(const union bpf_attr *attr)
+ 	case BPF_PROG_TYPE_LSM:
+ 		if (ptype == BPF_PROG_TYPE_LSM &&
+ 		    prog->expected_attach_type != BPF_LSM_CGROUP)
+-			return -EINVAL;
+-
+-		ret = cgroup_bpf_prog_attach(attr, ptype, prog);
++			ret = -EINVAL;
++		else
++			ret = cgroup_bpf_prog_attach(attr, ptype, prog);
+ 		break;
+ 	default:
+ 		ret = -EINVAL;
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index b781075dd5109..57f76b597012c 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -2751,7 +2751,7 @@ static void mark_all_scalars_precise(struct bpf_verifier_env *env,
+ 		}
+ }
+ 
+-static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
++static int __mark_chain_precision(struct bpf_verifier_env *env, int frame, int regno,
+ 				  int spi)
+ {
+ 	struct bpf_verifier_state *st = env->cur_state;
+@@ -2768,7 +2768,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+ 	if (!env->bpf_capable)
+ 		return 0;
+ 
+-	func = st->frame[st->curframe];
++	func = st->frame[frame];
+ 	if (regno >= 0) {
+ 		reg = &func->regs[regno];
+ 		if (reg->type != SCALAR_VALUE) {
+@@ -2849,7 +2849,7 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+ 			break;
+ 
+ 		new_marks = false;
+-		func = st->frame[st->curframe];
++		func = st->frame[frame];
+ 		bitmap_from_u64(mask, reg_mask);
+ 		for_each_set_bit(i, mask, 32) {
+ 			reg = &func->regs[i];
+@@ -2915,12 +2915,17 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
+ 
+ static int mark_chain_precision(struct bpf_verifier_env *env, int regno)
+ {
+-	return __mark_chain_precision(env, regno, -1);
++	return __mark_chain_precision(env, env->cur_state->curframe, regno, -1);
+ }
+ 
+-static int mark_chain_precision_stack(struct bpf_verifier_env *env, int spi)
++static int mark_chain_precision_frame(struct bpf_verifier_env *env, int frame, int regno)
+ {
+-	return __mark_chain_precision(env, -1, spi);
++	return __mark_chain_precision(env, frame, regno, -1);
++}
++
++static int mark_chain_precision_stack_frame(struct bpf_verifier_env *env, int frame, int spi)
++{
++	return __mark_chain_precision(env, frame, -1, spi);
+ }
+ 
+ static bool is_spillable_regtype(enum bpf_reg_type type)
+@@ -3169,14 +3174,17 @@ static int check_stack_write_var_off(struct bpf_verifier_env *env,
+ 		stype = &state->stack[spi].slot_type[slot % BPF_REG_SIZE];
+ 		mark_stack_slot_scratched(env, spi);
+ 
+-		if (!env->allow_ptr_leaks
+-				&& *stype != NOT_INIT
+-				&& *stype != SCALAR_VALUE) {
+-			/* Reject the write if there's are spilled pointers in
+-			 * range. If we didn't reject here, the ptr status
+-			 * would be erased below (even though not all slots are
+-			 * actually overwritten), possibly opening the door to
+-			 * leaks.
++		if (!env->allow_ptr_leaks && *stype != STACK_MISC && *stype != STACK_ZERO) {
++			/* Reject the write if range we may write to has not
++			 * been initialized beforehand. If we didn't reject
++			 * here, the ptr status would be erased below (even
++			 * though not all slots are actually overwritten),
++			 * possibly opening the door to leaks.
++			 *
++			 * We do however catch STACK_INVALID case below, and
++			 * only allow reading possibly uninitialized memory
++			 * later for CAP_PERFMON, as the write may not happen to
++			 * that slot.
+ 			 */
+ 			verbose(env, "spilled ptr in range of var-offset stack write; insn %d, ptr off: %d",
+ 				insn_idx, i);
+@@ -5142,10 +5150,6 @@ static int check_stack_range_initialized(
+ 			goto mark;
+ 		}
+ 
+-		if (is_spilled_reg(&state->stack[spi]) &&
+-		    base_type(state->stack[spi].spilled_ptr.type) == PTR_TO_BTF_ID)
+-			goto mark;
+-
+ 		if (is_spilled_reg(&state->stack[spi]) &&
+ 		    (state->stack[spi].spilled_ptr.type == SCALAR_VALUE ||
+ 		     env->allow_ptr_leaks)) {
+@@ -5176,6 +5180,11 @@ mark:
+ 		mark_reg_read(env, &state->stack[spi].spilled_ptr,
+ 			      state->stack[spi].spilled_ptr.parent,
+ 			      REG_LIVE_READ64);
++		/* We do not set REG_LIVE_WRITTEN for stack slot, as we can not
++		 * be sure that whether stack slot is written to or not. Hence,
++		 * we must still conservatively propagate reads upwards even if
++		 * helper may write to the entire memory range.
++		 */
+ 	}
+ 	return update_stack_depth(env, state, min_off);
+ }
+@@ -9057,6 +9066,11 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
+ 				return err;
+ 			return adjust_ptr_min_max_vals(env, insn,
+ 						       dst_reg, src_reg);
++		} else if (dst_reg->precise) {
++			/* if dst_reg is precise, src_reg should be precise as well */
++			err = mark_chain_precision(env, insn->src_reg);
++			if (err)
++				return err;
+ 		}
+ 	} else {
+ 		/* Pretend the src is a reg with a known value, since we only
+@@ -11693,34 +11707,36 @@ static int propagate_precision(struct bpf_verifier_env *env,
+ {
+ 	struct bpf_reg_state *state_reg;
+ 	struct bpf_func_state *state;
+-	int i, err = 0;
++	int i, err = 0, fr;
+ 
+-	state = old->frame[old->curframe];
+-	state_reg = state->regs;
+-	for (i = 0; i < BPF_REG_FP; i++, state_reg++) {
+-		if (state_reg->type != SCALAR_VALUE ||
+-		    !state_reg->precise)
+-			continue;
+-		if (env->log.level & BPF_LOG_LEVEL2)
+-			verbose(env, "propagating r%d\n", i);
+-		err = mark_chain_precision(env, i);
+-		if (err < 0)
+-			return err;
+-	}
++	for (fr = old->curframe; fr >= 0; fr--) {
++		state = old->frame[fr];
++		state_reg = state->regs;
++		for (i = 0; i < BPF_REG_FP; i++, state_reg++) {
++			if (state_reg->type != SCALAR_VALUE ||
++			    !state_reg->precise)
++				continue;
++			if (env->log.level & BPF_LOG_LEVEL2)
++				verbose(env, "frame %d: propagating r%d\n", i, fr);
++			err = mark_chain_precision_frame(env, fr, i);
++			if (err < 0)
++				return err;
++		}
+ 
+-	for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) {
+-		if (!is_spilled_reg(&state->stack[i]))
+-			continue;
+-		state_reg = &state->stack[i].spilled_ptr;
+-		if (state_reg->type != SCALAR_VALUE ||
+-		    !state_reg->precise)
+-			continue;
+-		if (env->log.level & BPF_LOG_LEVEL2)
+-			verbose(env, "propagating fp%d\n",
+-				(-i - 1) * BPF_REG_SIZE);
+-		err = mark_chain_precision_stack(env, i);
+-		if (err < 0)
+-			return err;
++		for (i = 0; i < state->allocated_stack / BPF_REG_SIZE; i++) {
++			if (!is_spilled_reg(&state->stack[i]))
++				continue;
++			state_reg = &state->stack[i].spilled_ptr;
++			if (state_reg->type != SCALAR_VALUE ||
++			    !state_reg->precise)
++				continue;
++			if (env->log.level & BPF_LOG_LEVEL2)
++				verbose(env, "frame %d: propagating fp%d\n",
++					(-i - 1) * BPF_REG_SIZE, fr);
++			err = mark_chain_precision_stack_frame(env, fr, i);
++			if (err < 0)
++				return err;
++		}
+ 	}
+ 	return 0;
+ }
+@@ -13283,6 +13299,10 @@ static int opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env,
+ 		if (!bpf_jit_needs_zext() && !is_cmpxchg_insn(&insn))
+ 			continue;
+ 
++		/* Zero-extension is done by the caller. */
++		if (bpf_pseudo_kfunc_call(&insn))
++			continue;
++
+ 		if (WARN_ON(load_reg == -1)) {
+ 			verbose(env, "verifier bug. zext_dst is set, but no reg is defined\n");
+ 			return -EFAULT;
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index bbad5e375d3ba..98a7a7b1471b7 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -663,21 +663,51 @@ static bool cpuhp_next_state(bool bringup,
+ 	return true;
+ }
+ 
+-static int cpuhp_invoke_callback_range(bool bringup,
+-				       unsigned int cpu,
+-				       struct cpuhp_cpu_state *st,
+-				       enum cpuhp_state target)
++static int __cpuhp_invoke_callback_range(bool bringup,
++					 unsigned int cpu,
++					 struct cpuhp_cpu_state *st,
++					 enum cpuhp_state target,
++					 bool nofail)
+ {
+ 	enum cpuhp_state state;
+-	int err = 0;
++	int ret = 0;
+ 
+ 	while (cpuhp_next_state(bringup, &state, st, target)) {
++		int err;
++
+ 		err = cpuhp_invoke_callback(cpu, state, bringup, NULL, NULL);
+-		if (err)
++		if (!err)
++			continue;
++
++		if (nofail) {
++			pr_warn("CPU %u %s state %s (%d) failed (%d)\n",
++				cpu, bringup ? "UP" : "DOWN",
++				cpuhp_get_step(st->state)->name,
++				st->state, err);
++			ret = -1;
++		} else {
++			ret = err;
+ 			break;
++		}
+ 	}
+ 
+-	return err;
++	return ret;
++}
++
++static inline int cpuhp_invoke_callback_range(bool bringup,
++					      unsigned int cpu,
++					      struct cpuhp_cpu_state *st,
++					      enum cpuhp_state target)
++{
++	return __cpuhp_invoke_callback_range(bringup, cpu, st, target, false);
++}
++
++static inline void cpuhp_invoke_callback_range_nofail(bool bringup,
++						      unsigned int cpu,
++						      struct cpuhp_cpu_state *st,
++						      enum cpuhp_state target)
++{
++	__cpuhp_invoke_callback_range(bringup, cpu, st, target, true);
+ }
+ 
+ static inline bool can_rollback_cpu(struct cpuhp_cpu_state *st)
+@@ -999,7 +1029,6 @@ static int take_cpu_down(void *_param)
+ 	struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state);
+ 	enum cpuhp_state target = max((int)st->target, CPUHP_AP_OFFLINE);
+ 	int err, cpu = smp_processor_id();
+-	int ret;
+ 
+ 	/* Ensure this CPU doesn't handle any more interrupts. */
+ 	err = __cpu_disable();
+@@ -1012,13 +1041,10 @@ static int take_cpu_down(void *_param)
+ 	 */
+ 	WARN_ON(st->state != (CPUHP_TEARDOWN_CPU - 1));
+ 
+-	/* Invoke the former CPU_DYING callbacks */
+-	ret = cpuhp_invoke_callback_range(false, cpu, st, target);
+-
+ 	/*
+-	 * DYING must not fail!
++	 * Invoke the former CPU_DYING callbacks. DYING must not fail!
+ 	 */
+-	WARN_ON_ONCE(ret);
++	cpuhp_invoke_callback_range_nofail(false, cpu, st, target);
+ 
+ 	/* Give up timekeeping duties */
+ 	tick_handover_do_timer();
+@@ -1296,16 +1322,14 @@ void notify_cpu_starting(unsigned int cpu)
+ {
+ 	struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
+ 	enum cpuhp_state target = min((int)st->target, CPUHP_AP_ONLINE);
+-	int ret;
+ 
+ 	rcu_cpu_starting(cpu);	/* Enables RCU usage on this CPU. */
+ 	cpumask_set_cpu(cpu, &cpus_booted_once_mask);
+-	ret = cpuhp_invoke_callback_range(true, cpu, st, target);
+ 
+ 	/*
+ 	 * STARTING must not fail!
+ 	 */
+-	WARN_ON_ONCE(ret);
++	cpuhp_invoke_callback_range_nofail(true, cpu, st, target);
+ }
+ 
+ /*
+@@ -2326,8 +2350,10 @@ static ssize_t target_store(struct device *dev, struct device_attribute *attr,
+ 
+ 	if (st->state < target)
+ 		ret = cpu_up(dev->id, target);
+-	else
++	else if (st->state > target)
+ 		ret = cpu_down(dev->id, target);
++	else if (WARN_ON(st->target != target))
++		st->target = target;
+ out:
+ 	unlock_device_hotplug();
+ 	return ret ? ret : count;
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 91473e9f88cd9..a636fab5e381a 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -11136,13 +11136,15 @@ static int pmu_dev_alloc(struct pmu *pmu)
+ 
+ 	pmu->dev->groups = pmu->attr_groups;
+ 	device_initialize(pmu->dev);
+-	ret = dev_set_name(pmu->dev, "%s", pmu->name);
+-	if (ret)
+-		goto free_dev;
+ 
+ 	dev_set_drvdata(pmu->dev, pmu);
+ 	pmu->dev->bus = &pmu_bus;
+ 	pmu->dev->release = pmu_dev_release;
++
++	ret = dev_set_name(pmu->dev, "%s", pmu->name);
++	if (ret)
++		goto free_dev;
++
+ 	ret = device_add(pmu->dev);
+ 	if (ret)
+ 		goto free_dev;
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 2b6bd511c6ed1..f925d2b96e0a9 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -537,6 +537,9 @@ void put_task_stack(struct task_struct *tsk)
+ 
+ void free_task(struct task_struct *tsk)
+ {
++#ifdef CONFIG_SECCOMP
++	WARN_ON_ONCE(tsk->seccomp.filter);
++#endif
+ 	release_user_cpus_ptr(tsk);
+ 	scs_release(tsk);
+ 
+@@ -2407,12 +2410,6 @@ static __latent_entropy struct task_struct *copy_process(
+ 
+ 	spin_lock(&current->sighand->siglock);
+ 
+-	/*
+-	 * Copy seccomp details explicitly here, in case they were changed
+-	 * before holding sighand lock.
+-	 */
+-	copy_seccomp(p);
+-
+ 	rv_task_fork(p);
+ 
+ 	rseq_fork(p, clone_flags);
+@@ -2429,6 +2426,14 @@ static __latent_entropy struct task_struct *copy_process(
+ 		goto bad_fork_cancel_cgroup;
+ 	}
+ 
++	/* No more failure paths after this point. */
++
++	/*
++	 * Copy seccomp details explicitly here, in case they were changed
++	 * before holding sighand lock.
++	 */
++	copy_seccomp(p);
++
+ 	init_task_pid_links(p);
+ 	if (likely(p->pid)) {
+ 		ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
+diff --git a/kernel/futex/core.c b/kernel/futex/core.c
+index b22ef1efe7511..514e4582b8634 100644
+--- a/kernel/futex/core.c
++++ b/kernel/futex/core.c
+@@ -638,6 +638,7 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr,
+ 			      bool pi, bool pending_op)
+ {
+ 	u32 uval, nval, mval;
++	pid_t owner;
+ 	int err;
+ 
+ 	/* Futex address must be 32bit aligned */
+@@ -659,6 +660,10 @@ retry:
+ 	 * 2. A woken up waiter is killed before it can acquire the
+ 	 *    futex in user space.
+ 	 *
++	 * In the second case, the wake up notification could be generated
++	 * by the unlock path in user space after setting the futex value
++	 * to zero or by the kernel after setting the OWNER_DIED bit below.
++	 *
+ 	 * In both cases the TID validation below prevents a wakeup of
+ 	 * potential waiters which can cause these waiters to block
+ 	 * forever.
+@@ -667,24 +672,27 @@ retry:
+ 	 *
+ 	 *	1) task->robust_list->list_op_pending != NULL
+ 	 *	   @pending_op == true
+-	 *	2) User space futex value == 0
++	 *	2) The owner part of user space futex value == 0
+ 	 *	3) Regular futex: @pi == false
+ 	 *
+ 	 * If these conditions are met, it is safe to attempt waking up a
+ 	 * potential waiter without touching the user space futex value and
+-	 * trying to set the OWNER_DIED bit. The user space futex value is
+-	 * uncontended and the rest of the user space mutex state is
+-	 * consistent, so a woken waiter will just take over the
+-	 * uncontended futex. Setting the OWNER_DIED bit would create
+-	 * inconsistent state and malfunction of the user space owner died
+-	 * handling.
++	 * trying to set the OWNER_DIED bit. If the futex value is zero,
++	 * the rest of the user space mutex state is consistent, so a woken
++	 * waiter will just take over the uncontended futex. Setting the
++	 * OWNER_DIED bit would create inconsistent state and malfunction
++	 * of the user space owner died handling. Otherwise, the OWNER_DIED
++	 * bit is already set, and the woken waiter is expected to deal with
++	 * this.
+ 	 */
+-	if (pending_op && !pi && !uval) {
++	owner = uval & FUTEX_TID_MASK;
++
++	if (pending_op && !pi && !owner) {
+ 		futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY);
+ 		return 0;
+ 	}
+ 
+-	if ((uval & FUTEX_TID_MASK) != task_pid_vnr(curr))
++	if (owner != task_pid_vnr(curr))
+ 		return 0;
+ 
+ 	/*
+diff --git a/kernel/gcov/gcc_4_7.c b/kernel/gcov/gcc_4_7.c
+index 7971e989e425b..74a4ef1da9ad7 100644
+--- a/kernel/gcov/gcc_4_7.c
++++ b/kernel/gcov/gcc_4_7.c
+@@ -82,6 +82,7 @@ struct gcov_fn_info {
+  * @version: gcov version magic indicating the gcc version used for compilation
+  * @next: list head for a singly-linked list
+  * @stamp: uniquifying time stamp
++ * @checksum: unique object checksum
+  * @filename: name of the associated gcov data file
+  * @merge: merge functions (null for unused counter type)
+  * @n_functions: number of instrumented functions
+@@ -94,6 +95,10 @@ struct gcov_info {
+ 	unsigned int version;
+ 	struct gcov_info *next;
+ 	unsigned int stamp;
++ /* Since GCC 12.1 a checksum field is added. */
++#if (__GNUC__ >= 12)
++	unsigned int checksum;
++#endif
+ 	const char *filename;
+ 	void (*merge[GCOV_COUNTERS])(gcov_type *, unsigned int);
+ 	unsigned int n_functions;
+diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
+index f09c60393e559..5fdc0b5575797 100644
+--- a/kernel/irq/internals.h
++++ b/kernel/irq/internals.h
+@@ -52,6 +52,7 @@ enum {
+  * IRQS_PENDING			- irq is pending and replayed later
+  * IRQS_SUSPENDED		- irq is suspended
+  * IRQS_NMI			- irq line is used to deliver NMIs
++ * IRQS_SYSFS			- descriptor has been added to sysfs
+  */
+ enum {
+ 	IRQS_AUTODETECT		= 0x00000001,
+@@ -64,6 +65,7 @@ enum {
+ 	IRQS_SUSPENDED		= 0x00000800,
+ 	IRQS_TIMINGS		= 0x00001000,
+ 	IRQS_NMI		= 0x00002000,
++	IRQS_SYSFS		= 0x00004000,
+ };
+ 
+ #include "debug.h"
+diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
+index 5db0230aa6b52..c797d4054d0e5 100644
+--- a/kernel/irq/irqdesc.c
++++ b/kernel/irq/irqdesc.c
+@@ -288,22 +288,25 @@ static void irq_sysfs_add(int irq, struct irq_desc *desc)
+ 	if (irq_kobj_base) {
+ 		/*
+ 		 * Continue even in case of failure as this is nothing
+-		 * crucial.
++		 * crucial and failures in the late irq_sysfs_init()
++		 * cannot be rolled back.
+ 		 */
+ 		if (kobject_add(&desc->kobj, irq_kobj_base, "%d", irq))
+ 			pr_warn("Failed to add kobject for irq %d\n", irq);
++		else
++			desc->istate |= IRQS_SYSFS;
+ 	}
+ }
+ 
+ static void irq_sysfs_del(struct irq_desc *desc)
+ {
+ 	/*
+-	 * If irq_sysfs_init() has not yet been invoked (early boot), then
+-	 * irq_kobj_base is NULL and the descriptor was never added.
+-	 * kobject_del() complains about a object with no parent, so make
+-	 * it conditional.
++	 * Only invoke kobject_del() when kobject_add() was successfully
++	 * invoked for the descriptor. This covers both early boot, where
++	 * sysfs is not initialized yet, and the case of a failed
++	 * kobject_add() invocation.
+ 	 */
+-	if (irq_kobj_base)
++	if (desc->istate & IRQS_SYSFS)
+ 		kobject_del(&desc->kobj);
+ }
+ 
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index 6d2a8623ec7b5..771fcce54fac0 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -2360,6 +2360,14 @@ static void kill_kprobe(struct kprobe *p)
+ 
+ 	lockdep_assert_held(&kprobe_mutex);
+ 
++	/*
++	 * The module is going away. We should disarm the kprobe which
++	 * is using ftrace, because ftrace framework is still available at
++	 * 'MODULE_STATE_GOING' notification.
++	 */
++	if (kprobe_ftrace(p) && !kprobe_disabled(p) && !kprobes_all_disarmed)
++		disarm_kprobe_ftrace(p);
++
+ 	p->flags |= KPROBE_FLAG_GONE;
+ 	if (kprobe_aggrprobe(p)) {
+ 		/*
+@@ -2376,14 +2384,6 @@ static void kill_kprobe(struct kprobe *p)
+ 	 * the original probed function (which will be freed soon) any more.
+ 	 */
+ 	arch_remove_kprobe(p);
+-
+-	/*
+-	 * The module is going away. We should disarm the kprobe which
+-	 * is using ftrace, because ftrace framework is still available at
+-	 * 'MODULE_STATE_GOING' notification.
+-	 */
+-	if (kprobe_ftrace(p) && !kprobe_disabled(p) && !kprobes_all_disarmed)
+-		disarm_kprobe_ftrace(p);
+ }
+ 
+ /* Disable one kprobe */
+diff --git a/kernel/module/decompress.c b/kernel/module/decompress.c
+index 4d0bcb3d9e449..82c07b1d97975 100644
+--- a/kernel/module/decompress.c
++++ b/kernel/module/decompress.c
+@@ -114,8 +114,8 @@ static ssize_t module_gzip_decompress(struct load_info *info,
+ 	do {
+ 		struct page *page = module_get_next_page(info);
+ 
+-		if (!page) {
+-			retval = -ENOMEM;
++		if (IS_ERR(page)) {
++			retval = PTR_ERR(page);
+ 			goto out_inflate_end;
+ 		}
+ 
+@@ -173,8 +173,8 @@ static ssize_t module_xz_decompress(struct load_info *info,
+ 	do {
+ 		struct page *page = module_get_next_page(info);
+ 
+-		if (!page) {
+-			retval = -ENOMEM;
++		if (IS_ERR(page)) {
++			retval = PTR_ERR(page);
+ 			goto out;
+ 		}
+ 
+diff --git a/kernel/padata.c b/kernel/padata.c
+index e5819bb8bd1dc..de90af5fcbe6b 100644
+--- a/kernel/padata.c
++++ b/kernel/padata.c
+@@ -207,14 +207,16 @@ int padata_do_parallel(struct padata_shell *ps,
+ 	pw = padata_work_alloc();
+ 	spin_unlock(&padata_works_lock);
+ 
++	if (!pw) {
++		/* Maximum works limit exceeded, run in the current task. */
++		padata->parallel(padata);
++	}
++
+ 	rcu_read_unlock_bh();
+ 
+ 	if (pw) {
+ 		padata_work_init(pw, padata_parallel_worker, padata, 0);
+ 		queue_work(pinst->parallel_wq, &pw->pw_work);
+-	} else {
+-		/* Maximum works limit exceeded, run in the current task. */
+-		padata->parallel(padata);
+ 	}
+ 
+ 	return 0;
+@@ -388,13 +390,16 @@ void padata_do_serial(struct padata_priv *padata)
+ 	int hashed_cpu = padata_cpu_hash(pd, padata->seq_nr);
+ 	struct padata_list *reorder = per_cpu_ptr(pd->reorder_list, hashed_cpu);
+ 	struct padata_priv *cur;
++	struct list_head *pos;
+ 
+ 	spin_lock(&reorder->lock);
+ 	/* Sort in ascending order of sequence number. */
+-	list_for_each_entry_reverse(cur, &reorder->list, list)
++	list_for_each_prev(pos, &reorder->list) {
++		cur = list_entry(pos, struct padata_priv, list);
+ 		if (cur->seq_nr < padata->seq_nr)
+ 			break;
+-	list_add(&padata->list, &cur->list);
++	}
++	list_add(&padata->list, pos);
+ 	spin_unlock(&reorder->lock);
+ 
+ 	/*
+diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
+index 2a406753af904..c20ca5fb9adc8 100644
+--- a/kernel/power/snapshot.c
++++ b/kernel/power/snapshot.c
+@@ -1723,8 +1723,8 @@ static unsigned long minimum_image_size(unsigned long saveable)
+  * /sys/power/reserved_size, respectively).  To make this happen, we compute the
+  * total number of available page frames and allocate at least
+  *
+- * ([page frames total] + PAGES_FOR_IO + [metadata pages]) / 2
+- *  + 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE)
++ * ([page frames total] - PAGES_FOR_IO - [metadata pages]) / 2
++ *  - 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE)
+  *
+  * of them, which corresponds to the maximum size of a hibernation image.
+  *
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index 5b52727dcc1c4..aedd43e1f21c4 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -2415,7 +2415,7 @@ void rcu_force_quiescent_state(void)
+ 	struct rcu_node *rnp_old = NULL;
+ 
+ 	/* Funnel through hierarchy to reduce memory contention. */
+-	rnp = __this_cpu_read(rcu_data.mynode);
++	rnp = raw_cpu_read(rcu_data.mynode);
+ 	for (; rnp != NULL; rnp = rnp->parent) {
+ 		ret = (READ_ONCE(rcu_state.gp_flags) & RCU_GP_FLAG_FQS) ||
+ 		       !raw_spin_trylock(&rnp->fqslock);
+diff --git a/kernel/relay.c b/kernel/relay.c
+index 6a611e779e958..fd1d196e04d4f 100644
+--- a/kernel/relay.c
++++ b/kernel/relay.c
+@@ -151,13 +151,13 @@ static struct rchan_buf *relay_create_buf(struct rchan *chan)
+ {
+ 	struct rchan_buf *buf;
+ 
+-	if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t *))
++	if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t))
+ 		return NULL;
+ 
+ 	buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL);
+ 	if (!buf)
+ 		return NULL;
+-	buf->padding = kmalloc_array(chan->n_subbufs, sizeof(size_t *),
++	buf->padding = kmalloc_array(chan->n_subbufs, sizeof(size_t),
+ 				     GFP_KERNEL);
+ 	if (!buf->padding)
+ 		goto free_buf;
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index ee28253c9ac0c..cb9d8ae7c4dbf 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -1398,7 +1398,7 @@ static inline void uclamp_idle_reset(struct rq *rq, enum uclamp_id clamp_id,
+ 	if (!(rq->uclamp_flags & UCLAMP_FLAG_IDLE))
+ 		return;
+ 
+-	WRITE_ONCE(rq->uclamp[clamp_id].value, clamp_value);
++	uclamp_rq_set(rq, clamp_id, clamp_value);
+ }
+ 
+ static inline
+@@ -1549,8 +1549,8 @@ static inline void uclamp_rq_inc_id(struct rq *rq, struct task_struct *p,
+ 	if (bucket->tasks == 1 || uc_se->value > bucket->value)
+ 		bucket->value = uc_se->value;
+ 
+-	if (uc_se->value > READ_ONCE(uc_rq->value))
+-		WRITE_ONCE(uc_rq->value, uc_se->value);
++	if (uc_se->value > uclamp_rq_get(rq, clamp_id))
++		uclamp_rq_set(rq, clamp_id, uc_se->value);
+ }
+ 
+ /*
+@@ -1616,7 +1616,7 @@ static inline void uclamp_rq_dec_id(struct rq *rq, struct task_struct *p,
+ 	if (likely(bucket->tasks))
+ 		return;
+ 
+-	rq_clamp = READ_ONCE(uc_rq->value);
++	rq_clamp = uclamp_rq_get(rq, clamp_id);
+ 	/*
+ 	 * Defensive programming: this should never happen. If it happens,
+ 	 * e.g. due to future modification, warn and fixup the expected value.
+@@ -1624,7 +1624,7 @@ static inline void uclamp_rq_dec_id(struct rq *rq, struct task_struct *p,
+ 	SCHED_WARN_ON(bucket->value > rq_clamp);
+ 	if (bucket->value >= rq_clamp) {
+ 		bkt_clamp = uclamp_rq_max_value(rq, clamp_id, uc_se->value);
+-		WRITE_ONCE(uc_rq->value, bkt_clamp);
++		uclamp_rq_set(rq, clamp_id, bkt_clamp);
+ 	}
+ }
+ 
+diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c
+index 02d970a879edd..57c92d751bcd7 100644
+--- a/kernel/sched/cpudeadline.c
++++ b/kernel/sched/cpudeadline.c
+@@ -123,7 +123,7 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p,
+ 		unsigned long cap, max_cap = 0;
+ 		int cpu, max_cpu = -1;
+ 
+-		if (!static_branch_unlikely(&sched_asym_cpucapacity))
++		if (!sched_asym_cpucap_active())
+ 			return 1;
+ 
+ 		/* Ensure the capacity of the CPUs fits the task. */
+diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
+index 0ab79d819a0d6..8bebc36a1b71b 100644
+--- a/kernel/sched/deadline.c
++++ b/kernel/sched/deadline.c
+@@ -144,7 +144,7 @@ static inline unsigned long __dl_bw_capacity(int i)
+  */
+ static inline unsigned long dl_bw_capacity(int i)
+ {
+-	if (!static_branch_unlikely(&sched_asym_cpucapacity) &&
++	if (!sched_asym_cpucap_active() &&
+ 	    capacity_orig_of(i) == SCHED_CAPACITY_SCALE) {
+ 		return dl_bw_cpus(i) << SCHED_CAPACITY_SHIFT;
+ 	} else {
+@@ -1849,7 +1849,7 @@ select_task_rq_dl(struct task_struct *p, int cpu, int flags)
+ 	 * Take the capacity of the CPU into account to
+ 	 * ensure it fits the requirement of the task.
+ 	 */
+-	if (static_branch_unlikely(&sched_asym_cpucapacity))
++	if (sched_asym_cpucap_active())
+ 		select_rq |= !dl_task_fits_capacity(p, cpu);
+ 
+ 	if (select_rq) {
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 914096c5b1ae1..532e6cdf706d6 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -4108,14 +4108,16 @@ static inline unsigned long task_util_est(struct task_struct *p)
+ }
+ 
+ #ifdef CONFIG_UCLAMP_TASK
+-static inline unsigned long uclamp_task_util(struct task_struct *p)
++static inline unsigned long uclamp_task_util(struct task_struct *p,
++					     unsigned long uclamp_min,
++					     unsigned long uclamp_max)
+ {
+-	return clamp(task_util_est(p),
+-		     uclamp_eff_value(p, UCLAMP_MIN),
+-		     uclamp_eff_value(p, UCLAMP_MAX));
++	return clamp(task_util_est(p), uclamp_min, uclamp_max);
+ }
+ #else
+-static inline unsigned long uclamp_task_util(struct task_struct *p)
++static inline unsigned long uclamp_task_util(struct task_struct *p,
++					     unsigned long uclamp_min,
++					     unsigned long uclamp_max)
+ {
+ 	return task_util_est(p);
+ }
+@@ -4254,15 +4256,140 @@ done:
+ 	trace_sched_util_est_se_tp(&p->se);
+ }
+ 
+-static inline int task_fits_capacity(struct task_struct *p,
+-				     unsigned long capacity)
++static inline int util_fits_cpu(unsigned long util,
++				unsigned long uclamp_min,
++				unsigned long uclamp_max,
++				int cpu)
+ {
+-	return fits_capacity(uclamp_task_util(p), capacity);
++	unsigned long capacity_orig, capacity_orig_thermal;
++	unsigned long capacity = capacity_of(cpu);
++	bool fits, uclamp_max_fits;
++
++	/*
++	 * Check if the real util fits without any uclamp boost/cap applied.
++	 */
++	fits = fits_capacity(util, capacity);
++
++	if (!uclamp_is_used())
++		return fits;
++
++	/*
++	 * We must use capacity_orig_of() for comparing against uclamp_min and
++	 * uclamp_max. We only care about capacity pressure (by using
++	 * capacity_of()) for comparing against the real util.
++	 *
++	 * If a task is boosted to 1024 for example, we don't want a tiny
++	 * pressure to skew the check whether it fits a CPU or not.
++	 *
++	 * Similarly if a task is capped to capacity_orig_of(little_cpu), it
++	 * should fit a little cpu even if there's some pressure.
++	 *
++	 * Only exception is for thermal pressure since it has a direct impact
++	 * on available OPP of the system.
++	 *
++	 * We honour it for uclamp_min only as a drop in performance level
++	 * could result in not getting the requested minimum performance level.
++	 *
++	 * For uclamp_max, we can tolerate a drop in performance level as the
++	 * goal is to cap the task. So it's okay if it's getting less.
++	 *
++	 * In case of capacity inversion, which is not handled yet, we should
++	 * honour the inverted capacity for both uclamp_min and uclamp_max all
++	 * the time.
++	 */
++	capacity_orig = capacity_orig_of(cpu);
++	capacity_orig_thermal = capacity_orig - arch_scale_thermal_pressure(cpu);
++
++	/*
++	 * We want to force a task to fit a cpu as implied by uclamp_max.
++	 * But we do have some corner cases to cater for..
++	 *
++	 *
++	 *                                 C=z
++	 *   |                             ___
++	 *   |                  C=y       |   |
++	 *   |_ _ _ _ _ _ _ _ _ ___ _ _ _ | _ | _ _ _ _ _  uclamp_max
++	 *   |      C=x        |   |      |   |
++	 *   |      ___        |   |      |   |
++	 *   |     |   |       |   |      |   |    (util somewhere in this region)
++	 *   |     |   |       |   |      |   |
++	 *   |     |   |       |   |      |   |
++	 *   +----------------------------------------
++	 *         cpu0        cpu1       cpu2
++	 *
++	 *   In the above example if a task is capped to a specific performance
++	 *   point, y, then when:
++	 *
++	 *   * util = 80% of x then it does not fit on cpu0 and should migrate
++	 *     to cpu1
++	 *   * util = 80% of y then it is forced to fit on cpu1 to honour
++	 *     uclamp_max request.
++	 *
++	 *   which is what we're enforcing here. A task always fits if
++	 *   uclamp_max <= capacity_orig. But when uclamp_max > capacity_orig,
++	 *   the normal upmigration rules should withhold still.
++	 *
++	 *   Only exception is when we are on max capacity, then we need to be
++	 *   careful not to block overutilized state. This is so because:
++	 *
++	 *     1. There's no concept of capping at max_capacity! We can't go
++	 *        beyond this performance level anyway.
++	 *     2. The system is being saturated when we're operating near
++	 *        max capacity, it doesn't make sense to block overutilized.
++	 */
++	uclamp_max_fits = (capacity_orig == SCHED_CAPACITY_SCALE) && (uclamp_max == SCHED_CAPACITY_SCALE);
++	uclamp_max_fits = !uclamp_max_fits && (uclamp_max <= capacity_orig);
++	fits = fits || uclamp_max_fits;
++
++	/*
++	 *
++	 *                                 C=z
++	 *   |                             ___       (region a, capped, util >= uclamp_max)
++	 *   |                  C=y       |   |
++	 *   |_ _ _ _ _ _ _ _ _ ___ _ _ _ | _ | _ _ _ _ _ uclamp_max
++	 *   |      C=x        |   |      |   |
++	 *   |      ___        |   |      |   |      (region b, uclamp_min <= util <= uclamp_max)
++	 *   |_ _ _|_ _|_ _ _ _| _ | _ _ _| _ | _ _ _ _ _ uclamp_min
++	 *   |     |   |       |   |      |   |
++	 *   |     |   |       |   |      |   |      (region c, boosted, util < uclamp_min)
++	 *   +----------------------------------------
++	 *         cpu0        cpu1       cpu2
++	 *
++	 * a) If util > uclamp_max, then we're capped, we don't care about
++	 *    actual fitness value here. We only care if uclamp_max fits
++	 *    capacity without taking margin/pressure into account.
++	 *    See comment above.
++	 *
++	 * b) If uclamp_min <= util <= uclamp_max, then the normal
++	 *    fits_capacity() rules apply. Except we need to ensure that we
++	 *    enforce we remain within uclamp_max, see comment above.
++	 *
++	 * c) If util < uclamp_min, then we are boosted. Same as (b) but we
++	 *    need to take into account the boosted value fits the CPU without
++	 *    taking margin/pressure into account.
++	 *
++	 * Cases (a) and (b) are handled in the 'fits' variable already. We
++	 * just need to consider an extra check for case (c) after ensuring we
++	 * handle the case uclamp_min > uclamp_max.
++	 */
++	uclamp_min = min(uclamp_min, uclamp_max);
++	if (util < uclamp_min && capacity_orig != SCHED_CAPACITY_SCALE)
++		fits = fits && (uclamp_min <= capacity_orig_thermal);
++
++	return fits;
++}
++
++static inline int task_fits_cpu(struct task_struct *p, int cpu)
++{
++	unsigned long uclamp_min = uclamp_eff_value(p, UCLAMP_MIN);
++	unsigned long uclamp_max = uclamp_eff_value(p, UCLAMP_MAX);
++	unsigned long util = task_util_est(p);
++	return util_fits_cpu(util, uclamp_min, uclamp_max, cpu);
+ }
+ 
+ static inline void update_misfit_status(struct task_struct *p, struct rq *rq)
+ {
+-	if (!static_branch_unlikely(&sched_asym_cpucapacity))
++	if (!sched_asym_cpucap_active())
+ 		return;
+ 
+ 	if (!p || p->nr_cpus_allowed == 1) {
+@@ -4270,7 +4397,7 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq)
+ 		return;
+ 	}
+ 
+-	if (task_fits_capacity(p, capacity_of(cpu_of(rq)))) {
++	if (task_fits_cpu(p, cpu_of(rq))) {
+ 		rq->misfit_task_load = 0;
+ 		return;
+ 	}
+@@ -5682,7 +5809,10 @@ static inline void hrtick_update(struct rq *rq)
+ #ifdef CONFIG_SMP
+ static inline bool cpu_overutilized(int cpu)
+ {
+-	return !fits_capacity(cpu_util_cfs(cpu), capacity_of(cpu));
++	unsigned long rq_util_min = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MIN);
++	unsigned long rq_util_max = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MAX);
++
++	return !util_fits_cpu(cpu_util_cfs(cpu), rq_util_min, rq_util_max, cpu);
+ }
+ 
+ static inline void update_overutilized_status(struct rq *rq)
+@@ -6478,21 +6608,23 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool
+ static int
+ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
+ {
+-	unsigned long task_util, best_cap = 0;
++	unsigned long task_util, util_min, util_max, best_cap = 0;
+ 	int cpu, best_cpu = -1;
+ 	struct cpumask *cpus;
+ 
+ 	cpus = this_cpu_cpumask_var_ptr(select_rq_mask);
+ 	cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
+ 
+-	task_util = uclamp_task_util(p);
++	task_util = task_util_est(p);
++	util_min = uclamp_eff_value(p, UCLAMP_MIN);
++	util_max = uclamp_eff_value(p, UCLAMP_MAX);
+ 
+ 	for_each_cpu_wrap(cpu, cpus, target) {
+ 		unsigned long cpu_cap = capacity_of(cpu);
+ 
+ 		if (!available_idle_cpu(cpu) && !sched_idle_cpu(cpu))
+ 			continue;
+-		if (fits_capacity(task_util, cpu_cap))
++		if (util_fits_cpu(task_util, util_min, util_max, cpu))
+ 			return cpu;
+ 
+ 		if (cpu_cap > best_cap) {
+@@ -6504,10 +6636,13 @@ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
+ 	return best_cpu;
+ }
+ 
+-static inline bool asym_fits_capacity(unsigned long task_util, int cpu)
++static inline bool asym_fits_cpu(unsigned long util,
++				 unsigned long util_min,
++				 unsigned long util_max,
++				 int cpu)
+ {
+-	if (static_branch_unlikely(&sched_asym_cpucapacity))
+-		return fits_capacity(task_util, capacity_of(cpu));
++	if (sched_asym_cpucap_active())
++		return util_fits_cpu(util, util_min, util_max, cpu);
+ 
+ 	return true;
+ }
+@@ -6519,16 +6654,18 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ {
+ 	bool has_idle_core = false;
+ 	struct sched_domain *sd;
+-	unsigned long task_util;
++	unsigned long task_util, util_min, util_max;
+ 	int i, recent_used_cpu;
+ 
+ 	/*
+ 	 * On asymmetric system, update task utilization because we will check
+ 	 * that the task fits with cpu's capacity.
+ 	 */
+-	if (static_branch_unlikely(&sched_asym_cpucapacity)) {
++	if (sched_asym_cpucap_active()) {
+ 		sync_entity_load_avg(&p->se);
+-		task_util = uclamp_task_util(p);
++		task_util = task_util_est(p);
++		util_min = uclamp_eff_value(p, UCLAMP_MIN);
++		util_max = uclamp_eff_value(p, UCLAMP_MAX);
+ 	}
+ 
+ 	/*
+@@ -6537,7 +6674,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ 	lockdep_assert_irqs_disabled();
+ 
+ 	if ((available_idle_cpu(target) || sched_idle_cpu(target)) &&
+-	    asym_fits_capacity(task_util, target))
++	    asym_fits_cpu(task_util, util_min, util_max, target))
+ 		return target;
+ 
+ 	/*
+@@ -6545,7 +6682,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ 	 */
+ 	if (prev != target && cpus_share_cache(prev, target) &&
+ 	    (available_idle_cpu(prev) || sched_idle_cpu(prev)) &&
+-	    asym_fits_capacity(task_util, prev))
++	    asym_fits_cpu(task_util, util_min, util_max, prev))
+ 		return prev;
+ 
+ 	/*
+@@ -6560,7 +6697,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ 	    in_task() &&
+ 	    prev == smp_processor_id() &&
+ 	    this_rq()->nr_running <= 1 &&
+-	    asym_fits_capacity(task_util, prev)) {
++	    asym_fits_cpu(task_util, util_min, util_max, prev)) {
+ 		return prev;
+ 	}
+ 
+@@ -6572,7 +6709,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ 	    cpus_share_cache(recent_used_cpu, target) &&
+ 	    (available_idle_cpu(recent_used_cpu) || sched_idle_cpu(recent_used_cpu)) &&
+ 	    cpumask_test_cpu(p->recent_used_cpu, p->cpus_ptr) &&
+-	    asym_fits_capacity(task_util, recent_used_cpu)) {
++	    asym_fits_cpu(task_util, util_min, util_max, recent_used_cpu)) {
+ 		return recent_used_cpu;
+ 	}
+ 
+@@ -6580,7 +6717,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
+ 	 * For asymmetric CPU capacity systems, our domain of interest is
+ 	 * sd_asym_cpucapacity rather than sd_llc.
+ 	 */
+-	if (static_branch_unlikely(&sched_asym_cpucapacity)) {
++	if (sched_asym_cpucap_active()) {
+ 		sd = rcu_dereference(per_cpu(sd_asym_cpucapacity, target));
+ 		/*
+ 		 * On an asymmetric CPU capacity system where an exclusive
+@@ -6868,6 +7005,8 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
+ {
+ 	struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_rq_mask);
+ 	unsigned long prev_delta = ULONG_MAX, best_delta = ULONG_MAX;
++	unsigned long p_util_min = uclamp_is_used() ? uclamp_eff_value(p, UCLAMP_MIN) : 0;
++	unsigned long p_util_max = uclamp_is_used() ? uclamp_eff_value(p, UCLAMP_MAX) : 1024;
+ 	struct root_domain *rd = this_rq()->rd;
+ 	int cpu, best_energy_cpu, target = -1;
+ 	struct sched_domain *sd;
+@@ -6892,7 +7031,7 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
+ 	target = prev_cpu;
+ 
+ 	sync_entity_load_avg(&p->se);
+-	if (!task_util_est(p))
++	if (!uclamp_task_util(p, p_util_min, p_util_max))
+ 		goto unlock;
+ 
+ 	eenv_task_busy_time(&eenv, p, prev_cpu);
+@@ -6900,6 +7039,8 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
+ 	for (; pd; pd = pd->next) {
+ 		unsigned long cpu_cap, cpu_thermal_cap, util;
+ 		unsigned long cur_delta, max_spare_cap = 0;
++		unsigned long rq_util_min, rq_util_max;
++		unsigned long util_min, util_max;
+ 		bool compute_prev_delta = false;
+ 		int max_spare_cap_cpu = -1;
+ 		unsigned long base_energy;
+@@ -6936,8 +7077,26 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
+ 			 * much capacity we can get out of the CPU; this is
+ 			 * aligned with sched_cpu_util().
+ 			 */
+-			util = uclamp_rq_util_with(cpu_rq(cpu), util, p);
+-			if (!fits_capacity(util, cpu_cap))
++			if (uclamp_is_used()) {
++				if (uclamp_rq_is_idle(cpu_rq(cpu))) {
++					util_min = p_util_min;
++					util_max = p_util_max;
++				} else {
++					/*
++					 * Open code uclamp_rq_util_with() except for
++					 * the clamp() part. Ie: apply max aggregation
++					 * only. util_fits_cpu() logic requires to
++					 * operate on non clamped util but must use the
++					 * max-aggregated uclamp_{min, max}.
++					 */
++					rq_util_min = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MIN);
++					rq_util_max = uclamp_rq_get(cpu_rq(cpu), UCLAMP_MAX);
++
++					util_min = max(rq_util_min, p_util_min);
++					util_max = max(rq_util_max, p_util_max);
++				}
++			}
++			if (!util_fits_cpu(util, util_min, util_max, cpu))
+ 				continue;
+ 
+ 			lsub_positive(&cpu_cap, util);
+@@ -8108,7 +8267,7 @@ static int detach_tasks(struct lb_env *env)
+ 
+ 		case migrate_misfit:
+ 			/* This is not a misfit task */
+-			if (task_fits_capacity(p, capacity_of(env->src_cpu)))
++			if (task_fits_cpu(p, env->src_cpu))
+ 				goto next;
+ 
+ 			env->imbalance = 0;
+@@ -9113,6 +9272,10 @@ static inline void update_sg_wakeup_stats(struct sched_domain *sd,
+ 
+ 	memset(sgs, 0, sizeof(*sgs));
+ 
++	/* Assume that task can't fit any CPU of the group */
++	if (sd->flags & SD_ASYM_CPUCAPACITY)
++		sgs->group_misfit_task_load = 1;
++
+ 	for_each_cpu(i, sched_group_span(group)) {
+ 		struct rq *rq = cpu_rq(i);
+ 		unsigned int local;
+@@ -9132,12 +9295,12 @@ static inline void update_sg_wakeup_stats(struct sched_domain *sd,
+ 		if (!nr_running && idle_cpu_without(i, p))
+ 			sgs->idle_cpus++;
+ 
+-	}
++		/* Check if task fits in the CPU */
++		if (sd->flags & SD_ASYM_CPUCAPACITY &&
++		    sgs->group_misfit_task_load &&
++		    task_fits_cpu(p, i))
++			sgs->group_misfit_task_load = 0;
+ 
+-	/* Check if task fits in the group */
+-	if (sd->flags & SD_ASYM_CPUCAPACITY &&
+-	    !task_fits_capacity(p, group->sgc->max_capacity)) {
+-		sgs->group_misfit_task_load = 1;
+ 	}
+ 
+ 	sgs->group_capacity = group->sgc->capacity;
+diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c
+index ecb4b4ff4ce0a..559416a27c0ed 100644
+--- a/kernel/sched/psi.c
++++ b/kernel/sched/psi.c
+@@ -537,10 +537,12 @@ static u64 update_triggers(struct psi_group *group, u64 now)
+ 
+ 			/* Calculate growth since last update */
+ 			growth = window_update(&t->win, now, total[t->state]);
+-			if (growth < t->threshold)
+-				continue;
++			if (!t->pending_event) {
++				if (growth < t->threshold)
++					continue;
+ 
+-			t->pending_event = true;
++				t->pending_event = true;
++			}
+ 		}
+ 		/* Limit event signaling to once per window */
+ 		if (now < t->last_event_time + t->win.size)
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index 55f39c8f42032..054b6711e9619 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -509,7 +509,7 @@ static inline bool rt_task_fits_capacity(struct task_struct *p, int cpu)
+ 	unsigned int cpu_cap;
+ 
+ 	/* Only heterogeneous systems can benefit from this check */
+-	if (!static_branch_unlikely(&sched_asym_cpucapacity))
++	if (!sched_asym_cpucap_active())
+ 		return true;
+ 
+ 	min_cap = uclamp_eff_value(p, UCLAMP_MIN);
+@@ -1897,7 +1897,7 @@ static int find_lowest_rq(struct task_struct *task)
+ 	 * If we're on asym system ensure we consider the different capacities
+ 	 * of the CPUs when searching for the lowest_mask.
+ 	 */
+-	if (static_branch_unlikely(&sched_asym_cpucapacity)) {
++	if (sched_asym_cpucap_active()) {
+ 
+ 		ret = cpupri_find_fitness(&task_rq(task)->rd->cpupri,
+ 					  task, lowest_mask,
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index f34b489636ffb..2fcb7eb56c018 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -1815,6 +1815,11 @@ DECLARE_PER_CPU(struct sched_domain __rcu *, sd_asym_packing);
+ DECLARE_PER_CPU(struct sched_domain __rcu *, sd_asym_cpucapacity);
+ extern struct static_key_false sched_asym_cpucapacity;
+ 
++static __always_inline bool sched_asym_cpucap_active(void)
++{
++	return static_branch_unlikely(&sched_asym_cpucapacity);
++}
++
+ struct sched_group_capacity {
+ 	atomic_t		ref;
+ 	/*
+@@ -2963,6 +2968,23 @@ static inline unsigned long cpu_util_rt(struct rq *rq)
+ #ifdef CONFIG_UCLAMP_TASK
+ unsigned long uclamp_eff_value(struct task_struct *p, enum uclamp_id clamp_id);
+ 
++static inline unsigned long uclamp_rq_get(struct rq *rq,
++					  enum uclamp_id clamp_id)
++{
++	return READ_ONCE(rq->uclamp[clamp_id].value);
++}
++
++static inline void uclamp_rq_set(struct rq *rq, enum uclamp_id clamp_id,
++				 unsigned int value)
++{
++	WRITE_ONCE(rq->uclamp[clamp_id].value, value);
++}
++
++static inline bool uclamp_rq_is_idle(struct rq *rq)
++{
++	return rq->uclamp_flags & UCLAMP_FLAG_IDLE;
++}
++
+ /**
+  * uclamp_rq_util_with - clamp @util with @rq and @p effective uclamp values.
+  * @rq:		The rq to clamp against. Must not be NULL.
+@@ -2998,12 +3020,12 @@ unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
+ 		 * Ignore last runnable task's max clamp, as this task will
+ 		 * reset it. Similarly, no need to read the rq's min clamp.
+ 		 */
+-		if (rq->uclamp_flags & UCLAMP_FLAG_IDLE)
++		if (uclamp_rq_is_idle(rq))
+ 			goto out;
+ 	}
+ 
+-	min_util = max_t(unsigned long, min_util, READ_ONCE(rq->uclamp[UCLAMP_MIN].value));
+-	max_util = max_t(unsigned long, max_util, READ_ONCE(rq->uclamp[UCLAMP_MAX].value));
++	min_util = max_t(unsigned long, min_util, uclamp_rq_get(rq, UCLAMP_MIN));
++	max_util = max_t(unsigned long, max_util, uclamp_rq_get(rq, UCLAMP_MAX));
+ out:
+ 	/*
+ 	 * Since CPU's {min,max}_util clamps are MAX aggregated considering
+@@ -3044,6 +3066,15 @@ static inline bool uclamp_is_used(void)
+ 	return static_branch_likely(&sched_uclamp_used);
+ }
+ #else /* CONFIG_UCLAMP_TASK */
++static inline unsigned long uclamp_eff_value(struct task_struct *p,
++					     enum uclamp_id clamp_id)
++{
++	if (clamp_id == UCLAMP_MIN)
++		return 0;
++
++	return SCHED_CAPACITY_SCALE;
++}
++
+ static inline
+ unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
+ 				  struct task_struct *p)
+@@ -3057,6 +3088,25 @@ static inline bool uclamp_is_used(void)
+ {
+ 	return false;
+ }
++
++static inline unsigned long uclamp_rq_get(struct rq *rq,
++					  enum uclamp_id clamp_id)
++{
++	if (clamp_id == UCLAMP_MIN)
++		return 0;
++
++	return SCHED_CAPACITY_SCALE;
++}
++
++static inline void uclamp_rq_set(struct rq *rq, enum uclamp_id clamp_id,
++				 unsigned int value)
++{
++}
++
++static inline bool uclamp_rq_is_idle(struct rq *rq)
++{
++	return false;
++}
+ #endif /* CONFIG_UCLAMP_TASK */
+ 
+ #ifdef CONFIG_HAVE_SCHED_AVG_IRQ
+diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
+index 7f5eb295fe198..ee22a3b1c1816 100644
+--- a/kernel/trace/blktrace.c
++++ b/kernel/trace/blktrace.c
+@@ -1546,7 +1546,8 @@ blk_trace_event_print_binary(struct trace_iterator *iter, int flags,
+ 
+ static enum print_line_t blk_tracer_print_line(struct trace_iterator *iter)
+ {
+-	if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
++	if ((iter->ent->type != TRACE_BLK) ||
++	    !(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
+ 		return TRACE_TYPE_UNHANDLED;
+ 
+ 	return print_one_line(iter, true);
+diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
+index 49243e8617148..d8406f6f5d399 100644
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -6346,7 +6346,7 @@ enable:
+ 	if (se)
+ 		se->ref++;
+  out:
+-	if (ret == 0)
++	if (ret == 0 && glob[0])
+ 		hist_err_clear();
+ 
+ 	return ret;
+diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c
+index a6621c52ce454..b885b6934893f 100644
+--- a/kernel/trace/trace_events_user.c
++++ b/kernel/trace/trace_events_user.c
+@@ -1127,6 +1127,7 @@ put_user_lock:
+ put_user:
+ 	user_event_destroy_fields(user);
+ 	user_event_destroy_validators(user);
++	kfree(user->call.print_fmt);
+ 	kfree(user);
+ 	return ret;
+ }
+diff --git a/lib/debugobjects.c b/lib/debugobjects.c
+index 337d797a71416..6f8e5dd1dcd0c 100644
+--- a/lib/debugobjects.c
++++ b/lib/debugobjects.c
+@@ -437,6 +437,7 @@ static int object_cpu_offline(unsigned int cpu)
+ 	struct debug_percpu_free *percpu_pool;
+ 	struct hlist_node *tmp;
+ 	struct debug_obj *obj;
++	unsigned long flags;
+ 
+ 	/* Remote access is safe as the CPU is dead already */
+ 	percpu_pool = per_cpu_ptr(&percpu_obj_pool, cpu);
+@@ -444,6 +445,12 @@ static int object_cpu_offline(unsigned int cpu)
+ 		hlist_del(&obj->node);
+ 		kmem_cache_free(obj_cache, obj);
+ 	}
++
++	raw_spin_lock_irqsave(&pool_lock, flags);
++	obj_pool_used -= percpu_pool->obj_free;
++	debug_objects_freed += percpu_pool->obj_free;
++	raw_spin_unlock_irqrestore(&pool_lock, flags);
++
+ 	percpu_pool->obj_free = 0;
+ 
+ 	return 0;
+@@ -1318,6 +1325,8 @@ static int __init debug_objects_replace_static_objects(void)
+ 		hlist_add_head(&obj->node, &objects);
+ 	}
+ 
++	debug_objects_allocated += i;
++
+ 	/*
+ 	 * debug_objects_mem_init() is now called early that only one CPU is up
+ 	 * and interrupts have been disabled, so it is safe to replace the
+@@ -1386,6 +1395,7 @@ void __init debug_objects_mem_init(void)
+ 		debug_objects_enabled = 0;
+ 		kmem_cache_destroy(obj_cache);
+ 		pr_warn("out of memory.\n");
++		return;
+ 	} else
+ 		debug_objects_selftest();
+ 
+diff --git a/lib/fonts/fonts.c b/lib/fonts/fonts.c
+index 5f4b07b56cd9c..9738664386088 100644
+--- a/lib/fonts/fonts.c
++++ b/lib/fonts/fonts.c
+@@ -135,8 +135,8 @@ const struct font_desc *get_default_font(int xres, int yres, u32 font_w,
+ 		if (res > 20)
+ 			c += 20 - res;
+ 
+-		if ((font_w & (1 << (f->width - 1))) &&
+-		    (font_h & (1 << (f->height - 1))))
++		if ((font_w & (1U << (f->width - 1))) &&
++		    (font_h & (1U << (f->height - 1))))
+ 			c += 1000;
+ 
+ 		if (c > cc) {
+diff --git a/lib/notifier-error-inject.c b/lib/notifier-error-inject.c
+index 21016b32d3131..2b24ea6c94979 100644
+--- a/lib/notifier-error-inject.c
++++ b/lib/notifier-error-inject.c
+@@ -15,7 +15,7 @@ static int debugfs_errno_get(void *data, u64 *val)
+ 	return 0;
+ }
+ 
+-DEFINE_SIMPLE_ATTRIBUTE(fops_errno, debugfs_errno_get, debugfs_errno_set,
++DEFINE_SIMPLE_ATTRIBUTE_SIGNED(fops_errno, debugfs_errno_get, debugfs_errno_set,
+ 			"%lld\n");
+ 
+ static struct dentry *debugfs_create_errno(const char *name, umode_t mode,
+diff --git a/lib/test_firmware.c b/lib/test_firmware.c
+index c82b65947ce68..1c5a2adb16ef5 100644
+--- a/lib/test_firmware.c
++++ b/lib/test_firmware.c
+@@ -1491,6 +1491,7 @@ static int __init test_firmware_init(void)
+ 
+ 	rc = misc_register(&test_fw_misc_device);
+ 	if (rc) {
++		__test_firmware_config_free();
+ 		kfree(test_fw_config);
+ 		pr_err("could not register misc device: %d\n", rc);
+ 		return rc;
+diff --git a/mm/gup.c b/mm/gup.c
+index d7f9116fc645c..60d7213ad95b3 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -1058,6 +1058,9 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags)
+ 		if (!(vm_flags & VM_WRITE)) {
+ 			if (!(gup_flags & FOLL_FORCE))
+ 				return -EFAULT;
++			/* hugetlb does not support FOLL_FORCE|FOLL_WRITE. */
++			if (is_vm_hugetlb_page(vma))
++				return -EFAULT;
+ 			/*
+ 			 * We used to let the write,force case do COW in a
+ 			 * VM_MAYWRITE VM_SHARED !VM_WRITE vma, so ptrace could
+diff --git a/net/802/mrp.c b/net/802/mrp.c
+index 35e04cc5390c4..c10a432a5b435 100644
+--- a/net/802/mrp.c
++++ b/net/802/mrp.c
+@@ -606,7 +606,10 @@ static void mrp_join_timer(struct timer_list *t)
+ 	spin_unlock(&app->lock);
+ 
+ 	mrp_queue_xmit(app);
+-	mrp_join_timer_arm(app);
++	spin_lock(&app->lock);
++	if (likely(app->active))
++		mrp_join_timer_arm(app);
++	spin_unlock(&app->lock);
+ }
+ 
+ static void mrp_periodic_timer_arm(struct mrp_applicant *app)
+@@ -620,11 +623,12 @@ static void mrp_periodic_timer(struct timer_list *t)
+ 	struct mrp_applicant *app = from_timer(app, t, periodic_timer);
+ 
+ 	spin_lock(&app->lock);
+-	mrp_mad_event(app, MRP_EVENT_PERIODIC);
+-	mrp_pdu_queue(app);
++	if (likely(app->active)) {
++		mrp_mad_event(app, MRP_EVENT_PERIODIC);
++		mrp_pdu_queue(app);
++		mrp_periodic_timer_arm(app);
++	}
+ 	spin_unlock(&app->lock);
+-
+-	mrp_periodic_timer_arm(app);
+ }
+ 
+ static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset)
+@@ -872,6 +876,7 @@ int mrp_init_applicant(struct net_device *dev, struct mrp_application *appl)
+ 	app->dev = dev;
+ 	app->app = appl;
+ 	app->mad = RB_ROOT;
++	app->active = true;
+ 	spin_lock_init(&app->lock);
+ 	skb_queue_head_init(&app->queue);
+ 	rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app);
+@@ -900,6 +905,9 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl)
+ 
+ 	RCU_INIT_POINTER(port->applicants[appl->type], NULL);
+ 
++	spin_lock_bh(&app->lock);
++	app->active = false;
++	spin_unlock_bh(&app->lock);
+ 	/* Delete timer and generate a final TX event to flush out
+ 	 * all pending messages before the applicant is gone.
+ 	 */
+diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
+index 035812b0461cc..ecdb47712d956 100644
+--- a/net/8021q/vlan_dev.c
++++ b/net/8021q/vlan_dev.c
+@@ -712,13 +712,13 @@ static void vlan_dev_get_stats64(struct net_device *dev,
+ 
+ 		p = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i);
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&p->syncp);
++			start = u64_stats_fetch_begin(&p->syncp);
+ 			rxpackets	= u64_stats_read(&p->rx_packets);
+ 			rxbytes		= u64_stats_read(&p->rx_bytes);
+ 			rxmulticast	= u64_stats_read(&p->rx_multicast);
+ 			txpackets	= u64_stats_read(&p->tx_packets);
+ 			txbytes		= u64_stats_read(&p->tx_bytes);
+-		} while (u64_stats_fetch_retry_irq(&p->syncp, start));
++		} while (u64_stats_fetch_retry(&p->syncp, start));
+ 
+ 		stats->rx_packets	+= rxpackets;
+ 		stats->rx_bytes		+= rxbytes;
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 0a6110e15d0f8..8464d95805d08 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -279,6 +279,11 @@ p9_tag_alloc(struct p9_client *c, int8_t type, unsigned int max_size)
+ 	p9pdu_reset(&req->rc);
+ 	req->t_err = 0;
+ 	req->status = REQ_STATUS_ALLOC;
++	/* refcount needs to be set to 0 before inserting into the idr
++	 * so p9_tag_lookup does not accept a request that is not fully
++	 * initialized. refcount_set to 2 below will mark request ready.
++	 */
++	refcount_set(&req->refcount, 0);
+ 	init_waitqueue_head(&req->wq);
+ 	INIT_LIST_HEAD(&req->req_list);
+ 
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index f26ed278d9e3c..67360444eee6c 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -1817,7 +1817,7 @@ static int hci_create_cis_sync(struct hci_dev *hdev, void *data)
+ 			continue;
+ 
+ 		/* Check if all CIS(s) belonging to a CIG are ready */
+-		if (conn->link->state != BT_CONNECTED ||
++		if (!conn->link || conn->link->state != BT_CONNECTED ||
+ 		    conn->state != BT_CONNECT) {
+ 			cmd.cp.num_cis = 0;
+ 			break;
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index c8ea03edd081f..9f8b49ff2d339 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -2653,7 +2653,7 @@ int hci_register_dev(struct hci_dev *hdev)
+ 
+ 	error = hci_register_suspend_notifier(hdev);
+ 	if (error)
+-		goto err_wqueue;
++		BT_WARN("register suspend notifier failed error:%d\n", error);
+ 
+ 	queue_work(hdev->req_workqueue, &hdev->power_on);
+ 
+@@ -3978,7 +3978,7 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
+ 			*req_complete_skb = bt_cb(skb)->hci.req_complete_skb;
+ 		else
+ 			*req_complete = bt_cb(skb)->hci.req_complete;
+-		kfree_skb(skb);
++		dev_kfree_skb_irq(skb);
+ 	}
+ 	spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
+ }
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index a5e89e1b5452a..117537f3e7ad0 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -3940,7 +3940,7 @@ static int hci_read_local_pairing_opts_sync(struct hci_dev *hdev)
+ /* Get MWS transport configuration if the HCI command is supported */
+ static int hci_get_mws_transport_config_sync(struct hci_dev *hdev)
+ {
+-	if (!(hdev->commands[30] & 0x08))
++	if (!mws_transport_config_capable(hdev))
+ 		return 0;
+ 
+ 	return __hci_cmd_sync_status(hdev, HCI_OP_GET_MWS_TRANSPORT_CONFIG,
+diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c
+index 469a0c95b6e8a..53a796ac078c3 100644
+--- a/net/bluetooth/lib.c
++++ b/net/bluetooth/lib.c
+@@ -170,7 +170,7 @@ __u8 bt_status(int err)
+ 	case -EMLINK:
+ 		return 0x09;
+ 
+-	case EALREADY:
++	case -EALREADY:
+ 		return 0x0b;
+ 
+ 	case -EBUSY:
+@@ -191,7 +191,7 @@ __u8 bt_status(int err)
+ 	case -ECONNABORTED:
+ 		return 0x16;
+ 
+-	case ELOOP:
++	case -ELOOP:
+ 		return 0x17;
+ 
+ 	case -EPROTONOSUPPORT:
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 3d1cd06669688..22bfeb5b2b3bb 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -8385,7 +8385,7 @@ static int add_ext_adv_params(struct sock *sk, struct hci_dev *hdev,
+ 	 * extra parameters we don't know about will be ignored in this request.
+ 	 */
+ 	if (data_len < MGMT_ADD_EXT_ADV_PARAMS_MIN_SIZE)
+-		return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
++		return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_EXT_ADV_PARAMS,
+ 				       MGMT_STATUS_INVALID_PARAMS);
+ 
+ 	flags = __le32_to_cpu(cp->flags);
+diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
+index 7324764384b67..8d6fce9005bdd 100644
+--- a/net/bluetooth/rfcomm/core.c
++++ b/net/bluetooth/rfcomm/core.c
+@@ -590,7 +590,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
+ 
+ 		ret = rfcomm_dlc_send_frag(d, frag);
+ 		if (ret < 0) {
+-			kfree_skb(frag);
++			dev_kfree_skb_irq(frag);
+ 			goto unlock;
+ 		}
+ 
+diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
+index b422238f9f86c..5d53332ea3c9d 100644
+--- a/net/bpf/test_run.c
++++ b/net/bpf/test_run.c
+@@ -939,9 +939,6 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb)
+ {
+ 	struct qdisc_skb_cb *cb = (struct qdisc_skb_cb *)skb->cb;
+ 
+-	if (!skb->len)
+-		return -EINVAL;
+-
+ 	if (!__skb)
+ 		return 0;
+ 
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index db4f2641d1cd1..7e2a9fb5786c9 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -4899,9 +4899,9 @@ void br_multicast_get_stats(const struct net_bridge *br,
+ 		unsigned int start;
+ 
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
++			start = u64_stats_fetch_begin(&cpu_stats->syncp);
+ 			memcpy(&temp, &cpu_stats->mstats, sizeof(temp));
+-		} while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
++		} while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
+ 
+ 		mcast_stats_add_dir(tdst.igmp_v1queries, temp.igmp_v1queries);
+ 		mcast_stats_add_dir(tdst.igmp_v2queries, temp.igmp_v2queries);
+diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
+index 9ffd40b8270c1..bc75fa1e4666a 100644
+--- a/net/bridge/br_vlan.c
++++ b/net/bridge/br_vlan.c
+@@ -1389,12 +1389,12 @@ void br_vlan_get_stats(const struct net_bridge_vlan *v,
+ 
+ 		cpu_stats = per_cpu_ptr(v->stats, i);
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
++			start = u64_stats_fetch_begin(&cpu_stats->syncp);
+ 			rxpackets = u64_stats_read(&cpu_stats->rx_packets);
+ 			rxbytes = u64_stats_read(&cpu_stats->rx_bytes);
+ 			txbytes = u64_stats_read(&cpu_stats->tx_bytes);
+ 			txpackets = u64_stats_read(&cpu_stats->tx_packets);
+-		} while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
++		} while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
+ 
+ 		u64_stats_add(&stats->rx_packets, rxpackets);
+ 		u64_stats_add(&stats->rx_bytes, rxbytes);
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 2c14f48d24573..25c73f9677611 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -10398,24 +10398,16 @@ void netdev_run_todo(void)
+ void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
+ 			     const struct net_device_stats *netdev_stats)
+ {
+-#if BITS_PER_LONG == 64
+-	BUILD_BUG_ON(sizeof(*stats64) < sizeof(*netdev_stats));
+-	memcpy(stats64, netdev_stats, sizeof(*netdev_stats));
+-	/* zero out counters that only exist in rtnl_link_stats64 */
+-	memset((char *)stats64 + sizeof(*netdev_stats), 0,
+-	       sizeof(*stats64) - sizeof(*netdev_stats));
+-#else
+-	size_t i, n = sizeof(*netdev_stats) / sizeof(unsigned long);
+-	const unsigned long *src = (const unsigned long *)netdev_stats;
++	size_t i, n = sizeof(*netdev_stats) / sizeof(atomic_long_t);
++	const atomic_long_t *src = (atomic_long_t *)netdev_stats;
+ 	u64 *dst = (u64 *)stats64;
+ 
+ 	BUILD_BUG_ON(n > sizeof(*stats64) / sizeof(u64));
+ 	for (i = 0; i < n; i++)
+-		dst[i] = src[i];
++		dst[i] = atomic_long_read(&src[i]);
+ 	/* zero out counters that only exist in rtnl_link_stats64 */
+ 	memset((char *)stats64 + n * sizeof(u64), 0,
+ 	       sizeof(*stats64) - n * sizeof(u64));
+-#endif
+ }
+ EXPORT_SYMBOL(netdev_stats_to_stats64);
+ 
+@@ -10496,12 +10488,12 @@ void dev_fetch_sw_netstats(struct rtnl_link_stats64 *s,
+ 
+ 		stats = per_cpu_ptr(netstats, cpu);
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&stats->syncp);
++			start = u64_stats_fetch_begin(&stats->syncp);
+ 			rx_packets = u64_stats_read(&stats->rx_packets);
+ 			rx_bytes   = u64_stats_read(&stats->rx_bytes);
+ 			tx_packets = u64_stats_read(&stats->tx_packets);
+ 			tx_bytes   = u64_stats_read(&stats->tx_bytes);
+-		} while (u64_stats_fetch_retry_irq(&stats->syncp, start));
++		} while (u64_stats_fetch_retry(&stats->syncp, start));
+ 
+ 		s->rx_packets += rx_packets;
+ 		s->rx_bytes   += rx_bytes;
+diff --git a/net/core/devlink.c b/net/core/devlink.c
+index b50bcc18b8d9e..5f894bd20c310 100644
+--- a/net/core/devlink.c
++++ b/net/core/devlink.c
+@@ -1498,10 +1498,13 @@ static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
+ 			continue;
+ 		}
+ 
++		devl_lock(devlink);
+ 		err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
+ 				      NETLINK_CB(cb->skb).portid,
+ 				      cb->nlh->nlmsg_seq, NLM_F_MULTI);
++		devl_unlock(devlink);
+ 		devlink_put(devlink);
++
+ 		if (err)
+ 			goto out;
+ 		idx++;
+@@ -8268,10 +8271,10 @@ static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
+ 
+ 		cpu_stats = per_cpu_ptr(trap_stats, i);
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
++			start = u64_stats_fetch_begin(&cpu_stats->syncp);
+ 			rx_packets = u64_stats_read(&cpu_stats->rx_packets);
+ 			rx_bytes = u64_stats_read(&cpu_stats->rx_bytes);
+-		} while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
++		} while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
+ 
+ 		u64_stats_add(&stats->rx_packets, rx_packets);
+ 		u64_stats_add(&stats->rx_bytes, rx_bytes);
+@@ -11358,8 +11361,10 @@ void devl_region_destroy(struct devlink_region *region)
+ 	devl_assert_locked(devlink);
+ 
+ 	/* Free all snapshots of region */
++	mutex_lock(&region->snapshot_lock);
+ 	list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
+ 		devlink_region_snapshot_del(region, snapshot);
++	mutex_unlock(&region->snapshot_lock);
+ 
+ 	list_del(&region->list);
+ 	mutex_destroy(&region->snapshot_lock);
+diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
+index 75501e1bdd25b..dfcaf61d972c7 100644
+--- a/net/core/drop_monitor.c
++++ b/net/core/drop_monitor.c
+@@ -1432,9 +1432,9 @@ static void net_dm_stats_read(struct net_dm_stats *stats)
+ 		u64 dropped;
+ 
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
++			start = u64_stats_fetch_begin(&cpu_stats->syncp);
+ 			dropped = u64_stats_read(&cpu_stats->dropped);
+-		} while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
++		} while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
+ 
+ 		u64_stats_add(&stats->dropped, dropped);
+ 	}
+@@ -1476,9 +1476,9 @@ static void net_dm_hw_stats_read(struct net_dm_stats *stats)
+ 		u64 dropped;
+ 
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
++			start = u64_stats_fetch_begin(&cpu_stats->syncp);
+ 			dropped = u64_stats_read(&cpu_stats->dropped);
+-		} while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
++		} while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
+ 
+ 		u64_stats_add(&stats->dropped, dropped);
+ 	}
+diff --git a/net/core/filter.c b/net/core/filter.c
+index c191db80ce93c..3aae1885b9702 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -2123,8 +2123,17 @@ static int __bpf_redirect_no_mac(struct sk_buff *skb, struct net_device *dev,
+ {
+ 	unsigned int mlen = skb_network_offset(skb);
+ 
++	if (unlikely(skb->len <= mlen)) {
++		kfree_skb(skb);
++		return -ERANGE;
++	}
++
+ 	if (mlen) {
+ 		__skb_pull(skb, mlen);
++		if (unlikely(!skb->len)) {
++			kfree_skb(skb);
++			return -ERANGE;
++		}
+ 
+ 		/* At ingress, the mac header has already been pulled once.
+ 		 * At egress, skb_pospull_rcsum has to be done in case that
+@@ -2144,7 +2153,7 @@ static int __bpf_redirect_common(struct sk_buff *skb, struct net_device *dev,
+ 				 u32 flags)
+ {
+ 	/* Verify that a link layer header is carried */
+-	if (unlikely(skb->mac_header >= skb->network_header)) {
++	if (unlikely(skb->mac_header >= skb->network_header || skb->len == 0)) {
+ 		kfree_skb(skb);
+ 		return -ERANGE;
+ 	}
+diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c
+index c8d137ef5980e..b71ccaec09914 100644
+--- a/net/core/gen_stats.c
++++ b/net/core/gen_stats.c
+@@ -135,10 +135,10 @@ static void gnet_stats_add_basic_cpu(struct gnet_stats_basic_sync *bstats,
+ 		u64 bytes, packets;
+ 
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&bcpu->syncp);
++			start = u64_stats_fetch_begin(&bcpu->syncp);
+ 			bytes = u64_stats_read(&bcpu->bytes);
+ 			packets = u64_stats_read(&bcpu->packets);
+-		} while (u64_stats_fetch_retry_irq(&bcpu->syncp, start));
++		} while (u64_stats_fetch_retry(&bcpu->syncp, start));
+ 
+ 		t_bytes += bytes;
+ 		t_packets += packets;
+@@ -162,10 +162,10 @@ void gnet_stats_add_basic(struct gnet_stats_basic_sync *bstats,
+ 	}
+ 	do {
+ 		if (running)
+-			start = u64_stats_fetch_begin_irq(&b->syncp);
++			start = u64_stats_fetch_begin(&b->syncp);
+ 		bytes = u64_stats_read(&b->bytes);
+ 		packets = u64_stats_read(&b->packets);
+-	} while (running && u64_stats_fetch_retry_irq(&b->syncp, start));
++	} while (running && u64_stats_fetch_retry(&b->syncp, start));
+ 
+ 	_bstats_update(bstats, bytes, packets);
+ }
+@@ -187,10 +187,10 @@ static void gnet_stats_read_basic(u64 *ret_bytes, u64 *ret_packets,
+ 			u64 bytes, packets;
+ 
+ 			do {
+-				start = u64_stats_fetch_begin_irq(&bcpu->syncp);
++				start = u64_stats_fetch_begin(&bcpu->syncp);
+ 				bytes = u64_stats_read(&bcpu->bytes);
+ 				packets = u64_stats_read(&bcpu->packets);
+-			} while (u64_stats_fetch_retry_irq(&bcpu->syncp, start));
++			} while (u64_stats_fetch_retry(&bcpu->syncp, start));
+ 
+ 			t_bytes += bytes;
+ 			t_packets += packets;
+@@ -201,10 +201,10 @@ static void gnet_stats_read_basic(u64 *ret_bytes, u64 *ret_packets,
+ 	}
+ 	do {
+ 		if (running)
+-			start = u64_stats_fetch_begin_irq(&b->syncp);
++			start = u64_stats_fetch_begin(&b->syncp);
+ 		*ret_bytes = u64_stats_read(&b->bytes);
+ 		*ret_packets = u64_stats_read(&b->packets);
+-	} while (running && u64_stats_fetch_retry_irq(&b->syncp, start));
++	} while (running && u64_stats_fetch_retry(&b->syncp, start));
+ }
+ 
+ static int
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index d9c19ae05fe67..9460998ac6d1e 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -2313,6 +2313,9 @@ void *__pskb_pull_tail(struct sk_buff *skb, int delta)
+ 				insp = list;
+ 			} else {
+ 				/* Eaten partially. */
++				if (skb_is_gso(skb) && !list->head_frag &&
++				    skb_headlen(list))
++					skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+ 
+ 				if (skb_shared(list)) {
+ 					/* Sucks! We need to fork list. :-( */
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index e6b9ced3eda82..53d0251788aa2 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -886,13 +886,16 @@ int sk_psock_msg_verdict(struct sock *sk, struct sk_psock *psock,
+ 	ret = sk_psock_map_verd(ret, msg->sk_redir);
+ 	psock->apply_bytes = msg->apply_bytes;
+ 	if (ret == __SK_REDIRECT) {
+-		if (psock->sk_redir)
++		if (psock->sk_redir) {
+ 			sock_put(psock->sk_redir);
+-		psock->sk_redir = msg->sk_redir;
+-		if (!psock->sk_redir) {
++			psock->sk_redir = NULL;
++		}
++		if (!msg->sk_redir) {
+ 			ret = __SK_DROP;
+ 			goto out;
+ 		}
++		psock->redir_ingress = sk_msg_to_ingress(msg);
++		psock->sk_redir = msg->sk_redir;
+ 		sock_hold(psock->sk_redir);
+ 	}
+ out:
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 788c1372663cb..f0eaa5d406b3f 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1400,7 +1400,7 @@ set_sndbuf:
+ 		break;
+ 		}
+ 	case SO_INCOMING_CPU:
+-		WRITE_ONCE(sk->sk_incoming_cpu, val);
++		reuseport_update_incoming_cpu(sk, val);
+ 		break;
+ 
+ 	case SO_CNX_ADVICE:
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index 632df0c525625..bfc3001032129 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -349,11 +349,13 @@ static void sock_map_free(struct bpf_map *map)
+ 
+ 		sk = xchg(psk, NULL);
+ 		if (sk) {
++			sock_hold(sk);
+ 			lock_sock(sk);
+ 			rcu_read_lock();
+ 			sock_map_unref(sk, psk);
+ 			rcu_read_unlock();
+ 			release_sock(sk);
++			sock_put(sk);
+ 		}
+ 	}
+ 
+diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
+index fb90e1e00773b..5a165286e4d8e 100644
+--- a/net/core/sock_reuseport.c
++++ b/net/core/sock_reuseport.c
+@@ -37,6 +37,70 @@ void reuseport_has_conns_set(struct sock *sk)
+ }
+ EXPORT_SYMBOL(reuseport_has_conns_set);
+ 
++static void __reuseport_get_incoming_cpu(struct sock_reuseport *reuse)
++{
++	/* Paired with READ_ONCE() in reuseport_select_sock_by_hash(). */
++	WRITE_ONCE(reuse->incoming_cpu, reuse->incoming_cpu + 1);
++}
++
++static void __reuseport_put_incoming_cpu(struct sock_reuseport *reuse)
++{
++	/* Paired with READ_ONCE() in reuseport_select_sock_by_hash(). */
++	WRITE_ONCE(reuse->incoming_cpu, reuse->incoming_cpu - 1);
++}
++
++static void reuseport_get_incoming_cpu(struct sock *sk, struct sock_reuseport *reuse)
++{
++	if (sk->sk_incoming_cpu >= 0)
++		__reuseport_get_incoming_cpu(reuse);
++}
++
++static void reuseport_put_incoming_cpu(struct sock *sk, struct sock_reuseport *reuse)
++{
++	if (sk->sk_incoming_cpu >= 0)
++		__reuseport_put_incoming_cpu(reuse);
++}
++
++void reuseport_update_incoming_cpu(struct sock *sk, int val)
++{
++	struct sock_reuseport *reuse;
++	int old_sk_incoming_cpu;
++
++	if (unlikely(!rcu_access_pointer(sk->sk_reuseport_cb))) {
++		/* Paired with REAE_ONCE() in sk_incoming_cpu_update()
++		 * and compute_score().
++		 */
++		WRITE_ONCE(sk->sk_incoming_cpu, val);
++		return;
++	}
++
++	spin_lock_bh(&reuseport_lock);
++
++	/* This must be done under reuseport_lock to avoid a race with
++	 * reuseport_grow(), which accesses sk->sk_incoming_cpu without
++	 * lock_sock() when detaching a shutdown()ed sk.
++	 *
++	 * Paired with READ_ONCE() in reuseport_select_sock_by_hash().
++	 */
++	old_sk_incoming_cpu = sk->sk_incoming_cpu;
++	WRITE_ONCE(sk->sk_incoming_cpu, val);
++
++	reuse = rcu_dereference_protected(sk->sk_reuseport_cb,
++					  lockdep_is_held(&reuseport_lock));
++
++	/* reuseport_grow() has detached a closed sk. */
++	if (!reuse)
++		goto out;
++
++	if (old_sk_incoming_cpu < 0 && val >= 0)
++		__reuseport_get_incoming_cpu(reuse);
++	else if (old_sk_incoming_cpu >= 0 && val < 0)
++		__reuseport_put_incoming_cpu(reuse);
++
++out:
++	spin_unlock_bh(&reuseport_lock);
++}
++
+ static int reuseport_sock_index(struct sock *sk,
+ 				const struct sock_reuseport *reuse,
+ 				bool closed)
+@@ -64,6 +128,7 @@ static void __reuseport_add_sock(struct sock *sk,
+ 	/* paired with smp_rmb() in reuseport_(select|migrate)_sock() */
+ 	smp_wmb();
+ 	reuse->num_socks++;
++	reuseport_get_incoming_cpu(sk, reuse);
+ }
+ 
+ static bool __reuseport_detach_sock(struct sock *sk,
+@@ -76,6 +141,7 @@ static bool __reuseport_detach_sock(struct sock *sk,
+ 
+ 	reuse->socks[i] = reuse->socks[reuse->num_socks - 1];
+ 	reuse->num_socks--;
++	reuseport_put_incoming_cpu(sk, reuse);
+ 
+ 	return true;
+ }
+@@ -86,6 +152,7 @@ static void __reuseport_add_closed_sock(struct sock *sk,
+ 	reuse->socks[reuse->max_socks - reuse->num_closed_socks - 1] = sk;
+ 	/* paired with READ_ONCE() in inet_csk_bind_conflict() */
+ 	WRITE_ONCE(reuse->num_closed_socks, reuse->num_closed_socks + 1);
++	reuseport_get_incoming_cpu(sk, reuse);
+ }
+ 
+ static bool __reuseport_detach_closed_sock(struct sock *sk,
+@@ -99,6 +166,7 @@ static bool __reuseport_detach_closed_sock(struct sock *sk,
+ 	reuse->socks[i] = reuse->socks[reuse->max_socks - reuse->num_closed_socks];
+ 	/* paired with READ_ONCE() in inet_csk_bind_conflict() */
+ 	WRITE_ONCE(reuse->num_closed_socks, reuse->num_closed_socks - 1);
++	reuseport_put_incoming_cpu(sk, reuse);
+ 
+ 	return true;
+ }
+@@ -166,6 +234,7 @@ int reuseport_alloc(struct sock *sk, bool bind_inany)
+ 	reuse->bind_inany = bind_inany;
+ 	reuse->socks[0] = sk;
+ 	reuse->num_socks = 1;
++	reuseport_get_incoming_cpu(sk, reuse);
+ 	rcu_assign_pointer(sk->sk_reuseport_cb, reuse);
+ 
+ out:
+@@ -209,6 +278,7 @@ static struct sock_reuseport *reuseport_grow(struct sock_reuseport *reuse)
+ 	more_reuse->reuseport_id = reuse->reuseport_id;
+ 	more_reuse->bind_inany = reuse->bind_inany;
+ 	more_reuse->has_conns = reuse->has_conns;
++	more_reuse->incoming_cpu = reuse->incoming_cpu;
+ 
+ 	memcpy(more_reuse->socks, reuse->socks,
+ 	       reuse->num_socks * sizeof(struct sock *));
+@@ -458,18 +528,32 @@ static struct sock *run_bpf_filter(struct sock_reuseport *reuse, u16 socks,
+ static struct sock *reuseport_select_sock_by_hash(struct sock_reuseport *reuse,
+ 						  u32 hash, u16 num_socks)
+ {
++	struct sock *first_valid_sk = NULL;
+ 	int i, j;
+ 
+ 	i = j = reciprocal_scale(hash, num_socks);
+-	while (reuse->socks[i]->sk_state == TCP_ESTABLISHED) {
++	do {
++		struct sock *sk = reuse->socks[i];
++
++		if (sk->sk_state != TCP_ESTABLISHED) {
++			/* Paired with WRITE_ONCE() in __reuseport_(get|put)_incoming_cpu(). */
++			if (!READ_ONCE(reuse->incoming_cpu))
++				return sk;
++
++			/* Paired with WRITE_ONCE() in reuseport_update_incoming_cpu(). */
++			if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
++				return sk;
++
++			if (!first_valid_sk)
++				first_valid_sk = sk;
++		}
++
+ 		i++;
+ 		if (i >= num_socks)
+ 			i = 0;
+-		if (i == j)
+-			return NULL;
+-	}
++	} while (i != j);
+ 
+-	return reuse->socks[i];
++	return first_valid_sk;
+ }
+ 
+ /**
+diff --git a/net/core/stream.c b/net/core/stream.c
+index 1105057ce00a5..2d03810841cbc 100644
+--- a/net/core/stream.c
++++ b/net/core/stream.c
+@@ -196,6 +196,12 @@ void sk_stream_kill_queues(struct sock *sk)
+ 	/* First the read buffer. */
+ 	__skb_queue_purge(&sk->sk_receive_queue);
+ 
++	/* Next, the error queue.
++	 * We need to use queue lock, because other threads might
++	 * add packets to the queue without socket lock being held.
++	 */
++	skb_queue_purge(&sk->sk_error_queue);
++
+ 	/* Next, the write queue. */
+ 	WARN_ON_ONCE(!skb_queue_empty(&sk->sk_write_queue));
+ 
+diff --git a/net/dsa/slave.c b/net/dsa/slave.c
+index 1291c2431d440..dcc550b871623 100644
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -934,12 +934,12 @@ static void dsa_slave_get_ethtool_stats(struct net_device *dev,
+ 
+ 		s = per_cpu_ptr(dev->tstats, i);
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&s->syncp);
++			start = u64_stats_fetch_begin(&s->syncp);
+ 			tx_packets = u64_stats_read(&s->tx_packets);
+ 			tx_bytes = u64_stats_read(&s->tx_bytes);
+ 			rx_packets = u64_stats_read(&s->rx_packets);
+ 			rx_bytes = u64_stats_read(&s->rx_bytes);
+-		} while (u64_stats_fetch_retry_irq(&s->syncp, start));
++		} while (u64_stats_fetch_retry(&s->syncp, start));
+ 		data[0] += tx_packets;
+ 		data[1] += tx_bytes;
+ 		data[2] += rx_packets;
+diff --git a/net/dsa/tag_8021q.c b/net/dsa/tag_8021q.c
+index 01a427800797c..6de53f5b40a7a 100644
+--- a/net/dsa/tag_8021q.c
++++ b/net/dsa/tag_8021q.c
+@@ -400,6 +400,7 @@ static void dsa_tag_8021q_teardown(struct dsa_switch *ds)
+ int dsa_tag_8021q_register(struct dsa_switch *ds, __be16 proto)
+ {
+ 	struct dsa_8021q_context *ctx;
++	int err;
+ 
+ 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ 	if (!ctx)
+@@ -412,7 +413,15 @@ int dsa_tag_8021q_register(struct dsa_switch *ds, __be16 proto)
+ 
+ 	ds->tag_8021q_ctx = ctx;
+ 
+-	return dsa_tag_8021q_setup(ds);
++	err = dsa_tag_8021q_setup(ds);
++	if (err)
++		goto err_free;
++
++	return 0;
++
++err_free:
++	kfree(ctx);
++	return err;
+ }
+ EXPORT_SYMBOL_GPL(dsa_tag_8021q_register);
+ 
+diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
+index 6a7308de192d9..6b59e7a1c9063 100644
+--- a/net/ethtool/ioctl.c
++++ b/net/ethtool/ioctl.c
+@@ -2007,7 +2007,8 @@ static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
+ 	} else {
+ 		/* Driver expects to be called at twice the frequency in rc */
+ 		int n = rc * 2, interval = HZ / n;
+-		u64 count = n * id.data, i = 0;
++		u64 count = mul_u32_u32(n, id.data);
++		u64 i = 0;
+ 
+ 		do {
+ 			rtnl_lock();
+diff --git a/net/hsr/hsr_debugfs.c b/net/hsr/hsr_debugfs.c
+index de476a4176314..1a195efc79cd1 100644
+--- a/net/hsr/hsr_debugfs.c
++++ b/net/hsr/hsr_debugfs.c
+@@ -9,7 +9,6 @@
+ #include <linux/module.h>
+ #include <linux/errno.h>
+ #include <linux/debugfs.h>
+-#include <linux/jhash.h>
+ #include "hsr_main.h"
+ #include "hsr_framereg.h"
+ 
+@@ -21,7 +20,6 @@ hsr_node_table_show(struct seq_file *sfp, void *data)
+ {
+ 	struct hsr_priv *priv = (struct hsr_priv *)sfp->private;
+ 	struct hsr_node *node;
+-	int i;
+ 
+ 	seq_printf(sfp, "Node Table entries for (%s) device\n",
+ 		   (priv->prot_version == PRP_V1 ? "PRP" : "HSR"));
+@@ -33,28 +31,22 @@ hsr_node_table_show(struct seq_file *sfp, void *data)
+ 		seq_puts(sfp, "DAN-H\n");
+ 
+ 	rcu_read_lock();
+-
+-	for (i = 0 ; i < priv->hash_buckets; i++) {
+-		hlist_for_each_entry_rcu(node, &priv->node_db[i], mac_list) {
+-			/* skip self node */
+-			if (hsr_addr_is_self(priv, node->macaddress_A))
+-				continue;
+-			seq_printf(sfp, "%pM ", &node->macaddress_A[0]);
+-			seq_printf(sfp, "%pM ", &node->macaddress_B[0]);
+-			seq_printf(sfp, "%10lx, ",
+-				   node->time_in[HSR_PT_SLAVE_A]);
+-			seq_printf(sfp, "%10lx, ",
+-				   node->time_in[HSR_PT_SLAVE_B]);
+-			seq_printf(sfp, "%14x, ", node->addr_B_port);
+-
+-			if (priv->prot_version == PRP_V1)
+-				seq_printf(sfp, "%5x, %5x, %5x\n",
+-					   node->san_a, node->san_b,
+-					   (node->san_a == 0 &&
+-					    node->san_b == 0));
+-			else
+-				seq_printf(sfp, "%5x\n", 1);
+-		}
++	list_for_each_entry_rcu(node, &priv->node_db, mac_list) {
++		/* skip self node */
++		if (hsr_addr_is_self(priv, node->macaddress_A))
++			continue;
++		seq_printf(sfp, "%pM ", &node->macaddress_A[0]);
++		seq_printf(sfp, "%pM ", &node->macaddress_B[0]);
++		seq_printf(sfp, "%10lx, ", node->time_in[HSR_PT_SLAVE_A]);
++		seq_printf(sfp, "%10lx, ", node->time_in[HSR_PT_SLAVE_B]);
++		seq_printf(sfp, "%14x, ", node->addr_B_port);
++
++		if (priv->prot_version == PRP_V1)
++			seq_printf(sfp, "%5x, %5x, %5x\n",
++				   node->san_a, node->san_b,
++				   (node->san_a == 0 && node->san_b == 0));
++		else
++			seq_printf(sfp, "%5x\n", 1);
+ 	}
+ 	rcu_read_unlock();
+ 	return 0;
+diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c
+index 6ffef47e9be55..b1e86a7265b32 100644
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -219,7 +219,9 @@ static netdev_tx_t hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev)
+ 		skb->dev = master->dev;
+ 		skb_reset_mac_header(skb);
+ 		skb_reset_mac_len(skb);
++		spin_lock_bh(&hsr->seqnr_lock);
+ 		hsr_forward_skb(skb, master);
++		spin_unlock_bh(&hsr->seqnr_lock);
+ 	} else {
+ 		dev_core_stats_tx_dropped_inc(dev);
+ 		dev_kfree_skb_any(skb);
+@@ -278,7 +280,6 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+ 	__u8 type = HSR_TLV_LIFE_CHECK;
+ 	struct hsr_sup_payload *hsr_sp;
+ 	struct hsr_sup_tag *hsr_stag;
+-	unsigned long irqflags;
+ 	struct sk_buff *skb;
+ 
+ 	*interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL);
+@@ -299,7 +300,7 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+ 	set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version);
+ 
+ 	/* From HSRv1 on we have separate supervision sequence numbers. */
+-	spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags);
++	spin_lock_bh(&hsr->seqnr_lock);
+ 	if (hsr->prot_version > 0) {
+ 		hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr);
+ 		hsr->sup_sequence_nr++;
+@@ -307,7 +308,6 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+ 		hsr_stag->sequence_nr = htons(hsr->sequence_nr);
+ 		hsr->sequence_nr++;
+ 	}
+-	spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
+ 
+ 	hsr_stag->tlv.HSR_TLV_type = type;
+ 	/* TODO: Why 12 in HSRv0? */
+@@ -318,11 +318,13 @@ static void send_hsr_supervision_frame(struct hsr_port *master,
+ 	hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));
+ 	ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr);
+ 
+-	if (skb_put_padto(skb, ETH_ZLEN))
++	if (skb_put_padto(skb, ETH_ZLEN)) {
++		spin_unlock_bh(&hsr->seqnr_lock);
+ 		return;
++	}
+ 
+ 	hsr_forward_skb(skb, master);
+-
++	spin_unlock_bh(&hsr->seqnr_lock);
+ 	return;
+ }
+ 
+@@ -332,7 +334,6 @@ static void send_prp_supervision_frame(struct hsr_port *master,
+ 	struct hsr_priv *hsr = master->hsr;
+ 	struct hsr_sup_payload *hsr_sp;
+ 	struct hsr_sup_tag *hsr_stag;
+-	unsigned long irqflags;
+ 	struct sk_buff *skb;
+ 
+ 	skb = hsr_init_skb(master);
+@@ -347,7 +348,7 @@ static void send_prp_supervision_frame(struct hsr_port *master,
+ 	set_hsr_stag_HSR_ver(hsr_stag, (hsr->prot_version ? 1 : 0));
+ 
+ 	/* From HSRv1 on we have separate supervision sequence numbers. */
+-	spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags);
++	spin_lock_bh(&hsr->seqnr_lock);
+ 	hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr);
+ 	hsr->sup_sequence_nr++;
+ 	hsr_stag->tlv.HSR_TLV_type = PRP_TLV_LIFE_CHECK_DD;
+@@ -358,13 +359,12 @@ static void send_prp_supervision_frame(struct hsr_port *master,
+ 	ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr);
+ 
+ 	if (skb_put_padto(skb, ETH_ZLEN)) {
+-		spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
++		spin_unlock_bh(&hsr->seqnr_lock);
+ 		return;
+ 	}
+ 
+-	spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags);
+-
+ 	hsr_forward_skb(skb, master);
++	spin_unlock_bh(&hsr->seqnr_lock);
+ }
+ 
+ /* Announce (supervision frame) timer function
+@@ -444,7 +444,7 @@ void hsr_dev_setup(struct net_device *dev)
+ 	dev->header_ops = &hsr_header_ops;
+ 	dev->netdev_ops = &hsr_device_ops;
+ 	SET_NETDEV_DEVTYPE(dev, &hsr_type);
+-	dev->priv_flags |= IFF_NO_QUEUE;
++	dev->priv_flags |= IFF_NO_QUEUE | IFF_DISABLE_NETPOLL;
+ 
+ 	dev->needs_free_netdev = true;
+ 
+@@ -485,16 +485,12 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
+ {
+ 	bool unregister = false;
+ 	struct hsr_priv *hsr;
+-	int res, i;
++	int res;
+ 
+ 	hsr = netdev_priv(hsr_dev);
+ 	INIT_LIST_HEAD(&hsr->ports);
+-	INIT_HLIST_HEAD(&hsr->self_node_db);
+-	hsr->hash_buckets = HSR_HSIZE;
+-	get_random_bytes(&hsr->hash_seed, sizeof(hsr->hash_seed));
+-	for (i = 0; i < hsr->hash_buckets; i++)
+-		INIT_HLIST_HEAD(&hsr->node_db[i]);
+-
++	INIT_LIST_HEAD(&hsr->node_db);
++	INIT_LIST_HEAD(&hsr->self_node_db);
+ 	spin_lock_init(&hsr->list_lock);
+ 
+ 	eth_hw_addr_set(hsr_dev, slave[0]->dev_addr);
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index 56bb27d67a2ee..629daacc96071 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -500,7 +500,6 @@ static void handle_std_frame(struct sk_buff *skb,
+ {
+ 	struct hsr_port *port = frame->port_rcv;
+ 	struct hsr_priv *hsr = port->hsr;
+-	unsigned long irqflags;
+ 
+ 	frame->skb_hsr = NULL;
+ 	frame->skb_prp = NULL;
+@@ -510,10 +509,9 @@ static void handle_std_frame(struct sk_buff *skb,
+ 		frame->is_from_san = true;
+ 	} else {
+ 		/* Sequence nr for the master node */
+-		spin_lock_irqsave(&hsr->seqnr_lock, irqflags);
++		lockdep_assert_held(&hsr->seqnr_lock);
+ 		frame->sequence_nr = hsr->sequence_nr;
+ 		hsr->sequence_nr++;
+-		spin_unlock_irqrestore(&hsr->seqnr_lock, irqflags);
+ 	}
+ }
+ 
+@@ -571,23 +569,20 @@ static int fill_frame_info(struct hsr_frame_info *frame,
+ 	struct ethhdr *ethhdr;
+ 	__be16 proto;
+ 	int ret;
+-	u32 hash;
+ 
+ 	/* Check if skb contains ethhdr */
+ 	if (skb->mac_len < sizeof(struct ethhdr))
+ 		return -EINVAL;
+ 
+ 	memset(frame, 0, sizeof(*frame));
+-
+-	ethhdr = (struct ethhdr *)skb_mac_header(skb);
+-	hash = hsr_mac_hash(port->hsr, ethhdr->h_source);
+ 	frame->is_supervision = is_supervision_frame(port->hsr, skb);
+-	frame->node_src = hsr_get_node(port, &hsr->node_db[hash], skb,
++	frame->node_src = hsr_get_node(port, &hsr->node_db, skb,
+ 				       frame->is_supervision,
+ 				       port->type);
+ 	if (!frame->node_src)
+ 		return -1; /* Unknown node and !is_supervision, or no mem */
+ 
++	ethhdr = (struct ethhdr *)skb_mac_header(skb);
+ 	frame->is_vlan = false;
+ 	proto = ethhdr->h_proto;
+ 
+@@ -617,11 +612,13 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)
+ {
+ 	struct hsr_frame_info frame;
+ 
++	rcu_read_lock();
+ 	if (fill_frame_info(&frame, skb, port) < 0)
+ 		goto out_drop;
+ 
+ 	hsr_register_frame_in(frame.node_src, port, frame.sequence_nr);
+ 	hsr_forward_do(&frame);
++	rcu_read_unlock();
+ 	/* Gets called for ingress frames as well as egress from master port.
+ 	 * So check and increment stats for master port only here.
+ 	 */
+@@ -636,6 +633,7 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)
+ 	return;
+ 
+ out_drop:
++	rcu_read_unlock();
+ 	port->dev->stats.tx_dropped++;
+ 	kfree_skb(skb);
+ }
+diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
+index 584e217887997..39a6088080e93 100644
+--- a/net/hsr/hsr_framereg.c
++++ b/net/hsr/hsr_framereg.c
+@@ -15,37 +15,10 @@
+ #include <linux/etherdevice.h>
+ #include <linux/slab.h>
+ #include <linux/rculist.h>
+-#include <linux/jhash.h>
+ #include "hsr_main.h"
+ #include "hsr_framereg.h"
+ #include "hsr_netlink.h"
+ 
+-#ifdef CONFIG_LOCKDEP
+-int lockdep_hsr_is_held(spinlock_t *lock)
+-{
+-	return lockdep_is_held(lock);
+-}
+-#endif
+-
+-u32 hsr_mac_hash(struct hsr_priv *hsr, const unsigned char *addr)
+-{
+-	u32 hash = jhash(addr, ETH_ALEN, hsr->hash_seed);
+-
+-	return reciprocal_scale(hash, hsr->hash_buckets);
+-}
+-
+-struct hsr_node *hsr_node_get_first(struct hlist_head *head, spinlock_t *lock)
+-{
+-	struct hlist_node *first;
+-
+-	first = rcu_dereference_bh_check(hlist_first_rcu(head),
+-					 lockdep_hsr_is_held(lock));
+-	if (first)
+-		return hlist_entry(first, struct hsr_node, mac_list);
+-
+-	return NULL;
+-}
+-
+ /* seq_nr_after(a, b) - return true if a is after (higher in sequence than) b,
+  * false otherwise.
+  */
+@@ -67,7 +40,8 @@ bool hsr_addr_is_self(struct hsr_priv *hsr, unsigned char *addr)
+ {
+ 	struct hsr_node *node;
+ 
+-	node = hsr_node_get_first(&hsr->self_node_db, &hsr->list_lock);
++	node = list_first_or_null_rcu(&hsr->self_node_db, struct hsr_node,
++				      mac_list);
+ 	if (!node) {
+ 		WARN_ONCE(1, "HSR: No self node\n");
+ 		return false;
+@@ -83,12 +57,12 @@ bool hsr_addr_is_self(struct hsr_priv *hsr, unsigned char *addr)
+ 
+ /* Search for mac entry. Caller must hold rcu read lock.
+  */
+-static struct hsr_node *find_node_by_addr_A(struct hlist_head *node_db,
++static struct hsr_node *find_node_by_addr_A(struct list_head *node_db,
+ 					    const unsigned char addr[ETH_ALEN])
+ {
+ 	struct hsr_node *node;
+ 
+-	hlist_for_each_entry_rcu(node, node_db, mac_list) {
++	list_for_each_entry_rcu(node, node_db, mac_list) {
+ 		if (ether_addr_equal(node->macaddress_A, addr))
+ 			return node;
+ 	}
+@@ -103,7 +77,7 @@ int hsr_create_self_node(struct hsr_priv *hsr,
+ 			 const unsigned char addr_a[ETH_ALEN],
+ 			 const unsigned char addr_b[ETH_ALEN])
+ {
+-	struct hlist_head *self_node_db = &hsr->self_node_db;
++	struct list_head *self_node_db = &hsr->self_node_db;
+ 	struct hsr_node *node, *oldnode;
+ 
+ 	node = kmalloc(sizeof(*node), GFP_KERNEL);
+@@ -114,13 +88,14 @@ int hsr_create_self_node(struct hsr_priv *hsr,
+ 	ether_addr_copy(node->macaddress_B, addr_b);
+ 
+ 	spin_lock_bh(&hsr->list_lock);
+-	oldnode = hsr_node_get_first(self_node_db, &hsr->list_lock);
++	oldnode = list_first_or_null_rcu(self_node_db,
++					 struct hsr_node, mac_list);
+ 	if (oldnode) {
+-		hlist_replace_rcu(&oldnode->mac_list, &node->mac_list);
++		list_replace_rcu(&oldnode->mac_list, &node->mac_list);
+ 		spin_unlock_bh(&hsr->list_lock);
+ 		kfree_rcu(oldnode, rcu_head);
+ 	} else {
+-		hlist_add_tail_rcu(&node->mac_list, self_node_db);
++		list_add_tail_rcu(&node->mac_list, self_node_db);
+ 		spin_unlock_bh(&hsr->list_lock);
+ 	}
+ 
+@@ -129,25 +104,25 @@ int hsr_create_self_node(struct hsr_priv *hsr,
+ 
+ void hsr_del_self_node(struct hsr_priv *hsr)
+ {
+-	struct hlist_head *self_node_db = &hsr->self_node_db;
++	struct list_head *self_node_db = &hsr->self_node_db;
+ 	struct hsr_node *node;
+ 
+ 	spin_lock_bh(&hsr->list_lock);
+-	node = hsr_node_get_first(self_node_db, &hsr->list_lock);
++	node = list_first_or_null_rcu(self_node_db, struct hsr_node, mac_list);
+ 	if (node) {
+-		hlist_del_rcu(&node->mac_list);
++		list_del_rcu(&node->mac_list);
+ 		kfree_rcu(node, rcu_head);
+ 	}
+ 	spin_unlock_bh(&hsr->list_lock);
+ }
+ 
+-void hsr_del_nodes(struct hlist_head *node_db)
++void hsr_del_nodes(struct list_head *node_db)
+ {
+ 	struct hsr_node *node;
+-	struct hlist_node *tmp;
++	struct hsr_node *tmp;
+ 
+-	hlist_for_each_entry_safe(node, tmp, node_db, mac_list)
+-		kfree_rcu(node, rcu_head);
++	list_for_each_entry_safe(node, tmp, node_db, mac_list)
++		kfree(node);
+ }
+ 
+ void prp_handle_san_frame(bool san, enum hsr_port_type port,
+@@ -168,7 +143,7 @@ void prp_handle_san_frame(bool san, enum hsr_port_type port,
+  * originating from the newly added node.
+  */
+ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr,
+-				     struct hlist_head *node_db,
++				     struct list_head *node_db,
+ 				     unsigned char addr[],
+ 				     u16 seq_out, bool san,
+ 				     enum hsr_port_type rx_port)
+@@ -182,6 +157,7 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr,
+ 		return NULL;
+ 
+ 	ether_addr_copy(new_node->macaddress_A, addr);
++	spin_lock_init(&new_node->seq_out_lock);
+ 
+ 	/* We are only interested in time diffs here, so use current jiffies
+ 	 * as initialization. (0 could trigger an spurious ring error warning).
+@@ -198,14 +174,14 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr,
+ 		hsr->proto_ops->handle_san_frame(san, rx_port, new_node);
+ 
+ 	spin_lock_bh(&hsr->list_lock);
+-	hlist_for_each_entry_rcu(node, node_db, mac_list,
+-				 lockdep_hsr_is_held(&hsr->list_lock)) {
++	list_for_each_entry_rcu(node, node_db, mac_list,
++				lockdep_is_held(&hsr->list_lock)) {
+ 		if (ether_addr_equal(node->macaddress_A, addr))
+ 			goto out;
+ 		if (ether_addr_equal(node->macaddress_B, addr))
+ 			goto out;
+ 	}
+-	hlist_add_tail_rcu(&new_node->mac_list, node_db);
++	list_add_tail_rcu(&new_node->mac_list, node_db);
+ 	spin_unlock_bh(&hsr->list_lock);
+ 	return new_node;
+ out:
+@@ -225,7 +201,7 @@ void prp_update_san_info(struct hsr_node *node, bool is_sup)
+ 
+ /* Get the hsr_node from which 'skb' was sent.
+  */
+-struct hsr_node *hsr_get_node(struct hsr_port *port, struct hlist_head *node_db,
++struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db,
+ 			      struct sk_buff *skb, bool is_sup,
+ 			      enum hsr_port_type rx_port)
+ {
+@@ -241,7 +217,7 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct hlist_head *node_db,
+ 
+ 	ethhdr = (struct ethhdr *)skb_mac_header(skb);
+ 
+-	hlist_for_each_entry_rcu(node, node_db, mac_list) {
++	list_for_each_entry_rcu(node, node_db, mac_list) {
+ 		if (ether_addr_equal(node->macaddress_A, ethhdr->h_source)) {
+ 			if (hsr->proto_ops->update_san_info)
+ 				hsr->proto_ops->update_san_info(node, is_sup);
+@@ -291,12 +267,11 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
+ 	struct hsr_sup_tlv *hsr_sup_tlv;
+ 	struct hsr_node *node_real;
+ 	struct sk_buff *skb = NULL;
+-	struct hlist_head *node_db;
++	struct list_head *node_db;
+ 	struct ethhdr *ethhdr;
+ 	int i;
+ 	unsigned int pull_size = 0;
+ 	unsigned int total_pull_size = 0;
+-	u32 hash;
+ 
+ 	/* Here either frame->skb_hsr or frame->skb_prp should be
+ 	 * valid as supervision frame always will have protocol
+@@ -334,13 +309,11 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
+ 	hsr_sp = (struct hsr_sup_payload *)skb->data;
+ 
+ 	/* Merge node_curr (registered on macaddress_B) into node_real */
+-	node_db = port_rcv->hsr->node_db;
+-	hash = hsr_mac_hash(hsr, hsr_sp->macaddress_A);
+-	node_real = find_node_by_addr_A(&node_db[hash], hsr_sp->macaddress_A);
++	node_db = &port_rcv->hsr->node_db;
++	node_real = find_node_by_addr_A(node_db, hsr_sp->macaddress_A);
+ 	if (!node_real)
+ 		/* No frame received from AddrA of this node yet */
+-		node_real = hsr_add_node(hsr, &node_db[hash],
+-					 hsr_sp->macaddress_A,
++		node_real = hsr_add_node(hsr, node_db, hsr_sp->macaddress_A,
+ 					 HSR_SEQNR_START - 1, true,
+ 					 port_rcv->type);
+ 	if (!node_real)
+@@ -374,14 +347,14 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
+ 		hsr_sp = (struct hsr_sup_payload *)skb->data;
+ 
+ 		/* Check if redbox mac and node mac are equal. */
+-		if (!ether_addr_equal(node_real->macaddress_A,
+-				      hsr_sp->macaddress_A)) {
++		if (!ether_addr_equal(node_real->macaddress_A, hsr_sp->macaddress_A)) {
+ 			/* This is a redbox supervision frame for a VDAN! */
+ 			goto done;
+ 		}
+ 	}
+ 
+ 	ether_addr_copy(node_real->macaddress_B, ethhdr->h_source);
++	spin_lock_bh(&node_real->seq_out_lock);
+ 	for (i = 0; i < HSR_PT_PORTS; i++) {
+ 		if (!node_curr->time_in_stale[i] &&
+ 		    time_after(node_curr->time_in[i], node_real->time_in[i])) {
+@@ -392,12 +365,16 @@ void hsr_handle_sup_frame(struct hsr_frame_info *frame)
+ 		if (seq_nr_after(node_curr->seq_out[i], node_real->seq_out[i]))
+ 			node_real->seq_out[i] = node_curr->seq_out[i];
+ 	}
++	spin_unlock_bh(&node_real->seq_out_lock);
+ 	node_real->addr_B_port = port_rcv->type;
+ 
+ 	spin_lock_bh(&hsr->list_lock);
+-	hlist_del_rcu(&node_curr->mac_list);
++	if (!node_curr->removed) {
++		list_del_rcu(&node_curr->mac_list);
++		node_curr->removed = true;
++		kfree_rcu(node_curr, rcu_head);
++	}
+ 	spin_unlock_bh(&hsr->list_lock);
+-	kfree_rcu(node_curr, rcu_head);
+ 
+ done:
+ 	/* Push back here */
+@@ -433,7 +410,6 @@ void hsr_addr_subst_dest(struct hsr_node *node_src, struct sk_buff *skb,
+ 			 struct hsr_port *port)
+ {
+ 	struct hsr_node *node_dst;
+-	u32 hash;
+ 
+ 	if (!skb_mac_header_was_set(skb)) {
+ 		WARN_ONCE(1, "%s: Mac header not set\n", __func__);
+@@ -443,8 +419,7 @@ void hsr_addr_subst_dest(struct hsr_node *node_src, struct sk_buff *skb,
+ 	if (!is_unicast_ether_addr(eth_hdr(skb)->h_dest))
+ 		return;
+ 
+-	hash = hsr_mac_hash(port->hsr, eth_hdr(skb)->h_dest);
+-	node_dst = find_node_by_addr_A(&port->hsr->node_db[hash],
++	node_dst = find_node_by_addr_A(&port->hsr->node_db,
+ 				       eth_hdr(skb)->h_dest);
+ 	if (!node_dst) {
+ 		if (net_ratelimit())
+@@ -484,13 +459,17 @@ void hsr_register_frame_in(struct hsr_node *node, struct hsr_port *port,
+ int hsr_register_frame_out(struct hsr_port *port, struct hsr_node *node,
+ 			   u16 sequence_nr)
+ {
++	spin_lock_bh(&node->seq_out_lock);
+ 	if (seq_nr_before_or_eq(sequence_nr, node->seq_out[port->type]) &&
+ 	    time_is_after_jiffies(node->time_out[port->type] +
+-	    msecs_to_jiffies(HSR_ENTRY_FORGET_TIME)))
++	    msecs_to_jiffies(HSR_ENTRY_FORGET_TIME))) {
++		spin_unlock_bh(&node->seq_out_lock);
+ 		return 1;
++	}
+ 
+ 	node->time_out[port->type] = jiffies;
+ 	node->seq_out[port->type] = sequence_nr;
++	spin_unlock_bh(&node->seq_out_lock);
+ 	return 0;
+ }
+ 
+@@ -520,71 +499,60 @@ static struct hsr_port *get_late_port(struct hsr_priv *hsr,
+ void hsr_prune_nodes(struct timer_list *t)
+ {
+ 	struct hsr_priv *hsr = from_timer(hsr, t, prune_timer);
+-	struct hlist_node *tmp;
+ 	struct hsr_node *node;
++	struct hsr_node *tmp;
+ 	struct hsr_port *port;
+ 	unsigned long timestamp;
+ 	unsigned long time_a, time_b;
+-	int i;
+ 
+ 	spin_lock_bh(&hsr->list_lock);
++	list_for_each_entry_safe(node, tmp, &hsr->node_db, mac_list) {
++		/* Don't prune own node. Neither time_in[HSR_PT_SLAVE_A]
++		 * nor time_in[HSR_PT_SLAVE_B], will ever be updated for
++		 * the master port. Thus the master node will be repeatedly
++		 * pruned leading to packet loss.
++		 */
++		if (hsr_addr_is_self(hsr, node->macaddress_A))
++			continue;
++
++		/* Shorthand */
++		time_a = node->time_in[HSR_PT_SLAVE_A];
++		time_b = node->time_in[HSR_PT_SLAVE_B];
++
++		/* Check for timestamps old enough to risk wrap-around */
++		if (time_after(jiffies, time_a + MAX_JIFFY_OFFSET / 2))
++			node->time_in_stale[HSR_PT_SLAVE_A] = true;
++		if (time_after(jiffies, time_b + MAX_JIFFY_OFFSET / 2))
++			node->time_in_stale[HSR_PT_SLAVE_B] = true;
++
++		/* Get age of newest frame from node.
++		 * At least one time_in is OK here; nodes get pruned long
++		 * before both time_ins can get stale
++		 */
++		timestamp = time_a;
++		if (node->time_in_stale[HSR_PT_SLAVE_A] ||
++		    (!node->time_in_stale[HSR_PT_SLAVE_B] &&
++		    time_after(time_b, time_a)))
++			timestamp = time_b;
++
++		/* Warn of ring error only as long as we get frames at all */
++		if (time_is_after_jiffies(timestamp +
++				msecs_to_jiffies(1.5 * MAX_SLAVE_DIFF))) {
++			rcu_read_lock();
++			port = get_late_port(hsr, node);
++			if (port)
++				hsr_nl_ringerror(hsr, node->macaddress_A, port);
++			rcu_read_unlock();
++		}
+ 
+-	for (i = 0; i < hsr->hash_buckets; i++) {
+-		hlist_for_each_entry_safe(node, tmp, &hsr->node_db[i],
+-					  mac_list) {
+-			/* Don't prune own node.
+-			 * Neither time_in[HSR_PT_SLAVE_A]
+-			 * nor time_in[HSR_PT_SLAVE_B], will ever be updated
+-			 * for the master port. Thus the master node will be
+-			 * repeatedly pruned leading to packet loss.
+-			 */
+-			if (hsr_addr_is_self(hsr, node->macaddress_A))
+-				continue;
+-
+-			/* Shorthand */
+-			time_a = node->time_in[HSR_PT_SLAVE_A];
+-			time_b = node->time_in[HSR_PT_SLAVE_B];
+-
+-			/* Check for timestamps old enough to
+-			 * risk wrap-around
+-			 */
+-			if (time_after(jiffies, time_a + MAX_JIFFY_OFFSET / 2))
+-				node->time_in_stale[HSR_PT_SLAVE_A] = true;
+-			if (time_after(jiffies, time_b + MAX_JIFFY_OFFSET / 2))
+-				node->time_in_stale[HSR_PT_SLAVE_B] = true;
+-
+-			/* Get age of newest frame from node.
+-			 * At least one time_in is OK here; nodes get pruned
+-			 * long before both time_ins can get stale
+-			 */
+-			timestamp = time_a;
+-			if (node->time_in_stale[HSR_PT_SLAVE_A] ||
+-			    (!node->time_in_stale[HSR_PT_SLAVE_B] &&
+-			     time_after(time_b, time_a)))
+-				timestamp = time_b;
+-
+-			/* Warn of ring error only as long as we get
+-			 * frames at all
+-			 */
+-			if (time_is_after_jiffies(timestamp +
+-						  msecs_to_jiffies(1.5 * MAX_SLAVE_DIFF))) {
+-				rcu_read_lock();
+-				port = get_late_port(hsr, node);
+-				if (port)
+-					hsr_nl_ringerror(hsr,
+-							 node->macaddress_A,
+-							 port);
+-				rcu_read_unlock();
+-			}
+-
+-			/* Prune old entries */
+-			if (time_is_before_jiffies(timestamp +
+-						   msecs_to_jiffies(HSR_NODE_FORGET_TIME))) {
+-				hsr_nl_nodedown(hsr, node->macaddress_A);
+-				hlist_del_rcu(&node->mac_list);
+-				/* Note that we need to free this
+-				 * entry later:
+-				 */
++		/* Prune old entries */
++		if (time_is_before_jiffies(timestamp +
++				msecs_to_jiffies(HSR_NODE_FORGET_TIME))) {
++			hsr_nl_nodedown(hsr, node->macaddress_A);
++			if (!node->removed) {
++				list_del_rcu(&node->mac_list);
++				node->removed = true;
++				/* Note that we need to free this entry later: */
+ 				kfree_rcu(node, rcu_head);
+ 			}
+ 		}
+@@ -600,20 +568,17 @@ void *hsr_get_next_node(struct hsr_priv *hsr, void *_pos,
+ 			unsigned char addr[ETH_ALEN])
+ {
+ 	struct hsr_node *node;
+-	u32 hash;
+-
+-	hash = hsr_mac_hash(hsr, addr);
+ 
+ 	if (!_pos) {
+-		node = hsr_node_get_first(&hsr->node_db[hash],
+-					  &hsr->list_lock);
++		node = list_first_or_null_rcu(&hsr->node_db,
++					      struct hsr_node, mac_list);
+ 		if (node)
+ 			ether_addr_copy(addr, node->macaddress_A);
+ 		return node;
+ 	}
+ 
+ 	node = _pos;
+-	hlist_for_each_entry_continue_rcu(node, mac_list) {
++	list_for_each_entry_continue_rcu(node, &hsr->node_db, mac_list) {
+ 		ether_addr_copy(addr, node->macaddress_A);
+ 		return node;
+ 	}
+@@ -633,11 +598,8 @@ int hsr_get_node_data(struct hsr_priv *hsr,
+ 	struct hsr_node *node;
+ 	struct hsr_port *port;
+ 	unsigned long tdiff;
+-	u32 hash;
+-
+-	hash = hsr_mac_hash(hsr, addr);
+ 
+-	node = find_node_by_addr_A(&hsr->node_db[hash], addr);
++	node = find_node_by_addr_A(&hsr->node_db, addr);
+ 	if (!node)
+ 		return -ENOENT;
+ 
+diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h
+index f3762e9e42b54..b23556251d621 100644
+--- a/net/hsr/hsr_framereg.h
++++ b/net/hsr/hsr_framereg.h
+@@ -28,17 +28,9 @@ struct hsr_frame_info {
+ 	bool is_from_san;
+ };
+ 
+-#ifdef CONFIG_LOCKDEP
+-int lockdep_hsr_is_held(spinlock_t *lock);
+-#else
+-#define lockdep_hsr_is_held(lock)	1
+-#endif
+-
+-u32 hsr_mac_hash(struct hsr_priv *hsr, const unsigned char *addr);
+-struct hsr_node *hsr_node_get_first(struct hlist_head *head, spinlock_t *lock);
+ void hsr_del_self_node(struct hsr_priv *hsr);
+-void hsr_del_nodes(struct hlist_head *node_db);
+-struct hsr_node *hsr_get_node(struct hsr_port *port, struct hlist_head *node_db,
++void hsr_del_nodes(struct list_head *node_db);
++struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db,
+ 			      struct sk_buff *skb, bool is_sup,
+ 			      enum hsr_port_type rx_port);
+ void hsr_handle_sup_frame(struct hsr_frame_info *frame);
+@@ -76,7 +68,9 @@ void prp_handle_san_frame(bool san, enum hsr_port_type port,
+ void prp_update_san_info(struct hsr_node *node, bool is_sup);
+ 
+ struct hsr_node {
+-	struct hlist_node	mac_list;
++	struct list_head	mac_list;
++	/* Protect R/W access to seq_out */
++	spinlock_t		seq_out_lock;
+ 	unsigned char		macaddress_A[ETH_ALEN];
+ 	unsigned char		macaddress_B[ETH_ALEN];
+ 	/* Local slave through which AddrB frames are received from this node */
+@@ -88,6 +82,7 @@ struct hsr_node {
+ 	bool			san_a;
+ 	bool			san_b;
+ 	u16			seq_out[HSR_PT_PORTS];
++	bool			removed;
+ 	struct rcu_head		rcu_head;
+ };
+ 
+diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h
+index b158ba409f9a4..16ae9fb09ccd2 100644
+--- a/net/hsr/hsr_main.h
++++ b/net/hsr/hsr_main.h
+@@ -47,9 +47,6 @@
+ 
+ #define HSR_V1_SUP_LSDUSIZE		52
+ 
+-#define HSR_HSIZE_SHIFT	8
+-#define HSR_HSIZE	BIT(HSR_HSIZE_SHIFT)
+-
+ /* The helper functions below assumes that 'path' occupies the 4 most
+  * significant bits of the 16-bit field shared by 'path' and 'LSDU_size' (or
+  * equivalently, the 4 most significant bits of HSR tag byte 14).
+@@ -188,8 +185,8 @@ struct hsr_proto_ops {
+ struct hsr_priv {
+ 	struct rcu_head		rcu_head;
+ 	struct list_head	ports;
+-	struct hlist_head	node_db[HSR_HSIZE];	/* Known HSR nodes */
+-	struct hlist_head	self_node_db;	/* MACs of slaves */
++	struct list_head	node_db;	/* Known HSR nodes */
++	struct list_head	self_node_db;	/* MACs of slaves */
+ 	struct timer_list	announce_timer;	/* Supervision frame dispatch */
+ 	struct timer_list	prune_timer;
+ 	int announce_count;
+@@ -199,8 +196,6 @@ struct hsr_priv {
+ 	spinlock_t seqnr_lock;	/* locking for sequence_nr */
+ 	spinlock_t list_lock;	/* locking for node list */
+ 	struct hsr_proto_ops	*proto_ops;
+-	u32 hash_buckets;
+-	u32 hash_seed;
+ #define PRP_LAN_ID	0x5     /* 0x1010 for A and 0x1011 for B. Bit 0 is set
+ 				 * based on SLAVE_A or SLAVE_B
+ 				 */
+diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
+index 1405c037cf7ab..f3c8f91dbe2c1 100644
+--- a/net/hsr/hsr_netlink.c
++++ b/net/hsr/hsr_netlink.c
+@@ -105,7 +105,6 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev,
+ static void hsr_dellink(struct net_device *dev, struct list_head *head)
+ {
+ 	struct hsr_priv *hsr = netdev_priv(dev);
+-	int i;
+ 
+ 	del_timer_sync(&hsr->prune_timer);
+ 	del_timer_sync(&hsr->announce_timer);
+@@ -114,8 +113,7 @@ static void hsr_dellink(struct net_device *dev, struct list_head *head)
+ 	hsr_del_ports(hsr);
+ 
+ 	hsr_del_self_node(hsr);
+-	for (i = 0; i < hsr->hash_buckets; i++)
+-		hsr_del_nodes(&hsr->node_db[i]);
++	hsr_del_nodes(&hsr->node_db);
+ 
+ 	unregister_netdevice_queue(dev, head);
+ }
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 7f6d7c355e38e..31f463f46f6ed 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -522,9 +522,9 @@ int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
+ 	/* Make sure we are allowed to bind here. */
+ 	if (snum || !(inet->bind_address_no_port ||
+ 		      (flags & BIND_FORCE_ADDRESS_NO_PORT))) {
+-		if (sk->sk_prot->get_port(sk, snum)) {
++		err = sk->sk_prot->get_port(sk, snum);
++		if (err) {
+ 			inet->inet_saddr = inet->inet_rcv_saddr = 0;
+-			err = -EADDRINUSE;
+ 			goto out_release_sock;
+ 		}
+ 		if (!(flags & BIND_FROM_BPF)) {
+@@ -1686,9 +1686,9 @@ u64 snmp_get_cpu_field64(void __percpu *mib, int cpu, int offt,
+ 	bhptr = per_cpu_ptr(mib, cpu);
+ 	syncp = (struct u64_stats_sync *)(bhptr + syncp_offset);
+ 	do {
+-		start = u64_stats_fetch_begin_irq(syncp);
++		start = u64_stats_fetch_begin(syncp);
+ 		v = *(((u64 *)bhptr) + offt);
+-	} while (u64_stats_fetch_retry_irq(syncp, start));
++	} while (u64_stats_fetch_retry(syncp, start));
+ 
+ 	return v;
+ }
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index eb31c7158b39c..971969cc7e17f 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -1041,7 +1041,7 @@ int inet_csk_listen_start(struct sock *sk)
+ {
+ 	struct inet_connection_sock *icsk = inet_csk(sk);
+ 	struct inet_sock *inet = inet_sk(sk);
+-	int err = -EADDRINUSE;
++	int err;
+ 
+ 	reqsk_queue_alloc(&icsk->icsk_accept_queue);
+ 
+@@ -1057,7 +1057,8 @@ int inet_csk_listen_start(struct sock *sk)
+ 	 * after validation is complete.
+ 	 */
+ 	inet_sk_state_store(sk, TCP_LISTEN);
+-	if (!sk->sk_prot->get_port(sk, inet->inet_num)) {
++	err = sk->sk_prot->get_port(sk, inet->inet_num);
++	if (!err) {
+ 		inet->inet_sport = htons(inet->inet_num);
+ 
+ 		sk_dst_reset(sk);
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index 3b2420829c237..948f4801f993e 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -142,7 +142,7 @@ next_port:
+ 
+ fail:
+ 	spin_unlock(&ping_table.lock);
+-	return 1;
++	return -EADDRINUSE;
+ }
+ EXPORT_SYMBOL_GPL(ping_get_port);
+ 
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index cf9c3e8f7ccbf..94aad3870c5fc 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -45,8 +45,11 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock,
+ 		tmp->sg.end = i;
+ 		if (apply) {
+ 			apply_bytes -= size;
+-			if (!apply_bytes)
++			if (!apply_bytes) {
++				if (sge->length)
++					sk_msg_iter_var_prev(i);
+ 				break;
++			}
+ 		}
+ 	} while (i != msg->sg.end);
+ 
+@@ -131,10 +134,9 @@ static int tcp_bpf_push_locked(struct sock *sk, struct sk_msg *msg,
+ 	return ret;
+ }
+ 
+-int tcp_bpf_sendmsg_redir(struct sock *sk, struct sk_msg *msg,
+-			  u32 bytes, int flags)
++int tcp_bpf_sendmsg_redir(struct sock *sk, bool ingress,
++			  struct sk_msg *msg, u32 bytes, int flags)
+ {
+-	bool ingress = sk_msg_to_ingress(msg);
+ 	struct sk_psock *psock = sk_psock_get(sk);
+ 	int ret;
+ 
+@@ -276,10 +278,10 @@ msg_bytes_ready:
+ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
+ 				struct sk_msg *msg, int *copied, int flags)
+ {
+-	bool cork = false, enospc = sk_msg_full(msg);
++	bool cork = false, enospc = sk_msg_full(msg), redir_ingress;
+ 	struct sock *sk_redir;
+ 	u32 tosend, origsize, sent, delta = 0;
+-	u32 eval = __SK_NONE;
++	u32 eval;
+ 	int ret;
+ 
+ more_data:
+@@ -310,6 +312,7 @@ more_data:
+ 	tosend = msg->sg.size;
+ 	if (psock->apply_bytes && psock->apply_bytes < tosend)
+ 		tosend = psock->apply_bytes;
++	eval = __SK_NONE;
+ 
+ 	switch (psock->eval) {
+ 	case __SK_PASS:
+@@ -321,6 +324,7 @@ more_data:
+ 		sk_msg_apply_bytes(psock, tosend);
+ 		break;
+ 	case __SK_REDIRECT:
++		redir_ingress = psock->redir_ingress;
+ 		sk_redir = psock->sk_redir;
+ 		sk_msg_apply_bytes(psock, tosend);
+ 		if (!psock->apply_bytes) {
+@@ -337,7 +341,8 @@ more_data:
+ 		release_sock(sk);
+ 
+ 		origsize = msg->sg.size;
+-		ret = tcp_bpf_sendmsg_redir(sk_redir, msg, tosend, flags);
++		ret = tcp_bpf_sendmsg_redir(sk_redir, redir_ingress,
++					    msg, tosend, flags);
+ 		sent = origsize - msg->sg.size;
+ 
+ 		if (eval == __SK_REDIRECT)
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index d9099754ac69d..7fe0ba3f0933e 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -232,16 +232,16 @@ static int udp_reuseport_add_sock(struct sock *sk, struct udp_hslot *hslot)
+ int udp_lib_get_port(struct sock *sk, unsigned short snum,
+ 		     unsigned int hash2_nulladdr)
+ {
+-	struct udp_hslot *hslot, *hslot2;
+ 	struct udp_table *udptable = sk->sk_prot->h.udp_table;
+-	int    error = 1;
++	struct udp_hslot *hslot, *hslot2;
+ 	struct net *net = sock_net(sk);
++	int error = -EADDRINUSE;
+ 
+ 	if (!snum) {
++		DECLARE_BITMAP(bitmap, PORTS_PER_CHAIN);
++		unsigned short first, last;
+ 		int low, high, remaining;
+ 		unsigned int rand;
+-		unsigned short first, last;
+-		DECLARE_BITMAP(bitmap, PORTS_PER_CHAIN);
+ 
+ 		inet_get_local_port_range(net, &low, &high);
+ 		remaining = (high - low) + 1;
+@@ -2527,10 +2527,13 @@ static struct sock *__udp4_lib_mcast_demux_lookup(struct net *net,
+ 						  __be16 rmt_port, __be32 rmt_addr,
+ 						  int dif, int sdif)
+ {
+-	struct sock *sk, *result;
+ 	unsigned short hnum = ntohs(loc_port);
+-	unsigned int slot = udp_hashfn(net, hnum, udp_table.mask);
+-	struct udp_hslot *hslot = &udp_table.hash[slot];
++	struct sock *sk, *result;
++	struct udp_hslot *hslot;
++	unsigned int slot;
++
++	slot = udp_hashfn(net, hnum, udp_table.mask);
++	hslot = &udp_table.hash[slot];
+ 
+ 	/* Do not bother scanning a too big list */
+ 	if (hslot->count > 10)
+@@ -2558,14 +2561,18 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net,
+ 					    __be16 rmt_port, __be32 rmt_addr,
+ 					    int dif, int sdif)
+ {
+-	unsigned short hnum = ntohs(loc_port);
+-	unsigned int hash2 = ipv4_portaddr_hash(net, loc_addr, hnum);
+-	unsigned int slot2 = hash2 & udp_table.mask;
+-	struct udp_hslot *hslot2 = &udp_table.hash2[slot2];
+ 	INET_ADDR_COOKIE(acookie, rmt_addr, loc_addr);
+-	const __portpair ports = INET_COMBINED_PORTS(rmt_port, hnum);
++	unsigned short hnum = ntohs(loc_port);
++	unsigned int hash2, slot2;
++	struct udp_hslot *hslot2;
++	__portpair ports;
+ 	struct sock *sk;
+ 
++	hash2 = ipv4_portaddr_hash(net, loc_addr, hnum);
++	slot2 = hash2 & udp_table.mask;
++	hslot2 = &udp_table.hash2[slot2];
++	ports = INET_COMBINED_PORTS(rmt_port, hnum);
++
+ 	udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
+ 		if (inet_match(net, sk, acookie, ports, dif, sdif))
+ 			return sk;
+@@ -2966,10 +2973,10 @@ EXPORT_SYMBOL(udp_prot);
+ 
+ static struct sock *udp_get_first(struct seq_file *seq, int start)
+ {
+-	struct sock *sk;
+-	struct udp_seq_afinfo *afinfo;
+ 	struct udp_iter_state *state = seq->private;
+ 	struct net *net = seq_file_net(seq);
++	struct udp_seq_afinfo *afinfo;
++	struct sock *sk;
+ 
+ 	if (state->bpf_seq_afinfo)
+ 		afinfo = state->bpf_seq_afinfo;
+@@ -3000,9 +3007,9 @@ found:
+ 
+ static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
+ {
+-	struct udp_seq_afinfo *afinfo;
+ 	struct udp_iter_state *state = seq->private;
+ 	struct net *net = seq_file_net(seq);
++	struct udp_seq_afinfo *afinfo;
+ 
+ 	if (state->bpf_seq_afinfo)
+ 		afinfo = state->bpf_seq_afinfo;
+@@ -3058,8 +3065,8 @@ EXPORT_SYMBOL(udp_seq_next);
+ 
+ void udp_seq_stop(struct seq_file *seq, void *v)
+ {
+-	struct udp_seq_afinfo *afinfo;
+ 	struct udp_iter_state *state = seq->private;
++	struct udp_seq_afinfo *afinfo;
+ 
+ 	if (state->bpf_seq_afinfo)
+ 		afinfo = state->bpf_seq_afinfo;
+diff --git a/net/ipv4/udp_tunnel_core.c b/net/ipv4/udp_tunnel_core.c
+index 8242c8947340e..5f8104cf082d0 100644
+--- a/net/ipv4/udp_tunnel_core.c
++++ b/net/ipv4/udp_tunnel_core.c
+@@ -176,6 +176,7 @@ EXPORT_SYMBOL_GPL(udp_tunnel_xmit_skb);
+ void udp_tunnel_sock_release(struct socket *sock)
+ {
+ 	rcu_assign_sk_user_data(sock->sk, NULL);
++	synchronize_rcu();
+ 	kernel_sock_shutdown(sock, SHUT_RDWR);
+ 	sock_release(sock);
+ }
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index dbb1430d6cc2e..cceda5c833021 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -403,10 +403,10 @@ static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
+ 	/* Make sure we are allowed to bind here. */
+ 	if (snum || !(inet->bind_address_no_port ||
+ 		      (flags & BIND_FORCE_ADDRESS_NO_PORT))) {
+-		if (sk->sk_prot->get_port(sk, snum)) {
++		err = sk->sk_prot->get_port(sk, snum);
++		if (err) {
+ 			sk->sk_ipv6only = saved_ipv6only;
+ 			inet_reset_saddr(sk);
+-			err = -EADDRINUSE;
+ 			goto out;
+ 		}
+ 		if (!(flags & BIND_FROM_BPF)) {
+diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
+index 5ecb56522f9d6..ba28aeb7cade0 100644
+--- a/net/ipv6/datagram.c
++++ b/net/ipv6/datagram.c
+@@ -42,24 +42,29 @@ static void ip6_datagram_flow_key_init(struct flowi6 *fl6, struct sock *sk)
+ {
+ 	struct inet_sock *inet = inet_sk(sk);
+ 	struct ipv6_pinfo *np = inet6_sk(sk);
++	int oif = sk->sk_bound_dev_if;
+ 
+ 	memset(fl6, 0, sizeof(*fl6));
+ 	fl6->flowi6_proto = sk->sk_protocol;
+ 	fl6->daddr = sk->sk_v6_daddr;
+ 	fl6->saddr = np->saddr;
+-	fl6->flowi6_oif = sk->sk_bound_dev_if;
+ 	fl6->flowi6_mark = sk->sk_mark;
+ 	fl6->fl6_dport = inet->inet_dport;
+ 	fl6->fl6_sport = inet->inet_sport;
+ 	fl6->flowlabel = np->flow_label;
+ 	fl6->flowi6_uid = sk->sk_uid;
+ 
+-	if (!fl6->flowi6_oif)
+-		fl6->flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
++	if (!oif)
++		oif = np->sticky_pktinfo.ipi6_ifindex;
+ 
+-	if (!fl6->flowi6_oif && ipv6_addr_is_multicast(&fl6->daddr))
+-		fl6->flowi6_oif = np->mcast_oif;
++	if (!oif) {
++		if (ipv6_addr_is_multicast(&fl6->daddr))
++			oif = np->mcast_oif;
++		else
++			oif = np->ucast_oif;
++	}
+ 
++	fl6->flowi6_oif = oif;
+ 	security_sk_classify_flow(sk, flowi6_to_flowi_common(fl6));
+ }
+ 
+diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
+index b7de5e46fdd8f..f84da849819cc 100644
+--- a/net/ipv6/seg6_local.c
++++ b/net/ipv6/seg6_local.c
+@@ -1508,13 +1508,13 @@ static int put_nla_counters(struct sk_buff *skb, struct seg6_local_lwt *slwt)
+ 
+ 		pcounters = per_cpu_ptr(slwt->pcpu_counters, i);
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&pcounters->syncp);
++			start = u64_stats_fetch_begin(&pcounters->syncp);
+ 
+ 			packets = u64_stats_read(&pcounters->packets);
+ 			bytes = u64_stats_read(&pcounters->bytes);
+ 			errors = u64_stats_read(&pcounters->errors);
+ 
+-		} while (u64_stats_fetch_retry_irq(&pcounters->syncp, start));
++		} while (u64_stats_fetch_retry(&pcounters->syncp, start));
+ 
+ 		counters.packets += packets;
+ 		counters.bytes += bytes;
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index 59b2d9a6210c8..ccb39b1e730f8 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -694,7 +694,7 @@ static int ipip6_rcv(struct sk_buff *skb)
+ 		skb->dev = tunnel->dev;
+ 
+ 		if (packet_is_spoofed(skb, iph, tunnel)) {
+-			tunnel->dev->stats.rx_errors++;
++			DEV_STATS_INC(tunnel->dev, rx_errors);
+ 			goto out;
+ 		}
+ 
+@@ -714,8 +714,8 @@ static int ipip6_rcv(struct sk_buff *skb)
+ 				net_info_ratelimited("non-ECT from %pI4 with TOS=%#x\n",
+ 						     &iph->saddr, iph->tos);
+ 			if (err > 1) {
+-				++tunnel->dev->stats.rx_frame_errors;
+-				++tunnel->dev->stats.rx_errors;
++				DEV_STATS_INC(tunnel->dev, rx_frame_errors);
++				DEV_STATS_INC(tunnel->dev, rx_errors);
+ 				goto out;
+ 			}
+ 		}
+@@ -942,7 +942,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ 	if (!rt) {
+ 		rt = ip_route_output_flow(tunnel->net, &fl4, NULL);
+ 		if (IS_ERR(rt)) {
+-			dev->stats.tx_carrier_errors++;
++			DEV_STATS_INC(dev, tx_carrier_errors);
+ 			goto tx_error_icmp;
+ 		}
+ 		dst_cache_set_ip4(&tunnel->dst_cache, &rt->dst, fl4.saddr);
+@@ -950,14 +950,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ 
+ 	if (rt->rt_type != RTN_UNICAST && rt->rt_type != RTN_LOCAL) {
+ 		ip_rt_put(rt);
+-		dev->stats.tx_carrier_errors++;
++		DEV_STATS_INC(dev, tx_carrier_errors);
+ 		goto tx_error_icmp;
+ 	}
+ 	tdev = rt->dst.dev;
+ 
+ 	if (tdev == dev) {
+ 		ip_rt_put(rt);
+-		dev->stats.collisions++;
++		DEV_STATS_INC(dev, collisions);
+ 		goto tx_error;
+ 	}
+ 
+@@ -970,7 +970,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ 		mtu = dst_mtu(&rt->dst) - t_hlen;
+ 
+ 		if (mtu < IPV4_MIN_MTU) {
+-			dev->stats.collisions++;
++			DEV_STATS_INC(dev, collisions);
+ 			ip_rt_put(rt);
+ 			goto tx_error;
+ 		}
+@@ -1009,7 +1009,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+ 		struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
+ 		if (!new_skb) {
+ 			ip_rt_put(rt);
+-			dev->stats.tx_dropped++;
++			DEV_STATS_INC(dev, tx_dropped);
+ 			kfree_skb(skb);
+ 			return NETDEV_TX_OK;
+ 		}
+@@ -1039,7 +1039,7 @@ tx_error_icmp:
+ 	dst_link_failure(skb);
+ tx_error:
+ 	kfree_skb(skb);
+-	dev->stats.tx_errors++;
++	DEV_STATS_INC(dev, tx_errors);
+ 	return NETDEV_TX_OK;
+ }
+ 
+@@ -1058,7 +1058,7 @@ static netdev_tx_t sit_tunnel_xmit__(struct sk_buff *skb,
+ 	return NETDEV_TX_OK;
+ tx_error:
+ 	kfree_skb(skb);
+-	dev->stats.tx_errors++;
++	DEV_STATS_INC(dev, tx_errors);
+ 	return NETDEV_TX_OK;
+ }
+ 
+@@ -1087,7 +1087,7 @@ static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb,
+ 	return NETDEV_TX_OK;
+ 
+ tx_err:
+-	dev->stats.tx_errors++;
++	DEV_STATS_INC(dev, tx_errors);
+ 	kfree_skb(skb);
+ 	return NETDEV_TX_OK;
+ 
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index fb667e02e9760..d917d62e662d6 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -1039,12 +1039,16 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net,
+ 			int dif, int sdif)
+ {
+ 	unsigned short hnum = ntohs(loc_port);
+-	unsigned int hash2 = ipv6_portaddr_hash(net, loc_addr, hnum);
+-	unsigned int slot2 = hash2 & udp_table.mask;
+-	struct udp_hslot *hslot2 = &udp_table.hash2[slot2];
+-	const __portpair ports = INET_COMBINED_PORTS(rmt_port, hnum);
++	unsigned int hash2, slot2;
++	struct udp_hslot *hslot2;
++	__portpair ports;
+ 	struct sock *sk;
+ 
++	hash2 = ipv6_portaddr_hash(net, loc_addr, hnum);
++	slot2 = hash2 & udp_table.mask;
++	hslot2 = &udp_table.hash2[slot2];
++	ports = INET_COMBINED_PORTS(rmt_port, hnum);
++
+ 	udp_portaddr_for_each_entry_rcu(sk, &hslot2->head) {
+ 		if (sk->sk_state == TCP_ESTABLISHED &&
+ 		    inet6_match(net, sk, rmt_addr, loc_addr, ports, dif, sdif))
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 65f34945a7678..538f8c0dbb2b6 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -539,7 +539,7 @@ static struct ieee80211_key *
+ ieee80211_lookup_key(struct ieee80211_sub_if_data *sdata,
+ 		     u8 key_idx, bool pairwise, const u8 *mac_addr)
+ {
+-	struct ieee80211_local *local = sdata->local;
++	struct ieee80211_local *local __maybe_unused = sdata->local;
+ 	struct ieee80211_key *key;
+ 	struct sta_info *sta;
+ 
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index 9583643b70332..c7dd1f49bb351 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -389,6 +389,7 @@ struct ieee80211_mgd_auth_data {
+ 	bool done, waiting;
+ 	bool peer_confirmed;
+ 	bool timeout_started;
++	int link_id;
+ 
+ 	u8 ap_addr[ETH_ALEN] __aligned(2);
+ 
+diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
+index 95b58c5cac07f..c3eb08b5a47e3 100644
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -2414,6 +2414,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
+ 
+ 		ret = cfg80211_register_netdevice(ndev);
+ 		if (ret) {
++			ieee80211_if_free(ndev);
+ 			free_netdev(ndev);
+ 			return ret;
+ 		}
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 654414caeb71e..0a9710747b80e 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -4955,6 +4955,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ 	struct cfg80211_rx_assoc_resp resp = {
+ 		.uapsd_queues = -1,
+ 	};
++	u8 ap_mld_addr[ETH_ALEN] __aligned(2);
+ 	unsigned int link_id;
+ 
+ 	sdata_assert_lock(sdata);
+@@ -5119,6 +5120,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ 				resp.uapsd_queues |= ieee80211_ac_to_qos_mask[ac];
+ 	}
+ 
++	if (sdata->vif.valid_links) {
++		ether_addr_copy(ap_mld_addr, sdata->vif.cfg.ap_addr);
++		resp.ap_mld_addr = ap_mld_addr;
++	}
++
+ 	ieee80211_destroy_assoc_data(sdata,
+ 				     status_code == WLAN_STATUS_SUCCESS ?
+ 					ASSOC_SUCCESS :
+@@ -5128,8 +5134,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ 	resp.len = len;
+ 	resp.req_ies = ifmgd->assoc_req_ies;
+ 	resp.req_ies_len = ifmgd->assoc_req_ies_len;
+-	if (sdata->vif.valid_links)
+-		resp.ap_mld_addr = sdata->vif.cfg.ap_addr;
+ 	cfg80211_rx_assoc_resp(sdata->dev, &resp);
+ notify_driver:
+ 	drv_mgd_complete_tx(sdata->local, sdata, &info);
+@@ -6578,6 +6582,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
+ 	       req->ap_mld_addr ?: req->bss->bssid,
+ 	       ETH_ALEN);
+ 	auth_data->bss = req->bss;
++	auth_data->link_id = req->link_id;
+ 
+ 	if (req->auth_data_len >= 4) {
+ 		if (req->auth_type == NL80211_AUTHTYPE_SAE) {
+@@ -6596,7 +6601,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
+ 	 * removal and re-addition of the STA entry in
+ 	 * ieee80211_prep_connection().
+ 	 */
+-	cont_auth = ifmgd->auth_data && req->bss == ifmgd->auth_data->bss;
++	cont_auth = ifmgd->auth_data && req->bss == ifmgd->auth_data->bss &&
++		    ifmgd->auth_data->link_id == req->link_id;
+ 
+ 	if (req->ie && req->ie_len) {
+ 		memcpy(&auth_data->data[auth_data->data_len],
+@@ -6933,7 +6939,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
+ 
+ 		/* keep sta info, bssid if matching */
+ 		match = ether_addr_equal(ifmgd->auth_data->ap_addr,
+-					 assoc_data->ap_addr);
++					 assoc_data->ap_addr) &&
++			ifmgd->auth_data->link_id == req->link_id;
+ 		ieee80211_destroy_auth_data(sdata, match);
+ 	}
+ 
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index 9d7b238a67372..965b9cb2ef3f2 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -2316,9 +2316,9 @@ static inline u64 sta_get_tidstats_msdu(struct ieee80211_sta_rx_stats *rxstats,
+ 	u64 value;
+ 
+ 	do {
+-		start = u64_stats_fetch_begin_irq(&rxstats->syncp);
++		start = u64_stats_fetch_begin(&rxstats->syncp);
+ 		value = rxstats->msdu[tid];
+-	} while (u64_stats_fetch_retry_irq(&rxstats->syncp, start));
++	} while (u64_stats_fetch_retry(&rxstats->syncp, start));
+ 
+ 	return value;
+ }
+@@ -2384,9 +2384,9 @@ static inline u64 sta_get_stats_bytes(struct ieee80211_sta_rx_stats *rxstats)
+ 	u64 value;
+ 
+ 	do {
+-		start = u64_stats_fetch_begin_irq(&rxstats->syncp);
++		start = u64_stats_fetch_begin(&rxstats->syncp);
+ 		value = rxstats->bytes;
+-	} while (u64_stats_fetch_retry_irq(&rxstats->syncp, start));
++	} while (u64_stats_fetch_retry(&rxstats->syncp, start));
+ 
+ 	return value;
+ }
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index d2c4f9226f947..dafd3a480f024 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -2934,7 +2934,7 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
+ 
+ 		if (pre_conf_link_id != link_id &&
+ 		    link_id != IEEE80211_LINK_UNSPECIFIED) {
+-#ifdef CPTCFG_MAC80211_VERBOSE_DEBUG
++#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ 			net_info_ratelimited("%s: dropped frame to %pM with bad link ID request (%d vs. %d)\n",
+ 					     sdata->name, hdr.addr1,
+ 					     pre_conf_link_id, link_id);
+diff --git a/net/mctp/device.c b/net/mctp/device.c
+index 99a3bda8852f8..acb97b2574289 100644
+--- a/net/mctp/device.c
++++ b/net/mctp/device.c
+@@ -429,12 +429,6 @@ static void mctp_unregister(struct net_device *dev)
+ 	struct mctp_dev *mdev;
+ 
+ 	mdev = mctp_dev_get_rtnl(dev);
+-	if (mdev && !mctp_known(dev)) {
+-		// Sanity check, should match what was set in mctp_register
+-		netdev_warn(dev, "%s: BUG mctp_ptr set for unknown type %d",
+-			    __func__, dev->type);
+-		return;
+-	}
+ 	if (!mdev)
+ 		return;
+ 
+@@ -451,14 +445,8 @@ static int mctp_register(struct net_device *dev)
+ 	struct mctp_dev *mdev;
+ 
+ 	/* Already registered? */
+-	mdev = rtnl_dereference(dev->mctp_ptr);
+-
+-	if (mdev) {
+-		if (!mctp_known(dev))
+-			netdev_warn(dev, "%s: BUG mctp_ptr set for unknown type %d",
+-				    __func__, dev->type);
++	if (rtnl_dereference(dev->mctp_ptr))
+ 		return 0;
+-	}
+ 
+ 	/* only register specific types */
+ 	if (!mctp_known(dev))
+diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
+index b52afe316dc41..35b5f806fdda1 100644
+--- a/net/mpls/af_mpls.c
++++ b/net/mpls/af_mpls.c
+@@ -1079,9 +1079,9 @@ static void mpls_get_stats(struct mpls_dev *mdev,
+ 
+ 		p = per_cpu_ptr(mdev->stats, i);
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&p->syncp);
++			start = u64_stats_fetch_begin(&p->syncp);
+ 			local = p->stats;
+-		} while (u64_stats_fetch_retry_irq(&p->syncp, start));
++		} while (u64_stats_fetch_retry(&p->syncp, start));
+ 
+ 		stats->rx_packets	+= local.rx_packets;
+ 		stats->rx_bytes		+= local.rx_bytes;
+diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
+index 51ad557a525b5..b5ae419661b80 100644
+--- a/net/netfilter/ipvs/ip_vs_core.c
++++ b/net/netfilter/ipvs/ip_vs_core.c
+@@ -132,21 +132,21 @@ ip_vs_in_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
+ 
+ 		s = this_cpu_ptr(dest->stats.cpustats);
+ 		u64_stats_update_begin(&s->syncp);
+-		s->cnt.inpkts++;
+-		s->cnt.inbytes += skb->len;
++		u64_stats_inc(&s->cnt.inpkts);
++		u64_stats_add(&s->cnt.inbytes, skb->len);
+ 		u64_stats_update_end(&s->syncp);
+ 
+ 		svc = rcu_dereference(dest->svc);
+ 		s = this_cpu_ptr(svc->stats.cpustats);
+ 		u64_stats_update_begin(&s->syncp);
+-		s->cnt.inpkts++;
+-		s->cnt.inbytes += skb->len;
++		u64_stats_inc(&s->cnt.inpkts);
++		u64_stats_add(&s->cnt.inbytes, skb->len);
+ 		u64_stats_update_end(&s->syncp);
+ 
+ 		s = this_cpu_ptr(ipvs->tot_stats.cpustats);
+ 		u64_stats_update_begin(&s->syncp);
+-		s->cnt.inpkts++;
+-		s->cnt.inbytes += skb->len;
++		u64_stats_inc(&s->cnt.inpkts);
++		u64_stats_add(&s->cnt.inbytes, skb->len);
+ 		u64_stats_update_end(&s->syncp);
+ 
+ 		local_bh_enable();
+@@ -168,21 +168,21 @@ ip_vs_out_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
+ 
+ 		s = this_cpu_ptr(dest->stats.cpustats);
+ 		u64_stats_update_begin(&s->syncp);
+-		s->cnt.outpkts++;
+-		s->cnt.outbytes += skb->len;
++		u64_stats_inc(&s->cnt.outpkts);
++		u64_stats_add(&s->cnt.outbytes, skb->len);
+ 		u64_stats_update_end(&s->syncp);
+ 
+ 		svc = rcu_dereference(dest->svc);
+ 		s = this_cpu_ptr(svc->stats.cpustats);
+ 		u64_stats_update_begin(&s->syncp);
+-		s->cnt.outpkts++;
+-		s->cnt.outbytes += skb->len;
++		u64_stats_inc(&s->cnt.outpkts);
++		u64_stats_add(&s->cnt.outbytes, skb->len);
+ 		u64_stats_update_end(&s->syncp);
+ 
+ 		s = this_cpu_ptr(ipvs->tot_stats.cpustats);
+ 		u64_stats_update_begin(&s->syncp);
+-		s->cnt.outpkts++;
+-		s->cnt.outbytes += skb->len;
++		u64_stats_inc(&s->cnt.outpkts);
++		u64_stats_add(&s->cnt.outbytes, skb->len);
+ 		u64_stats_update_end(&s->syncp);
+ 
+ 		local_bh_enable();
+@@ -200,17 +200,17 @@ ip_vs_conn_stats(struct ip_vs_conn *cp, struct ip_vs_service *svc)
+ 
+ 	s = this_cpu_ptr(cp->dest->stats.cpustats);
+ 	u64_stats_update_begin(&s->syncp);
+-	s->cnt.conns++;
++	u64_stats_inc(&s->cnt.conns);
+ 	u64_stats_update_end(&s->syncp);
+ 
+ 	s = this_cpu_ptr(svc->stats.cpustats);
+ 	u64_stats_update_begin(&s->syncp);
+-	s->cnt.conns++;
++	u64_stats_inc(&s->cnt.conns);
+ 	u64_stats_update_end(&s->syncp);
+ 
+ 	s = this_cpu_ptr(ipvs->tot_stats.cpustats);
+ 	u64_stats_update_begin(&s->syncp);
+-	s->cnt.conns++;
++	u64_stats_inc(&s->cnt.conns);
+ 	u64_stats_update_end(&s->syncp);
+ 
+ 	local_bh_enable();
+diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
+index efab2b06d3732..65bda976845da 100644
+--- a/net/netfilter/ipvs/ip_vs_ctl.c
++++ b/net/netfilter/ipvs/ip_vs_ctl.c
+@@ -2296,13 +2296,13 @@ static int ip_vs_stats_percpu_show(struct seq_file *seq, void *v)
+ 		u64 conns, inpkts, outpkts, inbytes, outbytes;
+ 
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&u->syncp);
+-			conns = u->cnt.conns;
+-			inpkts = u->cnt.inpkts;
+-			outpkts = u->cnt.outpkts;
+-			inbytes = u->cnt.inbytes;
+-			outbytes = u->cnt.outbytes;
+-		} while (u64_stats_fetch_retry_irq(&u->syncp, start));
++			start = u64_stats_fetch_begin(&u->syncp);
++			conns = u64_stats_read(&u->cnt.conns);
++			inpkts = u64_stats_read(&u->cnt.inpkts);
++			outpkts = u64_stats_read(&u->cnt.outpkts);
++			inbytes = u64_stats_read(&u->cnt.inbytes);
++			outbytes = u64_stats_read(&u->cnt.outbytes);
++		} while (u64_stats_fetch_retry(&u->syncp, start));
+ 
+ 		seq_printf(seq, "%3X %8LX %8LX %8LX %16LX %16LX\n",
+ 			   i, (u64)conns, (u64)inpkts,
+diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c
+index 9a1a7af6a186a..f53150d82a92d 100644
+--- a/net/netfilter/ipvs/ip_vs_est.c
++++ b/net/netfilter/ipvs/ip_vs_est.c
+@@ -67,11 +67,11 @@ static void ip_vs_read_cpu_stats(struct ip_vs_kstats *sum,
+ 		if (add) {
+ 			do {
+ 				start = u64_stats_fetch_begin(&s->syncp);
+-				conns = s->cnt.conns;
+-				inpkts = s->cnt.inpkts;
+-				outpkts = s->cnt.outpkts;
+-				inbytes = s->cnt.inbytes;
+-				outbytes = s->cnt.outbytes;
++				conns = u64_stats_read(&s->cnt.conns);
++				inpkts = u64_stats_read(&s->cnt.inpkts);
++				outpkts = u64_stats_read(&s->cnt.outpkts);
++				inbytes = u64_stats_read(&s->cnt.inbytes);
++				outbytes = u64_stats_read(&s->cnt.outbytes);
+ 			} while (u64_stats_fetch_retry(&s->syncp, start));
+ 			sum->conns += conns;
+ 			sum->inpkts += inpkts;
+@@ -82,11 +82,11 @@ static void ip_vs_read_cpu_stats(struct ip_vs_kstats *sum,
+ 			add = true;
+ 			do {
+ 				start = u64_stats_fetch_begin(&s->syncp);
+-				sum->conns = s->cnt.conns;
+-				sum->inpkts = s->cnt.inpkts;
+-				sum->outpkts = s->cnt.outpkts;
+-				sum->inbytes = s->cnt.inbytes;
+-				sum->outbytes = s->cnt.outbytes;
++				sum->conns = u64_stats_read(&s->cnt.conns);
++				sum->inpkts = u64_stats_read(&s->cnt.inpkts);
++				sum->outpkts = u64_stats_read(&s->cnt.outpkts);
++				sum->inbytes = u64_stats_read(&s->cnt.inbytes);
++				sum->outbytes = u64_stats_read(&s->cnt.outbytes);
+ 			} while (u64_stats_fetch_retry(&s->syncp, start));
+ 		}
+ 	}
+diff --git a/net/netfilter/nf_conntrack_proto_icmpv6.c b/net/netfilter/nf_conntrack_proto_icmpv6.c
+index 61e3b05cf02c3..1020d67600a95 100644
+--- a/net/netfilter/nf_conntrack_proto_icmpv6.c
++++ b/net/netfilter/nf_conntrack_proto_icmpv6.c
+@@ -129,6 +129,56 @@ static void icmpv6_error_log(const struct sk_buff *skb,
+ 	nf_l4proto_log_invalid(skb, state, IPPROTO_ICMPV6, "%s", msg);
+ }
+ 
++static noinline_for_stack int
++nf_conntrack_icmpv6_redirect(struct nf_conn *tmpl, struct sk_buff *skb,
++			     unsigned int dataoff,
++			     const struct nf_hook_state *state)
++{
++	u8 hl = ipv6_hdr(skb)->hop_limit;
++	union nf_inet_addr outer_daddr;
++	union {
++		struct nd_opt_hdr nd_opt;
++		struct rd_msg rd_msg;
++	} tmp;
++	const struct nd_opt_hdr *nd_opt;
++	const struct rd_msg *rd_msg;
++
++	rd_msg = skb_header_pointer(skb, dataoff, sizeof(*rd_msg), &tmp.rd_msg);
++	if (!rd_msg) {
++		icmpv6_error_log(skb, state, "short redirect");
++		return -NF_ACCEPT;
++	}
++
++	if (rd_msg->icmph.icmp6_code != 0)
++		return NF_ACCEPT;
++
++	if (hl != 255 || !(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
++		icmpv6_error_log(skb, state, "invalid saddr or hoplimit for redirect");
++		return -NF_ACCEPT;
++	}
++
++	dataoff += sizeof(*rd_msg);
++
++	/* warning: rd_msg no longer usable after this call */
++	nd_opt = skb_header_pointer(skb, dataoff, sizeof(*nd_opt), &tmp.nd_opt);
++	if (!nd_opt || nd_opt->nd_opt_len == 0) {
++		icmpv6_error_log(skb, state, "redirect without options");
++		return -NF_ACCEPT;
++	}
++
++	/* We could call ndisc_parse_options(), but it would need
++	 * skb_linearize() and a bit more work.
++	 */
++	if (nd_opt->nd_opt_type != ND_OPT_REDIRECT_HDR)
++		return NF_ACCEPT;
++
++	memcpy(&outer_daddr.ip6, &ipv6_hdr(skb)->daddr,
++	       sizeof(outer_daddr.ip6));
++	dataoff += 8;
++	return nf_conntrack_inet_error(tmpl, skb, dataoff, state,
++				       IPPROTO_ICMPV6, &outer_daddr);
++}
++
+ int nf_conntrack_icmpv6_error(struct nf_conn *tmpl,
+ 			      struct sk_buff *skb,
+ 			      unsigned int dataoff,
+@@ -159,6 +209,9 @@ int nf_conntrack_icmpv6_error(struct nf_conn *tmpl,
+ 		return NF_ACCEPT;
+ 	}
+ 
++	if (icmp6h->icmp6_type == NDISC_REDIRECT)
++		return nf_conntrack_icmpv6_redirect(tmpl, skb, dataoff, state);
++
+ 	/* is not error message ? */
+ 	if (icmp6h->icmp6_type >= 128)
+ 		return NF_ACCEPT;
+diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
+index 0fdcdb2c9ae43..4d9b99abe37d6 100644
+--- a/net/netfilter/nf_flow_table_offload.c
++++ b/net/netfilter/nf_flow_table_offload.c
+@@ -383,12 +383,12 @@ static void flow_offload_ipv6_mangle(struct nf_flow_rule *flow_rule,
+ 				     const __be32 *addr, const __be32 *mask)
+ {
+ 	struct flow_action_entry *entry;
+-	int i, j;
++	int i;
+ 
+-	for (i = 0, j = 0; i < sizeof(struct in6_addr) / sizeof(u32); i += sizeof(u32), j++) {
++	for (i = 0; i < sizeof(struct in6_addr) / sizeof(u32); i++) {
+ 		entry = flow_action_entry_next(flow_rule);
+ 		flow_offload_mangle(entry, FLOW_ACT_MANGLE_HDR_TYPE_IP6,
+-				    offset + i, &addr[j], mask);
++				    offset + i * sizeof(u32), &addr[i], mask);
+ 	}
+ }
+ 
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 0a6f3c1e9ab75..7977f0422ecf6 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -1534,10 +1534,10 @@ static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats)
+ 	for_each_possible_cpu(cpu) {
+ 		cpu_stats = per_cpu_ptr(stats, cpu);
+ 		do {
+-			seq = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
++			seq = u64_stats_fetch_begin(&cpu_stats->syncp);
+ 			pkts = cpu_stats->pkts;
+ 			bytes = cpu_stats->bytes;
+-		} while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, seq));
++		} while (u64_stats_fetch_retry(&cpu_stats->syncp, seq));
+ 		total.pkts += pkts;
+ 		total.bytes += bytes;
+ 	}
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 8a22574ed7ad6..ac66cdc7b67b8 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -715,9 +715,9 @@ static void get_dp_stats(const struct datapath *dp, struct ovs_dp_stats *stats,
+ 		percpu_stats = per_cpu_ptr(dp->stats_percpu, i);
+ 
+ 		do {
+-			start = u64_stats_fetch_begin_irq(&percpu_stats->syncp);
++			start = u64_stats_fetch_begin(&percpu_stats->syncp);
+ 			local_stats = *percpu_stats;
+-		} while (u64_stats_fetch_retry_irq(&percpu_stats->syncp, start));
++		} while (u64_stats_fetch_retry(&percpu_stats->syncp, start));
+ 
+ 		stats->n_hit += local_stats.n_hit;
+ 		stats->n_missed += local_stats.n_missed;
+@@ -947,6 +947,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+ 	struct sw_flow_mask mask;
+ 	struct sk_buff *reply;
+ 	struct datapath *dp;
++	struct sw_flow_key *key;
+ 	struct sw_flow_actions *acts;
+ 	struct sw_flow_match match;
+ 	u32 ufid_flags = ovs_nla_get_ufid_flags(a[OVS_FLOW_ATTR_UFID_FLAGS]);
+@@ -974,24 +975,26 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+ 	}
+ 
+ 	/* Extract key. */
+-	ovs_match_init(&match, &new_flow->key, false, &mask);
++	key = kzalloc(sizeof(*key), GFP_KERNEL);
++	if (!key) {
++		error = -ENOMEM;
++		goto err_kfree_key;
++	}
++
++	ovs_match_init(&match, key, false, &mask);
+ 	error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
+ 				  a[OVS_FLOW_ATTR_MASK], log);
+ 	if (error)
+ 		goto err_kfree_flow;
+ 
++	ovs_flow_mask_key(&new_flow->key, key, true, &mask);
++
+ 	/* Extract flow identifier. */
+ 	error = ovs_nla_get_identifier(&new_flow->id, a[OVS_FLOW_ATTR_UFID],
+-				       &new_flow->key, log);
++				       key, log);
+ 	if (error)
+ 		goto err_kfree_flow;
+ 
+-	/* unmasked key is needed to match when ufid is not used. */
+-	if (ovs_identifier_is_key(&new_flow->id))
+-		match.key = new_flow->id.unmasked_key;
+-
+-	ovs_flow_mask_key(&new_flow->key, &new_flow->key, true, &mask);
+-
+ 	/* Validate actions. */
+ 	error = ovs_nla_copy_actions(net, a[OVS_FLOW_ATTR_ACTIONS],
+ 				     &new_flow->key, &acts, log);
+@@ -1018,7 +1021,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+ 	if (ovs_identifier_is_ufid(&new_flow->id))
+ 		flow = ovs_flow_tbl_lookup_ufid(&dp->table, &new_flow->id);
+ 	if (!flow)
+-		flow = ovs_flow_tbl_lookup(&dp->table, &new_flow->key);
++		flow = ovs_flow_tbl_lookup(&dp->table, key);
+ 	if (likely(!flow)) {
+ 		rcu_assign_pointer(new_flow->sf_acts, acts);
+ 
+@@ -1088,6 +1091,8 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
+ 
+ 	if (reply)
+ 		ovs_notify(&dp_flow_genl_family, reply, info);
++
++	kfree(key);
+ 	return 0;
+ 
+ err_unlock_ovs:
+@@ -1097,6 +1102,8 @@ err_kfree_acts:
+ 	ovs_nla_free_flow_actions(acts);
+ err_kfree_flow:
+ 	ovs_flow_free(new_flow, false);
++err_kfree_key:
++	kfree(key);
+ error:
+ 	return error;
+ }
+diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c
+index d4a2db0b22998..0a0e4c283f02e 100644
+--- a/net/openvswitch/flow_table.c
++++ b/net/openvswitch/flow_table.c
+@@ -205,9 +205,9 @@ static void tbl_mask_array_reset_counters(struct mask_array *ma)
+ 
+ 			stats = per_cpu_ptr(ma->masks_usage_stats, cpu);
+ 			do {
+-				start = u64_stats_fetch_begin_irq(&stats->syncp);
++				start = u64_stats_fetch_begin(&stats->syncp);
+ 				counter = stats->usage_cntrs[i];
+-			} while (u64_stats_fetch_retry_irq(&stats->syncp, start));
++			} while (u64_stats_fetch_retry(&stats->syncp, start));
+ 
+ 			ma->masks_usage_zero_cntr[i] += counter;
+ 		}
+@@ -1136,10 +1136,9 @@ void ovs_flow_masks_rebalance(struct flow_table *table)
+ 
+ 			stats = per_cpu_ptr(ma->masks_usage_stats, cpu);
+ 			do {
+-				start = u64_stats_fetch_begin_irq(&stats->syncp);
++				start = u64_stats_fetch_begin(&stats->syncp);
+ 				counter = stats->usage_cntrs[i];
+-			} while (u64_stats_fetch_retry_irq(&stats->syncp,
+-							   start));
++			} while (u64_stats_fetch_retry(&stats->syncp, start));
+ 
+ 			masks_and_count[i].counter += counter;
+ 		}
+diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
+index 9683617db7049..08c117bc083ec 100644
+--- a/net/rxrpc/output.c
++++ b/net/rxrpc/output.c
+@@ -93,7 +93,7 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn,
+ 	*_hard_ack = hard_ack;
+ 	*_top = top;
+ 
+-	pkt->ack.bufferSpace	= htons(8);
++	pkt->ack.bufferSpace	= htons(0);
+ 	pkt->ack.maxSkew	= htons(0);
+ 	pkt->ack.firstPacket	= htonl(hard_ack + 1);
+ 	pkt->ack.previousPacket	= htonl(call->ackr_highest_seq);
+diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c
+index 3c3a626459deb..d4e4e94f4f987 100644
+--- a/net/rxrpc/sendmsg.c
++++ b/net/rxrpc/sendmsg.c
+@@ -716,7 +716,7 @@ int rxrpc_do_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, size_t len)
+ 			if (call->tx_total_len != -1 ||
+ 			    call->tx_pending ||
+ 			    call->tx_top != 0)
+-				goto error_put;
++				goto out_put_unlock;
+ 			call->tx_total_len = p.call.tx_total_len;
+ 		}
+ 	}
+diff --git a/net/sched/ematch.c b/net/sched/ematch.c
+index 4ce6813618515..5c1235e6076ae 100644
+--- a/net/sched/ematch.c
++++ b/net/sched/ematch.c
+@@ -255,6 +255,8 @@ static int tcf_em_validate(struct tcf_proto *tp,
+ 			 * the value carried.
+ 			 */
+ 			if (em_hdr->flags & TCF_EM_SIMPLE) {
++				if (em->ops->datalen > 0)
++					goto errout;
+ 				if (data_len < sizeof(u32))
+ 					goto errout;
+ 				em->data = *(u32 *) data;
+diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
+index b46a416787ec3..43ebf090029d7 100644
+--- a/net/sctp/sysctl.c
++++ b/net/sctp/sysctl.c
+@@ -84,17 +84,18 @@ static struct ctl_table sctp_table[] = {
+ 	{ /* sentinel */ }
+ };
+ 
++/* The following index defines are used in sctp_sysctl_net_register().
++ * If you add new items to the sctp_net_table, please ensure that
++ * the index values of these defines hold the same meaning indicated by
++ * their macro names when they appear in sctp_net_table.
++ */
++#define SCTP_RTO_MIN_IDX       0
++#define SCTP_RTO_MAX_IDX       1
++#define SCTP_PF_RETRANS_IDX    2
++#define SCTP_PS_RETRANS_IDX    3
++
+ static struct ctl_table sctp_net_table[] = {
+-	{
+-		.procname	= "rto_initial",
+-		.data		= &init_net.sctp.rto_initial,
+-		.maxlen		= sizeof(unsigned int),
+-		.mode		= 0644,
+-		.proc_handler	= proc_dointvec_minmax,
+-		.extra1         = SYSCTL_ONE,
+-		.extra2         = &timer_max
+-	},
+-	{
++	[SCTP_RTO_MIN_IDX] = {
+ 		.procname	= "rto_min",
+ 		.data		= &init_net.sctp.rto_min,
+ 		.maxlen		= sizeof(unsigned int),
+@@ -103,7 +104,7 @@ static struct ctl_table sctp_net_table[] = {
+ 		.extra1         = SYSCTL_ONE,
+ 		.extra2         = &init_net.sctp.rto_max
+ 	},
+-	{
++	[SCTP_RTO_MAX_IDX] =  {
+ 		.procname	= "rto_max",
+ 		.data		= &init_net.sctp.rto_max,
+ 		.maxlen		= sizeof(unsigned int),
+@@ -112,6 +113,33 @@ static struct ctl_table sctp_net_table[] = {
+ 		.extra1         = &init_net.sctp.rto_min,
+ 		.extra2         = &timer_max
+ 	},
++	[SCTP_PF_RETRANS_IDX] = {
++		.procname	= "pf_retrans",
++		.data		= &init_net.sctp.pf_retrans,
++		.maxlen		= sizeof(int),
++		.mode		= 0644,
++		.proc_handler	= proc_dointvec_minmax,
++		.extra1		= SYSCTL_ZERO,
++		.extra2		= &init_net.sctp.ps_retrans,
++	},
++	[SCTP_PS_RETRANS_IDX] = {
++		.procname	= "ps_retrans",
++		.data		= &init_net.sctp.ps_retrans,
++		.maxlen		= sizeof(int),
++		.mode		= 0644,
++		.proc_handler	= proc_dointvec_minmax,
++		.extra1		= &init_net.sctp.pf_retrans,
++		.extra2		= &ps_retrans_max,
++	},
++	{
++		.procname	= "rto_initial",
++		.data		= &init_net.sctp.rto_initial,
++		.maxlen		= sizeof(unsigned int),
++		.mode		= 0644,
++		.proc_handler	= proc_dointvec_minmax,
++		.extra1         = SYSCTL_ONE,
++		.extra2         = &timer_max
++	},
+ 	{
+ 		.procname	= "rto_alpha_exp_divisor",
+ 		.data		= &init_net.sctp.rto_alpha,
+@@ -207,24 +235,6 @@ static struct ctl_table sctp_net_table[] = {
+ 		.extra1		= SYSCTL_ONE,
+ 		.extra2		= SYSCTL_INT_MAX,
+ 	},
+-	{
+-		.procname	= "pf_retrans",
+-		.data		= &init_net.sctp.pf_retrans,
+-		.maxlen		= sizeof(int),
+-		.mode		= 0644,
+-		.proc_handler	= proc_dointvec_minmax,
+-		.extra1		= SYSCTL_ZERO,
+-		.extra2		= &init_net.sctp.ps_retrans,
+-	},
+-	{
+-		.procname	= "ps_retrans",
+-		.data		= &init_net.sctp.ps_retrans,
+-		.maxlen		= sizeof(int),
+-		.mode		= 0644,
+-		.proc_handler	= proc_dointvec_minmax,
+-		.extra1		= &init_net.sctp.pf_retrans,
+-		.extra2		= &ps_retrans_max,
+-	},
+ 	{
+ 		.procname	= "sndbuf_policy",
+ 		.data		= &init_net.sctp.sndbuf_policy,
+@@ -586,6 +596,11 @@ int sctp_sysctl_net_register(struct net *net)
+ 	for (i = 0; table[i].data; i++)
+ 		table[i].data += (char *)(&net->sctp) - (char *)&init_net.sctp;
+ 
++	table[SCTP_RTO_MIN_IDX].extra2 = &net->sctp.rto_max;
++	table[SCTP_RTO_MAX_IDX].extra1 = &net->sctp.rto_min;
++	table[SCTP_PF_RETRANS_IDX].extra2 = &net->sctp.ps_retrans;
++	table[SCTP_PS_RETRANS_IDX].extra1 = &net->sctp.pf_retrans;
++
+ 	net->sctp.sysctl_header = register_net_sysctl(net, "net/sctp", table);
+ 	if (net->sctp.sysctl_header == NULL) {
+ 		kfree(table);
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index c284efa3d1efc..0918fa4cc9330 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -1391,7 +1391,7 @@ static int rpc_sockname(struct net *net, struct sockaddr *sap, size_t salen,
+ 		break;
+ 	default:
+ 		err = -EAFNOSUPPORT;
+-		goto out;
++		goto out_release;
+ 	}
+ 	if (err < 0) {
+ 		dprintk("RPC:       can't bind UDP socket (%d)\n", err);
+diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
+index 2fbe9aaeec349..efa7bcdf6b283 100644
+--- a/net/sunrpc/xprtrdma/verbs.c
++++ b/net/sunrpc/xprtrdma/verbs.c
+@@ -834,7 +834,7 @@ struct rpcrdma_req *rpcrdma_req_create(struct rpcrdma_xprt *r_xprt, size_t size,
+ 	return req;
+ 
+ out3:
+-	kfree(req->rl_sendbuf);
++	rpcrdma_regbuf_free(req->rl_sendbuf);
+ out2:
+ 	kfree(req);
+ out1:
+diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
+index fe27241cd13fc..0ee1df154fee0 100644
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -792,7 +792,7 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk,
+ 	struct sk_psock *psock;
+ 	struct sock *sk_redir;
+ 	struct tls_rec *rec;
+-	bool enospc, policy;
++	bool enospc, policy, redir_ingress;
+ 	int err = 0, send;
+ 	u32 delta = 0;
+ 
+@@ -837,6 +837,7 @@ more_data:
+ 		}
+ 		break;
+ 	case __SK_REDIRECT:
++		redir_ingress = psock->redir_ingress;
+ 		sk_redir = psock->sk_redir;
+ 		memcpy(&msg_redir, msg, sizeof(*msg));
+ 		if (msg->apply_bytes < send)
+@@ -846,7 +847,8 @@ more_data:
+ 		sk_msg_return_zero(sk, msg, send);
+ 		msg->sg.size -= send;
+ 		release_sock(sk);
+-		err = tcp_bpf_sendmsg_redir(sk_redir, &msg_redir, send, flags);
++		err = tcp_bpf_sendmsg_redir(sk_redir, redir_ingress,
++					    &msg_redir, send, flags);
+ 		lock_sock(sk);
+ 		if (err < 0) {
+ 			*copied -= sk_msg_free_nocharge(sk, &msg_redir);
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index d686804119c99..48cc8223b06be 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1969,13 +1969,20 @@ restart_locked:
+ 			unix_state_lock(sk);
+ 
+ 		err = 0;
+-		if (unix_peer(sk) == other) {
++		if (sk->sk_type == SOCK_SEQPACKET) {
++			/* We are here only when racing with unix_release_sock()
++			 * is clearing @other. Never change state to TCP_CLOSE
++			 * unlike SOCK_DGRAM wants.
++			 */
++			unix_state_unlock(sk);
++			err = -EPIPE;
++		} else if (unix_peer(sk) == other) {
+ 			unix_peer(sk) = NULL;
+ 			unix_dgram_peer_wake_disconnect_wakeup(sk, other);
+ 
++			sk->sk_state = TCP_CLOSE;
+ 			unix_state_unlock(sk);
+ 
+-			sk->sk_state = TCP_CLOSE;
+ 			unix_dgram_disconnected(sk, other);
+ 			sock_put(other);
+ 			err = -ECONNREFUSED;
+@@ -3724,6 +3731,7 @@ static int __init af_unix_init(void)
+ 	rc = proto_register(&unix_stream_proto, 1);
+ 	if (rc != 0) {
+ 		pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__);
++		proto_unregister(&unix_dgram_proto);
+ 		goto out;
+ 	}
+ 
+diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
+index b14f0ed7427bc..a794e8b011363 100644
+--- a/net/vmw_vsock/vmci_transport.c
++++ b/net/vmw_vsock/vmci_transport.c
+@@ -1711,7 +1711,11 @@ static int vmci_transport_dgram_enqueue(
+ 	if (!dg)
+ 		return -ENOMEM;
+ 
+-	memcpy_from_msg(VMCI_DG_PAYLOAD(dg), msg, len);
++	err = memcpy_from_msg(VMCI_DG_PAYLOAD(dg), msg, len);
++	if (err) {
++		kfree(dg);
++		return err;
++	}
+ 
+ 	dg->dst = vmci_make_handle(remote_addr->svm_cid,
+ 				   remote_addr->svm_port);
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index 2705e3ee8fc4e..3e41edace1ba7 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -3849,6 +3849,9 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
+ 		for_each_valid_link(wdev, link_id) {
+ 			struct nlattr *link = nla_nest_start(msg, link_id + 1);
+ 
++			if (!link)
++				goto nla_put_failure;
++
+ 			if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id))
+ 				goto nla_put_failure;
+ 			if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index c3d950d294329..4f3f31244e8ba 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -4311,8 +4311,10 @@ static int __init regulatory_init_db(void)
+ 		return -EINVAL;
+ 
+ 	err = load_builtin_regdb_keys();
+-	if (err)
++	if (err) {
++		platform_device_unregister(reg_pdev);
+ 		return err;
++	}
+ 
+ 	/* We always try to get an update for the static regdomain */
+ 	err = regulatory_hint_core(cfg80211_world_regdom->alpha2);
+diff --git a/samples/bpf/xdp1_user.c b/samples/bpf/xdp1_user.c
+index ac370e638fa3d..281dc964de8da 100644
+--- a/samples/bpf/xdp1_user.c
++++ b/samples/bpf/xdp1_user.c
+@@ -51,7 +51,7 @@ static void poll_stats(int map_fd, int interval)
+ 
+ 		sleep(interval);
+ 
+-		while (bpf_map_get_next_key(map_fd, &key, &key) != -1) {
++		while (bpf_map_get_next_key(map_fd, &key, &key) == 0) {
+ 			__u64 sum = 0;
+ 
+ 			assert(bpf_map_lookup_elem(map_fd, &key, values) == 0);
+diff --git a/samples/bpf/xdp2_kern.c b/samples/bpf/xdp2_kern.c
+index 3332ba6bb95fb..67804ecf7ce37 100644
+--- a/samples/bpf/xdp2_kern.c
++++ b/samples/bpf/xdp2_kern.c
+@@ -112,6 +112,10 @@ int xdp_prog1(struct xdp_md *ctx)
+ 
+ 	if (ipproto == IPPROTO_UDP) {
+ 		swap_src_dst_mac(data);
++
++		if (bpf_xdp_store_bytes(ctx, 0, pkt, sizeof(pkt)))
++			return rc;
++
+ 		rc = XDP_TX;
+ 	}
+ 
+diff --git a/samples/vfio-mdev/mdpy-fb.c b/samples/vfio-mdev/mdpy-fb.c
+index 9ec93d90e8a5a..4eb7aa11cfbb2 100644
+--- a/samples/vfio-mdev/mdpy-fb.c
++++ b/samples/vfio-mdev/mdpy-fb.c
+@@ -109,7 +109,7 @@ static int mdpy_fb_probe(struct pci_dev *pdev,
+ 
+ 	ret = pci_request_regions(pdev, "mdpy-fb");
+ 	if (ret < 0)
+-		return ret;
++		goto err_disable_dev;
+ 
+ 	pci_read_config_dword(pdev, MDPY_FORMAT_OFFSET, &format);
+ 	pci_read_config_dword(pdev, MDPY_WIDTH_OFFSET,	&width);
+@@ -191,6 +191,9 @@ err_release_fb:
+ err_release_regions:
+ 	pci_release_regions(pdev);
+ 
++err_disable_dev:
++	pci_disable_device(pdev);
++
+ 	return ret;
+ }
+ 
+@@ -199,7 +202,10 @@ static void mdpy_fb_remove(struct pci_dev *pdev)
+ 	struct fb_info *info = pci_get_drvdata(pdev);
+ 
+ 	unregister_framebuffer(info);
++	iounmap(info->screen_base);
+ 	framebuffer_release(info);
++	pci_release_regions(pdev);
++	pci_disable_device(pdev);
+ }
+ 
+ static struct pci_device_id mdpy_fb_pci_table[] = {
+diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
+index 995bc42003e6c..254e07f34234c 100644
+--- a/security/Kconfig.hardening
++++ b/security/Kconfig.hardening
+@@ -253,6 +253,9 @@ config INIT_ON_FREE_DEFAULT_ON
+ 
+ config CC_HAS_ZERO_CALL_USED_REGS
+ 	def_bool $(cc-option,-fzero-call-used-regs=used-gpr)
++	# https://github.com/ClangBuiltLinux/linux/issues/1766
++	# https://github.com/llvm/llvm-project/issues/59242
++	depends on !CC_IS_CLANG || CLANG_VERSION > 150006
+ 
+ config ZERO_CALL_USED_REGS
+ 	bool "Enable register zeroing on function exit"
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index d066ccc219e2d..7160e7aa58b94 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -868,8 +868,10 @@ static struct multi_transaction *multi_transaction_new(struct file *file,
+ 	if (!t)
+ 		return ERR_PTR(-ENOMEM);
+ 	kref_init(&t->count);
+-	if (copy_from_user(t->data, buf, size))
++	if (copy_from_user(t->data, buf, size)) {
++		put_multi_transaction(t);
+ 		return ERR_PTR(-EFAULT);
++	}
+ 
+ 	return t;
+ }
+diff --git a/security/apparmor/label.c b/security/apparmor/label.c
+index 0f36ee9074381..a67c5897ee254 100644
+--- a/security/apparmor/label.c
++++ b/security/apparmor/label.c
+@@ -197,15 +197,18 @@ static bool vec_is_stale(struct aa_profile **vec, int n)
+ 	return false;
+ }
+ 
+-static long union_vec_flags(struct aa_profile **vec, int n, long mask)
++static long accum_vec_flags(struct aa_profile **vec, int n)
+ {
+-	long u = 0;
++	long u = FLAG_UNCONFINED;
+ 	int i;
+ 
+ 	AA_BUG(!vec);
+ 
+ 	for (i = 0; i < n; i++) {
+-		u |= vec[i]->label.flags & mask;
++		u |= vec[i]->label.flags & (FLAG_DEBUG1 | FLAG_DEBUG2 |
++					    FLAG_STALE);
++		if (!(u & vec[i]->label.flags & FLAG_UNCONFINED))
++			u &= ~FLAG_UNCONFINED;
+ 	}
+ 
+ 	return u;
+@@ -1097,8 +1100,7 @@ static struct aa_label *label_merge_insert(struct aa_label *new,
+ 		else if (k == b->size)
+ 			return aa_get_label(b);
+ 	}
+-	new->flags |= union_vec_flags(new->vec, new->size, FLAG_UNCONFINED |
+-					      FLAG_DEBUG1 | FLAG_DEBUG2);
++	new->flags |= accum_vec_flags(new->vec, new->size);
+ 	ls = labels_set(new);
+ 	write_lock_irqsave(&ls->lock, flags);
+ 	label = __label_insert(labels_set(new), new, false);
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index e29cade7b6627..9eb7972e08e49 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -1194,10 +1194,10 @@ static int apparmor_inet_conn_request(const struct sock *sk, struct sk_buff *skb
+ #endif
+ 
+ /*
+- * The cred blob is a pointer to, not an instance of, an aa_task_ctx.
++ * The cred blob is a pointer to, not an instance of, an aa_label.
+  */
+ struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = {
+-	.lbs_cred = sizeof(struct aa_task_ctx *),
++	.lbs_cred = sizeof(struct aa_label *),
+ 	.lbs_file = sizeof(struct aa_file_ctx),
+ 	.lbs_task = sizeof(struct aa_task_ctx),
+ };
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
+index 499c0209b6a46..fbdfcef91c616 100644
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -1170,7 +1170,7 @@ ssize_t aa_remove_profiles(struct aa_ns *policy_ns, struct aa_label *subj,
+ 
+ 	if (!name) {
+ 		/* remove namespace - can only happen if fqname[0] == ':' */
+-		mutex_lock_nested(&ns->parent->lock, ns->level);
++		mutex_lock_nested(&ns->parent->lock, ns->parent->level);
+ 		__aa_bump_ns_revision(ns);
+ 		__aa_remove_ns(ns);
+ 		mutex_unlock(&ns->parent->lock);
+diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c
+index 43beaad083feb..78700d94b4533 100644
+--- a/security/apparmor/policy_ns.c
++++ b/security/apparmor/policy_ns.c
+@@ -134,7 +134,7 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name)
+ 	return ns;
+ 
+ fail_unconfined:
+-	kfree_sensitive(ns->base.hname);
++	aa_policy_destroy(&ns->base);
+ fail_ns:
+ 	kfree_sensitive(ns);
+ 	return NULL;
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index 55d31bac4f35b..9d26bbb901338 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -972,7 +972,7 @@ static int verify_header(struct aa_ext *e, int required, const char **ns)
+ 	 * if not specified use previous version
+ 	 * Mask off everything that is not kernel abi version
+ 	 */
+-	if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) {
++	if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v8)) {
+ 		audit_iface(NULL, NULL, NULL, "unsupported interface version",
+ 			    e, error);
+ 		return error;
+diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
+index 8a82a6c7f48a4..f2193c531f4a4 100644
+--- a/security/integrity/digsig.c
++++ b/security/integrity/digsig.c
+@@ -126,6 +126,7 @@ int __init integrity_init_keyring(const unsigned int id)
+ {
+ 	struct key_restriction *restriction;
+ 	key_perm_t perm;
++	int ret;
+ 
+ 	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
+ 		| KEY_USR_READ | KEY_USR_SEARCH;
+@@ -154,7 +155,10 @@ int __init integrity_init_keyring(const unsigned int id)
+ 		perm |= KEY_USR_WRITE;
+ 
+ out:
+-	return __integrity_init_keyring(id, perm, restriction);
++	ret = __integrity_init_keyring(id, perm, restriction);
++	if (ret)
++		kfree(restriction);
++	return ret;
+ }
+ 
+ static int __init integrity_add_key(const unsigned int id, const void *data,
+diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
+index a8802b8da946b..2edff7f58c25c 100644
+--- a/security/integrity/ima/ima_policy.c
++++ b/security/integrity/ima/ima_policy.c
+@@ -398,12 +398,6 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
+ 
+ 		nentry->lsm[i].type = entry->lsm[i].type;
+ 		nentry->lsm[i].args_p = entry->lsm[i].args_p;
+-		/*
+-		 * Remove the reference from entry so that the associated
+-		 * memory will not be freed during a later call to
+-		 * ima_lsm_free_rule(entry).
+-		 */
+-		entry->lsm[i].args_p = NULL;
+ 
+ 		ima_filter_rule_init(nentry->lsm[i].type, Audit_equal,
+ 				     nentry->lsm[i].args_p,
+@@ -417,6 +411,7 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
+ 
+ static int ima_lsm_update_rule(struct ima_rule_entry *entry)
+ {
++	int i;
+ 	struct ima_rule_entry *nentry;
+ 
+ 	nentry = ima_lsm_copy_rule(entry);
+@@ -431,7 +426,8 @@ static int ima_lsm_update_rule(struct ima_rule_entry *entry)
+ 	 * references and the entry itself. All other memory references will now
+ 	 * be owned by nentry.
+ 	 */
+-	ima_lsm_free_rule(entry);
++	for (i = 0; i < MAX_LSM_RULES; i++)
++		ima_filter_rule_free(entry->lsm[i].rule);
+ 	kfree(entry);
+ 
+ 	return 0;
+@@ -549,6 +545,9 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
+ 			    const char *func_data)
+ {
+ 	int i;
++	bool result = false;
++	struct ima_rule_entry *lsm_rule = rule;
++	bool rule_reinitialized = false;
+ 
+ 	if ((rule->flags & IMA_FUNC) &&
+ 	    (rule->func != func && func != POST_SETATTR))
+@@ -610,35 +609,55 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
+ 		int rc = 0;
+ 		u32 osid;
+ 
+-		if (!rule->lsm[i].rule) {
+-			if (!rule->lsm[i].args_p)
++		if (!lsm_rule->lsm[i].rule) {
++			if (!lsm_rule->lsm[i].args_p)
+ 				continue;
+ 			else
+ 				return false;
+ 		}
++
++retry:
+ 		switch (i) {
+ 		case LSM_OBJ_USER:
+ 		case LSM_OBJ_ROLE:
+ 		case LSM_OBJ_TYPE:
+ 			security_inode_getsecid(inode, &osid);
+-			rc = ima_filter_rule_match(osid, rule->lsm[i].type,
++			rc = ima_filter_rule_match(osid, lsm_rule->lsm[i].type,
+ 						   Audit_equal,
+-						   rule->lsm[i].rule);
++						   lsm_rule->lsm[i].rule);
+ 			break;
+ 		case LSM_SUBJ_USER:
+ 		case LSM_SUBJ_ROLE:
+ 		case LSM_SUBJ_TYPE:
+-			rc = ima_filter_rule_match(secid, rule->lsm[i].type,
++			rc = ima_filter_rule_match(secid, lsm_rule->lsm[i].type,
+ 						   Audit_equal,
+-						   rule->lsm[i].rule);
++						   lsm_rule->lsm[i].rule);
+ 			break;
+ 		default:
+ 			break;
+ 		}
+-		if (!rc)
+-			return false;
++
++		if (rc == -ESTALE && !rule_reinitialized) {
++			lsm_rule = ima_lsm_copy_rule(rule);
++			if (lsm_rule) {
++				rule_reinitialized = true;
++				goto retry;
++			}
++		}
++		if (!rc) {
++			result = false;
++			goto out;
++		}
+ 	}
+-	return true;
++	result = true;
++
++out:
++	if (rule_reinitialized) {
++		for (i = 0; i < MAX_LSM_RULES; i++)
++			ima_filter_rule_free(lsm_rule->lsm[i].rule);
++		kfree(lsm_rule);
++	}
++	return result;
+ }
+ 
+ /*
+diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
+index c25079faa2088..195ac18f09275 100644
+--- a/security/integrity/ima/ima_template.c
++++ b/security/integrity/ima/ima_template.c
+@@ -245,11 +245,11 @@ int template_desc_init_fields(const char *template_fmt,
+ 	}
+ 
+ 	if (fields && num_fields) {
+-		*fields = kmalloc_array(i, sizeof(*fields), GFP_KERNEL);
++		*fields = kmalloc_array(i, sizeof(**fields), GFP_KERNEL);
+ 		if (*fields == NULL)
+ 			return -ENOMEM;
+ 
+-		memcpy(*fields, found_fields, i * sizeof(*fields));
++		memcpy(*fields, found_fields, i * sizeof(**fields));
+ 		*num_fields = i;
+ 	}
+ 
+diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c
+index 44521582dcba2..d6767fddbd5a2 100644
+--- a/security/loadpin/loadpin.c
++++ b/security/loadpin/loadpin.c
+@@ -120,21 +120,11 @@ static void loadpin_sb_free_security(struct super_block *mnt_sb)
+ 	}
+ }
+ 
+-static int loadpin_read_file(struct file *file, enum kernel_read_file_id id,
+-			     bool contents)
++static int loadpin_check(struct file *file, enum kernel_read_file_id id)
+ {
+ 	struct super_block *load_root;
+ 	const char *origin = kernel_read_file_id_str(id);
+ 
+-	/*
+-	 * If we will not know that we'll be seeing the full contents
+-	 * then we cannot trust a load will be complete and unchanged
+-	 * off disk. Treat all contents=false hooks as if there were
+-	 * no associated file struct.
+-	 */
+-	if (!contents)
+-		file = NULL;
+-
+ 	/* If the file id is excluded, ignore the pinning. */
+ 	if ((unsigned int)id < ARRAY_SIZE(ignore_read_file_id) &&
+ 	    ignore_read_file_id[id]) {
+@@ -190,9 +180,25 @@ static int loadpin_read_file(struct file *file, enum kernel_read_file_id id,
+ 	return 0;
+ }
+ 
++static int loadpin_read_file(struct file *file, enum kernel_read_file_id id,
++			     bool contents)
++{
++	/*
++	 * LoadPin only cares about the _origin_ of a file, not its
++	 * contents, so we can ignore the "are full contents available"
++	 * argument here.
++	 */
++	return loadpin_check(file, id);
++}
++
+ static int loadpin_load_data(enum kernel_load_data_id id, bool contents)
+ {
+-	return loadpin_read_file(NULL, (enum kernel_read_file_id) id, contents);
++	/*
++	 * LoadPin only cares about the _origin_ of a file, not its
++	 * contents, so a NULL file is passed, and we can ignore the
++	 * state of "contents".
++	 */
++	return loadpin_check(NULL, (enum kernel_read_file_id) id);
+ }
+ 
+ static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = {
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
+index ad0541e9e8880..ac985cec5c165 100644
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -1432,8 +1432,10 @@ static int snd_pcm_do_start(struct snd_pcm_substream *substream,
+ static void snd_pcm_undo_start(struct snd_pcm_substream *substream,
+ 			       snd_pcm_state_t state)
+ {
+-	if (substream->runtime->trigger_master == substream)
++	if (substream->runtime->trigger_master == substream) {
+ 		substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
++		substream->runtime->stop_operating = true;
++	}
+ }
+ 
+ static void snd_pcm_post_start(struct snd_pcm_substream *substream,
+diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
+index d3bc9e8c407dc..f0d34cf70c3e0 100644
+--- a/sound/drivers/mts64.c
++++ b/sound/drivers/mts64.c
+@@ -815,6 +815,9 @@ static void snd_mts64_interrupt(void *private)
+ 	u8 status, data;
+ 	struct snd_rawmidi_substream *substream;
+ 
++	if (!mts)
++		return;
++
+ 	spin_lock(&mts->lock);
+ 	ret = mts64_read(mts->pardev->port);
+ 	data = ret & 0x00ff;
+diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
+index f3582012d22f3..eea22cf72aefd 100644
+--- a/sound/hda/hdac_stream.c
++++ b/sound/hda/hdac_stream.c
+@@ -142,17 +142,28 @@ void snd_hdac_stream_stop(struct hdac_stream *azx_dev)
+ }
+ EXPORT_SYMBOL_GPL(snd_hdac_stream_stop);
+ 
++/**
++ * snd_hdac_stop_streams - stop all streams
++ * @bus: HD-audio core bus
++ */
++void snd_hdac_stop_streams(struct hdac_bus *bus)
++{
++	struct hdac_stream *stream;
++
++	list_for_each_entry(stream, &bus->stream_list, list)
++		snd_hdac_stream_stop(stream);
++}
++EXPORT_SYMBOL_GPL(snd_hdac_stop_streams);
++
+ /**
+  * snd_hdac_stop_streams_and_chip - stop all streams and chip if running
+  * @bus: HD-audio core bus
+  */
+ void snd_hdac_stop_streams_and_chip(struct hdac_bus *bus)
+ {
+-	struct hdac_stream *stream;
+ 
+ 	if (bus->chip_init) {
+-		list_for_each_entry(stream, &bus->stream_list, list)
+-			snd_hdac_stream_stop(stream);
++		snd_hdac_stop_streams(bus);
+ 		snd_hdac_bus_stop_chip(bus);
+ 	}
+ }
+diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c
+index bb31b7fe867d6..477a5b4b50bcb 100644
+--- a/sound/pci/asihpi/hpioctl.c
++++ b/sound/pci/asihpi/hpioctl.c
+@@ -361,7 +361,7 @@ int asihpi_adapter_probe(struct pci_dev *pci_dev,
+ 		pci_dev->device, pci_dev->subsystem_vendor,
+ 		pci_dev->subsystem_device, pci_dev->devfn);
+ 
+-	if (pci_enable_device(pci_dev) < 0) {
++	if (pcim_enable_device(pci_dev) < 0) {
+ 		dev_err(&pci_dev->dev,
+ 			"pci_enable_device failed, disabling device\n");
+ 		return -EIO;
+diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
+index 384426d7e9ddc..c853cba7fc2bf 100644
+--- a/sound/pci/hda/hda_codec.c
++++ b/sound/pci/hda/hda_codec.c
+@@ -2893,7 +2893,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec)
+ 	snd_hdac_enter_pm(&codec->core);
+ 	if (codec->patch_ops.suspend)
+ 		codec->patch_ops.suspend(codec);
+-	hda_cleanup_all_streams(codec);
++	if (!codec->no_stream_clean_at_suspend)
++		hda_cleanup_all_streams(codec);
+ 	state = hda_set_power_state(codec, AC_PWRST_D3);
+ 	update_power_acct(codec, true);
+ 	snd_hdac_leave_pm(&codec->core);
+diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
+index 75dcb14ff20ad..0ff286b7b66be 100644
+--- a/sound/pci/hda/hda_controller.c
++++ b/sound/pci/hda/hda_controller.c
+@@ -1033,10 +1033,8 @@ EXPORT_SYMBOL_GPL(azx_init_chip);
+ void azx_stop_all_streams(struct azx *chip)
+ {
+ 	struct hdac_bus *bus = azx_bus(chip);
+-	struct hdac_stream *s;
+ 
+-	list_for_each_entry(s, &bus->stream_list, list)
+-		snd_hdac_stream_stop(s);
++	snd_hdac_stop_streams(bus);
+ }
+ EXPORT_SYMBOL_GPL(azx_stop_all_streams);
+ 
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index 287f4f78e7b1e..913509b29f938 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -167,8 +167,6 @@ struct hdmi_spec {
+ 	struct hdmi_ops ops;
+ 
+ 	bool dyn_pin_out;
+-	bool dyn_pcm_assign;
+-	bool dyn_pcm_no_legacy;
+ 	/* hdmi interrupt trigger control flag for Nvidia codec */
+ 	bool hdmi_intr_trig_ctrl;
+ 	bool nv_dp_workaround; /* workaround DP audio infoframe for Nvidia */
+@@ -1187,9 +1185,7 @@ static void pin_cvt_fixup(struct hda_codec *codec,
+ 		spec->ops.pin_cvt_fixup(codec, per_pin, cvt_nid);
+ }
+ 
+-/* called in hdmi_pcm_open when no pin is assigned to the PCM
+- * in dyn_pcm_assign mode.
+- */
++/* called in hdmi_pcm_open when no pin is assigned to the PCM */
+ static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo,
+ 			 struct hda_codec *codec,
+ 			 struct snd_pcm_substream *substream)
+@@ -1257,19 +1253,12 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
+ 
+ 	mutex_lock(&spec->pcm_lock);
+ 	pin_idx = hinfo_to_pin_index(codec, hinfo);
+-	if (!spec->dyn_pcm_assign) {
+-		if (snd_BUG_ON(pin_idx < 0)) {
+-			err = -EINVAL;
+-			goto unlock;
+-		}
+-	} else {
+-		/* no pin is assigned to the PCM
+-		 * PA need pcm open successfully when probe
+-		 */
+-		if (pin_idx < 0) {
+-			err = hdmi_pcm_open_no_pin(hinfo, codec, substream);
+-			goto unlock;
+-		}
++	/* no pin is assigned to the PCM
++	 * PA need pcm open successfully when probe
++	 */
++	if (pin_idx < 0) {
++		err = hdmi_pcm_open_no_pin(hinfo, codec, substream);
++		goto unlock;
+ 	}
+ 
+ 	err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, false);
+@@ -1374,43 +1363,6 @@ static int hdmi_find_pcm_slot(struct hdmi_spec *spec,
+ {
+ 	int i;
+ 
+-	/* on the new machines, try to assign the pcm slot dynamically,
+-	 * not use the preferred fixed map (legacy way) anymore.
+-	 */
+-	if (spec->dyn_pcm_no_legacy)
+-		goto last_try;
+-
+-	/*
+-	 * generic_hdmi_build_pcms() may allocate extra PCMs on some
+-	 * platforms (with maximum of 'num_nids + dev_num - 1')
+-	 *
+-	 * The per_pin of pin_nid_idx=n and dev_id=m prefers to get pcm-n
+-	 * if m==0. This guarantees that dynamic pcm assignments are compatible
+-	 * with the legacy static per_pin-pcm assignment that existed in the
+-	 * days before DP-MST.
+-	 *
+-	 * Intel DP-MST prefers this legacy behavior for compatibility, too.
+-	 *
+-	 * per_pin of m!=0 prefers to get pcm=(num_nids + (m - 1)).
+-	 */
+-
+-	if (per_pin->dev_id == 0 || spec->intel_hsw_fixup) {
+-		if (!test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap))
+-			return per_pin->pin_nid_idx;
+-	} else {
+-		i = spec->num_nids + (per_pin->dev_id - 1);
+-		if (i < spec->pcm_used && !(test_bit(i, &spec->pcm_bitmap)))
+-			return i;
+-	}
+-
+-	/* have a second try; check the area over num_nids */
+-	for (i = spec->num_nids; i < spec->pcm_used; i++) {
+-		if (!test_bit(i, &spec->pcm_bitmap))
+-			return i;
+-	}
+-
+- last_try:
+-	/* the last try; check the empty slots in pins */
+ 	for (i = 0; i < spec->pcm_used; i++) {
+ 		if (!test_bit(i, &spec->pcm_bitmap))
+ 			return i;
+@@ -1573,14 +1525,12 @@ static void update_eld(struct hda_codec *codec,
+ 	 */
+ 	pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
+ 
+-	if (spec->dyn_pcm_assign) {
+-		if (eld->eld_valid) {
+-			hdmi_attach_hda_pcm(spec, per_pin);
+-			hdmi_pcm_setup_pin(spec, per_pin);
+-		} else {
+-			hdmi_pcm_reset_pin(spec, per_pin);
+-			hdmi_detach_hda_pcm(spec, per_pin);
+-		}
++	if (eld->eld_valid) {
++		hdmi_attach_hda_pcm(spec, per_pin);
++		hdmi_pcm_setup_pin(spec, per_pin);
++	} else {
++		hdmi_pcm_reset_pin(spec, per_pin);
++		hdmi_detach_hda_pcm(spec, per_pin);
+ 	}
+ 	/* if pcm_idx == -1, it means this is in monitor connection event
+ 	 * we can get the correct pcm_idx now.
+@@ -1788,6 +1738,7 @@ static void silent_stream_enable(struct hda_codec *codec,
+ 
+ 	switch (spec->silent_stream_type) {
+ 	case SILENT_STREAM_KAE:
++		silent_stream_enable_i915(codec, per_pin);
+ 		silent_stream_set_kae(codec, per_pin, true);
+ 		break;
+ 	case SILENT_STREAM_I915:
+@@ -1942,7 +1893,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
+ 		 * structures based on worst case.
+ 		 */
+ 		dev_num = spec->dev_num;
+-	} else if (spec->dyn_pcm_assign && codec->dp_mst) {
++	} else if (codec->dp_mst) {
+ 		dev_num = snd_hda_get_num_devices(codec, pin_nid) + 1;
+ 		/*
+ 		 * spec->dev_num is the maxinum number of device entries
+@@ -1967,13 +1918,8 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
+ 		if (!per_pin)
+ 			return -ENOMEM;
+ 
+-		if (spec->dyn_pcm_assign) {
+-			per_pin->pcm = NULL;
+-			per_pin->pcm_idx = -1;
+-		} else {
+-			per_pin->pcm = get_hdmi_pcm(spec, pin_idx);
+-			per_pin->pcm_idx = pin_idx;
+-		}
++		per_pin->pcm = NULL;
++		per_pin->pcm_idx = -1;
+ 		per_pin->pin_nid = pin_nid;
+ 		per_pin->pin_nid_idx = spec->num_nids;
+ 		per_pin->dev_id = i;
+@@ -1982,6 +1928,8 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
+ 		err = hdmi_read_pin_conn(codec, pin_idx);
+ 		if (err < 0)
+ 			return err;
++		if (!is_jack_detectable(codec, pin_nid))
++			codec_warn(codec, "HDMI: pin NID 0x%x - jack not detectable\n", pin_nid);
+ 		spec->num_pins++;
+ 	}
+ 	spec->num_nids++;
+@@ -2028,6 +1976,7 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
+ static const struct snd_pci_quirk force_connect_list[] = {
+ 	SND_PCI_QUIRK(0x103c, 0x870f, "HP", 1),
+ 	SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1),
++	SND_PCI_QUIRK(0x103c, 0x8711, "HP", 1),
+ 	SND_PCI_QUIRK(0x1462, 0xec94, "MS-7C94", 1),
+ 	SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", 1),
+ 	{}
+@@ -2129,10 +2078,9 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+ 
+ 	mutex_lock(&spec->pcm_lock);
+ 	pin_idx = hinfo_to_pin_index(codec, hinfo);
+-	if (spec->dyn_pcm_assign && pin_idx < 0) {
+-		/* when dyn_pcm_assign and pcm is not bound to a pin
+-		 * skip pin setup and return 0 to make audio playback
+-		 * be ongoing
++	if (pin_idx < 0) {
++		/* when pcm is not bound to a pin skip pin setup and return 0
++		 * to make audio playback be ongoing
+ 		 */
+ 		pin_cvt_fixup(codec, NULL, cvt_nid);
+ 		snd_hda_codec_setup_stream(codec, cvt_nid,
+@@ -2235,7 +2183,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
+ 		snd_hda_spdif_ctls_unassign(codec, pcm_idx);
+ 		clear_bit(pcm_idx, &spec->pcm_in_use);
+ 		pin_idx = hinfo_to_pin_index(codec, hinfo);
+-		if (spec->dyn_pcm_assign && pin_idx < 0)
++		if (pin_idx < 0)
+ 			goto unlock;
+ 
+ 		if (snd_BUG_ON(pin_idx < 0)) {
+@@ -2333,21 +2281,8 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
+ 	struct hdmi_spec *spec = codec->spec;
+ 	int idx, pcm_num;
+ 
+-	/*
+-	 * for non-mst mode, pcm number is the same as before
+-	 * for DP MST mode without extra PCM, pcm number is same
+-	 * for DP MST mode with extra PCMs, pcm number is
+-	 *  (nid number + dev_num - 1)
+-	 * dev_num is the device entry number in a pin
+-	 */
+-
+-	if (spec->dyn_pcm_no_legacy && codec->mst_no_extra_pcms)
+-		pcm_num = spec->num_cvts;
+-	else if (codec->mst_no_extra_pcms)
+-		pcm_num = spec->num_nids;
+-	else
+-		pcm_num = spec->num_nids + spec->dev_num - 1;
+-
++	/* limit the PCM devices to the codec converters */
++	pcm_num = spec->num_cvts;
+ 	codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num);
+ 
+ 	for (idx = 0; idx < pcm_num; idx++) {
+@@ -2386,17 +2321,12 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx)
+ {
+ 	char hdmi_str[32] = "HDMI/DP";
+ 	struct hdmi_spec *spec = codec->spec;
+-	struct hdmi_spec_per_pin *per_pin = get_pin(spec, pcm_idx);
+ 	struct snd_jack *jack;
+ 	int pcmdev = get_pcm_rec(spec, pcm_idx)->device;
+ 	int err;
+ 
+ 	if (pcmdev > 0)
+ 		sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);
+-	if (!spec->dyn_pcm_assign &&
+-	    !is_jack_detectable(codec, per_pin->pin_nid))
+-		strncat(hdmi_str, " Phantom",
+-			sizeof(hdmi_str) - strlen(hdmi_str) - 1);
+ 
+ 	err = snd_jack_new(codec->card, hdmi_str, SND_JACK_AVOUT, &jack,
+ 			   true, false);
+@@ -2429,18 +2359,9 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
+ 		/* create the spdif for each pcm
+ 		 * pin will be bound when monitor is connected
+ 		 */
+-		if (spec->dyn_pcm_assign)
+-			err = snd_hda_create_dig_out_ctls(codec,
++		err = snd_hda_create_dig_out_ctls(codec,
+ 					  0, spec->cvt_nids[0],
+ 					  HDA_PCM_TYPE_HDMI);
+-		else {
+-			struct hdmi_spec_per_pin *per_pin =
+-				get_pin(spec, pcm_idx);
+-			err = snd_hda_create_dig_out_ctls(codec,
+-						  per_pin->pin_nid,
+-						  per_pin->mux_nids[0],
+-						  HDA_PCM_TYPE_HDMI);
+-		}
+ 		if (err < 0)
+ 			return err;
+ 		snd_hda_spdif_ctls_unassign(codec, pcm_idx);
+@@ -2560,11 +2481,7 @@ static void generic_hdmi_free(struct hda_codec *codec)
+ 	for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
+ 		if (spec->pcm_rec[pcm_idx].jack == NULL)
+ 			continue;
+-		if (spec->dyn_pcm_assign)
+-			snd_device_free(codec->card,
+-					spec->pcm_rec[pcm_idx].jack);
+-		else
+-			spec->pcm_rec[pcm_idx].jack = NULL;
++		snd_device_free(codec->card, spec->pcm_rec[pcm_idx].jack);
+ 	}
+ 
+ 	generic_spec_free(codec);
+@@ -2963,9 +2880,33 @@ static int i915_hsw_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
+ 				 hda_nid_t pin_nid, int dev_id, u32 stream_tag,
+ 				 int format)
+ {
++	struct hdmi_spec *spec = codec->spec;
++	int pin_idx = pin_id_to_pin_index(codec, pin_nid, dev_id);
++	struct hdmi_spec_per_pin *per_pin;
++	int res;
++
++	if (pin_idx < 0)
++		per_pin = NULL;
++	else
++		per_pin = get_pin(spec, pin_idx);
++
+ 	haswell_verify_D0(codec, cvt_nid, pin_nid);
+-	return hdmi_setup_stream(codec, cvt_nid, pin_nid, dev_id,
+-				 stream_tag, format);
++
++	if (spec->silent_stream_type == SILENT_STREAM_KAE && per_pin && per_pin->silent_stream) {
++		silent_stream_set_kae(codec, per_pin, false);
++		/* wait for pending transfers in codec to clear */
++		usleep_range(100, 200);
++	}
++
++	res = hdmi_setup_stream(codec, cvt_nid, pin_nid, dev_id,
++				stream_tag, format);
++
++	if (spec->silent_stream_type == SILENT_STREAM_KAE && per_pin && per_pin->silent_stream) {
++		usleep_range(100, 200);
++		silent_stream_set_kae(codec, per_pin, true);
++	}
++
++	return res;
+ }
+ 
+ /* pin_cvt_fixup ops override for HSW+ and VLV+ */
+@@ -2985,6 +2926,88 @@ static void i915_pin_cvt_fixup(struct hda_codec *codec,
+ 	}
+ }
+ 
++#ifdef CONFIG_PM
++static int i915_adlp_hdmi_suspend(struct hda_codec *codec)
++{
++	struct hdmi_spec *spec = codec->spec;
++	bool silent_streams = false;
++	int pin_idx, res;
++
++	res = generic_hdmi_suspend(codec);
++
++	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
++		struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
++
++		if (per_pin->silent_stream) {
++			silent_streams = true;
++			break;
++		}
++	}
++
++	if (silent_streams && spec->silent_stream_type == SILENT_STREAM_KAE) {
++		/*
++		 * stream-id should remain programmed when codec goes
++		 * to runtime suspend
++		 */
++		codec->no_stream_clean_at_suspend = 1;
++
++		/*
++		 * the system might go to S3, in which case keep-alive
++		 * must be reprogrammed upon resume
++		 */
++		codec->forced_resume = 1;
++
++		codec_dbg(codec, "HDMI: KAE active at suspend\n");
++	} else {
++		codec->no_stream_clean_at_suspend = 0;
++		codec->forced_resume = 0;
++	}
++
++	return res;
++}
++
++static int i915_adlp_hdmi_resume(struct hda_codec *codec)
++{
++	struct hdmi_spec *spec = codec->spec;
++	int pin_idx, res;
++
++	res = generic_hdmi_resume(codec);
++
++	/* KAE not programmed at suspend, nothing to do here */
++	if (!codec->no_stream_clean_at_suspend)
++		return res;
++
++	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
++		struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
++
++		/*
++		 * If system was in suspend with monitor connected,
++		 * the codec setting may have been lost. Re-enable
++		 * keep-alive.
++		 */
++		if (per_pin->silent_stream) {
++			unsigned int param;
++
++			param = snd_hda_codec_read(codec, per_pin->cvt_nid, 0,
++						   AC_VERB_GET_CONV, 0);
++			if (!param) {
++				codec_dbg(codec, "HDMI: KAE: restore stream id\n");
++				silent_stream_enable_i915(codec, per_pin);
++			}
++
++			param = snd_hda_codec_read(codec, per_pin->cvt_nid, 0,
++						   AC_VERB_GET_DIGI_CONVERT_1, 0);
++			if (!(param & (AC_DIG3_KAE << 16))) {
++				codec_dbg(codec, "HDMI: KAE: restore DIG3_KAE\n");
++				silent_stream_set_kae(codec, per_pin, true);
++			}
++		}
++	}
++
++	return res;
++}
++#endif
++
+ /* precondition and allocation for Intel codecs */
+ static int alloc_intel_hdmi(struct hda_codec *codec)
+ {
+@@ -3038,7 +3061,6 @@ static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid,
+ 		return err;
+ 	spec = codec->spec;
+ 	codec->dp_mst = true;
+-	spec->dyn_pcm_assign = true;
+ 	spec->vendor_nid = vendor_nid;
+ 	spec->port_map = port_map;
+ 	spec->port_num = port_num;
+@@ -3102,17 +3124,9 @@ static int patch_i915_tgl_hdmi(struct hda_codec *codec)
+ 	 * the index indicate the port number.
+ 	 */
+ 	static const int map[] = {0x4, 0x6, 0x8, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
+-	int ret;
+-
+-	ret = intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map), 4,
+-				    enable_silent_stream);
+-	if (!ret) {
+-		struct hdmi_spec *spec = codec->spec;
+ 
+-		spec->dyn_pcm_no_legacy = true;
+-	}
+-
+-	return ret;
++	return intel_hsw_common_init(codec, 0x02, map, ARRAY_SIZE(map), 4,
++				     enable_silent_stream);
+ }
+ 
+ static int patch_i915_adlp_hdmi(struct hda_codec *codec)
+@@ -3124,8 +3138,14 @@ static int patch_i915_adlp_hdmi(struct hda_codec *codec)
+ 	if (!res) {
+ 		spec = codec->spec;
+ 
+-		if (spec->silent_stream_type)
++		if (spec->silent_stream_type) {
+ 			spec->silent_stream_type = SILENT_STREAM_KAE;
++
++#ifdef CONFIG_PM
++			codec->patch_ops.resume = i915_adlp_hdmi_resume;
++			codec->patch_ops.suspend = i915_adlp_hdmi_suspend;
++#endif
++		}
+ 	}
+ 
+ 	return res;
+@@ -3752,7 +3772,6 @@ static int patch_nvhdmi(struct hda_codec *codec)
+ 	codec->dp_mst = true;
+ 
+ 	spec = codec->spec;
+-	spec->dyn_pcm_assign = true;
+ 
+ 	err = hdmi_parse_codec(codec);
+ 	if (err < 0) {
+@@ -4032,10 +4051,8 @@ static int patch_tegra234_hdmi(struct hda_codec *codec)
+ 		return err;
+ 
+ 	codec->dp_mst = true;
+-	codec->mst_no_extra_pcms = true;
+ 	spec = codec->spec;
+ 	spec->dyn_pin_out = true;
+-	spec->dyn_pcm_assign = true;
+ 	spec->hdmi_intr_trig_ctrl = true;
+ 
+ 	return tegra_hdmi_init(codec);
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index ce6ea8819562b..94fe842178947 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10984,6 +10984,17 @@ static void alc897_fixup_lenovo_headset_mic(struct hda_codec *codec,
+ 	}
+ }
+ 
++static void alc897_fixup_lenovo_headset_mode(struct hda_codec *codec,
++				     const struct hda_fixup *fix, int action)
++{
++	struct alc_spec *spec = codec->spec;
++
++	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
++		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
++		spec->gen.hp_automute_hook = alc897_hp_automute_hook;
++	}
++}
++
+ static const struct coef_fw alc668_coefs[] = {
+ 	WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03,    0x0),
+ 	WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06,    0x0), WRITE_COEF(0x07, 0x0f80),
+@@ -11067,6 +11078,8 @@ enum {
+ 	ALC897_FIXUP_LENOVO_HEADSET_MIC,
+ 	ALC897_FIXUP_HEADSET_MIC_PIN,
+ 	ALC897_FIXUP_HP_HSMIC_VERB,
++	ALC897_FIXUP_LENOVO_HEADSET_MODE,
++	ALC897_FIXUP_HEADSET_MIC_PIN2,
+ };
+ 
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -11493,6 +11506,19 @@ static const struct hda_fixup alc662_fixups[] = {
+ 			{ }
+ 		},
+ 	},
++	[ALC897_FIXUP_LENOVO_HEADSET_MODE] = {
++		.type = HDA_FIXUP_FUNC,
++		.v.func = alc897_fixup_lenovo_headset_mode,
++	},
++	[ALC897_FIXUP_HEADSET_MIC_PIN2] = {
++		.type = HDA_FIXUP_PINS,
++		.v.pins = (const struct hda_pintbl[]) {
++			{ 0x1a, 0x01a11140 }, /* use as headset mic, without its own jack detect */
++			{ }
++		},
++		.chained = true,
++		.chain_id = ALC897_FIXUP_LENOVO_HEADSET_MODE
++	},
+ };
+ 
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+@@ -11545,6 +11571,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x17aa, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN),
+ 	SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN),
+ 	SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN),
++	SND_PCI_QUIRK(0x17aa, 0x3742, "Lenovo TianYi510Pro-14IOB", ALC897_FIXUP_HEADSET_MIC_PIN2),
+ 	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
+ 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
+ 	SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index d9715bea965e1..1f0b5527c5949 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -213,6 +213,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
+ 		}
+ 	},
++	{
++		.driver_data = &acp6x_card,
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 14 2022"),
++		}
++	},
+ 	{}
+ };
+ 
+diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c
+index ad20a3dff9b7e..61e8e9be6b8d7 100644
+--- a/sound/soc/codecs/hda.c
++++ b/sound/soc/codecs/hda.c
+@@ -224,9 +224,6 @@ static int hda_codec_probe(struct snd_soc_component *component)
+ 		goto err;
+ 	}
+ 
+-	/* configure codec for 1:1 PCM:DAI mapping */
+-	codec->mst_no_extra_pcms = 1;
+-
+ 	ret = snd_hda_codec_parse_pcms(codec);
+ 	if (ret < 0) {
+ 		dev_err(&hdev->dev, "unable to map pcms to dai %d\n", ret);
+diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c
+index 8debcee592247..7876bdd558a7a 100644
+--- a/sound/soc/codecs/hdac_hda.c
++++ b/sound/soc/codecs/hdac_hda.c
+@@ -461,9 +461,6 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component)
+ 		dev_dbg(&hdev->dev, "no patch file found\n");
+ 	}
+ 
+-	/* configure codec for 1:1 PCM:DAI mapping */
+-	hcodec->mst_no_extra_pcms = 1;
+-
+ 	ret = snd_hda_codec_parse_pcms(hcodec);
+ 	if (ret < 0) {
+ 		dev_err(&hdev->dev, "unable to map pcms to dai %d\n", ret);
+diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c
+index 767463e82665c..89059a673cf09 100644
+--- a/sound/soc/codecs/pcm512x.c
++++ b/sound/soc/codecs/pcm512x.c
+@@ -1634,7 +1634,7 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
+ 			if (val > 6) {
+ 				dev_err(dev, "Invalid pll-in\n");
+ 				ret = -EINVAL;
+-				goto err_clk;
++				goto err_pm;
+ 			}
+ 			pcm512x->pll_in = val;
+ 		}
+@@ -1643,7 +1643,7 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
+ 			if (val > 6) {
+ 				dev_err(dev, "Invalid pll-out\n");
+ 				ret = -EINVAL;
+-				goto err_clk;
++				goto err_pm;
+ 			}
+ 			pcm512x->pll_out = val;
+ 		}
+@@ -1652,12 +1652,12 @@ int pcm512x_probe(struct device *dev, struct regmap *regmap)
+ 			dev_err(dev,
+ 				"Error: both pll-in and pll-out, or none\n");
+ 			ret = -EINVAL;
+-			goto err_clk;
++			goto err_pm;
+ 		}
+ 		if (pcm512x->pll_in && pcm512x->pll_in == pcm512x->pll_out) {
+ 			dev_err(dev, "Error: pll-in == pll-out\n");
+ 			ret = -EINVAL;
+-			goto err_clk;
++			goto err_pm;
+ 		}
+ 	}
+ #endif
+diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c
+index b0b53d4f07df9..5f36064ed6e6f 100644
+--- a/sound/soc/codecs/rt298.c
++++ b/sound/soc/codecs/rt298.c
+@@ -1166,6 +1166,13 @@ static const struct dmi_system_id force_combo_jack_table[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "Geminilake")
+ 		}
+ 	},
++	{
++		.ident = "Intel Kabylake R RVP",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "Kabylake Client platform")
++		}
++	},
+ 	{ }
+ };
+ 
+diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
+index 60dbfa2a54f1b..c75045e371b20 100644
+--- a/sound/soc/codecs/rt5670.c
++++ b/sound/soc/codecs/rt5670.c
+@@ -3311,8 +3311,6 @@ static int rt5670_i2c_probe(struct i2c_client *i2c)
+ 	if (ret < 0)
+ 		goto err;
+ 
+-	pm_runtime_put(&i2c->dev);
+-
+ 	return 0;
+ err:
+ 	pm_runtime_disable(&i2c->dev);
+diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
+index d3cfd3788f2ab..8fe9a75d12357 100644
+--- a/sound/soc/codecs/wm8994.c
++++ b/sound/soc/codecs/wm8994.c
+@@ -3853,7 +3853,12 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
+ 	} else {
+ 		dev_dbg(component->dev, "Jack not detected\n");
+ 
++		/* Release wm8994->accdet_lock to avoid deadlock:
++		 * cancel_delayed_work_sync() takes wm8994->mic_work internal
++		 * lock and wm1811_mic_work takes wm8994->accdet_lock */
++		mutex_unlock(&wm8994->accdet_lock);
+ 		cancel_delayed_work_sync(&wm8994->mic_work);
++		mutex_lock(&wm8994->accdet_lock);
+ 
+ 		snd_soc_component_update_bits(component, WM8958_MICBIAS2,
+ 				    WM8958_MICB2_DISCH, WM8958_MICB2_DISCH);
+diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c
+index 63e1d7aa61379..9dfa0ac08e6f0 100644
+--- a/sound/soc/codecs/wsa883x.c
++++ b/sound/soc/codecs/wsa883x.c
+@@ -7,7 +7,7 @@
+ #include <linux/debugfs.h>
+ #include <linux/delay.h>
+ #include <linux/device.h>
+-#include <linux/gpio.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+@@ -1393,7 +1393,7 @@ static int wsa883x_probe(struct sdw_slave *pdev,
+ 	}
+ 
+ 	wsa883x->sd_n = devm_gpiod_get_optional(&pdev->dev, "powerdown",
+-						GPIOD_FLAGS_BIT_NONEXCLUSIVE);
++						GPIOD_FLAGS_BIT_NONEXCLUSIVE | GPIOD_OUT_HIGH);
+ 	if (IS_ERR(wsa883x->sd_n)) {
+ 		dev_err(&pdev->dev, "Shutdown Control GPIO not found\n");
+ 		ret = PTR_ERR(wsa883x->sd_n);
+@@ -1411,7 +1411,7 @@ static int wsa883x_probe(struct sdw_slave *pdev,
+ 	pdev->prop.sink_ports = GENMASK(WSA883X_MAX_SWR_PORTS, 0);
+ 	pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop;
+ 	pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
+-	gpiod_direction_output(wsa883x->sd_n, 1);
++	gpiod_direction_output(wsa883x->sd_n, 0);
+ 
+ 	wsa883x->regmap = devm_regmap_init_sdw(pdev, &wsa883x_regmap_config);
+ 	if (IS_ERR(wsa883x->regmap)) {
+diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c
+index b327372f2e4ae..4e776c2a38a4c 100644
+--- a/sound/soc/generic/audio-graph-card.c
++++ b/sound/soc/generic/audio-graph-card.c
+@@ -485,8 +485,10 @@ static int __graph_for_each_link(struct asoc_simple_priv *priv,
+ 			of_node_put(codec_ep);
+ 			of_node_put(codec_port);
+ 
+-			if (ret < 0)
++			if (ret < 0) {
++				of_node_put(cpu_ep);
+ 				return ret;
++			}
+ 
+ 			codec_port_old = codec_port;
+ 		}
+diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c
+index b28d36872dcba..58c9d9edecf0a 100644
+--- a/sound/soc/intel/avs/boards/rt298.c
++++ b/sound/soc/intel/avs/boards/rt298.c
+@@ -6,6 +6,7 @@
+ //          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
+ //
+ 
++#include <linux/dmi.h>
+ #include <linux/module.h>
+ #include <sound/jack.h>
+ #include <sound/pcm.h>
+@@ -14,6 +15,16 @@
+ #include <sound/soc-acpi.h>
+ #include "../../../codecs/rt298.h"
+ 
++static const struct dmi_system_id kblr_dmi_table[] = {
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
++			DMI_MATCH(DMI_BOARD_NAME, "Kabylake R DDR4 RVP"),
++		},
++	},
++	{}
++};
++
+ static const struct snd_kcontrol_new card_controls[] = {
+ 	SOC_DAPM_PIN_SWITCH("Headphone Jack"),
+ 	SOC_DAPM_PIN_SWITCH("Mic Jack"),
+@@ -96,9 +107,15 @@ avs_rt298_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_param
+ {
+ 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ 	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
++	unsigned int clk_freq;
+ 	int ret;
+ 
+-	ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, 19200000, SND_SOC_CLOCK_IN);
++	if (dmi_first_match(kblr_dmi_table))
++		clk_freq = 24000000;
++	else
++		clk_freq = 19200000;
++
++	ret = snd_soc_dai_set_sysclk(codec_dai, RT298_SCLK_S_PLL, clk_freq, SND_SOC_CLOCK_IN);
+ 	if (ret < 0)
+ 		dev_err(rtd->dev, "Set codec sysclk failed: %d\n", ret);
+ 
+@@ -139,7 +156,10 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in
+ 	dl->platforms = platform;
+ 	dl->num_platforms = 1;
+ 	dl->id = 0;
+-	dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
++	if (dmi_first_match(kblr_dmi_table))
++		dl->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
++	else
++		dl->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS;
+ 	dl->init = avs_rt298_codec_init;
+ 	dl->be_hw_params_fixup = avs_rt298_be_fixup;
+ 	dl->ops = &avs_rt298_ops;
+diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
+index c50c20fd681a1..58db133741662 100644
+--- a/sound/soc/intel/avs/core.c
++++ b/sound/soc/intel/avs/core.c
+@@ -440,7 +440,7 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
+ 	if (bus->mlcap)
+ 		snd_hdac_ext_bus_get_ml_capabilities(bus);
+ 
+-	if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)))
++	if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)))
+ 		dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+ 	dma_set_max_seg_size(dev, UINT_MAX);
+ 
+diff --git a/sound/soc/intel/avs/ipc.c b/sound/soc/intel/avs/ipc.c
+index 020d85c7520de..306f0dc4eaf58 100644
+--- a/sound/soc/intel/avs/ipc.c
++++ b/sound/soc/intel/avs/ipc.c
+@@ -123,7 +123,10 @@ static void avs_dsp_recovery(struct avs_dev *adev)
+ 				if (!substream || !substream->runtime)
+ 					continue;
+ 
++				/* No need for _irq() as we are in nonatomic context. */
++				snd_pcm_stream_lock(substream);
+ 				snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
++				snd_pcm_stream_unlock(substream);
+ 			}
+ 		}
+ 	}
+@@ -192,7 +195,8 @@ static void avs_dsp_receive_rx(struct avs_dev *adev, u64 header)
+ 		/* update size in case of LARGE_CONFIG_GET */
+ 		if (msg.msg_target == AVS_MOD_MSG &&
+ 		    msg.global_msg_type == AVS_MOD_LARGE_CONFIG_GET)
+-			ipc->rx.size = msg.ext.large_config.data_off_size;
++			ipc->rx.size = min_t(u32, AVS_MAILBOX_SIZE,
++					     msg.ext.large_config.data_off_size);
+ 
+ 		memcpy_fromio(ipc->rx.data, avs_uplink_addr(adev), ipc->rx.size);
+ 		trace_avs_msg_payload(ipc->rx.data, ipc->rx.size);
+diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
+index 5c218a39ca201..57adcefce043e 100644
+--- a/sound/soc/intel/boards/sof_es8336.c
++++ b/sound/soc/intel/boards/sof_es8336.c
+@@ -782,7 +782,7 @@ static int sof_es8336_remove(struct platform_device *pdev)
+ 	struct snd_soc_card *card = platform_get_drvdata(pdev);
+ 	struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
+ 
+-	cancel_delayed_work(&priv->pcm_pop_work);
++	cancel_delayed_work_sync(&priv->pcm_pop_work);
+ 	gpiod_put(priv->gpio_speakers);
+ 	device_remove_software_node(priv->codec_dev);
+ 	put_device(priv->codec_dev);
+diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
+index aeca58246fc77..77cd7d3e9409b 100644
+--- a/sound/soc/intel/skylake/skl.c
++++ b/sound/soc/intel/skylake/skl.c
+@@ -1097,7 +1097,10 @@ static void skl_shutdown(struct pci_dev *pci)
+ 	if (!skl->init_done)
+ 		return;
+ 
+-	snd_hdac_stop_streams_and_chip(bus);
++	snd_hdac_stop_streams(bus);
++	snd_hdac_ext_bus_link_power_down_all(bus);
++	skl_dsp_sleep(skl->dsp);
++
+ 	list_for_each_entry(s, &bus->stream_list, list) {
+ 		stream = stream_to_hdac_ext_stream(s);
+ 		snd_hdac_ext_stream_decouple(bus, stream, false);
+diff --git a/sound/soc/mediatek/common/mtk-btcvsd.c b/sound/soc/mediatek/common/mtk-btcvsd.c
+index d884bb7c0fc74..1c28b41e43112 100644
+--- a/sound/soc/mediatek/common/mtk-btcvsd.c
++++ b/sound/soc/mediatek/common/mtk-btcvsd.c
+@@ -1038,11 +1038,9 @@ static int mtk_pcm_btcvsd_copy(struct snd_soc_component *component,
+ 	struct mtk_btcvsd_snd *bt = snd_soc_component_get_drvdata(component);
+ 
+ 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+-		mtk_btcvsd_snd_write(bt, buf, count);
++		return mtk_btcvsd_snd_write(bt, buf, count);
+ 	else
+-		mtk_btcvsd_snd_read(bt, buf, count);
+-
+-	return 0;
++		return mtk_btcvsd_snd_read(bt, buf, count);
+ }
+ 
+ /* kcontrol */
+diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+index dcaeeeb8aac70..bc155dd937e0b 100644
+--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
++++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+@@ -1070,16 +1070,6 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
+ 
+ 	afe->dev = &pdev->dev;
+ 
+-	irq_id = platform_get_irq(pdev, 0);
+-	if (irq_id <= 0)
+-		return irq_id < 0 ? irq_id : -ENXIO;
+-	ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler,
+-			       0, "Afe_ISR_Handle", (void *)afe);
+-	if (ret) {
+-		dev_err(afe->dev, "could not request_irq\n");
+-		return ret;
+-	}
+-
+ 	afe->base_addr = devm_platform_ioremap_resource(pdev, 0);
+ 	if (IS_ERR(afe->base_addr))
+ 		return PTR_ERR(afe->base_addr);
+@@ -1185,6 +1175,16 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev)
+ 	if (ret)
+ 		goto err_cleanup_components;
+ 
++	irq_id = platform_get_irq(pdev, 0);
++	if (irq_id <= 0)
++		return irq_id < 0 ? irq_id : -ENXIO;
++	ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler,
++			       0, "Afe_ISR_Handle", (void *)afe);
++	if (ret) {
++		dev_err(afe->dev, "could not request_irq\n");
++		goto err_pm_disable;
++	}
++
+ 	dev_info(&pdev->dev, "MT8173 AFE driver initialized.\n");
+ 	return 0;
+ 
+diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+index 12f40c81b101e..f803f121659de 100644
+--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
++++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+@@ -200,14 +200,16 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
+ 	if (!mt8173_rt5650_rt5514_dais[DAI_LINK_CODEC_I2S].codecs[0].of_node) {
+ 		dev_err(&pdev->dev,
+ 			"Property 'audio-codec' missing or invalid\n");
+-		return -EINVAL;
++		ret = -EINVAL;
++		goto out;
+ 	}
+ 	mt8173_rt5650_rt5514_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node =
+ 		of_parse_phandle(pdev->dev.of_node, "mediatek,audio-codec", 1);
+ 	if (!mt8173_rt5650_rt5514_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node) {
+ 		dev_err(&pdev->dev,
+ 			"Property 'audio-codec' missing or invalid\n");
+-		return -EINVAL;
++		ret = -EINVAL;
++		goto out;
+ 	}
+ 	mt8173_rt5650_rt5514_codec_conf[0].dlc.of_node =
+ 		mt8173_rt5650_rt5514_dais[DAI_LINK_CODEC_I2S].codecs[1].of_node;
+@@ -216,6 +218,7 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
+ 
+ 	ret = devm_snd_soc_register_card(&pdev->dev, card);
+ 
++out:
+ 	of_node_put(platform_node);
+ 	return ret;
+ }
+diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
+index ab157db783350..cfb463f44af79 100644
+--- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
++++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
+@@ -644,8 +644,10 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev);
+-	if (!card)
++	if (!card) {
++		of_node_put(platform_node);
+ 		return -EINVAL;
++	}
+ 	card->dev = &pdev->dev;
+ 
+ 	ec_codec = of_parse_phandle(pdev->dev.of_node, "mediatek,ec-codec", 0);
+@@ -734,8 +736,10 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+-	if (!priv)
+-		return -ENOMEM;
++	if (!priv) {
++		ret = -ENOMEM;
++		goto out;
++	}
+ 
+ 	snd_soc_card_set_drvdata(card, priv);
+ 
+@@ -743,7 +747,8 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
+ 	if (IS_ERR(priv->pinctrl)) {
+ 		dev_err(&pdev->dev, "%s devm_pinctrl_get failed\n",
+ 			__func__);
+-		return PTR_ERR(priv->pinctrl);
++		ret = PTR_ERR(priv->pinctrl);
++		goto out;
+ 	}
+ 
+ 	for (i = 0; i < PIN_STATE_MAX; i++) {
+@@ -776,6 +781,7 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
+ 
+ 	ret = devm_snd_soc_register_card(&pdev->dev, card);
+ 
++out:
+ 	of_node_put(platform_node);
+ 	of_node_put(ec_codec);
+ 	of_node_put(hdmi_codec);
+diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
+index 5d520e18e512f..99b245e3079a2 100644
+--- a/sound/soc/pxa/mmp-pcm.c
++++ b/sound/soc/pxa/mmp-pcm.c
+@@ -98,7 +98,7 @@ static bool filter(struct dma_chan *chan, void *param)
+ 
+ 	devname = kasprintf(GFP_KERNEL, "%s.%d", dma_data->dma_res->name,
+ 		dma_data->ssp_id);
+-	if ((strcmp(dev_name(chan->device->dev), devname) == 0) &&
++	if (devname && (strcmp(dev_name(chan->device->dev), devname) == 0) &&
+ 		(chan->chan_id == dma_data->dma_res->start)) {
+ 		found = true;
+ 	}
+diff --git a/sound/soc/qcom/lpass-sc7180.c b/sound/soc/qcom/lpass-sc7180.c
+index 77a556b27cf09..24a1c121cb2e9 100644
+--- a/sound/soc/qcom/lpass-sc7180.c
++++ b/sound/soc/qcom/lpass-sc7180.c
+@@ -131,6 +131,9 @@ static int sc7180_lpass_init(struct platform_device *pdev)
+ 
+ 	drvdata->clks = devm_kcalloc(dev, variant->num_clks,
+ 				     sizeof(*drvdata->clks), GFP_KERNEL);
++	if (!drvdata->clks)
++		return -ENOMEM;
++
+ 	drvdata->num_clks = variant->num_clks;
+ 
+ 	for (i = 0; i < drvdata->num_clks; i++)
+diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c
+index a7549f8272359..5b1e47bdc376b 100644
+--- a/sound/soc/rockchip/rockchip_pdm.c
++++ b/sound/soc/rockchip/rockchip_pdm.c
+@@ -431,6 +431,7 @@ static int rockchip_pdm_runtime_resume(struct device *dev)
+ 
+ 	ret = clk_prepare_enable(pdm->hclk);
+ 	if (ret) {
++		clk_disable_unprepare(pdm->clk);
+ 		dev_err(pdm->dev, "hclock enable failed %d\n", ret);
+ 		return ret;
+ 	}
+diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
+index 8bef572d3cbc1..5b4f004575879 100644
+--- a/sound/soc/rockchip/rockchip_spdif.c
++++ b/sound/soc/rockchip/rockchip_spdif.c
+@@ -88,6 +88,7 @@ static int __maybe_unused rk_spdif_runtime_resume(struct device *dev)
+ 
+ 	ret = clk_prepare_enable(spdif->hclk);
+ 	if (ret) {
++		clk_disable_unprepare(spdif->mclk);
+ 		dev_err(spdif->dev, "hclk clock enable failed %d\n", ret);
+ 		return ret;
+ 	}
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index 874fcf245747f..271884e350035 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -76,6 +76,8 @@
+ { USB_DEVICE_VENDOR_SPEC(0x041e, 0x3f0a) },
+ /* E-Mu 0204 USB */
+ { USB_DEVICE_VENDOR_SPEC(0x041e, 0x3f19) },
++/* Ktmicro Usb_audio device */
++{ USB_DEVICE_VENDOR_SPEC(0x31b2, 0x0011) },
+ 
+ /*
+  * Creative Technology, Ltd Live! Cam Sync HD [VF0770]
+diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
+index 3bdbc0ce75b15..e54487e4005d3 100644
+--- a/tools/bpf/bpftool/common.c
++++ b/tools/bpf/bpftool/common.c
+@@ -499,6 +499,7 @@ static int do_build_table_cb(const char *fpath, const struct stat *sb,
+ 	if (err) {
+ 		p_err("failed to append entry to hashmap for ID %u, path '%s': %s",
+ 		      pinned_info.id, path, strerror(errno));
++		free(path);
+ 		goto out_close;
+ 	}
+ 
+diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
+index 9c50beabdd145..fddc05c667b5d 100644
+--- a/tools/lib/bpf/bpf.h
++++ b/tools/lib/bpf/bpf.h
+@@ -393,8 +393,15 @@ LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
+ 				 __u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
+ 				 __u64 *probe_offset, __u64 *probe_addr);
+ 
++#ifdef __cplusplus
++/* forward-declaring enums in C++ isn't compatible with pure C enums, so
++ * instead define bpf_enable_stats() as accepting int as an input
++ */
++LIBBPF_API int bpf_enable_stats(int type);
++#else
+ enum bpf_stats_type; /* defined in up-to-date linux/bpf.h */
+ LIBBPF_API int bpf_enable_stats(enum bpf_stats_type type);
++#endif
+ 
+ struct bpf_prog_bind_opts {
+ 	size_t sz; /* size of this struct for forward/backward compatibility */
+diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
+index 2d14f1a52d7aa..9b18cf3128acc 100644
+--- a/tools/lib/bpf/btf.c
++++ b/tools/lib/bpf/btf.c
+@@ -3889,14 +3889,14 @@ static inline __u16 btf_fwd_kind(struct btf_type *t)
+ }
+ 
+ /* Check if given two types are identical ARRAY definitions */
+-static int btf_dedup_identical_arrays(struct btf_dedup *d, __u32 id1, __u32 id2)
++static bool btf_dedup_identical_arrays(struct btf_dedup *d, __u32 id1, __u32 id2)
+ {
+ 	struct btf_type *t1, *t2;
+ 
+ 	t1 = btf_type_by_id(d->btf, id1);
+ 	t2 = btf_type_by_id(d->btf, id2);
+ 	if (!btf_is_array(t1) || !btf_is_array(t2))
+-		return 0;
++		return false;
+ 
+ 	return btf_equal_array(t1, t2);
+ }
+@@ -3920,7 +3920,9 @@ static bool btf_dedup_identical_structs(struct btf_dedup *d, __u32 id1, __u32 id
+ 	m1 = btf_members(t1);
+ 	m2 = btf_members(t2);
+ 	for (i = 0, n = btf_vlen(t1); i < n; i++, m1++, m2++) {
+-		if (m1->type != m2->type)
++		if (m1->type != m2->type &&
++		    !btf_dedup_identical_arrays(d, m1->type, m2->type) &&
++		    !btf_dedup_identical_structs(d, m1->type, m2->type))
+ 			return false;
+ 	}
+ 	return true;
+diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
+index 3937f66c7f8d6..0b470169729e6 100644
+--- a/tools/lib/bpf/btf_dump.c
++++ b/tools/lib/bpf/btf_dump.c
+@@ -219,6 +219,17 @@ static int btf_dump_resize(struct btf_dump *d)
+ 	return 0;
+ }
+ 
++static void btf_dump_free_names(struct hashmap *map)
++{
++	size_t bkt;
++	struct hashmap_entry *cur;
++
++	hashmap__for_each_entry(map, cur, bkt)
++		free((void *)cur->key);
++
++	hashmap__free(map);
++}
++
+ void btf_dump__free(struct btf_dump *d)
+ {
+ 	int i;
+@@ -237,8 +248,8 @@ void btf_dump__free(struct btf_dump *d)
+ 	free(d->cached_names);
+ 	free(d->emit_queue);
+ 	free(d->decl_stack);
+-	hashmap__free(d->type_names);
+-	hashmap__free(d->ident_names);
++	btf_dump_free_names(d->type_names);
++	btf_dump_free_names(d->ident_names);
+ 
+ 	free(d);
+ }
+@@ -1520,11 +1531,23 @@ static void btf_dump_emit_type_cast(struct btf_dump *d, __u32 id,
+ static size_t btf_dump_name_dups(struct btf_dump *d, struct hashmap *name_map,
+ 				 const char *orig_name)
+ {
++	char *old_name, *new_name;
+ 	size_t dup_cnt = 0;
++	int err;
++
++	new_name = strdup(orig_name);
++	if (!new_name)
++		return 1;
+ 
+ 	hashmap__find(name_map, orig_name, (void **)&dup_cnt);
+ 	dup_cnt++;
+-	hashmap__set(name_map, orig_name, (void *)dup_cnt, NULL, NULL);
++
++	err = hashmap__set(name_map, new_name, (void *)dup_cnt,
++			   (const void **)&old_name, NULL);
++	if (err)
++		free(new_name);
++
++	free(old_name);
+ 
+ 	return dup_cnt;
+ }
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 79ea83be21ce9..c01f57d31f89a 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -590,8 +590,7 @@ struct elf_state {
+ 	size_t shstrndx; /* section index for section name strings */
+ 	size_t strtabidx;
+ 	struct elf_sec_desc *secs;
+-	int sec_cnt;
+-	int maps_shndx;
++	size_t sec_cnt;
+ 	int btf_maps_shndx;
+ 	__u32 btf_maps_sec_btf_id;
+ 	int text_shndx;
+@@ -1272,7 +1271,6 @@ static struct bpf_object *bpf_object__new(const char *path,
+ 	 */
+ 	obj->efile.obj_buf = obj_buf;
+ 	obj->efile.obj_buf_sz = obj_buf_sz;
+-	obj->efile.maps_shndx = -1;
+ 	obj->efile.btf_maps_shndx = -1;
+ 	obj->efile.st_ops_shndx = -1;
+ 	obj->kconfig_map_idx = -1;
+@@ -1401,6 +1399,10 @@ static int bpf_object__check_endianness(struct bpf_object *obj)
+ static int
+ bpf_object__init_license(struct bpf_object *obj, void *data, size_t size)
+ {
++	if (!data) {
++		pr_warn("invalid license section in %s\n", obj->path);
++		return -LIBBPF_ERRNO__FORMAT;
++	}
+ 	/* libbpf_strlcpy() only copies first N - 1 bytes, so size + 1 won't
+ 	 * go over allowed ELF data section buffer
+ 	 */
+@@ -1414,7 +1416,7 @@ bpf_object__init_kversion(struct bpf_object *obj, void *data, size_t size)
+ {
+ 	__u32 kver;
+ 
+-	if (size != sizeof(kver)) {
++	if (!data || size != sizeof(kver)) {
+ 		pr_warn("invalid kver section in %s\n", obj->path);
+ 		return -LIBBPF_ERRNO__FORMAT;
+ 	}
+@@ -3284,10 +3286,15 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
+ 	Elf64_Shdr *sh;
+ 
+ 	/* ELF section indices are 0-based, but sec #0 is special "invalid"
+-	 * section. e_shnum does include sec #0, so e_shnum is the necessary
+-	 * size of an array to keep all the sections.
++	 * section. Since section count retrieved by elf_getshdrnum() does
++	 * include sec #0, it is already the necessary size of an array to keep
++	 * all the sections.
+ 	 */
+-	obj->efile.sec_cnt = obj->efile.ehdr->e_shnum;
++	if (elf_getshdrnum(obj->efile.elf, &obj->efile.sec_cnt)) {
++		pr_warn("elf: failed to get the number of sections for %s: %s\n",
++			obj->path, elf_errmsg(-1));
++		return -LIBBPF_ERRNO__FORMAT;
++	}
+ 	obj->efile.secs = calloc(obj->efile.sec_cnt, sizeof(*obj->efile.secs));
+ 	if (!obj->efile.secs)
+ 		return -ENOMEM;
+@@ -3359,7 +3366,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
+ 			if (err)
+ 				return err;
+ 		} else if (strcmp(name, "maps") == 0) {
+-			obj->efile.maps_shndx = idx;
++			pr_warn("elf: legacy map definitions in 'maps' section are not supported by libbpf v1.0+\n");
++			return -ENOTSUP;
+ 		} else if (strcmp(name, MAPS_ELF_SEC) == 0) {
+ 			obj->efile.btf_maps_shndx = idx;
+ 		} else if (strcmp(name, BTF_ELF_SEC) == 0) {
+@@ -3891,8 +3899,7 @@ static bool bpf_object__shndx_is_data(const struct bpf_object *obj,
+ static bool bpf_object__shndx_is_maps(const struct bpf_object *obj,
+ 				      int shndx)
+ {
+-	return shndx == obj->efile.maps_shndx ||
+-	       shndx == obj->efile.btf_maps_shndx;
++	return shndx == obj->efile.btf_maps_shndx;
+ }
+ 
+ static enum libbpf_map_type
+@@ -4078,6 +4085,9 @@ static struct bpf_program *find_prog_by_sec_insn(const struct bpf_object *obj,
+ 	int l = 0, r = obj->nr_programs - 1, m;
+ 	struct bpf_program *prog;
+ 
++	if (!obj->nr_programs)
++		return NULL;
++
+ 	while (l < r) {
+ 		m = l + (r - l + 1) / 2;
+ 		prog = &obj->programs[m];
+diff --git a/tools/lib/bpf/usdt.c b/tools/lib/bpf/usdt.c
+index d18e37982344c..2ade9c7969d72 100644
+--- a/tools/lib/bpf/usdt.c
++++ b/tools/lib/bpf/usdt.c
+@@ -1348,25 +1348,23 @@ static int calc_pt_regs_off(const char *reg_name)
+ 
+ static int parse_usdt_arg(const char *arg_str, int arg_num, struct usdt_arg_spec *arg)
+ {
+-	char *reg_name = NULL;
++	char reg_name[16];
+ 	int arg_sz, len, reg_off;
+ 	long off;
+ 
+-	if (sscanf(arg_str, " %d @ \[ %m[a-z0-9], %ld ] %n", &arg_sz, &reg_name, &off, &len) == 3) {
++	if (sscanf(arg_str, " %d @ \[ %15[a-z0-9], %ld ] %n", &arg_sz, reg_name, &off, &len) == 3) {
+ 		/* Memory dereference case, e.g., -4@[sp, 96] */
+ 		arg->arg_type = USDT_ARG_REG_DEREF;
+ 		arg->val_off = off;
+ 		reg_off = calc_pt_regs_off(reg_name);
+-		free(reg_name);
+ 		if (reg_off < 0)
+ 			return reg_off;
+ 		arg->reg_off = reg_off;
+-	} else if (sscanf(arg_str, " %d @ \[ %m[a-z0-9] ] %n", &arg_sz, &reg_name, &len) == 2) {
++	} else if (sscanf(arg_str, " %d @ \[ %15[a-z0-9] ] %n", &arg_sz, reg_name, &len) == 2) {
+ 		/* Memory dereference case, e.g., -4@[sp] */
+ 		arg->arg_type = USDT_ARG_REG_DEREF;
+ 		arg->val_off = 0;
+ 		reg_off = calc_pt_regs_off(reg_name);
+-		free(reg_name);
+ 		if (reg_off < 0)
+ 			return reg_off;
+ 		arg->reg_off = reg_off;
+@@ -1375,12 +1373,11 @@ static int parse_usdt_arg(const char *arg_str, int arg_num, struct usdt_arg_spec
+ 		arg->arg_type = USDT_ARG_CONST;
+ 		arg->val_off = off;
+ 		arg->reg_off = 0;
+-	} else if (sscanf(arg_str, " %d @ %m[a-z0-9] %n", &arg_sz, &reg_name, &len) == 2) {
++	} else if (sscanf(arg_str, " %d @ %15[a-z0-9] %n", &arg_sz, reg_name, &len) == 2) {
+ 		/* Register read case, e.g., -8@x4 */
+ 		arg->arg_type = USDT_ARG_REG;
+ 		arg->val_off = 0;
+ 		reg_off = calc_pt_regs_off(reg_name);
+-		free(reg_name);
+ 		if (reg_off < 0)
+ 			return reg_off;
+ 		arg->reg_off = reg_off;
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index e55fdf952a3a1..67afdce3421f5 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -999,6 +999,16 @@ static const char *uaccess_safe_builtin[] = {
+ 	"__tsan_read_write4",
+ 	"__tsan_read_write8",
+ 	"__tsan_read_write16",
++	"__tsan_volatile_read1",
++	"__tsan_volatile_read2",
++	"__tsan_volatile_read4",
++	"__tsan_volatile_read8",
++	"__tsan_volatile_read16",
++	"__tsan_volatile_write1",
++	"__tsan_volatile_write2",
++	"__tsan_volatile_write4",
++	"__tsan_volatile_write8",
++	"__tsan_volatile_write16",
+ 	"__tsan_atomic8_load",
+ 	"__tsan_atomic16_load",
+ 	"__tsan_atomic32_load",
+diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
+index 0b4a62e4ff675..cab6b70e95e26 100644
+--- a/tools/perf/builtin-stat.c
++++ b/tools/perf/builtin-stat.c
+@@ -573,26 +573,14 @@ static int enable_counters(void)
+ 			return err;
+ 	}
+ 
+-	if (stat_config.initial_delay < 0) {
+-		pr_info(EVLIST_DISABLED_MSG);
+-		return 0;
+-	}
+-
+-	if (stat_config.initial_delay > 0) {
+-		pr_info(EVLIST_DISABLED_MSG);
+-		usleep(stat_config.initial_delay * USEC_PER_MSEC);
+-	}
+-
+ 	/*
+ 	 * We need to enable counters only if:
+ 	 * - we don't have tracee (attaching to task or cpu)
+ 	 * - we have initial delay configured
+ 	 */
+-	if (!target__none(&target) || stat_config.initial_delay) {
++	if (!target__none(&target)) {
+ 		if (!all_counters_use_bpf)
+ 			evlist__enable(evsel_list);
+-		if (stat_config.initial_delay > 0)
+-			pr_info(EVLIST_ENABLED_MSG);
+ 	}
+ 	return 0;
+ }
+@@ -967,14 +955,27 @@ try_again_reset:
+ 			return err;
+ 	}
+ 
+-	err = enable_counters();
+-	if (err)
+-		return -1;
++	if (stat_config.initial_delay) {
++		pr_info(EVLIST_DISABLED_MSG);
++	} else {
++		err = enable_counters();
++		if (err)
++			return -1;
++	}
+ 
+ 	/* Exec the command, if any */
+ 	if (forks)
+ 		evlist__start_workload(evsel_list);
+ 
++	if (stat_config.initial_delay > 0) {
++		usleep(stat_config.initial_delay * USEC_PER_MSEC);
++		err = enable_counters();
++		if (err)
++			return -1;
++
++		pr_info(EVLIST_ENABLED_MSG);
++	}
++
+ 	t0 = rdclock();
+ 	clock_gettime(CLOCK_MONOTONIC, &ref_time);
+ 
+diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
+index 0bd9d01c0df9d..73f4a83edc443 100644
+--- a/tools/perf/builtin-trace.c
++++ b/tools/perf/builtin-trace.c
+@@ -88,6 +88,8 @@
+ # define F_LINUX_SPECIFIC_BASE	1024
+ #endif
+ 
++#define RAW_SYSCALL_ARGS_NUM	6
++
+ /*
+  * strtoul: Go from a string to a value, i.e. for msr: MSR_FS_BASE to 0xc0000100
+  */
+@@ -108,7 +110,7 @@ struct syscall_fmt {
+ 		const char *sys_enter,
+ 			   *sys_exit;
+ 	}	   bpf_prog_name;
+-	struct syscall_arg_fmt arg[6];
++	struct syscall_arg_fmt arg[RAW_SYSCALL_ARGS_NUM];
+ 	u8	   nr_args;
+ 	bool	   errpid;
+ 	bool	   timeout;
+@@ -1229,7 +1231,7 @@ struct syscall {
+  */
+ struct bpf_map_syscall_entry {
+ 	bool	enabled;
+-	u16	string_args_len[6];
++	u16	string_args_len[RAW_SYSCALL_ARGS_NUM];
+ };
+ 
+ /*
+@@ -1661,7 +1663,7 @@ static int syscall__alloc_arg_fmts(struct syscall *sc, int nr_args)
+ {
+ 	int idx;
+ 
+-	if (nr_args == 6 && sc->fmt && sc->fmt->nr_args != 0)
++	if (nr_args == RAW_SYSCALL_ARGS_NUM && sc->fmt && sc->fmt->nr_args != 0)
+ 		nr_args = sc->fmt->nr_args;
+ 
+ 	sc->arg_fmt = calloc(nr_args, sizeof(*sc->arg_fmt));
+@@ -1794,11 +1796,11 @@ static int trace__read_syscall_info(struct trace *trace, int id)
+ #endif
+ 	sc = trace->syscalls.table + id;
+ 	if (sc->nonexistent)
+-		return 0;
++		return -EEXIST;
+ 
+ 	if (name == NULL) {
+ 		sc->nonexistent = true;
+-		return 0;
++		return -EEXIST;
+ 	}
+ 
+ 	sc->name = name;
+@@ -1812,11 +1814,18 @@ static int trace__read_syscall_info(struct trace *trace, int id)
+ 		sc->tp_format = trace_event__tp_format("syscalls", tp_name);
+ 	}
+ 
+-	if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ? 6 : sc->tp_format->format.nr_fields))
+-		return -ENOMEM;
+-
+-	if (IS_ERR(sc->tp_format))
++	/*
++	 * Fails to read trace point format via sysfs node, so the trace point
++	 * doesn't exist.  Set the 'nonexistent' flag as true.
++	 */
++	if (IS_ERR(sc->tp_format)) {
++		sc->nonexistent = true;
+ 		return PTR_ERR(sc->tp_format);
++	}
++
++	if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ?
++					RAW_SYSCALL_ARGS_NUM : sc->tp_format->format.nr_fields))
++		return -ENOMEM;
+ 
+ 	sc->args = sc->tp_format->format.fields;
+ 	/*
+@@ -2134,11 +2143,8 @@ static struct syscall *trace__syscall_info(struct trace *trace,
+ 	    (err = trace__read_syscall_info(trace, id)) != 0)
+ 		goto out_cant_read;
+ 
+-	if (trace->syscalls.table[id].name == NULL) {
+-		if (trace->syscalls.table[id].nonexistent)
+-			return NULL;
++	if (trace->syscalls.table && trace->syscalls.table[id].nonexistent)
+ 		goto out_cant_read;
+-	}
+ 
+ 	return &trace->syscalls.table[id];
+ 
+diff --git a/tools/perf/tests/shell/stat_all_pmu.sh b/tools/perf/tests/shell/stat_all_pmu.sh
+index 9c9ef33e0b3c6..c779554191731 100755
+--- a/tools/perf/tests/shell/stat_all_pmu.sh
++++ b/tools/perf/tests/shell/stat_all_pmu.sh
+@@ -4,17 +4,8 @@
+ 
+ set -e
+ 
+-for p in $(perf list --raw-dump pmu); do
+-  # In powerpc, skip the events for hv_24x7 and hv_gpci.
+-  # These events needs input values to be filled in for
+-  # core, chip, partition id based on system.
+-  # Example: hv_24x7/CPM_ADJUNCT_INST,domain=?,core=?/
+-  # hv_gpci/event,partition_id=?/
+-  # Hence skip these events for ppc.
+-  if echo "$p" |grep -Eq 'hv_24x7|hv_gpci' ; then
+-    echo "Skipping: Event '$p' in powerpc"
+-    continue
+-  fi
++# Test all PMU events; however exclude parametrized ones (name contains '?')
++for p in $(perf list --raw-dump pmu | sed 's/[[:graph:]]\+?[[:graph:]]\+[[:space:]]//g'); do
+   echo "Testing $p"
+   result=$(perf stat -e "$p" true 2>&1)
+   if ! echo "$result" | grep -q "$p" && ! echo "$result" | grep -q "<not supported>" ; then
+diff --git a/tools/perf/util/bpf_off_cpu.c b/tools/perf/util/bpf_off_cpu.c
+index c257813e674ef..01f70b8e705a8 100644
+--- a/tools/perf/util/bpf_off_cpu.c
++++ b/tools/perf/util/bpf_off_cpu.c
+@@ -102,7 +102,7 @@ static void check_sched_switch_args(void)
+ 	const struct btf_type *t1, *t2, *t3;
+ 	u32 type_id;
+ 
+-	type_id = btf__find_by_name_kind(btf, "bpf_trace_sched_switch",
++	type_id = btf__find_by_name_kind(btf, "btf_trace_sched_switch",
+ 					 BTF_KIND_TYPEDEF);
+ 	if ((s32)type_id < 0)
+ 		return;
+diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c
+index 65e6c22f38e4f..190e818a07176 100644
+--- a/tools/perf/util/debug.c
++++ b/tools/perf/util/debug.c
+@@ -241,6 +241,10 @@ int perf_quiet_option(void)
+ 		opt++;
+ 	}
+ 
++	/* For debug variables that are used as bool types, set to 0. */
++	redirect_to_stderr = 0;
++	debug_peo_args = 0;
++
+ 	return 0;
+ }
+ 
+diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
+index 647b7dff8ef36..80345695b1360 100644
+--- a/tools/perf/util/symbol-elf.c
++++ b/tools/perf/util/symbol-elf.c
+@@ -1303,7 +1303,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
+ 			   (!used_opd && syms_ss->adjust_symbols)) {
+ 			GElf_Phdr phdr;
+ 
+-			if (elf_read_program_header(syms_ss->elf,
++			if (elf_read_program_header(runtime_ss->elf,
+ 						    (u64)sym.st_value, &phdr)) {
+ 				pr_debug4("%s: failed to find program header for "
+ 					   "symbol: %s st_value: %#" PRIx64 "\n",
+diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+index ac5d7c1396fb4..5085fea3cac5f 100644
+--- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
++++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+@@ -18,6 +18,46 @@ typedef int (*func_proto_typedef_nested1)(func_proto_typedef);
+ typedef int (*func_proto_typedef_nested2)(func_proto_typedef_nested1);
+ 
+ DEFINE_PER_CPU(int, bpf_testmod_ksym_percpu) = 123;
++long bpf_testmod_test_struct_arg_result;
++
++struct bpf_testmod_struct_arg_1 {
++	int a;
++};
++struct bpf_testmod_struct_arg_2 {
++	long a;
++	long b;
++};
++
++noinline int
++bpf_testmod_test_struct_arg_1(struct bpf_testmod_struct_arg_2 a, int b, int c) {
++	bpf_testmod_test_struct_arg_result = a.a + a.b  + b + c;
++	return bpf_testmod_test_struct_arg_result;
++}
++
++noinline int
++bpf_testmod_test_struct_arg_2(int a, struct bpf_testmod_struct_arg_2 b, int c) {
++	bpf_testmod_test_struct_arg_result = a + b.a + b.b + c;
++	return bpf_testmod_test_struct_arg_result;
++}
++
++noinline int
++bpf_testmod_test_struct_arg_3(int a, int b, struct bpf_testmod_struct_arg_2 c) {
++	bpf_testmod_test_struct_arg_result = a + b + c.a + c.b;
++	return bpf_testmod_test_struct_arg_result;
++}
++
++noinline int
++bpf_testmod_test_struct_arg_4(struct bpf_testmod_struct_arg_1 a, int b,
++			      int c, int d, struct bpf_testmod_struct_arg_2 e) {
++	bpf_testmod_test_struct_arg_result = a.a + b + c + d + e.a + e.b;
++	return bpf_testmod_test_struct_arg_result;
++}
++
++noinline int
++bpf_testmod_test_struct_arg_5(void) {
++	bpf_testmod_test_struct_arg_result = 1;
++	return bpf_testmod_test_struct_arg_result;
++}
+ 
+ noinline void
+ bpf_testmod_test_mod_kfunc(int i)
+@@ -115,11 +155,19 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
+ 		.off = off,
+ 		.len = len,
+ 	};
++	struct bpf_testmod_struct_arg_1 struct_arg1 = {10};
++	struct bpf_testmod_struct_arg_2 struct_arg2 = {2, 3};
+ 	int i = 1;
+ 
+ 	while (bpf_testmod_return_ptr(i))
+ 		i++;
+ 
++	(void)bpf_testmod_test_struct_arg_1(struct_arg2, 1, 4);
++	(void)bpf_testmod_test_struct_arg_2(1, struct_arg2, 4);
++	(void)bpf_testmod_test_struct_arg_3(1, 4, struct_arg2);
++	(void)bpf_testmod_test_struct_arg_4(struct_arg1, 1, 2, 3, struct_arg2);
++	(void)bpf_testmod_test_struct_arg_5();
++
+ 	/* This is always true. Use the check to make sure the compiler
+ 	 * doesn't remove bpf_testmod_loop_test.
+ 	 */
+diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config
+index fabf0c0143498..c5c5fc2a3ce7b 100644
+--- a/tools/testing/selftests/bpf/config
++++ b/tools/testing/selftests/bpf/config
+@@ -13,6 +13,7 @@ CONFIG_CRYPTO_USER_API_HASH=m
+ CONFIG_DYNAMIC_FTRACE=y
+ CONFIG_FPROBE=y
+ CONFIG_FTRACE_SYSCALLS=y
++CONFIG_FUNCTION_ERROR_INJECTION=y
+ CONFIG_FUNCTION_TRACER=y
+ CONFIG_GENEVE=y
+ CONFIG_IKCONFIG=y
+diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c
+index bec15558fd938..1f37adff7632c 100644
+--- a/tools/testing/selftests/bpf/network_helpers.c
++++ b/tools/testing/selftests/bpf/network_helpers.c
+@@ -426,6 +426,10 @@ static int setns_by_fd(int nsfd)
+ 	if (!ASSERT_OK(err, "mount /sys/fs/bpf"))
+ 		return err;
+ 
++	err = mount("debugfs", "/sys/kernel/debug", "debugfs", 0, NULL);
++	if (!ASSERT_OK(err, "mount /sys/kernel/debug"))
++		return err;
++
+ 	return 0;
+ }
+ 
+diff --git a/tools/testing/selftests/bpf/prog_tests/empty_skb.c b/tools/testing/selftests/bpf/prog_tests/empty_skb.c
+new file mode 100644
+index 0000000000000..0613f3bb8b5e4
+--- /dev/null
++++ b/tools/testing/selftests/bpf/prog_tests/empty_skb.c
+@@ -0,0 +1,146 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <test_progs.h>
++#include <network_helpers.h>
++#include <net/if.h>
++#include "empty_skb.skel.h"
++
++#define SYS(cmd) ({ \
++	if (!ASSERT_OK(system(cmd), (cmd))) \
++		goto out; \
++})
++
++void serial_test_empty_skb(void)
++{
++	LIBBPF_OPTS(bpf_test_run_opts, tattr);
++	struct empty_skb *bpf_obj = NULL;
++	struct nstoken *tok = NULL;
++	struct bpf_program *prog;
++	char eth_hlen_pp[15];
++	char eth_hlen[14];
++	int veth_ifindex;
++	int ipip_ifindex;
++	int err;
++	int i;
++
++	struct {
++		const char *msg;
++		const void *data_in;
++		__u32 data_size_in;
++		int *ifindex;
++		int err;
++		int ret;
++		bool success_on_tc;
++	} tests[] = {
++		/* Empty packets are always rejected. */
++
++		{
++			/* BPF_PROG_RUN ETH_HLEN size check */
++			.msg = "veth empty ingress packet",
++			.data_in = NULL,
++			.data_size_in = 0,
++			.ifindex = &veth_ifindex,
++			.err = -EINVAL,
++		},
++		{
++			/* BPF_PROG_RUN ETH_HLEN size check */
++			.msg = "ipip empty ingress packet",
++			.data_in = NULL,
++			.data_size_in = 0,
++			.ifindex = &ipip_ifindex,
++			.err = -EINVAL,
++		},
++
++		/* ETH_HLEN-sized packets:
++		 * - can not be redirected at LWT_XMIT
++		 * - can be redirected at TC to non-tunneling dest
++		 */
++
++		{
++			/* __bpf_redirect_common */
++			.msg = "veth ETH_HLEN packet ingress",
++			.data_in = eth_hlen,
++			.data_size_in = sizeof(eth_hlen),
++			.ifindex = &veth_ifindex,
++			.ret = -ERANGE,
++			.success_on_tc = true,
++		},
++		{
++			/* __bpf_redirect_no_mac
++			 *
++			 * lwt: skb->len=0 <= skb_network_offset=0
++			 * tc: skb->len=14 <= skb_network_offset=14
++			 */
++			.msg = "ipip ETH_HLEN packet ingress",
++			.data_in = eth_hlen,
++			.data_size_in = sizeof(eth_hlen),
++			.ifindex = &ipip_ifindex,
++			.ret = -ERANGE,
++		},
++
++		/* ETH_HLEN+1-sized packet should be redirected. */
++
++		{
++			.msg = "veth ETH_HLEN+1 packet ingress",
++			.data_in = eth_hlen_pp,
++			.data_size_in = sizeof(eth_hlen_pp),
++			.ifindex = &veth_ifindex,
++		},
++		{
++			.msg = "ipip ETH_HLEN+1 packet ingress",
++			.data_in = eth_hlen_pp,
++			.data_size_in = sizeof(eth_hlen_pp),
++			.ifindex = &ipip_ifindex,
++		},
++	};
++
++	SYS("ip netns add empty_skb");
++	tok = open_netns("empty_skb");
++	SYS("ip link add veth0 type veth peer veth1");
++	SYS("ip link set dev veth0 up");
++	SYS("ip link set dev veth1 up");
++	SYS("ip addr add 10.0.0.1/8 dev veth0");
++	SYS("ip addr add 10.0.0.2/8 dev veth1");
++	veth_ifindex = if_nametoindex("veth0");
++
++	SYS("ip link add ipip0 type ipip local 10.0.0.1 remote 10.0.0.2");
++	SYS("ip link set ipip0 up");
++	SYS("ip addr add 192.168.1.1/16 dev ipip0");
++	ipip_ifindex = if_nametoindex("ipip0");
++
++	bpf_obj = empty_skb__open_and_load();
++	if (!ASSERT_OK_PTR(bpf_obj, "open skeleton"))
++		goto out;
++
++	for (i = 0; i < ARRAY_SIZE(tests); i++) {
++		bpf_object__for_each_program(prog, bpf_obj->obj) {
++			char buf[128];
++			bool at_tc = !strncmp(bpf_program__section_name(prog), "tc", 2);
++
++			tattr.data_in = tests[i].data_in;
++			tattr.data_size_in = tests[i].data_size_in;
++
++			tattr.data_size_out = 0;
++			bpf_obj->bss->ifindex = *tests[i].ifindex;
++			bpf_obj->bss->ret = 0;
++			err = bpf_prog_test_run_opts(bpf_program__fd(prog), &tattr);
++			sprintf(buf, "err: %s [%s]", tests[i].msg, bpf_program__name(prog));
++
++			if (at_tc && tests[i].success_on_tc)
++				ASSERT_GE(err, 0, buf);
++			else
++				ASSERT_EQ(err, tests[i].err, buf);
++			sprintf(buf, "ret: %s [%s]", tests[i].msg, bpf_program__name(prog));
++			if (at_tc && tests[i].success_on_tc)
++				ASSERT_GE(bpf_obj->bss->ret, 0, buf);
++			else
++				ASSERT_EQ(bpf_obj->bss->ret, tests[i].ret, buf);
++		}
++	}
++
++out:
++	if (bpf_obj)
++		empty_skb__destroy(bpf_obj);
++	if (tok)
++		close_netns(tok);
++	system("ip netns del empty_skb");
++}
+diff --git a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
+index d457a55ff408e..287b3ac40227a 100644
+--- a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
++++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
+@@ -325,7 +325,7 @@ static bool symbol_equal(const void *key1, const void *key2, void *ctx __maybe_u
+ static int get_syms(char ***symsp, size_t *cntp)
+ {
+ 	size_t cap = 0, cnt = 0, i;
+-	char *name, **syms = NULL;
++	char *name = NULL, **syms = NULL;
+ 	struct hashmap *map;
+ 	char buf[256];
+ 	FILE *f;
+@@ -352,6 +352,8 @@ static int get_syms(char ***symsp, size_t *cntp)
+ 		/* skip modules */
+ 		if (strchr(buf, '['))
+ 			continue;
++
++		free(name);
+ 		if (sscanf(buf, "%ms$*[^\n]\n", &name) != 1)
+ 			continue;
+ 		/*
+@@ -369,32 +371,32 @@ static int get_syms(char ***symsp, size_t *cntp)
+ 		if (!strncmp(name, "__ftrace_invalid_address__",
+ 			     sizeof("__ftrace_invalid_address__") - 1))
+ 			continue;
++
+ 		err = hashmap__add(map, name, NULL);
+-		if (err) {
+-			free(name);
+-			if (err == -EEXIST)
+-				continue;
++		if (err == -EEXIST)
++			continue;
++		if (err)
+ 			goto error;
+-		}
++
+ 		err = libbpf_ensure_mem((void **) &syms, &cap,
+ 					sizeof(*syms), cnt + 1);
+-		if (err) {
+-			free(name);
++		if (err)
+ 			goto error;
+-		}
+-		syms[cnt] = name;
+-		cnt++;
++
++		syms[cnt++] = name;
++		name = NULL;
+ 	}
+ 
+ 	*symsp = syms;
+ 	*cntp = cnt;
+ 
+ error:
++	free(name);
+ 	fclose(f);
+ 	hashmap__free(map);
+ 	if (err) {
+ 		for (i = 0; i < cnt; i++)
+-			free(syms[cnt]);
++			free(syms[i]);
+ 		free(syms);
+ 	}
+ 	return err;
+diff --git a/tools/testing/selftests/bpf/prog_tests/lsm_cgroup.c b/tools/testing/selftests/bpf/prog_tests/lsm_cgroup.c
+index 1102e4f42d2d4..f117bfef68a14 100644
+--- a/tools/testing/selftests/bpf/prog_tests/lsm_cgroup.c
++++ b/tools/testing/selftests/bpf/prog_tests/lsm_cgroup.c
+@@ -173,10 +173,12 @@ static void test_lsm_cgroup_functional(void)
+ 	ASSERT_EQ(query_prog_cnt(cgroup_fd, NULL), 4, "total prog count");
+ 	ASSERT_EQ(query_prog_cnt(cgroup_fd2, NULL), 1, "total prog count");
+ 
+-	/* AF_UNIX is prohibited. */
+-
+ 	fd = socket(AF_UNIX, SOCK_STREAM, 0);
+-	ASSERT_LT(fd, 0, "socket(AF_UNIX)");
++	if (!(skel->kconfig->CONFIG_SECURITY_APPARMOR
++	    || skel->kconfig->CONFIG_SECURITY_SELINUX
++	    || skel->kconfig->CONFIG_SECURITY_SMACK))
++		/* AF_UNIX is prohibited. */
++		ASSERT_LT(fd, 0, "socket(AF_UNIX)");
+ 	close(fd);
+ 
+ 	/* AF_INET6 gets default policy (sk_priority). */
+@@ -233,11 +235,18 @@ static void test_lsm_cgroup_functional(void)
+ 
+ 	/* AF_INET6+SOCK_STREAM
+ 	 * AF_PACKET+SOCK_RAW
++	 * AF_UNIX+SOCK_RAW if already have non-bpf lsms installed
+ 	 * listen_fd
+ 	 * client_fd
+ 	 * accepted_fd
+ 	 */
+-	ASSERT_EQ(skel->bss->called_socket_post_create2, 5, "called_create2");
++	if (skel->kconfig->CONFIG_SECURITY_APPARMOR
++	    || skel->kconfig->CONFIG_SECURITY_SELINUX
++	    || skel->kconfig->CONFIG_SECURITY_SMACK)
++		/* AF_UNIX+SOCK_RAW if already have non-bpf lsms installed */
++		ASSERT_EQ(skel->bss->called_socket_post_create2, 6, "called_create2");
++	else
++		ASSERT_EQ(skel->bss->called_socket_post_create2, 5, "called_create2");
+ 
+ 	/* start_server
+ 	 * bind(ETH_P_ALL)
+diff --git a/tools/testing/selftests/bpf/prog_tests/map_kptr.c b/tools/testing/selftests/bpf/prog_tests/map_kptr.c
+index fdcea7a61491e..0d66b15242089 100644
+--- a/tools/testing/selftests/bpf/prog_tests/map_kptr.c
++++ b/tools/testing/selftests/bpf/prog_tests/map_kptr.c
+@@ -105,7 +105,7 @@ static void test_map_kptr_success(bool test_run)
+ 	ASSERT_OK(opts.retval, "test_map_kptr_ref2 retval");
+ 
+ 	if (test_run)
+-		return;
++		goto exit;
+ 
+ 	ret = bpf_map__update_elem(skel->maps.array_map,
+ 				   &key, sizeof(key), buf, sizeof(buf), 0);
+@@ -132,6 +132,7 @@ static void test_map_kptr_success(bool test_run)
+ 	ret = bpf_map__delete_elem(skel->maps.lru_hash_map, &key, sizeof(key), 0);
+ 	ASSERT_OK(ret, "lru_hash_map delete");
+ 
++exit:
+ 	map_kptr__destroy(skel);
+ }
+ 
+diff --git a/tools/testing/selftests/bpf/prog_tests/tracing_struct.c b/tools/testing/selftests/bpf/prog_tests/tracing_struct.c
+new file mode 100644
+index 0000000000000..48dc9472e160a
+--- /dev/null
++++ b/tools/testing/selftests/bpf/prog_tests/tracing_struct.c
+@@ -0,0 +1,64 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
++
++#include <test_progs.h>
++#include "tracing_struct.skel.h"
++
++static void test_fentry(void)
++{
++	struct tracing_struct *skel;
++	int err;
++
++	skel = tracing_struct__open_and_load();
++	if (!ASSERT_OK_PTR(skel, "tracing_struct__open_and_load"))
++		return;
++
++	err = tracing_struct__attach(skel);
++	if (!ASSERT_OK(err, "tracing_struct__attach"))
++		goto destroy_skel;
++
++	ASSERT_OK(trigger_module_test_read(256), "trigger_read");
++
++	ASSERT_EQ(skel->bss->t1_a_a, 2, "t1:a.a");
++	ASSERT_EQ(skel->bss->t1_a_b, 3, "t1:a.b");
++	ASSERT_EQ(skel->bss->t1_b, 1, "t1:b");
++	ASSERT_EQ(skel->bss->t1_c, 4, "t1:c");
++
++	ASSERT_EQ(skel->bss->t1_nregs, 4, "t1 nregs");
++	ASSERT_EQ(skel->bss->t1_reg0, 2, "t1 reg0");
++	ASSERT_EQ(skel->bss->t1_reg1, 3, "t1 reg1");
++	ASSERT_EQ(skel->bss->t1_reg2, 1, "t1 reg2");
++	ASSERT_EQ(skel->bss->t1_reg3, 4, "t1 reg3");
++	ASSERT_EQ(skel->bss->t1_ret, 10, "t1 ret");
++
++	ASSERT_EQ(skel->bss->t2_a, 1, "t2:a");
++	ASSERT_EQ(skel->bss->t2_b_a, 2, "t2:b.a");
++	ASSERT_EQ(skel->bss->t2_b_b, 3, "t2:b.b");
++	ASSERT_EQ(skel->bss->t2_c, 4, "t2:c");
++	ASSERT_EQ(skel->bss->t2_ret, 10, "t2 ret");
++
++	ASSERT_EQ(skel->bss->t3_a, 1, "t3:a");
++	ASSERT_EQ(skel->bss->t3_b, 4, "t3:b");
++	ASSERT_EQ(skel->bss->t3_c_a, 2, "t3:c.a");
++	ASSERT_EQ(skel->bss->t3_c_b, 3, "t3:c.b");
++	ASSERT_EQ(skel->bss->t3_ret, 10, "t3 ret");
++
++	ASSERT_EQ(skel->bss->t4_a_a, 10, "t4:a.a");
++	ASSERT_EQ(skel->bss->t4_b, 1, "t4:b");
++	ASSERT_EQ(skel->bss->t4_c, 2, "t4:c");
++	ASSERT_EQ(skel->bss->t4_d, 3, "t4:d");
++	ASSERT_EQ(skel->bss->t4_e_a, 2, "t4:e.a");
++	ASSERT_EQ(skel->bss->t4_e_b, 3, "t4:e.b");
++	ASSERT_EQ(skel->bss->t4_ret, 21, "t4 ret");
++
++	ASSERT_EQ(skel->bss->t5_ret, 1, "t5 ret");
++
++	tracing_struct__detach(skel);
++destroy_skel:
++	tracing_struct__destroy(skel);
++}
++
++void test_tracing_struct(void)
++{
++	test_fentry();
++}
+diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
+index 21ceac24e1744..8f2613267be26 100644
+--- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
++++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
+@@ -18,7 +18,7 @@ static void test_xdp_adjust_tail_shrink(void)
+ 	);
+ 
+ 	err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
+-	if (ASSERT_OK(err, "test_xdp_adjust_tail_shrink"))
++	if (!ASSERT_OK(err, "test_xdp_adjust_tail_shrink"))
+ 		return;
+ 
+ 	err = bpf_prog_test_run_opts(prog_fd, &topts);
+@@ -53,7 +53,7 @@ static void test_xdp_adjust_tail_grow(void)
+ 	);
+ 
+ 	err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
+-	if (ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
++	if (!ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
+ 		return;
+ 
+ 	err = bpf_prog_test_run_opts(prog_fd, &topts);
+@@ -63,6 +63,7 @@ static void test_xdp_adjust_tail_grow(void)
+ 	expect_sz = sizeof(pkt_v6) + 40; /* Test grow with 40 bytes */
+ 	topts.data_in = &pkt_v6;
+ 	topts.data_size_in = sizeof(pkt_v6);
++	topts.data_size_out = sizeof(buf);
+ 	err = bpf_prog_test_run_opts(prog_fd, &topts);
+ 	ASSERT_OK(err, "ipv6");
+ 	ASSERT_EQ(topts.retval, XDP_TX, "ipv6 retval");
+@@ -89,7 +90,7 @@ static void test_xdp_adjust_tail_grow2(void)
+ 	);
+ 
+ 	err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd);
+-	if (ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
++	if (!ASSERT_OK(err, "test_xdp_adjust_tail_grow"))
+ 		return;
+ 
+ 	/* Test case-64 */
+diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c b/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
+index a50971c6cf4a5..9ac6f6a268db2 100644
+--- a/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
++++ b/tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
+@@ -85,7 +85,7 @@ static void test_max_pkt_size(int fd)
+ }
+ 
+ #define NUM_PKTS 10000
+-void test_xdp_do_redirect(void)
++void serial_test_xdp_do_redirect(void)
+ {
+ 	int err, xdp_prog_fd, tc_prog_fd, ifindex_src, ifindex_dst;
+ 	char data[sizeof(pkt_udp) + sizeof(__u32)];
+diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c b/tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c
+index 874a846e298ca..b49d14580e516 100644
+--- a/tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c
++++ b/tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c
+@@ -174,7 +174,7 @@ out:
+ 	system("ip netns del synproxy");
+ }
+ 
+-void test_xdp_synproxy(void)
++void serial_test_xdp_synproxy(void)
+ {
+ 	if (test__start_subtest("xdp"))
+ 		test_synproxy(true);
+diff --git a/tools/testing/selftests/bpf/progs/bpf_iter_ksym.c b/tools/testing/selftests/bpf/progs/bpf_iter_ksym.c
+index 285c008cbf9c2..9ba14c37bbcc9 100644
+--- a/tools/testing/selftests/bpf/progs/bpf_iter_ksym.c
++++ b/tools/testing/selftests/bpf/progs/bpf_iter_ksym.c
+@@ -7,14 +7,14 @@ char _license[] SEC("license") = "GPL";
+ 
+ unsigned long last_sym_value = 0;
+ 
+-static inline char tolower(char c)
++static inline char to_lower(char c)
+ {
+ 	if (c >= 'A' && c <= 'Z')
+ 		c += ('a' - 'A');
+ 	return c;
+ }
+ 
+-static inline char toupper(char c)
++static inline char to_upper(char c)
+ {
+ 	if (c >= 'a' && c <= 'z')
+ 		c -= ('a' - 'A');
+@@ -54,7 +54,7 @@ int dump_ksym(struct bpf_iter__ksym *ctx)
+ 	type = iter->type;
+ 
+ 	if (iter->module_name[0]) {
+-		type = iter->exported ? toupper(type) : tolower(type);
++		type = iter->exported ? to_upper(type) : to_lower(type);
+ 		BPF_SEQ_PRINTF(seq, "0x%llx %c %s [ %s ] ",
+ 			       value, type, iter->name, iter->module_name);
+ 	} else {
+diff --git a/tools/testing/selftests/bpf/progs/empty_skb.c b/tools/testing/selftests/bpf/progs/empty_skb.c
+new file mode 100644
+index 0000000000000..4b0cd67532511
+--- /dev/null
++++ b/tools/testing/selftests/bpf/progs/empty_skb.c
+@@ -0,0 +1,37 @@
++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
++#include <linux/bpf.h>
++#include <bpf/bpf_helpers.h>
++#include <bpf/bpf_endian.h>
++
++char _license[] SEC("license") = "GPL";
++
++int ifindex;
++int ret;
++
++SEC("lwt_xmit")
++int redirect_ingress(struct __sk_buff *skb)
++{
++	ret = bpf_clone_redirect(skb, ifindex, BPF_F_INGRESS);
++	return 0;
++}
++
++SEC("lwt_xmit")
++int redirect_egress(struct __sk_buff *skb)
++{
++	ret = bpf_clone_redirect(skb, ifindex, 0);
++	return 0;
++}
++
++SEC("tc")
++int tc_redirect_ingress(struct __sk_buff *skb)
++{
++	ret = bpf_clone_redirect(skb, ifindex, BPF_F_INGRESS);
++	return 0;
++}
++
++SEC("tc")
++int tc_redirect_egress(struct __sk_buff *skb)
++{
++	ret = bpf_clone_redirect(skb, ifindex, 0);
++	return 0;
++}
+diff --git a/tools/testing/selftests/bpf/progs/lsm_cgroup.c b/tools/testing/selftests/bpf/progs/lsm_cgroup.c
+index 4f2d60b87b75d..02c11d16b692a 100644
+--- a/tools/testing/selftests/bpf/progs/lsm_cgroup.c
++++ b/tools/testing/selftests/bpf/progs/lsm_cgroup.c
+@@ -7,6 +7,10 @@
+ 
+ char _license[] SEC("license") = "GPL";
+ 
++extern bool CONFIG_SECURITY_SELINUX __kconfig __weak;
++extern bool CONFIG_SECURITY_SMACK __kconfig __weak;
++extern bool CONFIG_SECURITY_APPARMOR __kconfig __weak;
++
+ #ifndef AF_PACKET
+ #define AF_PACKET 17
+ #endif
+@@ -140,6 +144,10 @@ SEC("lsm_cgroup/sk_alloc_security")
+ int BPF_PROG(socket_alloc, struct sock *sk, int family, gfp_t priority)
+ {
+ 	called_socket_alloc++;
++	/* if already have non-bpf lsms installed, EPERM will cause memory leak of non-bpf lsms */
++	if (CONFIG_SECURITY_SELINUX || CONFIG_SECURITY_SMACK || CONFIG_SECURITY_APPARMOR)
++		return 1;
++
+ 	if (family == AF_UNIX)
+ 		return 0; /* EPERM */
+ 
+diff --git a/tools/testing/selftests/bpf/progs/tracing_struct.c b/tools/testing/selftests/bpf/progs/tracing_struct.c
+new file mode 100644
+index 0000000000000..e718f0ebee7dd
+--- /dev/null
++++ b/tools/testing/selftests/bpf/progs/tracing_struct.c
+@@ -0,0 +1,120 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
++
++#include <vmlinux.h>
++#include <bpf/bpf_tracing.h>
++#include <bpf/bpf_helpers.h>
++
++struct bpf_testmod_struct_arg_1 {
++	int a;
++};
++struct bpf_testmod_struct_arg_2 {
++	long a;
++	long b;
++};
++
++long t1_a_a, t1_a_b, t1_b, t1_c, t1_ret, t1_nregs;
++__u64 t1_reg0, t1_reg1, t1_reg2, t1_reg3;
++long t2_a, t2_b_a, t2_b_b, t2_c, t2_ret;
++long t3_a, t3_b, t3_c_a, t3_c_b, t3_ret;
++long t4_a_a, t4_b, t4_c, t4_d, t4_e_a, t4_e_b, t4_ret;
++long t5_ret;
++
++SEC("fentry/bpf_testmod_test_struct_arg_1")
++int BPF_PROG2(test_struct_arg_1, struct bpf_testmod_struct_arg_2, a, int, b, int, c)
++{
++	t1_a_a = a.a;
++	t1_a_b = a.b;
++	t1_b = b;
++	t1_c = c;
++	return 0;
++}
++
++SEC("fexit/bpf_testmod_test_struct_arg_1")
++int BPF_PROG2(test_struct_arg_2, struct bpf_testmod_struct_arg_2, a, int, b, int, c, int, ret)
++{
++	t1_nregs =  bpf_get_func_arg_cnt(ctx);
++	/* a.a */
++	bpf_get_func_arg(ctx, 0, &t1_reg0);
++	/* a.b */
++	bpf_get_func_arg(ctx, 1, &t1_reg1);
++	/* b */
++	bpf_get_func_arg(ctx, 2, &t1_reg2);
++	t1_reg2 = (int)t1_reg2;
++	/* c */
++	bpf_get_func_arg(ctx, 3, &t1_reg3);
++	t1_reg3 = (int)t1_reg3;
++
++	t1_ret = ret;
++	return 0;
++}
++
++SEC("fentry/bpf_testmod_test_struct_arg_2")
++int BPF_PROG2(test_struct_arg_3, int, a, struct bpf_testmod_struct_arg_2, b, int, c)
++{
++	t2_a = a;
++	t2_b_a = b.a;
++	t2_b_b = b.b;
++	t2_c = c;
++	return 0;
++}
++
++SEC("fexit/bpf_testmod_test_struct_arg_2")
++int BPF_PROG2(test_struct_arg_4, int, a, struct bpf_testmod_struct_arg_2, b, int, c, int, ret)
++{
++	t2_ret = ret;
++	return 0;
++}
++
++SEC("fentry/bpf_testmod_test_struct_arg_3")
++int BPF_PROG2(test_struct_arg_5, int, a, int, b, struct bpf_testmod_struct_arg_2, c)
++{
++	t3_a = a;
++	t3_b = b;
++	t3_c_a = c.a;
++	t3_c_b = c.b;
++	return 0;
++}
++
++SEC("fexit/bpf_testmod_test_struct_arg_3")
++int BPF_PROG2(test_struct_arg_6, int, a, int, b, struct bpf_testmod_struct_arg_2, c, int, ret)
++{
++	t3_ret = ret;
++	return 0;
++}
++
++SEC("fentry/bpf_testmod_test_struct_arg_4")
++int BPF_PROG2(test_struct_arg_7, struct bpf_testmod_struct_arg_1, a, int, b,
++	     int, c, int, d, struct bpf_testmod_struct_arg_2, e)
++{
++	t4_a_a = a.a;
++	t4_b = b;
++	t4_c = c;
++	t4_d = d;
++	t4_e_a = e.a;
++	t4_e_b = e.b;
++	return 0;
++}
++
++SEC("fexit/bpf_testmod_test_struct_arg_4")
++int BPF_PROG2(test_struct_arg_8, struct bpf_testmod_struct_arg_1, a, int, b,
++	     int, c, int, d, struct bpf_testmod_struct_arg_2, e, int, ret)
++{
++	t4_ret = ret;
++	return 0;
++}
++
++SEC("fentry/bpf_testmod_test_struct_arg_5")
++int BPF_PROG2(test_struct_arg_9)
++{
++	return 0;
++}
++
++SEC("fexit/bpf_testmod_test_struct_arg_5")
++int BPF_PROG2(test_struct_arg_10, int, ret)
++{
++	t5_ret = ret;
++	return 0;
++}
++
++char _license[] SEC("license") = "GPL";
+diff --git a/tools/testing/selftests/bpf/xdp_synproxy.c b/tools/testing/selftests/bpf/xdp_synproxy.c
+index d874ddfb39c46..8432836f3be2d 100644
+--- a/tools/testing/selftests/bpf/xdp_synproxy.c
++++ b/tools/testing/selftests/bpf/xdp_synproxy.c
+@@ -104,7 +104,8 @@ static void parse_options(int argc, char *argv[], unsigned int *ifindex, __u32 *
+ 		{ "tc", no_argument, NULL, 'c' },
+ 		{ NULL, 0, NULL, 0 },
+ 	};
+-	unsigned long mss4, mss6, wscale, ttl;
++	unsigned long mss4, wscale, ttl;
++	unsigned long long mss6;
+ 	unsigned int tcpipopts_mask = 0;
+ 
+ 	if (argc < 2)
+@@ -286,7 +287,7 @@ static int syncookie_open_bpf_maps(__u32 prog_id, int *values_map_fd, int *ports
+ 
+ 	prog_info = (struct bpf_prog_info) {
+ 		.nr_map_ids = 8,
+-		.map_ids = (__u64)map_ids,
++		.map_ids = (__u64)(unsigned long)map_ids,
+ 	};
+ 	info_len = sizeof(prog_info);
+ 
+diff --git a/tools/testing/selftests/cgroup/cgroup_util.c b/tools/testing/selftests/cgroup/cgroup_util.c
+index 4c52cc6f2f9cc..e8bbbdb77e0d5 100644
+--- a/tools/testing/selftests/cgroup/cgroup_util.c
++++ b/tools/testing/selftests/cgroup/cgroup_util.c
+@@ -555,6 +555,7 @@ int proc_mount_contains(const char *option)
+ ssize_t proc_read_text(int pid, bool thread, const char *item, char *buf, size_t size)
+ {
+ 	char path[PATH_MAX];
++	ssize_t ret;
+ 
+ 	if (!pid)
+ 		snprintf(path, sizeof(path), "/proc/%s/%s",
+@@ -562,8 +563,8 @@ ssize_t proc_read_text(int pid, bool thread, const char *item, char *buf, size_t
+ 	else
+ 		snprintf(path, sizeof(path), "/proc/%d/%s", pid, item);
+ 
+-	size = read_text(path, buf, size);
+-	return size < 0 ? -1 : size;
++	ret = read_text(path, buf, size);
++	return ret < 0 ? -1 : ret;
+ }
+ 
+ int proc_read_strstr(int pid, bool thread, const char *item, const char *needle)
+diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+index 9de1d123f4f5d..a08c02abde121 100755
+--- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
++++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+@@ -496,8 +496,8 @@ dummy_reporter_test()
+ 
+ 	check_reporter_info dummy healthy 3 3 10 true
+ 
+-	echo 8192> $DEBUGFS_DIR/health/binary_len
+-	check_fail $? "Failed set dummy reporter binary len to 8192"
++	echo 8192 > $DEBUGFS_DIR/health/binary_len
++	check_err $? "Failed set dummy reporter binary len to 8192"
+ 
+ 	local dump=$(devlink health dump show $DL_HANDLE reporter dummy -j)
+ 	check_err $? "Failed show dump of dummy reporter"
+diff --git a/tools/testing/selftests/efivarfs/efivarfs.sh b/tools/testing/selftests/efivarfs/efivarfs.sh
+index a90f394f9aa90..d374878cc0ba9 100755
+--- a/tools/testing/selftests/efivarfs/efivarfs.sh
++++ b/tools/testing/selftests/efivarfs/efivarfs.sh
+@@ -87,6 +87,11 @@ test_create_read()
+ {
+ 	local file=$efivarfs_mount/$FUNCNAME-$test_guid
+ 	./create-read $file
++	if [ $? -ne 0 ]; then
++		echo "create and read $file failed"
++		file_cleanup $file
++		exit 1
++	fi
+ 	file_cleanup $file
+ }
+ 
+diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
+index 3145b0f1835c3..27a68bbe778be 100644
+--- a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
++++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
+@@ -38,11 +38,18 @@ cnt_trace() {
+ 
+ test_event_enabled() {
+     val=$1
++    check_times=10		# wait for 10 * SLEEP_TIME at most
+ 
+-    e=`cat $EVENT_ENABLE`
+-    if [ "$e" != $val ]; then
+-	fail "Expected $val but found $e"
+-    fi
++    while [ $check_times -ne 0 ]; do
++	e=`cat $EVENT_ENABLE`
++	if [ "$e" == $val ]; then
++	    return 0
++	fi
++	sleep $SLEEP_TIME
++	check_times=$((check_times - 1))
++    done
++
++    fail "Expected $val but found $e"
+ }
+ 
+ run_enable_disable() {
+diff --git a/tools/testing/selftests/netfilter/conntrack_icmp_related.sh b/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
+index b48e1833bc896..76645aaf2b58f 100755
+--- a/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
++++ b/tools/testing/selftests/netfilter/conntrack_icmp_related.sh
+@@ -35,6 +35,8 @@ cleanup() {
+ 	for i in 1 2;do ip netns del nsrouter$i;done
+ }
+ 
++trap cleanup EXIT
++
+ ipv4() {
+     echo -n 192.168.$1.2
+ }
+@@ -146,11 +148,17 @@ ip netns exec nsclient1 nft -f - <<EOF
+ table inet filter {
+ 	counter unknown { }
+ 	counter related { }
++	counter redir4 { }
++	counter redir6 { }
+ 	chain input {
+ 		type filter hook input priority 0; policy accept;
+-		meta l4proto { icmp, icmpv6 } ct state established,untracked accept
+ 
++		icmp type "redirect" ct state "related" counter name "redir4" accept
++		icmpv6 type "nd-redirect" ct state "related" counter name "redir6" accept
++
++		meta l4proto { icmp, icmpv6 } ct state established,untracked accept
+ 		meta l4proto { icmp, icmpv6 } ct state "related" counter name "related" accept
++
+ 		counter name "unknown" drop
+ 	}
+ }
+@@ -279,5 +287,29 @@ else
+ 	echo "ERROR: icmp error RELATED state test has failed"
+ fi
+ 
+-cleanup
++# add 'bad' route,  expect icmp REDIRECT to be generated
++ip netns exec nsclient1 ip route add 192.168.1.42 via 192.168.1.1
++ip netns exec nsclient1 ip route add dead:1::42 via dead:1::1
++
++ip netns exec "nsclient1" ping -q -c 2 192.168.1.42 > /dev/null
++
++expect="packets 1 bytes 112"
++check_counter nsclient1 "redir4" "$expect"
++if [ $? -ne 0 ];then
++	ret=1
++fi
++
++ip netns exec "nsclient1" ping -c 1 dead:1::42 > /dev/null
++expect="packets 1 bytes 192"
++check_counter nsclient1 "redir6" "$expect"
++if [ $? -ne 0 ];then
++	ret=1
++fi
++
++if [ $ret -eq 0 ];then
++	echo "PASS: icmp redirects had RELATED state"
++else
++	echo "ERROR: icmp redirect RELATED state test has failed"
++fi
++
+ exit $ret
+diff --git a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
+index fbbdffdb2e5d2..f20d1c166d1e4 100644
+--- a/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
++++ b/tools/testing/selftests/powerpc/dscr/dscr_sysfs_test.c
+@@ -24,6 +24,7 @@ static int check_cpu_dscr_default(char *file, unsigned long val)
+ 	rc = read(fd, buf, sizeof(buf));
+ 	if (rc == -1) {
+ 		perror("read() failed");
++		close(fd);
+ 		return 1;
+ 	}
+ 	close(fd);
+@@ -65,8 +66,10 @@ static int check_all_cpu_dscr_defaults(unsigned long val)
+ 		if (access(file, F_OK))
+ 			continue;
+ 
+-		if (check_cpu_dscr_default(file, val))
++		if (check_cpu_dscr_default(file, val)) {
++			closedir(sysfs);
+ 			return 1;
++		}
+ 	}
+ 	closedir(sysfs);
+ 	return 0;
+diff --git a/tools/testing/selftests/proc/proc-uptime-002.c b/tools/testing/selftests/proc/proc-uptime-002.c
+index e7ceabed7f51f..7d0aa22bdc12b 100644
+--- a/tools/testing/selftests/proc/proc-uptime-002.c
++++ b/tools/testing/selftests/proc/proc-uptime-002.c
+@@ -17,6 +17,7 @@
+ // while shifting across CPUs.
+ #undef NDEBUG
+ #include <assert.h>
++#include <errno.h>
+ #include <unistd.h>
+ #include <sys/syscall.h>
+ #include <stdlib.h>
+@@ -54,7 +55,7 @@ int main(void)
+ 		len += sizeof(unsigned long);
+ 		free(m);
+ 		m = malloc(len);
+-	} while (sys_sched_getaffinity(0, len, m) == -EINVAL);
++	} while (sys_sched_getaffinity(0, len, m) == -1 && errno == EINVAL);
+ 
+ 	fd = open("/proc/uptime", O_RDONLY);
+ 	assert(fd >= 0);


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-21 18:50 Alice Ferrazzi
  0 siblings, 0 replies; 27+ messages in thread
From: Alice Ferrazzi @ 2022-12-21 18:50 UTC (permalink / raw
  To: gentoo-commits

commit:     0d6ea46e3e6783a7f13b4a75e254ae727414acbc
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 21 18:45:57 2022 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Wed Dec 21 18:46:42 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=0d6ea46e

Linux patch 6.0.15

Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org>

 0000_README             |    4 +
 1014_linux-6.0.15.patch | 1127 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1131 insertions(+)

diff --git a/0000_README b/0000_README
index 578f9e3d..302d8339 100644
--- a/0000_README
+++ b/0000_README
@@ -99,6 +99,10 @@ Patch:  1013_linux-6.0.14.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.14
 
+Patch:  1014_linux-6.0.15.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.15
+
 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/1014_linux-6.0.15.patch b/1014_linux-6.0.15.patch
new file mode 100644
index 00000000..2173b214
--- /dev/null
+++ b/1014_linux-6.0.15.patch
@@ -0,0 +1,1127 @@
+diff --git a/Documentation/security/keys/trusted-encrypted.rst b/Documentation/security/keys/trusted-encrypted.rst
+index 0bfb4c3397489..9bc9db8ec6517 100644
+--- a/Documentation/security/keys/trusted-encrypted.rst
++++ b/Documentation/security/keys/trusted-encrypted.rst
+@@ -350,7 +350,8 @@ Load an encrypted key "evm" from saved blob::
+ 
+ Instantiate an encrypted key "evm" using user-provided decrypted data::
+ 
+-    $ keyctl add encrypted evm "new default user:kmk 32 `cat evm_decrypted_data.blob`" @u
++    $ evmkey=$(dd if=/dev/urandom bs=1 count=32 | xxd -c32 -p)
++    $ keyctl add encrypted evm "new default user:kmk 32 $evmkey" @u
+     794890253
+ 
+     $ keyctl print 794890253
+diff --git a/Makefile b/Makefile
+index a3c02b45fb575..0c7ae314ad3d5 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 14
++SUBLEVEL = 15
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index 2796e81d27260..ea46649b2ed3e 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -7522,7 +7522,7 @@ static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
+ {
+ 	struct e1000_hw *hw = &adapter->hw;
+ 	unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
+-	u32 reg, msgbuf[3];
++	u32 reg, msgbuf[3] = {};
+ 	u8 *addr = (u8 *)(&msgbuf[1]);
+ 
+ 	/* process all the same items cleared in a function level reset */
+diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
+index 14e8d04cb4347..2e9742952c4e9 100644
+--- a/drivers/net/loopback.c
++++ b/drivers/net/loopback.c
+@@ -211,7 +211,7 @@ static __net_init int loopback_net_init(struct net *net)
+ 	int err;
+ 
+ 	err = -ENOMEM;
+-	dev = alloc_netdev(0, "lo", NET_NAME_UNKNOWN, loopback_setup);
++	dev = alloc_netdev(0, "lo", NET_NAME_PREDICTABLE, loopback_setup);
+ 	if (!dev)
+ 		goto out;
+ 
+diff --git a/drivers/pci/controller/pcie-mt7621.c b/drivers/pci/controller/pcie-mt7621.c
+index 33eb37a2225c1..0f02f191946a0 100644
+--- a/drivers/pci/controller/pcie-mt7621.c
++++ b/drivers/pci/controller/pcie-mt7621.c
+@@ -471,7 +471,8 @@ static int mt7621_pcie_register_host(struct pci_host_bridge *host)
+ }
+ 
+ static const struct soc_device_attribute mt7621_pcie_quirks_match[] = {
+-	{ .soc_id = "mt7621", .revision = "E2" }
++	{ .soc_id = "mt7621", .revision = "E2" },
++	{ /* sentinel */ }
+ };
+ 
+ static int mt7621_pcie_probe(struct platform_device *pdev)
+diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
+index 4ee4ca09873af..9d3bbbb33dcf3 100644
+--- a/drivers/usb/dwc3/dwc3-pci.c
++++ b/drivers/usb/dwc3/dwc3-pci.c
+@@ -44,7 +44,7 @@
+ #define PCI_DEVICE_ID_INTEL_ADLP		0x51ee
+ #define PCI_DEVICE_ID_INTEL_ADLM		0x54ee
+ #define PCI_DEVICE_ID_INTEL_ADLS		0x7ae1
+-#define PCI_DEVICE_ID_INTEL_RPL			0x460e
++#define PCI_DEVICE_ID_INTEL_RPL			0xa70e
+ #define PCI_DEVICE_ID_INTEL_RPLS		0x7a61
+ #define PCI_DEVICE_ID_INTEL_MTLP		0x7ec1
+ #define PCI_DEVICE_ID_INTEL_MTL			0x7e7e
+diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
+index 7ec223849d949..4d3f62d754789 100644
+--- a/drivers/usb/gadget/function/f_uvc.c
++++ b/drivers/usb/gadget/function/f_uvc.c
+@@ -216,8 +216,9 @@ uvc_function_ep0_complete(struct usb_ep *ep, struct usb_request *req)
+ 
+ 		memset(&v4l2_event, 0, sizeof(v4l2_event));
+ 		v4l2_event.type = UVC_EVENT_DATA;
+-		uvc_event->data.length = req->actual;
+-		memcpy(&uvc_event->data.data, req->buf, req->actual);
++		uvc_event->data.length = min_t(unsigned int, req->actual,
++			sizeof(uvc_event->data.data));
++		memcpy(&uvc_event->data.data, req->buf, uvc_event->data.length);
+ 		v4l2_event_queue(&uvc->vdev, &v4l2_event);
+ 	}
+ }
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index 0a8d37c5af030..7191cacba2274 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -59,6 +59,7 @@
+ #define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI		0x9a13
+ #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI		0x1138
+ #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI		0x51ed
++#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_PCH_XHCI	0x54ed
+ 
+ #define PCI_DEVICE_ID_AMD_RENOIR_XHCI			0x1639
+ #define PCI_DEVICE_ID_AMD_PROMONTORYA_4			0x43b9
+@@ -246,7 +247,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ 		xhci->quirks |= XHCI_MISSING_CAS;
+ 
+ 	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+-	    pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI)
++	    (pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI ||
++	     pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_PCH_XHCI))
+ 		xhci->quirks |= XHCI_RESET_TO_DEFAULT;
+ 
+ 	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index a34957c4b64c0..0fd3a9d76beba 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -195,6 +195,8 @@ static const struct usb_device_id id_table[] = {
+ 	{ USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */
+ 	{ USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */
+ 	{ USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */
++	{ USB_DEVICE(0x17A8, 0x0011) }, /* Kamstrup 444 MHz RF sniffer */
++	{ USB_DEVICE(0x17A8, 0x0013) }, /* Kamstrup 870 MHz RF sniffer */
+ 	{ USB_DEVICE(0x17A8, 0x0101) }, /* Kamstrup 868 MHz wM-Bus C-Mode Meter Reader (Int Ant) */
+ 	{ USB_DEVICE(0x17A8, 0x0102) }, /* Kamstrup 868 MHz wM-Bus C-Mode Meter Reader (Ext Ant) */
+ 	{ USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
+diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c
+index d9f20256a6a8e..b8cf21bec334e 100644
+--- a/drivers/usb/serial/f81232.c
++++ b/drivers/usb/serial/f81232.c
+@@ -130,9 +130,6 @@ static u8 const clock_table[] = { F81232_CLK_1_846_MHZ, F81232_CLK_14_77_MHZ,
+ 
+ static int calc_baud_divisor(speed_t baudrate, speed_t clockrate)
+ {
+-	if (!baudrate)
+-		return 0;
+-
+ 	return DIV_ROUND_CLOSEST(clockrate, baudrate);
+ }
+ 
+@@ -498,9 +495,14 @@ static void f81232_set_baudrate(struct tty_struct *tty,
+ 	speed_t baud_list[] = { baudrate, old_baudrate, F81232_DEF_BAUDRATE };
+ 
+ 	for (i = 0; i < ARRAY_SIZE(baud_list); ++i) {
+-		idx = f81232_find_clk(baud_list[i]);
++		baudrate = baud_list[i];
++		if (baudrate == 0) {
++			tty_encode_baud_rate(tty, 0, 0);
++			return;
++		}
++
++		idx = f81232_find_clk(baudrate);
+ 		if (idx >= 0) {
+-			baudrate = baud_list[i];
+ 			tty_encode_baud_rate(tty, baudrate, baudrate);
+ 			break;
+ 		}
+diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c
+index d789c1ec87b35..f331d39c3b267 100644
+--- a/drivers/usb/serial/f81534.c
++++ b/drivers/usb/serial/f81534.c
+@@ -536,9 +536,6 @@ static int f81534_submit_writer(struct usb_serial_port *port, gfp_t mem_flags)
+ 
+ static u32 f81534_calc_baud_divisor(u32 baudrate, u32 clockrate)
+ {
+-	if (!baudrate)
+-		return 0;
+-
+ 	/* Round to nearest divisor */
+ 	return DIV_ROUND_CLOSEST(clockrate, baudrate);
+ }
+@@ -568,9 +565,14 @@ static int f81534_set_port_config(struct usb_serial_port *port,
+ 	u32 baud_list[] = {baudrate, old_baudrate, F81534_DEFAULT_BAUD_RATE};
+ 
+ 	for (i = 0; i < ARRAY_SIZE(baud_list); ++i) {
+-		idx = f81534_find_clk(baud_list[i]);
++		baudrate = baud_list[i];
++		if (baudrate == 0) {
++			tty_encode_baud_rate(tty, 0, 0);
++			return 0;
++		}
++
++		idx = f81534_find_clk(baudrate);
+ 		if (idx >= 0) {
+-			baudrate = baud_list[i];
+ 			tty_encode_baud_rate(tty, baudrate, baudrate);
+ 			break;
+ 		}
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index c3b7f1d98e781..dee79c7d82d5c 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -255,6 +255,7 @@ static void option_instat_callback(struct urb *urb);
+ #define QUECTEL_PRODUCT_EP06			0x0306
+ #define QUECTEL_PRODUCT_EM05G			0x030a
+ #define QUECTEL_PRODUCT_EM060K			0x030b
++#define QUECTEL_PRODUCT_EM05G_SG		0x0311
+ #define QUECTEL_PRODUCT_EM12			0x0512
+ #define QUECTEL_PRODUCT_RM500Q			0x0800
+ #define QUECTEL_PRODUCT_RM520N			0x0801
+@@ -1160,6 +1161,8 @@ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
+ 	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff),
+ 	  .driver_info = RSVD(6) | ZLP },
++	{ USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_SG, 0xff),
++	  .driver_info = RSVD(6) | ZLP },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) },
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index a7987fc764cc6..eabe519013e78 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -1270,8 +1270,9 @@ err:
+ 	return ret;
+ }
+ 
+-int ucsi_resume(struct ucsi *ucsi)
++static void ucsi_resume_work(struct work_struct *work)
+ {
++	struct ucsi *ucsi = container_of(work, struct ucsi, resume_work);
+ 	struct ucsi_connector *con;
+ 	u64 command;
+ 	int ret;
+@@ -1279,15 +1280,21 @@ int ucsi_resume(struct ucsi *ucsi)
+ 	/* Restore UCSI notification enable mask after system resume */
+ 	command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
+ 	ret = ucsi_send_command(ucsi, command, NULL, 0);
+-	if (ret < 0)
+-		return ret;
++	if (ret < 0) {
++		dev_err(ucsi->dev, "failed to re-enable notifications (%d)\n", ret);
++		return;
++	}
+ 
+ 	for (con = ucsi->connector; con->port; con++) {
+ 		mutex_lock(&con->lock);
+-		ucsi_check_connection(con);
++		ucsi_partner_task(con, ucsi_check_connection, 1, 0);
+ 		mutex_unlock(&con->lock);
+ 	}
++}
+ 
++int ucsi_resume(struct ucsi *ucsi)
++{
++	queue_work(system_long_wq, &ucsi->resume_work);
+ 	return 0;
+ }
+ EXPORT_SYMBOL_GPL(ucsi_resume);
+@@ -1347,6 +1354,7 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops)
+ 	if (!ucsi)
+ 		return ERR_PTR(-ENOMEM);
+ 
++	INIT_WORK(&ucsi->resume_work, ucsi_resume_work);
+ 	INIT_DELAYED_WORK(&ucsi->work, ucsi_init_work);
+ 	mutex_init(&ucsi->ppm_lock);
+ 	ucsi->dev = dev;
+@@ -1401,6 +1409,7 @@ void ucsi_unregister(struct ucsi *ucsi)
+ 
+ 	/* Make sure that we are not in the middle of driver initialization */
+ 	cancel_delayed_work_sync(&ucsi->work);
++	cancel_work_sync(&ucsi->resume_work);
+ 
+ 	/* Disable notifications */
+ 	ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd));
+diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h
+index 8eb391e3e592c..c968474ee5473 100644
+--- a/drivers/usb/typec/ucsi/ucsi.h
++++ b/drivers/usb/typec/ucsi/ucsi.h
+@@ -287,6 +287,7 @@ struct ucsi {
+ 	struct ucsi_capability cap;
+ 	struct ucsi_connector *connector;
+ 
++	struct work_struct resume_work;
+ 	struct delayed_work work;
+ 	int work_count;
+ #define UCSI_ROLE_SWITCH_RETRY_PER_HZ	10
+diff --git a/fs/udf/inode.c b/fs/udf/inode.c
+index 8d06daed549f9..b9a83820e1adf 100644
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -439,6 +439,12 @@ static int udf_get_block(struct inode *inode, sector_t block,
+ 		iinfo->i_next_alloc_goal++;
+ 	}
+ 
++	/*
++	 * Block beyond EOF and prealloc extents? Just discard preallocation
++	 * as it is not useful and complicates things.
++	 */
++	if (((loff_t)block) << inode->i_blkbits > iinfo->i_lenExtents)
++		udf_discard_prealloc(inode);
+ 	udf_clear_extent_cache(inode);
+ 	phys = inode_getblk(inode, block, &err, &new);
+ 	if (!phys)
+@@ -488,8 +494,6 @@ static int udf_do_extend_file(struct inode *inode,
+ 	uint32_t add;
+ 	int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+ 	struct super_block *sb = inode->i_sb;
+-	struct kernel_lb_addr prealloc_loc = {};
+-	uint32_t prealloc_len = 0;
+ 	struct udf_inode_info *iinfo;
+ 	int err;
+ 
+@@ -510,19 +514,6 @@ static int udf_do_extend_file(struct inode *inode,
+ 			~(sb->s_blocksize - 1);
+ 	}
+ 
+-	/* Last extent are just preallocated blocks? */
+-	if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
+-						EXT_NOT_RECORDED_ALLOCATED) {
+-		/* Save the extent so that we can reattach it to the end */
+-		prealloc_loc = last_ext->extLocation;
+-		prealloc_len = last_ext->extLength;
+-		/* Mark the extent as a hole */
+-		last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+-			(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+-		last_ext->extLocation.logicalBlockNum = 0;
+-		last_ext->extLocation.partitionReferenceNum = 0;
+-	}
+-
+ 	/* Can we merge with the previous extent? */
+ 	if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
+ 					EXT_NOT_RECORDED_NOT_ALLOCATED) {
+@@ -550,7 +541,7 @@ static int udf_do_extend_file(struct inode *inode,
+ 		 * more extents, we may need to enter possible following
+ 		 * empty indirect extent.
+ 		 */
+-		if (new_block_bytes || prealloc_len)
++		if (new_block_bytes)
+ 			udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0);
+ 	}
+ 
+@@ -584,17 +575,6 @@ static int udf_do_extend_file(struct inode *inode,
+ 	}
+ 
+ out:
+-	/* Do we have some preallocated blocks saved? */
+-	if (prealloc_len) {
+-		err = udf_add_aext(inode, last_pos, &prealloc_loc,
+-				   prealloc_len, 1);
+-		if (err)
+-			return err;
+-		last_ext->extLocation = prealloc_loc;
+-		last_ext->extLength = prealloc_len;
+-		count++;
+-	}
+-
+ 	/* last_pos should point to the last written extent... */
+ 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
+ 		last_pos->offset -= sizeof(struct short_ad);
+@@ -610,13 +590,17 @@ out:
+ static void udf_do_extend_final_block(struct inode *inode,
+ 				      struct extent_position *last_pos,
+ 				      struct kernel_long_ad *last_ext,
+-				      uint32_t final_block_len)
++				      uint32_t new_elen)
+ {
+-	struct super_block *sb = inode->i_sb;
+ 	uint32_t added_bytes;
+ 
+-	added_bytes = final_block_len -
+-		      (last_ext->extLength & (sb->s_blocksize - 1));
++	/*
++	 * Extent already large enough? It may be already rounded up to block
++	 * size...
++	 */
++	if (new_elen <= (last_ext->extLength & UDF_EXTENT_LENGTH_MASK))
++		return;
++	added_bytes = (last_ext->extLength & UDF_EXTENT_LENGTH_MASK) - new_elen;
+ 	last_ext->extLength += added_bytes;
+ 	UDF_I(inode)->i_lenExtents += added_bytes;
+ 
+@@ -633,12 +617,12 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
+ 	int8_t etype;
+ 	struct super_block *sb = inode->i_sb;
+ 	sector_t first_block = newsize >> sb->s_blocksize_bits, offset;
+-	unsigned long partial_final_block;
++	loff_t new_elen;
+ 	int adsize;
+ 	struct udf_inode_info *iinfo = UDF_I(inode);
+ 	struct kernel_long_ad extent;
+ 	int err = 0;
+-	int within_final_block;
++	bool within_last_ext;
+ 
+ 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
+ 		adsize = sizeof(struct short_ad);
+@@ -647,8 +631,17 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
+ 	else
+ 		BUG();
+ 
++	/*
++	 * When creating hole in file, just don't bother with preserving
++	 * preallocation. It likely won't be very useful anyway.
++	 */
++	udf_discard_prealloc(inode);
++
+ 	etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
+-	within_final_block = (etype != -1);
++	within_last_ext = (etype != -1);
++	/* We don't expect extents past EOF... */
++	WARN_ON_ONCE(within_last_ext &&
++		     elen > ((loff_t)offset + 1) << inode->i_blkbits);
+ 
+ 	if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) ||
+ 	    (epos.bh && epos.offset == sizeof(struct allocExtDesc))) {
+@@ -664,19 +657,17 @@ static int udf_extend_file(struct inode *inode, loff_t newsize)
+ 		extent.extLength |= etype << 30;
+ 	}
+ 
+-	partial_final_block = newsize & (sb->s_blocksize - 1);
++	new_elen = ((loff_t)offset << inode->i_blkbits) |
++					(newsize & (sb->s_blocksize - 1));
+ 
+ 	/* File has extent covering the new size (could happen when extending
+ 	 * inside a block)?
+ 	 */
+-	if (within_final_block) {
++	if (within_last_ext) {
+ 		/* Extending file within the last file block */
+-		udf_do_extend_final_block(inode, &epos, &extent,
+-					  partial_final_block);
++		udf_do_extend_final_block(inode, &epos, &extent, new_elen);
+ 	} else {
+-		loff_t add = ((loff_t)offset << sb->s_blocksize_bits) |
+-			     partial_final_block;
+-		err = udf_do_extend_file(inode, &epos, &extent, add);
++		err = udf_do_extend_file(inode, &epos, &extent, new_elen);
+ 	}
+ 
+ 	if (err < 0)
+@@ -777,10 +768,11 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
+ 		goto out_free;
+ 	}
+ 
+-	/* Are we beyond EOF? */
++	/* Are we beyond EOF and preallocated extent? */
+ 	if (etype == -1) {
+ 		int ret;
+ 		loff_t hole_len;
++
+ 		isBeyondEOF = true;
+ 		if (count) {
+ 			if (c)
+diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
+index 532cda99644ee..036ebd892b852 100644
+--- a/fs/udf/truncate.c
++++ b/fs/udf/truncate.c
+@@ -120,60 +120,42 @@ void udf_truncate_tail_extent(struct inode *inode)
+ 
+ void udf_discard_prealloc(struct inode *inode)
+ {
+-	struct extent_position epos = { NULL, 0, {0, 0} };
++	struct extent_position epos = {};
++	struct extent_position prev_epos = {};
+ 	struct kernel_lb_addr eloc;
+ 	uint32_t elen;
+ 	uint64_t lbcount = 0;
+ 	int8_t etype = -1, netype;
+-	int adsize;
+ 	struct udf_inode_info *iinfo = UDF_I(inode);
++	int bsize = 1 << inode->i_blkbits;
+ 
+ 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB ||
+-	    inode->i_size == iinfo->i_lenExtents)
++	    ALIGN(inode->i_size, bsize) == ALIGN(iinfo->i_lenExtents, bsize))
+ 		return;
+ 
+-	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
+-		adsize = sizeof(struct short_ad);
+-	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
+-		adsize = sizeof(struct long_ad);
+-	else
+-		adsize = 0;
+-
+ 	epos.block = iinfo->i_location;
+ 
+ 	/* Find the last extent in the file */
+-	while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) {
+-		etype = netype;
++	while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 0)) != -1) {
++		brelse(prev_epos.bh);
++		prev_epos = epos;
++		if (prev_epos.bh)
++			get_bh(prev_epos.bh);
++
++		etype = udf_next_aext(inode, &epos, &eloc, &elen, 1);
+ 		lbcount += elen;
+ 	}
+ 	if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
+-		epos.offset -= adsize;
+ 		lbcount -= elen;
+-		extent_trunc(inode, &epos, &eloc, etype, elen, 0);
+-		if (!epos.bh) {
+-			iinfo->i_lenAlloc =
+-				epos.offset -
+-				udf_file_entry_alloc_offset(inode);
+-			mark_inode_dirty(inode);
+-		} else {
+-			struct allocExtDesc *aed =
+-				(struct allocExtDesc *)(epos.bh->b_data);
+-			aed->lengthAllocDescs =
+-				cpu_to_le32(epos.offset -
+-					    sizeof(struct allocExtDesc));
+-			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
+-			    UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
+-				udf_update_tag(epos.bh->b_data, epos.offset);
+-			else
+-				udf_update_tag(epos.bh->b_data,
+-					       sizeof(struct allocExtDesc));
+-			mark_buffer_dirty_inode(epos.bh, inode);
+-		}
++		udf_delete_aext(inode, prev_epos);
++		udf_free_blocks(inode->i_sb, inode, &eloc, 0,
++				DIV_ROUND_UP(elen, 1 << inode->i_blkbits));
+ 	}
+ 	/* This inode entry is in-memory only and thus we don't have to mark
+ 	 * the inode dirty */
+ 	iinfo->i_lenExtents = lbcount;
+ 	brelse(epos.bh);
++	brelse(prev_epos.bh);
+ }
+ 
+ static void udf_update_alloc_ext_desc(struct inode *inode,
+diff --git a/include/linux/module.h b/include/linux/module.h
+index 518296ea7f73a..e72db35fbf759 100644
+--- a/include/linux/module.h
++++ b/include/linux/module.h
+@@ -879,8 +879,17 @@ static inline bool module_sig_ok(struct module *module)
+ }
+ #endif	/* CONFIG_MODULE_SIG */
+ 
++#if defined(CONFIG_MODULES) && defined(CONFIG_KALLSYMS)
+ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+ 					     struct module *, unsigned long),
+ 				   void *data);
++#else
++static inline int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
++						 struct module *, unsigned long),
++						 void *data)
++{
++	return -EOPNOTSUPP;
++}
++#endif  /* CONFIG_MODULES && CONFIG_KALLSYMS */
+ 
+ #endif /* _LINUX_MODULE_H */
+diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c
+index f5c5c9175333d..4523f99b03589 100644
+--- a/kernel/module/kallsyms.c
++++ b/kernel/module/kallsyms.c
+@@ -494,7 +494,6 @@ unsigned long module_kallsyms_lookup_name(const char *name)
+ 	return ret;
+ }
+ 
+-#ifdef CONFIG_LIVEPATCH
+ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+ 					     struct module *, unsigned long),
+ 				   void *data)
+@@ -531,4 +530,3 @@ out:
+ 	mutex_unlock(&module_mutex);
+ 	return ret;
+ }
+-#endif /* CONFIG_LIVEPATCH */
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index ec4b81007796c..da8e7b6951793 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -2264,6 +2264,8 @@ struct bpf_kprobe_multi_link {
+ 	unsigned long *addrs;
+ 	u64 *cookies;
+ 	u32 cnt;
++	u32 mods_cnt;
++	struct module **mods;
+ };
+ 
+ struct bpf_kprobe_multi_run_ctx {
+@@ -2319,6 +2321,14 @@ error:
+ 	return err;
+ }
+ 
++static void kprobe_multi_put_modules(struct module **mods, u32 cnt)
++{
++	u32 i;
++
++	for (i = 0; i < cnt; i++)
++		module_put(mods[i]);
++}
++
+ static void free_user_syms(struct user_syms *us)
+ {
+ 	kvfree(us->syms);
+@@ -2331,6 +2341,7 @@ static void bpf_kprobe_multi_link_release(struct bpf_link *link)
+ 
+ 	kmulti_link = container_of(link, struct bpf_kprobe_multi_link, link);
+ 	unregister_fprobe(&kmulti_link->fp);
++	kprobe_multi_put_modules(kmulti_link->mods, kmulti_link->mods_cnt);
+ }
+ 
+ static void bpf_kprobe_multi_link_dealloc(struct bpf_link *link)
+@@ -2340,6 +2351,7 @@ static void bpf_kprobe_multi_link_dealloc(struct bpf_link *link)
+ 	kmulti_link = container_of(link, struct bpf_kprobe_multi_link, link);
+ 	kvfree(kmulti_link->addrs);
+ 	kvfree(kmulti_link->cookies);
++	kfree(kmulti_link->mods);
+ 	kfree(kmulti_link);
+ }
+ 
+@@ -2362,7 +2374,7 @@ static void bpf_kprobe_multi_cookie_swap(void *a, void *b, int size, const void
+ 	swap(*cookie_a, *cookie_b);
+ }
+ 
+-static int __bpf_kprobe_multi_cookie_cmp(const void *a, const void *b)
++static int bpf_kprobe_multi_addrs_cmp(const void *a, const void *b)
+ {
+ 	const unsigned long *addr_a = a, *addr_b = b;
+ 
+@@ -2373,7 +2385,7 @@ static int __bpf_kprobe_multi_cookie_cmp(const void *a, const void *b)
+ 
+ static int bpf_kprobe_multi_cookie_cmp(const void *a, const void *b, const void *priv)
+ {
+-	return __bpf_kprobe_multi_cookie_cmp(a, b);
++	return bpf_kprobe_multi_addrs_cmp(a, b);
+ }
+ 
+ static u64 bpf_kprobe_multi_cookie(struct bpf_run_ctx *ctx)
+@@ -2391,7 +2403,7 @@ static u64 bpf_kprobe_multi_cookie(struct bpf_run_ctx *ctx)
+ 		return 0;
+ 	entry_ip = run_ctx->entry_ip;
+ 	addr = bsearch(&entry_ip, link->addrs, link->cnt, sizeof(entry_ip),
+-		       __bpf_kprobe_multi_cookie_cmp);
++		       bpf_kprobe_multi_addrs_cmp);
+ 	if (!addr)
+ 		return 0;
+ 	cookie = link->cookies + (addr - link->addrs);
+@@ -2475,6 +2487,71 @@ static void symbols_swap_r(void *a, void *b, int size, const void *priv)
+ 	}
+ }
+ 
++struct module_addr_args {
++	unsigned long *addrs;
++	u32 addrs_cnt;
++	struct module **mods;
++	int mods_cnt;
++	int mods_cap;
++};
++
++static int module_callback(void *data, const char *name,
++			   struct module *mod, unsigned long addr)
++{
++	struct module_addr_args *args = data;
++	struct module **mods;
++
++	/* We iterate all modules symbols and for each we:
++	 * - search for it in provided addresses array
++	 * - if found we check if we already have the module pointer stored
++	 *   (we iterate modules sequentially, so we can check just the last
++	 *   module pointer)
++	 * - take module reference and store it
++	 */
++	if (!bsearch(&addr, args->addrs, args->addrs_cnt, sizeof(addr),
++		       bpf_kprobe_multi_addrs_cmp))
++		return 0;
++
++	if (args->mods && args->mods[args->mods_cnt - 1] == mod)
++		return 0;
++
++	if (args->mods_cnt == args->mods_cap) {
++		args->mods_cap = max(16, args->mods_cap * 3 / 2);
++		mods = krealloc_array(args->mods, args->mods_cap, sizeof(*mods), GFP_KERNEL);
++		if (!mods)
++			return -ENOMEM;
++		args->mods = mods;
++	}
++
++	if (!try_module_get(mod))
++		return -EINVAL;
++
++	args->mods[args->mods_cnt] = mod;
++	args->mods_cnt++;
++	return 0;
++}
++
++static int get_modules_for_addrs(struct module ***mods, unsigned long *addrs, u32 addrs_cnt)
++{
++	struct module_addr_args args = {
++		.addrs     = addrs,
++		.addrs_cnt = addrs_cnt,
++	};
++	int err;
++
++	/* We return either err < 0 in case of error, ... */
++	err = module_kallsyms_on_each_symbol(module_callback, &args);
++	if (err) {
++		kprobe_multi_put_modules(args.mods, args.mods_cnt);
++		kfree(args.mods);
++		return err;
++	}
++
++	/* or number of modules found if everything is ok. */
++	*mods = args.mods;
++	return args.mods_cnt;
++}
++
+ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
+ {
+ 	struct bpf_kprobe_multi_link *link = NULL;
+@@ -2585,10 +2662,25 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
+ 		       bpf_kprobe_multi_cookie_cmp,
+ 		       bpf_kprobe_multi_cookie_swap,
+ 		       link);
++	} else {
++		/*
++		 * We need to sort addrs array even if there are no cookies
++		 * provided, to allow bsearch in get_modules_for_addrs.
++		 */
++		sort(addrs, cnt, sizeof(*addrs),
++		       bpf_kprobe_multi_addrs_cmp, NULL);
++	}
++
++	err = get_modules_for_addrs(&link->mods, addrs, cnt);
++	if (err < 0) {
++		bpf_link_cleanup(&link_primer);
++		return err;
+ 	}
++	link->mods_cnt = err;
+ 
+ 	err = register_fprobe_ips(&link->fp, addrs, cnt);
+ 	if (err) {
++		kprobe_multi_put_modules(link->mods, link->mods_cnt);
+ 		bpf_link_cleanup(&link_primer);
+ 		return err;
+ 	}
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 9e6231f4a04f7..768306ec3c941 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -8261,6 +8261,10 @@ struct kallsyms_data {
+ 	size_t found;
+ };
+ 
++/* This function gets called for all kernel and module symbols
++ * and returns 1 in case we resolved all the requested symbols,
++ * 0 otherwise.
++ */
+ static int kallsyms_callback(void *data, const char *name,
+ 			     struct module *mod, unsigned long addr)
+ {
+@@ -8304,17 +8308,19 @@ static int kallsyms_callback(void *data, const char *name,
+ int ftrace_lookup_symbols(const char **sorted_syms, size_t cnt, unsigned long *addrs)
+ {
+ 	struct kallsyms_data args;
+-	int err;
++	int found_all;
+ 
+ 	memset(addrs, 0, sizeof(*addrs) * cnt);
+ 	args.addrs = addrs;
+ 	args.syms = sorted_syms;
+ 	args.cnt = cnt;
+ 	args.found = 0;
+-	err = kallsyms_on_each_symbol(kallsyms_callback, &args);
+-	if (err < 0)
+-		return err;
+-	return args.found == args.cnt ? 0 : -ESRCH;
++
++	found_all = kallsyms_on_each_symbol(kallsyms_callback, &args);
++	if (found_all)
++		return 0;
++	found_all = module_kallsyms_on_each_symbol(kallsyms_callback, &args);
++	return found_all ? 0 : -ESRCH;
+ }
+ 
+ #ifdef CONFIG_SYSCTL
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 9c24947aa41ef..9fdede5fe71c7 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -4453,7 +4453,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
+ 
+ 	chan->ident = cmd->ident;
+ 	l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
+-	chan->num_conf_rsp++;
++	if (chan->num_conf_rsp < L2CAP_CONF_MAX_CONF_RSP)
++		chan->num_conf_rsp++;
+ 
+ 	/* Reset config buffer. */
+ 	chan->conf_len = 0;
+diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
+index e05cfc2e49aeb..1e313982af02a 100644
+--- a/security/keys/encrypted-keys/encrypted.c
++++ b/security/keys/encrypted-keys/encrypted.c
+@@ -627,7 +627,7 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
+ 			pr_err("encrypted key: instantiation of keys using provided decrypted data is disabled since CONFIG_USER_DECRYPTED_DATA is set to false\n");
+ 			return ERR_PTR(-EINVAL);
+ 		}
+-		if (strlen(decrypted_data) != decrypted_datalen) {
++		if (strlen(decrypted_data) != decrypted_datalen * 2) {
+ 			pr_err("encrypted key: decrypted data provided does not match decrypted data length provided\n");
+ 			return ERR_PTR(-EINVAL);
+ 		}
+@@ -791,8 +791,8 @@ static int encrypted_init(struct encrypted_key_payload *epayload,
+ 		ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv);
+ 	} else if (decrypted_data) {
+ 		get_random_bytes(epayload->iv, ivsize);
+-		memcpy(epayload->decrypted_data, decrypted_data,
+-				   epayload->decrypted_datalen);
++		ret = hex2bin(epayload->decrypted_data, decrypted_data,
++			      epayload->decrypted_datalen);
+ 	} else {
+ 		get_random_bytes(epayload->iv, ivsize);
+ 		get_random_bytes(epayload->decrypted_data, epayload->decrypted_datalen);
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index d8c6af9e43ad6..ce6ea8819562b 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9376,6 +9376,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	 SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
++	SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
++	SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+ 	SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
+ 	SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
+ 	SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+index 792cb15bac40f..ac5d7c1396fb4 100644
+--- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
++++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+@@ -88,6 +88,23 @@ __weak noinline struct file *bpf_testmod_return_ptr(int arg)
+ 	}
+ }
+ 
++noinline int bpf_testmod_fentry_test1(int a)
++{
++	return a + 1;
++}
++
++noinline int bpf_testmod_fentry_test2(int a, u64 b)
++{
++	return a + b;
++}
++
++noinline int bpf_testmod_fentry_test3(char a, int b, u64 c)
++{
++	return a + b + c;
++}
++
++int bpf_testmod_fentry_ok;
++
+ noinline ssize_t
+ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
+ 		      struct bin_attribute *bin_attr,
+@@ -119,6 +136,13 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
+ 			return snprintf(buf, len, "%d\n", writable.val);
+ 	}
+ 
++	if (bpf_testmod_fentry_test1(1) != 2 ||
++	    bpf_testmod_fentry_test2(2, 3) != 5 ||
++	    bpf_testmod_fentry_test3(4, 5, 6) != 15)
++		goto out;
++
++	bpf_testmod_fentry_ok = 1;
++out:
+ 	return -EIO; /* always fail */
+ }
+ EXPORT_SYMBOL(bpf_testmod_test_read);
+diff --git a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_testmod_test.c b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_testmod_test.c
+new file mode 100644
+index 0000000000000..1fbe7e4ac00ab
+--- /dev/null
++++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_testmod_test.c
+@@ -0,0 +1,89 @@
++// SPDX-License-Identifier: GPL-2.0
++#include <test_progs.h>
++#include "kprobe_multi.skel.h"
++#include "trace_helpers.h"
++#include "bpf/libbpf_internal.h"
++
++static void kprobe_multi_testmod_check(struct kprobe_multi *skel)
++{
++	ASSERT_EQ(skel->bss->kprobe_testmod_test1_result, 1, "kprobe_test1_result");
++	ASSERT_EQ(skel->bss->kprobe_testmod_test2_result, 1, "kprobe_test2_result");
++	ASSERT_EQ(skel->bss->kprobe_testmod_test3_result, 1, "kprobe_test3_result");
++
++	ASSERT_EQ(skel->bss->kretprobe_testmod_test1_result, 1, "kretprobe_test1_result");
++	ASSERT_EQ(skel->bss->kretprobe_testmod_test2_result, 1, "kretprobe_test2_result");
++	ASSERT_EQ(skel->bss->kretprobe_testmod_test3_result, 1, "kretprobe_test3_result");
++}
++
++static void test_testmod_attach_api(struct bpf_kprobe_multi_opts *opts)
++{
++	struct kprobe_multi *skel = NULL;
++
++	skel = kprobe_multi__open_and_load();
++	if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))
++		return;
++
++	skel->bss->pid = getpid();
++
++	skel->links.test_kprobe_testmod = bpf_program__attach_kprobe_multi_opts(
++						skel->progs.test_kprobe_testmod,
++						NULL, opts);
++	if (!skel->links.test_kprobe_testmod)
++		goto cleanup;
++
++	opts->retprobe = true;
++	skel->links.test_kretprobe_testmod = bpf_program__attach_kprobe_multi_opts(
++						skel->progs.test_kretprobe_testmod,
++						NULL, opts);
++	if (!skel->links.test_kretprobe_testmod)
++		goto cleanup;
++
++	ASSERT_OK(trigger_module_test_read(1), "trigger_read");
++	kprobe_multi_testmod_check(skel);
++
++cleanup:
++	kprobe_multi__destroy(skel);
++}
++
++static void test_testmod_attach_api_addrs(void)
++{
++	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
++	unsigned long long addrs[3];
++
++	addrs[0] = ksym_get_addr("bpf_testmod_fentry_test1");
++	ASSERT_NEQ(addrs[0], 0, "ksym_get_addr");
++	addrs[1] = ksym_get_addr("bpf_testmod_fentry_test2");
++	ASSERT_NEQ(addrs[1], 0, "ksym_get_addr");
++	addrs[2] = ksym_get_addr("bpf_testmod_fentry_test3");
++	ASSERT_NEQ(addrs[2], 0, "ksym_get_addr");
++
++	opts.addrs = (const unsigned long *) addrs;
++	opts.cnt = ARRAY_SIZE(addrs);
++
++	test_testmod_attach_api(&opts);
++}
++
++static void test_testmod_attach_api_syms(void)
++{
++	LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
++	const char *syms[3] = {
++		"bpf_testmod_fentry_test1",
++		"bpf_testmod_fentry_test2",
++		"bpf_testmod_fentry_test3",
++	};
++
++	opts.syms = syms;
++	opts.cnt = ARRAY_SIZE(syms);
++	test_testmod_attach_api(&opts);
++}
++
++void serial_test_kprobe_multi_testmod_test(void)
++{
++	if (!ASSERT_OK(load_kallsyms_refresh(), "load_kallsyms_refresh"))
++		return;
++
++	if (test__start_subtest("testmod_attach_api_syms"))
++		test_testmod_attach_api_syms();
++	if (test__start_subtest("testmod_attach_api_addrs"))
++		test_testmod_attach_api_addrs();
++}
+diff --git a/tools/testing/selftests/bpf/prog_tests/module_attach.c b/tools/testing/selftests/bpf/prog_tests/module_attach.c
+index 6d0e50dcf47cc..7fc01ff490db7 100644
+--- a/tools/testing/selftests/bpf/prog_tests/module_attach.c
++++ b/tools/testing/selftests/bpf/prog_tests/module_attach.c
+@@ -103,6 +103,13 @@ void test_module_attach(void)
+ 	ASSERT_ERR(delete_module("bpf_testmod", 0), "delete_module");
+ 	bpf_link__destroy(link);
+ 
++	link = bpf_program__attach(skel->progs.kprobe_multi);
++	if (!ASSERT_OK_PTR(link, "attach_kprobe_multi"))
++		goto cleanup;
++
++	ASSERT_ERR(delete_module("bpf_testmod", 0), "delete_module");
++	bpf_link__destroy(link);
++
+ cleanup:
+ 	test_module_attach__destroy(skel);
+ }
+diff --git a/tools/testing/selftests/bpf/progs/kprobe_multi.c b/tools/testing/selftests/bpf/progs/kprobe_multi.c
+index 98c3399e15c03..9e1ca8e34913c 100644
+--- a/tools/testing/selftests/bpf/progs/kprobe_multi.c
++++ b/tools/testing/selftests/bpf/progs/kprobe_multi.c
+@@ -110,3 +110,53 @@ int test_kretprobe_manual(struct pt_regs *ctx)
+ 	kprobe_multi_check(ctx, true);
+ 	return 0;
+ }
++
++extern const void bpf_testmod_fentry_test1 __ksym;
++extern const void bpf_testmod_fentry_test2 __ksym;
++extern const void bpf_testmod_fentry_test3 __ksym;
++
++__u64 kprobe_testmod_test1_result = 0;
++__u64 kprobe_testmod_test2_result = 0;
++__u64 kprobe_testmod_test3_result = 0;
++
++__u64 kretprobe_testmod_test1_result = 0;
++__u64 kretprobe_testmod_test2_result = 0;
++__u64 kretprobe_testmod_test3_result = 0;
++
++static void kprobe_multi_testmod_check(void *ctx, bool is_return)
++{
++	if (bpf_get_current_pid_tgid() >> 32 != pid)
++		return;
++
++	__u64 addr = bpf_get_func_ip(ctx);
++
++	if (is_return) {
++		if ((const void *) addr == &bpf_testmod_fentry_test1)
++			kretprobe_testmod_test1_result = 1;
++		if ((const void *) addr == &bpf_testmod_fentry_test2)
++			kretprobe_testmod_test2_result = 1;
++		if ((const void *) addr == &bpf_testmod_fentry_test3)
++			kretprobe_testmod_test3_result = 1;
++	} else {
++		if ((const void *) addr == &bpf_testmod_fentry_test1)
++			kprobe_testmod_test1_result = 1;
++		if ((const void *) addr == &bpf_testmod_fentry_test2)
++			kprobe_testmod_test2_result = 1;
++		if ((const void *) addr == &bpf_testmod_fentry_test3)
++			kprobe_testmod_test3_result = 1;
++	}
++}
++
++SEC("kprobe.multi")
++int test_kprobe_testmod(struct pt_regs *ctx)
++{
++	kprobe_multi_testmod_check(ctx, false);
++	return 0;
++}
++
++SEC("kretprobe.multi")
++int test_kretprobe_testmod(struct pt_regs *ctx)
++{
++	kprobe_multi_testmod_check(ctx, true);
++	return 0;
++}
+diff --git a/tools/testing/selftests/bpf/progs/test_module_attach.c b/tools/testing/selftests/bpf/progs/test_module_attach.c
+index 08628afedb779..8a1b50f3a002d 100644
+--- a/tools/testing/selftests/bpf/progs/test_module_attach.c
++++ b/tools/testing/selftests/bpf/progs/test_module_attach.c
+@@ -110,4 +110,10 @@ int BPF_PROG(handle_fmod_ret,
+ 	return 0; /* don't override the exit code */
+ }
+ 
++SEC("kprobe.multi/bpf_testmod_test_read")
++int BPF_PROG(kprobe_multi)
++{
++	return 0;
++}
++
+ char _license[] SEC("license") = "GPL";
+diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
+index 9c4be2cdb21a0..09a16a77bae4b 100644
+--- a/tools/testing/selftests/bpf/trace_helpers.c
++++ b/tools/testing/selftests/bpf/trace_helpers.c
+@@ -23,7 +23,7 @@ static int ksym_cmp(const void *p1, const void *p2)
+ 	return ((struct ksym *)p1)->addr - ((struct ksym *)p2)->addr;
+ }
+ 
+-int load_kallsyms(void)
++int load_kallsyms_refresh(void)
+ {
+ 	FILE *f;
+ 	char func[256], buf[256];
+@@ -31,12 +31,7 @@ int load_kallsyms(void)
+ 	void *addr;
+ 	int i = 0;
+ 
+-	/*
+-	 * This is called/used from multiplace places,
+-	 * load symbols just once.
+-	 */
+-	if (sym_cnt)
+-		return 0;
++	sym_cnt = 0;
+ 
+ 	f = fopen("/proc/kallsyms", "r");
+ 	if (!f)
+@@ -57,6 +52,17 @@ int load_kallsyms(void)
+ 	return 0;
+ }
+ 
++int load_kallsyms(void)
++{
++	/*
++	 * This is called/used from multiplace places,
++	 * load symbols just once.
++	 */
++	if (sym_cnt)
++		return 0;
++	return load_kallsyms_refresh();
++}
++
+ struct ksym *ksym_search(long key)
+ {
+ 	int start = 0, end = sym_cnt;
+diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h
+index 238a9c98cde27..53efde0e2998e 100644
+--- a/tools/testing/selftests/bpf/trace_helpers.h
++++ b/tools/testing/selftests/bpf/trace_helpers.h
+@@ -10,6 +10,8 @@ struct ksym {
+ };
+ 
+ int load_kallsyms(void);
++int load_kallsyms_refresh(void);
++
+ struct ksym *ksym_search(long key);
+ long ksym_get_addr(const char *name);
+ 
+diff --git a/tools/testing/selftests/net/toeplitz.sh b/tools/testing/selftests/net/toeplitz.sh
+index 0a49907cd4fef..da5bfd834effe 100755
+--- a/tools/testing/selftests/net/toeplitz.sh
++++ b/tools/testing/selftests/net/toeplitz.sh
+@@ -32,7 +32,7 @@ DEV="eth0"
+ # This is determined by reading the RSS indirection table using ethtool.
+ get_rss_cfg_num_rxqs() {
+ 	echo $(ethtool -x "${DEV}" |
+-		egrep [[:space:]]+[0-9]+:[[:space:]]+ |
++		grep -E [[:space:]]+[0-9]+:[[:space:]]+ |
+ 		cut -d: -f2- |
+ 		awk '{$1=$1};1' |
+ 		tr ' ' '\n' |


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-19 12:23 Alice Ferrazzi
  0 siblings, 0 replies; 27+ messages in thread
From: Alice Ferrazzi @ 2022-12-19 12:23 UTC (permalink / raw
  To: gentoo-commits

commit:     a8d06a5181b19f2342dcd759b90907c15ac15b3d
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Mon Dec 19 12:17:11 2022 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Mon Dec 19 12:18:23 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=a8d06a51

Linux patch 6.0.14

Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org>

 0000_README             |   4 +
 1013_linux-6.0.14.patch | 421 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 425 insertions(+)

diff --git a/0000_README b/0000_README
index 78a95ddc..578f9e3d 100644
--- a/0000_README
+++ b/0000_README
@@ -95,6 +95,10 @@ Patch:  1012_linux-6.0.13.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.13
 
+Patch:  1013_linux-6.0.14.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.14
+
 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/1013_linux-6.0.14.patch b/1013_linux-6.0.14.patch
new file mode 100644
index 00000000..89b4e23c
--- /dev/null
+++ b/1013_linux-6.0.14.patch
@@ -0,0 +1,421 @@
+diff --git a/Makefile b/Makefile
+index bf00f3240b3a3..a3c02b45fb575 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 13
++SUBLEVEL = 14
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/x86/entry/vdso/vdso.lds.S b/arch/x86/entry/vdso/vdso.lds.S
+index 4bf48462fca7a..e8c60ae7a7c83 100644
+--- a/arch/x86/entry/vdso/vdso.lds.S
++++ b/arch/x86/entry/vdso/vdso.lds.S
+@@ -27,7 +27,9 @@ VERSION {
+ 		__vdso_time;
+ 		clock_getres;
+ 		__vdso_clock_getres;
++#ifdef CONFIG_X86_SGX
+ 		__vdso_sgx_enter_enclave;
++#endif
+ 	local: *;
+ 	};
+ }
+diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
+index 218b098b261df..47619e9cb0055 100644
+--- a/drivers/net/can/usb/mcba_usb.c
++++ b/drivers/net/can/usb/mcba_usb.c
+@@ -47,6 +47,10 @@
+ #define MCBA_VER_REQ_USB 1
+ #define MCBA_VER_REQ_CAN 2
+ 
++/* Drive the CAN_RES signal LOW "0" to activate R24 and R25 */
++#define MCBA_VER_TERMINATION_ON 0
++#define MCBA_VER_TERMINATION_OFF 1
++
+ #define MCBA_SIDL_EXID_MASK 0x8
+ #define MCBA_DLC_MASK 0xf
+ #define MCBA_DLC_RTR_MASK 0x40
+@@ -463,7 +467,7 @@ static void mcba_usb_process_ka_usb(struct mcba_priv *priv,
+ 		priv->usb_ka_first_pass = false;
+ 	}
+ 
+-	if (msg->termination_state)
++	if (msg->termination_state == MCBA_VER_TERMINATION_ON)
+ 		priv->can.termination = MCBA_TERMINATION_ENABLED;
+ 	else
+ 		priv->can.termination = MCBA_TERMINATION_DISABLED;
+@@ -785,9 +789,9 @@ static int mcba_set_termination(struct net_device *netdev, u16 term)
+ 	};
+ 
+ 	if (term == MCBA_TERMINATION_ENABLED)
+-		usb_msg.termination = 1;
++		usb_msg.termination = MCBA_VER_TERMINATION_ON;
+ 	else
+-		usb_msg.termination = 0;
++		usb_msg.termination = MCBA_VER_TERMINATION_OFF;
+ 
+ 	mcba_usb_xmit_cmd(priv, (struct mcba_usb_msg *)&usb_msg);
+ 
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index 5aa254eaa8d02..5945632ded2d6 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -72,7 +72,7 @@
+ #include "fec.h"
+ 
+ static void set_multicast_list(struct net_device *ndev);
+-static void fec_enet_itr_coal_init(struct net_device *ndev);
++static void fec_enet_itr_coal_set(struct net_device *ndev);
+ 
+ #define DRIVER_NAME	"fec"
+ 
+@@ -1164,8 +1164,8 @@ fec_restart(struct net_device *ndev)
+ 		writel(0, fep->hwp + FEC_IMASK);
+ 
+ 	/* Init the interrupt coalescing */
+-	fec_enet_itr_coal_init(ndev);
+-
++	if (fep->quirks & FEC_QUIRK_HAS_COALESCE)
++		fec_enet_itr_coal_set(ndev);
+ }
+ 
+ static void fec_enet_stop_mode(struct fec_enet_private *fep, bool enabled)
+@@ -2771,19 +2771,6 @@ static int fec_enet_set_coalesce(struct net_device *ndev,
+ 	return 0;
+ }
+ 
+-static void fec_enet_itr_coal_init(struct net_device *ndev)
+-{
+-	struct ethtool_coalesce ec;
+-
+-	ec.rx_coalesce_usecs = FEC_ITR_ICTT_DEFAULT;
+-	ec.rx_max_coalesced_frames = FEC_ITR_ICFT_DEFAULT;
+-
+-	ec.tx_coalesce_usecs = FEC_ITR_ICTT_DEFAULT;
+-	ec.tx_max_coalesced_frames = FEC_ITR_ICFT_DEFAULT;
+-
+-	fec_enet_set_coalesce(ndev, &ec, NULL, NULL);
+-}
+-
+ static int fec_enet_get_tunable(struct net_device *netdev,
+ 				const struct ethtool_tunable *tuna,
+ 				void *data)
+@@ -3538,6 +3525,10 @@ static int fec_enet_init(struct net_device *ndev)
+ 	fep->rx_align = 0x3;
+ 	fep->tx_align = 0x3;
+ #endif
++	fep->rx_pkts_itr = FEC_ITR_ICFT_DEFAULT;
++	fep->tx_pkts_itr = FEC_ITR_ICFT_DEFAULT;
++	fep->rx_time_itr = FEC_ITR_ICTT_DEFAULT;
++	fep->tx_time_itr = FEC_ITR_ICTT_DEFAULT;
+ 
+ 	/* Check mask of the streaming and coherent API */
+ 	ret = dma_set_mask_and_coherent(&fep->pdev->dev, DMA_BIT_MASK(32));
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 0f34114c4596d..6867620bcc986 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -804,6 +804,8 @@ static blk_status_t nvme_setup_prp_simple(struct nvme_dev *dev,
+ 	cmnd->dptr.prp1 = cpu_to_le64(iod->first_dma);
+ 	if (bv->bv_len > first_prp_len)
+ 		cmnd->dptr.prp2 = cpu_to_le64(iod->first_dma + first_prp_len);
++	else
++		cmnd->dptr.prp2 = 0;
+ 	return BLK_STS_OK;
+ }
+ 
+diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
+index f7b54a5517641..c24583bffa99d 100644
+--- a/drivers/pinctrl/mediatek/mtk-eint.c
++++ b/drivers/pinctrl/mediatek/mtk-eint.c
+@@ -287,12 +287,15 @@ static struct irq_chip mtk_eint_irq_chip = {
+ 
+ static unsigned int mtk_eint_hw_init(struct mtk_eint *eint)
+ {
+-	void __iomem *reg = eint->base + eint->regs->dom_en;
++	void __iomem *dom_en = eint->base + eint->regs->dom_en;
++	void __iomem *mask_set = eint->base + eint->regs->mask_set;
+ 	unsigned int i;
+ 
+ 	for (i = 0; i < eint->hw->ap_num; i += 32) {
+-		writel(0xffffffff, reg);
+-		reg += 4;
++		writel(0xffffffff, dom_en);
++		writel(0xffffffff, mask_set);
++		dom_en += 4;
++		mask_set += 4;
+ 	}
+ 
+ 	return 0;
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
+index bdb1df843c78d..58cc2bae2f8a0 100644
+--- a/drivers/rtc/rtc-cmos.c
++++ b/drivers/rtc/rtc-cmos.c
+@@ -1233,6 +1233,9 @@ static u32 rtc_handler(void *context)
+ 
+ static inline void rtc_wake_setup(struct device *dev)
+ {
++	if (acpi_disabled)
++		return;
++
+ 	acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, dev);
+ 	/*
+ 	 * After the RTC handler is installed, the Fixed_RTC event should
+@@ -1286,7 +1289,6 @@ static void cmos_wake_setup(struct device *dev)
+ 
+ 	use_acpi_alarm_quirks();
+ 
+-	rtc_wake_setup(dev);
+ 	acpi_rtc_info.wake_on = rtc_wake_on;
+ 	acpi_rtc_info.wake_off = rtc_wake_off;
+ 
+@@ -1344,6 +1346,9 @@ static void cmos_check_acpi_rtc_status(struct device *dev,
+ {
+ }
+ 
++static void rtc_wake_setup(struct device *dev)
++{
++}
+ #endif
+ 
+ #ifdef	CONFIG_PNP
+@@ -1352,10 +1357,12 @@ static void cmos_check_acpi_rtc_status(struct device *dev,
+ 
+ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+ {
++	int irq, ret;
++
+ 	cmos_wake_setup(&pnp->dev);
+ 
+ 	if (pnp_port_start(pnp, 0) == 0x70 && !pnp_irq_valid(pnp, 0)) {
+-		unsigned int irq = 0;
++		irq = 0;
+ #ifdef CONFIG_X86
+ 		/* Some machines contain a PNP entry for the RTC, but
+ 		 * don't define the IRQ. It should always be safe to
+@@ -1364,13 +1371,17 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+ 		if (nr_legacy_irqs())
+ 			irq = RTC_IRQ;
+ #endif
+-		return cmos_do_probe(&pnp->dev,
+-				pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
+ 	} else {
+-		return cmos_do_probe(&pnp->dev,
+-				pnp_get_resource(pnp, IORESOURCE_IO, 0),
+-				pnp_irq(pnp, 0));
++		irq = pnp_irq(pnp, 0);
+ 	}
++
++	ret = cmos_do_probe(&pnp->dev, pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
++	if (ret)
++		return ret;
++
++	rtc_wake_setup(&pnp->dev);
++
++	return 0;
+ }
+ 
+ static void cmos_pnp_remove(struct pnp_dev *pnp)
+@@ -1454,7 +1465,7 @@ static inline void cmos_of_init(struct platform_device *pdev) {}
+ static int __init cmos_platform_probe(struct platform_device *pdev)
+ {
+ 	struct resource *resource;
+-	int irq;
++	int irq, ret;
+ 
+ 	cmos_of_init(pdev);
+ 	cmos_wake_setup(&pdev->dev);
+@@ -1467,7 +1478,13 @@ static int __init cmos_platform_probe(struct platform_device *pdev)
+ 	if (irq < 0)
+ 		irq = -1;
+ 
+-	return cmos_do_probe(&pdev->dev, resource, irq);
++	ret = cmos_do_probe(&pdev->dev, resource, irq);
++	if (ret)
++		return ret;
++
++	rtc_wake_setup(&pdev->dev);
++
++	return 0;
+ }
+ 
+ static int cmos_platform_remove(struct platform_device *pdev)
+diff --git a/include/linux/can/platform/sja1000.h b/include/linux/can/platform/sja1000.h
+index 5755ae5a47122..6a869682c1207 100644
+--- a/include/linux/can/platform/sja1000.h
++++ b/include/linux/can/platform/sja1000.h
+@@ -14,7 +14,7 @@
+ #define OCR_MODE_TEST     0x01
+ #define OCR_MODE_NORMAL   0x02
+ #define OCR_MODE_CLOCK    0x03
+-#define OCR_MODE_MASK     0x07
++#define OCR_MODE_MASK     0x03
+ #define OCR_TX0_INVERT    0x04
+ #define OCR_TX0_PULLDOWN  0x08
+ #define OCR_TX0_PULLUP    0x10
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 8dcbefd90b7f6..91473e9f88cd9 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -2283,6 +2283,7 @@ event_sched_out(struct perf_event *event,
+ 		    !event->pending_work) {
+ 			event->pending_work = 1;
+ 			dec = false;
++			WARN_ON_ONCE(!atomic_long_inc_not_zero(&event->refcount));
+ 			task_work_add(current, &event->pending_task, TWA_RESUME);
+ 		}
+ 		if (dec)
+@@ -2328,6 +2329,7 @@ group_sched_out(struct perf_event *group_event,
+ 
+ #define DETACH_GROUP	0x01UL
+ #define DETACH_CHILD	0x02UL
++#define DETACH_DEAD	0x04UL
+ 
+ /*
+  * Cross CPU call to remove a performance event
+@@ -2348,12 +2350,20 @@ __perf_remove_from_context(struct perf_event *event,
+ 		update_cgrp_time_from_cpuctx(cpuctx, false);
+ 	}
+ 
++	/*
++	 * Ensure event_sched_out() switches to OFF, at the very least
++	 * this avoids raising perf_pending_task() at this time.
++	 */
++	if (flags & DETACH_DEAD)
++		event->pending_disable = 1;
+ 	event_sched_out(event, cpuctx, ctx);
+ 	if (flags & DETACH_GROUP)
+ 		perf_group_detach(event);
+ 	if (flags & DETACH_CHILD)
+ 		perf_child_detach(event);
+ 	list_del_event(event, ctx);
++	if (flags & DETACH_DEAD)
++		event->state = PERF_EVENT_STATE_DEAD;
+ 
+ 	if (!ctx->nr_events && ctx->is_active) {
+ 		if (ctx == &cpuctx->ctx)
+@@ -5113,9 +5123,7 @@ int perf_event_release_kernel(struct perf_event *event)
+ 
+ 	ctx = perf_event_ctx_lock(event);
+ 	WARN_ON_ONCE(ctx->parent_ctx);
+-	perf_remove_from_context(event, DETACH_GROUP);
+ 
+-	raw_spin_lock_irq(&ctx->lock);
+ 	/*
+ 	 * Mark this event as STATE_DEAD, there is no external reference to it
+ 	 * anymore.
+@@ -5127,8 +5135,7 @@ int perf_event_release_kernel(struct perf_event *event)
+ 	 * Thus this guarantees that we will in fact observe and kill _ALL_
+ 	 * child events.
+ 	 */
+-	event->state = PERF_EVENT_STATE_DEAD;
+-	raw_spin_unlock_irq(&ctx->lock);
++	perf_remove_from_context(event, DETACH_GROUP|DETACH_DEAD);
+ 
+ 	perf_event_ctx_unlock(event, ctx);
+ 
+@@ -6569,6 +6576,8 @@ static void perf_pending_task(struct callback_head *head)
+ 	if (rctx >= 0)
+ 		perf_swevent_put_recursion_context(rctx);
+ 	preempt_enable_notrace();
++
++	put_event(event);
+ }
+ 
+ #ifdef CONFIG_GUEST_PERF_EVENTS
+diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
+index 51721edd8f53c..e88d9ff95cdfc 100644
+--- a/sound/soc/codecs/cs42l51.c
++++ b/sound/soc/codecs/cs42l51.c
+@@ -143,7 +143,7 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
+ 			0, 0xA0, 96, adc_att_tlv),
+ 	SOC_DOUBLE_R_SX_TLV("PGA Volume",
+ 			CS42L51_ALC_PGA_CTL, CS42L51_ALC_PGB_CTL,
+-			0, 0x19, 30, pga_tlv),
++			0, 0x1A, 30, pga_tlv),
+ 	SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
+ 	SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0),
+ 	SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0),
+diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
+index 79ef4e269bc95..4b86ef82fd930 100644
+--- a/sound/soc/fsl/fsl_micfil.c
++++ b/sound/soc/fsl/fsl_micfil.c
+@@ -194,6 +194,25 @@ static int fsl_micfil_reset(struct device *dev)
+ 	if (ret)
+ 		return ret;
+ 
++	/*
++	 * SRES is self-cleared bit, but REG_MICFIL_CTRL1 is defined
++	 * as non-volatile register, so SRES still remain in regmap
++	 * cache after set, that every update of REG_MICFIL_CTRL1,
++	 * software reset happens. so clear it explicitly.
++	 */
++	ret = regmap_clear_bits(micfil->regmap, REG_MICFIL_CTRL1,
++				MICFIL_CTRL1_SRES);
++	if (ret)
++		return ret;
++
++	/*
++	 * Set SRES should clear CHnF flags, But even add delay here
++	 * the CHnF may not be cleared sometimes, so clear CHnF explicitly.
++	 */
++	ret = regmap_write_bits(micfil->regmap, REG_MICFIL_STAT, 0xFF, 0xFF);
++	if (ret)
++		return ret;
++
+ 	return 0;
+ }
+ 
+diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
+index 47691119306fb..55b009d3c6815 100644
+--- a/sound/soc/soc-ops.c
++++ b/sound/soc/soc-ops.c
+@@ -464,10 +464,15 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
+ 	ret = err;
+ 
+ 	if (snd_soc_volsw_is_stereo(mc)) {
+-		unsigned int val2;
++		unsigned int val2 = ucontrol->value.integer.value[1];
++
++		if (mc->platform_max && val2 > mc->platform_max)
++			return -EINVAL;
++		if (val2 > max)
++			return -EINVAL;
+ 
+ 		val_mask = mask << rshift;
+-		val2 = (ucontrol->value.integer.value[1] + min) & mask;
++		val2 = (val2 + min) & mask;
+ 		val2 = val2 << rshift;
+ 
+ 		err = snd_soc_component_update_bits(component, reg2, val_mask,
+diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
+index 4221f73a74d01..3937f66c7f8d6 100644
+--- a/tools/lib/bpf/btf_dump.c
++++ b/tools/lib/bpf/btf_dump.c
+@@ -1963,7 +1963,7 @@ static int btf_dump_struct_data(struct btf_dump *d,
+ {
+ 	const struct btf_member *m = btf_members(t);
+ 	__u16 n = btf_vlen(t);
+-	int i, err;
++	int i, err = 0;
+ 
+ 	/* note that we increment depth before calling btf_dump_print() below;
+ 	 * this is intentional.  btf_dump_data_newline() will not print a
+diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
+index 6d495656f554c..29f7cde107418 100644
+--- a/tools/lib/bpf/libbpf_probes.c
++++ b/tools/lib/bpf/libbpf_probes.c
+@@ -233,7 +233,7 @@ static int probe_map_create(enum bpf_map_type map_type)
+ 	case BPF_MAP_TYPE_RINGBUF:
+ 		key_size = 0;
+ 		value_size = 0;
+-		max_entries = 4096;
++		max_entries = sysconf(_SC_PAGE_SIZE);
+ 		break;
+ 	case BPF_MAP_TYPE_STRUCT_OPS:
+ 		/* we'll get -ENOTSUPP for invalid BTF type ID for struct_ops */


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-14 12:51 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-14 12:51 UTC (permalink / raw
  To: gentoo-commits

commit:     f112e38167272c5ea2abb110c2151fa0c9f8ddbd
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 14 12:51:13 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Dec 14 12:51:13 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=f112e381

Remove redundant patch

Removed:
2010_netfilter-ctnetlink-compilation-fix.patch

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

 0000_README                                    |  4 --
 2010_netfilter-ctnetlink-compilation-fix.patch | 90 --------------------------
 2 files changed, 94 deletions(-)

diff --git a/0000_README b/0000_README
index a5d5308b..78a95ddc 100644
--- a/0000_README
+++ b/0000_README
@@ -111,10 +111,6 @@ Patch:  2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
 From:   https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw
 Desc:   Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758
 
-Patch:  2010_netfilter-ctnetlink-compilation-fix.patch
-From:   https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git
-Desc:   netfilter: ctnetlink: fix compilation warning after data race fixes in ct mark
-
 Patch:  2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
 From:   https://bugs.gentoo.org/710790
 Desc:   tmp513 requies REGMAP_I2C to build.  Select it by default in Kconfig. See bug #710790. Thanks to Phil Stracchino

diff --git a/2010_netfilter-ctnetlink-compilation-fix.patch b/2010_netfilter-ctnetlink-compilation-fix.patch
deleted file mode 100644
index b7bd4dee..00000000
--- a/2010_netfilter-ctnetlink-compilation-fix.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 1feeae071507ad65cf9f462a1bdd543a4bf89e71 Mon Sep 17 00:00:00 2001
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-Date: Mon, 28 Nov 2022 10:58:53 +0100
-Subject: netfilter: ctnetlink: fix compilation warning after data race fixes
- in ct mark
-
-All warnings (new ones prefixed by >>):
-
-   net/netfilter/nf_conntrack_netlink.c: In function '__ctnetlink_glue_build':
->> net/netfilter/nf_conntrack_netlink.c:2674:13: warning: unused variable 'mark' [-Wunused-variable]
-    2674 |         u32 mark;
-         |             ^~~~
-
-Fixes: 52d1aa8b8249 ("netfilter: conntrack: Fix data-races around ct mark")
-Reported-by: kernel test robot <lkp@intel.com>
-Tested-by: Ivan Babrou <ivan@ivan.computer>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
----
- net/netfilter/nf_conntrack_netlink.c | 19 ++++++++++---------
- 1 file changed, 10 insertions(+), 9 deletions(-)
-
-diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
-index d71150a40fb08..1286ae7d46096 100644
---- a/net/netfilter/nf_conntrack_netlink.c
-+++ b/net/netfilter/nf_conntrack_netlink.c
-@@ -328,8 +328,13 @@ nla_put_failure:
- }
- 
- #ifdef CONFIG_NF_CONNTRACK_MARK
--static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark)
-+static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
- {
-+	u32 mark = READ_ONCE(ct->mark);
-+
-+	if (!mark)
-+		return 0;
-+
- 	if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
- 		goto nla_put_failure;
- 	return 0;
-@@ -543,7 +548,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
- static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
- {
- 	if (ctnetlink_dump_status(skb, ct) < 0 ||
--	    ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 ||
-+	    ctnetlink_dump_mark(skb, ct) < 0 ||
- 	    ctnetlink_dump_secctx(skb, ct) < 0 ||
- 	    ctnetlink_dump_id(skb, ct) < 0 ||
- 	    ctnetlink_dump_use(skb, ct) < 0 ||
-@@ -722,7 +727,6 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
- 	struct sk_buff *skb;
- 	unsigned int type;
- 	unsigned int flags = 0, group;
--	u32 mark;
- 	int err;
- 
- 	if (events & (1 << IPCT_DESTROY)) {
-@@ -827,9 +831,8 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
- 	}
- 
- #ifdef CONFIG_NF_CONNTRACK_MARK
--	mark = READ_ONCE(ct->mark);
--	if ((events & (1 << IPCT_MARK) || mark) &&
--	    ctnetlink_dump_mark(skb, mark) < 0)
-+	if (events & (1 << IPCT_MARK) &&
-+	    ctnetlink_dump_mark(skb, ct) < 0)
- 		goto nla_put_failure;
- #endif
- 	nlmsg_end(skb, nlh);
-@@ -2671,7 +2674,6 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
- {
- 	const struct nf_conntrack_zone *zone;
- 	struct nlattr *nest_parms;
--	u32 mark;
- 
- 	zone = nf_ct_zone(ct);
- 
-@@ -2733,8 +2735,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
- 		goto nla_put_failure;
- 
- #ifdef CONFIG_NF_CONNTRACK_MARK
--	mark = READ_ONCE(ct->mark);
--	if (mark && ctnetlink_dump_mark(skb, mark) < 0)
-+	if (ctnetlink_dump_mark(skb, ct) < 0)
- 		goto nla_put_failure;
- #endif
- 	if (ctnetlink_dump_labels(skb, ct) < 0)
--- 
-cgit 
-


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-14 12:13 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-14 12:13 UTC (permalink / raw
  To: gentoo-commits

commit:     458c78b0fda8c58e1930d06f4e7b5747ee0e7284
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 14 12:12:56 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Dec 14 12:12:56 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=458c78b0

Linux patch 6.0.13

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

 0000_README             |    4 +
 1012_linux-6.0.13.patch | 5882 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 5886 insertions(+)

diff --git a/0000_README b/0000_README
index 37d6ef5a..a5d5308b 100644
--- a/0000_README
+++ b/0000_README
@@ -91,6 +91,10 @@ Patch:  1011_linux-6.0.12.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.12
 
+Patch:  1012_linux-6.0.13.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.13
+
 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/1012_linux-6.0.13.patch b/1012_linux-6.0.13.patch
new file mode 100644
index 00000000..d636e963
--- /dev/null
+++ b/1012_linux-6.0.13.patch
@@ -0,0 +1,5882 @@
+diff --git a/.clang-format b/.clang-format
+index 1247d54f9e49f..8d01225bfcb7d 100644
+--- a/.clang-format
++++ b/.clang-format
+@@ -535,6 +535,7 @@ ForEachMacros:
+   - 'perf_hpp_list__for_each_sort_list_safe'
+   - 'perf_pmu__for_each_hybrid_pmu'
+   - 'ping_portaddr_for_each_entry'
++  - 'ping_portaddr_for_each_entry_rcu'
+   - 'plist_for_each'
+   - 'plist_for_each_continue'
+   - 'plist_for_each_entry'
+diff --git a/Makefile b/Makefile
+index 46c6eb57b354d..bf00f3240b3a3 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 12
++SUBLEVEL = 13
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
+index 1dc3bfac30b68..29148285f9fc8 100644
+--- a/arch/arm/boot/dts/imx7s.dtsi
++++ b/arch/arm/boot/dts/imx7s.dtsi
+@@ -1270,10 +1270,10 @@
+ 			clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>;
+ 		};
+ 
+-		gpmi: nand-controller@33002000 {
++		gpmi: nand-controller@33002000{
+ 			compatible = "fsl,imx7d-gpmi-nand";
+ 			#address-cells = <1>;
+-			#size-cells = <0>;
++			#size-cells = <1>;
+ 			reg = <0x33002000 0x2000>, <0x33004000 0x4000>;
+ 			reg-names = "gpmi-nand", "bch";
+ 			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+diff --git a/arch/arm/boot/dts/rk3036-evb.dts b/arch/arm/boot/dts/rk3036-evb.dts
+index 2a7e6624efb93..94216f870b57c 100644
+--- a/arch/arm/boot/dts/rk3036-evb.dts
++++ b/arch/arm/boot/dts/rk3036-evb.dts
+@@ -31,11 +31,10 @@
+ &i2c1 {
+ 	status = "okay";
+ 
+-	hym8563: hym8563@51 {
++	hym8563: rtc@51 {
+ 		compatible = "haoyu,hym8563";
+ 		reg = <0x51>;
+ 		#clock-cells = <0>;
+-		clock-frequency = <32768>;
+ 		clock-output-names = "xin32k";
+ 	};
+ };
+diff --git a/arch/arm/boot/dts/rk3066a-mk808.dts b/arch/arm/boot/dts/rk3066a-mk808.dts
+index cfa318a506eb0..2db5ba7062086 100644
+--- a/arch/arm/boot/dts/rk3066a-mk808.dts
++++ b/arch/arm/boot/dts/rk3066a-mk808.dts
+@@ -32,7 +32,7 @@
+ 		keyup-threshold-microvolt = <2500000>;
+ 		poll-interval = <100>;
+ 
+-		recovery {
++		button-recovery {
+ 			label = "recovery";
+ 			linux,code = <KEY_VENDOR>;
+ 			press-threshold-microvolt = <0>;
+diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts
+index a9ed3cd2c2da6..239d2ec37fdc4 100644
+--- a/arch/arm/boot/dts/rk3188-radxarock.dts
++++ b/arch/arm/boot/dts/rk3188-radxarock.dts
+@@ -71,7 +71,7 @@
+ 		#sound-dai-cells = <0>;
+ 	};
+ 
+-	ir_recv: gpio-ir-receiver {
++	ir_recv: ir-receiver {
+ 		compatible = "gpio-ir-receiver";
+ 		gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
+ 		pinctrl-names = "default";
+diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
+index cdd4a0bd5133d..44b54af0bbf9f 100644
+--- a/arch/arm/boot/dts/rk3188.dtsi
++++ b/arch/arm/boot/dts/rk3188.dtsi
+@@ -379,7 +379,7 @@
+ 				rockchip,pins = <2 RK_PD3 1 &pcfg_pull_none>;
+ 			};
+ 
+-			lcdc1_rgb24: ldcd1-rgb24 {
++			lcdc1_rgb24: lcdc1-rgb24 {
+ 				rockchip,pins = <2 RK_PA0 1 &pcfg_pull_none>,
+ 						<2 RK_PA1 1 &pcfg_pull_none>,
+ 						<2 RK_PA2 1 &pcfg_pull_none>,
+@@ -607,7 +607,6 @@
+ 
+ &global_timer {
+ 	interrupts = <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>;
+-	status = "disabled";
+ };
+ 
+ &local_timer {
+diff --git a/arch/arm/boot/dts/rk3288-evb-act8846.dts b/arch/arm/boot/dts/rk3288-evb-act8846.dts
+index be695b8c1f672..8a635c2431274 100644
+--- a/arch/arm/boot/dts/rk3288-evb-act8846.dts
++++ b/arch/arm/boot/dts/rk3288-evb-act8846.dts
+@@ -54,7 +54,7 @@
+ 		vin-supply = <&vcc_sys>;
+ 	};
+ 
+-	hym8563@51 {
++	rtc@51 {
+ 		compatible = "haoyu,hym8563";
+ 		reg = <0x51>;
+ 
+diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi
+index 399d6b9c5fd4b..382d2839cf472 100644
+--- a/arch/arm/boot/dts/rk3288-evb.dtsi
++++ b/arch/arm/boot/dts/rk3288-evb.dtsi
+@@ -28,19 +28,19 @@
+ 			press-threshold-microvolt = <300000>;
+ 		};
+ 
+-		menu {
++		button-menu {
+ 			label = "Menu";
+ 			linux,code = <KEY_MENU>;
+ 			press-threshold-microvolt = <640000>;
+ 		};
+ 
+-		esc {
++		button-esc {
+ 			label = "Esc";
+ 			linux,code = <KEY_ESC>;
+ 			press-threshold-microvolt = <1000000>;
+ 		};
+ 
+-		home  {
++		button-home  {
+ 			label = "Home";
+ 			linux,code = <KEY_HOME>;
+ 			press-threshold-microvolt = <1300000>;
+diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi
+index 052afe5543e2a..3836c61cfb761 100644
+--- a/arch/arm/boot/dts/rk3288-firefly.dtsi
++++ b/arch/arm/boot/dts/rk3288-firefly.dtsi
+@@ -233,11 +233,10 @@
+ 		vin-supply = <&vcc_sys>;
+ 	};
+ 
+-	hym8563: hym8563@51 {
++	hym8563: rtc@51 {
+ 		compatible = "haoyu,hym8563";
+ 		reg = <0x51>;
+ 		#clock-cells = <0>;
+-		clock-frequency = <32768>;
+ 		clock-output-names = "xin32k";
+ 		interrupt-parent = <&gpio7>;
+ 		interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>;
+diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts
+index 713f55e143c69..db1eb648e0e1a 100644
+--- a/arch/arm/boot/dts/rk3288-miqi.dts
++++ b/arch/arm/boot/dts/rk3288-miqi.dts
+@@ -162,11 +162,10 @@
+ 		vin-supply = <&vcc_sys>;
+ 	};
+ 
+-	hym8563: hym8563@51 {
++	hym8563: rtc@51 {
+ 		compatible = "haoyu,hym8563";
+ 		reg = <0x51>;
+ 		#clock-cells = <0>;
+-		clock-frequency = <32768>;
+ 		clock-output-names = "xin32k";
+ 	};
+ 
+diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts
+index 80e0f07c8e878..13cfdaa95cc7d 100644
+--- a/arch/arm/boot/dts/rk3288-rock2-square.dts
++++ b/arch/arm/boot/dts/rk3288-rock2-square.dts
+@@ -165,11 +165,10 @@
+ };
+ 
+ &i2c0 {
+-	hym8563: hym8563@51 {
++	hym8563: rtc@51 {
+ 		compatible = "haoyu,hym8563";
+ 		reg = <0x51>;
+ 		#clock-cells = <0>;
+-		clock-frequency = <32768>;
+ 		clock-output-names = "xin32k";
+ 		interrupt-parent = <&gpio0>;
+ 		interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>;
+diff --git a/arch/arm/boot/dts/rk3288-vmarc-som.dtsi b/arch/arm/boot/dts/rk3288-vmarc-som.dtsi
+index 0ae2bd150e372..793951655b73b 100644
+--- a/arch/arm/boot/dts/rk3288-vmarc-som.dtsi
++++ b/arch/arm/boot/dts/rk3288-vmarc-som.dtsi
+@@ -241,7 +241,6 @@
+ 		interrupt-parent = <&gpio5>;
+ 		interrupts = <RK_PC3 IRQ_TYPE_LEVEL_LOW>;
+ 		#clock-cells = <0>;
+-		clock-frequency = <32768>;
+ 		clock-output-names = "hym8563";
+ 		pinctrl-names = "default";
+ 		pinctrl-0 = <&hym8563_int>;
+diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
+index 616a828e0c6e4..17e89d30de781 100644
+--- a/arch/arm/boot/dts/rk3xxx.dtsi
++++ b/arch/arm/boot/dts/rk3xxx.dtsi
+@@ -76,6 +76,13 @@
+ 		reg = <0x1013c200 0x20>;
+ 		interrupts = <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>;
+ 		clocks = <&cru CORE_PERI>;
++		status = "disabled";
++		/* The clock source and the sched_clock provided by the arm_global_timer
++		 * on Rockchip rk3066a/rk3188 are quite unstable because their rates
++		 * depend on the CPU frequency.
++		 * Keep the arm_global_timer disabled in order to have the
++		 * DW_APB_TIMER (rk3066a) or ROCKCHIP_TIMER (rk3188) selected by default.
++		 */
+ 	};
+ 
+ 	local_timer: local-timer@1013c600 {
+diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
+index fe87397c3d8c6..bdbc1e590891e 100644
+--- a/arch/arm/include/asm/perf_event.h
++++ b/arch/arm/include/asm/perf_event.h
+@@ -17,7 +17,7 @@ extern unsigned long perf_misc_flags(struct pt_regs *regs);
+ 
+ #define perf_arch_fetch_caller_regs(regs, __ip) { \
+ 	(regs)->ARM_pc = (__ip); \
+-	(regs)->ARM_fp = (unsigned long) __builtin_frame_address(0); \
++	frame_pointer((regs)) = (unsigned long) __builtin_frame_address(0); \
+ 	(regs)->ARM_sp = current_stack_pointer; \
+ 	(regs)->ARM_cpsr = SVC_MODE; \
+ }
+diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h
+index d16aba48fa0a4..090011394477f 100644
+--- a/arch/arm/include/asm/pgtable-nommu.h
++++ b/arch/arm/include/asm/pgtable-nommu.h
+@@ -44,12 +44,6 @@
+ 
+ typedef pte_t *pte_addr_t;
+ 
+-/*
+- * ZERO_PAGE is a global shared page that is always zero: used
+- * for zero-mapped memory areas etc..
+- */
+-#define ZERO_PAGE(vaddr)	(virt_to_page(0))
+-
+ /*
+  * Mark the prot value as uncacheable and unbufferable.
+  */
+diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
+index 78a532068fec2..ef48a55e9af83 100644
+--- a/arch/arm/include/asm/pgtable.h
++++ b/arch/arm/include/asm/pgtable.h
+@@ -10,6 +10,15 @@
+ #include <linux/const.h>
+ #include <asm/proc-fns.h>
+ 
++#ifndef __ASSEMBLY__
++/*
++ * ZERO_PAGE is a global shared page that is always zero: used
++ * for zero-mapped memory areas etc..
++ */
++extern struct page *empty_zero_page;
++#define ZERO_PAGE(vaddr)	(empty_zero_page)
++#endif
++
+ #ifndef CONFIG_MMU
+ 
+ #include <asm-generic/pgtable-nopud.h>
+@@ -139,13 +148,6 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+  */
+ 
+ #ifndef __ASSEMBLY__
+-/*
+- * ZERO_PAGE is a global shared page that is always zero: used
+- * for zero-mapped memory areas etc..
+- */
+-extern struct page *empty_zero_page;
+-#define ZERO_PAGE(vaddr)	(empty_zero_page)
+-
+ 
+ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+ 
+diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c
+index 67ed68fbe3a55..bf2b5c6a18c6a 100644
+--- a/arch/arm/mach-at91/sama5.c
++++ b/arch/arm/mach-at91/sama5.c
+@@ -26,7 +26,7 @@ static void sama5_l2c310_write_sec(unsigned long val, unsigned reg)
+ static void __init sama5_secure_cache_init(void)
+ {
+ 	sam_secure_init();
+-	if (sam_linux_is_optee_available())
++	if (IS_ENABLED(CONFIG_OUTER_CACHE) && sam_linux_is_optee_available())
+ 		outer_cache.write_sec = sama5_l2c310_write_sec;
+ }
+ 
+diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
+index 46cccd6bf705a..de988cba9a4b1 100644
+--- a/arch/arm/mm/fault.c
++++ b/arch/arm/mm/fault.c
+@@ -105,6 +105,19 @@ static inline bool is_write_fault(unsigned int fsr)
+ 	return (fsr & FSR_WRITE) && !(fsr & FSR_CM);
+ }
+ 
++static inline bool is_translation_fault(unsigned int fsr)
++{
++	int fs = fsr_fs(fsr);
++#ifdef CONFIG_ARM_LPAE
++	if ((fs & FS_MMU_NOLL_MASK) == FS_TRANS_NOLL)
++		return true;
++#else
++	if (fs == FS_L1_TRANS || fs == FS_L2_TRANS)
++		return true;
++#endif
++	return false;
++}
++
+ static void die_kernel_fault(const char *msg, struct mm_struct *mm,
+ 			     unsigned long addr, unsigned int fsr,
+ 			     struct pt_regs *regs)
+@@ -140,7 +153,8 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
+ 	if (addr < PAGE_SIZE) {
+ 		msg = "NULL pointer dereference";
+ 	} else {
+-		if (kfence_handle_page_fault(addr, is_write_fault(fsr), regs))
++		if (is_translation_fault(fsr) &&
++		    kfence_handle_page_fault(addr, is_write_fault(fsr), regs))
+ 			return;
+ 
+ 		msg = "paging request";
+@@ -208,7 +222,7 @@ static inline bool is_permission_fault(unsigned int fsr)
+ {
+ 	int fs = fsr_fs(fsr);
+ #ifdef CONFIG_ARM_LPAE
+-	if ((fs & FS_PERM_NOLL_MASK) == FS_PERM_NOLL)
++	if ((fs & FS_MMU_NOLL_MASK) == FS_PERM_NOLL)
+ 		return true;
+ #else
+ 	if (fs == FS_L1_PERM || fs == FS_L2_PERM)
+diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h
+index 83b5ab32d7a48..54927ba1fa6ed 100644
+--- a/arch/arm/mm/fault.h
++++ b/arch/arm/mm/fault.h
+@@ -14,8 +14,9 @@
+ 
+ #ifdef CONFIG_ARM_LPAE
+ #define FSR_FS_AEA		17
++#define FS_TRANS_NOLL		0x4
+ #define FS_PERM_NOLL		0xC
+-#define FS_PERM_NOLL_MASK	0x3C
++#define FS_MMU_NOLL_MASK	0x3C
+ 
+ static inline int fsr_fs(unsigned int fsr)
+ {
+@@ -23,8 +24,10 @@ static inline int fsr_fs(unsigned int fsr)
+ }
+ #else
+ #define FSR_FS_AEA		22
+-#define FS_L1_PERM             0xD
+-#define FS_L2_PERM             0xF
++#define FS_L1_TRANS		0x5
++#define FS_L2_TRANS		0x7
++#define FS_L1_PERM		0xD
++#define FS_L2_PERM		0xF
+ 
+ static inline int fsr_fs(unsigned int fsr)
+ {
+diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
+index c42debaded95c..c1494a4dee25b 100644
+--- a/arch/arm/mm/nommu.c
++++ b/arch/arm/mm/nommu.c
+@@ -26,6 +26,13 @@
+ 
+ unsigned long vectors_base;
+ 
++/*
++ * empty_zero_page is a special page that is used for
++ * zero-initialized data and COW.
++ */
++struct page *empty_zero_page;
++EXPORT_SYMBOL(empty_zero_page);
++
+ #ifdef CONFIG_ARM_MPU
+ struct mpu_rgn_info mpu_rgn_info;
+ #endif
+@@ -148,9 +155,21 @@ void __init adjust_lowmem_bounds(void)
+  */
+ void __init paging_init(const struct machine_desc *mdesc)
+ {
++	void *zero_page;
++
+ 	early_trap_init((void *)vectors_base);
+ 	mpu_setup();
++
++	/* allocate the zero page. */
++	zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
++	if (!zero_page)
++		panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
++		      __func__, PAGE_SIZE, PAGE_SIZE);
++
+ 	bootmem_init();
++
++	empty_zero_page = virt_to_page(zero_page);
++	flush_dcache_page(empty_zero_page);
+ }
+ 
+ /*
+diff --git a/arch/arm64/boot/dts/rockchip/px30-evb.dts b/arch/arm64/boot/dts/rockchip/px30-evb.dts
+index 848bc39cf86ac..4249b42843dae 100644
+--- a/arch/arm64/boot/dts/rockchip/px30-evb.dts
++++ b/arch/arm64/boot/dts/rockchip/px30-evb.dts
+@@ -30,31 +30,31 @@
+ 		keyup-threshold-microvolt = <1800000>;
+ 		poll-interval = <100>;
+ 
+-		esc-key {
++		button-esc {
+ 			label = "esc";
+ 			linux,code = <KEY_ESC>;
+ 			press-threshold-microvolt = <1310000>;
+ 		};
+ 
+-		home-key {
++		button-home {
+ 			label = "home";
+ 			linux,code = <KEY_HOME>;
+ 			press-threshold-microvolt = <624000>;
+ 		};
+ 
+-		menu-key {
++		button-menu {
+ 			label = "menu";
+ 			linux,code = <KEY_MENU>;
+ 			press-threshold-microvolt = <987000>;
+ 		};
+ 
+-		vol-down-key {
++		button-down {
+ 			label = "volume down";
+ 			linux,code = <KEY_VOLUMEDOWN>;
+ 			press-threshold-microvolt = <300000>;
+ 		};
+ 
+-		vol-up-key {
++		button-up {
+ 			label = "volume up";
+ 			linux,code = <KEY_VOLUMEUP>;
+ 			press-threshold-microvolt = <17000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3308-evb.dts b/arch/arm64/boot/dts/rockchip/rk3308-evb.dts
+index 9fe9b0d11003a..184b84fdde075 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3308-evb.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-evb.dts
+@@ -23,7 +23,7 @@
+ 		poll-interval = <100>;
+ 		keyup-threshold-microvolt = <1800000>;
+ 
+-		func-key {
++		button-func {
+ 			linux,code = <KEY_FN>;
+ 			label = "function";
+ 			press-threshold-microvolt = <18000>;
+@@ -37,31 +37,31 @@
+ 		poll-interval = <100>;
+ 		keyup-threshold-microvolt = <1800000>;
+ 
+-		esc-key {
++		button-esc {
+ 			linux,code = <KEY_MICMUTE>;
+ 			label = "micmute";
+ 			press-threshold-microvolt = <1130000>;
+ 		};
+ 
+-		home-key {
++		button-home {
+ 			linux,code = <KEY_MODE>;
+ 			label = "mode";
+ 			press-threshold-microvolt = <901000>;
+ 		};
+ 
+-		menu-key {
++		button-menu {
+ 			linux,code = <KEY_PLAY>;
+ 			label = "play";
+ 			press-threshold-microvolt = <624000>;
+ 		};
+ 
+-		vol-down-key {
++		button-down {
+ 			linux,code = <KEY_VOLUMEDOWN>;
+ 			label = "volume down";
+ 			press-threshold-microvolt = <300000>;
+ 		};
+ 
+-		vol-up-key {
++		button-up {
+ 			linux,code = <KEY_VOLUMEUP>;
+ 			label = "volume up";
+ 			press-threshold-microvolt = <18000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
+index ea6820902ede0..7ea48167747c6 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
+@@ -19,7 +19,7 @@
+ 		stdout-path = "serial2:1500000n8";
+ 	};
+ 
+-	ir_rx {
++	ir-receiver {
+ 		compatible = "gpio-ir-receiver";
+ 		gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
+ 		pinctrl-names = "default";
+diff --git a/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts
+index 43c928ac98f0f..1deef53a4c940 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3318-a95x-z2.dts
+@@ -25,7 +25,7 @@
+ 		keyup-threshold-microvolt = <1800000>;
+ 		poll-interval = <100>;
+ 
+-		recovery {
++		button-recovery {
+ 			label = "recovery";
+ 			linux,code = <KEY_VENDOR>;
+ 			press-threshold-microvolt = <17000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
+index 7f5bba0c60014..0e88e9592c1cb 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
+@@ -208,7 +208,7 @@
+ 		vin-supply = <&vcc_sys>;
+ 	};
+ 
+-	hym8563: hym8563@51 {
++	hym8563: rtc@51 {
+ 		compatible = "haoyu,hym8563";
+ 		reg = <0x51>;
+ 		#clock-cells = <0>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
+index 38d757c005488..e147d6f8b43ee 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts
+@@ -192,7 +192,7 @@
+ 		vin-supply = <&vcc_sys>;
+ 	};
+ 
+-	hym8563: hym8563@51 {
++	hym8563: rtc@51 {
+ 		compatible = "haoyu,hym8563";
+ 		reg = <0x51>;
+ 		#clock-cells = <0>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi
+index 2a332763c35cd..9d9297bc5f04a 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi
+@@ -123,7 +123,7 @@
+ 		keyup-threshold-microvolt = <1800000>;
+ 		poll-interval = <100>;
+ 
+-		recovery {
++		button-recovery {
+ 			label = "Recovery";
+ 			linux,code = <KEY_VENDOR>;
+ 			press-threshold-microvolt = <18000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
+index 452728b82e42c..3bf8f959e42c4 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
+@@ -39,7 +39,7 @@
+ 		keyup-threshold-microvolt = <1800000>;
+ 		poll-interval = <100>;
+ 
+-		recovery {
++		button-recovery {
+ 			label = "Recovery";
+ 			linux,code = <KEY_VENDOR>;
+ 			press-threshold-microvolt = <18000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4b.dts b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4b.dts
+index 72182c58cc46a..65cb21837b0ca 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-nanopi-m4b.dts
+@@ -19,7 +19,7 @@
+ 		keyup-threshold-microvolt = <1500000>;
+ 		poll-interval = <100>;
+ 
+-		recovery {
++		button-recovery {
+ 			label = "Recovery";
+ 			linux,code = <KEY_VENDOR>;
+ 			press-threshold-microvolt = <18000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
+index 9e2e246e0bab7..dba4d03bfc2b8 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
+@@ -52,13 +52,13 @@
+ 			press-threshold-microvolt = <300000>;
+ 		};
+ 
+-		back {
++		button-back {
+ 			label = "Back";
+ 			linux,code = <KEY_BACK>;
+ 			press-threshold-microvolt = <985000>;
+ 		};
+ 
+-		menu {
++		button-menu {
+ 			label = "Menu";
+ 			linux,code = <KEY_MENU>;
+ 			press-threshold-microvolt = <1314000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts
+index 5a2661ae0131c..18b5050c6cd3b 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc-plus.dts
+@@ -98,7 +98,7 @@
+ };
+ 
+ &i2c0 {
+-	hym8563: hym8563@51 {
++	hym8563: rtc@51 {
+ 		compatible = "haoyu,hym8563";
+ 		reg = <0x51>;
+ 		interrupt-parent = <&gpio0>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+index acb174d3a8c5f..4f3dd107e83eb 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
+@@ -41,7 +41,7 @@
+ 		keyup-threshold-microvolt = <1500000>;
+ 		poll-interval = <100>;
+ 
+-		recovery {
++		button-recovery {
+ 			label = "Recovery";
+ 			linux,code = <KEY_VENDOR>;
+ 			press-threshold-microvolt = <18000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+index 401e1ae9d9443..b045f74071e45 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
+@@ -491,7 +491,6 @@
+ &i2s1 {
+ 	rockchip,playback-channels = <2>;
+ 	rockchip,capture-channels = <2>;
+-	status = "okay";
+ };
+ 
+ &i2s2 {
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
+index 13927e7d0724e..dbec2b7173a0b 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
+@@ -33,13 +33,13 @@
+ 			press-threshold-microvolt = <300000>;
+ 		};
+ 
+-		back {
++		button-back {
+ 			label = "Back";
+ 			linux,code = <KEY_BACK>;
+ 			press-threshold-microvolt = <985000>;
+ 		};
+ 
+-		menu {
++		button-menu {
+ 			label = "Menu";
+ 			linux,code = <KEY_MENU>;
+ 			press-threshold-microvolt = <1314000>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
+index 935b8c68a71d6..6c168566321ba 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
+@@ -297,7 +297,7 @@
+ 	clock-frequency = <400000>;
+ 	status = "okay";
+ 
+-	hym8563: hym8563@51 {
++	hym8563: rtc@51 {
+ 		compatible = "haoyu,hym8563";
+ 		reg = <0x51>;
+ 		#clock-cells = <0>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
+index 0d45868132b9d..8d61f824c12dc 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
+@@ -23,7 +23,7 @@
+ 		io-channel-names = "buttons";
+ 		keyup-threshold-microvolt = <1750000>;
+ 
+-		recovery {
++		button-recovery {
+ 			label = "recovery";
+ 			linux,code = <KEY_VENDOR>;
+ 			press-threshold-microvolt = <0>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts
+index 57759b66d44d0..ab1abf0bb7493 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts
+@@ -130,7 +130,7 @@
+ 	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>;
+ 	assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>, <&gmac1_clkin>;
+ 	clock_in_out = "input";
+-	phy-mode = "rgmii-id";
++	phy-mode = "rgmii";
+ 	phy-supply = <&vcc_3v3>;
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&gmac1m0_miim
+@@ -397,11 +397,7 @@
+ 
+ &i2c3 {
+ 	pinctrl-names = "default";
+-	pinctrl-0 = <&i2c3m1_xfer>;
+-	status = "okay";
+-};
+-
+-&i2c5 {
++	pinctrl-0 = <&i2c3m0_xfer>;
+ 	status = "okay";
+ };
+ 
+diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile
+index ec3de61912765..9123feb69854f 100644
+--- a/arch/loongarch/Makefile
++++ b/arch/loongarch/Makefile
+@@ -68,7 +68,7 @@ KBUILD_LDFLAGS	+= -m $(ld-emul)
+ 
+ ifdef CONFIG_LOONGARCH
+ CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \
+-	egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \
++	grep -E -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \
+ 	sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g')
+ endif
+ 
+diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h
+index cc0674d1b8f0f..645e24ebec68d 100644
+--- a/arch/loongarch/include/asm/pgtable.h
++++ b/arch/loongarch/include/asm/pgtable.h
+@@ -357,7 +357,9 @@ static inline pte_t pte_mkdirty(pte_t pte)
+ 
+ static inline pte_t pte_mkwrite(pte_t pte)
+ {
+-	pte_val(pte) |= (_PAGE_WRITE | _PAGE_DIRTY);
++	pte_val(pte) |= _PAGE_WRITE;
++	if (pte_val(pte) & _PAGE_MODIFIED)
++		pte_val(pte) |= _PAGE_DIRTY;
+ 	return pte;
+ }
+ 
+@@ -454,7 +456,9 @@ static inline int pmd_write(pmd_t pmd)
+ 
+ static inline pmd_t pmd_mkwrite(pmd_t pmd)
+ {
+-	pmd_val(pmd) |= (_PAGE_WRITE | _PAGE_DIRTY);
++	pmd_val(pmd) |= _PAGE_WRITE;
++	if (pmd_val(pmd) & _PAGE_MODIFIED)
++		pmd_val(pmd) |= _PAGE_DIRTY;
+ 	return pmd;
+ }
+ 
+diff --git a/arch/loongarch/kernel/acpi.c b/arch/loongarch/kernel/acpi.c
+index 3353984820388..8319cc4090090 100644
+--- a/arch/loongarch/kernel/acpi.c
++++ b/arch/loongarch/kernel/acpi.c
+@@ -56,23 +56,6 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
+ 		return ioremap_cache(phys, size);
+ }
+ 
+-void __init acpi_boot_table_init(void)
+-{
+-	/*
+-	 * If acpi_disabled, bail out
+-	 */
+-	if (acpi_disabled)
+-		return;
+-
+-	/*
+-	 * Initialize the ACPI boot-time table parser.
+-	 */
+-	if (acpi_table_init()) {
+-		disable_acpi();
+-		return;
+-	}
+-}
+-
+ #ifdef CONFIG_SMP
+ static int set_processor_mask(u32 id, u32 flags)
+ {
+@@ -156,13 +139,21 @@ static void __init acpi_process_madt(void)
+ 	loongson_sysconf.nr_cpus = num_processors;
+ }
+ 
+-int __init acpi_boot_init(void)
++void __init acpi_boot_table_init(void)
+ {
+ 	/*
+ 	 * If acpi_disabled, bail out
+ 	 */
+ 	if (acpi_disabled)
+-		return -1;
++		return;
++
++	/*
++	 * Initialize the ACPI boot-time table parser.
++	 */
++	if (acpi_table_init()) {
++		disable_acpi();
++		return;
++	}
+ 
+ 	loongson_sysconf.boot_cpu_id = read_csr_cpuid();
+ 
+@@ -173,8 +164,6 @@ int __init acpi_boot_init(void)
+ 
+ 	/* Do not enable ACPI SPCR console by default */
+ 	acpi_parse_spcr(earlycon_acpi_spcr_enable, false);
+-
+-	return 0;
+ }
+ 
+ #ifdef CONFIG_ACPI_NUMA
+diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c
+index 8f5c2f9a1a835..574647e3483d3 100644
+--- a/arch/loongarch/kernel/setup.c
++++ b/arch/loongarch/kernel/setup.c
+@@ -203,7 +203,6 @@ void __init platform_init(void)
+ #ifdef CONFIG_ACPI
+ 	acpi_gbl_use_default_register_widths = false;
+ 	acpi_boot_table_init();
+-	acpi_boot_init();
+ #endif
+ 
+ #ifdef CONFIG_NUMA
+diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c
+index b206d91592051..4571c3c87cd4c 100644
+--- a/arch/loongarch/kernel/unwind_prologue.c
++++ b/arch/loongarch/kernel/unwind_prologue.c
+@@ -43,7 +43,8 @@ static bool unwind_by_prologue(struct unwind_state *state)
+ {
+ 	struct stack_info *info = &state->stack_info;
+ 	union loongarch_instruction *ip, *ip_end;
+-	unsigned long frame_size = 0, frame_ra = -1;
++	long frame_ra = -1;
++	unsigned long frame_size = 0;
+ 	unsigned long size, offset, pc = state->pc;
+ 
+ 	if (state->sp >= info->end || state->sp < info->begin)
+diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c
+index 94138f8f0c1c3..ace2541ababd3 100644
+--- a/arch/s390/kvm/vsie.c
++++ b/arch/s390/kvm/vsie.c
+@@ -546,8 +546,10 @@ static int shadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
+ 	if (test_kvm_cpu_feat(vcpu->kvm, KVM_S390_VM_CPU_FEAT_CEI))
+ 		scb_s->eca |= scb_o->eca & ECA_CEI;
+ 	/* Epoch Extension */
+-	if (test_kvm_facility(vcpu->kvm, 139))
++	if (test_kvm_facility(vcpu->kvm, 139)) {
+ 		scb_s->ecd |= scb_o->ecd & ECD_MEF;
++		scb_s->epdx = scb_o->epdx;
++	}
+ 
+ 	/* etoken */
+ 	if (test_kvm_facility(vcpu->kvm, 156))
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 1bb46cbff0fac..882b5893f9108 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2042,6 +2042,11 @@ static int btusb_setup_csr(struct hci_dev *hdev)
+ 
+ 	rp = (struct hci_rp_read_local_version *)skb->data;
+ 
++	bt_dev_info(hdev, "CSR: Setting up dongle with HCI ver=%u rev=%04x; LMP ver=%u subver=%04x; manufacturer=%u",
++		le16_to_cpu(rp->hci_ver), le16_to_cpu(rp->hci_rev),
++		le16_to_cpu(rp->lmp_ver), le16_to_cpu(rp->lmp_subver),
++		le16_to_cpu(rp->manufacturer));
++
+ 	/* Detect a wide host of Chinese controllers that aren't CSR.
+ 	 *
+ 	 * Known fake bcdDevices: 0x0100, 0x0134, 0x1915, 0x2520, 0x7558, 0x8891
+@@ -2104,6 +2109,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
+ 		 * without these the controller will lock up.
+ 		 */
+ 		set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
++		set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
+ 		set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
+ 		set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
+ 
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index 6c49e6d06114f..034a74196a823 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -748,6 +748,11 @@ static int sev_update_firmware(struct device *dev)
+ 	struct page *p;
+ 	u64 data_size;
+ 
++	if (!sev_version_greater_or_equal(0, 15)) {
++		dev_dbg(dev, "DOWNLOAD_FIRMWARE not supported\n");
++		return -1;
++	}
++
+ 	if (sev_get_firmware(dev, &firmware) == -ENOENT) {
+ 		dev_dbg(dev, "No SEV firmware file present\n");
+ 		return -1;
+@@ -780,6 +785,14 @@ static int sev_update_firmware(struct device *dev)
+ 	data->len = firmware->size;
+ 
+ 	ret = sev_do_cmd(SEV_CMD_DOWNLOAD_FIRMWARE, data, &error);
++
++	/*
++	 * A quirk for fixing the committed TCB version, when upgrading from
++	 * earlier firmware version than 1.50.
++	 */
++	if (!ret && !sev_version_greater_or_equal(1, 50))
++		ret = sev_do_cmd(SEV_CMD_DOWNLOAD_FIRMWARE, data, &error);
++
+ 	if (ret)
+ 		dev_dbg(dev, "Failed to update SEV firmware: %#x\n", error);
+ 	else
+@@ -1289,8 +1302,7 @@ void sev_pci_init(void)
+ 	if (sev_get_api_version())
+ 		goto err;
+ 
+-	if (sev_version_greater_or_equal(0, 15) &&
+-	    sev_update_firmware(sev->dev) == 0)
++	if (sev_update_firmware(sev->dev) == 0)
+ 		sev_get_api_version();
+ 
+ 	/* If an init_ex_path is provided rely on INIT_EX for PSP initialization
+diff --git a/drivers/gpio/gpio-amd8111.c b/drivers/gpio/gpio-amd8111.c
+index 14e6b3e64add5..6f3ded619c8b2 100644
+--- a/drivers/gpio/gpio-amd8111.c
++++ b/drivers/gpio/gpio-amd8111.c
+@@ -226,7 +226,10 @@ found:
+ 		ioport_unmap(gp.pm);
+ 		goto out;
+ 	}
++	return 0;
++
+ out:
++	pci_dev_put(pdev);
+ 	return err;
+ }
+ 
+@@ -234,6 +237,7 @@ static void __exit amd_gpio_exit(void)
+ {
+ 	gpiochip_remove(&gp.chip);
+ 	ioport_unmap(gp.pm);
++	pci_dev_put(gp.pdev);
+ }
+ 
+ module_init(amd_gpio_init);
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index 9c976ad7208ef..09cfb49ed998d 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -621,6 +621,7 @@ static int rockchip_gpiolib_register(struct rockchip_pin_bank *bank)
+ 			return -ENODATA;
+ 
+ 		pctldev = of_pinctrl_get(pctlnp);
++		of_node_put(pctlnp);
+ 		if (!pctldev)
+ 			return -ENODEV;
+ 
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index cc9c0a12259e1..eb7d00608c7fb 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -526,12 +526,13 @@ static int gpiochip_setup_dev(struct gpio_device *gdev)
+ 	if (ret)
+ 		return ret;
+ 
++	/* From this point, the .release() function cleans up gpio_device */
++	gdev->dev.release = gpiodevice_release;
++
+ 	ret = gpiochip_sysfs_register(gdev);
+ 	if (ret)
+ 		goto err_remove_device;
+ 
+-	/* From this point, the .release() function cleans up gpio_device */
+-	gdev->dev.release = gpiodevice_release;
+ 	dev_dbg(&gdev->dev, "registered GPIOs %d to %d on %s\n", gdev->base,
+ 		gdev->base + gdev->ngpio - 1, gdev->chip->label ? : "generic");
+ 
+@@ -597,10 +598,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
+ 	struct fwnode_handle *fwnode = NULL;
+ 	struct gpio_device *gdev;
+ 	unsigned long flags;
+-	int base = gc->base;
+ 	unsigned int i;
++	u32 ngpios = 0;
++	int base = 0;
+ 	int ret = 0;
+-	u32 ngpios;
+ 
+ 	if (gc->fwnode)
+ 		fwnode = gc->fwnode;
+@@ -647,17 +648,12 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
+ 	else
+ 		gdev->owner = THIS_MODULE;
+ 
+-	gdev->descs = kcalloc(gc->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL);
+-	if (!gdev->descs) {
+-		ret = -ENOMEM;
+-		goto err_free_dev_name;
+-	}
+-
+ 	/*
+ 	 * Try the device properties if the driver didn't supply the number
+ 	 * of GPIO lines.
+ 	 */
+-	if (gc->ngpio == 0) {
++	ngpios = gc->ngpio;
++	if (ngpios == 0) {
+ 		ret = device_property_read_u32(&gdev->dev, "ngpios", &ngpios);
+ 		if (ret == -ENODATA)
+ 			/*
+@@ -668,7 +664,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
+ 			 */
+ 			ngpios = 0;
+ 		else if (ret)
+-			goto err_free_descs;
++			goto err_free_dev_name;
+ 
+ 		gc->ngpio = ngpios;
+ 	}
+@@ -676,13 +672,19 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
+ 	if (gc->ngpio == 0) {
+ 		chip_err(gc, "tried to insert a GPIO chip with zero lines\n");
+ 		ret = -EINVAL;
+-		goto err_free_descs;
++		goto err_free_dev_name;
+ 	}
+ 
+ 	if (gc->ngpio > FASTPATH_NGPIO)
+ 		chip_warn(gc, "line cnt %u is greater than fast path cnt %u\n",
+ 			  gc->ngpio, FASTPATH_NGPIO);
+ 
++	gdev->descs = kcalloc(gc->ngpio, sizeof(*gdev->descs), GFP_KERNEL);
++	if (!gdev->descs) {
++		ret = -ENOMEM;
++		goto err_free_dev_name;
++	}
++
+ 	gdev->label = kstrdup_const(gc->label ?: "unknown", GFP_KERNEL);
+ 	if (!gdev->label) {
+ 		ret = -ENOMEM;
+@@ -701,11 +703,13 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
+ 	 * it may be a pipe dream. It will not happen before we get rid
+ 	 * of the sysfs interface anyways.
+ 	 */
++	base = gc->base;
+ 	if (base < 0) {
+ 		base = gpiochip_find_base(gc->ngpio);
+ 		if (base < 0) {
+-			ret = base;
+ 			spin_unlock_irqrestore(&gpio_lock, flags);
++			ret = base;
++			base = 0;
+ 			goto err_free_label;
+ 		}
+ 		/*
+@@ -816,6 +820,11 @@ err_remove_of_chip:
+ err_free_gpiochip_mask:
+ 	gpiochip_remove_pin_ranges(gc);
+ 	gpiochip_free_valid_mask(gc);
++	if (gdev->dev.release) {
++		/* release() has been registered by gpiochip_setup_dev() */
++		put_device(&gdev->dev);
++		goto err_print_message;
++	}
+ err_remove_from_list:
+ 	spin_lock_irqsave(&gpio_lock, flags);
+ 	list_del(&gdev->list);
+@@ -829,13 +838,14 @@ err_free_dev_name:
+ err_free_ida:
+ 	ida_free(&gpio_ida, gdev->id);
+ err_free_gdev:
++	kfree(gdev);
++err_print_message:
+ 	/* failures here can mean systems won't boot... */
+ 	if (ret != -EPROBE_DEFER) {
+ 		pr_err("%s: GPIOs %d..%d (%s) failed to register, %d\n", __func__,
+-		       gdev->base, gdev->base + gdev->ngpio - 1,
++		       base, base + (int)ngpios - 1,
+ 		       gc->label ? : "generic", ret);
+ 	}
+-	kfree(gdev);
+ 	return ret;
+ }
+ EXPORT_SYMBOL_GPL(gpiochip_add_data_with_key);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+index 3b025aace2831..eb4c0523e42d5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+@@ -167,7 +167,11 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
+ 	amdgpu_sync_free(&job->sync);
+ 	amdgpu_sync_free(&job->sched_sync);
+ 
+-	dma_fence_put(&job->hw_fence);
++	/* only put the hw fence if has embedded fence */
++	if (!job->hw_fence.ops)
++		kfree(job);
++	else
++		dma_fence_put(&job->hw_fence);
+ }
+ 
+ void amdgpu_job_free(struct amdgpu_job *job)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
+index 60c608144480a..ecb8db731081b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
+@@ -161,6 +161,7 @@
+ #define AMDGPU_VCN_SW_RING_FLAG		(1 << 9)
+ #define AMDGPU_VCN_FW_LOGGING_FLAG	(1 << 10)
+ #define AMDGPU_VCN_SMU_VERSION_INFO_FLAG (1 << 11)
++#define AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG (1 << 11)
+ 
+ #define AMDGPU_VCN_IB_FLAG_DECODE_BUFFER	0x00000001
+ #define AMDGPU_VCN_CMD_FLAG_MSG_BUFFER		0x00000001
+@@ -170,6 +171,9 @@
+ #define VCN_CODEC_DISABLE_MASK_HEVC (1 << 2)
+ #define VCN_CODEC_DISABLE_MASK_H264 (1 << 3)
+ 
++#define AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU (0)
++#define AMDGPU_VCN_SMU_DPM_INTERFACE_APU (1)
++
+ enum fw_queue_mode {
+ 	FW_QUEUE_RING_RESET = 1,
+ 	FW_QUEUE_DPG_HOLD_OFF = 2,
+@@ -323,6 +327,9 @@ struct amdgpu_vcn4_fw_shared {
+ 	struct amdgpu_fw_shared_unified_queue_struct sq;
+ 	uint8_t pad1[8];
+ 	struct amdgpu_fw_shared_fw_logging fw_log;
++	uint8_t pad2[20];
++	uint32_t pad3[13];
++	struct amdgpu_fw_shared_smu_interface_info smu_dpm_interface;
+ };
+ 
+ struct amdgpu_vcn_fwlog {
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+index 65181efba50ec..408b0f399cfc4 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+@@ -980,13 +980,13 @@ static void sdma_v4_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
+ 
+ 
+ /**
+- * sdma_v4_0_gfx_stop - stop the gfx async dma engines
++ * sdma_v4_0_gfx_enable - enable the gfx async dma engines
+  *
+  * @adev: amdgpu_device pointer
+- *
+- * Stop the gfx async dma ring buffers (VEGA10).
++ * @enable: enable SDMA RB/IB
++ * control the gfx async dma ring buffers (VEGA10).
+  */
+-static void sdma_v4_0_gfx_stop(struct amdgpu_device *adev)
++static void sdma_v4_0_gfx_enable(struct amdgpu_device *adev, bool enable)
+ {
+ 	struct amdgpu_ring *sdma[AMDGPU_MAX_SDMA_INSTANCES];
+ 	u32 rb_cntl, ib_cntl;
+@@ -1001,10 +1001,10 @@ static void sdma_v4_0_gfx_stop(struct amdgpu_device *adev)
+ 		}
+ 
+ 		rb_cntl = RREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL);
+-		rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0);
++		rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, enable ? 1 : 0);
+ 		WREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL, rb_cntl);
+ 		ib_cntl = RREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL);
+-		ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0);
++		ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, enable ? 1 : 0);
+ 		WREG32_SDMA(i, mmSDMA0_GFX_IB_CNTL, ib_cntl);
+ 	}
+ }
+@@ -1131,7 +1131,7 @@ static void sdma_v4_0_enable(struct amdgpu_device *adev, bool enable)
+ 	int i;
+ 
+ 	if (!enable) {
+-		sdma_v4_0_gfx_stop(adev);
++		sdma_v4_0_gfx_enable(adev, enable);
+ 		sdma_v4_0_rlc_stop(adev);
+ 		if (adev->sdma.has_page_queue)
+ 			sdma_v4_0_page_stop(adev);
+@@ -2043,8 +2043,10 @@ static int sdma_v4_0_suspend(void *handle)
+ 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ 
+ 	/* SMU saves SDMA state for us */
+-	if (adev->in_s0ix)
++	if (adev->in_s0ix) {
++		sdma_v4_0_gfx_enable(adev, false);
+ 		return 0;
++	}
+ 
+ 	return sdma_v4_0_hw_fini(adev);
+ }
+@@ -2054,8 +2056,12 @@ static int sdma_v4_0_resume(void *handle)
+ 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ 
+ 	/* SMU restores SDMA state for us */
+-	if (adev->in_s0ix)
++	if (adev->in_s0ix) {
++		sdma_v4_0_enable(adev, true);
++		sdma_v4_0_gfx_enable(adev, true);
++		amdgpu_ttm_set_buffer_funcs_status(adev, true);
+ 		return 0;
++	}
+ 
+ 	return sdma_v4_0_hw_init(adev);
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
+index fb2d74f304481..c5afb5bc9eb60 100644
+--- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c
+@@ -132,6 +132,10 @@ static int vcn_v4_0_sw_init(void *handle)
+ 		fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
+ 		fw_shared->sq.is_enabled = 1;
+ 
++		fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG);
++		fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ?
++			AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU;
++
+ 		if (amdgpu_vcnfw_log)
+ 			amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
+ 	}
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
+index fb729674953b2..de9fa534b77af 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
+@@ -96,6 +96,13 @@ static void dccg314_set_pixel_rate_div(
+ 	struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
+ 	enum pixel_rate_div cur_k1 = PIXEL_RATE_DIV_NA, cur_k2 = PIXEL_RATE_DIV_NA;
+ 
++	// Don't program 0xF into the register field. Not valid since
++	// K1 / K2 field is only 1 / 2 bits wide
++	if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
++		BREAK_TO_DEBUGGER();
++		return;
++	}
++
+ 	dccg314_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
+ 	if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA || (k1 == cur_k1 && k2 == cur_k2))
+ 		return;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
+index f4d1b83979fe0..a0741794db62a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
+@@ -349,6 +349,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
+ 	odm_combine_factor = get_odm_config(pipe_ctx, NULL);
+ 
+ 	if (is_dp_128b_132b_signal(pipe_ctx)) {
++		*k1_div = PIXEL_RATE_DIV_BY_1;
+ 		*k2_div = PIXEL_RATE_DIV_BY_1;
+ 	} else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
+ 		*k1_div = PIXEL_RATE_DIV_BY_1;
+@@ -356,7 +357,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
+ 			*k2_div = PIXEL_RATE_DIV_BY_2;
+ 		else
+ 			*k2_div = PIXEL_RATE_DIV_BY_4;
+-	} else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
++	} else if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) {
+ 		if (two_pix_per_container) {
+ 			*k1_div = PIXEL_RATE_DIV_BY_1;
+ 			*k2_div = PIXEL_RATE_DIV_BY_2;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
+index 6640d0ac43040..6dd8dadd68a5d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
+@@ -96,8 +96,10 @@ static void dccg32_set_pixel_rate_div(
+ 
+ 	// Don't program 0xF into the register field. Not valid since
+ 	// K1 / K2 field is only 1 / 2 bits wide
+-	if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA)
++	if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
++		BREAK_TO_DEBUGGER();
+ 		return;
++	}
+ 
+ 	dccg32_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
+ 	if (k1 == cur_k1 && k2 == cur_k2)
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+index bbc0bfbec6c42..3128c111c6198 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -1171,6 +1171,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
+ 	odm_combine_factor = get_odm_config(pipe_ctx, NULL);
+ 
+ 	if (is_dp_128b_132b_signal(pipe_ctx)) {
++		*k1_div = PIXEL_RATE_DIV_BY_1;
+ 		*k2_div = PIXEL_RATE_DIV_BY_1;
+ 	} else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
+ 		*k1_div = PIXEL_RATE_DIV_BY_1;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+index 7c37575d69c73..0ef11fb338e9f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+@@ -103,7 +103,7 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
+ 			mall_alloc_width_blk_aligned = full_vp_width_blk_aligned;
+ 
+ 			/* mall_alloc_height_blk_aligned_l/c = CEILING(sub_vp_height_l/c - 1, blk_height_l/c) + blk_height_l/c */
+-			mall_alloc_height_blk_aligned = (pipe->stream->timing.v_addressable - 1 + mblk_height - 1) /
++			mall_alloc_height_blk_aligned = (pipe->plane_res.scl_data.viewport.height - 1 + mblk_height - 1) /
+ 					mblk_height * mblk_height + mblk_height;
+ 
+ 			/* full_mblk_width_ub_l/c = mall_alloc_width_blk_aligned_l/c;
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+index 2f996fdaa70dd..07c56e231b045 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+@@ -1803,7 +1803,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
+ 
+ 		if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] ==
+ 			dm_dram_clock_change_unsupported) {
+-			int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries - 1;
++			int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1;
+ 
+ 			min_dram_speed_mts =
+ 				dc->clk_mgr->bw_params->clk_table.entries[min_dram_speed_mts_offset].memclk_mhz * 16;
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
+index 2051ddaa641a7..6ec0947ace9cb 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
+@@ -1152,7 +1152,7 @@ struct vba_vars_st {
+ 	double UrgBurstFactorLumaPre[DC__NUM_DPP__MAX];
+ 	double UrgBurstFactorChromaPre[DC__NUM_DPP__MAX];
+ 	bool NotUrgentLatencyHidingPre[DC__NUM_DPP__MAX];
+-	bool LinkCapacitySupport[DC__NUM_DPP__MAX];
++	bool LinkCapacitySupport[DC__VOLTAGE_STATES];
+ 	bool VREADY_AT_OR_AFTER_VSYNC[DC__NUM_DPP__MAX];
+ 	unsigned int MIN_DST_Y_NEXT_START[DC__NUM_DPP__MAX];
+ 	unsigned int VFrontPorch[DC__NUM_DPP__MAX];
+diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+index 40d8ca37f5bc8..aa51c61a78c71 100644
+--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+@@ -2720,6 +2720,9 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
+ 	 * if supported. In any case the default RGB888 format is added
+ 	 */
+ 
++	/* Default 8bit RGB fallback */
++	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
++
+ 	if (max_bpc >= 16 && info->bpc == 16) {
+ 		if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
+ 			output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
+@@ -2753,9 +2756,6 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
+ 	if (info->color_formats & DRM_COLOR_FORMAT_YCBCR444)
+ 		output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
+ 
+-	/* Default 8bit RGB fallback */
+-	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
+-
+ 	*num_output_fmts = i;
+ 
+ 	return output_fmts;
+diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+index d6dd4d99a229a..d72bd1392c849 100644
+--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+@@ -906,9 +906,9 @@ static void ti_sn_bridge_set_video_timings(struct ti_sn65dsi86 *pdata)
+ 		&pdata->bridge.encoder->crtc->state->adjusted_mode;
+ 	u8 hsync_polarity = 0, vsync_polarity = 0;
+ 
+-	if (mode->flags & DRM_MODE_FLAG_PHSYNC)
++	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+ 		hsync_polarity = CHA_HSYNC_POLARITY;
+-	if (mode->flags & DRM_MODE_FLAG_PVSYNC)
++	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+ 		vsync_polarity = CHA_VSYNC_POLARITY;
+ 
+ 	ti_sn65dsi86_write_u16(pdata, SN_CHA_ACTIVE_LINE_LENGTH_LOW_REG,
+diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
+index 904fc893c905b..eb9e722a865b7 100644
+--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
++++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
+@@ -571,12 +571,20 @@ static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
+ {
+ 	struct drm_gem_object *obj = vma->vm_private_data;
+ 	struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+-	int ret;
+ 
+ 	WARN_ON(shmem->base.import_attach);
+ 
+-	ret = drm_gem_shmem_get_pages(shmem);
+-	WARN_ON_ONCE(ret != 0);
++	mutex_lock(&shmem->pages_lock);
++
++	/*
++	 * We should have already pinned the pages when the buffer was first
++	 * mmap'd, vm_open() just grabs an additional reference for the new
++	 * mm the vma is getting copied into (ie. on fork()).
++	 */
++	if (!WARN_ON_ONCE(!shmem->pages_use_count))
++		shmem->pages_use_count++;
++
++	mutex_unlock(&shmem->pages_lock);
+ 
+ 	drm_gem_vm_open(vma);
+ }
+@@ -622,10 +630,8 @@ int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct
+ 	}
+ 
+ 	ret = drm_gem_shmem_get_pages(shmem);
+-	if (ret) {
+-		drm_gem_vm_close(vma);
++	if (ret)
+ 		return ret;
+-	}
+ 
+ 	vma->vm_flags |= VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
+ 	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
+index fc5d94862ef32..d0f20bd0e51ae 100644
+--- a/drivers/gpu/drm/i915/display/intel_display.c
++++ b/drivers/gpu/drm/i915/display/intel_display.c
+@@ -3717,12 +3717,16 @@ out:
+ 
+ static u8 bigjoiner_pipes(struct drm_i915_private *i915)
+ {
++	u8 pipes;
++
+ 	if (DISPLAY_VER(i915) >= 12)
+-		return BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D);
++		pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D);
+ 	else if (DISPLAY_VER(i915) >= 11)
+-		return BIT(PIPE_B) | BIT(PIPE_C);
++		pipes = BIT(PIPE_B) | BIT(PIPE_C);
+ 	else
+-		return 0;
++		pipes = 0;
++
++	return pipes & INTEL_INFO(i915)->display.pipe_mask;
+ }
+ 
+ static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+index 089046fa21bea..50fa3df0bc0ca 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+@@ -1085,21 +1085,21 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,
+ 	reset_ppn_array(pdesc->strsPPNs, ARRAY_SIZE(pdesc->strsPPNs));
+ 
+ 	/* Pin mksGuestStat user pages and store those in the instance descriptor */
+-	nr_pinned_stat = pin_user_pages(arg->stat, num_pages_stat, FOLL_LONGTERM, pages_stat, NULL);
++	nr_pinned_stat = pin_user_pages_fast(arg->stat, num_pages_stat, FOLL_LONGTERM, pages_stat);
+ 	if (num_pages_stat != nr_pinned_stat)
+ 		goto err_pin_stat;
+ 
+ 	for (i = 0; i < num_pages_stat; ++i)
+ 		pdesc->statPPNs[i] = page_to_pfn(pages_stat[i]);
+ 
+-	nr_pinned_info = pin_user_pages(arg->info, num_pages_info, FOLL_LONGTERM, pages_info, NULL);
++	nr_pinned_info = pin_user_pages_fast(arg->info, num_pages_info, FOLL_LONGTERM, pages_info);
+ 	if (num_pages_info != nr_pinned_info)
+ 		goto err_pin_info;
+ 
+ 	for (i = 0; i < num_pages_info; ++i)
+ 		pdesc->infoPPNs[i] = page_to_pfn(pages_info[i]);
+ 
+-	nr_pinned_strs = pin_user_pages(arg->strs, num_pages_strs, FOLL_LONGTERM, pages_strs, NULL);
++	nr_pinned_strs = pin_user_pages_fast(arg->strs, num_pages_strs, FOLL_LONGTERM, pages_strs);
+ 	if (num_pages_strs != nr_pinned_strs)
+ 		goto err_pin_strs;
+ 
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+index c89ad3a2d141c..753d421a27ad8 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+@@ -950,6 +950,10 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
+ 	struct drm_device *dev = &dev_priv->drm;
+ 	int i, ret;
+ 
++	/* Screen objects won't work if GMR's aren't available */
++	if (!dev_priv->has_gmr)
++		return -ENOSYS;
++
+ 	if (!(dev_priv->capabilities & SVGA_CAP_SCREEN_OBJECT_2)) {
+ 		return -ENOSYS;
+ 	}
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index b7f5566e338d7..e4974c27ca3d8 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1315,6 +1315,9 @@ static s32 snto32(__u32 value, unsigned n)
+ 	if (!value || !n)
+ 		return 0;
+ 
++	if (n > 32)
++		n = 32;
++
+ 	switch (n) {
+ 	case 8:  return ((__s8)value);
+ 	case 16: return ((__s16)value);
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 256795ed6247e..86e754b9400ff 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -274,6 +274,7 @@
+ #define USB_DEVICE_ID_CH_AXIS_295	0x001c
+ 
+ #define USB_VENDOR_ID_CHERRY		0x046a
++#define USB_DEVICE_ID_CHERRY_MOUSE_000C	0x000c
+ #define USB_DEVICE_ID_CHERRY_CYMOTION	0x0023
+ #define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR	0x0027
+ 
+@@ -917,6 +918,7 @@
+ #define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER	0x02fd
+ #define USB_DEVICE_ID_MS_PIXART_MOUSE    0x00cb
+ #define USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS      0x02e0
++#define USB_DEVICE_ID_MS_MOUSE_0783      0x0783
+ 
+ #define USB_VENDOR_ID_MOJO		0x8282
+ #define USB_DEVICE_ID_RETRO_ADAPTER	0x3201
+@@ -1215,6 +1217,7 @@
+ #define USB_DEVICE_ID_SYNAPTICS_DELL_K15A	0x6e21
+ #define USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1002	0x73f4
+ #define USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003	0x73f5
++#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_017	0x73f6
+ #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5	0x81a7
+ 
+ #define USB_VENDOR_ID_TEXAS_INSTRUMENTS	0x2047
+@@ -1379,6 +1382,7 @@
+ 
+ #define USB_VENDOR_ID_PRIMAX	0x0461
+ #define USB_DEVICE_ID_PRIMAX_MOUSE_4D22	0x4d22
++#define USB_DEVICE_ID_PRIMAX_MOUSE_4E2A	0x4e2a
+ #define USB_DEVICE_ID_PRIMAX_KEYBOARD	0x4e05
+ #define USB_DEVICE_ID_PRIMAX_REZEL	0x4e72
+ #define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F	0x4d0f
+diff --git a/drivers/hid/hid-ite.c b/drivers/hid/hid-ite.c
+index 430fa4f52ed3b..75ebfcf318896 100644
+--- a/drivers/hid/hid-ite.c
++++ b/drivers/hid/hid-ite.c
+@@ -121,6 +121,11 @@ static const struct hid_device_id ite_devices[] = {
+ 		     USB_VENDOR_ID_SYNAPTICS,
+ 		     USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003),
+ 	  .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT },
++	/* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */
++	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
++		     USB_VENDOR_ID_SYNAPTICS,
++		     USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_017),
++	  .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT },
+ 	{ }
+ };
+ MODULE_DEVICE_TABLE(hid, ite_devices);
+diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
+index 5e6a0cef2a06d..e3fcf1353fb3b 100644
+--- a/drivers/hid/hid-lg4ff.c
++++ b/drivers/hid/hid-lg4ff.c
+@@ -872,6 +872,12 @@ static ssize_t lg4ff_alternate_modes_store(struct device *dev, struct device_att
+ 		return -ENOMEM;
+ 
+ 	i = strlen(lbuf);
++
++	if (i == 0) {
++		kfree(lbuf);
++		return -EINVAL;
++	}
++
+ 	if (lbuf[i-1] == '\n') {
+ 		if (i == 1) {
+ 			kfree(lbuf);
+diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
+index 50e1c717fc0a3..0e9702c7f7d6c 100644
+--- a/drivers/hid/hid-quirks.c
++++ b/drivers/hid/hid-quirks.c
+@@ -54,6 +54,7 @@ static const struct hid_device_id hid_quirks[] = {
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET },
++	{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_MOUSE_000C), HID_QUIRK_ALWAYS_POLL },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS },
+@@ -122,6 +123,7 @@ static const struct hid_device_id hid_quirks[] = {
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT },
++	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_MOUSE_0783), HID_QUIRK_ALWAYS_POLL },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE3_COVER), HID_QUIRK_NO_INIT_REPORTS },
+@@ -146,6 +148,7 @@ static const struct hid_device_id hid_quirks[] = {
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN), HID_QUIRK_NO_INIT_REPORTS },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL },
++	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4E2A), HID_QUIRK_ALWAYS_POLL },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F), HID_QUIRK_ALWAYS_POLL },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D65), HID_QUIRK_ALWAYS_POLL },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22), HID_QUIRK_ALWAYS_POLL },
+diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c
+index ff46604ef1d8c..683350596ea62 100644
+--- a/drivers/hid/hid-uclogic-core.c
++++ b/drivers/hid/hid-uclogic-core.c
+@@ -192,6 +192,7 @@ static int uclogic_probe(struct hid_device *hdev,
+ 	 * than the pen, so use QUIRK_MULTI_INPUT for all tablets.
+ 	 */
+ 	hdev->quirks |= HID_QUIRK_MULTI_INPUT;
++	hdev->quirks |= HID_QUIRK_HIDINPUT_FORCE;
+ 
+ 	/* Allocate and assign driver data */
+ 	drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
+diff --git a/drivers/hid/hid-uclogic-rdesc.c b/drivers/hid/hid-uclogic-rdesc.c
+index 81ca22398ed55..ce6cf6b18ae6c 100644
+--- a/drivers/hid/hid-uclogic-rdesc.c
++++ b/drivers/hid/hid-uclogic-rdesc.c
+@@ -1119,7 +1119,7 @@ __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
+ 			   p[sizeof(btn_head)] < param_num) {
+ 			v = param_list[p[sizeof(btn_head)]];
+ 			put_unaligned((__u8)0x2A, p); /* Usage Maximum */
+-			put_unaligned_le16((__force u16)cpu_to_le16(v), p + 1);
++			put_unaligned((__force u16)cpu_to_le16(v), (s16 *)(p + 1));
+ 			p += sizeof(btn_head) + 1;
+ 		} else {
+ 			p++;
+diff --git a/drivers/hid/i2c-hid/Kconfig b/drivers/hid/i2c-hid/Kconfig
+index 5273ee2bb1343..d65abe65ce739 100644
+--- a/drivers/hid/i2c-hid/Kconfig
++++ b/drivers/hid/i2c-hid/Kconfig
+@@ -66,6 +66,6 @@ endmenu
+ 
+ config I2C_HID_CORE
+ 	tristate
+-	default y if I2C_HID_ACPI=y || I2C_HID_OF=y || I2C_HID_OF_GOODIX=y
+-	default m if I2C_HID_ACPI=m || I2C_HID_OF=m || I2C_HID_OF_GOODIX=m
++	default y if I2C_HID_ACPI=y || I2C_HID_OF=y || I2C_HID_OF_ELAN=y || I2C_HID_OF_GOODIX=y
++	default m if I2C_HID_ACPI=m || I2C_HID_OF=m || I2C_HID_OF_ELAN=m || I2C_HID_OF_GOODIX=m
+ 	select HID
+diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
+index b203c1e26353e..4eac35c4ea3b7 100644
+--- a/drivers/media/common/videobuf2/videobuf2-core.c
++++ b/drivers/media/common/videobuf2/videobuf2-core.c
+@@ -813,7 +813,13 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ 	num_buffers = max_t(unsigned int, *count, q->min_buffers_needed);
+ 	num_buffers = min_t(unsigned int, num_buffers, VB2_MAX_FRAME);
+ 	memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
++	/*
++	 * Set this now to ensure that drivers see the correct q->memory value
++	 * in the queue_setup op.
++	 */
++	mutex_lock(&q->mmap_lock);
+ 	q->memory = memory;
++	mutex_unlock(&q->mmap_lock);
+ 	set_queue_coherency(q, non_coherent_mem);
+ 
+ 	/*
+@@ -823,22 +829,27 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ 	ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
+ 		       plane_sizes, q->alloc_devs);
+ 	if (ret)
+-		return ret;
++		goto error;
+ 
+ 	/* Check that driver has set sane values */
+-	if (WARN_ON(!num_planes))
+-		return -EINVAL;
++	if (WARN_ON(!num_planes)) {
++		ret = -EINVAL;
++		goto error;
++	}
+ 
+ 	for (i = 0; i < num_planes; i++)
+-		if (WARN_ON(!plane_sizes[i]))
+-			return -EINVAL;
++		if (WARN_ON(!plane_sizes[i])) {
++			ret = -EINVAL;
++			goto error;
++		}
+ 
+ 	/* Finally, allocate buffers and video memory */
+ 	allocated_buffers =
+ 		__vb2_queue_alloc(q, memory, num_buffers, num_planes, plane_sizes);
+ 	if (allocated_buffers == 0) {
+ 		dprintk(q, 1, "memory allocation failed\n");
+-		return -ENOMEM;
++		ret = -ENOMEM;
++		goto error;
+ 	}
+ 
+ 	/*
+@@ -879,7 +890,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ 	if (ret < 0) {
+ 		/*
+ 		 * Note: __vb2_queue_free() will subtract 'allocated_buffers'
+-		 * from q->num_buffers.
++		 * from q->num_buffers and it will reset q->memory to
++		 * VB2_MEMORY_UNKNOWN.
+ 		 */
+ 		__vb2_queue_free(q, allocated_buffers);
+ 		mutex_unlock(&q->mmap_lock);
+@@ -895,6 +907,12 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
+ 	q->waiting_for_buffers = !q->is_output;
+ 
+ 	return 0;
++
++error:
++	mutex_lock(&q->mmap_lock);
++	q->memory = VB2_MEMORY_UNKNOWN;
++	mutex_unlock(&q->mmap_lock);
++	return ret;
+ }
+ EXPORT_SYMBOL_GPL(vb2_core_reqbufs);
+ 
+@@ -906,6 +924,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ 	unsigned int num_planes = 0, num_buffers, allocated_buffers;
+ 	unsigned plane_sizes[VB2_MAX_PLANES] = { };
+ 	bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT;
++	bool no_previous_buffers = !q->num_buffers;
+ 	int ret;
+ 
+ 	if (q->num_buffers == VB2_MAX_FRAME) {
+@@ -913,13 +932,19 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ 		return -ENOBUFS;
+ 	}
+ 
+-	if (!q->num_buffers) {
++	if (no_previous_buffers) {
+ 		if (q->waiting_in_dqbuf && *count) {
+ 			dprintk(q, 1, "another dup()ped fd is waiting for a buffer\n");
+ 			return -EBUSY;
+ 		}
+ 		memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
++		/*
++		 * Set this now to ensure that drivers see the correct q->memory
++		 * value in the queue_setup op.
++		 */
++		mutex_lock(&q->mmap_lock);
+ 		q->memory = memory;
++		mutex_unlock(&q->mmap_lock);
+ 		q->waiting_for_buffers = !q->is_output;
+ 		set_queue_coherency(q, non_coherent_mem);
+ 	} else {
+@@ -945,14 +970,15 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ 	ret = call_qop(q, queue_setup, q, &num_buffers,
+ 		       &num_planes, plane_sizes, q->alloc_devs);
+ 	if (ret)
+-		return ret;
++		goto error;
+ 
+ 	/* Finally, allocate buffers and video memory */
+ 	allocated_buffers = __vb2_queue_alloc(q, memory, num_buffers,
+ 				num_planes, plane_sizes);
+ 	if (allocated_buffers == 0) {
+ 		dprintk(q, 1, "memory allocation failed\n");
+-		return -ENOMEM;
++		ret = -ENOMEM;
++		goto error;
+ 	}
+ 
+ 	/*
+@@ -983,7 +1009,8 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ 	if (ret < 0) {
+ 		/*
+ 		 * Note: __vb2_queue_free() will subtract 'allocated_buffers'
+-		 * from q->num_buffers.
++		 * from q->num_buffers and it will reset q->memory to
++		 * VB2_MEMORY_UNKNOWN.
+ 		 */
+ 		__vb2_queue_free(q, allocated_buffers);
+ 		mutex_unlock(&q->mmap_lock);
+@@ -998,6 +1025,14 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
+ 	*count = allocated_buffers;
+ 
+ 	return 0;
++
++error:
++	if (no_previous_buffers) {
++		mutex_lock(&q->mmap_lock);
++		q->memory = VB2_MEMORY_UNKNOWN;
++		mutex_unlock(&q->mmap_lock);
++	}
++	return ret;
+ }
+ EXPORT_SYMBOL_GPL(vb2_core_create_bufs);
+ 
+@@ -2164,6 +2199,22 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
+ 	struct vb2_buffer *vb;
+ 	unsigned int buffer, plane;
+ 
++	/*
++	 * Sanity checks to ensure the lock is held, MEMORY_MMAP is
++	 * used and fileio isn't active.
++	 */
++	lockdep_assert_held(&q->mmap_lock);
++
++	if (q->memory != VB2_MEMORY_MMAP) {
++		dprintk(q, 1, "queue is not currently set up for mmap\n");
++		return -EINVAL;
++	}
++
++	if (vb2_fileio_is_active(q)) {
++		dprintk(q, 1, "file io in progress\n");
++		return -EBUSY;
++	}
++
+ 	/*
+ 	 * Go over all buffers and their planes, comparing the given offset
+ 	 * with an offset assigned to each plane. If a match is found,
+@@ -2265,11 +2316,6 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
+ 	int ret;
+ 	unsigned long length;
+ 
+-	if (q->memory != VB2_MEMORY_MMAP) {
+-		dprintk(q, 1, "queue is not currently set up for mmap\n");
+-		return -EINVAL;
+-	}
+-
+ 	/*
+ 	 * Check memory area access mode.
+ 	 */
+@@ -2291,14 +2337,9 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
+ 
+ 	mutex_lock(&q->mmap_lock);
+ 
+-	if (vb2_fileio_is_active(q)) {
+-		dprintk(q, 1, "mmap: file io in progress\n");
+-		ret = -EBUSY;
+-		goto unlock;
+-	}
+-
+ 	/*
+-	 * Find the plane corresponding to the offset passed by userspace.
++	 * Find the plane corresponding to the offset passed by userspace. This
++	 * will return an error if not MEMORY_MMAP or file I/O is in progress.
+ 	 */
+ 	ret = __find_plane_by_offset(q, off, &buffer, &plane);
+ 	if (ret)
+@@ -2351,22 +2392,25 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
+ 	void *vaddr;
+ 	int ret;
+ 
+-	if (q->memory != VB2_MEMORY_MMAP) {
+-		dprintk(q, 1, "queue is not currently set up for mmap\n");
+-		return -EINVAL;
+-	}
++	mutex_lock(&q->mmap_lock);
+ 
+ 	/*
+-	 * Find the plane corresponding to the offset passed by userspace.
++	 * Find the plane corresponding to the offset passed by userspace. This
++	 * will return an error if not MEMORY_MMAP or file I/O is in progress.
+ 	 */
+ 	ret = __find_plane_by_offset(q, off, &buffer, &plane);
+ 	if (ret)
+-		return ret;
++		goto unlock;
+ 
+ 	vb = q->bufs[buffer];
+ 
+ 	vaddr = vb2_plane_vaddr(vb, plane);
++	mutex_unlock(&q->mmap_lock);
+ 	return vaddr ? (unsigned long)vaddr : -EINVAL;
++
++unlock:
++	mutex_unlock(&q->mmap_lock);
++	return ret;
+ }
+ EXPORT_SYMBOL_GPL(vb2_get_unmapped_area);
+ #endif
+diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
+index 003c32fed3f75..942d0005c55e8 100644
+--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
++++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
+@@ -145,6 +145,8 @@ bool v4l2_valid_dv_timings(const struct v4l2_dv_timings *t,
+ 	const struct v4l2_bt_timings *bt = &t->bt;
+ 	const struct v4l2_bt_timings_cap *cap = &dvcap->bt;
+ 	u32 caps = cap->capabilities;
++	const u32 max_vert = 10240;
++	u32 max_hor = 3 * bt->width;
+ 
+ 	if (t->type != V4L2_DV_BT_656_1120)
+ 		return false;
+@@ -166,14 +168,20 @@ bool v4l2_valid_dv_timings(const struct v4l2_dv_timings *t,
+ 	if (!bt->interlaced &&
+ 	    (bt->il_vbackporch || bt->il_vsync || bt->il_vfrontporch))
+ 		return false;
+-	if (bt->hfrontporch > 2 * bt->width ||
+-	    bt->hsync > 1024 || bt->hbackporch > 1024)
++	/*
++	 * Some video receivers cannot properly separate the frontporch,
++	 * backporch and sync values, and instead they only have the total
++	 * blanking. That can be assigned to any of these three fields.
++	 * So just check that none of these are way out of range.
++	 */
++	if (bt->hfrontporch > max_hor ||
++	    bt->hsync > max_hor || bt->hbackporch > max_hor)
+ 		return false;
+-	if (bt->vfrontporch > 4096 ||
+-	    bt->vsync > 128 || bt->vbackporch > 4096)
++	if (bt->vfrontporch > max_vert ||
++	    bt->vsync > max_vert || bt->vbackporch > max_vert)
+ 		return false;
+-	if (bt->interlaced && (bt->il_vfrontporch > 4096 ||
+-	    bt->il_vsync > 128 || bt->il_vbackporch > 4096))
++	if (bt->interlaced && (bt->il_vfrontporch > max_vert ||
++	    bt->il_vsync > max_vert || bt->il_vbackporch > max_vert))
+ 		return false;
+ 	return fnc == NULL || fnc(t, fnc_handle);
+ }
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 76dd5ff1d99d5..c2939621b683c 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -3247,7 +3247,7 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
+ 		goto out;
+ 
+ 	saddr = &combined->ip6.saddr;
+-	daddr = &combined->ip6.saddr;
++	daddr = &combined->ip6.daddr;
+ 
+ 	slave_dbg(bond->dev, slave->dev, "%s: %s/%d av %d sv %d sip %pI6c tip %pI6c\n",
+ 		  __func__, slave->dev->name, bond_slave_state(slave),
+diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
+index ed3d0b8989a07..dc7192ecb001f 100644
+--- a/drivers/net/can/can327.c
++++ b/drivers/net/can/can327.c
+@@ -796,9 +796,9 @@ static int can327_netdev_close(struct net_device *dev)
+ 
+ 	netif_stop_queue(dev);
+ 
+-	/* Give UART one final chance to flush. */
+-	clear_bit(TTY_DO_WRITE_WAKEUP, &elm->tty->flags);
+-	flush_work(&elm->tx_work);
++	/* We don't flush the UART TX queue here, as we want final stop
++	 * commands (like the above dummy char) to be flushed out.
++	 */
+ 
+ 	can_rx_offload_disable(&elm->offload);
+ 	elm->can.state = CAN_STATE_STOPPED;
+@@ -1069,12 +1069,15 @@ static void can327_ldisc_close(struct tty_struct *tty)
+ {
+ 	struct can327 *elm = (struct can327 *)tty->disc_data;
+ 
+-	/* unregister_netdev() calls .ndo_stop() so we don't have to.
+-	 * Our .ndo_stop() also flushes the TTY write wakeup handler,
+-	 * so we can safely set elm->tty = NULL after this.
+-	 */
++	/* unregister_netdev() calls .ndo_stop() so we don't have to. */
+ 	unregister_candev(elm->dev);
+ 
++	/* Give UART one final chance to flush.
++	 * No need to clear TTY_DO_WRITE_WAKEUP since .write_wakeup() is
++	 * serialised against .close() and will not be called once we return.
++	 */
++	flush_work(&elm->tx_work);
++
+ 	/* Mark channel as dead */
+ 	spin_lock_bh(&elm->lock);
+ 	tty->disc_data = NULL;
+diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
+index fbb34139daa1a..f4db77007c134 100644
+--- a/drivers/net/can/slcan/slcan-core.c
++++ b/drivers/net/can/slcan/slcan-core.c
+@@ -864,12 +864,14 @@ static void slcan_close(struct tty_struct *tty)
+ {
+ 	struct slcan *sl = (struct slcan *)tty->disc_data;
+ 
+-	/* unregister_netdev() calls .ndo_stop() so we don't have to.
+-	 * Our .ndo_stop() also flushes the TTY write wakeup handler,
+-	 * so we can safely set sl->tty = NULL after this.
+-	 */
+ 	unregister_candev(sl->dev);
+ 
++	/*
++	 * The netdev needn't be UP (so .ndo_stop() is not called). Hence make
++	 * sure this is not running before freeing it up.
++	 */
++	flush_work(&sl->tx_work);
++
+ 	/* Mark channel as dead */
+ 	spin_lock_bh(&sl->lock);
+ 	tty->disc_data = NULL;
+diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
+index 81b88e9e5bdc0..42323f5e6f3a0 100644
+--- a/drivers/net/can/usb/esd_usb.c
++++ b/drivers/net/can/usb/esd_usb.c
+@@ -234,6 +234,10 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
+ 		u8 rxerr = msg->msg.rx.data[2];
+ 		u8 txerr = msg->msg.rx.data[3];
+ 
++		netdev_dbg(priv->netdev,
++			   "CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n",
++			   msg->msg.rx.dlc, state, ecc, rxerr, txerr);
++
+ 		skb = alloc_can_err_skb(priv->netdev, &cf);
+ 		if (skb == NULL) {
+ 			stats->rx_dropped++;
+@@ -260,6 +264,8 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
+ 				break;
+ 			default:
+ 				priv->can.state = CAN_STATE_ERROR_ACTIVE;
++				txerr = 0;
++				rxerr = 0;
+ 				break;
+ 			}
+ 		} else {
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
+index 07e9a4da924c5..546d90dae9331 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -825,10 +825,13 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
+ 
+ 	chip->info->ops->phylink_get_caps(chip, port, config);
+ 
+-	/* Internal ports need GMII for PHYLIB */
+-	if (mv88e6xxx_phy_is_internal(ds, port))
++	if (mv88e6xxx_phy_is_internal(ds, port)) {
++		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
++			  config->supported_interfaces);
++		/* Internal ports with no phy-mode need GMII for PHYLIB */
+ 		__set_bit(PHY_INTERFACE_MODE_GMII,
+ 			  config->supported_interfaces);
++	}
+ }
+ 
+ static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
+diff --git a/drivers/net/dsa/sja1105/sja1105_devlink.c b/drivers/net/dsa/sja1105/sja1105_devlink.c
+index 10c6fea1227fa..bdbbff2a79095 100644
+--- a/drivers/net/dsa/sja1105/sja1105_devlink.c
++++ b/drivers/net/dsa/sja1105/sja1105_devlink.c
+@@ -95,6 +95,8 @@ static int sja1105_setup_devlink_regions(struct dsa_switch *ds)
+ 		if (IS_ERR(region)) {
+ 			while (--i >= 0)
+ 				dsa_devlink_region_destroy(priv->regions[i]);
++
++			kfree(priv->regions);
+ 			return PTR_ERR(region);
+ 		}
+ 
+diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
+index b03d0d0c3dbf5..2cb8fa2494cbe 100644
+--- a/drivers/net/dsa/sja1105/sja1105_main.c
++++ b/drivers/net/dsa/sja1105/sja1105_main.c
+@@ -1038,7 +1038,7 @@ static int sja1105_init_l2_policing(struct sja1105_private *priv)
+ 
+ 		policing[bcast].sharindx = port;
+ 		/* Only SJA1110 has multicast policers */
+-		if (mcast <= table->ops->max_entry_count)
++		if (mcast < table->ops->max_entry_count)
+ 			policing[mcast].sharindx = port;
+ 	}
+ 
+diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c
+index 447dc64a17e5d..4ce8367bb81c2 100644
+--- a/drivers/net/ethernet/aeroflex/greth.c
++++ b/drivers/net/ethernet/aeroflex/greth.c
+@@ -258,6 +258,7 @@ static int greth_init_rings(struct greth_private *greth)
+ 			if (dma_mapping_error(greth->dev, dma_addr)) {
+ 				if (netif_msg_ifup(greth))
+ 					dev_err(greth->dev, "Could not create initial DMA mapping\n");
++				dev_kfree_skb(skb);
+ 				goto cleanup;
+ 			}
+ 			greth->rx_skbuff[i] = skb;
+diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
+index 1cd3c289f49be..cd1706909044d 100644
+--- a/drivers/net/ethernet/broadcom/Kconfig
++++ b/drivers/net/ethernet/broadcom/Kconfig
+@@ -71,13 +71,14 @@ config BCM63XX_ENET
+ config BCMGENET
+ 	tristate "Broadcom GENET internal MAC support"
+ 	depends on HAS_IOMEM
++	depends on PTP_1588_CLOCK_OPTIONAL || !ARCH_BCM2835
+ 	select MII
+ 	select PHYLIB
+ 	select FIXED_PHY
+ 	select BCM7XXX_PHY
+ 	select MDIO_BCM_UNIMAC
+ 	select DIMLIB
+-	select BROADCOM_PHY if (ARCH_BCM2835 && PTP_1588_CLOCK_OPTIONAL)
++	select BROADCOM_PHY if ARCH_BCM2835
+ 	help
+ 	  This driver supports the built-in Ethernet MACs found in the
+ 	  Broadcom BCM7xxx Set Top Box family chipset.
+diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+index 768ea426d49f4..745bd2dfb7429 100644
+--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
++++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+@@ -2240,7 +2240,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	err = register_netdev(netdev);
+ 	if (err) {
+ 		dev_err(dev, "Failed to register netdevice\n");
+-		goto err_unregister_interrupts;
++		goto err_destroy_workqueue;
+ 	}
+ 
+ 	nic->msg_enable = debug;
+@@ -2249,6 +2249,8 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 
+ 	return 0;
+ 
++err_destroy_workqueue:
++	destroy_workqueue(nic->nicvf_rx_mode_wq);
+ err_unregister_interrupts:
+ 	nicvf_unregister_interrupts(nic);
+ err_free_netdev:
+diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c
+index cacd454ac696c..c39b866e2582d 100644
+--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c
++++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c
+@@ -132,6 +132,7 @@ int dpaa2_switch_acl_entry_add(struct dpaa2_switch_filter_block *filter_block,
+ 						 DMA_TO_DEVICE);
+ 	if (unlikely(dma_mapping_error(dev, acl_entry_cfg->key_iova))) {
+ 		dev_err(dev, "DMA mapping failed\n");
++		kfree(cmd_buff);
+ 		return -EFAULT;
+ 	}
+ 
+@@ -142,6 +143,7 @@ int dpaa2_switch_acl_entry_add(struct dpaa2_switch_filter_block *filter_block,
+ 			 DMA_TO_DEVICE);
+ 	if (err) {
+ 		dev_err(dev, "dpsw_acl_add_entry() failed %d\n", err);
++		kfree(cmd_buff);
+ 		return err;
+ 	}
+ 
+@@ -172,6 +174,7 @@ dpaa2_switch_acl_entry_remove(struct dpaa2_switch_filter_block *block,
+ 						 DMA_TO_DEVICE);
+ 	if (unlikely(dma_mapping_error(dev, acl_entry_cfg->key_iova))) {
+ 		dev_err(dev, "DMA mapping failed\n");
++		kfree(cmd_buff);
+ 		return -EFAULT;
+ 	}
+ 
+@@ -182,6 +185,7 @@ dpaa2_switch_acl_entry_remove(struct dpaa2_switch_filter_block *block,
+ 			 DMA_TO_DEVICE);
+ 	if (err) {
+ 		dev_err(dev, "dpsw_acl_remove_entry() failed %d\n", err);
++		kfree(cmd_buff);
+ 		return err;
+ 	}
+ 
+diff --git a/drivers/net/ethernet/hisilicon/hisi_femac.c b/drivers/net/ethernet/hisilicon/hisi_femac.c
+index 93846bace0285..ce2571c16e431 100644
+--- a/drivers/net/ethernet/hisilicon/hisi_femac.c
++++ b/drivers/net/ethernet/hisilicon/hisi_femac.c
+@@ -283,7 +283,7 @@ static int hisi_femac_rx(struct net_device *dev, int limit)
+ 		skb->protocol = eth_type_trans(skb, dev);
+ 		napi_gro_receive(&priv->napi, skb);
+ 		dev->stats.rx_packets++;
+-		dev->stats.rx_bytes += skb->len;
++		dev->stats.rx_bytes += len;
+ next:
+ 		pos = (pos + 1) % rxq->num;
+ 		if (rx_pkts_num >= limit)
+diff --git a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
+index d7e62eca050f4..b981b6cbe6fff 100644
+--- a/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
++++ b/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c
+@@ -550,7 +550,7 @@ static int hix5hd2_rx(struct net_device *dev, int limit)
+ 		skb->protocol = eth_type_trans(skb, dev);
+ 		napi_gro_receive(&priv->napi, skb);
+ 		dev->stats.rx_packets++;
+-		dev->stats.rx_bytes += skb->len;
++		dev->stats.rx_bytes += len;
+ next:
+ 		pos = dma_ring_incr(pos, RX_DESC_NUM);
+ 	}
+diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
+index 321f2a95ae3ab..da113f5011e99 100644
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -5936,9 +5936,9 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
+ 		e1000_tx_queue(tx_ring, tx_flags, count);
+ 		/* Make sure there is space in the ring for the next send. */
+ 		e1000_maybe_stop_tx(tx_ring,
+-				    (MAX_SKB_FRAGS *
++				    ((MAX_SKB_FRAGS + 1) *
+ 				     DIV_ROUND_UP(PAGE_SIZE,
+-						  adapter->tx_fifo_limit) + 2));
++						  adapter->tx_fifo_limit) + 4));
+ 
+ 		if (!netdev_xmit_more() ||
+ 		    netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) {
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+index 6f0d4160ff82f..d9368f7669aab 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+@@ -4464,11 +4464,7 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi,
+ 			return -EOPNOTSUPP;
+ 
+ 		/* First 4 bytes of L4 header */
+-		if (usr_ip4_spec->l4_4_bytes == htonl(0xFFFFFFFF))
+-			new_mask |= I40E_L4_SRC_MASK | I40E_L4_DST_MASK;
+-		else if (!usr_ip4_spec->l4_4_bytes)
+-			new_mask &= ~(I40E_L4_SRC_MASK | I40E_L4_DST_MASK);
+-		else
++		if (usr_ip4_spec->l4_4_bytes)
+ 			return -EOPNOTSUPP;
+ 
+ 		/* Filtering on Type of Service is not supported. */
+@@ -4507,11 +4503,7 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi,
+ 		else
+ 			return -EOPNOTSUPP;
+ 
+-		if (usr_ip6_spec->l4_4_bytes == htonl(0xFFFFFFFF))
+-			new_mask |= I40E_L4_SRC_MASK | I40E_L4_DST_MASK;
+-		else if (!usr_ip6_spec->l4_4_bytes)
+-			new_mask &= ~(I40E_L4_SRC_MASK | I40E_L4_DST_MASK);
+-		else
++		if (usr_ip6_spec->l4_4_bytes)
+ 			return -EOPNOTSUPP;
+ 
+ 		/* Filtering on Traffic class is not supported. */
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index 023685cca2c1c..e53ea7ed0b1d2 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -10661,6 +10661,21 @@ static int i40e_rebuild_channels(struct i40e_vsi *vsi)
+ 	return 0;
+ }
+ 
++/**
++ * i40e_clean_xps_state - clean xps state for every tx_ring
++ * @vsi: ptr to the VSI
++ **/
++static void i40e_clean_xps_state(struct i40e_vsi *vsi)
++{
++	int i;
++
++	if (vsi->tx_rings)
++		for (i = 0; i < vsi->num_queue_pairs; i++)
++			if (vsi->tx_rings[i])
++				clear_bit(__I40E_TX_XPS_INIT_DONE,
++					  vsi->tx_rings[i]->state);
++}
++
+ /**
+  * i40e_prep_for_reset - prep for the core to reset
+  * @pf: board private structure
+@@ -10685,8 +10700,10 @@ static void i40e_prep_for_reset(struct i40e_pf *pf)
+ 	i40e_pf_quiesce_all_vsi(pf);
+ 
+ 	for (v = 0; v < pf->num_alloc_vsi; v++) {
+-		if (pf->vsi[v])
++		if (pf->vsi[v]) {
++			i40e_clean_xps_state(pf->vsi[v]);
+ 			pf->vsi[v]->seid = 0;
++		}
+ 	}
+ 
+ 	i40e_shutdown_adminq(&pf->hw);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+index 72ddcefc45b1e..635f93d603186 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -1578,6 +1578,7 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
+ 	i40e_cleanup_reset_vf(vf);
+ 
+ 	i40e_flush(hw);
++	usleep_range(20000, 40000);
+ 	clear_bit(I40E_VF_STATE_RESETTING, &vf->vf_states);
+ 
+ 	return true;
+@@ -1701,6 +1702,7 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
+ 	}
+ 
+ 	i40e_flush(hw);
++	usleep_range(20000, 40000);
+ 	clear_bit(__I40E_VF_DISABLE, pf->state);
+ 
+ 	return true;
+diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
+index c14fc871dd417..677893f891edd 100644
+--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
++++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
+@@ -1413,6 +1413,8 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
+ 			*data = 1;
+ 			return -1;
+ 		}
++		wr32(E1000_IVAR_MISC, E1000_IVAR_VALID << 8);
++		wr32(E1000_EIMS, BIT(0));
+ 	} else if (adapter->flags & IGB_FLAG_HAS_MSI) {
+ 		shared_int = false;
+ 		if (request_irq(irq,
+diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
+index 0caa2df87c044..85c93ba6a82b7 100644
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -4271,7 +4271,7 @@ static void mvneta_percpu_elect(struct mvneta_port *pp)
+ 	/* Use the cpu associated to the rxq when it is online, in all
+ 	 * the other cases, use the cpu 0 which can't be offline.
+ 	 */
+-	if (cpu_online(pp->rxq_def))
++	if (pp->rxq_def < nr_cpu_ids && cpu_online(pp->rxq_def))
+ 		elected_cpu = pp->rxq_def;
+ 
+ 	max_cpu = num_present_cpus();
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
+index e64318c110fdd..6a01ab1a6e6f3 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
+@@ -1134,7 +1134,12 @@ int otx2_init_tc(struct otx2_nic *nic)
+ 		return err;
+ 
+ 	tc->flow_ht_params = tc_flow_ht_params;
+-	return rhashtable_init(&tc->flow_table, &tc->flow_ht_params);
++	err = rhashtable_init(&tc->flow_table, &tc->flow_ht_params);
++	if (err) {
++		kfree(tc->tc_entries_bitmap);
++		tc->tc_entries_bitmap = NULL;
++	}
++	return err;
+ }
+ EXPORT_SYMBOL(otx2_init_tc);
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+index 48f86e12f5c05..bbe810f3b373a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+@@ -201,9 +201,8 @@ static void mlx5_ldev_free(struct kref *ref)
+ 	if (ldev->nb.notifier_call)
+ 		unregister_netdevice_notifier_net(&init_net, &ldev->nb);
+ 	mlx5_lag_mp_cleanup(ldev);
+-	mlx5_lag_mpesw_cleanup(ldev);
+-	cancel_work_sync(&ldev->mpesw_work);
+ 	destroy_workqueue(ldev->wq);
++	mlx5_lag_mpesw_cleanup(ldev);
+ 	mutex_destroy(&ldev->lock);
+ 	kfree(ldev);
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
+index ce2ce8ccbd70e..f30ac2de639f9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h
+@@ -50,6 +50,19 @@ struct lag_tracker {
+ 	enum netdev_lag_hash hash_type;
+ };
+ 
++enum mpesw_op {
++	MLX5_MPESW_OP_ENABLE,
++	MLX5_MPESW_OP_DISABLE,
++};
++
++struct mlx5_mpesw_work_st {
++	struct work_struct work;
++	struct mlx5_lag    *lag;
++	enum mpesw_op	   op;
++	struct completion  comp;
++	int result;
++};
++
+ /* LAG data of a ConnectX card.
+  * It serves both its phys functions.
+  */
+@@ -66,7 +79,6 @@ struct mlx5_lag {
+ 	struct lag_tracker        tracker;
+ 	struct workqueue_struct   *wq;
+ 	struct delayed_work       bond_work;
+-	struct work_struct	  mpesw_work;
+ 	struct notifier_block     nb;
+ 	struct lag_mp             lag_mp;
+ 	struct mlx5_lag_port_sel  port_sel;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
+index f643202b29c6c..c17e8f1ec9146 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
+@@ -7,63 +7,95 @@
+ #include "eswitch.h"
+ #include "lib/mlx5.h"
+ 
+-void mlx5_mpesw_work(struct work_struct *work)
++static int add_mpesw_rule(struct mlx5_lag *ldev)
+ {
+-	struct mlx5_lag *ldev = container_of(work, struct mlx5_lag, mpesw_work);
++	struct mlx5_core_dev *dev = ldev->pf[MLX5_LAG_P1].dev;
++	int err;
+ 
+-	mutex_lock(&ldev->lock);
+-	mlx5_disable_lag(ldev);
+-	mutex_unlock(&ldev->lock);
+-}
++	if (atomic_add_return(1, &ldev->lag_mpesw.mpesw_rule_count) != 1)
++		return 0;
+ 
+-static void mlx5_lag_disable_mpesw(struct mlx5_core_dev *dev)
+-{
+-	struct mlx5_lag *ldev = dev->priv.lag;
++	if (ldev->mode != MLX5_LAG_MODE_NONE) {
++		err = -EINVAL;
++		goto out_err;
++	}
+ 
+-	if (!queue_work(ldev->wq, &ldev->mpesw_work))
+-		mlx5_core_warn(dev, "failed to queue work\n");
++	err = mlx5_activate_lag(ldev, NULL, MLX5_LAG_MODE_MPESW, false);
++	if (err) {
++		mlx5_core_warn(dev, "Failed to create LAG in MPESW mode (%d)\n", err);
++		goto out_err;
++	}
++
++	return 0;
++
++out_err:
++	atomic_dec(&ldev->lag_mpesw.mpesw_rule_count);
++	return err;
+ }
+ 
+-void mlx5_lag_del_mpesw_rule(struct mlx5_core_dev *dev)
++static void del_mpesw_rule(struct mlx5_lag *ldev)
+ {
+-	struct mlx5_lag *ldev = dev->priv.lag;
++	if (!atomic_dec_return(&ldev->lag_mpesw.mpesw_rule_count) &&
++	    ldev->mode == MLX5_LAG_MODE_MPESW)
++		mlx5_disable_lag(ldev);
++}
+ 
+-	if (!ldev)
+-		return;
++static void mlx5_mpesw_work(struct work_struct *work)
++{
++	struct mlx5_mpesw_work_st *mpesww = container_of(work, struct mlx5_mpesw_work_st, work);
++	struct mlx5_lag *ldev = mpesww->lag;
+ 
+ 	mutex_lock(&ldev->lock);
+-	if (!atomic_dec_return(&ldev->lag_mpesw.mpesw_rule_count) &&
+-	    ldev->mode == MLX5_LAG_MODE_MPESW)
+-		mlx5_lag_disable_mpesw(dev);
++	if (mpesww->op == MLX5_MPESW_OP_ENABLE)
++		mpesww->result = add_mpesw_rule(ldev);
++	else if (mpesww->op == MLX5_MPESW_OP_DISABLE)
++		del_mpesw_rule(ldev);
+ 	mutex_unlock(&ldev->lock);
++
++	complete(&mpesww->comp);
+ }
+ 
+-int mlx5_lag_add_mpesw_rule(struct mlx5_core_dev *dev)
++static int mlx5_lag_mpesw_queue_work(struct mlx5_core_dev *dev,
++				     enum mpesw_op op)
+ {
+ 	struct mlx5_lag *ldev = dev->priv.lag;
++	struct mlx5_mpesw_work_st *work;
+ 	int err = 0;
+ 
+ 	if (!ldev)
+ 		return 0;
+ 
+-	mutex_lock(&ldev->lock);
+-	if (atomic_add_return(1, &ldev->lag_mpesw.mpesw_rule_count) != 1)
+-		goto out;
++	work = kzalloc(sizeof(*work), GFP_KERNEL);
++	if (!work)
++		return -ENOMEM;
+ 
+-	if (ldev->mode != MLX5_LAG_MODE_NONE) {
++	INIT_WORK(&work->work, mlx5_mpesw_work);
++	init_completion(&work->comp);
++	work->op = op;
++	work->lag = ldev;
++
++	if (!queue_work(ldev->wq, &work->work)) {
++		mlx5_core_warn(dev, "failed to queue mpesw work\n");
+ 		err = -EINVAL;
+ 		goto out;
+ 	}
+-
+-	err = mlx5_activate_lag(ldev, NULL, MLX5_LAG_MODE_MPESW, false);
+-	if (err)
+-		mlx5_core_warn(dev, "Failed to create LAG in MPESW mode (%d)\n", err);
+-
++	wait_for_completion(&work->comp);
++	err = work->result;
+ out:
+-	mutex_unlock(&ldev->lock);
++	kfree(work);
+ 	return err;
+ }
+ 
++void mlx5_lag_del_mpesw_rule(struct mlx5_core_dev *dev)
++{
++	mlx5_lag_mpesw_queue_work(dev, MLX5_MPESW_OP_DISABLE);
++}
++
++int mlx5_lag_add_mpesw_rule(struct mlx5_core_dev *dev)
++{
++	return mlx5_lag_mpesw_queue_work(dev, MLX5_MPESW_OP_ENABLE);
++}
++
+ int mlx5_lag_do_mirred(struct mlx5_core_dev *mdev, struct net_device *out_dev)
+ {
+ 	struct mlx5_lag *ldev = mdev->priv.lag;
+@@ -71,12 +103,9 @@ int mlx5_lag_do_mirred(struct mlx5_core_dev *mdev, struct net_device *out_dev)
+ 	if (!netif_is_bond_master(out_dev) || !ldev)
+ 		return 0;
+ 
+-	mutex_lock(&ldev->lock);
+-	if (ldev->mode == MLX5_LAG_MODE_MPESW) {
+-		mutex_unlock(&ldev->lock);
++	if (ldev->mode == MLX5_LAG_MODE_MPESW)
+ 		return -EOPNOTSUPP;
+-	}
+-	mutex_unlock(&ldev->lock);
++
+ 	return 0;
+ }
+ 
+@@ -90,11 +119,10 @@ bool mlx5_lag_mpesw_is_activated(struct mlx5_core_dev *dev)
+ 
+ void mlx5_lag_mpesw_init(struct mlx5_lag *ldev)
+ {
+-	INIT_WORK(&ldev->mpesw_work, mlx5_mpesw_work);
+ 	atomic_set(&ldev->lag_mpesw.mpesw_rule_count, 0);
+ }
+ 
+ void mlx5_lag_mpesw_cleanup(struct mlx5_lag *ldev)
+ {
+-	cancel_delayed_work_sync(&ldev->bond_work);
++	WARN_ON(atomic_read(&ldev->lag_mpesw.mpesw_rule_count));
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h
+index be4abcb8fcd5b..88e8daffcf92e 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h
+@@ -12,7 +12,6 @@ struct lag_mpesw {
+ 	atomic_t mpesw_rule_count;
+ };
+ 
+-void mlx5_mpesw_work(struct work_struct *work);
+ int mlx5_lag_do_mirred(struct mlx5_core_dev *mdev, struct net_device *out_dev);
+ bool mlx5_lag_mpesw_is_activated(struct mlx5_core_dev *dev);
+ #if IS_ENABLED(CONFIG_MLX5_ESWITCH)
+diff --git a/drivers/net/ethernet/microchip/encx24j600-regmap.c b/drivers/net/ethernet/microchip/encx24j600-regmap.c
+index 81a8ccca7e5e0..5693784eec5bc 100644
+--- a/drivers/net/ethernet/microchip/encx24j600-regmap.c
++++ b/drivers/net/ethernet/microchip/encx24j600-regmap.c
+@@ -359,7 +359,7 @@ static int regmap_encx24j600_phy_reg_read(void *context, unsigned int reg,
+ 		goto err_out;
+ 
+ 	usleep_range(26, 100);
+-	while ((ret = regmap_read(ctx->regmap, MISTAT, &mistat) != 0) &&
++	while (((ret = regmap_read(ctx->regmap, MISTAT, &mistat)) == 0) &&
+ 	       (mistat & BUSY))
+ 		cpu_relax();
+ 
+@@ -397,7 +397,7 @@ static int regmap_encx24j600_phy_reg_write(void *context, unsigned int reg,
+ 		goto err_out;
+ 
+ 	usleep_range(26, 100);
+-	while ((ret = regmap_read(ctx->regmap, MISTAT, &mistat) != 0) &&
++	while (((ret = regmap_read(ctx->regmap, MISTAT, &mistat)) == 0) &&
+ 	       (mistat & BUSY))
+ 		cpu_relax();
+ 
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
+index 66360c8c5a38c..141897dfe3881 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
+@@ -317,7 +317,7 @@ int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb)
+ 	next_dcb_hw = sparx5_fdma_next_dcb(tx, tx->curr_entry);
+ 	db_hw = &next_dcb_hw->db[0];
+ 	if (!(db_hw->status & FDMA_DCB_STATUS_DONE))
+-		tx->dropped++;
++		return -EINVAL;
+ 	db = list_first_entry(&tx->db_list, struct sparx5_db, list);
+ 	list_move_tail(&db->list, &tx->db_list);
+ 	next_dcb_hw->nextptr = FDMA_DCB_INVALID_DATA;
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+index 30815c0e3f76a..e58de119186a6 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+@@ -876,6 +876,8 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
+ 
+ cleanup_ports:
+ 	sparx5_cleanup_ports(sparx5);
++	if (sparx5->mact_queue)
++		destroy_workqueue(sparx5->mact_queue);
+ cleanup_config:
+ 	kfree(configs);
+ cleanup_pnode:
+@@ -900,6 +902,7 @@ static int mchp_sparx5_remove(struct platform_device *pdev)
+ 	sparx5_cleanup_ports(sparx5);
+ 	/* Unregister netdevs */
+ 	sparx5_unregister_notifier_blocks(sparx5);
++	destroy_workqueue(sparx5->mact_queue);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
+index 21844beba72df..0ce0fc9852227 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
+@@ -234,9 +234,8 @@ int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
+ 	sparx5_set_port_ifh(ifh, port->portno);
+ 
+ 	if (sparx5->ptp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+-		ret = sparx5_ptp_txtstamp_request(port, skb);
+-		if (ret)
+-			return ret;
++		if (sparx5_ptp_txtstamp_request(port, skb) < 0)
++			return NETDEV_TX_BUSY;
+ 
+ 		sparx5_set_port_ifh_rew_op(ifh, SPARX5_SKB_CB(skb)->rew_op);
+ 		sparx5_set_port_ifh_pdu_type(ifh, SPARX5_SKB_CB(skb)->pdu_type);
+@@ -250,23 +249,31 @@ int sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
+ 	else
+ 		ret = sparx5_inject(sparx5, ifh, skb, dev);
+ 
+-	if (ret == NETDEV_TX_OK) {
+-		stats->tx_bytes += skb->len;
+-		stats->tx_packets++;
++	if (ret == -EBUSY)
++		goto busy;
++	if (ret < 0)
++		goto drop;
+ 
+-		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
+-		    SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
+-			return ret;
++	stats->tx_bytes += skb->len;
++	stats->tx_packets++;
++	sparx5->tx.packets++;
+ 
+-		dev_kfree_skb_any(skb);
+-	} else {
+-		stats->tx_dropped++;
++	if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
++	    SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
++		return NETDEV_TX_OK;
+ 
+-		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
+-		    SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
+-			sparx5_ptp_txtstamp_release(port, skb);
+-	}
+-	return ret;
++	dev_consume_skb_any(skb);
++	return NETDEV_TX_OK;
++drop:
++	stats->tx_dropped++;
++	sparx5->tx.dropped++;
++	dev_kfree_skb_any(skb);
++	return NETDEV_TX_OK;
++busy:
++	if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
++	    SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
++		sparx5_ptp_txtstamp_release(port, skb);
++	return NETDEV_TX_BUSY;
+ }
+ 
+ static enum hrtimer_restart sparx5_injection_timeout(struct hrtimer *tmr)
+diff --git a/drivers/net/ethernet/microsoft/mana/gdma.h b/drivers/net/ethernet/microsoft/mana/gdma.h
+index 4a6efe6ada080..65c24ee49efd9 100644
+--- a/drivers/net/ethernet/microsoft/mana/gdma.h
++++ b/drivers/net/ethernet/microsoft/mana/gdma.h
+@@ -498,7 +498,14 @@ enum {
+ 
+ #define GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT BIT(0)
+ 
+-#define GDMA_DRV_CAP_FLAGS1 GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT
++/* Advertise to the NIC firmware: the NAPI work_done variable race is fixed,
++ * so the driver is able to reliably support features like busy_poll.
++ */
++#define GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX BIT(2)
++
++#define GDMA_DRV_CAP_FLAGS1 \
++	(GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \
++	 GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX)
+ 
+ #define GDMA_DRV_CAP_FLAGS2 0
+ 
+diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
+index 9259a74eca40b..27a0f3af8aab4 100644
+--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
+@@ -1303,10 +1303,11 @@ static void mana_poll_rx_cq(struct mana_cq *cq)
+ 		xdp_do_flush();
+ }
+ 
+-static void mana_cq_handler(void *context, struct gdma_queue *gdma_queue)
++static int mana_cq_handler(void *context, struct gdma_queue *gdma_queue)
+ {
+ 	struct mana_cq *cq = context;
+ 	u8 arm_bit;
++	int w;
+ 
+ 	WARN_ON_ONCE(cq->gdma_cq != gdma_queue);
+ 
+@@ -1315,26 +1316,31 @@ static void mana_cq_handler(void *context, struct gdma_queue *gdma_queue)
+ 	else
+ 		mana_poll_tx_cq(cq);
+ 
+-	if (cq->work_done < cq->budget &&
+-	    napi_complete_done(&cq->napi, cq->work_done)) {
++	w = cq->work_done;
++
++	if (w < cq->budget &&
++	    napi_complete_done(&cq->napi, w)) {
+ 		arm_bit = SET_ARM_BIT;
+ 	} else {
+ 		arm_bit = 0;
+ 	}
+ 
+ 	mana_gd_ring_cq(gdma_queue, arm_bit);
++
++	return w;
+ }
+ 
+ static int mana_poll(struct napi_struct *napi, int budget)
+ {
+ 	struct mana_cq *cq = container_of(napi, struct mana_cq, napi);
++	int w;
+ 
+ 	cq->work_done = 0;
+ 	cq->budget = budget;
+ 
+-	mana_cq_handler(cq, cq->gdma_cq);
++	w = mana_cq_handler(cq, cq->gdma_cq);
+ 
+-	return min(cq->work_done, budget);
++	return min(w, budget);
+ }
+ 
+ static void mana_schedule_napi(void *context, struct gdma_queue *gdma_queue)
+diff --git a/drivers/net/ethernet/netronome/nfp/nfdk/dp.c b/drivers/net/ethernet/netronome/nfp/nfdk/dp.c
+index 2b427d8ccb2f3..ccacb6ab6c39f 100644
+--- a/drivers/net/ethernet/netronome/nfp/nfdk/dp.c
++++ b/drivers/net/ethernet/netronome/nfp/nfdk/dp.c
+@@ -282,7 +282,7 @@ netdev_tx_t nfp_nfdk_tx(struct sk_buff *skb, struct net_device *netdev)
+ 	dma_len = skb_headlen(skb);
+ 	if (skb_is_gso(skb))
+ 		type = NFDK_DESC_TX_TYPE_TSO;
+-	else if (!nr_frags && dma_len < NFDK_TX_MAX_DATA_PER_HEAD)
++	else if (!nr_frags && dma_len <= NFDK_TX_MAX_DATA_PER_HEAD)
+ 		type = NFDK_DESC_TX_TYPE_SIMPLE;
+ 	else
+ 		type = NFDK_DESC_TX_TYPE_GATHER;
+@@ -927,7 +927,7 @@ nfp_nfdk_tx_xdp_buf(struct nfp_net_dp *dp, struct nfp_net_rx_ring *rx_ring,
+ 	dma_len = pkt_len;
+ 	dma_addr = rxbuf->dma_addr + dma_off;
+ 
+-	if (dma_len < NFDK_TX_MAX_DATA_PER_HEAD)
++	if (dma_len <= NFDK_TX_MAX_DATA_PER_HEAD)
+ 		type = NFDK_DESC_TX_TYPE_SIMPLE;
+ 	else
+ 		type = NFDK_DESC_TX_TYPE_GATHER;
+@@ -1325,7 +1325,7 @@ nfp_nfdk_ctrl_tx_one(struct nfp_net *nn, struct nfp_net_r_vector *r_vec,
+ 	txbuf = &tx_ring->ktxbufs[wr_idx];
+ 
+ 	dma_len = skb_headlen(skb);
+-	if (dma_len < NFDK_TX_MAX_DATA_PER_HEAD)
++	if (dma_len <= NFDK_TX_MAX_DATA_PER_HEAD)
+ 		type = NFDK_DESC_TX_TYPE_SIMPLE;
+ 	else
+ 		type = NFDK_DESC_TX_TYPE_GATHER;
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 44f9b31f8b99b..77d4f3eab9715 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -835,7 +835,7 @@ static bool ravb_rx_gbeth(struct net_device *ndev, int *quota, int q)
+ 				napi_gro_receive(&priv->napi[q],
+ 						 priv->rx_1st_skb);
+ 				stats->rx_packets++;
+-				stats->rx_bytes += priv->rx_1st_skb->len;
++				stats->rx_bytes += pkt_len;
+ 				break;
+ 			}
+ 		}
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+index 9f5cac4000da6..5c234a8158c71 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+@@ -108,10 +108,10 @@ static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
+ 
+ 	axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
+ 	axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
+-	axi->axi_kbbe = of_property_read_bool(np, "snps,axi_kbbe");
+-	axi->axi_fb = of_property_read_bool(np, "snps,axi_fb");
+-	axi->axi_mb = of_property_read_bool(np, "snps,axi_mb");
+-	axi->axi_rb =  of_property_read_bool(np, "snps,axi_rb");
++	axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe");
++	axi->axi_fb = of_property_read_bool(np, "snps,fb");
++	axi->axi_mb = of_property_read_bool(np, "snps,mb");
++	axi->axi_rb =  of_property_read_bool(np, "snps,rb");
+ 
+ 	if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
+ 		axi->axi_wr_osr_lmt = 1;
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 95baacd6c7610..47da11b9ac286 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -1450,7 +1450,7 @@ static void am65_cpsw_nuss_mac_link_up(struct phylink_config *config, struct phy
+ 
+ 	if (speed == SPEED_1000)
+ 		mac_control |= CPSW_SL_CTL_GIG;
+-	if (speed == SPEED_10 && interface == PHY_INTERFACE_MODE_RGMII)
++	if (speed == SPEED_10 && phy_interface_mode_is_rgmii(interface))
+ 		/* Can be used with in band mode only */
+ 		mac_control |= CPSW_SL_CTL_EXT_EN;
+ 	if (speed == SPEED_100 && interface == PHY_INTERFACE_MODE_RMII)
+diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c
+index 450b16ad40a41..e1a569b99e4a6 100644
+--- a/drivers/net/ieee802154/ca8210.c
++++ b/drivers/net/ieee802154/ca8210.c
+@@ -885,7 +885,7 @@ static int ca8210_spi_transfer(
+ 
+ 	dev_dbg(&spi->dev, "%s called\n", __func__);
+ 
+-	cas_ctl = kmalloc(sizeof(*cas_ctl), GFP_ATOMIC);
++	cas_ctl = kzalloc(sizeof(*cas_ctl), GFP_ATOMIC);
+ 	if (!cas_ctl)
+ 		return -ENOMEM;
+ 
+diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c
+index c69b87d3837da..edc769daad077 100644
+--- a/drivers/net/ieee802154/cc2520.c
++++ b/drivers/net/ieee802154/cc2520.c
+@@ -970,7 +970,7 @@ static int cc2520_hw_init(struct cc2520_private *priv)
+ 
+ 		if (timeout-- <= 0) {
+ 			dev_err(&priv->spi->dev, "oscillator start failed!\n");
+-			return ret;
++			return -ETIMEDOUT;
+ 		}
+ 		udelay(1);
+ 	} while (!(status & CC2520_STATUS_XOSC32M_STABLE));
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 104fc564a766e..8dafc814282cb 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -3720,6 +3720,7 @@ static const struct nla_policy macsec_rtnl_policy[IFLA_MACSEC_MAX + 1] = {
+ 	[IFLA_MACSEC_SCB] = { .type = NLA_U8 },
+ 	[IFLA_MACSEC_REPLAY_PROTECT] = { .type = NLA_U8 },
+ 	[IFLA_MACSEC_VALIDATION] = { .type = NLA_U8 },
++	[IFLA_MACSEC_OFFLOAD] = { .type = NLA_U8 },
+ };
+ 
+ static void macsec_free_netdev(struct net_device *dev)
+diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
+index 40e745a1d1854..2c47efdae73b4 100644
+--- a/drivers/net/mdio/fwnode_mdio.c
++++ b/drivers/net/mdio/fwnode_mdio.c
+@@ -77,6 +77,7 @@ int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
+ 	 */
+ 	rc = phy_device_register(phy);
+ 	if (rc) {
++		device_set_node(&phy->mdio.dev, NULL);
+ 		fwnode_handle_put(child);
+ 		return rc;
+ 	}
+@@ -110,8 +111,8 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
+ 	else
+ 		phy = phy_device_create(bus, addr, phy_id, 0, NULL);
+ 	if (IS_ERR(phy)) {
+-		unregister_mii_timestamper(mii_ts);
+-		return PTR_ERR(phy);
++		rc = PTR_ERR(phy);
++		goto clean_mii_ts;
+ 	}
+ 
+ 	if (is_acpi_node(child)) {
+@@ -125,17 +126,14 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
+ 		/* All data is now stored in the phy struct, so register it */
+ 		rc = phy_device_register(phy);
+ 		if (rc) {
+-			phy_device_free(phy);
+-			fwnode_handle_put(phy->mdio.dev.fwnode);
+-			return rc;
++			phy->mdio.dev.fwnode = NULL;
++			fwnode_handle_put(child);
++			goto clean_phy;
+ 		}
+ 	} else if (is_of_node(child)) {
+ 		rc = fwnode_mdiobus_phy_device_register(bus, phy, child, addr);
+-		if (rc) {
+-			unregister_mii_timestamper(mii_ts);
+-			phy_device_free(phy);
+-			return rc;
+-		}
++		if (rc)
++			goto clean_phy;
+ 	}
+ 
+ 	/* phy->mii_ts may already be defined by the PHY driver. A
+@@ -145,5 +143,12 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
+ 	if (mii_ts)
+ 		phy->mii_ts = mii_ts;
+ 	return 0;
++
++clean_phy:
++	phy_device_free(phy);
++clean_mii_ts:
++	unregister_mii_timestamper(mii_ts);
++
++	return rc;
+ }
+ EXPORT_SYMBOL(fwnode_mdiobus_register_phy);
+diff --git a/drivers/net/mdio/of_mdio.c b/drivers/net/mdio/of_mdio.c
+index 796e9c7857d09..510822d6d0d90 100644
+--- a/drivers/net/mdio/of_mdio.c
++++ b/drivers/net/mdio/of_mdio.c
+@@ -68,8 +68,9 @@ static int of_mdiobus_register_device(struct mii_bus *mdio,
+ 	/* All data is now stored in the mdiodev struct; register it. */
+ 	rc = mdio_device_register(mdiodev);
+ 	if (rc) {
++		device_set_node(&mdiodev->dev, NULL);
++		fwnode_handle_put(fwnode);
+ 		mdio_device_free(mdiodev);
+-		of_node_put(child);
+ 		return rc;
+ 	}
+ 
+diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c
+index 250742ffdfd91..044828d081d22 100644
+--- a/drivers/net/phy/mdio_device.c
++++ b/drivers/net/phy/mdio_device.c
+@@ -21,6 +21,7 @@
+ #include <linux/slab.h>
+ #include <linux/string.h>
+ #include <linux/unistd.h>
++#include <linux/property.h>
+ 
+ void mdio_device_free(struct mdio_device *mdiodev)
+ {
+@@ -30,6 +31,7 @@ EXPORT_SYMBOL(mdio_device_free);
+ 
+ static void mdio_device_release(struct device *dev)
+ {
++	fwnode_handle_put(dev->fwnode);
+ 	kfree(to_mdio_device(dev));
+ }
+ 
+diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c
+index 24bae27eedefa..cae24091fb6f7 100644
+--- a/drivers/net/phy/mxl-gpy.c
++++ b/drivers/net/phy/mxl-gpy.c
+@@ -9,6 +9,7 @@
+ #include <linux/module.h>
+ #include <linux/bitfield.h>
+ #include <linux/hwmon.h>
++#include <linux/mutex.h>
+ #include <linux/phy.h>
+ #include <linux/polynomial.h>
+ #include <linux/netdevice.h>
+@@ -70,6 +71,14 @@
+ #define VPSPEC1_TEMP_STA	0x0E
+ #define VPSPEC1_TEMP_STA_DATA	GENMASK(9, 0)
+ 
++/* Mailbox */
++#define VSPEC1_MBOX_DATA	0x5
++#define VSPEC1_MBOX_ADDRLO	0x6
++#define VSPEC1_MBOX_CMD		0x7
++#define VSPEC1_MBOX_CMD_ADDRHI	GENMASK(7, 0)
++#define VSPEC1_MBOX_CMD_RD	(0 << 8)
++#define VSPEC1_MBOX_CMD_READY	BIT(15)
++
+ /* WoL */
+ #define VPSPEC2_WOL_CTL		0x0E06
+ #define VPSPEC2_WOL_AD01	0x0E08
+@@ -77,7 +86,13 @@
+ #define VPSPEC2_WOL_AD45	0x0E0A
+ #define WOL_EN			BIT(0)
+ 
++/* Internal registers, access via mbox */
++#define REG_GPIO0_OUT		0xd3ce00
++
+ struct gpy_priv {
++	/* serialize mailbox acesses */
++	struct mutex mbox_lock;
++
+ 	u8 fw_major;
+ 	u8 fw_minor;
+ };
+@@ -187,6 +202,45 @@ static int gpy_hwmon_register(struct phy_device *phydev)
+ }
+ #endif
+ 
++static int gpy_mbox_read(struct phy_device *phydev, u32 addr)
++{
++	struct gpy_priv *priv = phydev->priv;
++	int val, ret;
++	u16 cmd;
++
++	mutex_lock(&priv->mbox_lock);
++
++	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_ADDRLO,
++			    addr);
++	if (ret)
++		goto out;
++
++	cmd = VSPEC1_MBOX_CMD_RD;
++	cmd |= FIELD_PREP(VSPEC1_MBOX_CMD_ADDRHI, addr >> 16);
++
++	ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_CMD, cmd);
++	if (ret)
++		goto out;
++
++	/* The mbox read is used in the interrupt workaround. It was observed
++	 * that a read might take up to 2.5ms. This is also the time for which
++	 * the interrupt line is stuck low. To be on the safe side, poll the
++	 * ready bit for 10ms.
++	 */
++	ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
++					VSPEC1_MBOX_CMD, val,
++					(val & VSPEC1_MBOX_CMD_READY),
++					500, 10000, false);
++	if (ret)
++		goto out;
++
++	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_DATA);
++
++out:
++	mutex_unlock(&priv->mbox_lock);
++	return ret;
++}
++
+ static int gpy_config_init(struct phy_device *phydev)
+ {
+ 	int ret;
+@@ -201,6 +255,13 @@ static int gpy_config_init(struct phy_device *phydev)
+ 	return ret < 0 ? ret : 0;
+ }
+ 
++static bool gpy_has_broken_mdint(struct phy_device *phydev)
++{
++	/* At least these PHYs are known to have broken interrupt handling */
++	return phydev->drv->phy_id == PHY_ID_GPY215B ||
++	       phydev->drv->phy_id == PHY_ID_GPY215C;
++}
++
+ static int gpy_probe(struct phy_device *phydev)
+ {
+ 	struct device *dev = &phydev->mdio.dev;
+@@ -218,6 +279,7 @@ static int gpy_probe(struct phy_device *phydev)
+ 	if (!priv)
+ 		return -ENOMEM;
+ 	phydev->priv = priv;
++	mutex_init(&priv->mbox_lock);
+ 
+ 	fw_version = phy_read(phydev, PHY_FWV);
+ 	if (fw_version < 0)
+@@ -492,6 +554,29 @@ static irqreturn_t gpy_handle_interrupt(struct phy_device *phydev)
+ 	if (!(reg & PHY_IMASK_MASK))
+ 		return IRQ_NONE;
+ 
++	/* The PHY might leave the interrupt line asserted even after PHY_ISTAT
++	 * is read. To avoid interrupt storms, delay the interrupt handling as
++	 * long as the PHY drives the interrupt line. An internal bus read will
++	 * stall as long as the interrupt line is asserted, thus just read a
++	 * random register here.
++	 * Because we cannot access the internal bus at all while the interrupt
++	 * is driven by the PHY, there is no way to make the interrupt line
++	 * unstuck (e.g. by changing the pinmux to GPIO input) during that time
++	 * frame. Therefore, polling is the best we can do and won't do any more
++	 * harm.
++	 * It was observed that this bug happens on link state and link speed
++	 * changes on a GPY215B and GYP215C independent of the firmware version
++	 * (which doesn't mean that this list is exhaustive).
++	 */
++	if (gpy_has_broken_mdint(phydev) &&
++	    (reg & (PHY_IMASK_LSTC | PHY_IMASK_LSPC))) {
++		reg = gpy_mbox_read(phydev, REG_GPIO0_OUT);
++		if (reg < 0) {
++			phy_error(phydev);
++			return IRQ_NONE;
++		}
++	}
++
+ 	phy_trigger_machine(phydev);
+ 
+ 	return IRQ_HANDLED;
+diff --git a/drivers/net/plip/plip.c b/drivers/net/plip/plip.c
+index c8791e9b451d2..40ce8abe69995 100644
+--- a/drivers/net/plip/plip.c
++++ b/drivers/net/plip/plip.c
+@@ -450,12 +450,12 @@ plip_bh_timeout_error(struct net_device *dev, struct net_local *nl,
+ 	}
+ 	rcv->state = PLIP_PK_DONE;
+ 	if (rcv->skb) {
+-		kfree_skb(rcv->skb);
++		dev_kfree_skb_irq(rcv->skb);
+ 		rcv->skb = NULL;
+ 	}
+ 	snd->state = PLIP_PK_DONE;
+ 	if (snd->skb) {
+-		dev_kfree_skb(snd->skb);
++		dev_consume_skb_irq(snd->skb);
+ 		snd->skb = NULL;
+ 	}
+ 	spin_unlock_irq(&nl->lock);
+diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c
+index 8391f83034992..1f4dcadc284c8 100644
+--- a/drivers/net/thunderbolt.c
++++ b/drivers/net/thunderbolt.c
+@@ -902,6 +902,7 @@ static int tbnet_open(struct net_device *dev)
+ 				tbnet_start_poll, net);
+ 	if (!ring) {
+ 		netdev_err(dev, "failed to allocate Rx ring\n");
++		tb_xdomain_release_out_hopid(xd, hopid);
+ 		tb_ring_free(net->tx_ring.ring);
+ 		net->tx_ring.ring = NULL;
+ 		return -ENOMEM;
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index afd6faa4c2ec9..554d4e2a84a4e 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1423,6 +1423,7 @@ static const struct usb_device_id products[] = {
+ 	{QMI_FIXED_INTF(0x0489, 0xe0b4, 0)},	/* Foxconn T77W968 LTE */
+ 	{QMI_FIXED_INTF(0x0489, 0xe0b5, 0)},	/* Foxconn T77W968 LTE with eSIM support*/
+ 	{QMI_FIXED_INTF(0x2692, 0x9025, 4)},    /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */
++	{QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)},	/* u-blox LARA-L6 */
+ 
+ 	/* 4. Gobi 1000 devices */
+ 	{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */
+diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
+index 53b3b241e0278..c28c4a654615c 100644
+--- a/drivers/net/vmxnet3/vmxnet3_drv.c
++++ b/drivers/net/vmxnet3/vmxnet3_drv.c
+@@ -75,8 +75,14 @@ vmxnet3_enable_all_intrs(struct vmxnet3_adapter *adapter)
+ 
+ 	for (i = 0; i < adapter->intr.num_intrs; i++)
+ 		vmxnet3_enable_intr(adapter, i);
+-	adapter->shared->devRead.intrConf.intrCtrl &=
++	if (!VMXNET3_VERSION_GE_6(adapter) ||
++	    !adapter->queuesExtEnabled) {
++		adapter->shared->devRead.intrConf.intrCtrl &=
++					cpu_to_le32(~VMXNET3_IC_DISABLE_ALL);
++	} else {
++		adapter->shared->devReadExt.intrConfExt.intrCtrl &=
+ 					cpu_to_le32(~VMXNET3_IC_DISABLE_ALL);
++	}
+ }
+ 
+ 
+@@ -85,8 +91,14 @@ vmxnet3_disable_all_intrs(struct vmxnet3_adapter *adapter)
+ {
+ 	int i;
+ 
+-	adapter->shared->devRead.intrConf.intrCtrl |=
++	if (!VMXNET3_VERSION_GE_6(adapter) ||
++	    !adapter->queuesExtEnabled) {
++		adapter->shared->devRead.intrConf.intrCtrl |=
++					cpu_to_le32(VMXNET3_IC_DISABLE_ALL);
++	} else {
++		adapter->shared->devReadExt.intrConfExt.intrCtrl |=
+ 					cpu_to_le32(VMXNET3_IC_DISABLE_ALL);
++	}
+ 	for (i = 0; i < adapter->intr.num_intrs; i++)
+ 		vmxnet3_disable_intr(adapter, i);
+ }
+@@ -1396,6 +1408,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
+ 	};
+ 	u32 num_pkts = 0;
+ 	bool skip_page_frags = false;
++	bool encap_lro = false;
+ 	struct Vmxnet3_RxCompDesc *rcd;
+ 	struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
+ 	u16 segCnt = 0, mss = 0;
+@@ -1556,13 +1569,18 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
+ 			if (VMXNET3_VERSION_GE_2(adapter) &&
+ 			    rcd->type == VMXNET3_CDTYPE_RXCOMP_LRO) {
+ 				struct Vmxnet3_RxCompDescExt *rcdlro;
++				union Vmxnet3_GenericDesc *gdesc;
++
+ 				rcdlro = (struct Vmxnet3_RxCompDescExt *)rcd;
++				gdesc = (union Vmxnet3_GenericDesc *)rcd;
+ 
+ 				segCnt = rcdlro->segCnt;
+ 				WARN_ON_ONCE(segCnt == 0);
+ 				mss = rcdlro->mss;
+ 				if (unlikely(segCnt <= 1))
+ 					segCnt = 0;
++				encap_lro = (le32_to_cpu(gdesc->dword[0]) &
++					(1UL << VMXNET3_RCD_HDR_INNER_SHIFT));
+ 			} else {
+ 				segCnt = 0;
+ 			}
+@@ -1630,7 +1648,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
+ 			vmxnet3_rx_csum(adapter, skb,
+ 					(union Vmxnet3_GenericDesc *)rcd);
+ 			skb->protocol = eth_type_trans(skb, adapter->netdev);
+-			if (!rcd->tcp ||
++			if ((!rcd->tcp && !encap_lro) ||
+ 			    !(adapter->netdev->features & NETIF_F_LRO))
+ 				goto not_lro;
+ 
+@@ -1639,7 +1657,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
+ 					SKB_GSO_TCPV4 : SKB_GSO_TCPV6;
+ 				skb_shinfo(skb)->gso_size = mss;
+ 				skb_shinfo(skb)->gso_segs = segCnt;
+-			} else if (segCnt != 0 || skb->len > mtu) {
++			} else if ((segCnt != 0 || skb->len > mtu) && !encap_lro) {
+ 				u32 hlen;
+ 
+ 				hlen = vmxnet3_get_hdr_len(adapter, skb,
+@@ -1668,6 +1686,7 @@ not_lro:
+ 				napi_gro_receive(&rq->napi, skb);
+ 
+ 			ctx->skb = NULL;
++			encap_lro = false;
+ 			num_pkts++;
+ 		}
+ 
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_mux.c b/drivers/net/wwan/iosm/iosm_ipc_mux.c
+index 9c7a9a2a1f252..fc928b298a984 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_mux.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_mux.c
+@@ -332,6 +332,7 @@ struct iosm_mux *ipc_mux_init(struct ipc_mux_config *mux_cfg,
+ 			if (!ipc_mux->ul_adb.pp_qlt[i]) {
+ 				for (j = i - 1; j >= 0; j--)
+ 					kfree(ipc_mux->ul_adb.pp_qlt[j]);
++				kfree(ipc_mux);
+ 				return NULL;
+ 			}
+ 		}
+diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
+index 8174d7b2966c0..adfd21aa5b6ad 100644
+--- a/drivers/net/xen-netback/common.h
++++ b/drivers/net/xen-netback/common.h
+@@ -386,7 +386,7 @@ int xenvif_dealloc_kthread(void *data);
+ irqreturn_t xenvif_ctrl_irq_fn(int irq, void *data);
+ 
+ bool xenvif_have_rx_work(struct xenvif_queue *queue, bool test_kthread);
+-void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb);
++bool xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb);
+ 
+ void xenvif_carrier_on(struct xenvif *vif);
+ 
+diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
+index fb32ae82d9b04..d048a5cc918b2 100644
+--- a/drivers/net/xen-netback/interface.c
++++ b/drivers/net/xen-netback/interface.c
+@@ -254,14 +254,16 @@ xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE)
+ 		skb_clear_hash(skb);
+ 
+-	xenvif_rx_queue_tail(queue, skb);
++	if (!xenvif_rx_queue_tail(queue, skb))
++		goto drop;
++
+ 	xenvif_kick_thread(queue);
+ 
+ 	return NETDEV_TX_OK;
+ 
+  drop:
+ 	vif->dev->stats.tx_dropped++;
+-	dev_kfree_skb(skb);
++	dev_kfree_skb_any(skb);
+ 	return NETDEV_TX_OK;
+ }
+ 
+diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
+index a256695fc89ec..82d7910f7ade5 100644
+--- a/drivers/net/xen-netback/netback.c
++++ b/drivers/net/xen-netback/netback.c
+@@ -332,10 +332,13 @@ static int xenvif_count_requests(struct xenvif_queue *queue,
+ 
+ 
+ struct xenvif_tx_cb {
+-	u16 pending_idx;
++	u16 copy_pending_idx[XEN_NETBK_LEGACY_SLOTS_MAX + 1];
++	u8 copy_count;
+ };
+ 
+ #define XENVIF_TX_CB(skb) ((struct xenvif_tx_cb *)(skb)->cb)
++#define copy_pending_idx(skb, i) (XENVIF_TX_CB(skb)->copy_pending_idx[i])
++#define copy_count(skb) (XENVIF_TX_CB(skb)->copy_count)
+ 
+ static inline void xenvif_tx_create_map_op(struct xenvif_queue *queue,
+ 					   u16 pending_idx,
+@@ -370,31 +373,93 @@ static inline struct sk_buff *xenvif_alloc_skb(unsigned int size)
+ 	return skb;
+ }
+ 
+-static struct gnttab_map_grant_ref *xenvif_get_requests(struct xenvif_queue *queue,
+-							struct sk_buff *skb,
+-							struct xen_netif_tx_request *txp,
+-							struct gnttab_map_grant_ref *gop,
+-							unsigned int frag_overflow,
+-							struct sk_buff *nskb)
++static void xenvif_get_requests(struct xenvif_queue *queue,
++				struct sk_buff *skb,
++				struct xen_netif_tx_request *first,
++				struct xen_netif_tx_request *txfrags,
++			        unsigned *copy_ops,
++			        unsigned *map_ops,
++				unsigned int frag_overflow,
++				struct sk_buff *nskb,
++				unsigned int extra_count,
++				unsigned int data_len)
+ {
+ 	struct skb_shared_info *shinfo = skb_shinfo(skb);
+ 	skb_frag_t *frags = shinfo->frags;
+-	u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx;
+-	int start;
++	u16 pending_idx;
+ 	pending_ring_idx_t index;
+ 	unsigned int nr_slots;
++	struct gnttab_copy *cop = queue->tx_copy_ops + *copy_ops;
++	struct gnttab_map_grant_ref *gop = queue->tx_map_ops + *map_ops;
++	struct xen_netif_tx_request *txp = first;
++
++	nr_slots = shinfo->nr_frags + 1;
++
++	copy_count(skb) = 0;
++
++	/* Create copy ops for exactly data_len bytes into the skb head. */
++	__skb_put(skb, data_len);
++	while (data_len > 0) {
++		int amount = data_len > txp->size ? txp->size : data_len;
++
++		cop->source.u.ref = txp->gref;
++		cop->source.domid = queue->vif->domid;
++		cop->source.offset = txp->offset;
++
++		cop->dest.domid = DOMID_SELF;
++		cop->dest.offset = (offset_in_page(skb->data +
++						   skb_headlen(skb) -
++						   data_len)) & ~XEN_PAGE_MASK;
++		cop->dest.u.gmfn = virt_to_gfn(skb->data + skb_headlen(skb)
++				               - data_len);
++
++		cop->len = amount;
++		cop->flags = GNTCOPY_source_gref;
+ 
+-	nr_slots = shinfo->nr_frags;
++		index = pending_index(queue->pending_cons);
++		pending_idx = queue->pending_ring[index];
++		callback_param(queue, pending_idx).ctx = NULL;
++		copy_pending_idx(skb, copy_count(skb)) = pending_idx;
++		copy_count(skb)++;
++
++		cop++;
++		data_len -= amount;
+ 
+-	/* Skip first skb fragment if it is on same page as header fragment. */
+-	start = (frag_get_pending_idx(&shinfo->frags[0]) == pending_idx);
++		if (amount == txp->size) {
++			/* The copy op covered the full tx_request */
++
++			memcpy(&queue->pending_tx_info[pending_idx].req,
++			       txp, sizeof(*txp));
++			queue->pending_tx_info[pending_idx].extra_count =
++				(txp == first) ? extra_count : 0;
++
++			if (txp == first)
++				txp = txfrags;
++			else
++				txp++;
++			queue->pending_cons++;
++			nr_slots--;
++		} else {
++			/* The copy op partially covered the tx_request.
++			 * The remainder will be mapped.
++			 */
++			txp->offset += amount;
++			txp->size -= amount;
++		}
++	}
+ 
+-	for (shinfo->nr_frags = start; shinfo->nr_frags < nr_slots;
+-	     shinfo->nr_frags++, txp++, gop++) {
++	for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots;
++	     shinfo->nr_frags++, gop++) {
+ 		index = pending_index(queue->pending_cons++);
+ 		pending_idx = queue->pending_ring[index];
+-		xenvif_tx_create_map_op(queue, pending_idx, txp, 0, gop);
++		xenvif_tx_create_map_op(queue, pending_idx, txp,
++				        txp == first ? extra_count : 0, gop);
+ 		frag_set_pending_idx(&frags[shinfo->nr_frags], pending_idx);
++
++		if (txp == first)
++			txp = txfrags;
++		else
++			txp++;
+ 	}
+ 
+ 	if (frag_overflow) {
+@@ -415,7 +480,8 @@ static struct gnttab_map_grant_ref *xenvif_get_requests(struct xenvif_queue *que
+ 		skb_shinfo(skb)->frag_list = nskb;
+ 	}
+ 
+-	return gop;
++	(*copy_ops) = cop - queue->tx_copy_ops;
++	(*map_ops) = gop - queue->tx_map_ops;
+ }
+ 
+ static inline void xenvif_grant_handle_set(struct xenvif_queue *queue,
+@@ -451,7 +517,7 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
+ 			       struct gnttab_copy **gopp_copy)
+ {
+ 	struct gnttab_map_grant_ref *gop_map = *gopp_map;
+-	u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx;
++	u16 pending_idx;
+ 	/* This always points to the shinfo of the skb being checked, which
+ 	 * could be either the first or the one on the frag_list
+ 	 */
+@@ -462,24 +528,37 @@ static int xenvif_tx_check_gop(struct xenvif_queue *queue,
+ 	struct skb_shared_info *first_shinfo = NULL;
+ 	int nr_frags = shinfo->nr_frags;
+ 	const bool sharedslot = nr_frags &&
+-				frag_get_pending_idx(&shinfo->frags[0]) == pending_idx;
+-	int i, err;
++				frag_get_pending_idx(&shinfo->frags[0]) ==
++				    copy_pending_idx(skb, copy_count(skb) - 1);
++	int i, err = 0;
+ 
+-	/* Check status of header. */
+-	err = (*gopp_copy)->status;
+-	if (unlikely(err)) {
+-		if (net_ratelimit())
+-			netdev_dbg(queue->vif->dev,
+-				   "Grant copy of header failed! status: %d pending_idx: %u ref: %u\n",
+-				   (*gopp_copy)->status,
+-				   pending_idx,
+-				   (*gopp_copy)->source.u.ref);
+-		/* The first frag might still have this slot mapped */
+-		if (!sharedslot)
+-			xenvif_idx_release(queue, pending_idx,
+-					   XEN_NETIF_RSP_ERROR);
++	for (i = 0; i < copy_count(skb); i++) {
++		int newerr;
++
++		/* Check status of header. */
++		pending_idx = copy_pending_idx(skb, i);
++
++		newerr = (*gopp_copy)->status;
++		if (likely(!newerr)) {
++			/* The first frag might still have this slot mapped */
++			if (i < copy_count(skb) - 1 || !sharedslot)
++				xenvif_idx_release(queue, pending_idx,
++						   XEN_NETIF_RSP_OKAY);
++		} else {
++			err = newerr;
++			if (net_ratelimit())
++				netdev_dbg(queue->vif->dev,
++					   "Grant copy of header failed! status: %d pending_idx: %u ref: %u\n",
++					   (*gopp_copy)->status,
++					   pending_idx,
++					   (*gopp_copy)->source.u.ref);
++			/* The first frag might still have this slot mapped */
++			if (i < copy_count(skb) - 1 || !sharedslot)
++				xenvif_idx_release(queue, pending_idx,
++						   XEN_NETIF_RSP_ERROR);
++		}
++		(*gopp_copy)++;
+ 	}
+-	(*gopp_copy)++;
+ 
+ check_frags:
+ 	for (i = 0; i < nr_frags; i++, gop_map++) {
+@@ -526,14 +605,6 @@ check_frags:
+ 		if (err)
+ 			continue;
+ 
+-		/* First error: if the header haven't shared a slot with the
+-		 * first frag, release it as well.
+-		 */
+-		if (!sharedslot)
+-			xenvif_idx_release(queue,
+-					   XENVIF_TX_CB(skb)->pending_idx,
+-					   XEN_NETIF_RSP_OKAY);
+-
+ 		/* Invalidate preceding fragments of this skb. */
+ 		for (j = 0; j < i; j++) {
+ 			pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
+@@ -803,7 +874,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ 				     unsigned *copy_ops,
+ 				     unsigned *map_ops)
+ {
+-	struct gnttab_map_grant_ref *gop = queue->tx_map_ops;
+ 	struct sk_buff *skb, *nskb;
+ 	int ret;
+ 	unsigned int frag_overflow;
+@@ -885,8 +955,12 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ 			continue;
+ 		}
+ 
++		data_len = (txreq.size > XEN_NETBACK_TX_COPY_LEN) ?
++			XEN_NETBACK_TX_COPY_LEN : txreq.size;
++
+ 		ret = xenvif_count_requests(queue, &txreq, extra_count,
+ 					    txfrags, work_to_do);
++
+ 		if (unlikely(ret < 0))
+ 			break;
+ 
+@@ -912,9 +986,8 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ 		index = pending_index(queue->pending_cons);
+ 		pending_idx = queue->pending_ring[index];
+ 
+-		data_len = (txreq.size > XEN_NETBACK_TX_COPY_LEN &&
+-			    ret < XEN_NETBK_LEGACY_SLOTS_MAX) ?
+-			XEN_NETBACK_TX_COPY_LEN : txreq.size;
++		if (ret >= XEN_NETBK_LEGACY_SLOTS_MAX - 1 && data_len < txreq.size)
++			data_len = txreq.size;
+ 
+ 		skb = xenvif_alloc_skb(data_len);
+ 		if (unlikely(skb == NULL)) {
+@@ -925,8 +998,6 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ 		}
+ 
+ 		skb_shinfo(skb)->nr_frags = ret;
+-		if (data_len < txreq.size)
+-			skb_shinfo(skb)->nr_frags++;
+ 		/* At this point shinfo->nr_frags is in fact the number of
+ 		 * slots, which can be as large as XEN_NETBK_LEGACY_SLOTS_MAX.
+ 		 */
+@@ -988,54 +1059,19 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
+ 					     type);
+ 		}
+ 
+-		XENVIF_TX_CB(skb)->pending_idx = pending_idx;
+-
+-		__skb_put(skb, data_len);
+-		queue->tx_copy_ops[*copy_ops].source.u.ref = txreq.gref;
+-		queue->tx_copy_ops[*copy_ops].source.domid = queue->vif->domid;
+-		queue->tx_copy_ops[*copy_ops].source.offset = txreq.offset;
+-
+-		queue->tx_copy_ops[*copy_ops].dest.u.gmfn =
+-			virt_to_gfn(skb->data);
+-		queue->tx_copy_ops[*copy_ops].dest.domid = DOMID_SELF;
+-		queue->tx_copy_ops[*copy_ops].dest.offset =
+-			offset_in_page(skb->data) & ~XEN_PAGE_MASK;
+-
+-		queue->tx_copy_ops[*copy_ops].len = data_len;
+-		queue->tx_copy_ops[*copy_ops].flags = GNTCOPY_source_gref;
+-
+-		(*copy_ops)++;
+-
+-		if (data_len < txreq.size) {
+-			frag_set_pending_idx(&skb_shinfo(skb)->frags[0],
+-					     pending_idx);
+-			xenvif_tx_create_map_op(queue, pending_idx, &txreq,
+-						extra_count, gop);
+-			gop++;
+-		} else {
+-			frag_set_pending_idx(&skb_shinfo(skb)->frags[0],
+-					     INVALID_PENDING_IDX);
+-			memcpy(&queue->pending_tx_info[pending_idx].req,
+-			       &txreq, sizeof(txreq));
+-			queue->pending_tx_info[pending_idx].extra_count =
+-				extra_count;
+-		}
+-
+-		queue->pending_cons++;
+-
+-		gop = xenvif_get_requests(queue, skb, txfrags, gop,
+-				          frag_overflow, nskb);
++		xenvif_get_requests(queue, skb, &txreq, txfrags, copy_ops,
++				    map_ops, frag_overflow, nskb, extra_count,
++				    data_len);
+ 
+ 		__skb_queue_tail(&queue->tx_queue, skb);
+ 
+ 		queue->tx.req_cons = idx;
+ 
+-		if (((gop-queue->tx_map_ops) >= ARRAY_SIZE(queue->tx_map_ops)) ||
++		if ((*map_ops >= ARRAY_SIZE(queue->tx_map_ops)) ||
+ 		    (*copy_ops >= ARRAY_SIZE(queue->tx_copy_ops)))
+ 			break;
+ 	}
+ 
+-	(*map_ops) = gop - queue->tx_map_ops;
+ 	return;
+ }
+ 
+@@ -1114,9 +1150,8 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
+ 	while ((skb = __skb_dequeue(&queue->tx_queue)) != NULL) {
+ 		struct xen_netif_tx_request *txp;
+ 		u16 pending_idx;
+-		unsigned data_len;
+ 
+-		pending_idx = XENVIF_TX_CB(skb)->pending_idx;
++		pending_idx = copy_pending_idx(skb, 0);
+ 		txp = &queue->pending_tx_info[pending_idx].req;
+ 
+ 		/* Check the remap error code. */
+@@ -1135,18 +1170,6 @@ static int xenvif_tx_submit(struct xenvif_queue *queue)
+ 			continue;
+ 		}
+ 
+-		data_len = skb->len;
+-		callback_param(queue, pending_idx).ctx = NULL;
+-		if (data_len < txp->size) {
+-			/* Append the packet payload as a fragment. */
+-			txp->offset += data_len;
+-			txp->size -= data_len;
+-		} else {
+-			/* Schedule a response immediately. */
+-			xenvif_idx_release(queue, pending_idx,
+-					   XEN_NETIF_RSP_OKAY);
+-		}
+-
+ 		if (txp->flags & XEN_NETTXF_csum_blank)
+ 			skb->ip_summed = CHECKSUM_PARTIAL;
+ 		else if (txp->flags & XEN_NETTXF_data_validated)
+@@ -1331,7 +1354,7 @@ static inline void xenvif_tx_dealloc_action(struct xenvif_queue *queue)
+ /* Called after netfront has transmitted */
+ int xenvif_tx_action(struct xenvif_queue *queue, int budget)
+ {
+-	unsigned nr_mops, nr_cops = 0;
++	unsigned nr_mops = 0, nr_cops = 0;
+ 	int work_done, ret;
+ 
+ 	if (unlikely(!tx_work_todo(queue)))
+diff --git a/drivers/net/xen-netback/rx.c b/drivers/net/xen-netback/rx.c
+index 9327621771109..0ba754ebc5baa 100644
+--- a/drivers/net/xen-netback/rx.c
++++ b/drivers/net/xen-netback/rx.c
+@@ -82,9 +82,10 @@ static bool xenvif_rx_ring_slots_available(struct xenvif_queue *queue)
+ 	return false;
+ }
+ 
+-void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
++bool xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
+ {
+ 	unsigned long flags;
++	bool ret = true;
+ 
+ 	spin_lock_irqsave(&queue->rx_queue.lock, flags);
+ 
+@@ -92,8 +93,7 @@ void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
+ 		struct net_device *dev = queue->vif->dev;
+ 
+ 		netif_tx_stop_queue(netdev_get_tx_queue(dev, queue->id));
+-		kfree_skb(skb);
+-		queue->vif->dev->stats.rx_dropped++;
++		ret = false;
+ 	} else {
+ 		if (skb_queue_empty(&queue->rx_queue))
+ 			xenvif_update_needed_slots(queue, skb);
+@@ -104,6 +104,8 @@ void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb)
+ 	}
+ 
+ 	spin_unlock_irqrestore(&queue->rx_queue.lock, flags);
++
++	return ret;
+ }
+ 
+ static struct sk_buff *xenvif_rx_dequeue(struct xenvif_queue *queue)
+diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
+index 27a11cc08c61e..479e215159fcc 100644
+--- a/drivers/net/xen-netfront.c
++++ b/drivers/net/xen-netfront.c
+@@ -1862,6 +1862,12 @@ static int netfront_resume(struct xenbus_device *dev)
+ 	netif_tx_unlock_bh(info->netdev);
+ 
+ 	xennet_disconnect_backend(info);
++
++	rtnl_lock();
++	if (info->queues)
++		xennet_destroy_queues(info);
++	rtnl_unlock();
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index f612a0ba64d00..aca50bb937506 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -3089,10 +3089,6 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
+ 	if (!ctrl->identified) {
+ 		unsigned int i;
+ 
+-		ret = nvme_init_subsystem(ctrl, id);
+-		if (ret)
+-			goto out_free;
+-
+ 		/*
+ 		 * Check for quirks.  Quirk can depend on firmware version,
+ 		 * so, in principle, the set of quirks present can change
+@@ -3105,6 +3101,10 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
+ 			if (quirk_matches(id, &core_quirks[i]))
+ 				ctrl->quirks |= core_quirks[i].quirks;
+ 		}
++
++		ret = nvme_init_subsystem(ctrl, id);
++		if (ret)
++			goto out_free;
+ 	}
+ 	memcpy(ctrl->subsys->firmware_rev, id->fr,
+ 	       sizeof(ctrl->subsys->firmware_rev));
+diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
+index 478dd300b9c9a..d9e7cf6e4a0e1 100644
+--- a/drivers/platform/x86/asus-nb-wmi.c
++++ b/drivers/platform/x86/asus-nb-wmi.c
+@@ -115,12 +115,17 @@ static struct quirk_entry quirk_asus_forceals = {
+ };
+ 
+ static struct quirk_entry quirk_asus_use_kbd_dock_devid = {
+-	.use_kbd_dock_devid = true,
++	.tablet_switch_mode = asus_wmi_kbd_dock_devid,
+ };
+ 
+ static struct quirk_entry quirk_asus_use_lid_flip_devid = {
+ 	.wmi_backlight_set_devstate = true,
+-	.use_lid_flip_devid = true,
++	.tablet_switch_mode = asus_wmi_lid_flip_devid,
++};
++
++static struct quirk_entry quirk_asus_tablet_mode = {
++	.wmi_backlight_set_devstate = true,
++	.tablet_switch_mode = asus_wmi_lid_flip_rog_devid,
+ };
+ 
+ static int dmi_matched(const struct dmi_system_id *dmi)
+@@ -471,6 +476,15 @@ static const struct dmi_system_id asus_quirks[] = {
+ 		},
+ 		.driver_data = &quirk_asus_use_lid_flip_devid,
+ 	},
++	{
++		.callback = dmi_matched,
++		.ident = "ASUS ROG FLOW X13",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "GV301Q"),
++		},
++		.driver_data = &quirk_asus_tablet_mode,
++	},
+ 	{},
+ };
+ 
+@@ -492,16 +506,13 @@ static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver)
+ 
+ 	switch (tablet_mode_sw) {
+ 	case 0:
+-		quirks->use_kbd_dock_devid = false;
+-		quirks->use_lid_flip_devid = false;
++		quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
+ 		break;
+ 	case 1:
+-		quirks->use_kbd_dock_devid = true;
+-		quirks->use_lid_flip_devid = false;
++		quirks->tablet_switch_mode = asus_wmi_kbd_dock_devid;
+ 		break;
+ 	case 2:
+-		quirks->use_kbd_dock_devid = false;
+-		quirks->use_lid_flip_devid = true;
++		quirks->tablet_switch_mode = asus_wmi_lid_flip_devid;
+ 		break;
+ 	}
+ 
+@@ -581,6 +592,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = {
+ 	{ KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } },
+ 	{ KE_IGNORE, 0xC6, },  /* Ambient Light Sensor notification */
+ 	{ KE_KEY, 0xFA, { KEY_PROG2 } },           /* Lid flip action */
++	{ KE_KEY, 0xBD, { KEY_PROG2 } },           /* Lid flip action on ROG xflow laptops */
+ 	{ KE_END, 0},
+ };
+ 
+diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
+index 8e1979b477a7d..dce93187e11f9 100644
+--- a/drivers/platform/x86/asus-wmi.c
++++ b/drivers/platform/x86/asus-wmi.c
+@@ -68,6 +68,7 @@ module_param(fnlock_default, bool, 0444);
+ #define NOTIFY_KBD_FBM			0x99
+ #define NOTIFY_KBD_TTP			0xae
+ #define NOTIFY_LID_FLIP			0xfa
++#define NOTIFY_LID_FLIP_ROG		0xbd
+ 
+ #define ASUS_WMI_FNLOCK_BIOS_DISABLED	BIT(0)
+ 
+@@ -489,8 +490,11 @@ static bool asus_wmi_dev_is_present(struct asus_wmi *asus, u32 dev_id)
+ 
+ static int asus_wmi_input_init(struct asus_wmi *asus)
+ {
++	struct device *dev;
+ 	int err, result;
+ 
++	dev = &asus->platform_device->dev;
++
+ 	asus->inputdev = input_allocate_device();
+ 	if (!asus->inputdev)
+ 		return -ENOMEM;
+@@ -498,35 +502,51 @@ static int asus_wmi_input_init(struct asus_wmi *asus)
+ 	asus->inputdev->name = asus->driver->input_name;
+ 	asus->inputdev->phys = asus->driver->input_phys;
+ 	asus->inputdev->id.bustype = BUS_HOST;
+-	asus->inputdev->dev.parent = &asus->platform_device->dev;
++	asus->inputdev->dev.parent = dev;
+ 	set_bit(EV_REP, asus->inputdev->evbit);
+ 
+ 	err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL);
+ 	if (err)
+ 		goto err_free_dev;
+ 
+-	if (asus->driver->quirks->use_kbd_dock_devid) {
++	switch (asus->driver->quirks->tablet_switch_mode) {
++	case asus_wmi_no_tablet_switch:
++		break;
++	case asus_wmi_kbd_dock_devid:
+ 		result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_KBD_DOCK);
+ 		if (result >= 0) {
+ 			input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
+ 			input_report_switch(asus->inputdev, SW_TABLET_MODE, !result);
+ 		} else if (result != -ENODEV) {
+-			pr_err("Error checking for keyboard-dock: %d\n", result);
++			dev_err(dev, "Error checking for keyboard-dock: %d\n", result);
+ 		}
+-	}
+-
+-	if (asus->driver->quirks->use_lid_flip_devid) {
++		break;
++	case asus_wmi_lid_flip_devid:
+ 		result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP);
+ 		if (result < 0)
+-			asus->driver->quirks->use_lid_flip_devid = 0;
++			asus->driver->quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
++		if (result >= 0) {
++			input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
++			input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
++		} else if (result == -ENODEV) {
++			dev_err(dev, "This device has lid_flip quirk but got ENODEV checking it. This is a bug.");
++		} else {
++			dev_err(dev, "Error checking for lid-flip: %d\n", result);
++		}
++		break;
++	case asus_wmi_lid_flip_rog_devid:
++		result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP_ROG);
++		if (result < 0)
++			asus->driver->quirks->tablet_switch_mode = asus_wmi_no_tablet_switch;
+ 		if (result >= 0) {
+ 			input_set_capability(asus->inputdev, EV_SW, SW_TABLET_MODE);
+ 			input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
+ 		} else if (result == -ENODEV) {
+-			pr_err("This device has lid_flip quirk but got ENODEV checking it. This is a bug.");
++			dev_err(dev, "This device has lid-flip-rog quirk but got ENODEV checking it. This is a bug.");
+ 		} else {
+-			pr_err("Error checking for lid-flip: %d\n", result);
++			dev_err(dev, "Error checking for lid-flip: %d\n", result);
+ 		}
++		break;
+ 	}
+ 
+ 	err = input_register_device(asus->inputdev);
+@@ -552,8 +572,20 @@ static void asus_wmi_input_exit(struct asus_wmi *asus)
+ 
+ static void lid_flip_tablet_mode_get_state(struct asus_wmi *asus)
+ {
+-	int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP);
++	int result;
+ 
++	result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP);
++	if (result >= 0) {
++		input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
++		input_sync(asus->inputdev);
++	}
++}
++
++static void lid_flip_rog_tablet_mode_get_state(struct asus_wmi *asus)
++{
++	int result;
++
++	result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_LID_FLIP_ROG);
+ 	if (result >= 0) {
+ 		input_report_switch(asus->inputdev, SW_TABLET_MODE, result);
+ 		input_sync(asus->inputdev);
+@@ -3109,7 +3141,8 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
+ 		return;
+ 	}
+ 
+-	if (asus->driver->quirks->use_kbd_dock_devid && code == NOTIFY_KBD_DOCK_CHANGE) {
++	if (asus->driver->quirks->tablet_switch_mode == asus_wmi_kbd_dock_devid &&
++	    code == NOTIFY_KBD_DOCK_CHANGE) {
+ 		result = asus_wmi_get_devstate_simple(asus,
+ 						      ASUS_WMI_DEVID_KBD_DOCK);
+ 		if (result >= 0) {
+@@ -3120,11 +3153,18 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
+ 		return;
+ 	}
+ 
+-	if (asus->driver->quirks->use_lid_flip_devid && code == NOTIFY_LID_FLIP) {
++	if (asus->driver->quirks->tablet_switch_mode == asus_wmi_lid_flip_devid &&
++	    code == NOTIFY_LID_FLIP) {
+ 		lid_flip_tablet_mode_get_state(asus);
+ 		return;
+ 	}
+ 
++	if (asus->driver->quirks->tablet_switch_mode == asus_wmi_lid_flip_rog_devid &&
++	    code == NOTIFY_LID_FLIP_ROG) {
++		lid_flip_rog_tablet_mode_get_state(asus);
++		return;
++	}
++
+ 	if (asus->fan_boost_mode_available && code == NOTIFY_KBD_FBM) {
+ 		fan_boost_mode_switch_next(asus);
+ 		return;
+@@ -3757,8 +3797,17 @@ static int asus_hotk_resume(struct device *device)
+ 	if (asus_wmi_has_fnlock_key(asus))
+ 		asus_wmi_fnlock_update(asus);
+ 
+-	if (asus->driver->quirks->use_lid_flip_devid)
++	switch (asus->driver->quirks->tablet_switch_mode) {
++	case asus_wmi_no_tablet_switch:
++	case asus_wmi_kbd_dock_devid:
++		break;
++	case asus_wmi_lid_flip_devid:
+ 		lid_flip_tablet_mode_get_state(asus);
++		break;
++	case asus_wmi_lid_flip_rog_devid:
++		lid_flip_rog_tablet_mode_get_state(asus);
++		break;
++	}
+ 
+ 	return 0;
+ }
+@@ -3799,8 +3848,17 @@ static int asus_hotk_restore(struct device *device)
+ 	if (asus_wmi_has_fnlock_key(asus))
+ 		asus_wmi_fnlock_update(asus);
+ 
+-	if (asus->driver->quirks->use_lid_flip_devid)
++	switch (asus->driver->quirks->tablet_switch_mode) {
++	case asus_wmi_no_tablet_switch:
++	case asus_wmi_kbd_dock_devid:
++		break;
++	case asus_wmi_lid_flip_devid:
+ 		lid_flip_tablet_mode_get_state(asus);
++		break;
++	case asus_wmi_lid_flip_rog_devid:
++		lid_flip_rog_tablet_mode_get_state(asus);
++		break;
++	}
+ 
+ 	return 0;
+ }
+diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
+index b302415bf1d95..0187f13d24148 100644
+--- a/drivers/platform/x86/asus-wmi.h
++++ b/drivers/platform/x86/asus-wmi.h
+@@ -25,6 +25,13 @@ struct module;
+ struct key_entry;
+ struct asus_wmi;
+ 
++enum asus_wmi_tablet_switch_mode {
++	asus_wmi_no_tablet_switch,
++	asus_wmi_kbd_dock_devid,
++	asus_wmi_lid_flip_devid,
++	asus_wmi_lid_flip_rog_devid,
++};
++
+ struct quirk_entry {
+ 	bool hotplug_wireless;
+ 	bool scalar_panel_brightness;
+@@ -33,8 +40,7 @@ struct quirk_entry {
+ 	bool wmi_backlight_native;
+ 	bool wmi_backlight_set_devstate;
+ 	bool wmi_force_als_set;
+-	bool use_kbd_dock_devid;
+-	bool use_lid_flip_devid;
++	enum asus_wmi_tablet_switch_mode tablet_switch_mode;
+ 	int wapf;
+ 	/*
+ 	 * For machines with AMD graphic chips, it will send out WMI event
+diff --git a/drivers/regulator/slg51000-regulator.c b/drivers/regulator/slg51000-regulator.c
+index 75a941fb3c2bd..1b2eee95ad3f9 100644
+--- a/drivers/regulator/slg51000-regulator.c
++++ b/drivers/regulator/slg51000-regulator.c
+@@ -457,6 +457,8 @@ static int slg51000_i2c_probe(struct i2c_client *client)
+ 		chip->cs_gpiod = cs_gpiod;
+ 	}
+ 
++	usleep_range(10000, 11000);
++
+ 	i2c_set_clientdata(client, chip);
+ 	chip->chip_irq = client->irq;
+ 	chip->dev = dev;
+diff --git a/drivers/regulator/twl6030-regulator.c b/drivers/regulator/twl6030-regulator.c
+index 7c7e3648ea4bf..f3856750944f4 100644
+--- a/drivers/regulator/twl6030-regulator.c
++++ b/drivers/regulator/twl6030-regulator.c
+@@ -67,6 +67,7 @@ struct twlreg_info {
+ #define TWL6030_CFG_STATE_SLEEP	0x03
+ #define TWL6030_CFG_STATE_GRP_SHIFT	5
+ #define TWL6030_CFG_STATE_APP_SHIFT	2
++#define TWL6030_CFG_STATE_MASK		0x03
+ #define TWL6030_CFG_STATE_APP_MASK	(0x03 << TWL6030_CFG_STATE_APP_SHIFT)
+ #define TWL6030_CFG_STATE_APP(v)	(((v) & TWL6030_CFG_STATE_APP_MASK) >>\
+ 						TWL6030_CFG_STATE_APP_SHIFT)
+@@ -128,13 +129,14 @@ static int twl6030reg_is_enabled(struct regulator_dev *rdev)
+ 		if (grp < 0)
+ 			return grp;
+ 		grp &= P1_GRP_6030;
++		val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
++		val = TWL6030_CFG_STATE_APP(val);
+ 	} else {
++		val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
++		val &= TWL6030_CFG_STATE_MASK;
+ 		grp = 1;
+ 	}
+ 
+-	val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
+-	val = TWL6030_CFG_STATE_APP(val);
+-
+ 	return grp && (val == TWL6030_CFG_STATE_ON);
+ }
+ 
+@@ -187,7 +189,12 @@ static int twl6030reg_get_status(struct regulator_dev *rdev)
+ 
+ 	val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
+ 
+-	switch (TWL6030_CFG_STATE_APP(val)) {
++	if (info->features & TWL6032_SUBCLASS)
++		val &= TWL6030_CFG_STATE_MASK;
++	else
++		val = TWL6030_CFG_STATE_APP(val);
++
++	switch (val) {
+ 	case TWL6030_CFG_STATE_ON:
+ 		return REGULATOR_STATUS_NORMAL;
+ 
+diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
+index 2d4436cbcb47b..b38024a79376b 100644
+--- a/drivers/s390/net/qeth_l2_main.c
++++ b/drivers/s390/net/qeth_l2_main.c
+@@ -758,7 +758,6 @@ static void qeth_l2_br2dev_worker(struct work_struct *work)
+ 	struct list_head *iter;
+ 	int err = 0;
+ 
+-	kfree(br2dev_event_work);
+ 	QETH_CARD_TEXT_(card, 4, "b2dw%04lx", event);
+ 	QETH_CARD_TEXT_(card, 4, "ma%012llx", ether_addr_to_u64(addr));
+ 
+@@ -815,6 +814,7 @@ unlock:
+ 	dev_put(brdev);
+ 	dev_put(lsyncdev);
+ 	dev_put(dstdev);
++	kfree(br2dev_event_work);
+ }
+ 
+ static int qeth_l2_br2dev_queue_work(struct net_device *brdev,
+diff --git a/drivers/soundwire/dmi-quirks.c b/drivers/soundwire/dmi-quirks.c
+index 747983743a14b..f81cdd83ec26e 100644
+--- a/drivers/soundwire/dmi-quirks.c
++++ b/drivers/soundwire/dmi-quirks.c
+@@ -55,7 +55,26 @@ static const struct adr_remap dell_sku_0A3E[] = {
+ 	{}
+ };
+ 
++/*
++ * The HP Omen 16-k0005TX does not expose the correct version of RT711 on link0
++ * and does not expose a RT1316 on link3
++ */
++static const struct adr_remap hp_omen_16[] = {
++	/* rt711-sdca on link0 */
++	{
++		0x000020025d071100ull,
++		0x000030025d071101ull
++	},
++	/* rt1316-sdca on link3 */
++	{
++		0x000120025d071100ull,
++		0x000330025d131601ull
++	},
++	{}
++};
++
+ static const struct dmi_system_id adr_remap_quirk_table[] = {
++	/* TGL devices */
+ 	{
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+@@ -78,6 +97,14 @@ static const struct dmi_system_id adr_remap_quirk_table[] = {
+ 		},
+ 		.driver_data = (void *)dell_sku_0A3E,
+ 	},
++	/* ADL devices */
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"),
++		},
++		.driver_data = (void *)hp_omen_16,
++	},
+ 	{}
+ };
+ 
+diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
+index af6c1a93372d9..002bc26b525e8 100644
+--- a/drivers/soundwire/intel.c
++++ b/drivers/soundwire/intel.c
+@@ -1307,6 +1307,7 @@ static int intel_link_probe(struct auxiliary_device *auxdev,
+ 	cdns->msg_count = 0;
+ 
+ 	bus->link_id = auxdev->id;
++	bus->clk_stop_timeout = 1;
+ 
+ 	sdw_cdns_probe(cdns);
+ 
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index cd9dc358d3967..a7cc96aeb5903 100644
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -1268,8 +1268,11 @@ static int mtk_spi_remove(struct platform_device *pdev)
+ {
+ 	struct spi_master *master = platform_get_drvdata(pdev);
+ 	struct mtk_spi *mdata = spi_master_get_devdata(master);
++	int ret;
+ 
+-	pm_runtime_disable(&pdev->dev);
++	ret = pm_runtime_resume_and_get(&pdev->dev);
++	if (ret < 0)
++		return ret;
+ 
+ 	mtk_spi_reset(mdata);
+ 
+@@ -1278,6 +1281,9 @@ static int mtk_spi_remove(struct platform_device *pdev)
+ 		clk_unprepare(mdata->spi_hclk);
+ 	}
+ 
++	pm_runtime_put_noidle(&pdev->dev);
++	pm_runtime_disable(&pdev->dev);
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 6f61a288073bb..c2075b90f3dfe 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -291,7 +291,8 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
+ 	 *
+ 	 * DWC_usb3 3.30a and DWC_usb31 1.90a programming guide section 3.2.2
+ 	 */
+-	if (dwc->gadget->speed <= USB_SPEED_HIGH) {
++	if (dwc->gadget->speed <= USB_SPEED_HIGH ||
++	    DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER) {
+ 		reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+ 		if (unlikely(reg & DWC3_GUSB2PHYCFG_SUSPHY)) {
+ 			saved_config |= DWC3_GUSB2PHYCFG_SUSPHY;
+diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
+index 098b62f7b701e..c0143d38df83a 100644
+--- a/drivers/video/fbdev/core/fbcon.c
++++ b/drivers/video/fbdev/core/fbcon.c
+@@ -577,7 +577,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
+ 		if (scr_readw(r) != vc->vc_video_erase_char)
+ 			break;
+ 	if (r != q && new_rows >= rows + logo_lines) {
+-		save = kmalloc(array3_size(logo_lines, new_cols, 2),
++		save = kzalloc(array3_size(logo_lines, new_cols, 2),
+ 			       GFP_KERNEL);
+ 		if (save) {
+ 			int i = min(cols, new_cols);
+diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
+index e7671afcee4f0..8cc038460bed7 100644
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -5615,6 +5615,7 @@ static int clone_range(struct send_ctx *sctx, struct btrfs_path *dst_path,
+ 		u64 ext_len;
+ 		u64 clone_len;
+ 		u64 clone_data_offset;
++		bool crossed_src_i_size = false;
+ 
+ 		if (slot >= btrfs_header_nritems(leaf)) {
+ 			ret = btrfs_next_leaf(clone_root->root, path);
+@@ -5672,8 +5673,10 @@ static int clone_range(struct send_ctx *sctx, struct btrfs_path *dst_path,
+ 		if (key.offset >= clone_src_i_size)
+ 			break;
+ 
+-		if (key.offset + ext_len > clone_src_i_size)
++		if (key.offset + ext_len > clone_src_i_size) {
+ 			ext_len = clone_src_i_size - key.offset;
++			crossed_src_i_size = true;
++		}
+ 
+ 		clone_data_offset = btrfs_file_extent_offset(leaf, ei);
+ 		if (btrfs_file_extent_disk_bytenr(leaf, ei) == disk_byte) {
+@@ -5734,6 +5737,25 @@ static int clone_range(struct send_ctx *sctx, struct btrfs_path *dst_path,
+ 				ret = send_clone(sctx, offset, clone_len,
+ 						 clone_root);
+ 			}
++		} else if (crossed_src_i_size && clone_len < len) {
++			/*
++			 * If we are at i_size of the clone source inode and we
++			 * can not clone from it, terminate the loop. This is
++			 * to avoid sending two write operations, one with a
++			 * length matching clone_len and the final one after
++			 * this loop with a length of len - clone_len.
++			 *
++			 * When using encoded writes (BTRFS_SEND_FLAG_COMPRESSED
++			 * was passed to the send ioctl), this helps avoid
++			 * sending an encoded write for an offset that is not
++			 * sector size aligned, in case the i_size of the source
++			 * inode is not sector size aligned. That will make the
++			 * receiver fallback to decompression of the data and
++			 * writing it using regular buffered IO, therefore while
++			 * not incorrect, it's not optimal due decompression and
++			 * possible re-compression at the receiver.
++			 */
++			break;
+ 		} else {
+ 			ret = send_extent_data(sctx, dst_path, offset,
+ 					       clone_len);
+diff --git a/fs/file.c b/fs/file.c
+index 3bcc1ecc314a7..57af5f8375fd2 100644
+--- a/fs/file.c
++++ b/fs/file.c
+@@ -1002,7 +1002,16 @@ static unsigned long __fget_light(unsigned int fd, fmode_t mask)
+ 	struct files_struct *files = current->files;
+ 	struct file *file;
+ 
+-	if (atomic_read(&files->count) == 1) {
++	/*
++	 * If another thread is concurrently calling close_fd() followed
++	 * by put_files_struct(), we must not observe the old table
++	 * entry combined with the new refcount - otherwise we could
++	 * return a file that is concurrently being freed.
++	 *
++	 * atomic_read_acquire() pairs with atomic_dec_and_test() in
++	 * put_files_struct().
++	 */
++	if (atomic_read_acquire(&files->count) == 1) {
+ 		file = files_lookup_fd_raw(files, fd);
+ 		if (!file || unlikely(file->f_mode & mask))
+ 			return 0;
+diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
+index 451d8a077e125..bce2492186d0b 100644
+--- a/fs/fscache/cookie.c
++++ b/fs/fscache/cookie.c
+@@ -605,6 +605,14 @@ again:
+ 			set_bit(FSCACHE_COOKIE_DO_PREP_TO_WRITE, &cookie->flags);
+ 			queue = true;
+ 		}
++		/*
++		 * We could race with cookie_lru which may set LRU_DISCARD bit
++		 * but has yet to run the cookie state machine.  If this happens
++		 * and another thread tries to use the cookie, clear LRU_DISCARD
++		 * so we don't end up withdrawing the cookie while in use.
++		 */
++		if (test_and_clear_bit(FSCACHE_COOKIE_DO_LRU_DISCARD, &cookie->flags))
++			fscache_see_cookie(cookie, fscache_cookie_see_lru_discard_clear);
+ 		break;
+ 
+ 	case FSCACHE_COOKIE_STATE_FAILED:
+diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
+index 492dce43236ea..cab7cfebf40bd 100644
+--- a/include/asm-generic/tlb.h
++++ b/include/asm-generic/tlb.h
+@@ -222,12 +222,16 @@ extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
+ #define tlb_needs_table_invalidate() (true)
+ #endif
+ 
++void tlb_remove_table_sync_one(void);
++
+ #else
+ 
+ #ifdef tlb_needs_table_invalidate
+ #error tlb_needs_table_invalidate() requires MMU_GATHER_RCU_TABLE_FREE
+ #endif
+ 
++static inline void tlb_remove_table_sync_one(void) { }
++
+ #endif /* CONFIG_MMU_GATHER_RCU_TABLE_FREE */
+ 
+ 
+diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
+index ac5d0515680ea..a3535a485497b 100644
+--- a/include/linux/cgroup.h
++++ b/include/linux/cgroup.h
+@@ -68,6 +68,7 @@ struct css_task_iter {
+ 	struct list_head		iters_node;	/* css_set->task_iters */
+ };
+ 
++extern struct file_system_type cgroup_fs_type;
+ extern struct cgroup_root cgrp_dfl_root;
+ extern struct css_set init_css_set;
+ 
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 21f8b27bd9fd3..4ff52127a6b88 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1778,6 +1778,25 @@ extern void pagefault_out_of_memory(void);
+ 
+ extern void show_free_areas(unsigned int flags, nodemask_t *nodemask);
+ 
++/*
++ * Parameter block passed down to zap_pte_range in exceptional cases.
++ */
++struct zap_details {
++	struct folio *single_folio;	/* Locked folio to be unmapped */
++	bool even_cows;			/* Zap COWed private pages too? */
++	zap_flags_t zap_flags;		/* Extra flags for zapping */
++};
++
++/*
++ * Whether to drop the pte markers, for example, the uffd-wp information for
++ * file-backed memory.  This should only be specified when we will completely
++ * drop the page in the mm, either by truncation or unmapping of the vma.  By
++ * default, the flag is not set.
++ */
++#define  ZAP_FLAG_DROP_MARKER        ((__force zap_flags_t) BIT(0))
++/* Set in unmap_vmas() to indicate a final unmap call.  Only used by hugetlb */
++#define  ZAP_FLAG_UNMAP              ((__force zap_flags_t) BIT(1))
++
+ #ifdef CONFIG_MMU
+ extern bool can_do_mlock(void);
+ #else
+@@ -1797,6 +1816,8 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long address,
+ 		    unsigned long size);
+ void unmap_vmas(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
+ 		unsigned long start, unsigned long end);
++void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
++			   unsigned long size, struct zap_details *details);
+ 
+ struct mmu_notifier_range;
+ 
+@@ -3386,12 +3407,4 @@ madvise_set_anon_name(struct mm_struct *mm, unsigned long start,
+ }
+ #endif
+ 
+-/*
+- * Whether to drop the pte markers, for example, the uffd-wp information for
+- * file-backed memory.  This should only be specified when we will completely
+- * drop the page in the mm, either by truncation or unmapping of the vma.  By
+- * default, the flag is not set.
+- */
+-#define  ZAP_FLAG_DROP_MARKER        ((__force zap_flags_t) BIT(0))
+-
+ #endif /* _LINUX_MM_H */
+diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
+index 98f2b2f20f3e9..7c96db7f30602 100644
+--- a/include/linux/platform_data/x86/asus-wmi.h
++++ b/include/linux/platform_data/x86/asus-wmi.h
+@@ -65,6 +65,7 @@
+ #define ASUS_WMI_DEVID_PANEL_OD		0x00050019
+ #define ASUS_WMI_DEVID_CAMERA		0x00060013
+ #define ASUS_WMI_DEVID_LID_FLIP		0x00060062
++#define ASUS_WMI_DEVID_LID_FLIP_ROG	0x00060077
+ 
+ /* Storage */
+ #define ASUS_WMI_DEVID_CARDREADER	0x00080013
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index cf29511b25a8d..4518c63e9d179 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -228,6 +228,17 @@ enum {
+ 	 */
+ 	HCI_QUIRK_VALID_LE_STATES,
+ 
++	/* When this quirk is set, then erroneous data reporting
++	 * is ignored. This is mainly due to the fact that the HCI
++	 * Read Default Erroneous Data Reporting command is advertised,
++	 * but not supported; these controllers often reply with unknown
++	 * command and tend to lock up randomly. Needing a hard reset.
++	 *
++	 * This quirk can be set before hci_register_dev is called or
++	 * during the hdev->setup vendor callback.
++	 */
++	HCI_QUIRK_BROKEN_ERR_DATA_REPORTING,
++
+ 	/*
+ 	 * When this quirk is set, then the hci_suspend_notifier is not
+ 	 * registered. This is intended for devices which drop completely
+@@ -1420,7 +1431,6 @@ struct hci_std_codecs_v2 {
+ } __packed;
+ 
+ struct hci_vnd_codec_v2 {
+-	__u8	id;
+ 	__le16	cid;
+ 	__le16	vid;
+ 	__u8	transport;
+diff --git a/include/net/ping.h b/include/net/ping.h
+index e4ff3911cbf56..9233ad3de0ade 100644
+--- a/include/net/ping.h
++++ b/include/net/ping.h
+@@ -16,9 +16,6 @@
+ #define PING_HTABLE_SIZE 	64
+ #define PING_HTABLE_MASK 	(PING_HTABLE_SIZE-1)
+ 
+-#define ping_portaddr_for_each_entry(__sk, node, list) \
+-	hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
+-
+ /*
+  * gid_t is either uint or ushort.  We want to pass it to
+  * proc_dointvec_minmax(), so it must not be larger than MAX_INT
+diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h
+index c078c48a8e6d3..a6190aa1b4060 100644
+--- a/include/trace/events/fscache.h
++++ b/include/trace/events/fscache.h
+@@ -66,6 +66,7 @@ enum fscache_cookie_trace {
+ 	fscache_cookie_put_work,
+ 	fscache_cookie_see_active,
+ 	fscache_cookie_see_lru_discard,
++	fscache_cookie_see_lru_discard_clear,
+ 	fscache_cookie_see_lru_do_one,
+ 	fscache_cookie_see_relinquish,
+ 	fscache_cookie_see_withdraw,
+@@ -149,6 +150,7 @@ enum fscache_access_trace {
+ 	EM(fscache_cookie_put_work,		"PQ  work ")		\
+ 	EM(fscache_cookie_see_active,		"-   activ")		\
+ 	EM(fscache_cookie_see_lru_discard,	"-   x-lru")		\
++	EM(fscache_cookie_see_lru_discard_clear,"-   lrudc")            \
+ 	EM(fscache_cookie_see_lru_do_one,	"-   lrudo")		\
+ 	EM(fscache_cookie_see_relinquish,	"-   x-rlq")		\
+ 	EM(fscache_cookie_see_withdraw,		"-   x-wth")		\
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index adf73d1625218..1b6c25dc3f0c5 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -2560,8 +2560,10 @@ static __cold void io_tctx_exit_cb(struct callback_head *cb)
+ 	/*
+ 	 * When @in_idle, we're in cancellation and it's racy to remove the
+ 	 * node. It'll be removed by the end of cancellation, just ignore it.
++	 * tctx can be NULL if the queueing of this task_work raced with
++	 * work cancelation off the exec path.
+ 	 */
+-	if (!atomic_read(&tctx->in_idle))
++	if (tctx && !atomic_read(&tctx->in_idle))
+ 		io_uring_del_tctx_node((unsigned long)work->ctx);
+ 	complete(&work->completion);
+ }
+diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h
+index 36b740cb3d59e..b231081be177c 100644
+--- a/kernel/cgroup/cgroup-internal.h
++++ b/kernel/cgroup/cgroup-internal.h
+@@ -168,7 +168,6 @@ extern struct mutex cgroup_mutex;
+ extern spinlock_t css_set_lock;
+ extern struct cgroup_subsys *cgroup_subsys[];
+ extern struct list_head cgroup_roots;
+-extern struct file_system_type cgroup_fs_type;
+ 
+ /* iterate across the hierarchies */
+ #define for_each_root(root)						\
+diff --git a/mm/gup.c b/mm/gup.c
+index 251cb6a10bc0d..d7f9116fc645c 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -2818,7 +2818,7 @@ static int gup_pud_range(p4d_t *p4dp, p4d_t p4d, unsigned long addr, unsigned lo
+ 		next = pud_addr_end(addr, end);
+ 		if (unlikely(!pud_present(pud)))
+ 			return 0;
+-		if (unlikely(pud_huge(pud))) {
++		if (unlikely(pud_huge(pud) || pud_devmap(pud))) {
+ 			if (!gup_huge_pud(pud, pudp, addr, next, flags,
+ 					  pages, nr))
+ 				return 0;
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index dbb558e71e9e1..022a3bfafec44 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -5145,17 +5145,20 @@ void __unmap_hugepage_range_final(struct mmu_gather *tlb,
+ {
+ 	__unmap_hugepage_range(tlb, vma, start, end, ref_page, zap_flags);
+ 
+-	/*
+-	 * Clear this flag so that x86's huge_pmd_share page_table_shareable
+-	 * test will fail on a vma being torn down, and not grab a page table
+-	 * on its way out.  We're lucky that the flag has such an appropriate
+-	 * name, and can in fact be safely cleared here. We could clear it
+-	 * before the __unmap_hugepage_range above, but all that's necessary
+-	 * is to clear it before releasing the i_mmap_rwsem. This works
+-	 * because in the context this is called, the VMA is about to be
+-	 * destroyed and the i_mmap_rwsem is held.
+-	 */
+-	vma->vm_flags &= ~VM_MAYSHARE;
++	if (zap_flags & ZAP_FLAG_UNMAP) {	/* final unmap */
++		/*
++		 * Clear this flag so that x86's huge_pmd_share
++		 * page_table_shareable test will fail on a vma being torn
++		 * down, and not grab a page table on its way out.  We're lucky
++		 * that the flag has such an appropriate name, and can in fact
++		 * be safely cleared here. We could clear it before the
++		 * __unmap_hugepage_range above, but all that's necessary
++		 * is to clear it before releasing the i_mmap_rwsem. This works
++		 * because in the context this is called, the VMA is about to
++		 * be destroyed and the i_mmap_rwsem is held.
++		 */
++		vma->vm_flags &= ~VM_MAYSHARE;
++	}
+ }
+ 
+ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index 70b7ac66411c0..5935765bcb33b 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -1093,6 +1093,7 @@ static void collapse_huge_page(struct mm_struct *mm,
+ 	_pmd = pmdp_collapse_flush(vma, address, pmd);
+ 	spin_unlock(pmd_ptl);
+ 	mmu_notifier_invalidate_range_end(&range);
++	tlb_remove_table_sync_one();
+ 
+ 	spin_lock(pte_ptl);
+ 	isolated = __collapse_huge_page_isolate(vma, address, pte,
+@@ -1360,16 +1361,43 @@ static void khugepaged_add_pte_mapped_thp(struct mm_struct *mm,
+ 	spin_unlock(&khugepaged_mm_lock);
+ }
+ 
++/*
++ * A note about locking:
++ * Trying to take the page table spinlocks would be useless here because those
++ * are only used to synchronize:
++ *
++ *  - modifying terminal entries (ones that point to a data page, not to another
++ *    page table)
++ *  - installing *new* non-terminal entries
++ *
++ * Instead, we need roughly the same kind of protection as free_pgtables() or
++ * mm_take_all_locks() (but only for a single VMA):
++ * The mmap lock together with this VMA's rmap locks covers all paths towards
++ * the page table entries we're messing with here, except for hardware page
++ * table walks and lockless_pages_from_mm().
++ */
+ static void collapse_and_free_pmd(struct mm_struct *mm, struct vm_area_struct *vma,
+ 				  unsigned long addr, pmd_t *pmdp)
+ {
+-	spinlock_t *ptl;
+ 	pmd_t pmd;
++	struct mmu_notifier_range range;
+ 
+ 	mmap_assert_write_locked(mm);
+-	ptl = pmd_lock(vma->vm_mm, pmdp);
++	if (vma->vm_file)
++		lockdep_assert_held_write(&vma->vm_file->f_mapping->i_mmap_rwsem);
++	/*
++	 * All anon_vmas attached to the VMA have the same root and are
++	 * therefore locked by the same lock.
++	 */
++	if (vma->anon_vma)
++		lockdep_assert_held_write(&vma->anon_vma->root->rwsem);
++
++	mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, NULL, mm, addr,
++				addr + HPAGE_PMD_SIZE);
++	mmu_notifier_invalidate_range_start(&range);
+ 	pmd = pmdp_collapse_flush(vma, addr, pmdp);
+-	spin_unlock(ptl);
++	tlb_remove_table_sync_one();
++	mmu_notifier_invalidate_range_end(&range);
+ 	mm_dec_nr_ptes(mm);
+ 	page_table_check_pte_clear_range(mm, addr, pmd);
+ 	pte_free(mm, pmd_pgtable(pmd));
+@@ -1410,6 +1438,14 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+ 	if (!hugepage_vma_check(vma, vma->vm_flags | VM_HUGEPAGE, false, false))
+ 		return;
+ 
++	/*
++	 * Symmetry with retract_page_tables(): Exclude MAP_PRIVATE mappings
++	 * that got written to. Without this, we'd have to also lock the
++	 * anon_vma if one exists.
++	 */
++	if (vma->anon_vma)
++		return;
++
+ 	/* Keep pmd pgtable for uffd-wp; see comment in retract_page_tables() */
+ 	if (userfaultfd_wp(vma))
+ 		return;
+@@ -1426,6 +1462,20 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+ 	if (!pmd)
+ 		goto drop_hpage;
+ 
++	/*
++	 * We need to lock the mapping so that from here on, only GUP-fast and
++	 * hardware page walks can access the parts of the page tables that
++	 * we're operating on.
++	 * See collapse_and_free_pmd().
++	 */
++	i_mmap_lock_write(vma->vm_file->f_mapping);
++
++	/*
++	 * This spinlock should be unnecessary: Nobody else should be accessing
++	 * the page tables under spinlock protection here, only
++	 * lockless_pages_from_mm() and the hardware page walker can access page
++	 * tables while all the high-level locks are held in write mode.
++	 */
+ 	start_pte = pte_offset_map_lock(mm, pmd, haddr, &ptl);
+ 
+ 	/* step 1: check all mapped PTEs are to the right huge page */
+@@ -1476,6 +1526,9 @@ void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr)
+ 
+ 	/* step 4: collapse pmd */
+ 	collapse_and_free_pmd(mm, vma, haddr, pmd);
++
++	i_mmap_unlock_write(vma->vm_file->f_mapping);
++
+ drop_hpage:
+ 	unlock_page(hpage);
+ 	put_page(hpage);
+@@ -1483,6 +1536,7 @@ drop_hpage:
+ 
+ abort:
+ 	pte_unmap_unlock(start_pte, ptl);
++	i_mmap_unlock_write(vma->vm_file->f_mapping);
+ 	goto drop_hpage;
+ }
+ 
+@@ -1531,7 +1585,8 @@ static void retract_page_tables(struct address_space *mapping, pgoff_t pgoff)
+ 		 * An alternative would be drop the check, but check that page
+ 		 * table is clear before calling pmdp_collapse_flush() under
+ 		 * ptl. It has higher chance to recover THP for the VMA, but
+-		 * has higher cost too.
++		 * has higher cost too. It would also probably require locking
++		 * the anon_vma.
+ 		 */
+ 		if (vma->anon_vma)
+ 			continue;
+diff --git a/mm/madvise.c b/mm/madvise.c
+index 98ed17a4471a0..b2831b57aef8c 100644
+--- a/mm/madvise.c
++++ b/mm/madvise.c
+@@ -770,8 +770,8 @@ static int madvise_free_single_vma(struct vm_area_struct *vma,
+  * Application no longer needs these pages.  If the pages are dirty,
+  * it's OK to just throw them away.  The app will be more careful about
+  * data it wants to keep.  Be sure to free swap resources too.  The
+- * zap_page_range call sets things up for shrink_active_list to actually free
+- * these pages later if no one else has touched them in the meantime,
++ * zap_page_range_single call sets things up for shrink_active_list to actually
++ * free these pages later if no one else has touched them in the meantime,
+  * although we could add these pages to a global reuse list for
+  * shrink_active_list to pick up before reclaiming other pages.
+  *
+@@ -788,7 +788,7 @@ static int madvise_free_single_vma(struct vm_area_struct *vma,
+ static long madvise_dontneed_single_vma(struct vm_area_struct *vma,
+ 					unsigned long start, unsigned long end)
+ {
+-	zap_page_range(vma, start, end - start);
++	zap_page_range_single(vma, start, end - start, NULL);
+ 	return 0;
+ }
+ 
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index 6a95ea7c5ee70..f2fc11ba24267 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -4772,6 +4772,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
+ 	unsigned int efd, cfd;
+ 	struct fd efile;
+ 	struct fd cfile;
++	struct dentry *cdentry;
+ 	const char *name;
+ 	char *endp;
+ 	int ret;
+@@ -4825,6 +4826,16 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
+ 	if (ret < 0)
+ 		goto out_put_cfile;
+ 
++	/*
++	 * The control file must be a regular cgroup1 file. As a regular cgroup
++	 * file can't be renamed, it's safe to access its name afterwards.
++	 */
++	cdentry = cfile.file->f_path.dentry;
++	if (cdentry->d_sb->s_type != &cgroup_fs_type || !d_is_reg(cdentry)) {
++		ret = -EINVAL;
++		goto out_put_cfile;
++	}
++
+ 	/*
+ 	 * Determine the event callbacks and set them in @event.  This used
+ 	 * to be done via struct cftype but cgroup core no longer knows
+@@ -4833,7 +4844,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
+ 	 *
+ 	 * DO NOT ADD NEW FILES.
+ 	 */
+-	name = cfile.file->f_path.dentry->d_name.name;
++	name = cdentry->d_name.name;
+ 
+ 	if (!strcmp(name, "memory.usage_in_bytes")) {
+ 		event->register_event = mem_cgroup_usage_register_event;
+@@ -4857,7 +4868,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
+ 	 * automatically removed on cgroup destruction but the removal is
+ 	 * asynchronous, so take an extra ref on @css.
+ 	 */
+-	cfile_css = css_tryget_online_from_dir(cfile.file->f_path.dentry->d_parent,
++	cfile_css = css_tryget_online_from_dir(cdentry->d_parent,
+ 					       &memory_cgrp_subsys);
+ 	ret = -EINVAL;
+ 	if (IS_ERR(cfile_css))
+diff --git a/mm/memory.c b/mm/memory.c
+index de0dbe09b013f..a0fdaa74091fe 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -1341,15 +1341,6 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma)
+ 	return ret;
+ }
+ 
+-/*
+- * Parameter block passed down to zap_pte_range in exceptional cases.
+- */
+-struct zap_details {
+-	struct folio *single_folio;	/* Locked folio to be unmapped */
+-	bool even_cows;			/* Zap COWed private pages too? */
+-	zap_flags_t zap_flags;		/* Extra flags for zapping */
+-};
+-
+ /* Whether we should zap all COWed (private) pages too */
+ static inline bool should_zap_cows(struct zap_details *details)
+ {
+@@ -1721,7 +1712,7 @@ void unmap_vmas(struct mmu_gather *tlb,
+ {
+ 	struct mmu_notifier_range range;
+ 	struct zap_details details = {
+-		.zap_flags = ZAP_FLAG_DROP_MARKER,
++		.zap_flags = ZAP_FLAG_DROP_MARKER | ZAP_FLAG_UNMAP,
+ 		/* Careful - we need to zap private pages too! */
+ 		.even_cows = true,
+ 	};
+@@ -1769,19 +1760,27 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long start,
+  *
+  * The range must fit into one VMA.
+  */
+-static void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
++void zap_page_range_single(struct vm_area_struct *vma, unsigned long address,
+ 		unsigned long size, struct zap_details *details)
+ {
++	const unsigned long end = address + size;
+ 	struct mmu_notifier_range range;
+ 	struct mmu_gather tlb;
+ 
+ 	lru_add_drain();
+ 	mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma, vma->vm_mm,
+-				address, address + size);
++				address, end);
++	if (is_vm_hugetlb_page(vma))
++		adjust_range_if_pmd_sharing_possible(vma, &range.start,
++						     &range.end);
+ 	tlb_gather_mmu(&tlb, vma->vm_mm);
+ 	update_hiwater_rss(vma->vm_mm);
+ 	mmu_notifier_invalidate_range_start(&range);
+-	unmap_single_vma(&tlb, vma, address, range.end, details);
++	/*
++	 * unmap 'address-end' not 'range.start-range.end' as range
++	 * could have been expanded for hugetlb pmd sharing.
++	 */
++	unmap_single_vma(&tlb, vma, address, end, details);
+ 	mmu_notifier_invalidate_range_end(&range);
+ 	tlb_finish_mmu(&tlb);
+ }
+diff --git a/mm/mmu_gather.c b/mm/mmu_gather.c
+index a71924bd38c0d..ba7d26a291dda 100644
+--- a/mm/mmu_gather.c
++++ b/mm/mmu_gather.c
+@@ -152,7 +152,7 @@ static void tlb_remove_table_smp_sync(void *arg)
+ 	/* Simply deliver the interrupt */
+ }
+ 
+-static void tlb_remove_table_sync_one(void)
++void tlb_remove_table_sync_one(void)
+ {
+ 	/*
+ 	 * This isn't an RCU grace period and hence the page-tables cannot be
+@@ -176,8 +176,6 @@ static void tlb_remove_table_free(struct mmu_table_batch *batch)
+ 
+ #else /* !CONFIG_MMU_GATHER_RCU_TABLE_FREE */
+ 
+-static void tlb_remove_table_sync_one(void) { }
+-
+ static void tlb_remove_table_free(struct mmu_table_batch *batch)
+ {
+ 	__tlb_remove_table_free(batch);
+diff --git a/mm/shmem.c b/mm/shmem.c
+index 42e5888bf84d8..112ebf601bb41 100644
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -958,6 +958,15 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
+ 		index++;
+ 	}
+ 
++	/*
++	 * When undoing a failed fallocate, we want none of the partial folio
++	 * zeroing and splitting below, but shall want to truncate the whole
++	 * folio when !uptodate indicates that it was added by this fallocate,
++	 * even when [lstart, lend] covers only a part of the folio.
++	 */
++	if (unfalloc)
++		goto whole_folios;
++
+ 	same_folio = (lstart >> PAGE_SHIFT) == (lend >> PAGE_SHIFT);
+ 	folio = shmem_get_partial_folio(inode, lstart >> PAGE_SHIFT);
+ 	if (folio) {
+@@ -983,6 +992,8 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_t lend,
+ 		folio_put(folio);
+ 	}
+ 
++whole_folios:
++
+ 	index = start;
+ 	while (index < end) {
+ 		cond_resched();
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index 3e056fb043bb1..080b5de3e1ed8 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -120,7 +120,7 @@ struct p9_conn {
+ 	struct list_head unsent_req_list;
+ 	struct p9_req_t *rreq;
+ 	struct p9_req_t *wreq;
+-	char tmp_buf[7];
++	char tmp_buf[P9_HDRSZ];
+ 	struct p9_fcall rc;
+ 	int wpos;
+ 	int wsize;
+@@ -293,7 +293,7 @@ static void p9_read_work(struct work_struct *work)
+ 	if (!m->rc.sdata) {
+ 		m->rc.sdata = m->tmp_buf;
+ 		m->rc.offset = 0;
+-		m->rc.capacity = 7; /* start by reading header */
++		m->rc.capacity = P9_HDRSZ; /* start by reading header */
+ 	}
+ 
+ 	clear_bit(Rpending, &m->wsched);
+@@ -316,7 +316,7 @@ static void p9_read_work(struct work_struct *work)
+ 		p9_debug(P9_DEBUG_TRANS, "got new header\n");
+ 
+ 		/* Header size */
+-		m->rc.size = 7;
++		m->rc.size = P9_HDRSZ;
+ 		err = p9_parse_header(&m->rc, &m->rc.size, NULL, NULL, 0);
+ 		if (err) {
+ 			p9_debug(P9_DEBUG_ERROR,
+diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
+index 227f89cc7237c..0f862d5a59601 100644
+--- a/net/9p/trans_xen.c
++++ b/net/9p/trans_xen.c
+@@ -208,6 +208,14 @@ static void p9_xen_response(struct work_struct *work)
+ 			continue;
+ 		}
+ 
++		if (h.size > req->rc.capacity) {
++			dev_warn(&priv->dev->dev,
++				 "requested packet size too big: %d for tag %d with capacity %zd\n",
++				 h.size, h.tag, req->rc.capacity);
++			req->status = REQ_STATUS_ERROR;
++			goto recv_error;
++		}
++
+ 		memcpy(&req->rc, &h, sizeof(h));
+ 		req->rc.offset = 0;
+ 
+@@ -217,6 +225,7 @@ static void p9_xen_response(struct work_struct *work)
+ 				     masked_prod, &masked_cons,
+ 				     XEN_9PFS_RING_SIZE(ring));
+ 
++recv_error:
+ 		virt_mb();
+ 		cons += h.size;
+ 		ring->intf->in_cons = cons;
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 215af9b3b5895..c57d643afb108 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -972,6 +972,7 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
+ 	hci_dev_lock(hdev);
+ 	hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type);
+ 	hci_dev_unlock(hdev);
++	hci_dev_put(hdev);
+ 
+ 	if (!hcon)
+ 		return -ENOENT;
+diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
+index dc65974f5adb1..1c3c7ff5c3c66 100644
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -737,7 +737,7 @@ static int __init bt_init(void)
+ 
+ 	err = bt_sysfs_init();
+ 	if (err < 0)
+-		return err;
++		goto cleanup_led;
+ 
+ 	err = sock_register(&bt_sock_family_ops);
+ 	if (err)
+@@ -773,6 +773,8 @@ unregister_socket:
+ 	sock_unregister(PF_BLUETOOTH);
+ cleanup_sysfs:
+ 	bt_sysfs_cleanup();
++cleanup_led:
++	bt_leds_cleanup();
+ 	return err;
+ }
+ 
+diff --git a/net/bluetooth/hci_codec.c b/net/bluetooth/hci_codec.c
+index 38201532f58e8..3cc135bb1d30c 100644
+--- a/net/bluetooth/hci_codec.c
++++ b/net/bluetooth/hci_codec.c
+@@ -72,9 +72,8 @@ static void hci_read_codec_capabilities(struct hci_dev *hdev, __u8 transport,
+ 				continue;
+ 			}
+ 
+-			skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS,
+-					     sizeof(*cmd), cmd,
+-					     HCI_CMD_TIMEOUT);
++			skb = __hci_cmd_sync_sk(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS,
++						sizeof(*cmd), cmd, 0, HCI_CMD_TIMEOUT, NULL);
+ 			if (IS_ERR(skb)) {
+ 				bt_dev_err(hdev, "Failed to read codec capabilities (%ld)",
+ 					   PTR_ERR(skb));
+@@ -127,8 +126,8 @@ void hci_read_supported_codecs(struct hci_dev *hdev)
+ 	struct hci_op_read_local_codec_caps caps;
+ 	__u8 i;
+ 
+-	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODECS, 0, NULL,
+-			     HCI_CMD_TIMEOUT);
++	skb = __hci_cmd_sync_sk(hdev, HCI_OP_READ_LOCAL_CODECS, 0, NULL,
++				0, HCI_CMD_TIMEOUT, NULL);
+ 
+ 	if (IS_ERR(skb)) {
+ 		bt_dev_err(hdev, "Failed to read local supported codecs (%ld)",
+@@ -158,7 +157,8 @@ void hci_read_supported_codecs(struct hci_dev *hdev)
+ 	for (i = 0; i < std_codecs->num; i++) {
+ 		caps.id = std_codecs->codec[i];
+ 		caps.direction = 0x00;
+-		hci_read_codec_capabilities(hdev, LOCAL_CODEC_ACL_MASK, &caps);
++		hci_read_codec_capabilities(hdev,
++					    LOCAL_CODEC_ACL_MASK | LOCAL_CODEC_SCO_MASK, &caps);
+ 	}
+ 
+ 	skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num)
+@@ -178,7 +178,8 @@ void hci_read_supported_codecs(struct hci_dev *hdev)
+ 		caps.cid = vnd_codecs->codec[i].cid;
+ 		caps.vid = vnd_codecs->codec[i].vid;
+ 		caps.direction = 0x00;
+-		hci_read_codec_capabilities(hdev, LOCAL_CODEC_ACL_MASK, &caps);
++		hci_read_codec_capabilities(hdev,
++					    LOCAL_CODEC_ACL_MASK | LOCAL_CODEC_SCO_MASK, &caps);
+ 	}
+ 
+ error:
+@@ -194,8 +195,8 @@ void hci_read_supported_codecs_v2(struct hci_dev *hdev)
+ 	struct hci_op_read_local_codec_caps caps;
+ 	__u8 i;
+ 
+-	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODECS_V2, 0, NULL,
+-			     HCI_CMD_TIMEOUT);
++	skb = __hci_cmd_sync_sk(hdev, HCI_OP_READ_LOCAL_CODECS_V2, 0, NULL,
++				0, HCI_CMD_TIMEOUT, NULL);
+ 
+ 	if (IS_ERR(skb)) {
+ 		bt_dev_err(hdev, "Failed to read local supported codecs (%ld)",
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 6ae5aa5c0927b..c8ea03edd081f 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -2757,7 +2757,8 @@ int hci_register_suspend_notifier(struct hci_dev *hdev)
+ {
+ 	int ret = 0;
+ 
+-	if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
++	if (!hdev->suspend_notifier.notifier_call &&
++	    !test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
+ 		hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
+ 		ret = register_pm_notifier(&hdev->suspend_notifier);
+ 	}
+@@ -2769,8 +2770,11 @@ int hci_unregister_suspend_notifier(struct hci_dev *hdev)
+ {
+ 	int ret = 0;
+ 
+-	if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks))
++	if (hdev->suspend_notifier.notifier_call) {
+ 		ret = unregister_pm_notifier(&hdev->suspend_notifier);
++		if (!ret)
++			hdev->suspend_notifier.notifier_call = NULL;
++	}
+ 
+ 	return ret;
+ }
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index f70798589bf51..a5e89e1b5452a 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -12,6 +12,7 @@
+ #include <net/bluetooth/mgmt.h>
+ 
+ #include "hci_request.h"
++#include "hci_codec.h"
+ #include "hci_debugfs.h"
+ #include "smp.h"
+ #include "eir.h"
+@@ -3459,7 +3460,8 @@ static int hci_read_page_scan_activity_sync(struct hci_dev *hdev)
+ static int hci_read_def_err_data_reporting_sync(struct hci_dev *hdev)
+ {
+ 	if (!(hdev->commands[18] & 0x04) ||
+-	    !(hdev->features[0][6] & LMP_ERR_DATA_REPORTING))
++	    !(hdev->features[0][6] & LMP_ERR_DATA_REPORTING) ||
++	    test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks))
+ 		return 0;
+ 
+ 	return __hci_cmd_sync_status(hdev, HCI_OP_READ_DEF_ERR_DATA_REPORTING,
+@@ -3917,11 +3919,12 @@ static int hci_set_event_mask_page_2_sync(struct hci_dev *hdev)
+ /* Read local codec list if the HCI command is supported */
+ static int hci_read_local_codecs_sync(struct hci_dev *hdev)
+ {
+-	if (!(hdev->commands[29] & 0x20))
+-		return 0;
++	if (hdev->commands[45] & 0x04)
++		hci_read_supported_codecs_v2(hdev);
++	else if (hdev->commands[29] & 0x20)
++		hci_read_supported_codecs(hdev);
+ 
+-	return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_CODECS, 0, NULL,
+-				     HCI_CMD_TIMEOUT);
++	return 0;
+ }
+ 
+ /* Read local pairing options if the HCI command is supported */
+@@ -3977,7 +3980,8 @@ static int hci_set_err_data_report_sync(struct hci_dev *hdev)
+ 	bool enabled = hci_dev_test_flag(hdev, HCI_WIDEBAND_SPEECH_ENABLED);
+ 
+ 	if (!(hdev->commands[18] & 0x08) ||
+-	    !(hdev->features[0][6] & LMP_ERR_DATA_REPORTING))
++	    !(hdev->features[0][6] & LMP_ERR_DATA_REPORTING) ||
++	    test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks))
+ 		return 0;
+ 
+ 	if (enabled == hdev->err_data_reporting)
+@@ -4136,6 +4140,9 @@ static const struct {
+ 	HCI_QUIRK_BROKEN(STORED_LINK_KEY,
+ 			 "HCI Delete Stored Link Key command is advertised, "
+ 			 "but not supported."),
++	HCI_QUIRK_BROKEN(ERR_DATA_REPORTING,
++			 "HCI Read Default Erroneous Data Reporting command is "
++			 "advertised, but not supported."),
+ 	HCI_QUIRK_BROKEN(READ_TRANSMIT_POWER,
+ 			 "HCI Read Transmit Power Level command is advertised, "
+ 			 "but not supported."),
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index f825857db6d0b..26db929b97c43 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -879,6 +879,7 @@ static int iso_listen_bis(struct sock *sk)
+ 				 iso_pi(sk)->bc_sid);
+ 
+ 	hci_dev_unlock(hdev);
++	hci_dev_put(hdev);
+ 
+ 	return err;
+ }
+diff --git a/net/can/af_can.c b/net/can/af_can.c
+index e48ccf7cf2007..461fa7c04464b 100644
+--- a/net/can/af_can.c
++++ b/net/can/af_can.c
+@@ -680,7 +680,7 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
+ {
+ 	struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
+ 
+-	if (unlikely(dev->type != ARPHRD_CAN || skb->len != CAN_MTU)) {
++	if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || skb->len != CAN_MTU)) {
+ 		pr_warn_once("PF_CAN: dropped non conform CAN skbuff: dev type %d, len %d\n",
+ 			     dev->type, skb->len);
+ 		goto free_skb;
+@@ -706,7 +706,7 @@ static int canfd_rcv(struct sk_buff *skb, struct net_device *dev,
+ {
+ 	struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
+ 
+-	if (unlikely(dev->type != ARPHRD_CAN || skb->len != CANFD_MTU)) {
++	if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || skb->len != CANFD_MTU)) {
+ 		pr_warn_once("PF_CAN: dropped non conform CAN FD skbuff: dev type %d, len %d\n",
+ 			     dev->type, skb->len);
+ 		goto free_skb;
+diff --git a/net/dsa/tag_hellcreek.c b/net/dsa/tag_hellcreek.c
+index 846588c0070a5..53a206d116850 100644
+--- a/net/dsa/tag_hellcreek.c
++++ b/net/dsa/tag_hellcreek.c
+@@ -49,7 +49,8 @@ static struct sk_buff *hellcreek_rcv(struct sk_buff *skb,
+ 		return NULL;
+ 	}
+ 
+-	pskb_trim_rcsum(skb, skb->len - HELLCREEK_TAG_LEN);
++	if (pskb_trim_rcsum(skb, skb->len - HELLCREEK_TAG_LEN))
++		return NULL;
+ 
+ 	dsa_default_offload_fwd_mark(skb);
+ 
+diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
+index 38fa19c1e2d5e..429250298ac4b 100644
+--- a/net/dsa/tag_ksz.c
++++ b/net/dsa/tag_ksz.c
+@@ -21,7 +21,8 @@ static struct sk_buff *ksz_common_rcv(struct sk_buff *skb,
+ 	if (!skb->dev)
+ 		return NULL;
+ 
+-	pskb_trim_rcsum(skb, skb->len - len);
++	if (pskb_trim_rcsum(skb, skb->len - len))
++		return NULL;
+ 
+ 	dsa_default_offload_fwd_mark(skb);
+ 
+diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
+index 83e4136516b02..1a85125bda6da 100644
+--- a/net/dsa/tag_sja1105.c
++++ b/net/dsa/tag_sja1105.c
+@@ -665,7 +665,8 @@ static struct sk_buff *sja1110_rcv_inband_control_extension(struct sk_buff *skb,
+ 		 * padding and trailer we need to account for the fact that
+ 		 * skb->data points to skb_mac_header(skb) + ETH_HLEN.
+ 		 */
+-		pskb_trim_rcsum(skb, start_of_padding - ETH_HLEN);
++		if (pskb_trim_rcsum(skb, start_of_padding - ETH_HLEN))
++			return NULL;
+ 	/* Trap-to-host frame, no timestamp trailer */
+ 	} else {
+ 		*source_port = SJA1110_RX_HEADER_SRC_PORT(rx_header);
+diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
+index 943edf4ad4db0..3528e8befa58f 100644
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -841,6 +841,9 @@ static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
+ 		return -EINVAL;
+ 	}
+ 
++	if (!cfg->fc_table)
++		cfg->fc_table = RT_TABLE_MAIN;
++
+ 	return 0;
+ errout:
+ 	return err;
+diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
+index cb24260692e10..7885b2f15315e 100644
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -423,6 +423,7 @@ static struct fib_info *fib_find_info(struct fib_info *nfi)
+ 		    nfi->fib_prefsrc == fi->fib_prefsrc &&
+ 		    nfi->fib_priority == fi->fib_priority &&
+ 		    nfi->fib_type == fi->fib_type &&
++		    nfi->fib_tb_id == fi->fib_tb_id &&
+ 		    memcmp(nfi->fib_metrics, fi->fib_metrics,
+ 			   sizeof(u32) * RTAX_MAX) == 0 &&
+ 		    !((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_COMPARE_MASK) &&
+diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
+index f866d6282b2b3..cae9f1a4e059f 100644
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -1492,24 +1492,6 @@ static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
+ 	struct ip_tunnel_parm *p = &t->parms;
+ 	__be16 o_flags = p->o_flags;
+ 
+-	if (t->erspan_ver <= 2) {
+-		if (t->erspan_ver != 0 && !t->collect_md)
+-			o_flags |= TUNNEL_KEY;
+-
+-		if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, t->erspan_ver))
+-			goto nla_put_failure;
+-
+-		if (t->erspan_ver == 1) {
+-			if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index))
+-				goto nla_put_failure;
+-		} else if (t->erspan_ver == 2) {
+-			if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, t->dir))
+-				goto nla_put_failure;
+-			if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, t->hwid))
+-				goto nla_put_failure;
+-		}
+-	}
+-
+ 	if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
+ 	    nla_put_be16(skb, IFLA_GRE_IFLAGS,
+ 			 gre_tnl_flags_to_gre_flags(p->i_flags)) ||
+@@ -1550,6 +1532,34 @@ nla_put_failure:
+ 	return -EMSGSIZE;
+ }
+ 
++static int erspan_fill_info(struct sk_buff *skb, const struct net_device *dev)
++{
++	struct ip_tunnel *t = netdev_priv(dev);
++
++	if (t->erspan_ver <= 2) {
++		if (t->erspan_ver != 0 && !t->collect_md)
++			t->parms.o_flags |= TUNNEL_KEY;
++
++		if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, t->erspan_ver))
++			goto nla_put_failure;
++
++		if (t->erspan_ver == 1) {
++			if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index))
++				goto nla_put_failure;
++		} else if (t->erspan_ver == 2) {
++			if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, t->dir))
++				goto nla_put_failure;
++			if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, t->hwid))
++				goto nla_put_failure;
++		}
++	}
++
++	return ipgre_fill_info(skb, dev);
++
++nla_put_failure:
++	return -EMSGSIZE;
++}
++
+ static void erspan_setup(struct net_device *dev)
+ {
+ 	struct ip_tunnel *t = netdev_priv(dev);
+@@ -1628,7 +1638,7 @@ static struct rtnl_link_ops erspan_link_ops __read_mostly = {
+ 	.changelink	= erspan_changelink,
+ 	.dellink	= ip_tunnel_dellink,
+ 	.get_size	= ipgre_get_size,
+-	.fill_info	= ipgre_fill_info,
++	.fill_info	= erspan_fill_info,
+ 	.get_link_net	= ip_tunnel_get_link_net,
+ };
+ 
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index b83c2bd9d7223..3b2420829c237 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -48,6 +48,11 @@
+ #include <net/transp_v6.h>
+ #endif
+ 
++#define ping_portaddr_for_each_entry(__sk, node, list) \
++	hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
++#define ping_portaddr_for_each_entry_rcu(__sk, node, list) \
++	hlist_nulls_for_each_entry_rcu(__sk, node, list, sk_nulls_node)
++
+ struct ping_table {
+ 	struct hlist_nulls_head	hash[PING_HTABLE_SIZE];
+ 	spinlock_t		lock;
+@@ -191,7 +196,7 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
+ 		return NULL;
+ 	}
+ 
+-	ping_portaddr_for_each_entry(sk, hnode, hslot) {
++	ping_portaddr_for_each_entry_rcu(sk, hnode, hslot) {
+ 		isk = inet_sk(sk);
+ 
+ 		pr_debug("iterate\n");
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index f152e51242cb6..4fb5dd35af188 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -920,6 +920,9 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
+ 		if (err < 0)
+ 			goto fail;
+ 
++		/* We prevent @rt from being freed. */
++		rcu_read_lock();
++
+ 		for (;;) {
+ 			/* Prepare header of the next frame,
+ 			 * before previous one went down. */
+@@ -943,6 +946,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
+ 		if (err == 0) {
+ 			IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
+ 				      IPSTATS_MIB_FRAGOKS);
++			rcu_read_unlock();
+ 			return 0;
+ 		}
+ 
+@@ -950,6 +954,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
+ 
+ 		IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
+ 			      IPSTATS_MIB_FRAGFAILS);
++		rcu_read_unlock();
+ 		return err;
+ 
+ slow_path_clean:
+diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
+index 500ed1b812503..7e2065e729156 100644
+--- a/net/mac802154/iface.c
++++ b/net/mac802154/iface.c
+@@ -662,6 +662,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
+ 	sdata->dev = ndev;
+ 	sdata->wpan_dev.wpan_phy = local->hw.phy;
+ 	sdata->local = local;
++	INIT_LIST_HEAD(&sdata->wpan_dev.list);
+ 
+ 	/* setup type-dependent data */
+ 	ret = ieee802154_setup_sdata(sdata, type);
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 60289c074eef4..df46e9a35e47a 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -891,7 +891,7 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
+ 	zone = nf_ct_zone(ct);
+ 
+ 	if (!nf_ct_ext_valid_pre(ct->ext)) {
+-		NF_CT_STAT_INC(net, insert_failed);
++		NF_CT_STAT_INC_ATOMIC(net, insert_failed);
+ 		return -ETIMEDOUT;
+ 	}
+ 
+@@ -938,7 +938,7 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
+ 
+ 	if (!nf_ct_ext_valid_post(ct->ext)) {
+ 		nf_ct_kill(ct);
+-		NF_CT_STAT_INC(net, drop);
++		NF_CT_STAT_INC_ATOMIC(net, drop);
+ 		return -ETIMEDOUT;
+ 	}
+ 
+@@ -1275,7 +1275,7 @@ chaintoolong:
+ 	 */
+ 	if (!nf_ct_ext_valid_post(ct->ext)) {
+ 		nf_ct_kill(ct);
+-		NF_CT_STAT_INC(net, drop);
++		NF_CT_STAT_INC_ATOMIC(net, drop);
+ 		return NF_DROP;
+ 	}
+ 
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index d71150a40fb08..1286ae7d46096 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -328,8 +328,13 @@ nla_put_failure:
+ }
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark)
++static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
+ {
++	u32 mark = READ_ONCE(ct->mark);
++
++	if (!mark)
++		return 0;
++
+ 	if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
+ 		goto nla_put_failure;
+ 	return 0;
+@@ -543,7 +548,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
+ static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ 	if (ctnetlink_dump_status(skb, ct) < 0 ||
+-	    ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 ||
++	    ctnetlink_dump_mark(skb, ct) < 0 ||
+ 	    ctnetlink_dump_secctx(skb, ct) < 0 ||
+ 	    ctnetlink_dump_id(skb, ct) < 0 ||
+ 	    ctnetlink_dump_use(skb, ct) < 0 ||
+@@ -722,7 +727,6 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ 	struct sk_buff *skb;
+ 	unsigned int type;
+ 	unsigned int flags = 0, group;
+-	u32 mark;
+ 	int err;
+ 
+ 	if (events & (1 << IPCT_DESTROY)) {
+@@ -827,9 +831,8 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ 	}
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-	mark = READ_ONCE(ct->mark);
+-	if ((events & (1 << IPCT_MARK) || mark) &&
+-	    ctnetlink_dump_mark(skb, mark) < 0)
++	if (events & (1 << IPCT_MARK) &&
++	    ctnetlink_dump_mark(skb, ct) < 0)
+ 		goto nla_put_failure;
+ #endif
+ 	nlmsg_end(skb, nlh);
+@@ -2671,7 +2674,6 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ 	const struct nf_conntrack_zone *zone;
+ 	struct nlattr *nest_parms;
+-	u32 mark;
+ 
+ 	zone = nf_ct_zone(ct);
+ 
+@@ -2733,8 +2735,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ 		goto nla_put_failure;
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-	mark = READ_ONCE(ct->mark);
+-	if (mark && ctnetlink_dump_mark(skb, mark) < 0)
++	if (ctnetlink_dump_mark(skb, ct) < 0)
+ 		goto nla_put_failure;
+ #endif
+ 	if (ctnetlink_dump_labels(skb, ct) < 0)
+diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
+index 00b522890d77b..0fdcdb2c9ae43 100644
+--- a/net/netfilter/nf_flow_table_offload.c
++++ b/net/netfilter/nf_flow_table_offload.c
+@@ -997,13 +997,13 @@ static void flow_offload_queue_work(struct flow_offload_work *offload)
+ 	struct net *net = read_pnet(&offload->flowtable->net);
+ 
+ 	if (offload->cmd == FLOW_CLS_REPLACE) {
+-		NF_FLOW_TABLE_STAT_INC(net, count_wq_add);
++		NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count_wq_add);
+ 		queue_work(nf_flow_offload_add_wq, &offload->work);
+ 	} else if (offload->cmd == FLOW_CLS_DESTROY) {
+-		NF_FLOW_TABLE_STAT_INC(net, count_wq_del);
++		NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count_wq_del);
+ 		queue_work(nf_flow_offload_del_wq, &offload->work);
+ 	} else {
+-		NF_FLOW_TABLE_STAT_INC(net, count_wq_stats);
++		NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count_wq_stats);
+ 		queue_work(nf_flow_offload_stats_wq, &offload->work);
+ 	}
+ }
+diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
+index 4f9299b9dcddc..06d46d1826347 100644
+--- a/net/netfilter/nft_set_pipapo.c
++++ b/net/netfilter/nft_set_pipapo.c
+@@ -1162,6 +1162,7 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
+ 	struct nft_pipapo_match *m = priv->clone;
+ 	u8 genmask = nft_genmask_next(net);
+ 	struct nft_pipapo_field *f;
++	const u8 *start_p, *end_p;
+ 	int i, bsize_max, err = 0;
+ 
+ 	if (nft_set_ext_exists(ext, NFT_SET_EXT_KEY_END))
+@@ -1202,9 +1203,9 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
+ 	}
+ 
+ 	/* Validate */
++	start_p = start;
++	end_p = end;
+ 	nft_pipapo_for_each_field(f, i, m) {
+-		const u8 *start_p = start, *end_p = end;
+-
+ 		if (f->rules >= (unsigned long)NFT_PIPAPO_RULE0_MAX)
+ 			return -ENOSPC;
+ 
+diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c
+index 282c51051dccd..994a0a1efb589 100644
+--- a/net/nfc/nci/ntf.c
++++ b/net/nfc/nci/ntf.c
+@@ -240,6 +240,8 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
+ 		target->sens_res = nfca_poll->sens_res;
+ 		target->sel_res = nfca_poll->sel_res;
+ 		target->nfcid1_len = nfca_poll->nfcid1_len;
++		if (target->nfcid1_len > ARRAY_SIZE(target->nfcid1))
++			return -EPROTO;
+ 		if (target->nfcid1_len > 0) {
+ 			memcpy(target->nfcid1, nfca_poll->nfcid1,
+ 			       target->nfcid1_len);
+@@ -248,6 +250,8 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
+ 		nfcb_poll = (struct rf_tech_specific_params_nfcb_poll *)params;
+ 
+ 		target->sensb_res_len = nfcb_poll->sensb_res_len;
++		if (target->sensb_res_len > ARRAY_SIZE(target->sensb_res))
++			return -EPROTO;
+ 		if (target->sensb_res_len > 0) {
+ 			memcpy(target->sensb_res, nfcb_poll->sensb_res,
+ 			       target->sensb_res_len);
+@@ -256,6 +260,8 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
+ 		nfcf_poll = (struct rf_tech_specific_params_nfcf_poll *)params;
+ 
+ 		target->sensf_res_len = nfcf_poll->sensf_res_len;
++		if (target->sensf_res_len > ARRAY_SIZE(target->sensf_res))
++			return -EPROTO;
+ 		if (target->sensf_res_len > 0) {
+ 			memcpy(target->sensf_res, nfcf_poll->sensf_res,
+ 			       target->sensf_res_len);
+diff --git a/net/tipc/link.c b/net/tipc/link.c
+index e260c0d557f5c..b3ce24823f503 100644
+--- a/net/tipc/link.c
++++ b/net/tipc/link.c
+@@ -2224,7 +2224,9 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
+ 	if (tipc_own_addr(l->net) > msg_prevnode(hdr))
+ 		l->net_plane = msg_net_plane(hdr);
+ 
+-	skb_linearize(skb);
++	if (skb_linearize(skb))
++		goto exit;
++
+ 	hdr = buf_msg(skb);
+ 	data = msg_data(hdr);
+ 
+diff --git a/net/tipc/node.c b/net/tipc/node.c
+index b48d97cbbe29c..49ddc484c4fe7 100644
+--- a/net/tipc/node.c
++++ b/net/tipc/node.c
+@@ -1689,6 +1689,7 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
+ 	struct tipc_node *n;
+ 	struct sk_buff_head xmitq;
+ 	bool node_up = false;
++	struct net *peer_net;
+ 	int bearer_id;
+ 	int rc;
+ 
+@@ -1705,18 +1706,23 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
+ 		return -EHOSTUNREACH;
+ 	}
+ 
++	rcu_read_lock();
+ 	tipc_node_read_lock(n);
+ 	node_up = node_is_up(n);
+-	if (node_up && n->peer_net && check_net(n->peer_net)) {
++	peer_net = n->peer_net;
++	tipc_node_read_unlock(n);
++	if (node_up && peer_net && check_net(peer_net)) {
+ 		/* xmit inner linux container */
+-		tipc_lxc_xmit(n->peer_net, list);
++		tipc_lxc_xmit(peer_net, list);
+ 		if (likely(skb_queue_empty(list))) {
+-			tipc_node_read_unlock(n);
++			rcu_read_unlock();
+ 			tipc_node_put(n);
+ 			return 0;
+ 		}
+ 	}
++	rcu_read_unlock();
+ 
++	tipc_node_read_lock(n);
+ 	bearer_id = n->active_links[selector & 1];
+ 	if (unlikely(bearer_id == INVALID_BEARER_ID)) {
+ 		tipc_node_read_unlock(n);
+diff --git a/net/unix/diag.c b/net/unix/diag.c
+index 105f522a89fe0..616b55c5b8908 100644
+--- a/net/unix/diag.c
++++ b/net/unix/diag.c
+@@ -114,14 +114,16 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb)
+ 	return nla_put(nlskb, UNIX_DIAG_RQLEN, sizeof(rql), &rql);
+ }
+ 
+-static int sk_diag_dump_uid(struct sock *sk, struct sk_buff *nlskb)
++static int sk_diag_dump_uid(struct sock *sk, struct sk_buff *nlskb,
++			    struct user_namespace *user_ns)
+ {
+-	uid_t uid = from_kuid_munged(sk_user_ns(nlskb->sk), sock_i_uid(sk));
++	uid_t uid = from_kuid_munged(user_ns, sock_i_uid(sk));
+ 	return nla_put(nlskb, UNIX_DIAG_UID, sizeof(uid_t), &uid);
+ }
+ 
+ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
+-		u32 portid, u32 seq, u32 flags, int sk_ino)
++			struct user_namespace *user_ns,
++			u32 portid, u32 seq, u32 flags, int sk_ino)
+ {
+ 	struct nlmsghdr *nlh;
+ 	struct unix_diag_msg *rep;
+@@ -167,7 +169,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
+ 		goto out_nlmsg_trim;
+ 
+ 	if ((req->udiag_show & UDIAG_SHOW_UID) &&
+-	    sk_diag_dump_uid(sk, skb))
++	    sk_diag_dump_uid(sk, skb, user_ns))
+ 		goto out_nlmsg_trim;
+ 
+ 	nlmsg_end(skb, nlh);
+@@ -179,7 +181,8 @@ out_nlmsg_trim:
+ }
+ 
+ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
+-		u32 portid, u32 seq, u32 flags)
++			struct user_namespace *user_ns,
++			u32 portid, u32 seq, u32 flags)
+ {
+ 	int sk_ino;
+ 
+@@ -190,7 +193,7 @@ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
+ 	if (!sk_ino)
+ 		return 0;
+ 
+-	return sk_diag_fill(sk, skb, req, portid, seq, flags, sk_ino);
++	return sk_diag_fill(sk, skb, req, user_ns, portid, seq, flags, sk_ino);
+ }
+ 
+ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
+@@ -214,7 +217,7 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
+ 				goto next;
+ 			if (!(req->udiag_states & (1 << sk->sk_state)))
+ 				goto next;
+-			if (sk_diag_dump(sk, skb, req,
++			if (sk_diag_dump(sk, skb, req, sk_user_ns(skb->sk),
+ 					 NETLINK_CB(cb->skb).portid,
+ 					 cb->nlh->nlmsg_seq,
+ 					 NLM_F_MULTI) < 0) {
+@@ -282,7 +285,8 @@ again:
+ 	if (!rep)
+ 		goto out;
+ 
+-	err = sk_diag_fill(sk, rep, req, NETLINK_CB(in_skb).portid,
++	err = sk_diag_fill(sk, rep, req, sk_user_ns(NETLINK_CB(in_skb).sk),
++			   NETLINK_CB(in_skb).portid,
+ 			   nlh->nlmsg_seq, 0, req->udiag_ino);
+ 	if (err < 0) {
+ 		nlmsg_free(rep);
+diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
+index b7aee23fc3876..47ef6bc30c0ee 100644
+--- a/sound/core/seq/seq_memory.c
++++ b/sound/core/seq/seq_memory.c
+@@ -113,15 +113,19 @@ EXPORT_SYMBOL(snd_seq_dump_var_event);
+  * expand the variable length event to linear buffer space.
+  */
+ 
+-static int seq_copy_in_kernel(char **bufptr, const void *src, int size)
++static int seq_copy_in_kernel(void *ptr, void *src, int size)
+ {
++	char **bufptr = ptr;
++
+ 	memcpy(*bufptr, src, size);
+ 	*bufptr += size;
+ 	return 0;
+ }
+ 
+-static int seq_copy_in_user(char __user **bufptr, const void *src, int size)
++static int seq_copy_in_user(void *ptr, void *src, int size)
+ {
++	char __user **bufptr = ptr;
++
+ 	if (copy_to_user(*bufptr, src, size))
+ 		return -EFAULT;
+ 	*bufptr += size;
+@@ -151,8 +155,7 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char
+ 		return newlen;
+ 	}
+ 	err = snd_seq_dump_var_event(event,
+-				     in_kernel ? (snd_seq_dump_func_t)seq_copy_in_kernel :
+-				     (snd_seq_dump_func_t)seq_copy_in_user,
++				     in_kernel ? seq_copy_in_kernel : seq_copy_in_user,
+ 				     &buf);
+ 	return err < 0 ? err : newlen;
+ }
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index bf58e98c7a699..d8c6af9e43ad6 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -18,6 +18,7 @@
+ #include <linux/module.h>
+ #include <linux/input.h>
+ #include <linux/leds.h>
++#include <linux/ctype.h>
+ #include <sound/core.h>
+ #include <sound/jack.h>
+ #include <sound/hda_codec.h>
+@@ -6704,23 +6705,51 @@ static void comp_generic_playback_hook(struct hda_pcm_stream *hinfo, struct hda_
+ 	}
+ }
+ 
++struct cs35l41_dev_name {
++	const char *bus;
++	const char *hid;
++	int index;
++};
++
++/* match the device name in a slightly relaxed manner */
++static int comp_match_cs35l41_dev_name(struct device *dev, void *data)
++{
++	struct cs35l41_dev_name *p = data;
++	const char *d = dev_name(dev);
++	int n = strlen(p->bus);
++	char tmp[32];
++
++	/* check the bus name */
++	if (strncmp(d, p->bus, n))
++		return 0;
++	/* skip the bus number */
++	if (isdigit(d[n]))
++		n++;
++	/* the rest must be exact matching */
++	snprintf(tmp, sizeof(tmp), "-%s:00-cs35l41-hda.%d", p->hid, p->index);
++	return !strcmp(d + n, tmp);
++}
++
+ static void cs35l41_generic_fixup(struct hda_codec *cdc, int action, const char *bus,
+ 				  const char *hid, int count)
+ {
+ 	struct device *dev = hda_codec_dev(cdc);
+ 	struct alc_spec *spec = cdc->spec;
+-	char *name;
++	struct cs35l41_dev_name *rec;
+ 	int ret, i;
+ 
+ 	switch (action) {
+ 	case HDA_FIXUP_ACT_PRE_PROBE:
+ 		for (i = 0; i < count; i++) {
+-			name = devm_kasprintf(dev, GFP_KERNEL,
+-					      "%s-%s:00-cs35l41-hda.%d", bus, hid, i);
+-			if (!name)
++			rec = devm_kmalloc(dev, sizeof(*rec), GFP_KERNEL);
++			if (!rec)
+ 				return;
++			rec->bus = bus;
++			rec->hid = hid;
++			rec->index = i;
+ 			spec->comps[i].codec = cdc;
+-			component_match_add(dev, &spec->match, component_compare_dev_name, name);
++			component_match_add(dev, &spec->match,
++					    comp_match_cs35l41_dev_name, rec);
+ 		}
+ 		ret = component_master_add_with_match(dev, &comp_master_ops, spec->match);
+ 		if (ret)
+@@ -6738,17 +6767,12 @@ static void cs35l41_fixup_i2c_two(struct hda_codec *cdc, const struct hda_fixup
+ 
+ static void cs35l41_fixup_spi_two(struct hda_codec *codec, const struct hda_fixup *fix, int action)
+ {
+-	cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 2);
+-}
+-
+-static void cs35l41_fixup_spi1_two(struct hda_codec *codec, const struct hda_fixup *fix, int action)
+-{
+-	cs35l41_generic_fixup(codec, action, "spi1", "CSC3551", 2);
++	cs35l41_generic_fixup(codec, action, "spi", "CSC3551", 2);
+ }
+ 
+ static void cs35l41_fixup_spi_four(struct hda_codec *codec, const struct hda_fixup *fix, int action)
+ {
+-	cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 4);
++	cs35l41_generic_fixup(codec, action, "spi", "CSC3551", 4);
+ }
+ 
+ static void alc287_fixup_legion_16achg6_speakers(struct hda_codec *cdc, const struct hda_fixup *fix,
+@@ -7137,8 +7161,6 @@ enum {
+ 	ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED,
+ 	ALC245_FIXUP_CS35L41_SPI_2,
+ 	ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED,
+-	ALC245_FIXUP_CS35L41_SPI1_2,
+-	ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED,
+ 	ALC245_FIXUP_CS35L41_SPI_4,
+ 	ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED,
+ 	ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
+@@ -8988,16 +9010,6 @@ static const struct hda_fixup alc269_fixups[] = {
+ 		.chained = true,
+ 		.chain_id = ALC285_FIXUP_HP_GPIO_LED,
+ 	},
+-	[ALC245_FIXUP_CS35L41_SPI1_2] = {
+-		.type = HDA_FIXUP_FUNC,
+-		.v.func = cs35l41_fixup_spi1_two,
+-	},
+-	[ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED] = {
+-		.type = HDA_FIXUP_FUNC,
+-		.v.func = cs35l41_fixup_spi1_two,
+-		.chained = true,
+-		.chain_id = ALC285_FIXUP_HP_GPIO_LED,
+-	},
+ 	[ALC245_FIXUP_CS35L41_SPI_4] = {
+ 		.type = HDA_FIXUP_FUNC,
+ 		.v.func = cs35l41_fixup_spi_four,
+@@ -9361,7 +9373,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8aa8, "HP EliteBook 640 G9 (MB 8AA6)", ALC236_FIXUP_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8aab, "HP EliteBook 650 G9 (MB 8AA9)", ALC236_FIXUP_HP_GPIO_LED),
+-	 SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED),
++	 SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
+diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c
+index a085b2f530aa1..31e77d462ef34 100644
+--- a/sound/soc/codecs/rt711-sdca-sdw.c
++++ b/sound/soc/codecs/rt711-sdca-sdw.c
+@@ -230,7 +230,7 @@ static int rt711_sdca_read_prop(struct sdw_slave *slave)
+ 	}
+ 
+ 	/* set the timeout values */
+-	prop->clk_stop_timeout = 20;
++	prop->clk_stop_timeout = 700;
+ 
+ 	/* wake-up event */
+ 	prop->wake_capable = 1;
+diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
+index 6df06fba43778..ee1cad5af5353 100644
+--- a/sound/soc/codecs/wm8962.c
++++ b/sound/soc/codecs/wm8962.c
+@@ -2503,6 +2503,14 @@ static void wm8962_configure_bclk(struct snd_soc_component *component)
+ 		snd_soc_component_update_bits(component, WM8962_CLOCKING2,
+ 				WM8962_SYSCLK_ENA_MASK, WM8962_SYSCLK_ENA);
+ 
++	/* DSPCLK_DIV field in WM8962_CLOCKING1 register is used to generate
++	 * correct frequency of LRCLK and BCLK. Sometimes the read-only value
++	 * can't be updated timely after enabling SYSCLK. This results in wrong
++	 * calculation values. Delay is introduced here to wait for newest
++	 * value from register. The time of the delay should be at least
++	 * 500~1000us according to test.
++	 */
++	usleep_range(500, 1000);
+ 	dspclk = snd_soc_component_read(component, WM8962_CLOCKING1);
+ 
+ 	if (snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON)
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index f6a996f0f9c74..f000a7168afc6 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -1242,6 +1242,8 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
+ 		return;
+ 
+ 	be_substream = snd_soc_dpcm_get_substream(be, stream);
++	if (!be_substream)
++		return;
+ 
+ 	for_each_dpcm_fe(be, stream, dpcm) {
+ 		if (dpcm->fe == fe)
+diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/net/config
+index ead7963b9bf0b..bd89198cd8176 100644
+--- a/tools/testing/selftests/net/config
++++ b/tools/testing/selftests/net/config
+@@ -43,5 +43,5 @@ CONFIG_NET_ACT_TUNNEL_KEY=m
+ CONFIG_NET_ACT_MIRRED=m
+ CONFIG_BAREUDP=m
+ CONFIG_IPV6_IOAM6_LWTUNNEL=y
+-CONFIG_CRYPTO_SM4=y
++CONFIG_CRYPTO_SM4_GENERIC=y
+ CONFIG_AMT=m
+diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh
+index 31c3b6ebd388b..21ca91473c095 100755
+--- a/tools/testing/selftests/net/fcnal-test.sh
++++ b/tools/testing/selftests/net/fcnal-test.sh
+@@ -4196,10 +4196,13 @@ elif [ "$TESTS" = "ipv6" ]; then
+ 	TESTS="$TESTS_IPV6"
+ fi
+ 
+-which nettest >/dev/null
+-if [ $? -ne 0 ]; then
+-	echo "'nettest' command not found; skipping tests"
+-	exit $ksft_skip
++# nettest can be run from PATH or from same directory as this selftest
++if ! which nettest >/dev/null; then
++	PATH=$PWD:$PATH
++	if ! which nettest >/dev/null; then
++		echo "'nettest' command not found; skipping tests"
++		exit $ksft_skip
++	fi
+ fi
+ 
+ declare -i nfail=0
+diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh
+index 2271a8727f623..5637b5dadabdb 100755
+--- a/tools/testing/selftests/net/fib_tests.sh
++++ b/tools/testing/selftests/net/fib_tests.sh
+@@ -1711,13 +1711,21 @@ ipv4_del_addr_test()
+ 
+ 	$IP addr add dev dummy1 172.16.104.1/24
+ 	$IP addr add dev dummy1 172.16.104.11/24
++	$IP addr add dev dummy1 172.16.104.12/24
++	$IP addr add dev dummy1 172.16.104.13/24
+ 	$IP addr add dev dummy2 172.16.104.1/24
+ 	$IP addr add dev dummy2 172.16.104.11/24
++	$IP addr add dev dummy2 172.16.104.12/24
+ 	$IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
++	$IP route add 172.16.106.0/24 dev lo src 172.16.104.12
++	$IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.13
+ 	$IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
++	$IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
+ 	set +e
+ 
+ 	# removing address from device in vrf should only remove route from vrf table
++	echo "    Regular FIB info"
++
+ 	$IP addr del dev dummy2 172.16.104.11/24
+ 	$IP ro ls vrf red | grep -q 172.16.105.0/24
+ 	log_test $? 1 "Route removed from VRF when source address deleted"
+@@ -1735,6 +1743,35 @@ ipv4_del_addr_test()
+ 	$IP ro ls vrf red | grep -q 172.16.105.0/24
+ 	log_test $? 0 "Route in VRF is not removed by address delete"
+ 
++	# removing address from device in vrf should only remove route from vrf
++	# table even when the associated fib info only differs in table ID
++	echo "    Identical FIB info with different table ID"
++
++	$IP addr del dev dummy2 172.16.104.12/24
++	$IP ro ls vrf red | grep -q 172.16.106.0/24
++	log_test $? 1 "Route removed from VRF when source address deleted"
++
++	$IP ro ls | grep -q 172.16.106.0/24
++	log_test $? 0 "Route in default VRF not removed"
++
++	$IP addr add dev dummy2 172.16.104.12/24
++	$IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
++
++	$IP addr del dev dummy1 172.16.104.12/24
++	$IP ro ls | grep -q 172.16.106.0/24
++	log_test $? 1 "Route removed in default VRF when source address deleted"
++
++	$IP ro ls vrf red | grep -q 172.16.106.0/24
++	log_test $? 0 "Route in VRF is not removed by address delete"
++
++	# removing address from device in default vrf should remove route from
++	# the default vrf even when route was inserted with a table ID of 0.
++	echo "    Table ID 0"
++
++	$IP addr del dev dummy1 172.16.104.13/24
++	$IP ro ls | grep -q 172.16.107.0/24
++	log_test $? 1 "Route removed in default VRF when source address deleted"
++
+ 	$IP li del dummy1
+ 	$IP li del dummy2
+ 	cleanup
+diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh
+index 736e358dc549d..dfe3d287f01d2 100755
+--- a/tools/testing/selftests/net/pmtu.sh
++++ b/tools/testing/selftests/net/pmtu.sh
+@@ -686,10 +686,12 @@ setup_xfrm() {
+ }
+ 
+ setup_nettest_xfrm() {
+-	which nettest >/dev/null
+-	if [ $? -ne 0 ]; then
+-		echo "'nettest' command not found; skipping tests"
+-	        return 1
++	if ! which nettest >/dev/null; then
++		PATH=$PWD:$PATH
++		if ! which nettest >/dev/null; then
++			echo "'nettest' command not found; skipping tests"
++			return 1
++		fi
+ 	fi
+ 
+ 	[ ${1} -eq 6 ] && proto="-6" || proto=""
+diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh
+index 0900c5438fbb6..275491be3da2f 100755
+--- a/tools/testing/selftests/net/rtnetlink.sh
++++ b/tools/testing/selftests/net/rtnetlink.sh
+@@ -782,7 +782,7 @@ kci_test_ipsec_offload()
+ 	    tmpl proto esp src $srcip dst $dstip spi 9 \
+ 	    mode transport reqid 42
+ 	check_err $?
+-	ip x p add dir out src $dstip/24 dst $srcip/24 \
++	ip x p add dir in src $dstip/24 dst $srcip/24 \
+ 	    tmpl proto esp src $dstip dst $srcip spi 9 \
+ 	    mode transport reqid 42
+ 	check_err $?


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-08 11:40 Alice Ferrazzi
  0 siblings, 0 replies; 27+ messages in thread
From: Alice Ferrazzi @ 2022-12-08 11:40 UTC (permalink / raw
  To: gentoo-commits

commit:     a50c38236ed2bbbe1fd3b03fa28959329ea054c6
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Thu Dec  8 11:37:53 2022 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Thu Dec  8 11:38:02 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=a50c3823

Linux patch 6.0.12

Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org>

 0000_README             |    4 +
 1011_linux-6.0.12.patch | 4938 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 4942 insertions(+)

diff --git a/0000_README b/0000_README
index 52214e7a..37d6ef5a 100644
--- a/0000_README
+++ b/0000_README
@@ -87,6 +87,10 @@ Patch:  1010_linux-6.0.11.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.11
 
+Patch:  1011_linux-6.0.12.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.12
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

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


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-06 13:46 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-06 13:46 UTC (permalink / raw
  To: gentoo-commits

commit:     e01b6489b92edbd322b294a32911346fdac2cc27
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Tue Dec  6 13:45:18 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Tue Dec  6 13:45:18 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=e01b6489

netfilter: ctnetlink fix compl. warning after data race fixes in ct mark

Bug: https://bugs.gentoo.org/884585

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

 0000_README                                    |  4 ++
 2010_netfilter-ctnetlink-compilation-fix.patch | 90 ++++++++++++++++++++++++++
 2 files changed, 94 insertions(+)

diff --git a/0000_README b/0000_README
index 5f75f686..52214e7a 100644
--- a/0000_README
+++ b/0000_README
@@ -103,6 +103,10 @@ Patch:  2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
 From:   https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw
 Desc:   Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758
 
+Patch:  2010_netfilter-ctnetlink-compilation-fix.patch
+From:   https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf.git
+Desc:   netfilter: ctnetlink: fix compilation warning after data race fixes in ct mark
+
 Patch:  2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
 From:   https://bugs.gentoo.org/710790
 Desc:   tmp513 requies REGMAP_I2C to build.  Select it by default in Kconfig. See bug #710790. Thanks to Phil Stracchino

diff --git a/2010_netfilter-ctnetlink-compilation-fix.patch b/2010_netfilter-ctnetlink-compilation-fix.patch
new file mode 100644
index 00000000..b7bd4dee
--- /dev/null
+++ b/2010_netfilter-ctnetlink-compilation-fix.patch
@@ -0,0 +1,90 @@
+From 1feeae071507ad65cf9f462a1bdd543a4bf89e71 Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Mon, 28 Nov 2022 10:58:53 +0100
+Subject: netfilter: ctnetlink: fix compilation warning after data race fixes
+ in ct mark
+
+All warnings (new ones prefixed by >>):
+
+   net/netfilter/nf_conntrack_netlink.c: In function '__ctnetlink_glue_build':
+>> net/netfilter/nf_conntrack_netlink.c:2674:13: warning: unused variable 'mark' [-Wunused-variable]
+    2674 |         u32 mark;
+         |             ^~~~
+
+Fixes: 52d1aa8b8249 ("netfilter: conntrack: Fix data-races around ct mark")
+Reported-by: kernel test robot <lkp@intel.com>
+Tested-by: Ivan Babrou <ivan@ivan.computer>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ net/netfilter/nf_conntrack_netlink.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index d71150a40fb08..1286ae7d46096 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -328,8 +328,13 @@ nla_put_failure:
+ }
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark)
++static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
+ {
++	u32 mark = READ_ONCE(ct->mark);
++
++	if (!mark)
++		return 0;
++
+ 	if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
+ 		goto nla_put_failure;
+ 	return 0;
+@@ -543,7 +548,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
+ static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ 	if (ctnetlink_dump_status(skb, ct) < 0 ||
+-	    ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 ||
++	    ctnetlink_dump_mark(skb, ct) < 0 ||
+ 	    ctnetlink_dump_secctx(skb, ct) < 0 ||
+ 	    ctnetlink_dump_id(skb, ct) < 0 ||
+ 	    ctnetlink_dump_use(skb, ct) < 0 ||
+@@ -722,7 +727,6 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ 	struct sk_buff *skb;
+ 	unsigned int type;
+ 	unsigned int flags = 0, group;
+-	u32 mark;
+ 	int err;
+ 
+ 	if (events & (1 << IPCT_DESTROY)) {
+@@ -827,9 +831,8 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ 	}
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-	mark = READ_ONCE(ct->mark);
+-	if ((events & (1 << IPCT_MARK) || mark) &&
+-	    ctnetlink_dump_mark(skb, mark) < 0)
++	if (events & (1 << IPCT_MARK) &&
++	    ctnetlink_dump_mark(skb, ct) < 0)
+ 		goto nla_put_failure;
+ #endif
+ 	nlmsg_end(skb, nlh);
+@@ -2671,7 +2674,6 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ 	const struct nf_conntrack_zone *zone;
+ 	struct nlattr *nest_parms;
+-	u32 mark;
+ 
+ 	zone = nf_ct_zone(ct);
+ 
+@@ -2733,8 +2735,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ 		goto nla_put_failure;
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-	mark = READ_ONCE(ct->mark);
+-	if (mark && ctnetlink_dump_mark(skb, mark) < 0)
++	if (ctnetlink_dump_mark(skb, ct) < 0)
+ 		goto nla_put_failure;
+ #endif
+ 	if (ctnetlink_dump_labels(skb, ct) < 0)
+-- 
+cgit 
+


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-06 13:00 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-06 13:00 UTC (permalink / raw
  To: gentoo-commits

commit:     d88f68a1c45be889061120a9d1a196424496f78d
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Tue Dec  6 13:00:01 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Tue Dec  6 13:00:01 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=d88f68a1

Add the BMQ(BitMap Queue) Scheduler (USE=experiemental)

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

 0000_README                                 |     3 +
 5020_BMQ-and-PDS-io-scheduler-v6.0-r0.patch | 10036 ++++++++++++++++++++++++++
 2 files changed, 10039 insertions(+)

diff --git a/0000_README b/0000_README
index 12c46dfc..5f75f686 100644
--- a/0000_README
+++ b/0000_README
@@ -127,3 +127,6 @@ Patch:  5010_enable-cpu-optimizations-universal.patch
 From:   https://github.com/graysky2/kernel_compiler_patch
 Desc:   Kernel >= 5.15 patch enables gcc = v11.1+ optimizations for additional CPUs.
 
+Patch:  5020_BMQ-and-PDS-io-scheduler-v6.0-r0.patch
+From:   https://gitlab.com/alfredchen/projectc
+Desc:   BMQ(BitMap Queue) Scheduler. A new CPU scheduler developed from PDS(incld). Inspired by the scheduler in zircon.

diff --git a/5020_BMQ-and-PDS-io-scheduler-v6.0-r0.patch b/5020_BMQ-and-PDS-io-scheduler-v6.0-r0.patch
new file mode 100644
index 00000000..e0ebdb65
--- /dev/null
+++ b/5020_BMQ-and-PDS-io-scheduler-v6.0-r0.patch
@@ -0,0 +1,10036 @@
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index 426fa892d311..43b06e44128c 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -5385,6 +5385,12 @@
+ 	sa1100ir	[NET]
+ 			See drivers/net/irda/sa1100_ir.c.
+ 
++	sched_timeslice=
++			[KNL] Time slice in ms for Project C BMQ/PDS scheduler.
++			Format: integer 2, 4
++			Default: 4
++			See Documentation/scheduler/sched-BMQ.txt
++
+ 	sched_verbose	[KNL] Enables verbose scheduler debug messages.
+ 
+ 	schedstats=	[KNL,X86] Enable or disable scheduled statistics.
+diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
+index ee6572b1edad..5d3e6ce49e23 100644
+--- a/Documentation/admin-guide/sysctl/kernel.rst
++++ b/Documentation/admin-guide/sysctl/kernel.rst
+@@ -1536,3 +1536,13 @@ is 10 seconds.
+ 
+ The softlockup threshold is (``2 * watchdog_thresh``). Setting this
+ tunable to zero will disable lockup detection altogether.
++
++yield_type:
++===========
++
++BMQ/PDS CPU scheduler only. This determines what type of yield calls
++to sched_yield will perform.
++
++  0 - No yield.
++  1 - Deboost and requeue task. (default)
++  2 - Set run queue skip task.
+diff --git a/Documentation/scheduler/sched-BMQ.txt b/Documentation/scheduler/sched-BMQ.txt
+new file mode 100644
+index 000000000000..05c84eec0f31
+--- /dev/null
++++ b/Documentation/scheduler/sched-BMQ.txt
+@@ -0,0 +1,110 @@
++                         BitMap queue CPU Scheduler
++                         --------------------------
++
++CONTENT
++========
++
++ Background
++ Design
++   Overview
++   Task policy
++   Priority management
++   BitMap Queue
++   CPU Assignment and Migration
++
++
++Background
++==========
++
++BitMap Queue CPU scheduler, referred to as BMQ from here on, is an evolution
++of previous Priority and Deadline based Skiplist multiple queue scheduler(PDS),
++and inspired by Zircon scheduler. The goal of it is to keep the scheduler code
++simple, while efficiency and scalable for interactive tasks, such as desktop,
++movie playback and gaming etc.
++
++Design
++======
++
++Overview
++--------
++
++BMQ use per CPU run queue design, each CPU(logical) has it's own run queue,
++each CPU is responsible for scheduling the tasks that are putting into it's
++run queue.
++
++The run queue is a set of priority queues. Note that these queues are fifo
++queue for non-rt tasks or priority queue for rt tasks in data structure. See
++BitMap Queue below for details. BMQ is optimized for non-rt tasks in the fact
++that most applications are non-rt tasks. No matter the queue is fifo or
++priority, In each queue is an ordered list of runnable tasks awaiting execution
++and the data structures are the same. When it is time for a new task to run,
++the scheduler simply looks the lowest numbered queueue that contains a task,
++and runs the first task from the head of that queue. And per CPU idle task is
++also in the run queue, so the scheduler can always find a task to run on from
++its run queue.
++
++Each task will assigned the same timeslice(default 4ms) when it is picked to
++start running. Task will be reinserted at the end of the appropriate priority
++queue when it uses its whole timeslice. When the scheduler selects a new task
++from the priority queue it sets the CPU's preemption timer for the remainder of
++the previous timeslice. When that timer fires the scheduler will stop execution
++on that task, select another task and start over again.
++
++If a task blocks waiting for a shared resource then it's taken out of its
++priority queue and is placed in a wait queue for the shared resource. When it
++is unblocked it will be reinserted in the appropriate priority queue of an
++eligible CPU.
++
++Task policy
++-----------
++
++BMQ supports DEADLINE, FIFO, RR, NORMAL, BATCH and IDLE task policy like the
++mainline CFS scheduler. But BMQ is heavy optimized for non-rt task, that's
++NORMAL/BATCH/IDLE policy tasks. Below is the implementation detail of each
++policy.
++
++DEADLINE
++	It is squashed as priority 0 FIFO task.
++
++FIFO/RR
++	All RT tasks share one single priority queue in BMQ run queue designed. The
++complexity of insert operation is O(n). BMQ is not designed for system runs
++with major rt policy tasks.
++
++NORMAL/BATCH/IDLE
++	BATCH and IDLE tasks are treated as the same policy. They compete CPU with
++NORMAL policy tasks, but they just don't boost. To control the priority of
++NORMAL/BATCH/IDLE tasks, simply use nice level.
++
++ISO
++	ISO policy is not supported in BMQ. Please use nice level -20 NORMAL policy
++task instead.
++
++Priority management
++-------------------
++
++RT tasks have priority from 0-99. For non-rt tasks, there are three different
++factors used to determine the effective priority of a task. The effective
++priority being what is used to determine which queue it will be in.
++
++The first factor is simply the task’s static priority. Which is assigned from
++task's nice level, within [-20, 19] in userland's point of view and [0, 39]
++internally.
++
++The second factor is the priority boost. This is a value bounded between
++[-MAX_PRIORITY_ADJ, MAX_PRIORITY_ADJ] used to offset the base priority, it is
++modified by the following cases:
++
++*When a thread has used up its entire timeslice, always deboost its boost by
++increasing by one.
++*When a thread gives up cpu control(voluntary or non-voluntary) to reschedule,
++and its switch-in time(time after last switch and run) below the thredhold
++based on its priority boost, will boost its boost by decreasing by one buti is
++capped at 0 (won’t go negative).
++
++The intent in this system is to ensure that interactive threads are serviced
++quickly. These are usually the threads that interact directly with the user
++and cause user-perceivable latency. These threads usually do little work and
++spend most of their time blocked awaiting another user event. So they get the
++priority boost from unblocking while background threads that do most of the
++processing receive the priority penalty for using their entire timeslice.
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index 93f7e3d971e4..8cdeb0d9048c 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -479,7 +479,7 @@ static int proc_pid_schedstat(struct seq_file *m, struct pid_namespace *ns,
+ 		seq_puts(m, "0 0 0\n");
+ 	else
+ 		seq_printf(m, "%llu %llu %lu\n",
+-		   (unsigned long long)task->se.sum_exec_runtime,
++		   (unsigned long long)tsk_seruntime(task),
+ 		   (unsigned long long)task->sched_info.run_delay,
+ 		   task->sched_info.pcount);
+ 
+diff --git a/include/asm-generic/resource.h b/include/asm-generic/resource.h
+index 8874f681b056..59eb72bf7d5f 100644
+--- a/include/asm-generic/resource.h
++++ b/include/asm-generic/resource.h
+@@ -23,7 +23,7 @@
+ 	[RLIMIT_LOCKS]		= {  RLIM_INFINITY,  RLIM_INFINITY },	\
+ 	[RLIMIT_SIGPENDING]	= { 		0,	       0 },	\
+ 	[RLIMIT_MSGQUEUE]	= {   MQ_BYTES_MAX,   MQ_BYTES_MAX },	\
+-	[RLIMIT_NICE]		= { 0, 0 },				\
++	[RLIMIT_NICE]		= { 30, 30 },				\
+ 	[RLIMIT_RTPRIO]		= { 0, 0 },				\
+ 	[RLIMIT_RTTIME]		= {  RLIM_INFINITY,  RLIM_INFINITY },	\
+ }
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index e7b2f8a5c711..9e3742ad8f32 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -752,8 +752,14 @@ struct task_struct {
+ 	unsigned int			ptrace;
+ 
+ #ifdef CONFIG_SMP
+-	int				on_cpu;
+ 	struct __call_single_node	wake_entry;
++#endif
++#if defined(CONFIG_SMP) || defined(CONFIG_SCHED_ALT)
++	int				on_cpu;
++#endif
++
++#ifdef CONFIG_SMP
++#ifndef CONFIG_SCHED_ALT
+ 	unsigned int			wakee_flips;
+ 	unsigned long			wakee_flip_decay_ts;
+ 	struct task_struct		*last_wakee;
+@@ -767,6 +773,7 @@ struct task_struct {
+ 	 */
+ 	int				recent_used_cpu;
+ 	int				wake_cpu;
++#endif /* !CONFIG_SCHED_ALT */
+ #endif
+ 	int				on_rq;
+ 
+@@ -775,6 +782,20 @@ struct task_struct {
+ 	int				normal_prio;
+ 	unsigned int			rt_priority;
+ 
++#ifdef CONFIG_SCHED_ALT
++	u64				last_ran;
++	s64				time_slice;
++	int				sq_idx;
++	struct list_head		sq_node;
++#ifdef CONFIG_SCHED_BMQ
++	int				boost_prio;
++#endif /* CONFIG_SCHED_BMQ */
++#ifdef CONFIG_SCHED_PDS
++	u64				deadline;
++#endif /* CONFIG_SCHED_PDS */
++	/* sched_clock time spent running */
++	u64				sched_time;
++#else /* !CONFIG_SCHED_ALT */
+ 	struct sched_entity		se;
+ 	struct sched_rt_entity		rt;
+ 	struct sched_dl_entity		dl;
+@@ -785,6 +806,7 @@ struct task_struct {
+ 	unsigned long			core_cookie;
+ 	unsigned int			core_occupation;
+ #endif
++#endif /* !CONFIG_SCHED_ALT */
+ 
+ #ifdef CONFIG_CGROUP_SCHED
+ 	struct task_group		*sched_task_group;
+@@ -1529,6 +1551,15 @@ struct task_struct {
+ 	 */
+ };
+ 
++#ifdef CONFIG_SCHED_ALT
++#define tsk_seruntime(t)		((t)->sched_time)
++/* replace the uncertian rt_timeout with 0UL */
++#define tsk_rttimeout(t)		(0UL)
++#else /* CFS */
++#define tsk_seruntime(t)	((t)->se.sum_exec_runtime)
++#define tsk_rttimeout(t)	((t)->rt.timeout)
++#endif /* !CONFIG_SCHED_ALT */
++
+ static inline struct pid *task_pid(struct task_struct *task)
+ {
+ 	return task->thread_pid;
+diff --git a/include/linux/sched/deadline.h b/include/linux/sched/deadline.h
+index 7c83d4d5a971..fa30f98cb2be 100644
+--- a/include/linux/sched/deadline.h
++++ b/include/linux/sched/deadline.h
+@@ -1,5 +1,24 @@
+ /* SPDX-License-Identifier: GPL-2.0 */
+ 
++#ifdef CONFIG_SCHED_ALT
++
++static inline int dl_task(struct task_struct *p)
++{
++	return 0;
++}
++
++#ifdef CONFIG_SCHED_BMQ
++#define __tsk_deadline(p)	(0UL)
++#endif
++
++#ifdef CONFIG_SCHED_PDS
++#define __tsk_deadline(p)	((((u64) ((p)->prio))<<56) | (p)->deadline)
++#endif
++
++#else
++
++#define __tsk_deadline(p)	((p)->dl.deadline)
++
+ /*
+  * SCHED_DEADLINE tasks has negative priorities, reflecting
+  * the fact that any of them has higher prio than RT and
+@@ -21,6 +40,7 @@ static inline int dl_task(struct task_struct *p)
+ {
+ 	return dl_prio(p->prio);
+ }
++#endif /* CONFIG_SCHED_ALT */
+ 
+ static inline bool dl_time_before(u64 a, u64 b)
+ {
+diff --git a/include/linux/sched/prio.h b/include/linux/sched/prio.h
+index ab83d85e1183..6af9ae681116 100644
+--- a/include/linux/sched/prio.h
++++ b/include/linux/sched/prio.h
+@@ -18,6 +18,32 @@
+ #define MAX_PRIO		(MAX_RT_PRIO + NICE_WIDTH)
+ #define DEFAULT_PRIO		(MAX_RT_PRIO + NICE_WIDTH / 2)
+ 
++#ifdef CONFIG_SCHED_ALT
++
++/* Undefine MAX_PRIO and DEFAULT_PRIO */
++#undef MAX_PRIO
++#undef DEFAULT_PRIO
++
++/* +/- priority levels from the base priority */
++#ifdef CONFIG_SCHED_BMQ
++#define MAX_PRIORITY_ADJ	(7)
++
++#define MIN_NORMAL_PRIO		(MAX_RT_PRIO)
++#define MAX_PRIO		(MIN_NORMAL_PRIO + NICE_WIDTH)
++#define DEFAULT_PRIO		(MIN_NORMAL_PRIO + NICE_WIDTH / 2)
++#endif
++
++#ifdef CONFIG_SCHED_PDS
++#define MAX_PRIORITY_ADJ	(0)
++
++#define MIN_NORMAL_PRIO		(128)
++#define NORMAL_PRIO_NUM		(64)
++#define MAX_PRIO		(MIN_NORMAL_PRIO + NORMAL_PRIO_NUM)
++#define DEFAULT_PRIO		(MAX_PRIO - NICE_WIDTH / 2)
++#endif
++
++#endif /* CONFIG_SCHED_ALT */
++
+ /*
+  * Convert user-nice values [ -20 ... 0 ... 19 ]
+  * to static priority [ MAX_RT_PRIO..MAX_PRIO-1 ],
+diff --git a/include/linux/sched/rt.h b/include/linux/sched/rt.h
+index 994c25640e15..8c050a59ece1 100644
+--- a/include/linux/sched/rt.h
++++ b/include/linux/sched/rt.h
+@@ -24,8 +24,10 @@ static inline bool task_is_realtime(struct task_struct *tsk)
+ 
+ 	if (policy == SCHED_FIFO || policy == SCHED_RR)
+ 		return true;
++#ifndef CONFIG_SCHED_ALT
+ 	if (policy == SCHED_DEADLINE)
+ 		return true;
++#endif
+ 	return false;
+ }
+ 
+diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h
+index 816df6cc444e..c8da08e18c91 100644
+--- a/include/linux/sched/topology.h
++++ b/include/linux/sched/topology.h
+@@ -234,7 +234,8 @@ static inline bool cpus_share_cache(int this_cpu, int that_cpu)
+ 
+ #endif	/* !CONFIG_SMP */
+ 
+-#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL)
++#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) && \
++	!defined(CONFIG_SCHED_ALT)
+ extern void rebuild_sched_domains_energy(void);
+ #else
+ static inline void rebuild_sched_domains_energy(void)
+diff --git a/init/Kconfig b/init/Kconfig
+index 532362fcfe31..2bf9e67b73c9 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -808,6 +808,7 @@ menu "Scheduler features"
+ config UCLAMP_TASK
+ 	bool "Enable utilization clamping for RT/FAIR tasks"
+ 	depends on CPU_FREQ_GOV_SCHEDUTIL
++	depends on !SCHED_ALT
+ 	help
+ 	  This feature enables the scheduler to track the clamped utilization
+ 	  of each CPU based on RUNNABLE tasks scheduled on that CPU.
+@@ -854,6 +855,35 @@ config UCLAMP_BUCKETS_COUNT
+ 
+ 	  If in doubt, use the default value.
+ 
++menuconfig SCHED_ALT
++	bool "Alternative CPU Schedulers"
++	default y
++	help
++	  This feature enable alternative CPU scheduler"
++
++if SCHED_ALT
++
++choice
++	prompt "Alternative CPU Scheduler"
++	default SCHED_BMQ
++
++config SCHED_BMQ
++	bool "BMQ CPU scheduler"
++	help
++	  The BitMap Queue CPU scheduler for excellent interactivity and
++	  responsiveness on the desktop and solid scalability on normal
++	  hardware and commodity servers.
++
++config SCHED_PDS
++	bool "PDS CPU scheduler"
++	help
++	  The Priority and Deadline based Skip list multiple queue CPU
++	  Scheduler.
++
++endchoice
++
++endif
++
+ endmenu
+ 
+ #
+@@ -907,6 +937,7 @@ config NUMA_BALANCING
+ 	depends on ARCH_SUPPORTS_NUMA_BALANCING
+ 	depends on !ARCH_WANT_NUMA_VARIABLE_LOCALITY
+ 	depends on SMP && NUMA && MIGRATION && !PREEMPT_RT
++	depends on !SCHED_ALT
+ 	help
+ 	  This option adds support for automatic NUMA aware memory/task placement.
+ 	  The mechanism is quite primitive and is based on migrating memory when
+@@ -1009,6 +1040,7 @@ config FAIR_GROUP_SCHED
+ 	depends on CGROUP_SCHED
+ 	default CGROUP_SCHED
+ 
++if !SCHED_ALT
+ config CFS_BANDWIDTH
+ 	bool "CPU bandwidth provisioning for FAIR_GROUP_SCHED"
+ 	depends on FAIR_GROUP_SCHED
+@@ -1031,6 +1063,7 @@ config RT_GROUP_SCHED
+ 	  realtime bandwidth for them.
+ 	  See Documentation/scheduler/sched-rt-group.rst for more information.
+ 
++endif #!SCHED_ALT
+ endif #CGROUP_SCHED
+ 
+ config UCLAMP_TASK_GROUP
+@@ -1274,6 +1307,7 @@ config CHECKPOINT_RESTORE
+ 
+ config SCHED_AUTOGROUP
+ 	bool "Automatic process group scheduling"
++	depends on !SCHED_ALT
+ 	select CGROUPS
+ 	select CGROUP_SCHED
+ 	select FAIR_GROUP_SCHED
+diff --git a/init/init_task.c b/init/init_task.c
+index ff6c4b9bfe6b..19e9c662d1a1 100644
+--- a/init/init_task.c
++++ b/init/init_task.c
+@@ -75,9 +75,15 @@ struct task_struct init_task
+ 	.stack		= init_stack,
+ 	.usage		= REFCOUNT_INIT(2),
+ 	.flags		= PF_KTHREAD,
++#ifdef CONFIG_SCHED_ALT
++	.prio		= DEFAULT_PRIO + MAX_PRIORITY_ADJ,
++	.static_prio	= DEFAULT_PRIO,
++	.normal_prio	= DEFAULT_PRIO + MAX_PRIORITY_ADJ,
++#else
+ 	.prio		= MAX_PRIO - 20,
+ 	.static_prio	= MAX_PRIO - 20,
+ 	.normal_prio	= MAX_PRIO - 20,
++#endif
+ 	.policy		= SCHED_NORMAL,
+ 	.cpus_ptr	= &init_task.cpus_mask,
+ 	.user_cpus_ptr	= NULL,
+@@ -88,6 +94,17 @@ struct task_struct init_task
+ 	.restart_block	= {
+ 		.fn = do_no_restart_syscall,
+ 	},
++#ifdef CONFIG_SCHED_ALT
++	.sq_node	= LIST_HEAD_INIT(init_task.sq_node),
++#ifdef CONFIG_SCHED_BMQ
++	.boost_prio	= 0,
++	.sq_idx		= 15,
++#endif
++#ifdef CONFIG_SCHED_PDS
++	.deadline	= 0,
++#endif
++	.time_slice	= HZ,
++#else
+ 	.se		= {
+ 		.group_node 	= LIST_HEAD_INIT(init_task.se.group_node),
+ 	},
+@@ -95,6 +112,7 @@ struct task_struct init_task
+ 		.run_list	= LIST_HEAD_INIT(init_task.rt.run_list),
+ 		.time_slice	= RR_TIMESLICE,
+ 	},
++#endif
+ 	.tasks		= LIST_HEAD_INIT(init_task.tasks),
+ #ifdef CONFIG_SMP
+ 	.pushable_tasks	= PLIST_NODE_INIT(init_task.pushable_tasks, MAX_PRIO),
+diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
+index c2f1fd95a821..41654679b1b2 100644
+--- a/kernel/Kconfig.preempt
++++ b/kernel/Kconfig.preempt
+@@ -117,7 +117,7 @@ config PREEMPT_DYNAMIC
+ 
+ config SCHED_CORE
+ 	bool "Core Scheduling for SMT"
+-	depends on SCHED_SMT
++	depends on SCHED_SMT && !SCHED_ALT
+ 	help
+ 	  This option permits Core Scheduling, a means of coordinated task
+ 	  selection across SMT siblings. When enabled -- see
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index 1f3a55297f39..a7ce153c6f91 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -704,7 +704,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial)
+ 	return ret;
+ }
+ 
+-#ifdef CONFIG_SMP
++#if defined(CONFIG_SMP) && !defined(CONFIG_SCHED_ALT)
+ /*
+  * Helper routine for generate_sched_domains().
+  * Do cpusets a, b have overlapping effective cpus_allowed masks?
+@@ -1100,7 +1100,7 @@ static void rebuild_sched_domains_locked(void)
+ 	/* Have scheduler rebuild the domains */
+ 	partition_and_rebuild_sched_domains(ndoms, doms, attr);
+ }
+-#else /* !CONFIG_SMP */
++#else /* !CONFIG_SMP || CONFIG_SCHED_ALT */
+ static void rebuild_sched_domains_locked(void)
+ {
+ }
+diff --git a/kernel/delayacct.c b/kernel/delayacct.c
+index 164ed9ef77a3..c974a84b056f 100644
+--- a/kernel/delayacct.c
++++ b/kernel/delayacct.c
+@@ -150,7 +150,7 @@ int delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
+ 	 */
+ 	t1 = tsk->sched_info.pcount;
+ 	t2 = tsk->sched_info.run_delay;
+-	t3 = tsk->se.sum_exec_runtime;
++	t3 = tsk_seruntime(tsk);
+ 
+ 	d->cpu_count += t1;
+ 
+diff --git a/kernel/exit.c b/kernel/exit.c
+index 84021b24f79e..a9b77bf74eec 100644
+--- a/kernel/exit.c
++++ b/kernel/exit.c
+@@ -124,7 +124,7 @@ static void __exit_signal(struct task_struct *tsk)
+ 			sig->curr_target = next_thread(tsk);
+ 	}
+ 
+-	add_device_randomness((const void*) &tsk->se.sum_exec_runtime,
++	add_device_randomness((const void*) &tsk_seruntime(tsk),
+ 			      sizeof(unsigned long long));
+ 
+ 	/*
+@@ -145,7 +145,7 @@ static void __exit_signal(struct task_struct *tsk)
+ 	sig->inblock += task_io_get_inblock(tsk);
+ 	sig->oublock += task_io_get_oublock(tsk);
+ 	task_io_accounting_add(&sig->ioac, &tsk->ioac);
+-	sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
++	sig->sum_sched_runtime += tsk_seruntime(tsk);
+ 	sig->nr_threads--;
+ 	__unhash_process(tsk, group_dead);
+ 	write_sequnlock(&sig->stats_lock);
+diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
+index 7779ee8abc2a..5b9893cdfb1b 100644
+--- a/kernel/locking/rtmutex.c
++++ b/kernel/locking/rtmutex.c
+@@ -300,21 +300,25 @@ static __always_inline void
+ waiter_update_prio(struct rt_mutex_waiter *waiter, struct task_struct *task)
+ {
+ 	waiter->prio = __waiter_prio(task);
+-	waiter->deadline = task->dl.deadline;
++	waiter->deadline = __tsk_deadline(task);
+ }
+ 
+ /*
+  * Only use with rt_mutex_waiter_{less,equal}()
+  */
+ #define task_to_waiter(p)	\
+-	&(struct rt_mutex_waiter){ .prio = __waiter_prio(p), .deadline = (p)->dl.deadline }
++	&(struct rt_mutex_waiter){ .prio = __waiter_prio(p), .deadline = __tsk_deadline(p) }
+ 
+ static __always_inline int rt_mutex_waiter_less(struct rt_mutex_waiter *left,
+ 						struct rt_mutex_waiter *right)
+ {
++#ifdef CONFIG_SCHED_PDS
++	return (left->deadline < right->deadline);
++#else
+ 	if (left->prio < right->prio)
+ 		return 1;
+ 
++#ifndef CONFIG_SCHED_BMQ
+ 	/*
+ 	 * If both waiters have dl_prio(), we check the deadlines of the
+ 	 * associated tasks.
+@@ -323,16 +327,22 @@ static __always_inline int rt_mutex_waiter_less(struct rt_mutex_waiter *left,
+ 	 */
+ 	if (dl_prio(left->prio))
+ 		return dl_time_before(left->deadline, right->deadline);
++#endif
+ 
+ 	return 0;
++#endif
+ }
+ 
+ static __always_inline int rt_mutex_waiter_equal(struct rt_mutex_waiter *left,
+ 						 struct rt_mutex_waiter *right)
+ {
++#ifdef CONFIG_SCHED_PDS
++	return (left->deadline == right->deadline);
++#else
+ 	if (left->prio != right->prio)
+ 		return 0;
+ 
++#ifndef CONFIG_SCHED_BMQ
+ 	/*
+ 	 * If both waiters have dl_prio(), we check the deadlines of the
+ 	 * associated tasks.
+@@ -341,8 +351,10 @@ static __always_inline int rt_mutex_waiter_equal(struct rt_mutex_waiter *left,
+ 	 */
+ 	if (dl_prio(left->prio))
+ 		return left->deadline == right->deadline;
++#endif
+ 
+ 	return 1;
++#endif
+ }
+ 
+ static inline bool rt_mutex_steal(struct rt_mutex_waiter *waiter,
+diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile
+index 976092b7bd45..31d587c16ec1 100644
+--- a/kernel/sched/Makefile
++++ b/kernel/sched/Makefile
+@@ -28,7 +28,12 @@ endif
+ # These compilation units have roughly the same size and complexity - so their
+ # build parallelizes well and finishes roughly at once:
+ #
++ifdef CONFIG_SCHED_ALT
++obj-y += alt_core.o
++obj-$(CONFIG_SCHED_DEBUG) += alt_debug.o
++else
+ obj-y += core.o
+ obj-y += fair.o
++endif
+ obj-y += build_policy.o
+ obj-y += build_utility.o
+diff --git a/kernel/sched/alt_core.c b/kernel/sched/alt_core.c
+new file mode 100644
+index 000000000000..03e3956194f7
+--- /dev/null
++++ b/kernel/sched/alt_core.c
+@@ -0,0 +1,7887 @@
++/*
++ *  kernel/sched/alt_core.c
++ *
++ *  Core alternative kernel scheduler code and related syscalls
++ *
++ *  Copyright (C) 1991-2002  Linus Torvalds
++ *
++ *  2009-08-13	Brainfuck deadline scheduling policy by Con Kolivas deletes
++ *		a whole lot of those previous things.
++ *  2017-09-06	Priority and Deadline based Skip list multiple queue kernel
++ *		scheduler by Alfred Chen.
++ *  2019-02-20	BMQ(BitMap Queue) kernel scheduler by Alfred Chen.
++ */
++#include <linux/sched/cputime.h>
++#include <linux/sched/debug.h>
++#include <linux/sched/isolation.h>
++#include <linux/sched/loadavg.h>
++#include <linux/sched/mm.h>
++#include <linux/sched/nohz.h>
++#include <linux/sched/stat.h>
++#include <linux/sched/wake_q.h>
++
++#include <linux/blkdev.h>
++#include <linux/context_tracking.h>
++#include <linux/cpuset.h>
++#include <linux/delayacct.h>
++#include <linux/init_task.h>
++#include <linux/kcov.h>
++#include <linux/kprobes.h>
++#include <linux/profile.h>
++#include <linux/nmi.h>
++#include <linux/scs.h>
++
++#include <uapi/linux/sched/types.h>
++
++#include <asm/switch_to.h>
++
++#define CREATE_TRACE_POINTS
++#include <trace/events/sched.h>
++#undef CREATE_TRACE_POINTS
++
++#include "sched.h"
++
++#include "pelt.h"
++
++#include "../../io_uring/io-wq.h"
++#include "../smpboot.h"
++
++/*
++ * Export tracepoints that act as a bare tracehook (ie: have no trace event
++ * associated with them) to allow external modules to probe them.
++ */
++EXPORT_TRACEPOINT_SYMBOL_GPL(pelt_irq_tp);
++
++#ifdef CONFIG_SCHED_DEBUG
++#define sched_feat(x)	(1)
++/*
++ * Print a warning if need_resched is set for the given duration (if
++ * LATENCY_WARN is enabled).
++ *
++ * If sysctl_resched_latency_warn_once is set, only one warning will be shown
++ * per boot.
++ */
++__read_mostly int sysctl_resched_latency_warn_ms = 100;
++__read_mostly int sysctl_resched_latency_warn_once = 1;
++#else
++#define sched_feat(x)	(0)
++#endif /* CONFIG_SCHED_DEBUG */
++
++#define ALT_SCHED_VERSION "v6.0-r0"
++
++/* rt_prio(prio) defined in include/linux/sched/rt.h */
++#define rt_task(p)		rt_prio((p)->prio)
++#define rt_policy(policy)	((policy) == SCHED_FIFO || (policy) == SCHED_RR)
++#define task_has_rt_policy(p)	(rt_policy((p)->policy))
++
++#define STOP_PRIO		(MAX_RT_PRIO - 1)
++
++/* Default time slice is 4 in ms, can be set via kernel parameter "sched_timeslice" */
++u64 sched_timeslice_ns __read_mostly = (4 << 20);
++
++static inline void requeue_task(struct task_struct *p, struct rq *rq, int idx);
++
++#ifdef CONFIG_SCHED_BMQ
++#include "bmq.h"
++#endif
++#ifdef CONFIG_SCHED_PDS
++#include "pds.h"
++#endif
++
++static int __init sched_timeslice(char *str)
++{
++	int timeslice_ms;
++
++	get_option(&str, &timeslice_ms);
++	if (2 != timeslice_ms)
++		timeslice_ms = 4;
++	sched_timeslice_ns = timeslice_ms << 20;
++	sched_timeslice_imp(timeslice_ms);
++
++	return 0;
++}
++early_param("sched_timeslice", sched_timeslice);
++
++/* Reschedule if less than this many μs left */
++#define RESCHED_NS		(100 << 10)
++
++/**
++ * sched_yield_type - Choose what sort of yield sched_yield will perform.
++ * 0: No yield.
++ * 1: Deboost and requeue task. (default)
++ * 2: Set rq skip task.
++ */
++int sched_yield_type __read_mostly = 1;
++
++#ifdef CONFIG_SMP
++static cpumask_t sched_rq_pending_mask ____cacheline_aligned_in_smp;
++
++DEFINE_PER_CPU(cpumask_t [NR_CPU_AFFINITY_LEVELS], sched_cpu_topo_masks);
++DEFINE_PER_CPU(cpumask_t *, sched_cpu_llc_mask);
++DEFINE_PER_CPU(cpumask_t *, sched_cpu_topo_end_mask);
++
++#ifdef CONFIG_SCHED_SMT
++DEFINE_STATIC_KEY_FALSE(sched_smt_present);
++EXPORT_SYMBOL_GPL(sched_smt_present);
++#endif
++
++/*
++ * Keep a unique ID per domain (we use the first CPUs number in the cpumask of
++ * the domain), this allows us to quickly tell if two cpus are in the same cache
++ * domain, see cpus_share_cache().
++ */
++DEFINE_PER_CPU(int, sd_llc_id);
++#endif /* CONFIG_SMP */
++
++static DEFINE_MUTEX(sched_hotcpu_mutex);
++
++DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
++
++#ifndef prepare_arch_switch
++# define prepare_arch_switch(next)	do { } while (0)
++#endif
++#ifndef finish_arch_post_lock_switch
++# define finish_arch_post_lock_switch()	do { } while (0)
++#endif
++
++#ifdef CONFIG_SCHED_SMT
++static cpumask_t sched_sg_idle_mask ____cacheline_aligned_in_smp;
++#endif
++static cpumask_t sched_rq_watermark[SCHED_QUEUE_BITS] ____cacheline_aligned_in_smp;
++
++/* sched_queue related functions */
++static inline void sched_queue_init(struct sched_queue *q)
++{
++	int i;
++
++	bitmap_zero(q->bitmap, SCHED_QUEUE_BITS);
++	for(i = 0; i < SCHED_BITS; i++)
++		INIT_LIST_HEAD(&q->heads[i]);
++}
++
++/*
++ * Init idle task and put into queue structure of rq
++ * IMPORTANT: may be called multiple times for a single cpu
++ */
++static inline void sched_queue_init_idle(struct sched_queue *q,
++					 struct task_struct *idle)
++{
++	idle->sq_idx = IDLE_TASK_SCHED_PRIO;
++	INIT_LIST_HEAD(&q->heads[idle->sq_idx]);
++	list_add(&idle->sq_node, &q->heads[idle->sq_idx]);
++}
++
++/* water mark related functions */
++static inline void update_sched_rq_watermark(struct rq *rq)
++{
++	unsigned long watermark = find_first_bit(rq->queue.bitmap, SCHED_QUEUE_BITS);
++	unsigned long last_wm = rq->watermark;
++	unsigned long i;
++	int cpu;
++
++	if (watermark == last_wm)
++		return;
++
++	rq->watermark = watermark;
++	cpu = cpu_of(rq);
++	if (watermark < last_wm) {
++		for (i = last_wm; i > watermark; i--)
++			cpumask_clear_cpu(cpu, sched_rq_watermark + SCHED_QUEUE_BITS - i);
++#ifdef CONFIG_SCHED_SMT
++		if (static_branch_likely(&sched_smt_present) &&
++		    IDLE_TASK_SCHED_PRIO == last_wm)
++			cpumask_andnot(&sched_sg_idle_mask,
++				       &sched_sg_idle_mask, cpu_smt_mask(cpu));
++#endif
++		return;
++	}
++	/* last_wm < watermark */
++	for (i = watermark; i > last_wm; i--)
++		cpumask_set_cpu(cpu, sched_rq_watermark + SCHED_QUEUE_BITS - i);
++#ifdef CONFIG_SCHED_SMT
++	if (static_branch_likely(&sched_smt_present) &&
++	    IDLE_TASK_SCHED_PRIO == watermark) {
++		cpumask_t tmp;
++
++		cpumask_and(&tmp, cpu_smt_mask(cpu), sched_rq_watermark);
++		if (cpumask_equal(&tmp, cpu_smt_mask(cpu)))
++			cpumask_or(&sched_sg_idle_mask,
++				   &sched_sg_idle_mask, cpu_smt_mask(cpu));
++	}
++#endif
++}
++
++/*
++ * This routine assume that the idle task always in queue
++ */
++static inline struct task_struct *sched_rq_first_task(struct rq *rq)
++{
++	unsigned long idx = find_first_bit(rq->queue.bitmap, SCHED_QUEUE_BITS);
++	const struct list_head *head = &rq->queue.heads[sched_prio2idx(idx, rq)];
++
++	return list_first_entry(head, struct task_struct, sq_node);
++}
++
++static inline struct task_struct *
++sched_rq_next_task(struct task_struct *p, struct rq *rq)
++{
++	unsigned long idx = p->sq_idx;
++	struct list_head *head = &rq->queue.heads[idx];
++
++	if (list_is_last(&p->sq_node, head)) {
++		idx = find_next_bit(rq->queue.bitmap, SCHED_QUEUE_BITS,
++				    sched_idx2prio(idx, rq) + 1);
++		head = &rq->queue.heads[sched_prio2idx(idx, rq)];
++
++		return list_first_entry(head, struct task_struct, sq_node);
++	}
++
++	return list_next_entry(p, sq_node);
++}
++
++static inline struct task_struct *rq_runnable_task(struct rq *rq)
++{
++	struct task_struct *next = sched_rq_first_task(rq);
++
++	if (unlikely(next == rq->skip))
++		next = sched_rq_next_task(next, rq);
++
++	return next;
++}
++
++/*
++ * Serialization rules:
++ *
++ * Lock order:
++ *
++ *   p->pi_lock
++ *     rq->lock
++ *       hrtimer_cpu_base->lock (hrtimer_start() for bandwidth controls)
++ *
++ *  rq1->lock
++ *    rq2->lock  where: rq1 < rq2
++ *
++ * Regular state:
++ *
++ * Normal scheduling state is serialized by rq->lock. __schedule() takes the
++ * local CPU's rq->lock, it optionally removes the task from the runqueue and
++ * always looks at the local rq data structures to find the most eligible task
++ * to run next.
++ *
++ * Task enqueue is also under rq->lock, possibly taken from another CPU.
++ * Wakeups from another LLC domain might use an IPI to transfer the enqueue to
++ * the local CPU to avoid bouncing the runqueue state around [ see
++ * ttwu_queue_wakelist() ]
++ *
++ * Task wakeup, specifically wakeups that involve migration, are horribly
++ * complicated to avoid having to take two rq->locks.
++ *
++ * Special state:
++ *
++ * System-calls and anything external will use task_rq_lock() which acquires
++ * both p->pi_lock and rq->lock. As a consequence the state they change is
++ * stable while holding either lock:
++ *
++ *  - sched_setaffinity()/
++ *    set_cpus_allowed_ptr():	p->cpus_ptr, p->nr_cpus_allowed
++ *  - set_user_nice():		p->se.load, p->*prio
++ *  - __sched_setscheduler():	p->sched_class, p->policy, p->*prio,
++ *				p->se.load, p->rt_priority,
++ *				p->dl.dl_{runtime, deadline, period, flags, bw, density}
++ *  - sched_setnuma():		p->numa_preferred_nid
++ *  - sched_move_task()/
++ *    cpu_cgroup_fork():	p->sched_task_group
++ *  - uclamp_update_active()	p->uclamp*
++ *
++ * p->state <- TASK_*:
++ *
++ *   is changed locklessly using set_current_state(), __set_current_state() or
++ *   set_special_state(), see their respective comments, or by
++ *   try_to_wake_up(). This latter uses p->pi_lock to serialize against
++ *   concurrent self.
++ *
++ * p->on_rq <- { 0, 1 = TASK_ON_RQ_QUEUED, 2 = TASK_ON_RQ_MIGRATING }:
++ *
++ *   is set by activate_task() and cleared by deactivate_task(), under
++ *   rq->lock. Non-zero indicates the task is runnable, the special
++ *   ON_RQ_MIGRATING state is used for migration without holding both
++ *   rq->locks. It indicates task_cpu() is not stable, see task_rq_lock().
++ *
++ * p->on_cpu <- { 0, 1 }:
++ *
++ *   is set by prepare_task() and cleared by finish_task() such that it will be
++ *   set before p is scheduled-in and cleared after p is scheduled-out, both
++ *   under rq->lock. Non-zero indicates the task is running on its CPU.
++ *
++ *   [ The astute reader will observe that it is possible for two tasks on one
++ *     CPU to have ->on_cpu = 1 at the same time. ]
++ *
++ * task_cpu(p): is changed by set_task_cpu(), the rules are:
++ *
++ *  - Don't call set_task_cpu() on a blocked task:
++ *
++ *    We don't care what CPU we're not running on, this simplifies hotplug,
++ *    the CPU assignment of blocked tasks isn't required to be valid.
++ *
++ *  - for try_to_wake_up(), called under p->pi_lock:
++ *
++ *    This allows try_to_wake_up() to only take one rq->lock, see its comment.
++ *
++ *  - for migration called under rq->lock:
++ *    [ see task_on_rq_migrating() in task_rq_lock() ]
++ *
++ *    o move_queued_task()
++ *    o detach_task()
++ *
++ *  - for migration called under double_rq_lock():
++ *
++ *    o __migrate_swap_task()
++ *    o push_rt_task() / pull_rt_task()
++ *    o push_dl_task() / pull_dl_task()
++ *    o dl_task_offline_migration()
++ *
++ */
++
++/*
++ * Context: p->pi_lock
++ */
++static inline struct rq
++*__task_access_lock(struct task_struct *p, raw_spinlock_t **plock)
++{
++	struct rq *rq;
++	for (;;) {
++		rq = task_rq(p);
++		if (p->on_cpu || task_on_rq_queued(p)) {
++			raw_spin_lock(&rq->lock);
++			if (likely((p->on_cpu || task_on_rq_queued(p))
++				   && rq == task_rq(p))) {
++				*plock = &rq->lock;
++				return rq;
++			}
++			raw_spin_unlock(&rq->lock);
++		} else if (task_on_rq_migrating(p)) {
++			do {
++				cpu_relax();
++			} while (unlikely(task_on_rq_migrating(p)));
++		} else {
++			*plock = NULL;
++			return rq;
++		}
++	}
++}
++
++static inline void
++__task_access_unlock(struct task_struct *p, raw_spinlock_t *lock)
++{
++	if (NULL != lock)
++		raw_spin_unlock(lock);
++}
++
++static inline struct rq
++*task_access_lock_irqsave(struct task_struct *p, raw_spinlock_t **plock,
++			  unsigned long *flags)
++{
++	struct rq *rq;
++	for (;;) {
++		rq = task_rq(p);
++		if (p->on_cpu || task_on_rq_queued(p)) {
++			raw_spin_lock_irqsave(&rq->lock, *flags);
++			if (likely((p->on_cpu || task_on_rq_queued(p))
++				   && rq == task_rq(p))) {
++				*plock = &rq->lock;
++				return rq;
++			}
++			raw_spin_unlock_irqrestore(&rq->lock, *flags);
++		} else if (task_on_rq_migrating(p)) {
++			do {
++				cpu_relax();
++			} while (unlikely(task_on_rq_migrating(p)));
++		} else {
++			raw_spin_lock_irqsave(&p->pi_lock, *flags);
++			if (likely(!p->on_cpu && !p->on_rq &&
++				   rq == task_rq(p))) {
++				*plock = &p->pi_lock;
++				return rq;
++			}
++			raw_spin_unlock_irqrestore(&p->pi_lock, *flags);
++		}
++	}
++}
++
++static inline void
++task_access_unlock_irqrestore(struct task_struct *p, raw_spinlock_t *lock,
++			      unsigned long *flags)
++{
++	raw_spin_unlock_irqrestore(lock, *flags);
++}
++
++/*
++ * __task_rq_lock - lock the rq @p resides on.
++ */
++struct rq *__task_rq_lock(struct task_struct *p, struct rq_flags *rf)
++	__acquires(rq->lock)
++{
++	struct rq *rq;
++
++	lockdep_assert_held(&p->pi_lock);
++
++	for (;;) {
++		rq = task_rq(p);
++		raw_spin_lock(&rq->lock);
++		if (likely(rq == task_rq(p) && !task_on_rq_migrating(p)))
++			return rq;
++		raw_spin_unlock(&rq->lock);
++
++		while (unlikely(task_on_rq_migrating(p)))
++			cpu_relax();
++	}
++}
++
++/*
++ * task_rq_lock - lock p->pi_lock and lock the rq @p resides on.
++ */
++struct rq *task_rq_lock(struct task_struct *p, struct rq_flags *rf)
++	__acquires(p->pi_lock)
++	__acquires(rq->lock)
++{
++	struct rq *rq;
++
++	for (;;) {
++		raw_spin_lock_irqsave(&p->pi_lock, rf->flags);
++		rq = task_rq(p);
++		raw_spin_lock(&rq->lock);
++		/*
++		 *	move_queued_task()		task_rq_lock()
++		 *
++		 *	ACQUIRE (rq->lock)
++		 *	[S] ->on_rq = MIGRATING		[L] rq = task_rq()
++		 *	WMB (__set_task_cpu())		ACQUIRE (rq->lock);
++		 *	[S] ->cpu = new_cpu		[L] task_rq()
++		 *					[L] ->on_rq
++		 *	RELEASE (rq->lock)
++		 *
++		 * If we observe the old CPU in task_rq_lock(), the acquire of
++		 * the old rq->lock will fully serialize against the stores.
++		 *
++		 * If we observe the new CPU in task_rq_lock(), the address
++		 * dependency headed by '[L] rq = task_rq()' and the acquire
++		 * will pair with the WMB to ensure we then also see migrating.
++		 */
++		if (likely(rq == task_rq(p) && !task_on_rq_migrating(p))) {
++			return rq;
++		}
++		raw_spin_unlock(&rq->lock);
++		raw_spin_unlock_irqrestore(&p->pi_lock, rf->flags);
++
++		while (unlikely(task_on_rq_migrating(p)))
++			cpu_relax();
++	}
++}
++
++static inline void
++rq_lock_irqsave(struct rq *rq, struct rq_flags *rf)
++	__acquires(rq->lock)
++{
++	raw_spin_lock_irqsave(&rq->lock, rf->flags);
++}
++
++static inline void
++rq_unlock_irqrestore(struct rq *rq, struct rq_flags *rf)
++	__releases(rq->lock)
++{
++	raw_spin_unlock_irqrestore(&rq->lock, rf->flags);
++}
++
++void raw_spin_rq_lock_nested(struct rq *rq, int subclass)
++{
++	raw_spinlock_t *lock;
++
++	/* Matches synchronize_rcu() in __sched_core_enable() */
++	preempt_disable();
++
++	for (;;) {
++		lock = __rq_lockp(rq);
++		raw_spin_lock_nested(lock, subclass);
++		if (likely(lock == __rq_lockp(rq))) {
++			/* preempt_count *MUST* be > 1 */
++			preempt_enable_no_resched();
++			return;
++		}
++		raw_spin_unlock(lock);
++	}
++}
++
++void raw_spin_rq_unlock(struct rq *rq)
++{
++	raw_spin_unlock(rq_lockp(rq));
++}
++
++/*
++ * RQ-clock updating methods:
++ */
++
++static void update_rq_clock_task(struct rq *rq, s64 delta)
++{
++/*
++ * In theory, the compile should just see 0 here, and optimize out the call
++ * to sched_rt_avg_update. But I don't trust it...
++ */
++	s64 __maybe_unused steal = 0, irq_delta = 0;
++
++#ifdef CONFIG_IRQ_TIME_ACCOUNTING
++	irq_delta = irq_time_read(cpu_of(rq)) - rq->prev_irq_time;
++
++	/*
++	 * Since irq_time is only updated on {soft,}irq_exit, we might run into
++	 * this case when a previous update_rq_clock() happened inside a
++	 * {soft,}irq region.
++	 *
++	 * When this happens, we stop ->clock_task and only update the
++	 * prev_irq_time stamp to account for the part that fit, so that a next
++	 * update will consume the rest. This ensures ->clock_task is
++	 * monotonic.
++	 *
++	 * It does however cause some slight miss-attribution of {soft,}irq
++	 * time, a more accurate solution would be to update the irq_time using
++	 * the current rq->clock timestamp, except that would require using
++	 * atomic ops.
++	 */
++	if (irq_delta > delta)
++		irq_delta = delta;
++
++	rq->prev_irq_time += irq_delta;
++	delta -= irq_delta;
++#endif
++#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
++	if (static_key_false((&paravirt_steal_rq_enabled))) {
++		steal = paravirt_steal_clock(cpu_of(rq));
++		steal -= rq->prev_steal_time_rq;
++
++		if (unlikely(steal > delta))
++			steal = delta;
++
++		rq->prev_steal_time_rq += steal;
++		delta -= steal;
++	}
++#endif
++
++	rq->clock_task += delta;
++
++#ifdef CONFIG_HAVE_SCHED_AVG_IRQ
++	if ((irq_delta + steal))
++		update_irq_load_avg(rq, irq_delta + steal);
++#endif
++}
++
++static inline void update_rq_clock(struct rq *rq)
++{
++	s64 delta = sched_clock_cpu(cpu_of(rq)) - rq->clock;
++
++	if (unlikely(delta <= 0))
++		return;
++	rq->clock += delta;
++	update_rq_time_edge(rq);
++	update_rq_clock_task(rq, delta);
++}
++
++/*
++ * RQ Load update routine
++ */
++#define RQ_LOAD_HISTORY_BITS		(sizeof(s32) * 8ULL)
++#define RQ_UTIL_SHIFT			(8)
++#define RQ_LOAD_HISTORY_TO_UTIL(l)	(((l) >> (RQ_LOAD_HISTORY_BITS - 1 - RQ_UTIL_SHIFT)) & 0xff)
++
++#define LOAD_BLOCK(t)		((t) >> 17)
++#define LOAD_HALF_BLOCK(t)	((t) >> 16)
++#define BLOCK_MASK(t)		((t) & ((0x01 << 18) - 1))
++#define LOAD_BLOCK_BIT(b)	(1UL << (RQ_LOAD_HISTORY_BITS - 1 - (b)))
++#define CURRENT_LOAD_BIT	LOAD_BLOCK_BIT(0)
++
++static inline void rq_load_update(struct rq *rq)
++{
++	u64 time = rq->clock;
++	u64 delta = min(LOAD_BLOCK(time) - LOAD_BLOCK(rq->load_stamp),
++			RQ_LOAD_HISTORY_BITS - 1);
++	u64 prev = !!(rq->load_history & CURRENT_LOAD_BIT);
++	u64 curr = !!rq->nr_running;
++
++	if (delta) {
++		rq->load_history = rq->load_history >> delta;
++
++		if (delta < RQ_UTIL_SHIFT) {
++			rq->load_block += (~BLOCK_MASK(rq->load_stamp)) * prev;
++			if (!!LOAD_HALF_BLOCK(rq->load_block) ^ curr)
++				rq->load_history ^= LOAD_BLOCK_BIT(delta);
++		}
++
++		rq->load_block = BLOCK_MASK(time) * prev;
++	} else {
++		rq->load_block += (time - rq->load_stamp) * prev;
++	}
++	if (prev ^ curr)
++		rq->load_history ^= CURRENT_LOAD_BIT;
++	rq->load_stamp = time;
++}
++
++unsigned long rq_load_util(int cpu)
++{
++	struct rq *rq;
++	unsigned long max;
++
++	rq = cpu_rq(cpu);
++	max = arch_scale_cpu_capacity(cpu);
++
++	return RQ_LOAD_HISTORY_TO_UTIL(rq->load_history) * (max >> RQ_UTIL_SHIFT);
++}
++
++#ifdef CONFIG_SMP
++unsigned long sched_cpu_util(int cpu)
++{
++	return rq_load_util(cpu);
++}
++#endif /* CONFIG_SMP */
++
++#ifdef CONFIG_CPU_FREQ
++/**
++ * cpufreq_update_util - Take a note about CPU utilization changes.
++ * @rq: Runqueue to carry out the update for.
++ * @flags: Update reason flags.
++ *
++ * This function is called by the scheduler on the CPU whose utilization is
++ * being updated.
++ *
++ * It can only be called from RCU-sched read-side critical sections.
++ *
++ * The way cpufreq is currently arranged requires it to evaluate the CPU
++ * performance state (frequency/voltage) on a regular basis to prevent it from
++ * being stuck in a completely inadequate performance level for too long.
++ * That is not guaranteed to happen if the updates are only triggered from CFS
++ * and DL, though, because they may not be coming in if only RT tasks are
++ * active all the time (or there are RT tasks only).
++ *
++ * As a workaround for that issue, this function is called periodically by the
++ * RT sched class to trigger extra cpufreq updates to prevent it from stalling,
++ * but that really is a band-aid.  Going forward it should be replaced with
++ * solutions targeted more specifically at RT tasks.
++ */
++static inline void cpufreq_update_util(struct rq *rq, unsigned int flags)
++{
++	struct update_util_data *data;
++
++#ifdef CONFIG_SMP
++	rq_load_update(rq);
++#endif
++	data = rcu_dereference_sched(*per_cpu_ptr(&cpufreq_update_util_data,
++						  cpu_of(rq)));
++	if (data)
++		data->func(data, rq_clock(rq), flags);
++}
++#else
++static inline void cpufreq_update_util(struct rq *rq, unsigned int flags)
++{
++#ifdef CONFIG_SMP
++	rq_load_update(rq);
++#endif
++}
++#endif /* CONFIG_CPU_FREQ */
++
++#ifdef CONFIG_NO_HZ_FULL
++/*
++ * Tick may be needed by tasks in the runqueue depending on their policy and
++ * requirements. If tick is needed, lets send the target an IPI to kick it out
++ * of nohz mode if necessary.
++ */
++static inline void sched_update_tick_dependency(struct rq *rq)
++{
++	int cpu = cpu_of(rq);
++
++	if (!tick_nohz_full_cpu(cpu))
++		return;
++
++	if (rq->nr_running < 2)
++		tick_nohz_dep_clear_cpu(cpu, TICK_DEP_BIT_SCHED);
++	else
++		tick_nohz_dep_set_cpu(cpu, TICK_DEP_BIT_SCHED);
++}
++#else /* !CONFIG_NO_HZ_FULL */
++static inline void sched_update_tick_dependency(struct rq *rq) { }
++#endif
++
++bool sched_task_on_rq(struct task_struct *p)
++{
++	return task_on_rq_queued(p);
++}
++
++unsigned long get_wchan(struct task_struct *p)
++{
++	unsigned long ip = 0;
++	unsigned int state;
++
++	if (!p || p == current)
++		return 0;
++
++	/* Only get wchan if task is blocked and we can keep it that way. */
++	raw_spin_lock_irq(&p->pi_lock);
++	state = READ_ONCE(p->__state);
++	smp_rmb(); /* see try_to_wake_up() */
++	if (state != TASK_RUNNING && state != TASK_WAKING && !p->on_rq)
++		ip = __get_wchan(p);
++	raw_spin_unlock_irq(&p->pi_lock);
++
++	return ip;
++}
++
++/*
++ * Add/Remove/Requeue task to/from the runqueue routines
++ * Context: rq->lock
++ */
++#define __SCHED_DEQUEUE_TASK(p, rq, flags)					\
++	psi_dequeue(p, flags & DEQUEUE_SLEEP);					\
++	sched_info_dequeue(rq, p);						\
++										\
++	list_del(&p->sq_node);							\
++	if (list_empty(&rq->queue.heads[p->sq_idx])) 				\
++		clear_bit(sched_idx2prio(p->sq_idx, rq), rq->queue.bitmap);
++
++#define __SCHED_ENQUEUE_TASK(p, rq, flags)				\
++	sched_info_enqueue(rq, p);					\
++	psi_enqueue(p, flags);						\
++									\
++	p->sq_idx = task_sched_prio_idx(p, rq);				\
++	list_add_tail(&p->sq_node, &rq->queue.heads[p->sq_idx]);	\
++	set_bit(sched_idx2prio(p->sq_idx, rq), rq->queue.bitmap);
++
++static inline void dequeue_task(struct task_struct *p, struct rq *rq, int flags)
++{
++	lockdep_assert_held(&rq->lock);
++
++	/*printk(KERN_INFO "sched: dequeue(%d) %px %016llx\n", cpu_of(rq), p, p->priodl);*/
++	WARN_ONCE(task_rq(p) != rq, "sched: dequeue task reside on cpu%d from cpu%d\n",
++		  task_cpu(p), cpu_of(rq));
++
++	__SCHED_DEQUEUE_TASK(p, rq, flags);
++	--rq->nr_running;
++#ifdef CONFIG_SMP
++	if (1 == rq->nr_running)
++		cpumask_clear_cpu(cpu_of(rq), &sched_rq_pending_mask);
++#endif
++
++	sched_update_tick_dependency(rq);
++}
++
++static inline void enqueue_task(struct task_struct *p, struct rq *rq, int flags)
++{
++	lockdep_assert_held(&rq->lock);
++
++	/*printk(KERN_INFO "sched: enqueue(%d) %px %016llx\n", cpu_of(rq), p, p->priodl);*/
++	WARN_ONCE(task_rq(p) != rq, "sched: enqueue task reside on cpu%d to cpu%d\n",
++		  task_cpu(p), cpu_of(rq));
++
++	__SCHED_ENQUEUE_TASK(p, rq, flags);
++	update_sched_rq_watermark(rq);
++	++rq->nr_running;
++#ifdef CONFIG_SMP
++	if (2 == rq->nr_running)
++		cpumask_set_cpu(cpu_of(rq), &sched_rq_pending_mask);
++#endif
++
++	sched_update_tick_dependency(rq);
++}
++
++static inline void requeue_task(struct task_struct *p, struct rq *rq, int idx)
++{
++	lockdep_assert_held(&rq->lock);
++	/*printk(KERN_INFO "sched: requeue(%d) %px %016llx\n", cpu_of(rq), p, p->priodl);*/
++	WARN_ONCE(task_rq(p) != rq, "sched: cpu[%d] requeue task reside on cpu%d\n",
++		  cpu_of(rq), task_cpu(p));
++
++	list_del(&p->sq_node);
++	list_add_tail(&p->sq_node, &rq->queue.heads[idx]);
++	if (idx != p->sq_idx) {
++		if (list_empty(&rq->queue.heads[p->sq_idx]))
++			clear_bit(sched_idx2prio(p->sq_idx, rq),
++				  rq->queue.bitmap);
++		p->sq_idx = idx;
++		set_bit(sched_idx2prio(p->sq_idx, rq), rq->queue.bitmap);
++		update_sched_rq_watermark(rq);
++	}
++}
++
++/*
++ * cmpxchg based fetch_or, macro so it works for different integer types
++ */
++#define fetch_or(ptr, mask)						\
++	({								\
++		typeof(ptr) _ptr = (ptr);				\
++		typeof(mask) _mask = (mask);				\
++		typeof(*_ptr) _old, _val = *_ptr;			\
++									\
++		for (;;) {						\
++			_old = cmpxchg(_ptr, _val, _val | _mask);	\
++			if (_old == _val)				\
++				break;					\
++			_val = _old;					\
++		}							\
++	_old;								\
++})
++
++#if defined(CONFIG_SMP) && defined(TIF_POLLING_NRFLAG)
++/*
++ * Atomically set TIF_NEED_RESCHED and test for TIF_POLLING_NRFLAG,
++ * this avoids any races wrt polling state changes and thereby avoids
++ * spurious IPIs.
++ */
++static bool set_nr_and_not_polling(struct task_struct *p)
++{
++	struct thread_info *ti = task_thread_info(p);
++	return !(fetch_or(&ti->flags, _TIF_NEED_RESCHED) & _TIF_POLLING_NRFLAG);
++}
++
++/*
++ * Atomically set TIF_NEED_RESCHED if TIF_POLLING_NRFLAG is set.
++ *
++ * If this returns true, then the idle task promises to call
++ * sched_ttwu_pending() and reschedule soon.
++ */
++static bool set_nr_if_polling(struct task_struct *p)
++{
++	struct thread_info *ti = task_thread_info(p);
++	typeof(ti->flags) old, val = READ_ONCE(ti->flags);
++
++	for (;;) {
++		if (!(val & _TIF_POLLING_NRFLAG))
++			return false;
++		if (val & _TIF_NEED_RESCHED)
++			return true;
++		old = cmpxchg(&ti->flags, val, val | _TIF_NEED_RESCHED);
++		if (old == val)
++			break;
++		val = old;
++	}
++	return true;
++}
++
++#else
++static bool set_nr_and_not_polling(struct task_struct *p)
++{
++	set_tsk_need_resched(p);
++	return true;
++}
++
++#ifdef CONFIG_SMP
++static bool set_nr_if_polling(struct task_struct *p)
++{
++	return false;
++}
++#endif
++#endif
++
++static bool __wake_q_add(struct wake_q_head *head, struct task_struct *task)
++{
++	struct wake_q_node *node = &task->wake_q;
++
++	/*
++	 * Atomically grab the task, if ->wake_q is !nil already it means
++	 * it's already queued (either by us or someone else) and will get the
++	 * wakeup due to that.
++	 *
++	 * In order to ensure that a pending wakeup will observe our pending
++	 * state, even in the failed case, an explicit smp_mb() must be used.
++	 */
++	smp_mb__before_atomic();
++	if (unlikely(cmpxchg_relaxed(&node->next, NULL, WAKE_Q_TAIL)))
++		return false;
++
++	/*
++	 * The head is context local, there can be no concurrency.
++	 */
++	*head->lastp = node;
++	head->lastp = &node->next;
++	return true;
++}
++
++/**
++ * wake_q_add() - queue a wakeup for 'later' waking.
++ * @head: the wake_q_head to add @task to
++ * @task: the task to queue for 'later' wakeup
++ *
++ * Queue a task for later wakeup, most likely by the wake_up_q() call in the
++ * same context, _HOWEVER_ this is not guaranteed, the wakeup can come
++ * instantly.
++ *
++ * This function must be used as-if it were wake_up_process(); IOW the task
++ * must be ready to be woken at this location.
++ */
++void wake_q_add(struct wake_q_head *head, struct task_struct *task)
++{
++	if (__wake_q_add(head, task))
++		get_task_struct(task);
++}
++
++/**
++ * wake_q_add_safe() - safely queue a wakeup for 'later' waking.
++ * @head: the wake_q_head to add @task to
++ * @task: the task to queue for 'later' wakeup
++ *
++ * Queue a task for later wakeup, most likely by the wake_up_q() call in the
++ * same context, _HOWEVER_ this is not guaranteed, the wakeup can come
++ * instantly.
++ *
++ * This function must be used as-if it were wake_up_process(); IOW the task
++ * must be ready to be woken at this location.
++ *
++ * This function is essentially a task-safe equivalent to wake_q_add(). Callers
++ * that already hold reference to @task can call the 'safe' version and trust
++ * wake_q to do the right thing depending whether or not the @task is already
++ * queued for wakeup.
++ */
++void wake_q_add_safe(struct wake_q_head *head, struct task_struct *task)
++{
++	if (!__wake_q_add(head, task))
++		put_task_struct(task);
++}
++
++void wake_up_q(struct wake_q_head *head)
++{
++	struct wake_q_node *node = head->first;
++
++	while (node != WAKE_Q_TAIL) {
++		struct task_struct *task;
++
++		task = container_of(node, struct task_struct, wake_q);
++		/* task can safely be re-inserted now: */
++		node = node->next;
++		task->wake_q.next = NULL;
++
++		/*
++		 * wake_up_process() executes a full barrier, which pairs with
++		 * the queueing in wake_q_add() so as not to miss wakeups.
++		 */
++		wake_up_process(task);
++		put_task_struct(task);
++	}
++}
++
++/*
++ * resched_curr - mark rq's current task 'to be rescheduled now'.
++ *
++ * On UP this means the setting of the need_resched flag, on SMP it
++ * might also involve a cross-CPU call to trigger the scheduler on
++ * the target CPU.
++ */
++void resched_curr(struct rq *rq)
++{
++	struct task_struct *curr = rq->curr;
++	int cpu;
++
++	lockdep_assert_held(&rq->lock);
++
++	if (test_tsk_need_resched(curr))
++		return;
++
++	cpu = cpu_of(rq);
++	if (cpu == smp_processor_id()) {
++		set_tsk_need_resched(curr);
++		set_preempt_need_resched();
++		return;
++	}
++
++	if (set_nr_and_not_polling(curr))
++		smp_send_reschedule(cpu);
++	else
++		trace_sched_wake_idle_without_ipi(cpu);
++}
++
++void resched_cpu(int cpu)
++{
++	struct rq *rq = cpu_rq(cpu);
++	unsigned long flags;
++
++	raw_spin_lock_irqsave(&rq->lock, flags);
++	if (cpu_online(cpu) || cpu == smp_processor_id())
++		resched_curr(cpu_rq(cpu));
++	raw_spin_unlock_irqrestore(&rq->lock, flags);
++}
++
++#ifdef CONFIG_SMP
++#ifdef CONFIG_NO_HZ_COMMON
++void nohz_balance_enter_idle(int cpu) {}
++
++void select_nohz_load_balancer(int stop_tick) {}
++
++void set_cpu_sd_state_idle(void) {}
++
++/*
++ * In the semi idle case, use the nearest busy CPU for migrating timers
++ * from an idle CPU.  This is good for power-savings.
++ *
++ * We don't do similar optimization for completely idle system, as
++ * selecting an idle CPU will add more delays to the timers than intended
++ * (as that CPU's timer base may not be uptodate wrt jiffies etc).
++ */
++int get_nohz_timer_target(void)
++{
++	int i, cpu = smp_processor_id(), default_cpu = -1;
++	struct cpumask *mask;
++	const struct cpumask *hk_mask;
++
++	if (housekeeping_cpu(cpu, HK_TYPE_TIMER)) {
++		if (!idle_cpu(cpu))
++			return cpu;
++		default_cpu = cpu;
++	}
++
++	hk_mask = housekeeping_cpumask(HK_TYPE_TIMER);
++
++	for (mask = per_cpu(sched_cpu_topo_masks, cpu) + 1;
++	     mask < per_cpu(sched_cpu_topo_end_mask, cpu); mask++)
++		for_each_cpu_and(i, mask, hk_mask)
++			if (!idle_cpu(i))
++				return i;
++
++	if (default_cpu == -1)
++		default_cpu = housekeeping_any_cpu(HK_TYPE_TIMER);
++	cpu = default_cpu;
++
++	return cpu;
++}
++
++/*
++ * When add_timer_on() enqueues a timer into the timer wheel of an
++ * idle CPU then this timer might expire before the next timer event
++ * which is scheduled to wake up that CPU. In case of a completely
++ * idle system the next event might even be infinite time into the
++ * future. wake_up_idle_cpu() ensures that the CPU is woken up and
++ * leaves the inner idle loop so the newly added timer is taken into
++ * account when the CPU goes back to idle and evaluates the timer
++ * wheel for the next timer event.
++ */
++static inline void wake_up_idle_cpu(int cpu)
++{
++	struct rq *rq = cpu_rq(cpu);
++
++	if (cpu == smp_processor_id())
++		return;
++
++	if (set_nr_and_not_polling(rq->idle))
++		smp_send_reschedule(cpu);
++	else
++		trace_sched_wake_idle_without_ipi(cpu);
++}
++
++static inline bool wake_up_full_nohz_cpu(int cpu)
++{
++	/*
++	 * We just need the target to call irq_exit() and re-evaluate
++	 * the next tick. The nohz full kick at least implies that.
++	 * If needed we can still optimize that later with an
++	 * empty IRQ.
++	 */
++	if (cpu_is_offline(cpu))
++		return true;  /* Don't try to wake offline CPUs. */
++	if (tick_nohz_full_cpu(cpu)) {
++		if (cpu != smp_processor_id() ||
++		    tick_nohz_tick_stopped())
++			tick_nohz_full_kick_cpu(cpu);
++		return true;
++	}
++
++	return false;
++}
++
++void wake_up_nohz_cpu(int cpu)
++{
++	if (!wake_up_full_nohz_cpu(cpu))
++		wake_up_idle_cpu(cpu);
++}
++
++static void nohz_csd_func(void *info)
++{
++	struct rq *rq = info;
++	int cpu = cpu_of(rq);
++	unsigned int flags;
++
++	/*
++	 * Release the rq::nohz_csd.
++	 */
++	flags = atomic_fetch_andnot(NOHZ_KICK_MASK, nohz_flags(cpu));
++	WARN_ON(!(flags & NOHZ_KICK_MASK));
++
++	rq->idle_balance = idle_cpu(cpu);
++	if (rq->idle_balance && !need_resched()) {
++		rq->nohz_idle_balance = flags;
++		raise_softirq_irqoff(SCHED_SOFTIRQ);
++	}
++}
++
++#endif /* CONFIG_NO_HZ_COMMON */
++#endif /* CONFIG_SMP */
++
++static inline void check_preempt_curr(struct rq *rq)
++{
++	if (sched_rq_first_task(rq) != rq->curr)
++		resched_curr(rq);
++}
++
++#ifdef CONFIG_SCHED_HRTICK
++/*
++ * Use HR-timers to deliver accurate preemption points.
++ */
++
++static void hrtick_clear(struct rq *rq)
++{
++	if (hrtimer_active(&rq->hrtick_timer))
++		hrtimer_cancel(&rq->hrtick_timer);
++}
++
++/*
++ * High-resolution timer tick.
++ * Runs from hardirq context with interrupts disabled.
++ */
++static enum hrtimer_restart hrtick(struct hrtimer *timer)
++{
++	struct rq *rq = container_of(timer, struct rq, hrtick_timer);
++
++	WARN_ON_ONCE(cpu_of(rq) != smp_processor_id());
++
++	raw_spin_lock(&rq->lock);
++	resched_curr(rq);
++	raw_spin_unlock(&rq->lock);
++
++	return HRTIMER_NORESTART;
++}
++
++/*
++ * Use hrtick when:
++ *  - enabled by features
++ *  - hrtimer is actually high res
++ */
++static inline int hrtick_enabled(struct rq *rq)
++{
++	/**
++	 * Alt schedule FW doesn't support sched_feat yet
++	if (!sched_feat(HRTICK))
++		return 0;
++	*/
++	if (!cpu_active(cpu_of(rq)))
++		return 0;
++	return hrtimer_is_hres_active(&rq->hrtick_timer);
++}
++
++#ifdef CONFIG_SMP
++
++static void __hrtick_restart(struct rq *rq)
++{
++	struct hrtimer *timer = &rq->hrtick_timer;
++	ktime_t time = rq->hrtick_time;
++
++	hrtimer_start(timer, time, HRTIMER_MODE_ABS_PINNED_HARD);
++}
++
++/*
++ * called from hardirq (IPI) context
++ */
++static void __hrtick_start(void *arg)
++{
++	struct rq *rq = arg;
++
++	raw_spin_lock(&rq->lock);
++	__hrtick_restart(rq);
++	raw_spin_unlock(&rq->lock);
++}
++
++/*
++ * Called to set the hrtick timer state.
++ *
++ * called with rq->lock held and irqs disabled
++ */
++void hrtick_start(struct rq *rq, u64 delay)
++{
++	struct hrtimer *timer = &rq->hrtick_timer;
++	s64 delta;
++
++	/*
++	 * Don't schedule slices shorter than 10000ns, that just
++	 * doesn't make sense and can cause timer DoS.
++	 */
++	delta = max_t(s64, delay, 10000LL);
++
++	rq->hrtick_time = ktime_add_ns(timer->base->get_time(), delta);
++
++	if (rq == this_rq())
++		__hrtick_restart(rq);
++	else
++		smp_call_function_single_async(cpu_of(rq), &rq->hrtick_csd);
++}
++
++#else
++/*
++ * Called to set the hrtick timer state.
++ *
++ * called with rq->lock held and irqs disabled
++ */
++void hrtick_start(struct rq *rq, u64 delay)
++{
++	/*
++	 * Don't schedule slices shorter than 10000ns, that just
++	 * doesn't make sense. Rely on vruntime for fairness.
++	 */
++	delay = max_t(u64, delay, 10000LL);
++	hrtimer_start(&rq->hrtick_timer, ns_to_ktime(delay),
++		      HRTIMER_MODE_REL_PINNED_HARD);
++}
++#endif /* CONFIG_SMP */
++
++static void hrtick_rq_init(struct rq *rq)
++{
++#ifdef CONFIG_SMP
++	INIT_CSD(&rq->hrtick_csd, __hrtick_start, rq);
++#endif
++
++	hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD);
++	rq->hrtick_timer.function = hrtick;
++}
++#else	/* CONFIG_SCHED_HRTICK */
++static inline int hrtick_enabled(struct rq *rq)
++{
++	return 0;
++}
++
++static inline void hrtick_clear(struct rq *rq)
++{
++}
++
++static inline void hrtick_rq_init(struct rq *rq)
++{
++}
++#endif	/* CONFIG_SCHED_HRTICK */
++
++static inline int __normal_prio(int policy, int rt_prio, int static_prio)
++{
++	return rt_policy(policy) ? (MAX_RT_PRIO - 1 - rt_prio) :
++		static_prio + MAX_PRIORITY_ADJ;
++}
++
++/*
++ * Calculate the expected normal priority: i.e. priority
++ * without taking RT-inheritance into account. Might be
++ * boosted by interactivity modifiers. Changes upon fork,
++ * setprio syscalls, and whenever the interactivity
++ * estimator recalculates.
++ */
++static inline int normal_prio(struct task_struct *p)
++{
++	return __normal_prio(p->policy, p->rt_priority, p->static_prio);
++}
++
++/*
++ * Calculate the current priority, i.e. the priority
++ * taken into account by the scheduler. This value might
++ * be boosted by RT tasks as it will be RT if the task got
++ * RT-boosted. If not then it returns p->normal_prio.
++ */
++static int effective_prio(struct task_struct *p)
++{
++	p->normal_prio = normal_prio(p);
++	/*
++	 * If we are RT tasks or we were boosted to RT priority,
++	 * keep the priority unchanged. Otherwise, update priority
++	 * to the normal priority:
++	 */
++	if (!rt_prio(p->prio))
++		return p->normal_prio;
++	return p->prio;
++}
++
++/*
++ * activate_task - move a task to the runqueue.
++ *
++ * Context: rq->lock
++ */
++static void activate_task(struct task_struct *p, struct rq *rq)
++{
++	enqueue_task(p, rq, ENQUEUE_WAKEUP);
++	p->on_rq = TASK_ON_RQ_QUEUED;
++
++	/*
++	 * If in_iowait is set, the code below may not trigger any cpufreq
++	 * utilization updates, so do it here explicitly with the IOWAIT flag
++	 * passed.
++	 */
++	cpufreq_update_util(rq, SCHED_CPUFREQ_IOWAIT * p->in_iowait);
++}
++
++/*
++ * deactivate_task - remove a task from the runqueue.
++ *
++ * Context: rq->lock
++ */
++static inline void deactivate_task(struct task_struct *p, struct rq *rq)
++{
++	dequeue_task(p, rq, DEQUEUE_SLEEP);
++	p->on_rq = 0;
++	cpufreq_update_util(rq, 0);
++}
++
++static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu)
++{
++#ifdef CONFIG_SMP
++	/*
++	 * After ->cpu is set up to a new value, task_access_lock(p, ...) can be
++	 * successfully executed on another CPU. We must ensure that updates of
++	 * per-task data have been completed by this moment.
++	 */
++	smp_wmb();
++
++	WRITE_ONCE(task_thread_info(p)->cpu, cpu);
++#endif
++}
++
++static inline bool is_migration_disabled(struct task_struct *p)
++{
++#ifdef CONFIG_SMP
++	return p->migration_disabled;
++#else
++	return false;
++#endif
++}
++
++#define SCA_CHECK		0x01
++#define SCA_USER		0x08
++
++#ifdef CONFIG_SMP
++
++void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
++{
++#ifdef CONFIG_SCHED_DEBUG
++	unsigned int state = READ_ONCE(p->__state);
++
++	/*
++	 * We should never call set_task_cpu() on a blocked task,
++	 * ttwu() will sort out the placement.
++	 */
++	WARN_ON_ONCE(state != TASK_RUNNING && state != TASK_WAKING && !p->on_rq);
++
++#ifdef CONFIG_LOCKDEP
++	/*
++	 * The caller should hold either p->pi_lock or rq->lock, when changing
++	 * a task's CPU. ->pi_lock for waking tasks, rq->lock for runnable tasks.
++	 *
++	 * sched_move_task() holds both and thus holding either pins the cgroup,
++	 * see task_group().
++	 */
++	WARN_ON_ONCE(debug_locks && !(lockdep_is_held(&p->pi_lock) ||
++				      lockdep_is_held(&task_rq(p)->lock)));
++#endif
++	/*
++	 * Clearly, migrating tasks to offline CPUs is a fairly daft thing.
++	 */
++	WARN_ON_ONCE(!cpu_online(new_cpu));
++
++	WARN_ON_ONCE(is_migration_disabled(p));
++#endif
++	if (task_cpu(p) == new_cpu)
++		return;
++	trace_sched_migrate_task(p, new_cpu);
++	rseq_migrate(p);
++	perf_event_task_migrate(p);
++
++	__set_task_cpu(p, new_cpu);
++}
++
++#define MDF_FORCE_ENABLED	0x80
++
++static void
++__do_set_cpus_ptr(struct task_struct *p, const struct cpumask *new_mask)
++{
++	/*
++	 * This here violates the locking rules for affinity, since we're only
++	 * supposed to change these variables while holding both rq->lock and
++	 * p->pi_lock.
++	 *
++	 * HOWEVER, it magically works, because ttwu() is the only code that
++	 * accesses these variables under p->pi_lock and only does so after
++	 * smp_cond_load_acquire(&p->on_cpu, !VAL), and we're in __schedule()
++	 * before finish_task().
++	 *
++	 * XXX do further audits, this smells like something putrid.
++	 */
++	SCHED_WARN_ON(!p->on_cpu);
++	p->cpus_ptr = new_mask;
++}
++
++void migrate_disable(void)
++{
++	struct task_struct *p = current;
++	int cpu;
++
++	if (p->migration_disabled) {
++		p->migration_disabled++;
++		return;
++	}
++
++	preempt_disable();
++	cpu = smp_processor_id();
++	if (cpumask_test_cpu(cpu, &p->cpus_mask)) {
++		cpu_rq(cpu)->nr_pinned++;
++		p->migration_disabled = 1;
++		p->migration_flags &= ~MDF_FORCE_ENABLED;
++
++		/*
++		 * Violates locking rules! see comment in __do_set_cpus_ptr().
++		 */
++		if (p->cpus_ptr == &p->cpus_mask)
++			__do_set_cpus_ptr(p, cpumask_of(cpu));
++	}
++	preempt_enable();
++}
++EXPORT_SYMBOL_GPL(migrate_disable);
++
++void migrate_enable(void)
++{
++	struct task_struct *p = current;
++
++	if (0 == p->migration_disabled)
++		return;
++
++	if (p->migration_disabled > 1) {
++		p->migration_disabled--;
++		return;
++	}
++
++	if (WARN_ON_ONCE(!p->migration_disabled))
++		return;
++
++	/*
++	 * Ensure stop_task runs either before or after this, and that
++	 * __set_cpus_allowed_ptr(SCA_MIGRATE_ENABLE) doesn't schedule().
++	 */
++	preempt_disable();
++	/*
++	 * Assumption: current should be running on allowed cpu
++	 */
++	WARN_ON_ONCE(!cpumask_test_cpu(smp_processor_id(), &p->cpus_mask));
++	if (p->cpus_ptr != &p->cpus_mask)
++		__do_set_cpus_ptr(p, &p->cpus_mask);
++	/*
++	 * Mustn't clear migration_disabled() until cpus_ptr points back at the
++	 * regular cpus_mask, otherwise things that race (eg.
++	 * select_fallback_rq) get confused.
++	 */
++	barrier();
++	p->migration_disabled = 0;
++	this_rq()->nr_pinned--;
++	preempt_enable();
++}
++EXPORT_SYMBOL_GPL(migrate_enable);
++
++static inline bool rq_has_pinned_tasks(struct rq *rq)
++{
++	return rq->nr_pinned;
++}
++
++/*
++ * Per-CPU kthreads are allowed to run on !active && online CPUs, see
++ * __set_cpus_allowed_ptr() and select_fallback_rq().
++ */
++static inline bool is_cpu_allowed(struct task_struct *p, int cpu)
++{
++	/* When not in the task's cpumask, no point in looking further. */
++	if (!cpumask_test_cpu(cpu, p->cpus_ptr))
++		return false;
++
++	/* migrate_disabled() must be allowed to finish. */
++	if (is_migration_disabled(p))
++		return cpu_online(cpu);
++
++	/* Non kernel threads are not allowed during either online or offline. */
++	if (!(p->flags & PF_KTHREAD))
++		return cpu_active(cpu) && task_cpu_possible(cpu, p);
++
++	/* KTHREAD_IS_PER_CPU is always allowed. */
++	if (kthread_is_per_cpu(p))
++		return cpu_online(cpu);
++
++	/* Regular kernel threads don't get to stay during offline. */
++	if (cpu_dying(cpu))
++		return false;
++
++	/* But are allowed during online. */
++	return cpu_online(cpu);
++}
++
++/*
++ * This is how migration works:
++ *
++ * 1) we invoke migration_cpu_stop() on the target CPU using
++ *    stop_one_cpu().
++ * 2) stopper starts to run (implicitly forcing the migrated thread
++ *    off the CPU)
++ * 3) it checks whether the migrated task is still in the wrong runqueue.
++ * 4) if it's in the wrong runqueue then the migration thread removes
++ *    it and puts it into the right queue.
++ * 5) stopper completes and stop_one_cpu() returns and the migration
++ *    is done.
++ */
++
++/*
++ * move_queued_task - move a queued task to new rq.
++ *
++ * Returns (locked) new rq. Old rq's lock is released.
++ */
++static struct rq *move_queued_task(struct rq *rq, struct task_struct *p, int
++				   new_cpu)
++{
++	lockdep_assert_held(&rq->lock);
++
++	WRITE_ONCE(p->on_rq, TASK_ON_RQ_MIGRATING);
++	dequeue_task(p, rq, 0);
++	update_sched_rq_watermark(rq);
++	set_task_cpu(p, new_cpu);
++	raw_spin_unlock(&rq->lock);
++
++	rq = cpu_rq(new_cpu);
++
++	raw_spin_lock(&rq->lock);
++	BUG_ON(task_cpu(p) != new_cpu);
++	sched_task_sanity_check(p, rq);
++	enqueue_task(p, rq, 0);
++	p->on_rq = TASK_ON_RQ_QUEUED;
++	check_preempt_curr(rq);
++
++	return rq;
++}
++
++struct migration_arg {
++	struct task_struct *task;
++	int dest_cpu;
++};
++
++/*
++ * Move (not current) task off this CPU, onto the destination CPU. We're doing
++ * this because either it can't run here any more (set_cpus_allowed()
++ * away from this CPU, or CPU going down), or because we're
++ * attempting to rebalance this task on exec (sched_exec).
++ *
++ * So we race with normal scheduler movements, but that's OK, as long
++ * as the task is no longer on this CPU.
++ */
++static struct rq *__migrate_task(struct rq *rq, struct task_struct *p, int
++				 dest_cpu)
++{
++	/* Affinity changed (again). */
++	if (!is_cpu_allowed(p, dest_cpu))
++		return rq;
++
++	update_rq_clock(rq);
++	return move_queued_task(rq, p, dest_cpu);
++}
++
++/*
++ * migration_cpu_stop - this will be executed by a highprio stopper thread
++ * and performs thread migration by bumping thread off CPU then
++ * 'pushing' onto another runqueue.
++ */
++static int migration_cpu_stop(void *data)
++{
++	struct migration_arg *arg = data;
++	struct task_struct *p = arg->task;
++	struct rq *rq = this_rq();
++	unsigned long flags;
++
++	/*
++	 * The original target CPU might have gone down and we might
++	 * be on another CPU but it doesn't matter.
++	 */
++	local_irq_save(flags);
++	/*
++	 * We need to explicitly wake pending tasks before running
++	 * __migrate_task() such that we will not miss enforcing cpus_ptr
++	 * during wakeups, see set_cpus_allowed_ptr()'s TASK_WAKING test.
++	 */
++	flush_smp_call_function_queue();
++
++	raw_spin_lock(&p->pi_lock);
++	raw_spin_lock(&rq->lock);
++	/*
++	 * If task_rq(p) != rq, it cannot be migrated here, because we're
++	 * holding rq->lock, if p->on_rq == 0 it cannot get enqueued because
++	 * we're holding p->pi_lock.
++	 */
++	if (task_rq(p) == rq && task_on_rq_queued(p))
++		rq = __migrate_task(rq, p, arg->dest_cpu);
++	raw_spin_unlock(&rq->lock);
++	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++
++	return 0;
++}
++
++static inline void
++set_cpus_allowed_common(struct task_struct *p, const struct cpumask *new_mask)
++{
++	cpumask_copy(&p->cpus_mask, new_mask);
++	p->nr_cpus_allowed = cpumask_weight(new_mask);
++}
++
++static void
++__do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
++{
++	lockdep_assert_held(&p->pi_lock);
++	set_cpus_allowed_common(p, new_mask);
++}
++
++void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
++{
++	__do_set_cpus_allowed(p, new_mask);
++}
++
++int dup_user_cpus_ptr(struct task_struct *dst, struct task_struct *src,
++		      int node)
++{
++	if (!src->user_cpus_ptr)
++		return 0;
++
++	dst->user_cpus_ptr = kmalloc_node(cpumask_size(), GFP_KERNEL, node);
++	if (!dst->user_cpus_ptr)
++		return -ENOMEM;
++
++	cpumask_copy(dst->user_cpus_ptr, src->user_cpus_ptr);
++	return 0;
++}
++
++static inline struct cpumask *clear_user_cpus_ptr(struct task_struct *p)
++{
++	struct cpumask *user_mask = NULL;
++
++	swap(p->user_cpus_ptr, user_mask);
++
++	return user_mask;
++}
++
++void release_user_cpus_ptr(struct task_struct *p)
++{
++	kfree(clear_user_cpus_ptr(p));
++}
++
++#endif
++
++/**
++ * task_curr - is this task currently executing on a CPU?
++ * @p: the task in question.
++ *
++ * Return: 1 if the task is currently executing. 0 otherwise.
++ */
++inline int task_curr(const struct task_struct *p)
++{
++	return cpu_curr(task_cpu(p)) == p;
++}
++
++#ifdef CONFIG_SMP
++/*
++ * wait_task_inactive - wait for a thread to unschedule.
++ *
++ * If @match_state is nonzero, it's the @p->state value just checked and
++ * not expected to change.  If it changes, i.e. @p might have woken up,
++ * then return zero.  When we succeed in waiting for @p to be off its CPU,
++ * we return a positive number (its total switch count).  If a second call
++ * a short while later returns the same number, the caller can be sure that
++ * @p has remained unscheduled the whole time.
++ *
++ * The caller must ensure that the task *will* unschedule sometime soon,
++ * else this function might spin for a *long* time. This function can't
++ * be called with interrupts off, or it may introduce deadlock with
++ * smp_call_function() if an IPI is sent by the same process we are
++ * waiting to become inactive.
++ */
++unsigned long wait_task_inactive(struct task_struct *p, unsigned int match_state)
++{
++	unsigned long flags;
++	bool running, on_rq;
++	unsigned long ncsw;
++	struct rq *rq;
++	raw_spinlock_t *lock;
++
++	for (;;) {
++		rq = task_rq(p);
++
++		/*
++		 * If the task is actively running on another CPU
++		 * still, just relax and busy-wait without holding
++		 * any locks.
++		 *
++		 * NOTE! Since we don't hold any locks, it's not
++		 * even sure that "rq" stays as the right runqueue!
++		 * But we don't care, since this will return false
++		 * if the runqueue has changed and p is actually now
++		 * running somewhere else!
++		 */
++		while (task_running(p) && p == rq->curr) {
++			if (match_state && unlikely(READ_ONCE(p->__state) != match_state))
++				return 0;
++			cpu_relax();
++		}
++
++		/*
++		 * Ok, time to look more closely! We need the rq
++		 * lock now, to be *sure*. If we're wrong, we'll
++		 * just go back and repeat.
++		 */
++		task_access_lock_irqsave(p, &lock, &flags);
++		trace_sched_wait_task(p);
++		running = task_running(p);
++		on_rq = p->on_rq;
++		ncsw = 0;
++		if (!match_state || READ_ONCE(p->__state) == match_state)
++			ncsw = p->nvcsw | LONG_MIN; /* sets MSB */
++		task_access_unlock_irqrestore(p, lock, &flags);
++
++		/*
++		 * If it changed from the expected state, bail out now.
++		 */
++		if (unlikely(!ncsw))
++			break;
++
++		/*
++		 * Was it really running after all now that we
++		 * checked with the proper locks actually held?
++		 *
++		 * Oops. Go back and try again..
++		 */
++		if (unlikely(running)) {
++			cpu_relax();
++			continue;
++		}
++
++		/*
++		 * It's not enough that it's not actively running,
++		 * it must be off the runqueue _entirely_, and not
++		 * preempted!
++		 *
++		 * So if it was still runnable (but just not actively
++		 * running right now), it's preempted, and we should
++		 * yield - it could be a while.
++		 */
++		if (unlikely(on_rq)) {
++			ktime_t to = NSEC_PER_SEC / HZ;
++
++			set_current_state(TASK_UNINTERRUPTIBLE);
++			schedule_hrtimeout(&to, HRTIMER_MODE_REL_HARD);
++			continue;
++		}
++
++		/*
++		 * Ahh, all good. It wasn't running, and it wasn't
++		 * runnable, which means that it will never become
++		 * running in the future either. We're all done!
++		 */
++		break;
++	}
++
++	return ncsw;
++}
++
++/***
++ * kick_process - kick a running thread to enter/exit the kernel
++ * @p: the to-be-kicked thread
++ *
++ * Cause a process which is running on another CPU to enter
++ * kernel-mode, without any delay. (to get signals handled.)
++ *
++ * NOTE: this function doesn't have to take the runqueue lock,
++ * because all it wants to ensure is that the remote task enters
++ * the kernel. If the IPI races and the task has been migrated
++ * to another CPU then no harm is done and the purpose has been
++ * achieved as well.
++ */
++void kick_process(struct task_struct *p)
++{
++	int cpu;
++
++	preempt_disable();
++	cpu = task_cpu(p);
++	if ((cpu != smp_processor_id()) && task_curr(p))
++		smp_send_reschedule(cpu);
++	preempt_enable();
++}
++EXPORT_SYMBOL_GPL(kick_process);
++
++/*
++ * ->cpus_ptr is protected by both rq->lock and p->pi_lock
++ *
++ * A few notes on cpu_active vs cpu_online:
++ *
++ *  - cpu_active must be a subset of cpu_online
++ *
++ *  - on CPU-up we allow per-CPU kthreads on the online && !active CPU,
++ *    see __set_cpus_allowed_ptr(). At this point the newly online
++ *    CPU isn't yet part of the sched domains, and balancing will not
++ *    see it.
++ *
++ *  - on cpu-down we clear cpu_active() to mask the sched domains and
++ *    avoid the load balancer to place new tasks on the to be removed
++ *    CPU. Existing tasks will remain running there and will be taken
++ *    off.
++ *
++ * This means that fallback selection must not select !active CPUs.
++ * And can assume that any active CPU must be online. Conversely
++ * select_task_rq() below may allow selection of !active CPUs in order
++ * to satisfy the above rules.
++ */
++static int select_fallback_rq(int cpu, struct task_struct *p)
++{
++	int nid = cpu_to_node(cpu);
++	const struct cpumask *nodemask = NULL;
++	enum { cpuset, possible, fail } state = cpuset;
++	int dest_cpu;
++
++	/*
++	 * If the node that the CPU is on has been offlined, cpu_to_node()
++	 * will return -1. There is no CPU on the node, and we should
++	 * select the CPU on the other node.
++	 */
++	if (nid != -1) {
++		nodemask = cpumask_of_node(nid);
++
++		/* Look for allowed, online CPU in same node. */
++		for_each_cpu(dest_cpu, nodemask) {
++			if (is_cpu_allowed(p, dest_cpu))
++				return dest_cpu;
++		}
++	}
++
++	for (;;) {
++		/* Any allowed, online CPU? */
++		for_each_cpu(dest_cpu, p->cpus_ptr) {
++			if (!is_cpu_allowed(p, dest_cpu))
++				continue;
++			goto out;
++		}
++
++		/* No more Mr. Nice Guy. */
++		switch (state) {
++		case cpuset:
++			if (cpuset_cpus_allowed_fallback(p)) {
++				state = possible;
++				break;
++			}
++			fallthrough;
++		case possible:
++			/*
++			 * XXX When called from select_task_rq() we only
++			 * hold p->pi_lock and again violate locking order.
++			 *
++			 * More yuck to audit.
++			 */
++			do_set_cpus_allowed(p, task_cpu_possible_mask(p));
++			state = fail;
++			break;
++
++		case fail:
++			BUG();
++			break;
++		}
++	}
++
++out:
++	if (state != cpuset) {
++		/*
++		 * Don't tell them about moving exiting tasks or
++		 * kernel threads (both mm NULL), since they never
++		 * leave kernel.
++		 */
++		if (p->mm && printk_ratelimit()) {
++			printk_deferred("process %d (%s) no longer affine to cpu%d\n",
++					task_pid_nr(p), p->comm, cpu);
++		}
++	}
++
++	return dest_cpu;
++}
++
++static inline int select_task_rq(struct task_struct *p)
++{
++	cpumask_t chk_mask, tmp;
++
++	if (unlikely(!cpumask_and(&chk_mask, p->cpus_ptr, cpu_active_mask)))
++		return select_fallback_rq(task_cpu(p), p);
++
++	if (
++#ifdef CONFIG_SCHED_SMT
++	    cpumask_and(&tmp, &chk_mask, &sched_sg_idle_mask) ||
++#endif
++	    cpumask_and(&tmp, &chk_mask, sched_rq_watermark) ||
++	    cpumask_and(&tmp, &chk_mask,
++			sched_rq_watermark + SCHED_QUEUE_BITS - 1 - task_sched_prio(p)))
++		return best_mask_cpu(task_cpu(p), &tmp);
++
++	return best_mask_cpu(task_cpu(p), &chk_mask);
++}
++
++void sched_set_stop_task(int cpu, struct task_struct *stop)
++{
++	static struct lock_class_key stop_pi_lock;
++	struct sched_param stop_param = { .sched_priority = STOP_PRIO };
++	struct sched_param start_param = { .sched_priority = 0 };
++	struct task_struct *old_stop = cpu_rq(cpu)->stop;
++
++	if (stop) {
++		/*
++		 * Make it appear like a SCHED_FIFO task, its something
++		 * userspace knows about and won't get confused about.
++		 *
++		 * Also, it will make PI more or less work without too
++		 * much confusion -- but then, stop work should not
++		 * rely on PI working anyway.
++		 */
++		sched_setscheduler_nocheck(stop, SCHED_FIFO, &stop_param);
++
++		/*
++		 * The PI code calls rt_mutex_setprio() with ->pi_lock held to
++		 * adjust the effective priority of a task. As a result,
++		 * rt_mutex_setprio() can trigger (RT) balancing operations,
++		 * which can then trigger wakeups of the stop thread to push
++		 * around the current task.
++		 *
++		 * The stop task itself will never be part of the PI-chain, it
++		 * never blocks, therefore that ->pi_lock recursion is safe.
++		 * Tell lockdep about this by placing the stop->pi_lock in its
++		 * own class.
++		 */
++		lockdep_set_class(&stop->pi_lock, &stop_pi_lock);
++	}
++
++	cpu_rq(cpu)->stop = stop;
++
++	if (old_stop) {
++		/*
++		 * Reset it back to a normal scheduling policy so that
++		 * it can die in pieces.
++		 */
++		sched_setscheduler_nocheck(old_stop, SCHED_NORMAL, &start_param);
++	}
++}
++
++static int affine_move_task(struct rq *rq, struct task_struct *p, int dest_cpu,
++			    raw_spinlock_t *lock, unsigned long irq_flags)
++{
++	/* Can the task run on the task's current CPU? If so, we're done */
++	if (!cpumask_test_cpu(task_cpu(p), &p->cpus_mask)) {
++		if (p->migration_disabled) {
++			if (likely(p->cpus_ptr != &p->cpus_mask))
++				__do_set_cpus_ptr(p, &p->cpus_mask);
++			p->migration_disabled = 0;
++			p->migration_flags |= MDF_FORCE_ENABLED;
++			/* When p is migrate_disabled, rq->lock should be held */
++			rq->nr_pinned--;
++		}
++
++		if (task_running(p) || READ_ONCE(p->__state) == TASK_WAKING) {
++			struct migration_arg arg = { p, dest_cpu };
++
++			/* Need help from migration thread: drop lock and wait. */
++			__task_access_unlock(p, lock);
++			raw_spin_unlock_irqrestore(&p->pi_lock, irq_flags);
++			stop_one_cpu(cpu_of(rq), migration_cpu_stop, &arg);
++			return 0;
++		}
++		if (task_on_rq_queued(p)) {
++			/*
++			 * OK, since we're going to drop the lock immediately
++			 * afterwards anyway.
++			 */
++			update_rq_clock(rq);
++			rq = move_queued_task(rq, p, dest_cpu);
++			lock = &rq->lock;
++		}
++	}
++	__task_access_unlock(p, lock);
++	raw_spin_unlock_irqrestore(&p->pi_lock, irq_flags);
++	return 0;
++}
++
++static int __set_cpus_allowed_ptr_locked(struct task_struct *p,
++					 const struct cpumask *new_mask,
++					 u32 flags,
++					 struct rq *rq,
++					 raw_spinlock_t *lock,
++					 unsigned long irq_flags)
++{
++	const struct cpumask *cpu_allowed_mask = task_cpu_possible_mask(p);
++	const struct cpumask *cpu_valid_mask = cpu_active_mask;
++	bool kthread = p->flags & PF_KTHREAD;
++	struct cpumask *user_mask = NULL;
++	int dest_cpu;
++	int ret = 0;
++
++	if (kthread || is_migration_disabled(p)) {
++		/*
++		 * Kernel threads are allowed on online && !active CPUs,
++		 * however, during cpu-hot-unplug, even these might get pushed
++		 * away if not KTHREAD_IS_PER_CPU.
++		 *
++		 * Specifically, migration_disabled() tasks must not fail the
++		 * cpumask_any_and_distribute() pick below, esp. so on
++		 * SCA_MIGRATE_ENABLE, otherwise we'll not call
++		 * set_cpus_allowed_common() and actually reset p->cpus_ptr.
++		 */
++		cpu_valid_mask = cpu_online_mask;
++	}
++
++	if (!kthread && !cpumask_subset(new_mask, cpu_allowed_mask)) {
++		ret = -EINVAL;
++		goto out;
++	}
++
++	/*
++	 * Must re-check here, to close a race against __kthread_bind(),
++	 * sched_setaffinity() is not guaranteed to observe the flag.
++	 */
++	if ((flags & SCA_CHECK) && (p->flags & PF_NO_SETAFFINITY)) {
++		ret = -EINVAL;
++		goto out;
++	}
++
++	if (cpumask_equal(&p->cpus_mask, new_mask))
++		goto out;
++
++	dest_cpu = cpumask_any_and(cpu_valid_mask, new_mask);
++	if (dest_cpu >= nr_cpu_ids) {
++		ret = -EINVAL;
++		goto out;
++	}
++
++	__do_set_cpus_allowed(p, new_mask);
++
++	if (flags & SCA_USER)
++		user_mask = clear_user_cpus_ptr(p);
++
++	ret = affine_move_task(rq, p, dest_cpu, lock, irq_flags);
++
++	kfree(user_mask);
++
++	return ret;
++
++out:
++	__task_access_unlock(p, lock);
++	raw_spin_unlock_irqrestore(&p->pi_lock, irq_flags);
++
++	return ret;
++}
++
++/*
++ * Change a given task's CPU affinity. Migrate the thread to a
++ * proper CPU and schedule it away if the CPU it's executing on
++ * is removed from the allowed bitmask.
++ *
++ * NOTE: the caller must have a valid reference to the task, the
++ * task must not exit() & deallocate itself prematurely. The
++ * call is not atomic; no spinlocks may be held.
++ */
++static int __set_cpus_allowed_ptr(struct task_struct *p,
++				  const struct cpumask *new_mask, u32 flags)
++{
++	unsigned long irq_flags;
++	struct rq *rq;
++	raw_spinlock_t *lock;
++
++	raw_spin_lock_irqsave(&p->pi_lock, irq_flags);
++	rq = __task_access_lock(p, &lock);
++
++	return __set_cpus_allowed_ptr_locked(p, new_mask, flags, rq, lock, irq_flags);
++}
++
++int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
++{
++	return __set_cpus_allowed_ptr(p, new_mask, 0);
++}
++EXPORT_SYMBOL_GPL(set_cpus_allowed_ptr);
++
++/*
++ * Change a given task's CPU affinity to the intersection of its current
++ * affinity mask and @subset_mask, writing the resulting mask to @new_mask
++ * and pointing @p->user_cpus_ptr to a copy of the old mask.
++ * If the resulting mask is empty, leave the affinity unchanged and return
++ * -EINVAL.
++ */
++static int restrict_cpus_allowed_ptr(struct task_struct *p,
++				     struct cpumask *new_mask,
++				     const struct cpumask *subset_mask)
++{
++	struct cpumask *user_mask = NULL;
++	unsigned long irq_flags;
++	raw_spinlock_t *lock;
++	struct rq *rq;
++	int err;
++
++	if (!p->user_cpus_ptr) {
++		user_mask = kmalloc(cpumask_size(), GFP_KERNEL);
++		if (!user_mask)
++			return -ENOMEM;
++	}
++
++	raw_spin_lock_irqsave(&p->pi_lock, irq_flags);
++	rq = __task_access_lock(p, &lock);
++
++	if (!cpumask_and(new_mask, &p->cpus_mask, subset_mask)) {
++		err = -EINVAL;
++		goto err_unlock;
++	}
++
++	/*
++	 * We're about to butcher the task affinity, so keep track of what
++	 * the user asked for in case we're able to restore it later on.
++	 */
++	if (user_mask) {
++		cpumask_copy(user_mask, p->cpus_ptr);
++		p->user_cpus_ptr = user_mask;
++	}
++
++	/*return __set_cpus_allowed_ptr_locked(p, new_mask, 0, rq, &rf);*/
++	return __set_cpus_allowed_ptr_locked(p, new_mask, 0, rq, lock, irq_flags);
++
++err_unlock:
++	__task_access_unlock(p, lock);
++	raw_spin_unlock_irqrestore(&p->pi_lock, irq_flags);
++	kfree(user_mask);
++	return err;
++}
++
++/*
++ * Restrict the CPU affinity of task @p so that it is a subset of
++ * task_cpu_possible_mask() and point @p->user_cpu_ptr to a copy of the
++ * old affinity mask. If the resulting mask is empty, we warn and walk
++ * up the cpuset hierarchy until we find a suitable mask.
++ */
++void force_compatible_cpus_allowed_ptr(struct task_struct *p)
++{
++	cpumask_var_t new_mask;
++	const struct cpumask *override_mask = task_cpu_possible_mask(p);
++
++	alloc_cpumask_var(&new_mask, GFP_KERNEL);
++
++	/*
++	 * __migrate_task() can fail silently in the face of concurrent
++	 * offlining of the chosen destination CPU, so take the hotplug
++	 * lock to ensure that the migration succeeds.
++	 */
++	cpus_read_lock();
++	if (!cpumask_available(new_mask))
++		goto out_set_mask;
++
++	if (!restrict_cpus_allowed_ptr(p, new_mask, override_mask))
++		goto out_free_mask;
++
++	/*
++	 * We failed to find a valid subset of the affinity mask for the
++	 * task, so override it based on its cpuset hierarchy.
++	 */
++	cpuset_cpus_allowed(p, new_mask);
++	override_mask = new_mask;
++
++out_set_mask:
++	if (printk_ratelimit()) {
++		printk_deferred("Overriding affinity for process %d (%s) to CPUs %*pbl\n",
++				task_pid_nr(p), p->comm,
++				cpumask_pr_args(override_mask));
++	}
++
++	WARN_ON(set_cpus_allowed_ptr(p, override_mask));
++out_free_mask:
++	cpus_read_unlock();
++	free_cpumask_var(new_mask);
++}
++
++static int
++__sched_setaffinity(struct task_struct *p, const struct cpumask *mask);
++
++/*
++ * Restore the affinity of a task @p which was previously restricted by a
++ * call to force_compatible_cpus_allowed_ptr(). This will clear (and free)
++ * @p->user_cpus_ptr.
++ *
++ * It is the caller's responsibility to serialise this with any calls to
++ * force_compatible_cpus_allowed_ptr(@p).
++ */
++void relax_compatible_cpus_allowed_ptr(struct task_struct *p)
++{
++	struct cpumask *user_mask = p->user_cpus_ptr;
++	unsigned long flags;
++
++	/*
++	 * Try to restore the old affinity mask. If this fails, then
++	 * we free the mask explicitly to avoid it being inherited across
++	 * a subsequent fork().
++	 */
++	if (!user_mask || !__sched_setaffinity(p, user_mask))
++		return;
++
++	raw_spin_lock_irqsave(&p->pi_lock, flags);
++	user_mask = clear_user_cpus_ptr(p);
++	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++
++	kfree(user_mask);
++}
++
++#else /* CONFIG_SMP */
++
++static inline int select_task_rq(struct task_struct *p)
++{
++	return 0;
++}
++
++static inline int
++__set_cpus_allowed_ptr(struct task_struct *p,
++		       const struct cpumask *new_mask, u32 flags)
++{
++	return set_cpus_allowed_ptr(p, new_mask);
++}
++
++static inline bool rq_has_pinned_tasks(struct rq *rq)
++{
++	return false;
++}
++
++#endif /* !CONFIG_SMP */
++
++static void
++ttwu_stat(struct task_struct *p, int cpu, int wake_flags)
++{
++	struct rq *rq;
++
++	if (!schedstat_enabled())
++		return;
++
++	rq = this_rq();
++
++#ifdef CONFIG_SMP
++	if (cpu == rq->cpu) {
++		__schedstat_inc(rq->ttwu_local);
++		__schedstat_inc(p->stats.nr_wakeups_local);
++	} else {
++		/** Alt schedule FW ToDo:
++		 * How to do ttwu_wake_remote
++		 */
++	}
++#endif /* CONFIG_SMP */
++
++	__schedstat_inc(rq->ttwu_count);
++	__schedstat_inc(p->stats.nr_wakeups);
++}
++
++/*
++ * Mark the task runnable and perform wakeup-preemption.
++ */
++static inline void
++ttwu_do_wakeup(struct rq *rq, struct task_struct *p, int wake_flags)
++{
++	check_preempt_curr(rq);
++	WRITE_ONCE(p->__state, TASK_RUNNING);
++	trace_sched_wakeup(p);
++}
++
++static inline void
++ttwu_do_activate(struct rq *rq, struct task_struct *p, int wake_flags)
++{
++	if (p->sched_contributes_to_load)
++		rq->nr_uninterruptible--;
++
++	if (
++#ifdef CONFIG_SMP
++	    !(wake_flags & WF_MIGRATED) &&
++#endif
++	    p->in_iowait) {
++		delayacct_blkio_end(p);
++		atomic_dec(&task_rq(p)->nr_iowait);
++	}
++
++	activate_task(p, rq);
++	ttwu_do_wakeup(rq, p, 0);
++}
++
++/*
++ * Consider @p being inside a wait loop:
++ *
++ *   for (;;) {
++ *      set_current_state(TASK_UNINTERRUPTIBLE);
++ *
++ *      if (CONDITION)
++ *         break;
++ *
++ *      schedule();
++ *   }
++ *   __set_current_state(TASK_RUNNING);
++ *
++ * between set_current_state() and schedule(). In this case @p is still
++ * runnable, so all that needs doing is change p->state back to TASK_RUNNING in
++ * an atomic manner.
++ *
++ * By taking task_rq(p)->lock we serialize against schedule(), if @p->on_rq
++ * then schedule() must still happen and p->state can be changed to
++ * TASK_RUNNING. Otherwise we lost the race, schedule() has happened, and we
++ * need to do a full wakeup with enqueue.
++ *
++ * Returns: %true when the wakeup is done,
++ *          %false otherwise.
++ */
++static int ttwu_runnable(struct task_struct *p, int wake_flags)
++{
++	struct rq *rq;
++	raw_spinlock_t *lock;
++	int ret = 0;
++
++	rq = __task_access_lock(p, &lock);
++	if (task_on_rq_queued(p)) {
++		/* check_preempt_curr() may use rq clock */
++		update_rq_clock(rq);
++		ttwu_do_wakeup(rq, p, wake_flags);
++		ret = 1;
++	}
++	__task_access_unlock(p, lock);
++
++	return ret;
++}
++
++#ifdef CONFIG_SMP
++void sched_ttwu_pending(void *arg)
++{
++	struct llist_node *llist = arg;
++	struct rq *rq = this_rq();
++	struct task_struct *p, *t;
++	struct rq_flags rf;
++
++	if (!llist)
++		return;
++
++	/*
++	 * rq::ttwu_pending racy indication of out-standing wakeups.
++	 * Races such that false-negatives are possible, since they
++	 * are shorter lived that false-positives would be.
++	 */
++	WRITE_ONCE(rq->ttwu_pending, 0);
++
++	rq_lock_irqsave(rq, &rf);
++	update_rq_clock(rq);
++
++	llist_for_each_entry_safe(p, t, llist, wake_entry.llist) {
++		if (WARN_ON_ONCE(p->on_cpu))
++			smp_cond_load_acquire(&p->on_cpu, !VAL);
++
++		if (WARN_ON_ONCE(task_cpu(p) != cpu_of(rq)))
++			set_task_cpu(p, cpu_of(rq));
++
++		ttwu_do_activate(rq, p, p->sched_remote_wakeup ? WF_MIGRATED : 0);
++	}
++
++	rq_unlock_irqrestore(rq, &rf);
++}
++
++void send_call_function_single_ipi(int cpu)
++{
++	struct rq *rq = cpu_rq(cpu);
++
++	if (!set_nr_if_polling(rq->idle))
++		arch_send_call_function_single_ipi(cpu);
++	else
++		trace_sched_wake_idle_without_ipi(cpu);
++}
++
++/*
++ * Queue a task on the target CPUs wake_list and wake the CPU via IPI if
++ * necessary. The wakee CPU on receipt of the IPI will queue the task
++ * via sched_ttwu_wakeup() for activation so the wakee incurs the cost
++ * of the wakeup instead of the waker.
++ */
++static void __ttwu_queue_wakelist(struct task_struct *p, int cpu, int wake_flags)
++{
++	struct rq *rq = cpu_rq(cpu);
++
++	p->sched_remote_wakeup = !!(wake_flags & WF_MIGRATED);
++
++	WRITE_ONCE(rq->ttwu_pending, 1);
++	__smp_call_single_queue(cpu, &p->wake_entry.llist);
++}
++
++static inline bool ttwu_queue_cond(struct task_struct *p, int cpu)
++{
++	/*
++	 * Do not complicate things with the async wake_list while the CPU is
++	 * in hotplug state.
++	 */
++	if (!cpu_active(cpu))
++		return false;
++
++	/* Ensure the task will still be allowed to run on the CPU. */
++	if (!cpumask_test_cpu(cpu, p->cpus_ptr))
++		return false;
++
++	/*
++	 * If the CPU does not share cache, then queue the task on the
++	 * remote rqs wakelist to avoid accessing remote data.
++	 */
++	if (!cpus_share_cache(smp_processor_id(), cpu))
++		return true;
++
++	if (cpu == smp_processor_id())
++		return false;
++
++	/*
++	 * If the wakee cpu is idle, or the task is descheduling and the
++	 * only running task on the CPU, then use the wakelist to offload
++	 * the task activation to the idle (or soon-to-be-idle) CPU as
++	 * the current CPU is likely busy. nr_running is checked to
++	 * avoid unnecessary task stacking.
++	 *
++	 * Note that we can only get here with (wakee) p->on_rq=0,
++	 * p->on_cpu can be whatever, we've done the dequeue, so
++	 * the wakee has been accounted out of ->nr_running.
++	 */
++	if (!cpu_rq(cpu)->nr_running)
++		return true;
++
++	return false;
++}
++
++static bool ttwu_queue_wakelist(struct task_struct *p, int cpu, int wake_flags)
++{
++	if (__is_defined(ALT_SCHED_TTWU_QUEUE) && ttwu_queue_cond(p, cpu)) {
++		sched_clock_cpu(cpu); /* Sync clocks across CPUs */
++		__ttwu_queue_wakelist(p, cpu, wake_flags);
++		return true;
++	}
++
++	return false;
++}
++
++void wake_up_if_idle(int cpu)
++{
++	struct rq *rq = cpu_rq(cpu);
++	unsigned long flags;
++
++	rcu_read_lock();
++
++	if (!is_idle_task(rcu_dereference(rq->curr)))
++		goto out;
++
++	raw_spin_lock_irqsave(&rq->lock, flags);
++	if (is_idle_task(rq->curr))
++		resched_curr(rq);
++	/* Else CPU is not idle, do nothing here */
++	raw_spin_unlock_irqrestore(&rq->lock, flags);
++
++out:
++	rcu_read_unlock();
++}
++
++bool cpus_share_cache(int this_cpu, int that_cpu)
++{
++	if (this_cpu == that_cpu)
++		return true;
++
++	return per_cpu(sd_llc_id, this_cpu) == per_cpu(sd_llc_id, that_cpu);
++}
++#else /* !CONFIG_SMP */
++
++static inline bool ttwu_queue_wakelist(struct task_struct *p, int cpu, int wake_flags)
++{
++	return false;
++}
++
++#endif /* CONFIG_SMP */
++
++static inline void ttwu_queue(struct task_struct *p, int cpu, int wake_flags)
++{
++	struct rq *rq = cpu_rq(cpu);
++
++	if (ttwu_queue_wakelist(p, cpu, wake_flags))
++		return;
++
++	raw_spin_lock(&rq->lock);
++	update_rq_clock(rq);
++	ttwu_do_activate(rq, p, wake_flags);
++	raw_spin_unlock(&rq->lock);
++}
++
++/*
++ * Invoked from try_to_wake_up() to check whether the task can be woken up.
++ *
++ * The caller holds p::pi_lock if p != current or has preemption
++ * disabled when p == current.
++ *
++ * The rules of PREEMPT_RT saved_state:
++ *
++ *   The related locking code always holds p::pi_lock when updating
++ *   p::saved_state, which means the code is fully serialized in both cases.
++ *
++ *   The lock wait and lock wakeups happen via TASK_RTLOCK_WAIT. No other
++ *   bits set. This allows to distinguish all wakeup scenarios.
++ */
++static __always_inline
++bool ttwu_state_match(struct task_struct *p, unsigned int state, int *success)
++{
++	if (IS_ENABLED(CONFIG_DEBUG_PREEMPT)) {
++		WARN_ON_ONCE((state & TASK_RTLOCK_WAIT) &&
++			     state != TASK_RTLOCK_WAIT);
++	}
++
++	if (READ_ONCE(p->__state) & state) {
++		*success = 1;
++		return true;
++	}
++
++#ifdef CONFIG_PREEMPT_RT
++	/*
++	 * Saved state preserves the task state across blocking on
++	 * an RT lock.  If the state matches, set p::saved_state to
++	 * TASK_RUNNING, but do not wake the task because it waits
++	 * for a lock wakeup. Also indicate success because from
++	 * the regular waker's point of view this has succeeded.
++	 *
++	 * After acquiring the lock the task will restore p::__state
++	 * from p::saved_state which ensures that the regular
++	 * wakeup is not lost. The restore will also set
++	 * p::saved_state to TASK_RUNNING so any further tests will
++	 * not result in false positives vs. @success
++	 */
++	if (p->saved_state & state) {
++		p->saved_state = TASK_RUNNING;
++		*success = 1;
++	}
++#endif
++	return false;
++}
++
++/*
++ * Notes on Program-Order guarantees on SMP systems.
++ *
++ *  MIGRATION
++ *
++ * The basic program-order guarantee on SMP systems is that when a task [t]
++ * migrates, all its activity on its old CPU [c0] happens-before any subsequent
++ * execution on its new CPU [c1].
++ *
++ * For migration (of runnable tasks) this is provided by the following means:
++ *
++ *  A) UNLOCK of the rq(c0)->lock scheduling out task t
++ *  B) migration for t is required to synchronize *both* rq(c0)->lock and
++ *     rq(c1)->lock (if not at the same time, then in that order).
++ *  C) LOCK of the rq(c1)->lock scheduling in task
++ *
++ * Transitivity guarantees that B happens after A and C after B.
++ * Note: we only require RCpc transitivity.
++ * Note: the CPU doing B need not be c0 or c1
++ *
++ * Example:
++ *
++ *   CPU0            CPU1            CPU2
++ *
++ *   LOCK rq(0)->lock
++ *   sched-out X
++ *   sched-in Y
++ *   UNLOCK rq(0)->lock
++ *
++ *                                   LOCK rq(0)->lock // orders against CPU0
++ *                                   dequeue X
++ *                                   UNLOCK rq(0)->lock
++ *
++ *                                   LOCK rq(1)->lock
++ *                                   enqueue X
++ *                                   UNLOCK rq(1)->lock
++ *
++ *                   LOCK rq(1)->lock // orders against CPU2
++ *                   sched-out Z
++ *                   sched-in X
++ *                   UNLOCK rq(1)->lock
++ *
++ *
++ *  BLOCKING -- aka. SLEEP + WAKEUP
++ *
++ * For blocking we (obviously) need to provide the same guarantee as for
++ * migration. However the means are completely different as there is no lock
++ * chain to provide order. Instead we do:
++ *
++ *   1) smp_store_release(X->on_cpu, 0)   -- finish_task()
++ *   2) smp_cond_load_acquire(!X->on_cpu) -- try_to_wake_up()
++ *
++ * Example:
++ *
++ *   CPU0 (schedule)  CPU1 (try_to_wake_up) CPU2 (schedule)
++ *
++ *   LOCK rq(0)->lock LOCK X->pi_lock
++ *   dequeue X
++ *   sched-out X
++ *   smp_store_release(X->on_cpu, 0);
++ *
++ *                    smp_cond_load_acquire(&X->on_cpu, !VAL);
++ *                    X->state = WAKING
++ *                    set_task_cpu(X,2)
++ *
++ *                    LOCK rq(2)->lock
++ *                    enqueue X
++ *                    X->state = RUNNING
++ *                    UNLOCK rq(2)->lock
++ *
++ *                                          LOCK rq(2)->lock // orders against CPU1
++ *                                          sched-out Z
++ *                                          sched-in X
++ *                                          UNLOCK rq(2)->lock
++ *
++ *                    UNLOCK X->pi_lock
++ *   UNLOCK rq(0)->lock
++ *
++ *
++ * However; for wakeups there is a second guarantee we must provide, namely we
++ * must observe the state that lead to our wakeup. That is, not only must our
++ * task observe its own prior state, it must also observe the stores prior to
++ * its wakeup.
++ *
++ * This means that any means of doing remote wakeups must order the CPU doing
++ * the wakeup against the CPU the task is going to end up running on. This,
++ * however, is already required for the regular Program-Order guarantee above,
++ * since the waking CPU is the one issueing the ACQUIRE (smp_cond_load_acquire).
++ *
++ */
++
++/**
++ * try_to_wake_up - wake up a thread
++ * @p: the thread to be awakened
++ * @state: the mask of task states that can be woken
++ * @wake_flags: wake modifier flags (WF_*)
++ *
++ * Conceptually does:
++ *
++ *   If (@state & @p->state) @p->state = TASK_RUNNING.
++ *
++ * If the task was not queued/runnable, also place it back on a runqueue.
++ *
++ * This function is atomic against schedule() which would dequeue the task.
++ *
++ * It issues a full memory barrier before accessing @p->state, see the comment
++ * with set_current_state().
++ *
++ * Uses p->pi_lock to serialize against concurrent wake-ups.
++ *
++ * Relies on p->pi_lock stabilizing:
++ *  - p->sched_class
++ *  - p->cpus_ptr
++ *  - p->sched_task_group
++ * in order to do migration, see its use of select_task_rq()/set_task_cpu().
++ *
++ * Tries really hard to only take one task_rq(p)->lock for performance.
++ * Takes rq->lock in:
++ *  - ttwu_runnable()    -- old rq, unavoidable, see comment there;
++ *  - ttwu_queue()       -- new rq, for enqueue of the task;
++ *  - psi_ttwu_dequeue() -- much sadness :-( accounting will kill us.
++ *
++ * As a consequence we race really badly with just about everything. See the
++ * many memory barriers and their comments for details.
++ *
++ * Return: %true if @p->state changes (an actual wakeup was done),
++ *	   %false otherwise.
++ */
++static int try_to_wake_up(struct task_struct *p, unsigned int state,
++			  int wake_flags)
++{
++	unsigned long flags;
++	int cpu, success = 0;
++
++	preempt_disable();
++	if (p == current) {
++		/*
++		 * We're waking current, this means 'p->on_rq' and 'task_cpu(p)
++		 * == smp_processor_id()'. Together this means we can special
++		 * case the whole 'p->on_rq && ttwu_runnable()' case below
++		 * without taking any locks.
++		 *
++		 * In particular:
++		 *  - we rely on Program-Order guarantees for all the ordering,
++		 *  - we're serialized against set_special_state() by virtue of
++		 *    it disabling IRQs (this allows not taking ->pi_lock).
++		 */
++		if (!ttwu_state_match(p, state, &success))
++			goto out;
++
++		trace_sched_waking(p);
++		WRITE_ONCE(p->__state, TASK_RUNNING);
++		trace_sched_wakeup(p);
++		goto out;
++	}
++
++	/*
++	 * If we are going to wake up a thread waiting for CONDITION we
++	 * need to ensure that CONDITION=1 done by the caller can not be
++	 * reordered with p->state check below. This pairs with smp_store_mb()
++	 * in set_current_state() that the waiting thread does.
++	 */
++	raw_spin_lock_irqsave(&p->pi_lock, flags);
++	smp_mb__after_spinlock();
++	if (!ttwu_state_match(p, state, &success))
++		goto unlock;
++
++	trace_sched_waking(p);
++
++	/*
++	 * Ensure we load p->on_rq _after_ p->state, otherwise it would
++	 * be possible to, falsely, observe p->on_rq == 0 and get stuck
++	 * in smp_cond_load_acquire() below.
++	 *
++	 * sched_ttwu_pending()			try_to_wake_up()
++	 *   STORE p->on_rq = 1			  LOAD p->state
++	 *   UNLOCK rq->lock
++	 *
++	 * __schedule() (switch to task 'p')
++	 *   LOCK rq->lock			  smp_rmb();
++	 *   smp_mb__after_spinlock();
++	 *   UNLOCK rq->lock
++	 *
++	 * [task p]
++	 *   STORE p->state = UNINTERRUPTIBLE	  LOAD p->on_rq
++	 *
++	 * Pairs with the LOCK+smp_mb__after_spinlock() on rq->lock in
++	 * __schedule().  See the comment for smp_mb__after_spinlock().
++	 *
++	 * A similar smb_rmb() lives in try_invoke_on_locked_down_task().
++	 */
++	smp_rmb();
++	if (READ_ONCE(p->on_rq) && ttwu_runnable(p, wake_flags))
++		goto unlock;
++
++#ifdef CONFIG_SMP
++	/*
++	 * Ensure we load p->on_cpu _after_ p->on_rq, otherwise it would be
++	 * possible to, falsely, observe p->on_cpu == 0.
++	 *
++	 * One must be running (->on_cpu == 1) in order to remove oneself
++	 * from the runqueue.
++	 *
++	 * __schedule() (switch to task 'p')	try_to_wake_up()
++	 *   STORE p->on_cpu = 1		  LOAD p->on_rq
++	 *   UNLOCK rq->lock
++	 *
++	 * __schedule() (put 'p' to sleep)
++	 *   LOCK rq->lock			  smp_rmb();
++	 *   smp_mb__after_spinlock();
++	 *   STORE p->on_rq = 0			  LOAD p->on_cpu
++	 *
++	 * Pairs with the LOCK+smp_mb__after_spinlock() on rq->lock in
++	 * __schedule().  See the comment for smp_mb__after_spinlock().
++	 *
++	 * Form a control-dep-acquire with p->on_rq == 0 above, to ensure
++	 * schedule()'s deactivate_task() has 'happened' and p will no longer
++	 * care about it's own p->state. See the comment in __schedule().
++	 */
++	smp_acquire__after_ctrl_dep();
++
++	/*
++	 * We're doing the wakeup (@success == 1), they did a dequeue (p->on_rq
++	 * == 0), which means we need to do an enqueue, change p->state to
++	 * TASK_WAKING such that we can unlock p->pi_lock before doing the
++	 * enqueue, such as ttwu_queue_wakelist().
++	 */
++	WRITE_ONCE(p->__state, TASK_WAKING);
++
++	/*
++	 * If the owning (remote) CPU is still in the middle of schedule() with
++	 * this task as prev, considering queueing p on the remote CPUs wake_list
++	 * which potentially sends an IPI instead of spinning on p->on_cpu to
++	 * let the waker make forward progress. This is safe because IRQs are
++	 * disabled and the IPI will deliver after on_cpu is cleared.
++	 *
++	 * Ensure we load task_cpu(p) after p->on_cpu:
++	 *
++	 * set_task_cpu(p, cpu);
++	 *   STORE p->cpu = @cpu
++	 * __schedule() (switch to task 'p')
++	 *   LOCK rq->lock
++	 *   smp_mb__after_spin_lock()          smp_cond_load_acquire(&p->on_cpu)
++	 *   STORE p->on_cpu = 1                LOAD p->cpu
++	 *
++	 * to ensure we observe the correct CPU on which the task is currently
++	 * scheduling.
++	 */
++	if (smp_load_acquire(&p->on_cpu) &&
++	    ttwu_queue_wakelist(p, task_cpu(p), wake_flags))
++		goto unlock;
++
++	/*
++	 * If the owning (remote) CPU is still in the middle of schedule() with
++	 * this task as prev, wait until it's done referencing the task.
++	 *
++	 * Pairs with the smp_store_release() in finish_task().
++	 *
++	 * This ensures that tasks getting woken will be fully ordered against
++	 * their previous state and preserve Program Order.
++	 */
++	smp_cond_load_acquire(&p->on_cpu, !VAL);
++
++	sched_task_ttwu(p);
++
++	cpu = select_task_rq(p);
++
++	if (cpu != task_cpu(p)) {
++		if (p->in_iowait) {
++			delayacct_blkio_end(p);
++			atomic_dec(&task_rq(p)->nr_iowait);
++		}
++
++		wake_flags |= WF_MIGRATED;
++		psi_ttwu_dequeue(p);
++		set_task_cpu(p, cpu);
++	}
++#else
++	cpu = task_cpu(p);
++#endif /* CONFIG_SMP */
++
++	ttwu_queue(p, cpu, wake_flags);
++unlock:
++	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++out:
++	if (success)
++		ttwu_stat(p, task_cpu(p), wake_flags);
++	preempt_enable();
++
++	return success;
++}
++
++/**
++ * task_call_func - Invoke a function on task in fixed state
++ * @p: Process for which the function is to be invoked, can be @current.
++ * @func: Function to invoke.
++ * @arg: Argument to function.
++ *
++ * Fix the task in it's current state by avoiding wakeups and or rq operations
++ * and call @func(@arg) on it.  This function can use ->on_rq and task_curr()
++ * to work out what the state is, if required.  Given that @func can be invoked
++ * with a runqueue lock held, it had better be quite lightweight.
++ *
++ * Returns:
++ *   Whatever @func returns
++ */
++int task_call_func(struct task_struct *p, task_call_f func, void *arg)
++{
++	struct rq *rq = NULL;
++	unsigned int state;
++	struct rq_flags rf;
++	int ret;
++
++	raw_spin_lock_irqsave(&p->pi_lock, rf.flags);
++
++	state = READ_ONCE(p->__state);
++
++	/*
++	 * Ensure we load p->on_rq after p->__state, otherwise it would be
++	 * possible to, falsely, observe p->on_rq == 0.
++	 *
++	 * See try_to_wake_up() for a longer comment.
++	 */
++	smp_rmb();
++
++	/*
++	 * Since pi->lock blocks try_to_wake_up(), we don't need rq->lock when
++	 * the task is blocked. Make sure to check @state since ttwu() can drop
++	 * locks at the end, see ttwu_queue_wakelist().
++	 */
++	if (state == TASK_RUNNING || state == TASK_WAKING || p->on_rq)
++		rq = __task_rq_lock(p, &rf);
++
++	/*
++	 * At this point the task is pinned; either:
++	 *  - blocked and we're holding off wakeups      (pi->lock)
++	 *  - woken, and we're holding off enqueue       (rq->lock)
++	 *  - queued, and we're holding off schedule     (rq->lock)
++	 *  - running, and we're holding off de-schedule (rq->lock)
++	 *
++	 * The called function (@func) can use: task_curr(), p->on_rq and
++	 * p->__state to differentiate between these states.
++	 */
++	ret = func(p, arg);
++
++	if (rq)
++		__task_rq_unlock(rq, &rf);
++
++	raw_spin_unlock_irqrestore(&p->pi_lock, rf.flags);
++	return ret;
++}
++
++/**
++ * cpu_curr_snapshot - Return a snapshot of the currently running task
++ * @cpu: The CPU on which to snapshot the task.
++ *
++ * Returns the task_struct pointer of the task "currently" running on
++ * the specified CPU.  If the same task is running on that CPU throughout,
++ * the return value will be a pointer to that task's task_struct structure.
++ * If the CPU did any context switches even vaguely concurrently with the
++ * execution of this function, the return value will be a pointer to the
++ * task_struct structure of a randomly chosen task that was running on
++ * that CPU somewhere around the time that this function was executing.
++ *
++ * If the specified CPU was offline, the return value is whatever it
++ * is, perhaps a pointer to the task_struct structure of that CPU's idle
++ * task, but there is no guarantee.  Callers wishing a useful return
++ * value must take some action to ensure that the specified CPU remains
++ * online throughout.
++ *
++ * This function executes full memory barriers before and after fetching
++ * the pointer, which permits the caller to confine this function's fetch
++ * with respect to the caller's accesses to other shared variables.
++ */
++struct task_struct *cpu_curr_snapshot(int cpu)
++{
++	struct task_struct *t;
++
++	smp_mb(); /* Pairing determined by caller's synchronization design. */
++	t = rcu_dereference(cpu_curr(cpu));
++	smp_mb(); /* Pairing determined by caller's synchronization design. */
++	return t;
++}
++
++/**
++ * wake_up_process - Wake up a specific process
++ * @p: The process to be woken up.
++ *
++ * Attempt to wake up the nominated process and move it to the set of runnable
++ * processes.
++ *
++ * Return: 1 if the process was woken up, 0 if it was already running.
++ *
++ * This function executes a full memory barrier before accessing the task state.
++ */
++int wake_up_process(struct task_struct *p)
++{
++	return try_to_wake_up(p, TASK_NORMAL, 0);
++}
++EXPORT_SYMBOL(wake_up_process);
++
++int wake_up_state(struct task_struct *p, unsigned int state)
++{
++	return try_to_wake_up(p, state, 0);
++}
++
++/*
++ * Perform scheduler related setup for a newly forked process p.
++ * p is forked by current.
++ *
++ * __sched_fork() is basic setup used by init_idle() too:
++ */
++static inline void __sched_fork(unsigned long clone_flags, struct task_struct *p)
++{
++	p->on_rq			= 0;
++	p->on_cpu			= 0;
++	p->utime			= 0;
++	p->stime			= 0;
++	p->sched_time			= 0;
++
++#ifdef CONFIG_SCHEDSTATS
++	/* Even if schedstat is disabled, there should not be garbage */
++	memset(&p->stats, 0, sizeof(p->stats));
++#endif
++
++#ifdef CONFIG_PREEMPT_NOTIFIERS
++	INIT_HLIST_HEAD(&p->preempt_notifiers);
++#endif
++
++#ifdef CONFIG_COMPACTION
++	p->capture_control = NULL;
++#endif
++#ifdef CONFIG_SMP
++	p->wake_entry.u_flags = CSD_TYPE_TTWU;
++#endif
++}
++
++/*
++ * fork()/clone()-time setup:
++ */
++int sched_fork(unsigned long clone_flags, struct task_struct *p)
++{
++	__sched_fork(clone_flags, p);
++	/*
++	 * We mark the process as NEW here. This guarantees that
++	 * nobody will actually run it, and a signal or other external
++	 * event cannot wake it up and insert it on the runqueue either.
++	 */
++	p->__state = TASK_NEW;
++
++	/*
++	 * Make sure we do not leak PI boosting priority to the child.
++	 */
++	p->prio = current->normal_prio;
++
++	/*
++	 * Revert to default priority/policy on fork if requested.
++	 */
++	if (unlikely(p->sched_reset_on_fork)) {
++		if (task_has_rt_policy(p)) {
++			p->policy = SCHED_NORMAL;
++			p->static_prio = NICE_TO_PRIO(0);
++			p->rt_priority = 0;
++		} else if (PRIO_TO_NICE(p->static_prio) < 0)
++			p->static_prio = NICE_TO_PRIO(0);
++
++		p->prio = p->normal_prio = p->static_prio;
++
++		/*
++		 * We don't need the reset flag anymore after the fork. It has
++		 * fulfilled its duty:
++		 */
++		p->sched_reset_on_fork = 0;
++	}
++
++#ifdef CONFIG_SCHED_INFO
++	if (unlikely(sched_info_on()))
++		memset(&p->sched_info, 0, sizeof(p->sched_info));
++#endif
++	init_task_preempt_count(p);
++
++	return 0;
++}
++
++void sched_cgroup_fork(struct task_struct *p, struct kernel_clone_args *kargs)
++{
++	unsigned long flags;
++	struct rq *rq;
++
++	/*
++	 * Because we're not yet on the pid-hash, p->pi_lock isn't strictly
++	 * required yet, but lockdep gets upset if rules are violated.
++	 */
++	raw_spin_lock_irqsave(&p->pi_lock, flags);
++	/*
++	 * Share the timeslice between parent and child, thus the
++	 * total amount of pending timeslices in the system doesn't change,
++	 * resulting in more scheduling fairness.
++	 */
++	rq = this_rq();
++	raw_spin_lock(&rq->lock);
++
++	rq->curr->time_slice /= 2;
++	p->time_slice = rq->curr->time_slice;
++#ifdef CONFIG_SCHED_HRTICK
++	hrtick_start(rq, rq->curr->time_slice);
++#endif
++
++	if (p->time_slice < RESCHED_NS) {
++		p->time_slice = sched_timeslice_ns;
++		resched_curr(rq);
++	}
++	sched_task_fork(p, rq);
++	raw_spin_unlock(&rq->lock);
++
++	rseq_migrate(p);
++	/*
++	 * We're setting the CPU for the first time, we don't migrate,
++	 * so use __set_task_cpu().
++	 */
++	__set_task_cpu(p, smp_processor_id());
++	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++}
++
++void sched_post_fork(struct task_struct *p)
++{
++}
++
++#ifdef CONFIG_SCHEDSTATS
++
++DEFINE_STATIC_KEY_FALSE(sched_schedstats);
++
++static void set_schedstats(bool enabled)
++{
++	if (enabled)
++		static_branch_enable(&sched_schedstats);
++	else
++		static_branch_disable(&sched_schedstats);
++}
++
++void force_schedstat_enabled(void)
++{
++	if (!schedstat_enabled()) {
++		pr_info("kernel profiling enabled schedstats, disable via kernel.sched_schedstats.\n");
++		static_branch_enable(&sched_schedstats);
++	}
++}
++
++static int __init setup_schedstats(char *str)
++{
++	int ret = 0;
++	if (!str)
++		goto out;
++
++	if (!strcmp(str, "enable")) {
++		set_schedstats(true);
++		ret = 1;
++	} else if (!strcmp(str, "disable")) {
++		set_schedstats(false);
++		ret = 1;
++	}
++out:
++	if (!ret)
++		pr_warn("Unable to parse schedstats=\n");
++
++	return ret;
++}
++__setup("schedstats=", setup_schedstats);
++
++#ifdef CONFIG_PROC_SYSCTL
++static int sysctl_schedstats(struct ctl_table *table, int write, void *buffer,
++		size_t *lenp, loff_t *ppos)
++{
++	struct ctl_table t;
++	int err;
++	int state = static_branch_likely(&sched_schedstats);
++
++	if (write && !capable(CAP_SYS_ADMIN))
++		return -EPERM;
++
++	t = *table;
++	t.data = &state;
++	err = proc_dointvec_minmax(&t, write, buffer, lenp, ppos);
++	if (err < 0)
++		return err;
++	if (write)
++		set_schedstats(state);
++	return err;
++}
++
++static struct ctl_table sched_core_sysctls[] = {
++	{
++		.procname       = "sched_schedstats",
++		.data           = NULL,
++		.maxlen         = sizeof(unsigned int),
++		.mode           = 0644,
++		.proc_handler   = sysctl_schedstats,
++		.extra1         = SYSCTL_ZERO,
++		.extra2         = SYSCTL_ONE,
++	},
++	{}
++};
++static int __init sched_core_sysctl_init(void)
++{
++	register_sysctl_init("kernel", sched_core_sysctls);
++	return 0;
++}
++late_initcall(sched_core_sysctl_init);
++#endif /* CONFIG_PROC_SYSCTL */
++#endif /* CONFIG_SCHEDSTATS */
++
++/*
++ * wake_up_new_task - wake up a newly created task for the first time.
++ *
++ * This function will do some initial scheduler statistics housekeeping
++ * that must be done for every newly created context, then puts the task
++ * on the runqueue and wakes it.
++ */
++void wake_up_new_task(struct task_struct *p)
++{
++	unsigned long flags;
++	struct rq *rq;
++
++	raw_spin_lock_irqsave(&p->pi_lock, flags);
++	WRITE_ONCE(p->__state, TASK_RUNNING);
++	rq = cpu_rq(select_task_rq(p));
++#ifdef CONFIG_SMP
++	rseq_migrate(p);
++	/*
++	 * Fork balancing, do it here and not earlier because:
++	 * - cpus_ptr can change in the fork path
++	 * - any previously selected CPU might disappear through hotplug
++	 *
++	 * Use __set_task_cpu() to avoid calling sched_class::migrate_task_rq,
++	 * as we're not fully set-up yet.
++	 */
++	__set_task_cpu(p, cpu_of(rq));
++#endif
++
++	raw_spin_lock(&rq->lock);
++	update_rq_clock(rq);
++
++	activate_task(p, rq);
++	trace_sched_wakeup_new(p);
++	check_preempt_curr(rq);
++
++	raw_spin_unlock(&rq->lock);
++	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++}
++
++#ifdef CONFIG_PREEMPT_NOTIFIERS
++
++static DEFINE_STATIC_KEY_FALSE(preempt_notifier_key);
++
++void preempt_notifier_inc(void)
++{
++	static_branch_inc(&preempt_notifier_key);
++}
++EXPORT_SYMBOL_GPL(preempt_notifier_inc);
++
++void preempt_notifier_dec(void)
++{
++	static_branch_dec(&preempt_notifier_key);
++}
++EXPORT_SYMBOL_GPL(preempt_notifier_dec);
++
++/**
++ * preempt_notifier_register - tell me when current is being preempted & rescheduled
++ * @notifier: notifier struct to register
++ */
++void preempt_notifier_register(struct preempt_notifier *notifier)
++{
++	if (!static_branch_unlikely(&preempt_notifier_key))
++		WARN(1, "registering preempt_notifier while notifiers disabled\n");
++
++	hlist_add_head(&notifier->link, &current->preempt_notifiers);
++}
++EXPORT_SYMBOL_GPL(preempt_notifier_register);
++
++/**
++ * preempt_notifier_unregister - no longer interested in preemption notifications
++ * @notifier: notifier struct to unregister
++ *
++ * This is *not* safe to call from within a preemption notifier.
++ */
++void preempt_notifier_unregister(struct preempt_notifier *notifier)
++{
++	hlist_del(&notifier->link);
++}
++EXPORT_SYMBOL_GPL(preempt_notifier_unregister);
++
++static void __fire_sched_in_preempt_notifiers(struct task_struct *curr)
++{
++	struct preempt_notifier *notifier;
++
++	hlist_for_each_entry(notifier, &curr->preempt_notifiers, link)
++		notifier->ops->sched_in(notifier, raw_smp_processor_id());
++}
++
++static __always_inline void fire_sched_in_preempt_notifiers(struct task_struct *curr)
++{
++	if (static_branch_unlikely(&preempt_notifier_key))
++		__fire_sched_in_preempt_notifiers(curr);
++}
++
++static void
++__fire_sched_out_preempt_notifiers(struct task_struct *curr,
++				   struct task_struct *next)
++{
++	struct preempt_notifier *notifier;
++
++	hlist_for_each_entry(notifier, &curr->preempt_notifiers, link)
++		notifier->ops->sched_out(notifier, next);
++}
++
++static __always_inline void
++fire_sched_out_preempt_notifiers(struct task_struct *curr,
++				 struct task_struct *next)
++{
++	if (static_branch_unlikely(&preempt_notifier_key))
++		__fire_sched_out_preempt_notifiers(curr, next);
++}
++
++#else /* !CONFIG_PREEMPT_NOTIFIERS */
++
++static inline void fire_sched_in_preempt_notifiers(struct task_struct *curr)
++{
++}
++
++static inline void
++fire_sched_out_preempt_notifiers(struct task_struct *curr,
++				 struct task_struct *next)
++{
++}
++
++#endif /* CONFIG_PREEMPT_NOTIFIERS */
++
++static inline void prepare_task(struct task_struct *next)
++{
++	/*
++	 * Claim the task as running, we do this before switching to it
++	 * such that any running task will have this set.
++	 *
++	 * See the smp_load_acquire(&p->on_cpu) case in ttwu() and
++	 * its ordering comment.
++	 */
++	WRITE_ONCE(next->on_cpu, 1);
++}
++
++static inline void finish_task(struct task_struct *prev)
++{
++#ifdef CONFIG_SMP
++	/*
++	 * This must be the very last reference to @prev from this CPU. After
++	 * p->on_cpu is cleared, the task can be moved to a different CPU. We
++	 * must ensure this doesn't happen until the switch is completely
++	 * finished.
++	 *
++	 * In particular, the load of prev->state in finish_task_switch() must
++	 * happen before this.
++	 *
++	 * Pairs with the smp_cond_load_acquire() in try_to_wake_up().
++	 */
++	smp_store_release(&prev->on_cpu, 0);
++#else
++	prev->on_cpu = 0;
++#endif
++}
++
++#ifdef CONFIG_SMP
++
++static void do_balance_callbacks(struct rq *rq, struct callback_head *head)
++{
++	void (*func)(struct rq *rq);
++	struct callback_head *next;
++
++	lockdep_assert_held(&rq->lock);
++
++	while (head) {
++		func = (void (*)(struct rq *))head->func;
++		next = head->next;
++		head->next = NULL;
++		head = next;
++
++		func(rq);
++	}
++}
++
++static void balance_push(struct rq *rq);
++
++/*
++ * balance_push_callback is a right abuse of the callback interface and plays
++ * by significantly different rules.
++ *
++ * Where the normal balance_callback's purpose is to be ran in the same context
++ * that queued it (only later, when it's safe to drop rq->lock again),
++ * balance_push_callback is specifically targeted at __schedule().
++ *
++ * This abuse is tolerated because it places all the unlikely/odd cases behind
++ * a single test, namely: rq->balance_callback == NULL.
++ */
++struct callback_head balance_push_callback = {
++	.next = NULL,
++	.func = (void (*)(struct callback_head *))balance_push,
++};
++
++static inline struct callback_head *
++__splice_balance_callbacks(struct rq *rq, bool split)
++{
++	struct callback_head *head = rq->balance_callback;
++
++	if (likely(!head))
++		return NULL;
++
++	lockdep_assert_rq_held(rq);
++	/*
++	 * Must not take balance_push_callback off the list when
++	 * splice_balance_callbacks() and balance_callbacks() are not
++	 * in the same rq->lock section.
++	 *
++	 * In that case it would be possible for __schedule() to interleave
++	 * and observe the list empty.
++	 */
++	if (split && head == &balance_push_callback)
++		head = NULL;
++	else
++		rq->balance_callback = NULL;
++
++	return head;
++}
++
++static inline struct callback_head *splice_balance_callbacks(struct rq *rq)
++{
++	return __splice_balance_callbacks(rq, true);
++}
++
++static void __balance_callbacks(struct rq *rq)
++{
++	do_balance_callbacks(rq, __splice_balance_callbacks(rq, false));
++}
++
++static inline void balance_callbacks(struct rq *rq, struct callback_head *head)
++{
++	unsigned long flags;
++
++	if (unlikely(head)) {
++		raw_spin_lock_irqsave(&rq->lock, flags);
++		do_balance_callbacks(rq, head);
++		raw_spin_unlock_irqrestore(&rq->lock, flags);
++	}
++}
++
++#else
++
++static inline void __balance_callbacks(struct rq *rq)
++{
++}
++
++static inline struct callback_head *splice_balance_callbacks(struct rq *rq)
++{
++	return NULL;
++}
++
++static inline void balance_callbacks(struct rq *rq, struct callback_head *head)
++{
++}
++
++#endif
++
++static inline void
++prepare_lock_switch(struct rq *rq, struct task_struct *next)
++{
++	/*
++	 * Since the runqueue lock will be released by the next
++	 * task (which is an invalid locking op but in the case
++	 * of the scheduler it's an obvious special-case), so we
++	 * do an early lockdep release here:
++	 */
++	spin_release(&rq->lock.dep_map, _THIS_IP_);
++#ifdef CONFIG_DEBUG_SPINLOCK
++	/* this is a valid case when another task releases the spinlock */
++	rq->lock.owner = next;
++#endif
++}
++
++static inline void finish_lock_switch(struct rq *rq)
++{
++	/*
++	 * If we are tracking spinlock dependencies then we have to
++	 * fix up the runqueue lock - which gets 'carried over' from
++	 * prev into current:
++	 */
++	spin_acquire(&rq->lock.dep_map, 0, 0, _THIS_IP_);
++	__balance_callbacks(rq);
++	raw_spin_unlock_irq(&rq->lock);
++}
++
++/*
++ * NOP if the arch has not defined these:
++ */
++
++#ifndef prepare_arch_switch
++# define prepare_arch_switch(next)	do { } while (0)
++#endif
++
++#ifndef finish_arch_post_lock_switch
++# define finish_arch_post_lock_switch()	do { } while (0)
++#endif
++
++static inline void kmap_local_sched_out(void)
++{
++#ifdef CONFIG_KMAP_LOCAL
++	if (unlikely(current->kmap_ctrl.idx))
++		__kmap_local_sched_out();
++#endif
++}
++
++static inline void kmap_local_sched_in(void)
++{
++#ifdef CONFIG_KMAP_LOCAL
++	if (unlikely(current->kmap_ctrl.idx))
++		__kmap_local_sched_in();
++#endif
++}
++
++/**
++ * prepare_task_switch - prepare to switch tasks
++ * @rq: the runqueue preparing to switch
++ * @next: the task we are going to switch to.
++ *
++ * This is called with the rq lock held and interrupts off. It must
++ * be paired with a subsequent finish_task_switch after the context
++ * switch.
++ *
++ * prepare_task_switch sets up locking and calls architecture specific
++ * hooks.
++ */
++static inline void
++prepare_task_switch(struct rq *rq, struct task_struct *prev,
++		    struct task_struct *next)
++{
++	kcov_prepare_switch(prev);
++	sched_info_switch(rq, prev, next);
++	perf_event_task_sched_out(prev, next);
++	rseq_preempt(prev);
++	fire_sched_out_preempt_notifiers(prev, next);
++	kmap_local_sched_out();
++	prepare_task(next);
++	prepare_arch_switch(next);
++}
++
++/**
++ * finish_task_switch - clean up after a task-switch
++ * @rq: runqueue associated with task-switch
++ * @prev: the thread we just switched away from.
++ *
++ * finish_task_switch must be called after the context switch, paired
++ * with a prepare_task_switch call before the context switch.
++ * finish_task_switch will reconcile locking set up by prepare_task_switch,
++ * and do any other architecture-specific cleanup actions.
++ *
++ * Note that we may have delayed dropping an mm in context_switch(). If
++ * so, we finish that here outside of the runqueue lock.  (Doing it
++ * with the lock held can cause deadlocks; see schedule() for
++ * details.)
++ *
++ * The context switch have flipped the stack from under us and restored the
++ * local variables which were saved when this task called schedule() in the
++ * past. prev == current is still correct but we need to recalculate this_rq
++ * because prev may have moved to another CPU.
++ */
++static struct rq *finish_task_switch(struct task_struct *prev)
++	__releases(rq->lock)
++{
++	struct rq *rq = this_rq();
++	struct mm_struct *mm = rq->prev_mm;
++	unsigned int prev_state;
++
++	/*
++	 * The previous task will have left us with a preempt_count of 2
++	 * because it left us after:
++	 *
++	 *	schedule()
++	 *	  preempt_disable();			// 1
++	 *	  __schedule()
++	 *	    raw_spin_lock_irq(&rq->lock)	// 2
++	 *
++	 * Also, see FORK_PREEMPT_COUNT.
++	 */
++	if (WARN_ONCE(preempt_count() != 2*PREEMPT_DISABLE_OFFSET,
++		      "corrupted preempt_count: %s/%d/0x%x\n",
++		      current->comm, current->pid, preempt_count()))
++		preempt_count_set(FORK_PREEMPT_COUNT);
++
++	rq->prev_mm = NULL;
++
++	/*
++	 * A task struct has one reference for the use as "current".
++	 * If a task dies, then it sets TASK_DEAD in tsk->state and calls
++	 * schedule one last time. The schedule call will never return, and
++	 * the scheduled task must drop that reference.
++	 *
++	 * We must observe prev->state before clearing prev->on_cpu (in
++	 * finish_task), otherwise a concurrent wakeup can get prev
++	 * running on another CPU and we could rave with its RUNNING -> DEAD
++	 * transition, resulting in a double drop.
++	 */
++	prev_state = READ_ONCE(prev->__state);
++	vtime_task_switch(prev);
++	perf_event_task_sched_in(prev, current);
++	finish_task(prev);
++	tick_nohz_task_switch();
++	finish_lock_switch(rq);
++	finish_arch_post_lock_switch();
++	kcov_finish_switch(current);
++	/*
++	 * kmap_local_sched_out() is invoked with rq::lock held and
++	 * interrupts disabled. There is no requirement for that, but the
++	 * sched out code does not have an interrupt enabled section.
++	 * Restoring the maps on sched in does not require interrupts being
++	 * disabled either.
++	 */
++	kmap_local_sched_in();
++
++	fire_sched_in_preempt_notifiers(current);
++	/*
++	 * When switching through a kernel thread, the loop in
++	 * membarrier_{private,global}_expedited() may have observed that
++	 * kernel thread and not issued an IPI. It is therefore possible to
++	 * schedule between user->kernel->user threads without passing though
++	 * switch_mm(). Membarrier requires a barrier after storing to
++	 * rq->curr, before returning to userspace, so provide them here:
++	 *
++	 * - a full memory barrier for {PRIVATE,GLOBAL}_EXPEDITED, implicitly
++	 *   provided by mmdrop(),
++	 * - a sync_core for SYNC_CORE.
++	 */
++	if (mm) {
++		membarrier_mm_sync_core_before_usermode(mm);
++		mmdrop_sched(mm);
++	}
++	if (unlikely(prev_state == TASK_DEAD)) {
++		/* Task is done with its stack. */
++		put_task_stack(prev);
++
++		put_task_struct_rcu_user(prev);
++	}
++
++	return rq;
++}
++
++/**
++ * schedule_tail - first thing a freshly forked thread must call.
++ * @prev: the thread we just switched away from.
++ */
++asmlinkage __visible void schedule_tail(struct task_struct *prev)
++	__releases(rq->lock)
++{
++	/*
++	 * New tasks start with FORK_PREEMPT_COUNT, see there and
++	 * finish_task_switch() for details.
++	 *
++	 * finish_task_switch() will drop rq->lock() and lower preempt_count
++	 * and the preempt_enable() will end up enabling preemption (on
++	 * PREEMPT_COUNT kernels).
++	 */
++
++	finish_task_switch(prev);
++	preempt_enable();
++
++	if (current->set_child_tid)
++		put_user(task_pid_vnr(current), current->set_child_tid);
++
++	calculate_sigpending();
++}
++
++/*
++ * context_switch - switch to the new MM and the new thread's register state.
++ */
++static __always_inline struct rq *
++context_switch(struct rq *rq, struct task_struct *prev,
++	       struct task_struct *next)
++{
++	prepare_task_switch(rq, prev, next);
++
++	/*
++	 * For paravirt, this is coupled with an exit in switch_to to
++	 * combine the page table reload and the switch backend into
++	 * one hypercall.
++	 */
++	arch_start_context_switch(prev);
++
++	/*
++	 * kernel -> kernel   lazy + transfer active
++	 *   user -> kernel   lazy + mmgrab() active
++	 *
++	 * kernel ->   user   switch + mmdrop() active
++	 *   user ->   user   switch
++	 */
++	if (!next->mm) {                                // to kernel
++		enter_lazy_tlb(prev->active_mm, next);
++
++		next->active_mm = prev->active_mm;
++		if (prev->mm)                           // from user
++			mmgrab(prev->active_mm);
++		else
++			prev->active_mm = NULL;
++	} else {                                        // to user
++		membarrier_switch_mm(rq, prev->active_mm, next->mm);
++		/*
++		 * sys_membarrier() requires an smp_mb() between setting
++		 * rq->curr / membarrier_switch_mm() and returning to userspace.
++		 *
++		 * The below provides this either through switch_mm(), or in
++		 * case 'prev->active_mm == next->mm' through
++		 * finish_task_switch()'s mmdrop().
++		 */
++		switch_mm_irqs_off(prev->active_mm, next->mm, next);
++
++		if (!prev->mm) {                        // from kernel
++			/* will mmdrop() in finish_task_switch(). */
++			rq->prev_mm = prev->active_mm;
++			prev->active_mm = NULL;
++		}
++	}
++
++	prepare_lock_switch(rq, next);
++
++	/* Here we just switch the register state and the stack. */
++	switch_to(prev, next, prev);
++	barrier();
++
++	return finish_task_switch(prev);
++}
++
++/*
++ * nr_running, nr_uninterruptible and nr_context_switches:
++ *
++ * externally visible scheduler statistics: current number of runnable
++ * threads, total number of context switches performed since bootup.
++ */
++unsigned int nr_running(void)
++{
++	unsigned int i, sum = 0;
++
++	for_each_online_cpu(i)
++		sum += cpu_rq(i)->nr_running;
++
++	return sum;
++}
++
++/*
++ * Check if only the current task is running on the CPU.
++ *
++ * Caution: this function does not check that the caller has disabled
++ * preemption, thus the result might have a time-of-check-to-time-of-use
++ * race.  The caller is responsible to use it correctly, for example:
++ *
++ * - from a non-preemptible section (of course)
++ *
++ * - from a thread that is bound to a single CPU
++ *
++ * - in a loop with very short iterations (e.g. a polling loop)
++ */
++bool single_task_running(void)
++{
++	return raw_rq()->nr_running == 1;
++}
++EXPORT_SYMBOL(single_task_running);
++
++unsigned long long nr_context_switches(void)
++{
++	int i;
++	unsigned long long sum = 0;
++
++	for_each_possible_cpu(i)
++		sum += cpu_rq(i)->nr_switches;
++
++	return sum;
++}
++
++/*
++ * Consumers of these two interfaces, like for example the cpuidle menu
++ * governor, are using nonsensical data. Preferring shallow idle state selection
++ * for a CPU that has IO-wait which might not even end up running the task when
++ * it does become runnable.
++ */
++
++unsigned int nr_iowait_cpu(int cpu)
++{
++	return atomic_read(&cpu_rq(cpu)->nr_iowait);
++}
++
++/*
++ * IO-wait accounting, and how it's mostly bollocks (on SMP).
++ *
++ * The idea behind IO-wait account is to account the idle time that we could
++ * have spend running if it were not for IO. That is, if we were to improve the
++ * storage performance, we'd have a proportional reduction in IO-wait time.
++ *
++ * This all works nicely on UP, where, when a task blocks on IO, we account
++ * idle time as IO-wait, because if the storage were faster, it could've been
++ * running and we'd not be idle.
++ *
++ * This has been extended to SMP, by doing the same for each CPU. This however
++ * is broken.
++ *
++ * Imagine for instance the case where two tasks block on one CPU, only the one
++ * CPU will have IO-wait accounted, while the other has regular idle. Even
++ * though, if the storage were faster, both could've ran at the same time,
++ * utilising both CPUs.
++ *
++ * This means, that when looking globally, the current IO-wait accounting on
++ * SMP is a lower bound, by reason of under accounting.
++ *
++ * Worse, since the numbers are provided per CPU, they are sometimes
++ * interpreted per CPU, and that is nonsensical. A blocked task isn't strictly
++ * associated with any one particular CPU, it can wake to another CPU than it
++ * blocked on. This means the per CPU IO-wait number is meaningless.
++ *
++ * Task CPU affinities can make all that even more 'interesting'.
++ */
++
++unsigned int nr_iowait(void)
++{
++	unsigned int i, sum = 0;
++
++	for_each_possible_cpu(i)
++		sum += nr_iowait_cpu(i);
++
++	return sum;
++}
++
++#ifdef CONFIG_SMP
++
++/*
++ * sched_exec - execve() is a valuable balancing opportunity, because at
++ * this point the task has the smallest effective memory and cache
++ * footprint.
++ */
++void sched_exec(void)
++{
++}
++
++#endif
++
++DEFINE_PER_CPU(struct kernel_stat, kstat);
++DEFINE_PER_CPU(struct kernel_cpustat, kernel_cpustat);
++
++EXPORT_PER_CPU_SYMBOL(kstat);
++EXPORT_PER_CPU_SYMBOL(kernel_cpustat);
++
++static inline void update_curr(struct rq *rq, struct task_struct *p)
++{
++	s64 ns = rq->clock_task - p->last_ran;
++
++	p->sched_time += ns;
++	cgroup_account_cputime(p, ns);
++	account_group_exec_runtime(p, ns);
++
++	p->time_slice -= ns;
++	p->last_ran = rq->clock_task;
++}
++
++/*
++ * Return accounted runtime for the task.
++ * Return separately the current's pending runtime that have not been
++ * accounted yet.
++ */
++unsigned long long task_sched_runtime(struct task_struct *p)
++{
++	unsigned long flags;
++	struct rq *rq;
++	raw_spinlock_t *lock;
++	u64 ns;
++
++#if defined(CONFIG_64BIT) && defined(CONFIG_SMP)
++	/*
++	 * 64-bit doesn't need locks to atomically read a 64-bit value.
++	 * So we have a optimization chance when the task's delta_exec is 0.
++	 * Reading ->on_cpu is racy, but this is ok.
++	 *
++	 * If we race with it leaving CPU, we'll take a lock. So we're correct.
++	 * If we race with it entering CPU, unaccounted time is 0. This is
++	 * indistinguishable from the read occurring a few cycles earlier.
++	 * If we see ->on_cpu without ->on_rq, the task is leaving, and has
++	 * been accounted, so we're correct here as well.
++	 */
++	if (!p->on_cpu || !task_on_rq_queued(p))
++		return tsk_seruntime(p);
++#endif
++
++	rq = task_access_lock_irqsave(p, &lock, &flags);
++	/*
++	 * Must be ->curr _and_ ->on_rq.  If dequeued, we would
++	 * project cycles that may never be accounted to this
++	 * thread, breaking clock_gettime().
++	 */
++	if (p == rq->curr && task_on_rq_queued(p)) {
++		update_rq_clock(rq);
++		update_curr(rq, p);
++	}
++	ns = tsk_seruntime(p);
++	task_access_unlock_irqrestore(p, lock, &flags);
++
++	return ns;
++}
++
++/* This manages tasks that have run out of timeslice during a scheduler_tick */
++static inline void scheduler_task_tick(struct rq *rq)
++{
++	struct task_struct *p = rq->curr;
++
++	if (is_idle_task(p))
++		return;
++
++	update_curr(rq, p);
++	cpufreq_update_util(rq, 0);
++
++	/*
++	 * Tasks have less than RESCHED_NS of time slice left they will be
++	 * rescheduled.
++	 */
++	if (p->time_slice >= RESCHED_NS)
++		return;
++	set_tsk_need_resched(p);
++	set_preempt_need_resched();
++}
++
++#ifdef CONFIG_SCHED_DEBUG
++static u64 cpu_resched_latency(struct rq *rq)
++{
++	int latency_warn_ms = READ_ONCE(sysctl_resched_latency_warn_ms);
++	u64 resched_latency, now = rq_clock(rq);
++	static bool warned_once;
++
++	if (sysctl_resched_latency_warn_once && warned_once)
++		return 0;
++
++	if (!need_resched() || !latency_warn_ms)
++		return 0;
++
++	if (system_state == SYSTEM_BOOTING)
++		return 0;
++
++	if (!rq->last_seen_need_resched_ns) {
++		rq->last_seen_need_resched_ns = now;
++		rq->ticks_without_resched = 0;
++		return 0;
++	}
++
++	rq->ticks_without_resched++;
++	resched_latency = now - rq->last_seen_need_resched_ns;
++	if (resched_latency <= latency_warn_ms * NSEC_PER_MSEC)
++		return 0;
++
++	warned_once = true;
++
++	return resched_latency;
++}
++
++static int __init setup_resched_latency_warn_ms(char *str)
++{
++	long val;
++
++	if ((kstrtol(str, 0, &val))) {
++		pr_warn("Unable to set resched_latency_warn_ms\n");
++		return 1;
++	}
++
++	sysctl_resched_latency_warn_ms = val;
++	return 1;
++}
++__setup("resched_latency_warn_ms=", setup_resched_latency_warn_ms);
++#else
++static inline u64 cpu_resched_latency(struct rq *rq) { return 0; }
++#endif /* CONFIG_SCHED_DEBUG */
++
++/*
++ * This function gets called by the timer code, with HZ frequency.
++ * We call it with interrupts disabled.
++ */
++void scheduler_tick(void)
++{
++	int cpu __maybe_unused = smp_processor_id();
++	struct rq *rq = cpu_rq(cpu);
++	u64 resched_latency;
++
++	arch_scale_freq_tick();
++	sched_clock_tick();
++
++	raw_spin_lock(&rq->lock);
++	update_rq_clock(rq);
++
++	scheduler_task_tick(rq);
++	if (sched_feat(LATENCY_WARN))
++		resched_latency = cpu_resched_latency(rq);
++	calc_global_load_tick(rq);
++
++	rq->last_tick = rq->clock;
++	raw_spin_unlock(&rq->lock);
++
++	if (sched_feat(LATENCY_WARN) && resched_latency)
++		resched_latency_warn(cpu, resched_latency);
++
++	perf_event_task_tick();
++}
++
++#ifdef CONFIG_SCHED_SMT
++static inline int sg_balance_cpu_stop(void *data)
++{
++	struct rq *rq = this_rq();
++	struct task_struct *p = data;
++	cpumask_t tmp;
++	unsigned long flags;
++
++	local_irq_save(flags);
++
++	raw_spin_lock(&p->pi_lock);
++	raw_spin_lock(&rq->lock);
++
++	rq->active_balance = 0;
++	/* _something_ may have changed the task, double check again */
++	if (task_on_rq_queued(p) && task_rq(p) == rq &&
++	    cpumask_and(&tmp, p->cpus_ptr, &sched_sg_idle_mask) &&
++	    !is_migration_disabled(p)) {
++		int cpu = cpu_of(rq);
++		int dcpu = __best_mask_cpu(&tmp, per_cpu(sched_cpu_llc_mask, cpu));
++		rq = move_queued_task(rq, p, dcpu);
++	}
++
++	raw_spin_unlock(&rq->lock);
++	raw_spin_unlock(&p->pi_lock);
++
++	local_irq_restore(flags);
++
++	return 0;
++}
++
++/* sg_balance_trigger - trigger slibing group balance for @cpu */
++static inline int sg_balance_trigger(const int cpu)
++{
++	struct rq *rq= cpu_rq(cpu);
++	unsigned long flags;
++	struct task_struct *curr;
++	int res;
++
++	if (!raw_spin_trylock_irqsave(&rq->lock, flags))
++		return 0;
++	curr = rq->curr;
++	res = (!is_idle_task(curr)) && (1 == rq->nr_running) &&\
++	      cpumask_intersects(curr->cpus_ptr, &sched_sg_idle_mask) &&\
++	      !is_migration_disabled(curr) && (!rq->active_balance);
++
++	if (res)
++		rq->active_balance = 1;
++
++	raw_spin_unlock_irqrestore(&rq->lock, flags);
++
++	if (res)
++		stop_one_cpu_nowait(cpu, sg_balance_cpu_stop, curr,
++				    &rq->active_balance_work);
++	return res;
++}
++
++/*
++ * sg_balance - slibing group balance check for run queue @rq
++ */
++static inline void sg_balance(struct rq *rq)
++{
++	cpumask_t chk;
++	int cpu = cpu_of(rq);
++
++	/* exit when cpu is offline */
++	if (unlikely(!rq->online))
++		return;
++
++	/*
++	 * Only cpu in slibing idle group will do the checking and then
++	 * find potential cpus which can migrate the current running task
++	 */
++	if (cpumask_test_cpu(cpu, &sched_sg_idle_mask) &&
++	    cpumask_andnot(&chk, cpu_online_mask, sched_rq_watermark) &&
++	    cpumask_andnot(&chk, &chk, &sched_rq_pending_mask)) {
++		int i;
++
++		for_each_cpu_wrap(i, &chk, cpu) {
++			if (cpumask_subset(cpu_smt_mask(i), &chk) &&
++			    sg_balance_trigger(i))
++				return;
++		}
++	}
++}
++#endif /* CONFIG_SCHED_SMT */
++
++#ifdef CONFIG_NO_HZ_FULL
++
++struct tick_work {
++	int			cpu;
++	atomic_t		state;
++	struct delayed_work	work;
++};
++/* Values for ->state, see diagram below. */
++#define TICK_SCHED_REMOTE_OFFLINE	0
++#define TICK_SCHED_REMOTE_OFFLINING	1
++#define TICK_SCHED_REMOTE_RUNNING	2
++
++/*
++ * State diagram for ->state:
++ *
++ *
++ *          TICK_SCHED_REMOTE_OFFLINE
++ *                    |   ^
++ *                    |   |
++ *                    |   | sched_tick_remote()
++ *                    |   |
++ *                    |   |
++ *                    +--TICK_SCHED_REMOTE_OFFLINING
++ *                    |   ^
++ *                    |   |
++ * sched_tick_start() |   | sched_tick_stop()
++ *                    |   |
++ *                    V   |
++ *          TICK_SCHED_REMOTE_RUNNING
++ *
++ *
++ * Other transitions get WARN_ON_ONCE(), except that sched_tick_remote()
++ * and sched_tick_start() are happy to leave the state in RUNNING.
++ */
++
++static struct tick_work __percpu *tick_work_cpu;
++
++static void sched_tick_remote(struct work_struct *work)
++{
++	struct delayed_work *dwork = to_delayed_work(work);
++	struct tick_work *twork = container_of(dwork, struct tick_work, work);
++	int cpu = twork->cpu;
++	struct rq *rq = cpu_rq(cpu);
++	struct task_struct *curr;
++	unsigned long flags;
++	u64 delta;
++	int os;
++
++	/*
++	 * Handle the tick only if it appears the remote CPU is running in full
++	 * dynticks mode. The check is racy by nature, but missing a tick or
++	 * having one too much is no big deal because the scheduler tick updates
++	 * statistics and checks timeslices in a time-independent way, regardless
++	 * of when exactly it is running.
++	 */
++	if (!tick_nohz_tick_stopped_cpu(cpu))
++		goto out_requeue;
++
++	raw_spin_lock_irqsave(&rq->lock, flags);
++	curr = rq->curr;
++	if (cpu_is_offline(cpu))
++		goto out_unlock;
++
++	update_rq_clock(rq);
++	if (!is_idle_task(curr)) {
++		/*
++		 * Make sure the next tick runs within a reasonable
++		 * amount of time.
++		 */
++		delta = rq_clock_task(rq) - curr->last_ran;
++		WARN_ON_ONCE(delta > (u64)NSEC_PER_SEC * 3);
++	}
++	scheduler_task_tick(rq);
++
++	calc_load_nohz_remote(rq);
++out_unlock:
++	raw_spin_unlock_irqrestore(&rq->lock, flags);
++
++out_requeue:
++	/*
++	 * Run the remote tick once per second (1Hz). This arbitrary
++	 * frequency is large enough to avoid overload but short enough
++	 * to keep scheduler internal stats reasonably up to date.  But
++	 * first update state to reflect hotplug activity if required.
++	 */
++	os = atomic_fetch_add_unless(&twork->state, -1, TICK_SCHED_REMOTE_RUNNING);
++	WARN_ON_ONCE(os == TICK_SCHED_REMOTE_OFFLINE);
++	if (os == TICK_SCHED_REMOTE_RUNNING)
++		queue_delayed_work(system_unbound_wq, dwork, HZ);
++}
++
++static void sched_tick_start(int cpu)
++{
++	int os;
++	struct tick_work *twork;
++
++	if (housekeeping_cpu(cpu, HK_TYPE_TICK))
++		return;
++
++	WARN_ON_ONCE(!tick_work_cpu);
++
++	twork = per_cpu_ptr(tick_work_cpu, cpu);
++	os = atomic_xchg(&twork->state, TICK_SCHED_REMOTE_RUNNING);
++	WARN_ON_ONCE(os == TICK_SCHED_REMOTE_RUNNING);
++	if (os == TICK_SCHED_REMOTE_OFFLINE) {
++		twork->cpu = cpu;
++		INIT_DELAYED_WORK(&twork->work, sched_tick_remote);
++		queue_delayed_work(system_unbound_wq, &twork->work, HZ);
++	}
++}
++
++#ifdef CONFIG_HOTPLUG_CPU
++static void sched_tick_stop(int cpu)
++{
++	struct tick_work *twork;
++
++	if (housekeeping_cpu(cpu, HK_TYPE_TICK))
++		return;
++
++	WARN_ON_ONCE(!tick_work_cpu);
++
++	twork = per_cpu_ptr(tick_work_cpu, cpu);
++	cancel_delayed_work_sync(&twork->work);
++}
++#endif /* CONFIG_HOTPLUG_CPU */
++
++int __init sched_tick_offload_init(void)
++{
++	tick_work_cpu = alloc_percpu(struct tick_work);
++	BUG_ON(!tick_work_cpu);
++	return 0;
++}
++
++#else /* !CONFIG_NO_HZ_FULL */
++static inline void sched_tick_start(int cpu) { }
++static inline void sched_tick_stop(int cpu) { }
++#endif
++
++#if defined(CONFIG_PREEMPTION) && (defined(CONFIG_DEBUG_PREEMPT) || \
++				defined(CONFIG_PREEMPT_TRACER))
++/*
++ * If the value passed in is equal to the current preempt count
++ * then we just disabled preemption. Start timing the latency.
++ */
++static inline void preempt_latency_start(int val)
++{
++	if (preempt_count() == val) {
++		unsigned long ip = get_lock_parent_ip();
++#ifdef CONFIG_DEBUG_PREEMPT
++		current->preempt_disable_ip = ip;
++#endif
++		trace_preempt_off(CALLER_ADDR0, ip);
++	}
++}
++
++void preempt_count_add(int val)
++{
++#ifdef CONFIG_DEBUG_PREEMPT
++	/*
++	 * Underflow?
++	 */
++	if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0)))
++		return;
++#endif
++	__preempt_count_add(val);
++#ifdef CONFIG_DEBUG_PREEMPT
++	/*
++	 * Spinlock count overflowing soon?
++	 */
++	DEBUG_LOCKS_WARN_ON((preempt_count() & PREEMPT_MASK) >=
++				PREEMPT_MASK - 10);
++#endif
++	preempt_latency_start(val);
++}
++EXPORT_SYMBOL(preempt_count_add);
++NOKPROBE_SYMBOL(preempt_count_add);
++
++/*
++ * If the value passed in equals to the current preempt count
++ * then we just enabled preemption. Stop timing the latency.
++ */
++static inline void preempt_latency_stop(int val)
++{
++	if (preempt_count() == val)
++		trace_preempt_on(CALLER_ADDR0, get_lock_parent_ip());
++}
++
++void preempt_count_sub(int val)
++{
++#ifdef CONFIG_DEBUG_PREEMPT
++	/*
++	 * Underflow?
++	 */
++	if (DEBUG_LOCKS_WARN_ON(val > preempt_count()))
++		return;
++	/*
++	 * Is the spinlock portion underflowing?
++	 */
++	if (DEBUG_LOCKS_WARN_ON((val < PREEMPT_MASK) &&
++			!(preempt_count() & PREEMPT_MASK)))
++		return;
++#endif
++
++	preempt_latency_stop(val);
++	__preempt_count_sub(val);
++}
++EXPORT_SYMBOL(preempt_count_sub);
++NOKPROBE_SYMBOL(preempt_count_sub);
++
++#else
++static inline void preempt_latency_start(int val) { }
++static inline void preempt_latency_stop(int val) { }
++#endif
++
++static inline unsigned long get_preempt_disable_ip(struct task_struct *p)
++{
++#ifdef CONFIG_DEBUG_PREEMPT
++	return p->preempt_disable_ip;
++#else
++	return 0;
++#endif
++}
++
++/*
++ * Print scheduling while atomic bug:
++ */
++static noinline void __schedule_bug(struct task_struct *prev)
++{
++	/* Save this before calling printk(), since that will clobber it */
++	unsigned long preempt_disable_ip = get_preempt_disable_ip(current);
++
++	if (oops_in_progress)
++		return;
++
++	printk(KERN_ERR "BUG: scheduling while atomic: %s/%d/0x%08x\n",
++		prev->comm, prev->pid, preempt_count());
++
++	debug_show_held_locks(prev);
++	print_modules();
++	if (irqs_disabled())
++		print_irqtrace_events(prev);
++	if (IS_ENABLED(CONFIG_DEBUG_PREEMPT)
++	    && in_atomic_preempt_off()) {
++		pr_err("Preemption disabled at:");
++		print_ip_sym(KERN_ERR, preempt_disable_ip);
++	}
++	if (panic_on_warn)
++		panic("scheduling while atomic\n");
++
++	dump_stack();
++	add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
++}
++
++/*
++ * Various schedule()-time debugging checks and statistics:
++ */
++static inline void schedule_debug(struct task_struct *prev, bool preempt)
++{
++#ifdef CONFIG_SCHED_STACK_END_CHECK
++	if (task_stack_end_corrupted(prev))
++		panic("corrupted stack end detected inside scheduler\n");
++
++	if (task_scs_end_corrupted(prev))
++		panic("corrupted shadow stack detected inside scheduler\n");
++#endif
++
++#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
++	if (!preempt && READ_ONCE(prev->__state) && prev->non_block_count) {
++		printk(KERN_ERR "BUG: scheduling in a non-blocking section: %s/%d/%i\n",
++			prev->comm, prev->pid, prev->non_block_count);
++		dump_stack();
++		add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
++	}
++#endif
++
++	if (unlikely(in_atomic_preempt_off())) {
++		__schedule_bug(prev);
++		preempt_count_set(PREEMPT_DISABLED);
++	}
++	rcu_sleep_check();
++	SCHED_WARN_ON(ct_state() == CONTEXT_USER);
++
++	profile_hit(SCHED_PROFILING, __builtin_return_address(0));
++
++	schedstat_inc(this_rq()->sched_count);
++}
++
++/*
++ * Compile time debug macro
++ * #define ALT_SCHED_DEBUG
++ */
++
++#ifdef ALT_SCHED_DEBUG
++void alt_sched_debug(void)
++{
++	printk(KERN_INFO "sched: pending: 0x%04lx, idle: 0x%04lx, sg_idle: 0x%04lx\n",
++	       sched_rq_pending_mask.bits[0],
++	       sched_rq_watermark[0].bits[0],
++	       sched_sg_idle_mask.bits[0]);
++}
++#else
++inline void alt_sched_debug(void) {}
++#endif
++
++#ifdef	CONFIG_SMP
++
++#define SCHED_RQ_NR_MIGRATION (32U)
++/*
++ * Migrate pending tasks in @rq to @dest_cpu
++ * Will try to migrate mininal of half of @rq nr_running tasks and
++ * SCHED_RQ_NR_MIGRATION to @dest_cpu
++ */
++static inline int
++migrate_pending_tasks(struct rq *rq, struct rq *dest_rq, const int dest_cpu)
++{
++	struct task_struct *p, *skip = rq->curr;
++	int nr_migrated = 0;
++	int nr_tries = min(rq->nr_running / 2, SCHED_RQ_NR_MIGRATION);
++
++	while (skip != rq->idle && nr_tries &&
++	       (p = sched_rq_next_task(skip, rq)) != rq->idle) {
++		skip = sched_rq_next_task(p, rq);
++		if (cpumask_test_cpu(dest_cpu, p->cpus_ptr)) {
++			__SCHED_DEQUEUE_TASK(p, rq, 0);
++			set_task_cpu(p, dest_cpu);
++			sched_task_sanity_check(p, dest_rq);
++			__SCHED_ENQUEUE_TASK(p, dest_rq, 0);
++			nr_migrated++;
++		}
++		nr_tries--;
++	}
++
++	return nr_migrated;
++}
++
++static inline int take_other_rq_tasks(struct rq *rq, int cpu)
++{
++	struct cpumask *topo_mask, *end_mask;
++
++	if (unlikely(!rq->online))
++		return 0;
++
++	if (cpumask_empty(&sched_rq_pending_mask))
++		return 0;
++
++	topo_mask = per_cpu(sched_cpu_topo_masks, cpu) + 1;
++	end_mask = per_cpu(sched_cpu_topo_end_mask, cpu);
++	do {
++		int i;
++		for_each_cpu_and(i, &sched_rq_pending_mask, topo_mask) {
++			int nr_migrated;
++			struct rq *src_rq;
++
++			src_rq = cpu_rq(i);
++			if (!do_raw_spin_trylock(&src_rq->lock))
++				continue;
++			spin_acquire(&src_rq->lock.dep_map,
++				     SINGLE_DEPTH_NESTING, 1, _RET_IP_);
++
++			if ((nr_migrated = migrate_pending_tasks(src_rq, rq, cpu))) {
++				src_rq->nr_running -= nr_migrated;
++				if (src_rq->nr_running < 2)
++					cpumask_clear_cpu(i, &sched_rq_pending_mask);
++
++				rq->nr_running += nr_migrated;
++				if (rq->nr_running > 1)
++					cpumask_set_cpu(cpu, &sched_rq_pending_mask);
++
++				cpufreq_update_util(rq, 0);
++
++				spin_release(&src_rq->lock.dep_map, _RET_IP_);
++				do_raw_spin_unlock(&src_rq->lock);
++
++				return 1;
++			}
++
++			spin_release(&src_rq->lock.dep_map, _RET_IP_);
++			do_raw_spin_unlock(&src_rq->lock);
++		}
++	} while (++topo_mask < end_mask);
++
++	return 0;
++}
++#endif
++
++/*
++ * Timeslices below RESCHED_NS are considered as good as expired as there's no
++ * point rescheduling when there's so little time left.
++ */
++static inline void check_curr(struct task_struct *p, struct rq *rq)
++{
++	if (unlikely(rq->idle == p))
++		return;
++
++	update_curr(rq, p);
++
++	if (p->time_slice < RESCHED_NS)
++		time_slice_expired(p, rq);
++}
++
++static inline struct task_struct *
++choose_next_task(struct rq *rq, int cpu, struct task_struct *prev)
++{
++	struct task_struct *next;
++
++	if (unlikely(rq->skip)) {
++		next = rq_runnable_task(rq);
++		if (next == rq->idle) {
++#ifdef	CONFIG_SMP
++			if (!take_other_rq_tasks(rq, cpu)) {
++#endif
++				rq->skip = NULL;
++				schedstat_inc(rq->sched_goidle);
++				return next;
++#ifdef	CONFIG_SMP
++			}
++			next = rq_runnable_task(rq);
++#endif
++		}
++		rq->skip = NULL;
++#ifdef CONFIG_HIGH_RES_TIMERS
++		hrtick_start(rq, next->time_slice);
++#endif
++		return next;
++	}
++
++	next = sched_rq_first_task(rq);
++	if (next == rq->idle) {
++#ifdef	CONFIG_SMP
++		if (!take_other_rq_tasks(rq, cpu)) {
++#endif
++			schedstat_inc(rq->sched_goidle);
++			/*printk(KERN_INFO "sched: choose_next_task(%d) idle %px\n", cpu, next);*/
++			return next;
++#ifdef	CONFIG_SMP
++		}
++		next = sched_rq_first_task(rq);
++#endif
++	}
++#ifdef CONFIG_HIGH_RES_TIMERS
++	hrtick_start(rq, next->time_slice);
++#endif
++	/*printk(KERN_INFO "sched: choose_next_task(%d) next %px\n", cpu,
++	 * next);*/
++	return next;
++}
++
++/*
++ * Constants for the sched_mode argument of __schedule().
++ *
++ * The mode argument allows RT enabled kernels to differentiate a
++ * preemption from blocking on an 'sleeping' spin/rwlock. Note that
++ * SM_MASK_PREEMPT for !RT has all bits set, which allows the compiler to
++ * optimize the AND operation out and just check for zero.
++ */
++#define SM_NONE			0x0
++#define SM_PREEMPT		0x1
++#define SM_RTLOCK_WAIT		0x2
++
++#ifndef CONFIG_PREEMPT_RT
++# define SM_MASK_PREEMPT	(~0U)
++#else
++# define SM_MASK_PREEMPT	SM_PREEMPT
++#endif
++
++/*
++ * schedule() is the main scheduler function.
++ *
++ * The main means of driving the scheduler and thus entering this function are:
++ *
++ *   1. Explicit blocking: mutex, semaphore, waitqueue, etc.
++ *
++ *   2. TIF_NEED_RESCHED flag is checked on interrupt and userspace return
++ *      paths. For example, see arch/x86/entry_64.S.
++ *
++ *      To drive preemption between tasks, the scheduler sets the flag in timer
++ *      interrupt handler scheduler_tick().
++ *
++ *   3. Wakeups don't really cause entry into schedule(). They add a
++ *      task to the run-queue and that's it.
++ *
++ *      Now, if the new task added to the run-queue preempts the current
++ *      task, then the wakeup sets TIF_NEED_RESCHED and schedule() gets
++ *      called on the nearest possible occasion:
++ *
++ *       - If the kernel is preemptible (CONFIG_PREEMPTION=y):
++ *
++ *         - in syscall or exception context, at the next outmost
++ *           preempt_enable(). (this might be as soon as the wake_up()'s
++ *           spin_unlock()!)
++ *
++ *         - in IRQ context, return from interrupt-handler to
++ *           preemptible context
++ *
++ *       - If the kernel is not preemptible (CONFIG_PREEMPTION is not set)
++ *         then at the next:
++ *
++ *          - cond_resched() call
++ *          - explicit schedule() call
++ *          - return from syscall or exception to user-space
++ *          - return from interrupt-handler to user-space
++ *
++ * WARNING: must be called with preemption disabled!
++ */
++static void __sched notrace __schedule(unsigned int sched_mode)
++{
++	struct task_struct *prev, *next;
++	unsigned long *switch_count;
++	unsigned long prev_state;
++	struct rq *rq;
++	int cpu;
++	int deactivated = 0;
++
++	cpu = smp_processor_id();
++	rq = cpu_rq(cpu);
++	prev = rq->curr;
++
++	schedule_debug(prev, !!sched_mode);
++
++	/* by passing sched_feat(HRTICK) checking which Alt schedule FW doesn't support */
++	hrtick_clear(rq);
++
++	local_irq_disable();
++	rcu_note_context_switch(!!sched_mode);
++
++	/*
++	 * Make sure that signal_pending_state()->signal_pending() below
++	 * can't be reordered with __set_current_state(TASK_INTERRUPTIBLE)
++	 * done by the caller to avoid the race with signal_wake_up():
++	 *
++	 * __set_current_state(@state)		signal_wake_up()
++	 * schedule()				  set_tsk_thread_flag(p, TIF_SIGPENDING)
++	 *					  wake_up_state(p, state)
++	 *   LOCK rq->lock			    LOCK p->pi_state
++	 *   smp_mb__after_spinlock()		    smp_mb__after_spinlock()
++	 *     if (signal_pending_state())	    if (p->state & @state)
++	 *
++	 * Also, the membarrier system call requires a full memory barrier
++	 * after coming from user-space, before storing to rq->curr.
++	 */
++	raw_spin_lock(&rq->lock);
++	smp_mb__after_spinlock();
++
++	update_rq_clock(rq);
++
++	switch_count = &prev->nivcsw;
++	/*
++	 * We must load prev->state once (task_struct::state is volatile), such
++	 * that we form a control dependency vs deactivate_task() below.
++	 */
++	prev_state = READ_ONCE(prev->__state);
++	if (!(sched_mode & SM_MASK_PREEMPT) && prev_state) {
++		if (signal_pending_state(prev_state, prev)) {
++			WRITE_ONCE(prev->__state, TASK_RUNNING);
++		} else {
++			prev->sched_contributes_to_load =
++				(prev_state & TASK_UNINTERRUPTIBLE) &&
++				!(prev_state & TASK_NOLOAD) &&
++				!(prev->flags & PF_FROZEN);
++
++			if (prev->sched_contributes_to_load)
++				rq->nr_uninterruptible++;
++
++			/*
++			 * __schedule()			ttwu()
++			 *   prev_state = prev->state;    if (p->on_rq && ...)
++			 *   if (prev_state)		    goto out;
++			 *     p->on_rq = 0;		  smp_acquire__after_ctrl_dep();
++			 *				  p->state = TASK_WAKING
++			 *
++			 * Where __schedule() and ttwu() have matching control dependencies.
++			 *
++			 * After this, schedule() must not care about p->state any more.
++			 */
++			sched_task_deactivate(prev, rq);
++			deactivate_task(prev, rq);
++			deactivated = 1;
++
++			if (prev->in_iowait) {
++				atomic_inc(&rq->nr_iowait);
++				delayacct_blkio_start();
++			}
++		}
++		switch_count = &prev->nvcsw;
++	}
++
++	check_curr(prev, rq);
++
++	next = choose_next_task(rq, cpu, prev);
++	clear_tsk_need_resched(prev);
++	clear_preempt_need_resched();
++#ifdef CONFIG_SCHED_DEBUG
++	rq->last_seen_need_resched_ns = 0;
++#endif
++
++	if (likely(prev != next)) {
++		if (deactivated)
++			update_sched_rq_watermark(rq);
++		next->last_ran = rq->clock_task;
++		rq->last_ts_switch = rq->clock;
++
++		rq->nr_switches++;
++		/*
++		 * RCU users of rcu_dereference(rq->curr) may not see
++		 * changes to task_struct made by pick_next_task().
++		 */
++		RCU_INIT_POINTER(rq->curr, next);
++		/*
++		 * The membarrier system call requires each architecture
++		 * to have a full memory barrier after updating
++		 * rq->curr, before returning to user-space.
++		 *
++		 * Here are the schemes providing that barrier on the
++		 * various architectures:
++		 * - mm ? switch_mm() : mmdrop() for x86, s390, sparc, PowerPC.
++		 *   switch_mm() rely on membarrier_arch_switch_mm() on PowerPC.
++		 * - finish_lock_switch() for weakly-ordered
++		 *   architectures where spin_unlock is a full barrier,
++		 * - switch_to() for arm64 (weakly-ordered, spin_unlock
++		 *   is a RELEASE barrier),
++		 */
++		++*switch_count;
++
++		psi_sched_switch(prev, next, !task_on_rq_queued(prev));
++
++		trace_sched_switch(sched_mode & SM_MASK_PREEMPT, prev, next, prev_state);
++
++		/* Also unlocks the rq: */
++		rq = context_switch(rq, prev, next);
++	} else {
++		__balance_callbacks(rq);
++		raw_spin_unlock_irq(&rq->lock);
++	}
++
++#ifdef CONFIG_SCHED_SMT
++	sg_balance(rq);
++#endif
++}
++
++void __noreturn do_task_dead(void)
++{
++	/* Causes final put_task_struct in finish_task_switch(): */
++	set_special_state(TASK_DEAD);
++
++	/* Tell freezer to ignore us: */
++	current->flags |= PF_NOFREEZE;
++
++	__schedule(SM_NONE);
++	BUG();
++
++	/* Avoid "noreturn function does return" - but don't continue if BUG() is a NOP: */
++	for (;;)
++		cpu_relax();
++}
++
++static inline void sched_submit_work(struct task_struct *tsk)
++{
++	unsigned int task_flags;
++
++	if (task_is_running(tsk))
++		return;
++
++	task_flags = tsk->flags;
++	/*
++	 * If a worker goes to sleep, notify and ask workqueue whether it
++	 * wants to wake up a task to maintain concurrency.
++	 */
++	if (task_flags & (PF_WQ_WORKER | PF_IO_WORKER)) {
++		if (task_flags & PF_WQ_WORKER)
++			wq_worker_sleeping(tsk);
++		else
++			io_wq_worker_sleeping(tsk);
++	}
++
++	/*
++	 * spinlock and rwlock must not flush block requests.  This will
++	 * deadlock if the callback attempts to acquire a lock which is
++	 * already acquired.
++	 */
++	SCHED_WARN_ON(current->__state & TASK_RTLOCK_WAIT);
++
++	/*
++	 * If we are going to sleep and we have plugged IO queued,
++	 * make sure to submit it to avoid deadlocks.
++	 */
++	blk_flush_plug(tsk->plug, true);
++}
++
++static void sched_update_worker(struct task_struct *tsk)
++{
++	if (tsk->flags & (PF_WQ_WORKER | PF_IO_WORKER)) {
++		if (tsk->flags & PF_WQ_WORKER)
++			wq_worker_running(tsk);
++		else
++			io_wq_worker_running(tsk);
++	}
++}
++
++asmlinkage __visible void __sched schedule(void)
++{
++	struct task_struct *tsk = current;
++
++	sched_submit_work(tsk);
++	do {
++		preempt_disable();
++		__schedule(SM_NONE);
++		sched_preempt_enable_no_resched();
++	} while (need_resched());
++	sched_update_worker(tsk);
++}
++EXPORT_SYMBOL(schedule);
++
++/*
++ * synchronize_rcu_tasks() makes sure that no task is stuck in preempted
++ * state (have scheduled out non-voluntarily) by making sure that all
++ * tasks have either left the run queue or have gone into user space.
++ * As idle tasks do not do either, they must not ever be preempted
++ * (schedule out non-voluntarily).
++ *
++ * schedule_idle() is similar to schedule_preempt_disable() except that it
++ * never enables preemption because it does not call sched_submit_work().
++ */
++void __sched schedule_idle(void)
++{
++	/*
++	 * As this skips calling sched_submit_work(), which the idle task does
++	 * regardless because that function is a nop when the task is in a
++	 * TASK_RUNNING state, make sure this isn't used someplace that the
++	 * current task can be in any other state. Note, idle is always in the
++	 * TASK_RUNNING state.
++	 */
++	WARN_ON_ONCE(current->__state);
++	do {
++		__schedule(SM_NONE);
++	} while (need_resched());
++}
++
++#if defined(CONFIG_CONTEXT_TRACKING_USER) && !defined(CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK)
++asmlinkage __visible void __sched schedule_user(void)
++{
++	/*
++	 * If we come here after a random call to set_need_resched(),
++	 * or we have been woken up remotely but the IPI has not yet arrived,
++	 * we haven't yet exited the RCU idle mode. Do it here manually until
++	 * we find a better solution.
++	 *
++	 * NB: There are buggy callers of this function.  Ideally we
++	 * should warn if prev_state != CONTEXT_USER, but that will trigger
++	 * too frequently to make sense yet.
++	 */
++	enum ctx_state prev_state = exception_enter();
++	schedule();
++	exception_exit(prev_state);
++}
++#endif
++
++/**
++ * schedule_preempt_disabled - called with preemption disabled
++ *
++ * Returns with preemption disabled. Note: preempt_count must be 1
++ */
++void __sched schedule_preempt_disabled(void)
++{
++	sched_preempt_enable_no_resched();
++	schedule();
++	preempt_disable();
++}
++
++#ifdef CONFIG_PREEMPT_RT
++void __sched notrace schedule_rtlock(void)
++{
++	do {
++		preempt_disable();
++		__schedule(SM_RTLOCK_WAIT);
++		sched_preempt_enable_no_resched();
++	} while (need_resched());
++}
++NOKPROBE_SYMBOL(schedule_rtlock);
++#endif
++
++static void __sched notrace preempt_schedule_common(void)
++{
++	do {
++		/*
++		 * Because the function tracer can trace preempt_count_sub()
++		 * and it also uses preempt_enable/disable_notrace(), if
++		 * NEED_RESCHED is set, the preempt_enable_notrace() called
++		 * by the function tracer will call this function again and
++		 * cause infinite recursion.
++		 *
++		 * Preemption must be disabled here before the function
++		 * tracer can trace. Break up preempt_disable() into two
++		 * calls. One to disable preemption without fear of being
++		 * traced. The other to still record the preemption latency,
++		 * which can also be traced by the function tracer.
++		 */
++		preempt_disable_notrace();
++		preempt_latency_start(1);
++		__schedule(SM_PREEMPT);
++		preempt_latency_stop(1);
++		preempt_enable_no_resched_notrace();
++
++		/*
++		 * Check again in case we missed a preemption opportunity
++		 * between schedule and now.
++		 */
++	} while (need_resched());
++}
++
++#ifdef CONFIG_PREEMPTION
++/*
++ * This is the entry point to schedule() from in-kernel preemption
++ * off of preempt_enable.
++ */
++asmlinkage __visible void __sched notrace preempt_schedule(void)
++{
++	/*
++	 * If there is a non-zero preempt_count or interrupts are disabled,
++	 * we do not want to preempt the current task. Just return..
++	 */
++	if (likely(!preemptible()))
++		return;
++
++	preempt_schedule_common();
++}
++NOKPROBE_SYMBOL(preempt_schedule);
++EXPORT_SYMBOL(preempt_schedule);
++
++#ifdef CONFIG_PREEMPT_DYNAMIC
++#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
++#ifndef preempt_schedule_dynamic_enabled
++#define preempt_schedule_dynamic_enabled	preempt_schedule
++#define preempt_schedule_dynamic_disabled	NULL
++#endif
++DEFINE_STATIC_CALL(preempt_schedule, preempt_schedule_dynamic_enabled);
++EXPORT_STATIC_CALL_TRAMP(preempt_schedule);
++#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
++static DEFINE_STATIC_KEY_TRUE(sk_dynamic_preempt_schedule);
++void __sched notrace dynamic_preempt_schedule(void)
++{
++	if (!static_branch_unlikely(&sk_dynamic_preempt_schedule))
++		return;
++	preempt_schedule();
++}
++NOKPROBE_SYMBOL(dynamic_preempt_schedule);
++EXPORT_SYMBOL(dynamic_preempt_schedule);
++#endif
++#endif
++
++/**
++ * preempt_schedule_notrace - preempt_schedule called by tracing
++ *
++ * The tracing infrastructure uses preempt_enable_notrace to prevent
++ * recursion and tracing preempt enabling caused by the tracing
++ * infrastructure itself. But as tracing can happen in areas coming
++ * from userspace or just about to enter userspace, a preempt enable
++ * can occur before user_exit() is called. This will cause the scheduler
++ * to be called when the system is still in usermode.
++ *
++ * To prevent this, the preempt_enable_notrace will use this function
++ * instead of preempt_schedule() to exit user context if needed before
++ * calling the scheduler.
++ */
++asmlinkage __visible void __sched notrace preempt_schedule_notrace(void)
++{
++	enum ctx_state prev_ctx;
++
++	if (likely(!preemptible()))
++		return;
++
++	do {
++		/*
++		 * Because the function tracer can trace preempt_count_sub()
++		 * and it also uses preempt_enable/disable_notrace(), if
++		 * NEED_RESCHED is set, the preempt_enable_notrace() called
++		 * by the function tracer will call this function again and
++		 * cause infinite recursion.
++		 *
++		 * Preemption must be disabled here before the function
++		 * tracer can trace. Break up preempt_disable() into two
++		 * calls. One to disable preemption without fear of being
++		 * traced. The other to still record the preemption latency,
++		 * which can also be traced by the function tracer.
++		 */
++		preempt_disable_notrace();
++		preempt_latency_start(1);
++		/*
++		 * Needs preempt disabled in case user_exit() is traced
++		 * and the tracer calls preempt_enable_notrace() causing
++		 * an infinite recursion.
++		 */
++		prev_ctx = exception_enter();
++		__schedule(SM_PREEMPT);
++		exception_exit(prev_ctx);
++
++		preempt_latency_stop(1);
++		preempt_enable_no_resched_notrace();
++	} while (need_resched());
++}
++EXPORT_SYMBOL_GPL(preempt_schedule_notrace);
++
++#ifdef CONFIG_PREEMPT_DYNAMIC
++#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
++#ifndef preempt_schedule_notrace_dynamic_enabled
++#define preempt_schedule_notrace_dynamic_enabled	preempt_schedule_notrace
++#define preempt_schedule_notrace_dynamic_disabled	NULL
++#endif
++DEFINE_STATIC_CALL(preempt_schedule_notrace, preempt_schedule_notrace_dynamic_enabled);
++EXPORT_STATIC_CALL_TRAMP(preempt_schedule_notrace);
++#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
++static DEFINE_STATIC_KEY_TRUE(sk_dynamic_preempt_schedule_notrace);
++void __sched notrace dynamic_preempt_schedule_notrace(void)
++{
++	if (!static_branch_unlikely(&sk_dynamic_preempt_schedule_notrace))
++		return;
++	preempt_schedule_notrace();
++}
++NOKPROBE_SYMBOL(dynamic_preempt_schedule_notrace);
++EXPORT_SYMBOL(dynamic_preempt_schedule_notrace);
++#endif
++#endif
++
++#endif /* CONFIG_PREEMPTION */
++
++/*
++ * This is the entry point to schedule() from kernel preemption
++ * off of irq context.
++ * Note, that this is called and return with irqs disabled. This will
++ * protect us against recursive calling from irq.
++ */
++asmlinkage __visible void __sched preempt_schedule_irq(void)
++{
++	enum ctx_state prev_state;
++
++	/* Catch callers which need to be fixed */
++	BUG_ON(preempt_count() || !irqs_disabled());
++
++	prev_state = exception_enter();
++
++	do {
++		preempt_disable();
++		local_irq_enable();
++		__schedule(SM_PREEMPT);
++		local_irq_disable();
++		sched_preempt_enable_no_resched();
++	} while (need_resched());
++
++	exception_exit(prev_state);
++}
++
++int default_wake_function(wait_queue_entry_t *curr, unsigned mode, int wake_flags,
++			  void *key)
++{
++	WARN_ON_ONCE(IS_ENABLED(CONFIG_SCHED_DEBUG) && wake_flags & ~WF_SYNC);
++	return try_to_wake_up(curr->private, mode, wake_flags);
++}
++EXPORT_SYMBOL(default_wake_function);
++
++static inline void check_task_changed(struct task_struct *p, struct rq *rq)
++{
++	int idx;
++
++	/* Trigger resched if task sched_prio has been modified. */
++	if (task_on_rq_queued(p) && (idx = task_sched_prio_idx(p, rq)) != p->sq_idx) {
++		requeue_task(p, rq, idx);
++		check_preempt_curr(rq);
++	}
++}
++
++static void __setscheduler_prio(struct task_struct *p, int prio)
++{
++	p->prio = prio;
++}
++
++#ifdef CONFIG_RT_MUTEXES
++
++static inline int __rt_effective_prio(struct task_struct *pi_task, int prio)
++{
++	if (pi_task)
++		prio = min(prio, pi_task->prio);
++
++	return prio;
++}
++
++static inline int rt_effective_prio(struct task_struct *p, int prio)
++{
++	struct task_struct *pi_task = rt_mutex_get_top_task(p);
++
++	return __rt_effective_prio(pi_task, prio);
++}
++
++/*
++ * rt_mutex_setprio - set the current priority of a task
++ * @p: task to boost
++ * @pi_task: donor task
++ *
++ * This function changes the 'effective' priority of a task. It does
++ * not touch ->normal_prio like __setscheduler().
++ *
++ * Used by the rt_mutex code to implement priority inheritance
++ * logic. Call site only calls if the priority of the task changed.
++ */
++void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task)
++{
++	int prio;
++	struct rq *rq;
++	raw_spinlock_t *lock;
++
++	/* XXX used to be waiter->prio, not waiter->task->prio */
++	prio = __rt_effective_prio(pi_task, p->normal_prio);
++
++	/*
++	 * If nothing changed; bail early.
++	 */
++	if (p->pi_top_task == pi_task && prio == p->prio)
++		return;
++
++	rq = __task_access_lock(p, &lock);
++	/*
++	 * Set under pi_lock && rq->lock, such that the value can be used under
++	 * either lock.
++	 *
++	 * Note that there is loads of tricky to make this pointer cache work
++	 * right. rt_mutex_slowunlock()+rt_mutex_postunlock() work together to
++	 * ensure a task is de-boosted (pi_task is set to NULL) before the
++	 * task is allowed to run again (and can exit). This ensures the pointer
++	 * points to a blocked task -- which guarantees the task is present.
++	 */
++	p->pi_top_task = pi_task;
++
++	/*
++	 * For FIFO/RR we only need to set prio, if that matches we're done.
++	 */
++	if (prio == p->prio)
++		goto out_unlock;
++
++	/*
++	 * Idle task boosting is a nono in general. There is one
++	 * exception, when PREEMPT_RT and NOHZ is active:
++	 *
++	 * The idle task calls get_next_timer_interrupt() and holds
++	 * the timer wheel base->lock on the CPU and another CPU wants
++	 * to access the timer (probably to cancel it). We can safely
++	 * ignore the boosting request, as the idle CPU runs this code
++	 * with interrupts disabled and will complete the lock
++	 * protected section without being interrupted. So there is no
++	 * real need to boost.
++	 */
++	if (unlikely(p == rq->idle)) {
++		WARN_ON(p != rq->curr);
++		WARN_ON(p->pi_blocked_on);
++		goto out_unlock;
++	}
++
++	trace_sched_pi_setprio(p, pi_task);
++
++	__setscheduler_prio(p, prio);
++
++	check_task_changed(p, rq);
++out_unlock:
++	/* Avoid rq from going away on us: */
++	preempt_disable();
++
++	__balance_callbacks(rq);
++	__task_access_unlock(p, lock);
++
++	preempt_enable();
++}
++#else
++static inline int rt_effective_prio(struct task_struct *p, int prio)
++{
++	return prio;
++}
++#endif
++
++void set_user_nice(struct task_struct *p, long nice)
++{
++	unsigned long flags;
++	struct rq *rq;
++	raw_spinlock_t *lock;
++
++	if (task_nice(p) == nice || nice < MIN_NICE || nice > MAX_NICE)
++		return;
++	/*
++	 * We have to be careful, if called from sys_setpriority(),
++	 * the task might be in the middle of scheduling on another CPU.
++	 */
++	raw_spin_lock_irqsave(&p->pi_lock, flags);
++	rq = __task_access_lock(p, &lock);
++
++	p->static_prio = NICE_TO_PRIO(nice);
++	/*
++	 * The RT priorities are set via sched_setscheduler(), but we still
++	 * allow the 'normal' nice value to be set - but as expected
++	 * it won't have any effect on scheduling until the task is
++	 * not SCHED_NORMAL/SCHED_BATCH:
++	 */
++	if (task_has_rt_policy(p))
++		goto out_unlock;
++
++	p->prio = effective_prio(p);
++
++	check_task_changed(p, rq);
++out_unlock:
++	__task_access_unlock(p, lock);
++	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++}
++EXPORT_SYMBOL(set_user_nice);
++
++/*
++ * is_nice_reduction - check if nice value is an actual reduction
++ *
++ * Similar to can_nice() but does not perform a capability check.
++ *
++ * @p: task
++ * @nice: nice value
++ */
++static bool is_nice_reduction(const struct task_struct *p, const int nice)
++{
++	/* Convert nice value [19,-20] to rlimit style value [1,40]: */
++	int nice_rlim = nice_to_rlimit(nice);
++
++	return (nice_rlim <= task_rlimit(p, RLIMIT_NICE));
++}
++
++/*
++ * can_nice - check if a task can reduce its nice value
++ * @p: task
++ * @nice: nice value
++ */
++int can_nice(const struct task_struct *p, const int nice)
++{
++	return is_nice_reduction(p, nice) || capable(CAP_SYS_NICE);
++}
++
++#ifdef __ARCH_WANT_SYS_NICE
++
++/*
++ * sys_nice - change the priority of the current process.
++ * @increment: priority increment
++ *
++ * sys_setpriority is a more generic, but much slower function that
++ * does similar things.
++ */
++SYSCALL_DEFINE1(nice, int, increment)
++{
++	long nice, retval;
++
++	/*
++	 * Setpriority might change our priority at the same moment.
++	 * We don't have to worry. Conceptually one call occurs first
++	 * and we have a single winner.
++	 */
++
++	increment = clamp(increment, -NICE_WIDTH, NICE_WIDTH);
++	nice = task_nice(current) + increment;
++
++	nice = clamp_val(nice, MIN_NICE, MAX_NICE);
++	if (increment < 0 && !can_nice(current, nice))
++		return -EPERM;
++
++	retval = security_task_setnice(current, nice);
++	if (retval)
++		return retval;
++
++	set_user_nice(current, nice);
++	return 0;
++}
++
++#endif
++
++/**
++ * task_prio - return the priority value of a given task.
++ * @p: the task in question.
++ *
++ * Return: The priority value as seen by users in /proc.
++ *
++ * sched policy         return value   kernel prio    user prio/nice
++ *
++ * (BMQ)normal, batch, idle[0 ... 53]  [100 ... 139]          0/[-20 ... 19]/[-7 ... 7]
++ * (PDS)normal, batch, idle[0 ... 39]            100          0/[-20 ... 19]
++ * fifo, rr             [-1 ... -100]     [99 ... 0]  [0 ... 99]
++ */
++int task_prio(const struct task_struct *p)
++{
++	return (p->prio < MAX_RT_PRIO) ? p->prio - MAX_RT_PRIO :
++		task_sched_prio_normal(p, task_rq(p));
++}
++
++/**
++ * idle_cpu - is a given CPU idle currently?
++ * @cpu: the processor in question.
++ *
++ * Return: 1 if the CPU is currently idle. 0 otherwise.
++ */
++int idle_cpu(int cpu)
++{
++	struct rq *rq = cpu_rq(cpu);
++
++	if (rq->curr != rq->idle)
++		return 0;
++
++	if (rq->nr_running)
++		return 0;
++
++#ifdef CONFIG_SMP
++	if (rq->ttwu_pending)
++		return 0;
++#endif
++
++	return 1;
++}
++
++/**
++ * idle_task - return the idle task for a given CPU.
++ * @cpu: the processor in question.
++ *
++ * Return: The idle task for the cpu @cpu.
++ */
++struct task_struct *idle_task(int cpu)
++{
++	return cpu_rq(cpu)->idle;
++}
++
++/**
++ * find_process_by_pid - find a process with a matching PID value.
++ * @pid: the pid in question.
++ *
++ * The task of @pid, if found. %NULL otherwise.
++ */
++static inline struct task_struct *find_process_by_pid(pid_t pid)
++{
++	return pid ? find_task_by_vpid(pid) : current;
++}
++
++/*
++ * sched_setparam() passes in -1 for its policy, to let the functions
++ * it calls know not to change it.
++ */
++#define SETPARAM_POLICY -1
++
++static void __setscheduler_params(struct task_struct *p,
++		const struct sched_attr *attr)
++{
++	int policy = attr->sched_policy;
++
++	if (policy == SETPARAM_POLICY)
++		policy = p->policy;
++
++	p->policy = policy;
++
++	/*
++	 * allow normal nice value to be set, but will not have any
++	 * effect on scheduling until the task not SCHED_NORMAL/
++	 * SCHED_BATCH
++	 */
++	p->static_prio = NICE_TO_PRIO(attr->sched_nice);
++
++	/*
++	 * __sched_setscheduler() ensures attr->sched_priority == 0 when
++	 * !rt_policy. Always setting this ensures that things like
++	 * getparam()/getattr() don't report silly values for !rt tasks.
++	 */
++	p->rt_priority = attr->sched_priority;
++	p->normal_prio = normal_prio(p);
++}
++
++/*
++ * check the target process has a UID that matches the current process's
++ */
++static bool check_same_owner(struct task_struct *p)
++{
++	const struct cred *cred = current_cred(), *pcred;
++	bool match;
++
++	rcu_read_lock();
++	pcred = __task_cred(p);
++	match = (uid_eq(cred->euid, pcred->euid) ||
++		 uid_eq(cred->euid, pcred->uid));
++	rcu_read_unlock();
++	return match;
++}
++
++/*
++ * Allow unprivileged RT tasks to decrease priority.
++ * Only issue a capable test if needed and only once to avoid an audit
++ * event on permitted non-privileged operations:
++ */
++static int user_check_sched_setscheduler(struct task_struct *p,
++					 const struct sched_attr *attr,
++					 int policy, int reset_on_fork)
++{
++	if (rt_policy(policy)) {
++		unsigned long rlim_rtprio = task_rlimit(p, RLIMIT_RTPRIO);
++
++		/* Can't set/change the rt policy: */
++		if (policy != p->policy && !rlim_rtprio)
++			goto req_priv;
++
++		/* Can't increase priority: */
++		if (attr->sched_priority > p->rt_priority &&
++		    attr->sched_priority > rlim_rtprio)
++			goto req_priv;
++	}
++
++	/* Can't change other user's priorities: */
++	if (!check_same_owner(p))
++		goto req_priv;
++
++	/* Normal users shall not reset the sched_reset_on_fork flag: */
++	if (p->sched_reset_on_fork && !reset_on_fork)
++		goto req_priv;
++
++	return 0;
++
++req_priv:
++	if (!capable(CAP_SYS_NICE))
++		return -EPERM;
++
++	return 0;
++}
++
++static int __sched_setscheduler(struct task_struct *p,
++				const struct sched_attr *attr,
++				bool user, bool pi)
++{
++	const struct sched_attr dl_squash_attr = {
++		.size		= sizeof(struct sched_attr),
++		.sched_policy	= SCHED_FIFO,
++		.sched_nice	= 0,
++		.sched_priority = 99,
++	};
++	int oldpolicy = -1, policy = attr->sched_policy;
++	int retval, newprio;
++	struct callback_head *head;
++	unsigned long flags;
++	struct rq *rq;
++	int reset_on_fork;
++	raw_spinlock_t *lock;
++
++	/* The pi code expects interrupts enabled */
++	BUG_ON(pi && in_interrupt());
++
++	/*
++	 * Alt schedule FW supports SCHED_DEADLINE by squash it as prio 0 SCHED_FIFO
++	 */
++	if (unlikely(SCHED_DEADLINE == policy)) {
++		attr = &dl_squash_attr;
++		policy = attr->sched_policy;
++	}
++recheck:
++	/* Double check policy once rq lock held */
++	if (policy < 0) {
++		reset_on_fork = p->sched_reset_on_fork;
++		policy = oldpolicy = p->policy;
++	} else {
++		reset_on_fork = !!(attr->sched_flags & SCHED_RESET_ON_FORK);
++
++		if (policy > SCHED_IDLE)
++			return -EINVAL;
++	}
++
++	if (attr->sched_flags & ~(SCHED_FLAG_ALL))
++		return -EINVAL;
++
++	/*
++	 * Valid priorities for SCHED_FIFO and SCHED_RR are
++	 * 1..MAX_RT_PRIO-1, valid priority for SCHED_NORMAL and
++	 * SCHED_BATCH and SCHED_IDLE is 0.
++	 */
++	if (attr->sched_priority < 0 ||
++	    (p->mm && attr->sched_priority > MAX_RT_PRIO - 1) ||
++	    (!p->mm && attr->sched_priority > MAX_RT_PRIO - 1))
++		return -EINVAL;
++	if ((SCHED_RR == policy || SCHED_FIFO == policy) !=
++	    (attr->sched_priority != 0))
++		return -EINVAL;
++
++	if (user) {
++		retval = user_check_sched_setscheduler(p, attr, policy, reset_on_fork);
++		if (retval)
++			return retval;
++
++		retval = security_task_setscheduler(p);
++		if (retval)
++			return retval;
++	}
++
++	if (pi)
++		cpuset_read_lock();
++
++	/*
++	 * Make sure no PI-waiters arrive (or leave) while we are
++	 * changing the priority of the task:
++	 */
++	raw_spin_lock_irqsave(&p->pi_lock, flags);
++
++	/*
++	 * To be able to change p->policy safely, task_access_lock()
++	 * must be called.
++	 * IF use task_access_lock() here:
++	 * For the task p which is not running, reading rq->stop is
++	 * racy but acceptable as ->stop doesn't change much.
++	 * An enhancemnet can be made to read rq->stop saftly.
++	 */
++	rq = __task_access_lock(p, &lock);
++
++	/*
++	 * Changing the policy of the stop threads its a very bad idea
++	 */
++	if (p == rq->stop) {
++		retval = -EINVAL;
++		goto unlock;
++	}
++
++	/*
++	 * If not changing anything there's no need to proceed further:
++	 */
++	if (unlikely(policy == p->policy)) {
++		if (rt_policy(policy) && attr->sched_priority != p->rt_priority)
++			goto change;
++		if (!rt_policy(policy) &&
++		    NICE_TO_PRIO(attr->sched_nice) != p->static_prio)
++			goto change;
++
++		p->sched_reset_on_fork = reset_on_fork;
++		retval = 0;
++		goto unlock;
++	}
++change:
++
++	/* Re-check policy now with rq lock held */
++	if (unlikely(oldpolicy != -1 && oldpolicy != p->policy)) {
++		policy = oldpolicy = -1;
++		__task_access_unlock(p, lock);
++		raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++		if (pi)
++			cpuset_read_unlock();
++		goto recheck;
++	}
++
++	p->sched_reset_on_fork = reset_on_fork;
++
++	newprio = __normal_prio(policy, attr->sched_priority, NICE_TO_PRIO(attr->sched_nice));
++	if (pi) {
++		/*
++		 * Take priority boosted tasks into account. If the new
++		 * effective priority is unchanged, we just store the new
++		 * normal parameters and do not touch the scheduler class and
++		 * the runqueue. This will be done when the task deboost
++		 * itself.
++		 */
++		newprio = rt_effective_prio(p, newprio);
++	}
++
++	if (!(attr->sched_flags & SCHED_FLAG_KEEP_PARAMS)) {
++		__setscheduler_params(p, attr);
++		__setscheduler_prio(p, newprio);
++	}
++
++	check_task_changed(p, rq);
++
++	/* Avoid rq from going away on us: */
++	preempt_disable();
++	head = splice_balance_callbacks(rq);
++	__task_access_unlock(p, lock);
++	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++
++	if (pi) {
++		cpuset_read_unlock();
++		rt_mutex_adjust_pi(p);
++	}
++
++	/* Run balance callbacks after we've adjusted the PI chain: */
++	balance_callbacks(rq, head);
++	preempt_enable();
++
++	return 0;
++
++unlock:
++	__task_access_unlock(p, lock);
++	raw_spin_unlock_irqrestore(&p->pi_lock, flags);
++	if (pi)
++		cpuset_read_unlock();
++	return retval;
++}
++
++static int _sched_setscheduler(struct task_struct *p, int policy,
++			       const struct sched_param *param, bool check)
++{
++	struct sched_attr attr = {
++		.sched_policy   = policy,
++		.sched_priority = param->sched_priority,
++		.sched_nice     = PRIO_TO_NICE(p->static_prio),
++	};
++
++	/* Fixup the legacy SCHED_RESET_ON_FORK hack. */
++	if ((policy != SETPARAM_POLICY) && (policy & SCHED_RESET_ON_FORK)) {
++		attr.sched_flags |= SCHED_FLAG_RESET_ON_FORK;
++		policy &= ~SCHED_RESET_ON_FORK;
++		attr.sched_policy = policy;
++	}
++
++	return __sched_setscheduler(p, &attr, check, true);
++}
++
++/**
++ * sched_setscheduler - change the scheduling policy and/or RT priority of a thread.
++ * @p: the task in question.
++ * @policy: new policy.
++ * @param: structure containing the new RT priority.
++ *
++ * Use sched_set_fifo(), read its comment.
++ *
++ * Return: 0 on success. An error code otherwise.
++ *
++ * NOTE that the task may be already dead.
++ */
++int sched_setscheduler(struct task_struct *p, int policy,
++		       const struct sched_param *param)
++{
++	return _sched_setscheduler(p, policy, param, true);
++}
++
++int sched_setattr(struct task_struct *p, const struct sched_attr *attr)
++{
++	return __sched_setscheduler(p, attr, true, true);
++}
++
++int sched_setattr_nocheck(struct task_struct *p, const struct sched_attr *attr)
++{
++	return __sched_setscheduler(p, attr, false, true);
++}
++EXPORT_SYMBOL_GPL(sched_setattr_nocheck);
++
++/**
++ * sched_setscheduler_nocheck - change the scheduling policy and/or RT priority of a thread from kernelspace.
++ * @p: the task in question.
++ * @policy: new policy.
++ * @param: structure containing the new RT priority.
++ *
++ * Just like sched_setscheduler, only don't bother checking if the
++ * current context has permission.  For example, this is needed in
++ * stop_machine(): we create temporary high priority worker threads,
++ * but our caller might not have that capability.
++ *
++ * Return: 0 on success. An error code otherwise.
++ */
++int sched_setscheduler_nocheck(struct task_struct *p, int policy,
++			       const struct sched_param *param)
++{
++	return _sched_setscheduler(p, policy, param, false);
++}
++
++/*
++ * SCHED_FIFO is a broken scheduler model; that is, it is fundamentally
++ * incapable of resource management, which is the one thing an OS really should
++ * be doing.
++ *
++ * This is of course the reason it is limited to privileged users only.
++ *
++ * Worse still; it is fundamentally impossible to compose static priority
++ * workloads. You cannot take two correctly working static prio workloads
++ * and smash them together and still expect them to work.
++ *
++ * For this reason 'all' FIFO tasks the kernel creates are basically at:
++ *
++ *   MAX_RT_PRIO / 2
++ *
++ * The administrator _MUST_ configure the system, the kernel simply doesn't
++ * know enough information to make a sensible choice.
++ */
++void sched_set_fifo(struct task_struct *p)
++{
++	struct sched_param sp = { .sched_priority = MAX_RT_PRIO / 2 };
++	WARN_ON_ONCE(sched_setscheduler_nocheck(p, SCHED_FIFO, &sp) != 0);
++}
++EXPORT_SYMBOL_GPL(sched_set_fifo);
++
++/*
++ * For when you don't much care about FIFO, but want to be above SCHED_NORMAL.
++ */
++void sched_set_fifo_low(struct task_struct *p)
++{
++	struct sched_param sp = { .sched_priority = 1 };
++	WARN_ON_ONCE(sched_setscheduler_nocheck(p, SCHED_FIFO, &sp) != 0);
++}
++EXPORT_SYMBOL_GPL(sched_set_fifo_low);
++
++void sched_set_normal(struct task_struct *p, int nice)
++{
++	struct sched_attr attr = {
++		.sched_policy = SCHED_NORMAL,
++		.sched_nice = nice,
++	};
++	WARN_ON_ONCE(sched_setattr_nocheck(p, &attr) != 0);
++}
++EXPORT_SYMBOL_GPL(sched_set_normal);
++
++static int
++do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param)
++{
++	struct sched_param lparam;
++	struct task_struct *p;
++	int retval;
++
++	if (!param || pid < 0)
++		return -EINVAL;
++	if (copy_from_user(&lparam, param, sizeof(struct sched_param)))
++		return -EFAULT;
++
++	rcu_read_lock();
++	retval = -ESRCH;
++	p = find_process_by_pid(pid);
++	if (likely(p))
++		get_task_struct(p);
++	rcu_read_unlock();
++
++	if (likely(p)) {
++		retval = sched_setscheduler(p, policy, &lparam);
++		put_task_struct(p);
++	}
++
++	return retval;
++}
++
++/*
++ * Mimics kernel/events/core.c perf_copy_attr().
++ */
++static int sched_copy_attr(struct sched_attr __user *uattr, struct sched_attr *attr)
++{
++	u32 size;
++	int ret;
++
++	/* Zero the full structure, so that a short copy will be nice: */
++	memset(attr, 0, sizeof(*attr));
++
++	ret = get_user(size, &uattr->size);
++	if (ret)
++		return ret;
++
++	/* ABI compatibility quirk: */
++	if (!size)
++		size = SCHED_ATTR_SIZE_VER0;
++
++	if (size < SCHED_ATTR_SIZE_VER0 || size > PAGE_SIZE)
++		goto err_size;
++
++	ret = copy_struct_from_user(attr, sizeof(*attr), uattr, size);
++	if (ret) {
++		if (ret == -E2BIG)
++			goto err_size;
++		return ret;
++	}
++
++	/*
++	 * XXX: Do we want to be lenient like existing syscalls; or do we want
++	 * to be strict and return an error on out-of-bounds values?
++	 */
++	attr->sched_nice = clamp(attr->sched_nice, -20, 19);
++
++	/* sched/core.c uses zero here but we already know ret is zero */
++	return 0;
++
++err_size:
++	put_user(sizeof(*attr), &uattr->size);
++	return -E2BIG;
++}
++
++/**
++ * sys_sched_setscheduler - set/change the scheduler policy and RT priority
++ * @pid: the pid in question.
++ * @policy: new policy.
++ *
++ * Return: 0 on success. An error code otherwise.
++ * @param: structure containing the new RT priority.
++ */
++SYSCALL_DEFINE3(sched_setscheduler, pid_t, pid, int, policy, struct sched_param __user *, param)
++{
++	if (policy < 0)
++		return -EINVAL;
++
++	return do_sched_setscheduler(pid, policy, param);
++}
++
++/**
++ * sys_sched_setparam - set/change the RT priority of a thread
++ * @pid: the pid in question.
++ * @param: structure containing the new RT priority.
++ *
++ * Return: 0 on success. An error code otherwise.
++ */
++SYSCALL_DEFINE2(sched_setparam, pid_t, pid, struct sched_param __user *, param)
++{
++	return do_sched_setscheduler(pid, SETPARAM_POLICY, param);
++}
++
++/**
++ * sys_sched_setattr - same as above, but with extended sched_attr
++ * @pid: the pid in question.
++ * @uattr: structure containing the extended parameters.
++ */
++SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr,
++			       unsigned int, flags)
++{
++	struct sched_attr attr;
++	struct task_struct *p;
++	int retval;
++
++	if (!uattr || pid < 0 || flags)
++		return -EINVAL;
++
++	retval = sched_copy_attr(uattr, &attr);
++	if (retval)
++		return retval;
++
++	if ((int)attr.sched_policy < 0)
++		return -EINVAL;
++
++	rcu_read_lock();
++	retval = -ESRCH;
++	p = find_process_by_pid(pid);
++	if (likely(p))
++		get_task_struct(p);
++	rcu_read_unlock();
++
++	if (likely(p)) {
++		retval = sched_setattr(p, &attr);
++		put_task_struct(p);
++	}
++
++	return retval;
++}
++
++/**
++ * sys_sched_getscheduler - get the policy (scheduling class) of a thread
++ * @pid: the pid in question.
++ *
++ * Return: On success, the policy of the thread. Otherwise, a negative error
++ * code.
++ */
++SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid)
++{
++	struct task_struct *p;
++	int retval = -EINVAL;
++
++	if (pid < 0)
++		goto out_nounlock;
++
++	retval = -ESRCH;
++	rcu_read_lock();
++	p = find_process_by_pid(pid);
++	if (p) {
++		retval = security_task_getscheduler(p);
++		if (!retval)
++			retval = p->policy;
++	}
++	rcu_read_unlock();
++
++out_nounlock:
++	return retval;
++}
++
++/**
++ * sys_sched_getscheduler - get the RT priority of a thread
++ * @pid: the pid in question.
++ * @param: structure containing the RT priority.
++ *
++ * Return: On success, 0 and the RT priority is in @param. Otherwise, an error
++ * code.
++ */
++SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param)
++{
++	struct sched_param lp = { .sched_priority = 0 };
++	struct task_struct *p;
++	int retval = -EINVAL;
++
++	if (!param || pid < 0)
++		goto out_nounlock;
++
++	rcu_read_lock();
++	p = find_process_by_pid(pid);
++	retval = -ESRCH;
++	if (!p)
++		goto out_unlock;
++
++	retval = security_task_getscheduler(p);
++	if (retval)
++		goto out_unlock;
++
++	if (task_has_rt_policy(p))
++		lp.sched_priority = p->rt_priority;
++	rcu_read_unlock();
++
++	/*
++	 * This one might sleep, we cannot do it with a spinlock held ...
++	 */
++	retval = copy_to_user(param, &lp, sizeof(*param)) ? -EFAULT : 0;
++
++out_nounlock:
++	return retval;
++
++out_unlock:
++	rcu_read_unlock();
++	return retval;
++}
++
++/*
++ * Copy the kernel size attribute structure (which might be larger
++ * than what user-space knows about) to user-space.
++ *
++ * Note that all cases are valid: user-space buffer can be larger or
++ * smaller than the kernel-space buffer. The usual case is that both
++ * have the same size.
++ */
++static int
++sched_attr_copy_to_user(struct sched_attr __user *uattr,
++			struct sched_attr *kattr,
++			unsigned int usize)
++{
++	unsigned int ksize = sizeof(*kattr);
++
++	if (!access_ok(uattr, usize))
++		return -EFAULT;
++
++	/*
++	 * sched_getattr() ABI forwards and backwards compatibility:
++	 *
++	 * If usize == ksize then we just copy everything to user-space and all is good.
++	 *
++	 * If usize < ksize then we only copy as much as user-space has space for,
++	 * this keeps ABI compatibility as well. We skip the rest.
++	 *
++	 * If usize > ksize then user-space is using a newer version of the ABI,
++	 * which part the kernel doesn't know about. Just ignore it - tooling can
++	 * detect the kernel's knowledge of attributes from the attr->size value
++	 * which is set to ksize in this case.
++	 */
++	kattr->size = min(usize, ksize);
++
++	if (copy_to_user(uattr, kattr, kattr->size))
++		return -EFAULT;
++
++	return 0;
++}
++
++/**
++ * sys_sched_getattr - similar to sched_getparam, but with sched_attr
++ * @pid: the pid in question.
++ * @uattr: structure containing the extended parameters.
++ * @usize: sizeof(attr) for fwd/bwd comp.
++ * @flags: for future extension.
++ */
++SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,
++		unsigned int, usize, unsigned int, flags)
++{
++	struct sched_attr kattr = { };
++	struct task_struct *p;
++	int retval;
++
++	if (!uattr || pid < 0 || usize > PAGE_SIZE ||
++	    usize < SCHED_ATTR_SIZE_VER0 || flags)
++		return -EINVAL;
++
++	rcu_read_lock();
++	p = find_process_by_pid(pid);
++	retval = -ESRCH;
++	if (!p)
++		goto out_unlock;
++
++	retval = security_task_getscheduler(p);
++	if (retval)
++		goto out_unlock;
++
++	kattr.sched_policy = p->policy;
++	if (p->sched_reset_on_fork)
++		kattr.sched_flags |= SCHED_FLAG_RESET_ON_FORK;
++	if (task_has_rt_policy(p))
++		kattr.sched_priority = p->rt_priority;
++	else
++		kattr.sched_nice = task_nice(p);
++	kattr.sched_flags &= SCHED_FLAG_ALL;
++
++#ifdef CONFIG_UCLAMP_TASK
++	kattr.sched_util_min = p->uclamp_req[UCLAMP_MIN].value;
++	kattr.sched_util_max = p->uclamp_req[UCLAMP_MAX].value;
++#endif
++
++	rcu_read_unlock();
++
++	return sched_attr_copy_to_user(uattr, &kattr, usize);
++
++out_unlock:
++	rcu_read_unlock();
++	return retval;
++}
++
++static int
++__sched_setaffinity(struct task_struct *p, const struct cpumask *mask)
++{
++	int retval;
++	cpumask_var_t cpus_allowed, new_mask;
++
++	if (!alloc_cpumask_var(&cpus_allowed, GFP_KERNEL))
++		return -ENOMEM;
++
++	if (!alloc_cpumask_var(&new_mask, GFP_KERNEL)) {
++		retval = -ENOMEM;
++		goto out_free_cpus_allowed;
++	}
++
++	cpuset_cpus_allowed(p, cpus_allowed);
++	cpumask_and(new_mask, mask, cpus_allowed);
++again:
++	retval = __set_cpus_allowed_ptr(p, new_mask, SCA_CHECK | SCA_USER);
++	if (retval)
++		goto out_free_new_mask;
++
++	cpuset_cpus_allowed(p, cpus_allowed);
++	if (!cpumask_subset(new_mask, cpus_allowed)) {
++		/*
++		 * We must have raced with a concurrent cpuset
++		 * update. Just reset the cpus_allowed to the
++		 * cpuset's cpus_allowed
++		 */
++		cpumask_copy(new_mask, cpus_allowed);
++		goto again;
++	}
++
++out_free_new_mask:
++	free_cpumask_var(new_mask);
++out_free_cpus_allowed:
++	free_cpumask_var(cpus_allowed);
++	return retval;
++}
++
++long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
++{
++	struct task_struct *p;
++	int retval;
++
++	rcu_read_lock();
++
++	p = find_process_by_pid(pid);
++	if (!p) {
++		rcu_read_unlock();
++		return -ESRCH;
++	}
++
++	/* Prevent p going away */
++	get_task_struct(p);
++	rcu_read_unlock();
++
++	if (p->flags & PF_NO_SETAFFINITY) {
++		retval = -EINVAL;
++		goto out_put_task;
++	}
++
++	if (!check_same_owner(p)) {
++		rcu_read_lock();
++		if (!ns_capable(__task_cred(p)->user_ns, CAP_SYS_NICE)) {
++			rcu_read_unlock();
++			retval = -EPERM;
++			goto out_put_task;
++		}
++		rcu_read_unlock();
++	}
++
++	retval = security_task_setscheduler(p);
++	if (retval)
++		goto out_put_task;
++
++	retval = __sched_setaffinity(p, in_mask);
++out_put_task:
++	put_task_struct(p);
++	return retval;
++}
++
++static int get_user_cpu_mask(unsigned long __user *user_mask_ptr, unsigned len,
++			     struct cpumask *new_mask)
++{
++	if (len < cpumask_size())
++		cpumask_clear(new_mask);
++	else if (len > cpumask_size())
++		len = cpumask_size();
++
++	return copy_from_user(new_mask, user_mask_ptr, len) ? -EFAULT : 0;
++}
++
++/**
++ * sys_sched_setaffinity - set the CPU affinity of a process
++ * @pid: pid of the process
++ * @len: length in bytes of the bitmask pointed to by user_mask_ptr
++ * @user_mask_ptr: user-space pointer to the new CPU mask
++ *
++ * Return: 0 on success. An error code otherwise.
++ */
++SYSCALL_DEFINE3(sched_setaffinity, pid_t, pid, unsigned int, len,
++		unsigned long __user *, user_mask_ptr)
++{
++	cpumask_var_t new_mask;
++	int retval;
++
++	if (!alloc_cpumask_var(&new_mask, GFP_KERNEL))
++		return -ENOMEM;
++
++	retval = get_user_cpu_mask(user_mask_ptr, len, new_mask);
++	if (retval == 0)
++		retval = sched_setaffinity(pid, new_mask);
++	free_cpumask_var(new_mask);
++	return retval;
++}
++
++long sched_getaffinity(pid_t pid, cpumask_t *mask)
++{
++	struct task_struct *p;
++	raw_spinlock_t *lock;
++	unsigned long flags;
++	int retval;
++
++	rcu_read_lock();
++
++	retval = -ESRCH;
++	p = find_process_by_pid(pid);
++	if (!p)
++		goto out_unlock;
++
++	retval = security_task_getscheduler(p);
++	if (retval)
++		goto out_unlock;
++
++	task_access_lock_irqsave(p, &lock, &flags);
++	cpumask_and(mask, &p->cpus_mask, cpu_active_mask);
++	task_access_unlock_irqrestore(p, lock, &flags);
++
++out_unlock:
++	rcu_read_unlock();
++
++	return retval;
++}
++
++/**
++ * sys_sched_getaffinity - get the CPU affinity of a process
++ * @pid: pid of the process
++ * @len: length in bytes of the bitmask pointed to by user_mask_ptr
++ * @user_mask_ptr: user-space pointer to hold the current CPU mask
++ *
++ * Return: size of CPU mask copied to user_mask_ptr on success. An
++ * error code otherwise.
++ */
++SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
++		unsigned long __user *, user_mask_ptr)
++{
++	int ret;
++	cpumask_var_t mask;
++
++	if ((len * BITS_PER_BYTE) < nr_cpu_ids)
++		return -EINVAL;
++	if (len & (sizeof(unsigned long)-1))
++		return -EINVAL;
++
++	if (!alloc_cpumask_var(&mask, GFP_KERNEL))
++		return -ENOMEM;
++
++	ret = sched_getaffinity(pid, mask);
++	if (ret == 0) {
++		unsigned int retlen = min_t(size_t, len, cpumask_size());
++
++		if (copy_to_user(user_mask_ptr, mask, retlen))
++			ret = -EFAULT;
++		else
++			ret = retlen;
++	}
++	free_cpumask_var(mask);
++
++	return ret;
++}
++
++static void do_sched_yield(void)
++{
++	struct rq *rq;
++	struct rq_flags rf;
++
++	if (!sched_yield_type)
++		return;
++
++	rq = this_rq_lock_irq(&rf);
++
++	schedstat_inc(rq->yld_count);
++
++	if (1 == sched_yield_type) {
++		if (!rt_task(current))
++			do_sched_yield_type_1(current, rq);
++	} else if (2 == sched_yield_type) {
++		if (rq->nr_running > 1)
++			rq->skip = current;
++	}
++
++	preempt_disable();
++	raw_spin_unlock_irq(&rq->lock);
++	sched_preempt_enable_no_resched();
++
++	schedule();
++}
++
++/**
++ * sys_sched_yield - yield the current processor to other threads.
++ *
++ * This function yields the current CPU to other tasks. If there are no
++ * other threads running on this CPU then this function will return.
++ *
++ * Return: 0.
++ */
++SYSCALL_DEFINE0(sched_yield)
++{
++	do_sched_yield();
++	return 0;
++}
++
++#if !defined(CONFIG_PREEMPTION) || defined(CONFIG_PREEMPT_DYNAMIC)
++int __sched __cond_resched(void)
++{
++	if (should_resched(0)) {
++		preempt_schedule_common();
++		return 1;
++	}
++	/*
++	 * In preemptible kernels, ->rcu_read_lock_nesting tells the tick
++	 * whether the current CPU is in an RCU read-side critical section,
++	 * so the tick can report quiescent states even for CPUs looping
++	 * in kernel context.  In contrast, in non-preemptible kernels,
++	 * RCU readers leave no in-memory hints, which means that CPU-bound
++	 * processes executing in kernel context might never report an
++	 * RCU quiescent state.  Therefore, the following code causes
++	 * cond_resched() to report a quiescent state, but only when RCU
++	 * is in urgent need of one.
++	 */
++#ifndef CONFIG_PREEMPT_RCU
++	rcu_all_qs();
++#endif
++	return 0;
++}
++EXPORT_SYMBOL(__cond_resched);
++#endif
++
++#ifdef CONFIG_PREEMPT_DYNAMIC
++#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
++#define cond_resched_dynamic_enabled	__cond_resched
++#define cond_resched_dynamic_disabled	((void *)&__static_call_return0)
++DEFINE_STATIC_CALL_RET0(cond_resched, __cond_resched);
++EXPORT_STATIC_CALL_TRAMP(cond_resched);
++
++#define might_resched_dynamic_enabled	__cond_resched
++#define might_resched_dynamic_disabled	((void *)&__static_call_return0)
++DEFINE_STATIC_CALL_RET0(might_resched, __cond_resched);
++EXPORT_STATIC_CALL_TRAMP(might_resched);
++#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
++static DEFINE_STATIC_KEY_FALSE(sk_dynamic_cond_resched);
++int __sched dynamic_cond_resched(void)
++{
++	if (!static_branch_unlikely(&sk_dynamic_cond_resched))
++		return 0;
++	return __cond_resched();
++}
++EXPORT_SYMBOL(dynamic_cond_resched);
++
++static DEFINE_STATIC_KEY_FALSE(sk_dynamic_might_resched);
++int __sched dynamic_might_resched(void)
++{
++	if (!static_branch_unlikely(&sk_dynamic_might_resched))
++		return 0;
++	return __cond_resched();
++}
++EXPORT_SYMBOL(dynamic_might_resched);
++#endif
++#endif
++
++/*
++ * __cond_resched_lock() - if a reschedule is pending, drop the given lock,
++ * call schedule, and on return reacquire the lock.
++ *
++ * This works OK both with and without CONFIG_PREEMPTION.  We do strange low-level
++ * operations here to prevent schedule() from being called twice (once via
++ * spin_unlock(), once by hand).
++ */
++int __cond_resched_lock(spinlock_t *lock)
++{
++	int resched = should_resched(PREEMPT_LOCK_OFFSET);
++	int ret = 0;
++
++	lockdep_assert_held(lock);
++
++	if (spin_needbreak(lock) || resched) {
++		spin_unlock(lock);
++		if (!_cond_resched())
++			cpu_relax();
++		ret = 1;
++		spin_lock(lock);
++	}
++	return ret;
++}
++EXPORT_SYMBOL(__cond_resched_lock);
++
++int __cond_resched_rwlock_read(rwlock_t *lock)
++{
++	int resched = should_resched(PREEMPT_LOCK_OFFSET);
++	int ret = 0;
++
++	lockdep_assert_held_read(lock);
++
++	if (rwlock_needbreak(lock) || resched) {
++		read_unlock(lock);
++		if (!_cond_resched())
++			cpu_relax();
++		ret = 1;
++		read_lock(lock);
++	}
++	return ret;
++}
++EXPORT_SYMBOL(__cond_resched_rwlock_read);
++
++int __cond_resched_rwlock_write(rwlock_t *lock)
++{
++	int resched = should_resched(PREEMPT_LOCK_OFFSET);
++	int ret = 0;
++
++	lockdep_assert_held_write(lock);
++
++	if (rwlock_needbreak(lock) || resched) {
++		write_unlock(lock);
++		if (!_cond_resched())
++			cpu_relax();
++		ret = 1;
++		write_lock(lock);
++	}
++	return ret;
++}
++EXPORT_SYMBOL(__cond_resched_rwlock_write);
++
++#ifdef CONFIG_PREEMPT_DYNAMIC
++
++#ifdef CONFIG_GENERIC_ENTRY
++#include <linux/entry-common.h>
++#endif
++
++/*
++ * SC:cond_resched
++ * SC:might_resched
++ * SC:preempt_schedule
++ * SC:preempt_schedule_notrace
++ * SC:irqentry_exit_cond_resched
++ *
++ *
++ * NONE:
++ *   cond_resched               <- __cond_resched
++ *   might_resched              <- RET0
++ *   preempt_schedule           <- NOP
++ *   preempt_schedule_notrace   <- NOP
++ *   irqentry_exit_cond_resched <- NOP
++ *
++ * VOLUNTARY:
++ *   cond_resched               <- __cond_resched
++ *   might_resched              <- __cond_resched
++ *   preempt_schedule           <- NOP
++ *   preempt_schedule_notrace   <- NOP
++ *   irqentry_exit_cond_resched <- NOP
++ *
++ * FULL:
++ *   cond_resched               <- RET0
++ *   might_resched              <- RET0
++ *   preempt_schedule           <- preempt_schedule
++ *   preempt_schedule_notrace   <- preempt_schedule_notrace
++ *   irqentry_exit_cond_resched <- irqentry_exit_cond_resched
++ */
++
++enum {
++	preempt_dynamic_undefined = -1,
++	preempt_dynamic_none,
++	preempt_dynamic_voluntary,
++	preempt_dynamic_full,
++};
++
++int preempt_dynamic_mode = preempt_dynamic_undefined;
++
++int sched_dynamic_mode(const char *str)
++{
++	if (!strcmp(str, "none"))
++		return preempt_dynamic_none;
++
++	if (!strcmp(str, "voluntary"))
++		return preempt_dynamic_voluntary;
++
++	if (!strcmp(str, "full"))
++		return preempt_dynamic_full;
++
++	return -EINVAL;
++}
++
++#if defined(CONFIG_HAVE_PREEMPT_DYNAMIC_CALL)
++#define preempt_dynamic_enable(f)	static_call_update(f, f##_dynamic_enabled)
++#define preempt_dynamic_disable(f)	static_call_update(f, f##_dynamic_disabled)
++#elif defined(CONFIG_HAVE_PREEMPT_DYNAMIC_KEY)
++#define preempt_dynamic_enable(f)	static_key_enable(&sk_dynamic_##f.key)
++#define preempt_dynamic_disable(f)	static_key_disable(&sk_dynamic_##f.key)
++#else
++#error "Unsupported PREEMPT_DYNAMIC mechanism"
++#endif
++
++void sched_dynamic_update(int mode)
++{
++	/*
++	 * Avoid {NONE,VOLUNTARY} -> FULL transitions from ever ending up in
++	 * the ZERO state, which is invalid.
++	 */
++	preempt_dynamic_enable(cond_resched);
++	preempt_dynamic_enable(might_resched);
++	preempt_dynamic_enable(preempt_schedule);
++	preempt_dynamic_enable(preempt_schedule_notrace);
++	preempt_dynamic_enable(irqentry_exit_cond_resched);
++
++	switch (mode) {
++	case preempt_dynamic_none:
++		preempt_dynamic_enable(cond_resched);
++		preempt_dynamic_disable(might_resched);
++		preempt_dynamic_disable(preempt_schedule);
++		preempt_dynamic_disable(preempt_schedule_notrace);
++		preempt_dynamic_disable(irqentry_exit_cond_resched);
++		pr_info("Dynamic Preempt: none\n");
++		break;
++
++	case preempt_dynamic_voluntary:
++		preempt_dynamic_enable(cond_resched);
++		preempt_dynamic_enable(might_resched);
++		preempt_dynamic_disable(preempt_schedule);
++		preempt_dynamic_disable(preempt_schedule_notrace);
++		preempt_dynamic_disable(irqentry_exit_cond_resched);
++		pr_info("Dynamic Preempt: voluntary\n");
++		break;
++
++	case preempt_dynamic_full:
++		preempt_dynamic_disable(cond_resched);
++		preempt_dynamic_disable(might_resched);
++		preempt_dynamic_enable(preempt_schedule);
++		preempt_dynamic_enable(preempt_schedule_notrace);
++		preempt_dynamic_enable(irqentry_exit_cond_resched);
++		pr_info("Dynamic Preempt: full\n");
++		break;
++	}
++
++	preempt_dynamic_mode = mode;
++}
++
++static int __init setup_preempt_mode(char *str)
++{
++	int mode = sched_dynamic_mode(str);
++	if (mode < 0) {
++		pr_warn("Dynamic Preempt: unsupported mode: %s\n", str);
++		return 0;
++	}
++
++	sched_dynamic_update(mode);
++	return 1;
++}
++__setup("preempt=", setup_preempt_mode);
++
++static void __init preempt_dynamic_init(void)
++{
++	if (preempt_dynamic_mode == preempt_dynamic_undefined) {
++		if (IS_ENABLED(CONFIG_PREEMPT_NONE)) {
++			sched_dynamic_update(preempt_dynamic_none);
++		} else if (IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY)) {
++			sched_dynamic_update(preempt_dynamic_voluntary);
++		} else {
++			/* Default static call setting, nothing to do */
++			WARN_ON_ONCE(!IS_ENABLED(CONFIG_PREEMPT));
++			preempt_dynamic_mode = preempt_dynamic_full;
++			pr_info("Dynamic Preempt: full\n");
++		}
++	}
++}
++
++#define PREEMPT_MODEL_ACCESSOR(mode) \
++	bool preempt_model_##mode(void)						 \
++	{									 \
++		WARN_ON_ONCE(preempt_dynamic_mode == preempt_dynamic_undefined); \
++		return preempt_dynamic_mode == preempt_dynamic_##mode;		 \
++	}									 \
++	EXPORT_SYMBOL_GPL(preempt_model_##mode)
++
++PREEMPT_MODEL_ACCESSOR(none);
++PREEMPT_MODEL_ACCESSOR(voluntary);
++PREEMPT_MODEL_ACCESSOR(full);
++
++#else /* !CONFIG_PREEMPT_DYNAMIC */
++
++static inline void preempt_dynamic_init(void) { }
++
++#endif /* #ifdef CONFIG_PREEMPT_DYNAMIC */
++
++/**
++ * yield - yield the current processor to other threads.
++ *
++ * Do not ever use this function, there's a 99% chance you're doing it wrong.
++ *
++ * The scheduler is at all times free to pick the calling task as the most
++ * eligible task to run, if removing the yield() call from your code breaks
++ * it, it's already broken.
++ *
++ * Typical broken usage is:
++ *
++ * while (!event)
++ * 	yield();
++ *
++ * where one assumes that yield() will let 'the other' process run that will
++ * make event true. If the current task is a SCHED_FIFO task that will never
++ * happen. Never use yield() as a progress guarantee!!
++ *
++ * If you want to use yield() to wait for something, use wait_event().
++ * If you want to use yield() to be 'nice' for others, use cond_resched().
++ * If you still want to use yield(), do not!
++ */
++void __sched yield(void)
++{
++	set_current_state(TASK_RUNNING);
++	do_sched_yield();
++}
++EXPORT_SYMBOL(yield);
++
++/**
++ * yield_to - yield the current processor to another thread in
++ * your thread group, or accelerate that thread toward the
++ * processor it's on.
++ * @p: target task
++ * @preempt: whether task preemption is allowed or not
++ *
++ * It's the caller's job to ensure that the target task struct
++ * can't go away on us before we can do any checks.
++ *
++ * In Alt schedule FW, yield_to is not supported.
++ *
++ * Return:
++ *	true (>0) if we indeed boosted the target task.
++ *	false (0) if we failed to boost the target.
++ *	-ESRCH if there's no task to yield to.
++ */
++int __sched yield_to(struct task_struct *p, bool preempt)
++{
++	return 0;
++}
++EXPORT_SYMBOL_GPL(yield_to);
++
++int io_schedule_prepare(void)
++{
++	int old_iowait = current->in_iowait;
++
++	current->in_iowait = 1;
++	blk_flush_plug(current->plug, true);
++	return old_iowait;
++}
++
++void io_schedule_finish(int token)
++{
++	current->in_iowait = token;
++}
++
++/*
++ * This task is about to go to sleep on IO.  Increment rq->nr_iowait so
++ * that process accounting knows that this is a task in IO wait state.
++ *
++ * But don't do that if it is a deliberate, throttling IO wait (this task
++ * has set its backing_dev_info: the queue against which it should throttle)
++ */
++
++long __sched io_schedule_timeout(long timeout)
++{
++	int token;
++	long ret;
++
++	token = io_schedule_prepare();
++	ret = schedule_timeout(timeout);
++	io_schedule_finish(token);
++
++	return ret;
++}
++EXPORT_SYMBOL(io_schedule_timeout);
++
++void __sched io_schedule(void)
++{
++	int token;
++
++	token = io_schedule_prepare();
++	schedule();
++	io_schedule_finish(token);
++}
++EXPORT_SYMBOL(io_schedule);
++
++/**
++ * sys_sched_get_priority_max - return maximum RT priority.
++ * @policy: scheduling class.
++ *
++ * Return: On success, this syscall returns the maximum
++ * rt_priority that can be used by a given scheduling class.
++ * On failure, a negative error code is returned.
++ */
++SYSCALL_DEFINE1(sched_get_priority_max, int, policy)
++{
++	int ret = -EINVAL;
++
++	switch (policy) {
++	case SCHED_FIFO:
++	case SCHED_RR:
++		ret = MAX_RT_PRIO - 1;
++		break;
++	case SCHED_NORMAL:
++	case SCHED_BATCH:
++	case SCHED_IDLE:
++		ret = 0;
++		break;
++	}
++	return ret;
++}
++
++/**
++ * sys_sched_get_priority_min - return minimum RT priority.
++ * @policy: scheduling class.
++ *
++ * Return: On success, this syscall returns the minimum
++ * rt_priority that can be used by a given scheduling class.
++ * On failure, a negative error code is returned.
++ */
++SYSCALL_DEFINE1(sched_get_priority_min, int, policy)
++{
++	int ret = -EINVAL;
++
++	switch (policy) {
++	case SCHED_FIFO:
++	case SCHED_RR:
++		ret = 1;
++		break;
++	case SCHED_NORMAL:
++	case SCHED_BATCH:
++	case SCHED_IDLE:
++		ret = 0;
++		break;
++	}
++	return ret;
++}
++
++static int sched_rr_get_interval(pid_t pid, struct timespec64 *t)
++{
++	struct task_struct *p;
++	int retval;
++
++	alt_sched_debug();
++
++	if (pid < 0)
++		return -EINVAL;
++
++	retval = -ESRCH;
++	rcu_read_lock();
++	p = find_process_by_pid(pid);
++	if (!p)
++		goto out_unlock;
++
++	retval = security_task_getscheduler(p);
++	if (retval)
++		goto out_unlock;
++	rcu_read_unlock();
++
++	*t = ns_to_timespec64(sched_timeslice_ns);
++	return 0;
++
++out_unlock:
++	rcu_read_unlock();
++	return retval;
++}
++
++/**
++ * sys_sched_rr_get_interval - return the default timeslice of a process.
++ * @pid: pid of the process.
++ * @interval: userspace pointer to the timeslice value.
++ *
++ *
++ * Return: On success, 0 and the timeslice is in @interval. Otherwise,
++ * an error code.
++ */
++SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
++		struct __kernel_timespec __user *, interval)
++{
++	struct timespec64 t;
++	int retval = sched_rr_get_interval(pid, &t);
++
++	if (retval == 0)
++		retval = put_timespec64(&t, interval);
++
++	return retval;
++}
++
++#ifdef CONFIG_COMPAT_32BIT_TIME
++SYSCALL_DEFINE2(sched_rr_get_interval_time32, pid_t, pid,
++		struct old_timespec32 __user *, interval)
++{
++	struct timespec64 t;
++	int retval = sched_rr_get_interval(pid, &t);
++
++	if (retval == 0)
++		retval = put_old_timespec32(&t, interval);
++	return retval;
++}
++#endif
++
++void sched_show_task(struct task_struct *p)
++{
++	unsigned long free = 0;
++	int ppid;
++
++	if (!try_get_task_stack(p))
++		return;
++
++	pr_info("task:%-15.15s state:%c", p->comm, task_state_to_char(p));
++
++	if (task_is_running(p))
++		pr_cont("  running task    ");
++#ifdef CONFIG_DEBUG_STACK_USAGE
++	free = stack_not_used(p);
++#endif
++	ppid = 0;
++	rcu_read_lock();
++	if (pid_alive(p))
++		ppid = task_pid_nr(rcu_dereference(p->real_parent));
++	rcu_read_unlock();
++	pr_cont(" stack:%5lu pid:%5d ppid:%6d flags:0x%08lx\n",
++		free, task_pid_nr(p), ppid,
++		read_task_thread_flags(p));
++
++	print_worker_info(KERN_INFO, p);
++	print_stop_info(KERN_INFO, p);
++	show_stack(p, NULL, KERN_INFO);
++	put_task_stack(p);
++}
++EXPORT_SYMBOL_GPL(sched_show_task);
++
++static inline bool
++state_filter_match(unsigned long state_filter, struct task_struct *p)
++{
++	unsigned int state = READ_ONCE(p->__state);
++
++	/* no filter, everything matches */
++	if (!state_filter)
++		return true;
++
++	/* filter, but doesn't match */
++	if (!(state & state_filter))
++		return false;
++
++	/*
++	 * When looking for TASK_UNINTERRUPTIBLE skip TASK_IDLE (allows
++	 * TASK_KILLABLE).
++	 */
++	if (state_filter == TASK_UNINTERRUPTIBLE && state == TASK_IDLE)
++		return false;
++
++	return true;
++}
++
++
++void show_state_filter(unsigned int state_filter)
++{
++	struct task_struct *g, *p;
++
++	rcu_read_lock();
++	for_each_process_thread(g, p) {
++		/*
++		 * reset the NMI-timeout, listing all files on a slow
++		 * console might take a lot of time:
++		 * Also, reset softlockup watchdogs on all CPUs, because
++		 * another CPU might be blocked waiting for us to process
++		 * an IPI.
++		 */
++		touch_nmi_watchdog();
++		touch_all_softlockup_watchdogs();
++		if (state_filter_match(state_filter, p))
++			sched_show_task(p);
++	}
++
++#ifdef CONFIG_SCHED_DEBUG
++	/* TODO: Alt schedule FW should support this
++	if (!state_filter)
++		sysrq_sched_debug_show();
++	*/
++#endif
++	rcu_read_unlock();
++	/*
++	 * Only show locks if all tasks are dumped:
++	 */
++	if (!state_filter)
++		debug_show_all_locks();
++}
++
++void dump_cpu_task(int cpu)
++{
++	pr_info("Task dump for CPU %d:\n", cpu);
++	sched_show_task(cpu_curr(cpu));
++}
++
++/**
++ * init_idle - set up an idle thread for a given CPU
++ * @idle: task in question
++ * @cpu: CPU the idle task belongs to
++ *
++ * NOTE: this function does not set the idle thread's NEED_RESCHED
++ * flag, to make booting more robust.
++ */
++void __init init_idle(struct task_struct *idle, int cpu)
++{
++	struct rq *rq = cpu_rq(cpu);
++	unsigned long flags;
++
++	__sched_fork(0, idle);
++
++	raw_spin_lock_irqsave(&idle->pi_lock, flags);
++	raw_spin_lock(&rq->lock);
++	update_rq_clock(rq);
++
++	idle->last_ran = rq->clock_task;
++	idle->__state = TASK_RUNNING;
++	/*
++	 * PF_KTHREAD should already be set at this point; regardless, make it
++	 * look like a proper per-CPU kthread.
++	 */
++	idle->flags |= PF_IDLE | PF_KTHREAD | PF_NO_SETAFFINITY;
++	kthread_set_per_cpu(idle, cpu);
++
++	sched_queue_init_idle(&rq->queue, idle);
++
++#ifdef CONFIG_SMP
++	/*
++	 * It's possible that init_idle() gets called multiple times on a task,
++	 * in that case do_set_cpus_allowed() will not do the right thing.
++	 *
++	 * And since this is boot we can forgo the serialisation.
++	 */
++	set_cpus_allowed_common(idle, cpumask_of(cpu));
++#endif
++
++	/* Silence PROVE_RCU */
++	rcu_read_lock();
++	__set_task_cpu(idle, cpu);
++	rcu_read_unlock();
++
++	rq->idle = idle;
++	rcu_assign_pointer(rq->curr, idle);
++	idle->on_cpu = 1;
++
++	raw_spin_unlock(&rq->lock);
++	raw_spin_unlock_irqrestore(&idle->pi_lock, flags);
++
++	/* Set the preempt count _outside_ the spinlocks! */
++	init_idle_preempt_count(idle, cpu);
++
++	ftrace_graph_init_idle_task(idle, cpu);
++	vtime_init_idle(idle, cpu);
++#ifdef CONFIG_SMP
++	sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu);
++#endif
++}
++
++#ifdef CONFIG_SMP
++
++int cpuset_cpumask_can_shrink(const struct cpumask __maybe_unused *cur,
++			      const struct cpumask __maybe_unused *trial)
++{
++	return 1;
++}
++
++int task_can_attach(struct task_struct *p,
++		    const struct cpumask *cs_effective_cpus)
++{
++	int ret = 0;
++
++	/*
++	 * Kthreads which disallow setaffinity shouldn't be moved
++	 * to a new cpuset; we don't want to change their CPU
++	 * affinity and isolating such threads by their set of
++	 * allowed nodes is unnecessary.  Thus, cpusets are not
++	 * applicable for such threads.  This prevents checking for
++	 * success of set_cpus_allowed_ptr() on all attached tasks
++	 * before cpus_mask may be changed.
++	 */
++	if (p->flags & PF_NO_SETAFFINITY)
++		ret = -EINVAL;
++
++	return ret;
++}
++
++bool sched_smp_initialized __read_mostly;
++
++#ifdef CONFIG_HOTPLUG_CPU
++/*
++ * Ensures that the idle task is using init_mm right before its CPU goes
++ * offline.
++ */
++void idle_task_exit(void)
++{
++	struct mm_struct *mm = current->active_mm;
++
++	BUG_ON(current != this_rq()->idle);
++
++	if (mm != &init_mm) {
++		switch_mm(mm, &init_mm, current);
++		finish_arch_post_lock_switch();
++	}
++
++	/* finish_cpu(), as ran on the BP, will clean up the active_mm state */
++}
++
++static int __balance_push_cpu_stop(void *arg)
++{
++	struct task_struct *p = arg;
++	struct rq *rq = this_rq();
++	struct rq_flags rf;
++	int cpu;
++
++	raw_spin_lock_irq(&p->pi_lock);
++	rq_lock(rq, &rf);
++
++	update_rq_clock(rq);
++
++	if (task_rq(p) == rq && task_on_rq_queued(p)) {
++		cpu = select_fallback_rq(rq->cpu, p);
++		rq = __migrate_task(rq, p, cpu);
++	}
++
++	rq_unlock(rq, &rf);
++	raw_spin_unlock_irq(&p->pi_lock);
++
++	put_task_struct(p);
++
++	return 0;
++}
++
++static DEFINE_PER_CPU(struct cpu_stop_work, push_work);
++
++/*
++ * This is enabled below SCHED_AP_ACTIVE; when !cpu_active(), but only
++ * effective when the hotplug motion is down.
++ */
++static void balance_push(struct rq *rq)
++{
++	struct task_struct *push_task = rq->curr;
++
++	lockdep_assert_held(&rq->lock);
++
++	/*
++	 * Ensure the thing is persistent until balance_push_set(.on = false);
++	 */
++	rq->balance_callback = &balance_push_callback;
++
++	/*
++	 * Only active while going offline and when invoked on the outgoing
++	 * CPU.
++	 */
++	if (!cpu_dying(rq->cpu) || rq != this_rq())
++		return;
++
++	/*
++	 * Both the cpu-hotplug and stop task are in this case and are
++	 * required to complete the hotplug process.
++	 */
++	if (kthread_is_per_cpu(push_task) ||
++	    is_migration_disabled(push_task)) {
++
++		/*
++		 * If this is the idle task on the outgoing CPU try to wake
++		 * up the hotplug control thread which might wait for the
++		 * last task to vanish. The rcuwait_active() check is
++		 * accurate here because the waiter is pinned on this CPU
++		 * and can't obviously be running in parallel.
++		 *
++		 * On RT kernels this also has to check whether there are
++		 * pinned and scheduled out tasks on the runqueue. They
++		 * need to leave the migrate disabled section first.
++		 */
++		if (!rq->nr_running && !rq_has_pinned_tasks(rq) &&
++		    rcuwait_active(&rq->hotplug_wait)) {
++			raw_spin_unlock(&rq->lock);
++			rcuwait_wake_up(&rq->hotplug_wait);
++			raw_spin_lock(&rq->lock);
++		}
++		return;
++	}
++
++	get_task_struct(push_task);
++	/*
++	 * Temporarily drop rq->lock such that we can wake-up the stop task.
++	 * Both preemption and IRQs are still disabled.
++	 */
++	raw_spin_unlock(&rq->lock);
++	stop_one_cpu_nowait(rq->cpu, __balance_push_cpu_stop, push_task,
++			    this_cpu_ptr(&push_work));
++	/*
++	 * At this point need_resched() is true and we'll take the loop in
++	 * schedule(). The next pick is obviously going to be the stop task
++	 * which kthread_is_per_cpu() and will push this task away.
++	 */
++	raw_spin_lock(&rq->lock);
++}
++
++static void balance_push_set(int cpu, bool on)
++{
++	struct rq *rq = cpu_rq(cpu);
++	struct rq_flags rf;
++
++	rq_lock_irqsave(rq, &rf);
++	if (on) {
++		WARN_ON_ONCE(rq->balance_callback);
++		rq->balance_callback = &balance_push_callback;
++	} else if (rq->balance_callback == &balance_push_callback) {
++		rq->balance_callback = NULL;
++	}
++	rq_unlock_irqrestore(rq, &rf);
++}
++
++/*
++ * Invoked from a CPUs hotplug control thread after the CPU has been marked
++ * inactive. All tasks which are not per CPU kernel threads are either
++ * pushed off this CPU now via balance_push() or placed on a different CPU
++ * during wakeup. Wait until the CPU is quiescent.
++ */
++static void balance_hotplug_wait(void)
++{
++	struct rq *rq = this_rq();
++
++	rcuwait_wait_event(&rq->hotplug_wait,
++			   rq->nr_running == 1 && !rq_has_pinned_tasks(rq),
++			   TASK_UNINTERRUPTIBLE);
++}
++
++#else
++
++static void balance_push(struct rq *rq)
++{
++}
++
++static void balance_push_set(int cpu, bool on)
++{
++}
++
++static inline void balance_hotplug_wait(void)
++{
++}
++#endif /* CONFIG_HOTPLUG_CPU */
++
++static void set_rq_offline(struct rq *rq)
++{
++	if (rq->online)
++		rq->online = false;
++}
++
++static void set_rq_online(struct rq *rq)
++{
++	if (!rq->online)
++		rq->online = true;
++}
++
++/*
++ * used to mark begin/end of suspend/resume:
++ */
++static int num_cpus_frozen;
++
++/*
++ * Update cpusets according to cpu_active mask.  If cpusets are
++ * disabled, cpuset_update_active_cpus() becomes a simple wrapper
++ * around partition_sched_domains().
++ *
++ * If we come here as part of a suspend/resume, don't touch cpusets because we
++ * want to restore it back to its original state upon resume anyway.
++ */
++static void cpuset_cpu_active(void)
++{
++	if (cpuhp_tasks_frozen) {
++		/*
++		 * num_cpus_frozen tracks how many CPUs are involved in suspend
++		 * resume sequence. As long as this is not the last online
++		 * operation in the resume sequence, just build a single sched
++		 * domain, ignoring cpusets.
++		 */
++		partition_sched_domains(1, NULL, NULL);
++		if (--num_cpus_frozen)
++			return;
++		/*
++		 * This is the last CPU online operation. So fall through and
++		 * restore the original sched domains by considering the
++		 * cpuset configurations.
++		 */
++		cpuset_force_rebuild();
++	}
++
++	cpuset_update_active_cpus();
++}
++
++static int cpuset_cpu_inactive(unsigned int cpu)
++{
++	if (!cpuhp_tasks_frozen) {
++		cpuset_update_active_cpus();
++	} else {
++		num_cpus_frozen++;
++		partition_sched_domains(1, NULL, NULL);
++	}
++	return 0;
++}
++
++int sched_cpu_activate(unsigned int cpu)
++{
++	struct rq *rq = cpu_rq(cpu);
++	unsigned long flags;
++
++	/*
++	 * Clear the balance_push callback and prepare to schedule
++	 * regular tasks.
++	 */
++	balance_push_set(cpu, false);
++
++#ifdef CONFIG_SCHED_SMT
++	/*
++	 * When going up, increment the number of cores with SMT present.
++	 */
++	if (cpumask_weight(cpu_smt_mask(cpu)) == 2)
++		static_branch_inc_cpuslocked(&sched_smt_present);
++#endif
++	set_cpu_active(cpu, true);
++
++	if (sched_smp_initialized)
++		cpuset_cpu_active();
++
++	/*
++	 * Put the rq online, if not already. This happens:
++	 *
++	 * 1) In the early boot process, because we build the real domains
++	 *    after all cpus have been brought up.
++	 *
++	 * 2) At runtime, if cpuset_cpu_active() fails to rebuild the
++	 *    domains.
++	 */
++	raw_spin_lock_irqsave(&rq->lock, flags);
++	set_rq_online(rq);
++	raw_spin_unlock_irqrestore(&rq->lock, flags);
++
++	return 0;
++}
++
++int sched_cpu_deactivate(unsigned int cpu)
++{
++	struct rq *rq = cpu_rq(cpu);
++	unsigned long flags;
++	int ret;
++
++	set_cpu_active(cpu, false);
++
++	/*
++	 * From this point forward, this CPU will refuse to run any task that
++	 * is not: migrate_disable() or KTHREAD_IS_PER_CPU, and will actively
++	 * push those tasks away until this gets cleared, see
++	 * sched_cpu_dying().
++	 */
++	balance_push_set(cpu, true);
++
++	/*
++	 * We've cleared cpu_active_mask, wait for all preempt-disabled and RCU
++	 * users of this state to go away such that all new such users will
++	 * observe it.
++	 *
++	 * Specifically, we rely on ttwu to no longer target this CPU, see
++	 * ttwu_queue_cond() and is_cpu_allowed().
++	 *
++	 * Do sync before park smpboot threads to take care the rcu boost case.
++	 */
++	synchronize_rcu();
++
++	raw_spin_lock_irqsave(&rq->lock, flags);
++	update_rq_clock(rq);
++	set_rq_offline(rq);
++	raw_spin_unlock_irqrestore(&rq->lock, flags);
++
++#ifdef CONFIG_SCHED_SMT
++	/*
++	 * When going down, decrement the number of cores with SMT present.
++	 */
++	if (cpumask_weight(cpu_smt_mask(cpu)) == 2) {
++		static_branch_dec_cpuslocked(&sched_smt_present);
++		if (!static_branch_likely(&sched_smt_present))
++			cpumask_clear(&sched_sg_idle_mask);
++	}
++#endif
++
++	if (!sched_smp_initialized)
++		return 0;
++
++	ret = cpuset_cpu_inactive(cpu);
++	if (ret) {
++		balance_push_set(cpu, false);
++		set_cpu_active(cpu, true);
++		return ret;
++	}
++
++	return 0;
++}
++
++static void sched_rq_cpu_starting(unsigned int cpu)
++{
++	struct rq *rq = cpu_rq(cpu);
++
++	rq->calc_load_update = calc_load_update;
++}
++
++int sched_cpu_starting(unsigned int cpu)
++{
++	sched_rq_cpu_starting(cpu);
++	sched_tick_start(cpu);
++	return 0;
++}
++
++#ifdef CONFIG_HOTPLUG_CPU
++
++/*
++ * Invoked immediately before the stopper thread is invoked to bring the
++ * CPU down completely. At this point all per CPU kthreads except the
++ * hotplug thread (current) and the stopper thread (inactive) have been
++ * either parked or have been unbound from the outgoing CPU. Ensure that
++ * any of those which might be on the way out are gone.
++ *
++ * If after this point a bound task is being woken on this CPU then the
++ * responsible hotplug callback has failed to do it's job.
++ * sched_cpu_dying() will catch it with the appropriate fireworks.
++ */
++int sched_cpu_wait_empty(unsigned int cpu)
++{
++	balance_hotplug_wait();
++	return 0;
++}
++
++/*
++ * Since this CPU is going 'away' for a while, fold any nr_active delta we
++ * might have. Called from the CPU stopper task after ensuring that the
++ * stopper is the last running task on the CPU, so nr_active count is
++ * stable. We need to take the teardown thread which is calling this into
++ * account, so we hand in adjust = 1 to the load calculation.
++ *
++ * Also see the comment "Global load-average calculations".
++ */
++static void calc_load_migrate(struct rq *rq)
++{
++	long delta = calc_load_fold_active(rq, 1);
++
++	if (delta)
++		atomic_long_add(delta, &calc_load_tasks);
++}
++
++static void dump_rq_tasks(struct rq *rq, const char *loglvl)
++{
++	struct task_struct *g, *p;
++	int cpu = cpu_of(rq);
++
++	lockdep_assert_held(&rq->lock);
++
++	printk("%sCPU%d enqueued tasks (%u total):\n", loglvl, cpu, rq->nr_running);
++	for_each_process_thread(g, p) {
++		if (task_cpu(p) != cpu)
++			continue;
++
++		if (!task_on_rq_queued(p))
++			continue;
++
++		printk("%s\tpid: %d, name: %s\n", loglvl, p->pid, p->comm);
++	}
++}
++
++int sched_cpu_dying(unsigned int cpu)
++{
++	struct rq *rq = cpu_rq(cpu);
++	unsigned long flags;
++
++	/* Handle pending wakeups and then migrate everything off */
++	sched_tick_stop(cpu);
++
++	raw_spin_lock_irqsave(&rq->lock, flags);
++	if (rq->nr_running != 1 || rq_has_pinned_tasks(rq)) {
++		WARN(true, "Dying CPU not properly vacated!");
++		dump_rq_tasks(rq, KERN_WARNING);
++	}
++	raw_spin_unlock_irqrestore(&rq->lock, flags);
++
++	calc_load_migrate(rq);
++	hrtick_clear(rq);
++	return 0;
++}
++#endif
++
++#ifdef CONFIG_SMP
++static void sched_init_topology_cpumask_early(void)
++{
++	int cpu;
++	cpumask_t *tmp;
++
++	for_each_possible_cpu(cpu) {
++		/* init topo masks */
++		tmp = per_cpu(sched_cpu_topo_masks, cpu);
++
++		cpumask_copy(tmp, cpumask_of(cpu));
++		tmp++;
++		cpumask_copy(tmp, cpu_possible_mask);
++		per_cpu(sched_cpu_llc_mask, cpu) = tmp;
++		per_cpu(sched_cpu_topo_end_mask, cpu) = ++tmp;
++		/*per_cpu(sd_llc_id, cpu) = cpu;*/
++	}
++}
++
++#define TOPOLOGY_CPUMASK(name, mask, last)\
++	if (cpumask_and(topo, topo, mask)) {					\
++		cpumask_copy(topo, mask);					\
++		printk(KERN_INFO "sched: cpu#%02d topo: 0x%08lx - "#name,	\
++		       cpu, (topo++)->bits[0]);					\
++	}									\
++	if (!last)								\
++		cpumask_complement(topo, mask)
++
++static void sched_init_topology_cpumask(void)
++{
++	int cpu;
++	cpumask_t *topo;
++
++	for_each_online_cpu(cpu) {
++		/* take chance to reset time slice for idle tasks */
++		cpu_rq(cpu)->idle->time_slice = sched_timeslice_ns;
++
++		topo = per_cpu(sched_cpu_topo_masks, cpu) + 1;
++
++		cpumask_complement(topo, cpumask_of(cpu));
++#ifdef CONFIG_SCHED_SMT
++		TOPOLOGY_CPUMASK(smt, topology_sibling_cpumask(cpu), false);
++#endif
++		per_cpu(sd_llc_id, cpu) = cpumask_first(cpu_coregroup_mask(cpu));
++		per_cpu(sched_cpu_llc_mask, cpu) = topo;
++		TOPOLOGY_CPUMASK(coregroup, cpu_coregroup_mask(cpu), false);
++
++		TOPOLOGY_CPUMASK(core, topology_core_cpumask(cpu), false);
++
++		TOPOLOGY_CPUMASK(others, cpu_online_mask, true);
++
++		per_cpu(sched_cpu_topo_end_mask, cpu) = topo;
++		printk(KERN_INFO "sched: cpu#%02d llc_id = %d, llc_mask idx = %d\n",
++		       cpu, per_cpu(sd_llc_id, cpu),
++		       (int) (per_cpu(sched_cpu_llc_mask, cpu) -
++			      per_cpu(sched_cpu_topo_masks, cpu)));
++	}
++}
++#endif
++
++void __init sched_init_smp(void)
++{
++	/* Move init over to a non-isolated CPU */
++	if (set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_TYPE_DOMAIN)) < 0)
++		BUG();
++	current->flags &= ~PF_NO_SETAFFINITY;
++
++	sched_init_topology_cpumask();
++
++	sched_smp_initialized = true;
++}
++#else
++void __init sched_init_smp(void)
++{
++	cpu_rq(0)->idle->time_slice = sched_timeslice_ns;
++}
++#endif /* CONFIG_SMP */
++
++int in_sched_functions(unsigned long addr)
++{
++	return in_lock_functions(addr) ||
++		(addr >= (unsigned long)__sched_text_start
++		&& addr < (unsigned long)__sched_text_end);
++}
++
++#ifdef CONFIG_CGROUP_SCHED
++/* task group related information */
++struct task_group {
++	struct cgroup_subsys_state css;
++
++	struct rcu_head rcu;
++	struct list_head list;
++
++	struct task_group *parent;
++	struct list_head siblings;
++	struct list_head children;
++#ifdef CONFIG_FAIR_GROUP_SCHED
++	unsigned long		shares;
++#endif
++};
++
++/*
++ * Default task group.
++ * Every task in system belongs to this group at bootup.
++ */
++struct task_group root_task_group;
++LIST_HEAD(task_groups);
++
++/* Cacheline aligned slab cache for task_group */
++static struct kmem_cache *task_group_cache __read_mostly;
++#endif /* CONFIG_CGROUP_SCHED */
++
++void __init sched_init(void)
++{
++	int i;
++	struct rq *rq;
++
++	printk(KERN_INFO ALT_SCHED_VERSION_MSG);
++
++	wait_bit_init();
++
++#ifdef CONFIG_SMP
++	for (i = 0; i < SCHED_QUEUE_BITS; i++)
++		cpumask_copy(sched_rq_watermark + i, cpu_present_mask);
++#endif
++
++#ifdef CONFIG_CGROUP_SCHED
++	task_group_cache = KMEM_CACHE(task_group, 0);
++
++	list_add(&root_task_group.list, &task_groups);
++	INIT_LIST_HEAD(&root_task_group.children);
++	INIT_LIST_HEAD(&root_task_group.siblings);
++#endif /* CONFIG_CGROUP_SCHED */
++	for_each_possible_cpu(i) {
++		rq = cpu_rq(i);
++
++		sched_queue_init(&rq->queue);
++		rq->watermark = IDLE_TASK_SCHED_PRIO;
++		rq->skip = NULL;
++
++		raw_spin_lock_init(&rq->lock);
++		rq->nr_running = rq->nr_uninterruptible = 0;
++		rq->calc_load_active = 0;
++		rq->calc_load_update = jiffies + LOAD_FREQ;
++#ifdef CONFIG_SMP
++		rq->online = false;
++		rq->cpu = i;
++
++#ifdef CONFIG_SCHED_SMT
++		rq->active_balance = 0;
++#endif
++
++#ifdef CONFIG_NO_HZ_COMMON
++		INIT_CSD(&rq->nohz_csd, nohz_csd_func, rq);
++#endif
++		rq->balance_callback = &balance_push_callback;
++#ifdef CONFIG_HOTPLUG_CPU
++		rcuwait_init(&rq->hotplug_wait);
++#endif
++#endif /* CONFIG_SMP */
++		rq->nr_switches = 0;
++
++		hrtick_rq_init(rq);
++		atomic_set(&rq->nr_iowait, 0);
++	}
++#ifdef CONFIG_SMP
++	/* Set rq->online for cpu 0 */
++	cpu_rq(0)->online = true;
++#endif
++	/*
++	 * The boot idle thread does lazy MMU switching as well:
++	 */
++	mmgrab(&init_mm);
++	enter_lazy_tlb(&init_mm, current);
++
++	/*
++	 * The idle task doesn't need the kthread struct to function, but it
++	 * is dressed up as a per-CPU kthread and thus needs to play the part
++	 * if we want to avoid special-casing it in code that deals with per-CPU
++	 * kthreads.
++	 */
++	WARN_ON(!set_kthread_struct(current));
++
++	/*
++	 * Make us the idle thread. Technically, schedule() should not be
++	 * called from this thread, however somewhere below it might be,
++	 * but because we are the idle thread, we just pick up running again
++	 * when this runqueue becomes "idle".
++	 */
++	init_idle(current, smp_processor_id());
++
++	calc_load_update = jiffies + LOAD_FREQ;
++
++#ifdef CONFIG_SMP
++	idle_thread_set_boot_cpu();
++	balance_push_set(smp_processor_id(), false);
++
++	sched_init_topology_cpumask_early();
++#endif /* SMP */
++
++	psi_init();
++
++	preempt_dynamic_init();
++}
++
++#ifdef CONFIG_DEBUG_ATOMIC_SLEEP
++
++void __might_sleep(const char *file, int line)
++{
++	unsigned int state = get_current_state();
++	/*
++	 * Blocking primitives will set (and therefore destroy) current->state,
++	 * since we will exit with TASK_RUNNING make sure we enter with it,
++	 * otherwise we will destroy state.
++	 */
++	WARN_ONCE(state != TASK_RUNNING && current->task_state_change,
++			"do not call blocking ops when !TASK_RUNNING; "
++			"state=%x set at [<%p>] %pS\n", state,
++			(void *)current->task_state_change,
++			(void *)current->task_state_change);
++
++	__might_resched(file, line, 0);
++}
++EXPORT_SYMBOL(__might_sleep);
++
++static void print_preempt_disable_ip(int preempt_offset, unsigned long ip)
++{
++	if (!IS_ENABLED(CONFIG_DEBUG_PREEMPT))
++		return;
++
++	if (preempt_count() == preempt_offset)
++		return;
++
++	pr_err("Preemption disabled at:");
++	print_ip_sym(KERN_ERR, ip);
++}
++
++static inline bool resched_offsets_ok(unsigned int offsets)
++{
++	unsigned int nested = preempt_count();
++
++	nested += rcu_preempt_depth() << MIGHT_RESCHED_RCU_SHIFT;
++
++	return nested == offsets;
++}
++
++void __might_resched(const char *file, int line, unsigned int offsets)
++{
++	/* Ratelimiting timestamp: */
++	static unsigned long prev_jiffy;
++
++	unsigned long preempt_disable_ip;
++
++	/* WARN_ON_ONCE() by default, no rate limit required: */
++	rcu_sleep_check();
++
++	if ((resched_offsets_ok(offsets) && !irqs_disabled() &&
++	     !is_idle_task(current) && !current->non_block_count) ||
++	    system_state == SYSTEM_BOOTING || system_state > SYSTEM_RUNNING ||
++	    oops_in_progress)
++		return;
++	if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
++		return;
++	prev_jiffy = jiffies;
++
++	/* Save this before calling printk(), since that will clobber it: */
++	preempt_disable_ip = get_preempt_disable_ip(current);
++
++	pr_err("BUG: sleeping function called from invalid context at %s:%d\n",
++	       file, line);
++	pr_err("in_atomic(): %d, irqs_disabled(): %d, non_block: %d, pid: %d, name: %s\n",
++	       in_atomic(), irqs_disabled(), current->non_block_count,
++	       current->pid, current->comm);
++	pr_err("preempt_count: %x, expected: %x\n", preempt_count(),
++	       offsets & MIGHT_RESCHED_PREEMPT_MASK);
++
++	if (IS_ENABLED(CONFIG_PREEMPT_RCU)) {
++		pr_err("RCU nest depth: %d, expected: %u\n",
++		       rcu_preempt_depth(), offsets >> MIGHT_RESCHED_RCU_SHIFT);
++	}
++
++	if (task_stack_end_corrupted(current))
++		pr_emerg("Thread overran stack, or stack corrupted\n");
++
++	debug_show_held_locks(current);
++	if (irqs_disabled())
++		print_irqtrace_events(current);
++
++	print_preempt_disable_ip(offsets & MIGHT_RESCHED_PREEMPT_MASK,
++				 preempt_disable_ip);
++
++	dump_stack();
++	add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
++}
++EXPORT_SYMBOL(__might_resched);
++
++void __cant_sleep(const char *file, int line, int preempt_offset)
++{
++	static unsigned long prev_jiffy;
++
++	if (irqs_disabled())
++		return;
++
++	if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
++		return;
++
++	if (preempt_count() > preempt_offset)
++		return;
++
++	if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
++		return;
++	prev_jiffy = jiffies;
++
++	printk(KERN_ERR "BUG: assuming atomic context at %s:%d\n", file, line);
++	printk(KERN_ERR "in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n",
++			in_atomic(), irqs_disabled(),
++			current->pid, current->comm);
++
++	debug_show_held_locks(current);
++	dump_stack();
++	add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
++}
++EXPORT_SYMBOL_GPL(__cant_sleep);
++
++#ifdef CONFIG_SMP
++void __cant_migrate(const char *file, int line)
++{
++	static unsigned long prev_jiffy;
++
++	if (irqs_disabled())
++		return;
++
++	if (is_migration_disabled(current))
++		return;
++
++	if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
++		return;
++
++	if (preempt_count() > 0)
++		return;
++
++	if (current->migration_flags & MDF_FORCE_ENABLED)
++		return;
++
++	if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
++		return;
++	prev_jiffy = jiffies;
++
++	pr_err("BUG: assuming non migratable context at %s:%d\n", file, line);
++	pr_err("in_atomic(): %d, irqs_disabled(): %d, migration_disabled() %u pid: %d, name: %s\n",
++	       in_atomic(), irqs_disabled(), is_migration_disabled(current),
++	       current->pid, current->comm);
++
++	debug_show_held_locks(current);
++	dump_stack();
++	add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
++}
++EXPORT_SYMBOL_GPL(__cant_migrate);
++#endif
++#endif
++
++#ifdef CONFIG_MAGIC_SYSRQ
++void normalize_rt_tasks(void)
++{
++	struct task_struct *g, *p;
++	struct sched_attr attr = {
++		.sched_policy = SCHED_NORMAL,
++	};
++
++	read_lock(&tasklist_lock);
++	for_each_process_thread(g, p) {
++		/*
++		 * Only normalize user tasks:
++		 */
++		if (p->flags & PF_KTHREAD)
++			continue;
++
++		schedstat_set(p->stats.wait_start,  0);
++		schedstat_set(p->stats.sleep_start, 0);
++		schedstat_set(p->stats.block_start, 0);
++
++		if (!rt_task(p)) {
++			/*
++			 * Renice negative nice level userspace
++			 * tasks back to 0:
++			 */
++			if (task_nice(p) < 0)
++				set_user_nice(p, 0);
++			continue;
++		}
++
++		__sched_setscheduler(p, &attr, false, false);
++	}
++	read_unlock(&tasklist_lock);
++}
++#endif /* CONFIG_MAGIC_SYSRQ */
++
++#if defined(CONFIG_IA64) || defined(CONFIG_KGDB_KDB)
++/*
++ * These functions are only useful for the IA64 MCA handling, or kdb.
++ *
++ * They can only be called when the whole system has been
++ * stopped - every CPU needs to be quiescent, and no scheduling
++ * activity can take place. Using them for anything else would
++ * be a serious bug, and as a result, they aren't even visible
++ * under any other configuration.
++ */
++
++/**
++ * curr_task - return the current task for a given CPU.
++ * @cpu: the processor in question.
++ *
++ * ONLY VALID WHEN THE WHOLE SYSTEM IS STOPPED!
++ *
++ * Return: The current task for @cpu.
++ */
++struct task_struct *curr_task(int cpu)
++{
++	return cpu_curr(cpu);
++}
++
++#endif /* defined(CONFIG_IA64) || defined(CONFIG_KGDB_KDB) */
++
++#ifdef CONFIG_IA64
++/**
++ * ia64_set_curr_task - set the current task for a given CPU.
++ * @cpu: the processor in question.
++ * @p: the task pointer to set.
++ *
++ * Description: This function must only be used when non-maskable interrupts
++ * are serviced on a separate stack.  It allows the architecture to switch the
++ * notion of the current task on a CPU in a non-blocking manner.  This function
++ * must be called with all CPU's synchronised, and interrupts disabled, the
++ * and caller must save the original value of the current task (see
++ * curr_task() above) and restore that value before reenabling interrupts and
++ * re-starting the system.
++ *
++ * ONLY VALID WHEN THE WHOLE SYSTEM IS STOPPED!
++ */
++void ia64_set_curr_task(int cpu, struct task_struct *p)
++{
++	cpu_curr(cpu) = p;
++}
++
++#endif
++
++#ifdef CONFIG_CGROUP_SCHED
++static void sched_free_group(struct task_group *tg)
++{
++	kmem_cache_free(task_group_cache, tg);
++}
++
++static void sched_free_group_rcu(struct rcu_head *rhp)
++{
++	sched_free_group(container_of(rhp, struct task_group, rcu));
++}
++
++static void sched_unregister_group(struct task_group *tg)
++{
++	/*
++	 * We have to wait for yet another RCU grace period to expire, as
++	 * print_cfs_stats() might run concurrently.
++	 */
++	call_rcu(&tg->rcu, sched_free_group_rcu);
++}
++
++/* allocate runqueue etc for a new task group */
++struct task_group *sched_create_group(struct task_group *parent)
++{
++	struct task_group *tg;
++
++	tg = kmem_cache_alloc(task_group_cache, GFP_KERNEL | __GFP_ZERO);
++	if (!tg)
++		return ERR_PTR(-ENOMEM);
++
++	return tg;
++}
++
++void sched_online_group(struct task_group *tg, struct task_group *parent)
++{
++}
++
++/* rcu callback to free various structures associated with a task group */
++static void sched_unregister_group_rcu(struct rcu_head *rhp)
++{
++	/* Now it should be safe to free those cfs_rqs: */
++	sched_unregister_group(container_of(rhp, struct task_group, rcu));
++}
++
++void sched_destroy_group(struct task_group *tg)
++{
++	/* Wait for possible concurrent references to cfs_rqs complete: */
++	call_rcu(&tg->rcu, sched_unregister_group_rcu);
++}
++
++void sched_release_group(struct task_group *tg)
++{
++}
++
++static inline struct task_group *css_tg(struct cgroup_subsys_state *css)
++{
++	return css ? container_of(css, struct task_group, css) : NULL;
++}
++
++static struct cgroup_subsys_state *
++cpu_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
++{
++	struct task_group *parent = css_tg(parent_css);
++	struct task_group *tg;
++
++	if (!parent) {
++		/* This is early initialization for the top cgroup */
++		return &root_task_group.css;
++	}
++
++	tg = sched_create_group(parent);
++	if (IS_ERR(tg))
++		return ERR_PTR(-ENOMEM);
++	return &tg->css;
++}
++
++/* Expose task group only after completing cgroup initialization */
++static int cpu_cgroup_css_online(struct cgroup_subsys_state *css)
++{
++	struct task_group *tg = css_tg(css);
++	struct task_group *parent = css_tg(css->parent);
++
++	if (parent)
++		sched_online_group(tg, parent);
++	return 0;
++}
++
++static void cpu_cgroup_css_released(struct cgroup_subsys_state *css)
++{
++	struct task_group *tg = css_tg(css);
++
++	sched_release_group(tg);
++}
++
++static void cpu_cgroup_css_free(struct cgroup_subsys_state *css)
++{
++	struct task_group *tg = css_tg(css);
++
++	/*
++	 * Relies on the RCU grace period between css_released() and this.
++	 */
++	sched_unregister_group(tg);
++}
++
++static void cpu_cgroup_fork(struct task_struct *task)
++{
++}
++
++static int cpu_cgroup_can_attach(struct cgroup_taskset *tset)
++{
++	return 0;
++}
++
++static void cpu_cgroup_attach(struct cgroup_taskset *tset)
++{
++}
++
++#ifdef CONFIG_FAIR_GROUP_SCHED
++static DEFINE_MUTEX(shares_mutex);
++
++int sched_group_set_shares(struct task_group *tg, unsigned long shares)
++{
++	/*
++	 * We can't change the weight of the root cgroup.
++	 */
++	if (&root_task_group == tg)
++		return -EINVAL;
++
++	shares = clamp(shares, scale_load(MIN_SHARES), scale_load(MAX_SHARES));
++
++	mutex_lock(&shares_mutex);
++	if (tg->shares == shares)
++		goto done;
++
++	tg->shares = shares;
++done:
++	mutex_unlock(&shares_mutex);
++	return 0;
++}
++
++static int cpu_shares_write_u64(struct cgroup_subsys_state *css,
++				struct cftype *cftype, u64 shareval)
++{
++	if (shareval > scale_load_down(ULONG_MAX))
++		shareval = MAX_SHARES;
++	return sched_group_set_shares(css_tg(css), scale_load(shareval));
++}
++
++static u64 cpu_shares_read_u64(struct cgroup_subsys_state *css,
++			       struct cftype *cft)
++{
++	struct task_group *tg = css_tg(css);
++
++	return (u64) scale_load_down(tg->shares);
++}
++#endif
++
++static struct cftype cpu_legacy_files[] = {
++#ifdef CONFIG_FAIR_GROUP_SCHED
++	{
++		.name = "shares",
++		.read_u64 = cpu_shares_read_u64,
++		.write_u64 = cpu_shares_write_u64,
++	},
++#endif
++	{ }	/* Terminate */
++};
++
++
++static struct cftype cpu_files[] = {
++	{ }	/* terminate */
++};
++
++static int cpu_extra_stat_show(struct seq_file *sf,
++			       struct cgroup_subsys_state *css)
++{
++	return 0;
++}
++
++struct cgroup_subsys cpu_cgrp_subsys = {
++	.css_alloc	= cpu_cgroup_css_alloc,
++	.css_online	= cpu_cgroup_css_online,
++	.css_released	= cpu_cgroup_css_released,
++	.css_free	= cpu_cgroup_css_free,
++	.css_extra_stat_show = cpu_extra_stat_show,
++	.fork		= cpu_cgroup_fork,
++	.can_attach	= cpu_cgroup_can_attach,
++	.attach		= cpu_cgroup_attach,
++	.legacy_cftypes	= cpu_files,
++	.legacy_cftypes	= cpu_legacy_files,
++	.dfl_cftypes	= cpu_files,
++	.early_init	= true,
++	.threaded	= true,
++};
++#endif	/* CONFIG_CGROUP_SCHED */
++
++#undef CREATE_TRACE_POINTS
+diff --git a/kernel/sched/alt_debug.c b/kernel/sched/alt_debug.c
+new file mode 100644
+index 000000000000..1212a031700e
+--- /dev/null
++++ b/kernel/sched/alt_debug.c
+@@ -0,0 +1,31 @@
++/*
++ * kernel/sched/alt_debug.c
++ *
++ * Print the alt scheduler debugging details
++ *
++ * Author: Alfred Chen
++ * Date  : 2020
++ */
++#include "sched.h"
++
++/*
++ * This allows printing both to /proc/sched_debug and
++ * to the console
++ */
++#define SEQ_printf(m, x...)			\
++ do {						\
++	if (m)					\
++		seq_printf(m, x);		\
++	else					\
++		pr_cont(x);			\
++ } while (0)
++
++void proc_sched_show_task(struct task_struct *p, struct pid_namespace *ns,
++			  struct seq_file *m)
++{
++	SEQ_printf(m, "%s (%d, #threads: %d)\n", p->comm, task_pid_nr_ns(p, ns),
++						get_nr_threads(p));
++}
++
++void proc_sched_set_task(struct task_struct *p)
++{}
+diff --git a/kernel/sched/alt_sched.h b/kernel/sched/alt_sched.h
+new file mode 100644
+index 000000000000..bec061f2ae10
+--- /dev/null
++++ b/kernel/sched/alt_sched.h
+@@ -0,0 +1,645 @@
++#ifndef ALT_SCHED_H
++#define ALT_SCHED_H
++
++#include <linux/context_tracking.h>
++#include <linux/psi.h>
++#include <linux/stop_machine.h>
++#include <linux/syscalls.h>
++#include <linux/tick.h>
++
++#include <trace/events/power.h>
++#include <trace/events/sched.h>
++
++#include "../workqueue_internal.h"
++
++#include "cpupri.h"
++
++#ifdef CONFIG_SCHED_BMQ
++/* bits:
++ * RT(0-99), (Low prio adj range, nice width, high prio adj range) / 2, cpu idle task */
++#define SCHED_BITS	(MAX_RT_PRIO + NICE_WIDTH / 2 + MAX_PRIORITY_ADJ + 1)
++#endif
++
++#ifdef CONFIG_SCHED_PDS
++/* bits: RT(0-99), reserved(100-127), NORMAL_PRIO_NUM, cpu idle task */
++#define SCHED_BITS	(MIN_NORMAL_PRIO + NORMAL_PRIO_NUM + 1)
++#endif /* CONFIG_SCHED_PDS */
++
++#define IDLE_TASK_SCHED_PRIO	(SCHED_BITS - 1)
++
++#ifdef CONFIG_SCHED_DEBUG
++# define SCHED_WARN_ON(x)	WARN_ONCE(x, #x)
++extern void resched_latency_warn(int cpu, u64 latency);
++#else
++# define SCHED_WARN_ON(x)	({ (void)(x), 0; })
++static inline void resched_latency_warn(int cpu, u64 latency) {}
++#endif
++
++/*
++ * Increase resolution of nice-level calculations for 64-bit architectures.
++ * The extra resolution improves shares distribution and load balancing of
++ * low-weight task groups (eg. nice +19 on an autogroup), deeper taskgroup
++ * hierarchies, especially on larger systems. This is not a user-visible change
++ * and does not change the user-interface for setting shares/weights.
++ *
++ * We increase resolution only if we have enough bits to allow this increased
++ * resolution (i.e. 64-bit). The costs for increasing resolution when 32-bit
++ * are pretty high and the returns do not justify the increased costs.
++ *
++ * Really only required when CONFIG_FAIR_GROUP_SCHED=y is also set, but to
++ * increase coverage and consistency always enable it on 64-bit platforms.
++ */
++#ifdef CONFIG_64BIT
++# define NICE_0_LOAD_SHIFT	(SCHED_FIXEDPOINT_SHIFT + SCHED_FIXEDPOINT_SHIFT)
++# define scale_load(w)		((w) << SCHED_FIXEDPOINT_SHIFT)
++# define scale_load_down(w) \
++({ \
++	unsigned long __w = (w); \
++	if (__w) \
++		__w = max(2UL, __w >> SCHED_FIXEDPOINT_SHIFT); \
++	__w; \
++})
++#else
++# define NICE_0_LOAD_SHIFT	(SCHED_FIXEDPOINT_SHIFT)
++# define scale_load(w)		(w)
++# define scale_load_down(w)	(w)
++#endif
++
++#ifdef CONFIG_FAIR_GROUP_SCHED
++#define ROOT_TASK_GROUP_LOAD	NICE_0_LOAD
++
++/*
++ * A weight of 0 or 1 can cause arithmetics problems.
++ * A weight of a cfs_rq is the sum of weights of which entities
++ * are queued on this cfs_rq, so a weight of a entity should not be
++ * too large, so as the shares value of a task group.
++ * (The default weight is 1024 - so there's no practical
++ *  limitation from this.)
++ */
++#define MIN_SHARES		(1UL <<  1)
++#define MAX_SHARES		(1UL << 18)
++#endif
++
++/* task_struct::on_rq states: */
++#define TASK_ON_RQ_QUEUED	1
++#define TASK_ON_RQ_MIGRATING	2
++
++static inline int task_on_rq_queued(struct task_struct *p)
++{
++	return p->on_rq == TASK_ON_RQ_QUEUED;
++}
++
++static inline int task_on_rq_migrating(struct task_struct *p)
++{
++	return READ_ONCE(p->on_rq) == TASK_ON_RQ_MIGRATING;
++}
++
++/*
++ * wake flags
++ */
++#define WF_SYNC		0x01		/* waker goes to sleep after wakeup */
++#define WF_FORK		0x02		/* child wakeup after fork */
++#define WF_MIGRATED	0x04		/* internal use, task got migrated */
++
++#define SCHED_QUEUE_BITS	(SCHED_BITS - 1)
++
++struct sched_queue {
++	DECLARE_BITMAP(bitmap, SCHED_QUEUE_BITS);
++	struct list_head heads[SCHED_BITS];
++};
++
++/*
++ * This is the main, per-CPU runqueue data structure.
++ * This data should only be modified by the local cpu.
++ */
++struct rq {
++	/* runqueue lock: */
++	raw_spinlock_t lock;
++
++	struct task_struct __rcu *curr;
++	struct task_struct *idle, *stop, *skip;
++	struct mm_struct *prev_mm;
++
++	struct sched_queue	queue;
++#ifdef CONFIG_SCHED_PDS
++	u64			time_edge;
++#endif
++	unsigned long watermark;
++
++	/* switch count */
++	u64 nr_switches;
++
++	atomic_t nr_iowait;
++
++#ifdef CONFIG_SCHED_DEBUG
++	u64 last_seen_need_resched_ns;
++	int ticks_without_resched;
++#endif
++
++#ifdef CONFIG_MEMBARRIER
++	int membarrier_state;
++#endif
++
++#ifdef CONFIG_SMP
++	int cpu;		/* cpu of this runqueue */
++	bool online;
++
++	unsigned int		ttwu_pending;
++	unsigned char		nohz_idle_balance;
++	unsigned char		idle_balance;
++
++#ifdef CONFIG_HAVE_SCHED_AVG_IRQ
++	struct sched_avg	avg_irq;
++#endif
++
++#ifdef CONFIG_SCHED_SMT
++	int active_balance;
++	struct cpu_stop_work	active_balance_work;
++#endif
++	struct callback_head	*balance_callback;
++#ifdef CONFIG_HOTPLUG_CPU
++	struct rcuwait		hotplug_wait;
++#endif
++	unsigned int		nr_pinned;
++
++#endif /* CONFIG_SMP */
++#ifdef CONFIG_IRQ_TIME_ACCOUNTING
++	u64 prev_irq_time;
++#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
++#ifdef CONFIG_PARAVIRT
++	u64 prev_steal_time;
++#endif /* CONFIG_PARAVIRT */
++#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
++	u64 prev_steal_time_rq;
++#endif /* CONFIG_PARAVIRT_TIME_ACCOUNTING */
++
++	/* For genenal cpu load util */
++	s32 load_history;
++	u64 load_block;
++	u64 load_stamp;
++
++	/* calc_load related fields */
++	unsigned long calc_load_update;
++	long calc_load_active;
++
++	u64 clock, last_tick;
++	u64 last_ts_switch;
++	u64 clock_task;
++
++	unsigned int  nr_running;
++	unsigned long nr_uninterruptible;
++
++#ifdef CONFIG_SCHED_HRTICK
++#ifdef CONFIG_SMP
++	call_single_data_t hrtick_csd;
++#endif
++	struct hrtimer		hrtick_timer;
++	ktime_t			hrtick_time;
++#endif
++
++#ifdef CONFIG_SCHEDSTATS
++
++	/* latency stats */
++	struct sched_info rq_sched_info;
++	unsigned long long rq_cpu_time;
++	/* could above be rq->cfs_rq.exec_clock + rq->rt_rq.rt_runtime ? */
++
++	/* sys_sched_yield() stats */
++	unsigned int yld_count;
++
++	/* schedule() stats */
++	unsigned int sched_switch;
++	unsigned int sched_count;
++	unsigned int sched_goidle;
++
++	/* try_to_wake_up() stats */
++	unsigned int ttwu_count;
++	unsigned int ttwu_local;
++#endif /* CONFIG_SCHEDSTATS */
++
++#ifdef CONFIG_CPU_IDLE
++	/* Must be inspected within a rcu lock section */
++	struct cpuidle_state *idle_state;
++#endif
++
++#ifdef CONFIG_NO_HZ_COMMON
++#ifdef CONFIG_SMP
++	call_single_data_t	nohz_csd;
++#endif
++	atomic_t		nohz_flags;
++#endif /* CONFIG_NO_HZ_COMMON */
++};
++
++extern unsigned long rq_load_util(int cpu);
++
++extern unsigned long calc_load_update;
++extern atomic_long_t calc_load_tasks;
++
++extern void calc_global_load_tick(struct rq *this_rq);
++extern long calc_load_fold_active(struct rq *this_rq, long adjust);
++
++DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
++#define cpu_rq(cpu)		(&per_cpu(runqueues, (cpu)))
++#define this_rq()		this_cpu_ptr(&runqueues)
++#define task_rq(p)		cpu_rq(task_cpu(p))
++#define cpu_curr(cpu)		(cpu_rq(cpu)->curr)
++#define raw_rq()		raw_cpu_ptr(&runqueues)
++
++#ifdef CONFIG_SMP
++#if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SYSCTL)
++void register_sched_domain_sysctl(void);
++void unregister_sched_domain_sysctl(void);
++#else
++static inline void register_sched_domain_sysctl(void)
++{
++}
++static inline void unregister_sched_domain_sysctl(void)
++{
++}
++#endif
++
++extern bool sched_smp_initialized;
++
++enum {
++	ITSELF_LEVEL_SPACE_HOLDER,
++#ifdef CONFIG_SCHED_SMT
++	SMT_LEVEL_SPACE_HOLDER,
++#endif
++	COREGROUP_LEVEL_SPACE_HOLDER,
++	CORE_LEVEL_SPACE_HOLDER,
++	OTHER_LEVEL_SPACE_HOLDER,
++	NR_CPU_AFFINITY_LEVELS
++};
++
++DECLARE_PER_CPU(cpumask_t [NR_CPU_AFFINITY_LEVELS], sched_cpu_topo_masks);
++DECLARE_PER_CPU(cpumask_t *, sched_cpu_llc_mask);
++
++static inline int
++__best_mask_cpu(const cpumask_t *cpumask, const cpumask_t *mask)
++{
++	int cpu;
++
++	while ((cpu = cpumask_any_and(cpumask, mask)) >= nr_cpu_ids)
++		mask++;
++
++	return cpu;
++}
++
++static inline int best_mask_cpu(int cpu, const cpumask_t *mask)
++{
++	return __best_mask_cpu(mask, per_cpu(sched_cpu_topo_masks, cpu));
++}
++
++extern void flush_smp_call_function_queue(void);
++
++#else  /* !CONFIG_SMP */
++static inline void flush_smp_call_function_queue(void) { }
++#endif
++
++#ifndef arch_scale_freq_tick
++static __always_inline
++void arch_scale_freq_tick(void)
++{
++}
++#endif
++
++#ifndef arch_scale_freq_capacity
++static __always_inline
++unsigned long arch_scale_freq_capacity(int cpu)
++{
++	return SCHED_CAPACITY_SCALE;
++}
++#endif
++
++static inline u64 __rq_clock_broken(struct rq *rq)
++{
++	return READ_ONCE(rq->clock);
++}
++
++static inline u64 rq_clock(struct rq *rq)
++{
++	/*
++	 * Relax lockdep_assert_held() checking as in VRQ, call to
++	 * sched_info_xxxx() may not held rq->lock
++	 * lockdep_assert_held(&rq->lock);
++	 */
++	return rq->clock;
++}
++
++static inline u64 rq_clock_task(struct rq *rq)
++{
++	/*
++	 * Relax lockdep_assert_held() checking as in VRQ, call to
++	 * sched_info_xxxx() may not held rq->lock
++	 * lockdep_assert_held(&rq->lock);
++	 */
++	return rq->clock_task;
++}
++
++/*
++ * {de,en}queue flags:
++ *
++ * DEQUEUE_SLEEP  - task is no longer runnable
++ * ENQUEUE_WAKEUP - task just became runnable
++ *
++ */
++
++#define DEQUEUE_SLEEP		0x01
++
++#define ENQUEUE_WAKEUP		0x01
++
++
++/*
++ * Below are scheduler API which using in other kernel code
++ * It use the dummy rq_flags
++ * ToDo : BMQ need to support these APIs for compatibility with mainline
++ * scheduler code.
++ */
++struct rq_flags {
++	unsigned long flags;
++};
++
++struct rq *__task_rq_lock(struct task_struct *p, struct rq_flags *rf)
++	__acquires(rq->lock);
++
++struct rq *task_rq_lock(struct task_struct *p, struct rq_flags *rf)
++	__acquires(p->pi_lock)
++	__acquires(rq->lock);
++
++static inline void __task_rq_unlock(struct rq *rq, struct rq_flags *rf)
++	__releases(rq->lock)
++{
++	raw_spin_unlock(&rq->lock);
++}
++
++static inline void
++task_rq_unlock(struct rq *rq, struct task_struct *p, struct rq_flags *rf)
++	__releases(rq->lock)
++	__releases(p->pi_lock)
++{
++	raw_spin_unlock(&rq->lock);
++	raw_spin_unlock_irqrestore(&p->pi_lock, rf->flags);
++}
++
++static inline void
++rq_lock(struct rq *rq, struct rq_flags *rf)
++	__acquires(rq->lock)
++{
++	raw_spin_lock(&rq->lock);
++}
++
++static inline void
++rq_unlock_irq(struct rq *rq, struct rq_flags *rf)
++	__releases(rq->lock)
++{
++	raw_spin_unlock_irq(&rq->lock);
++}
++
++static inline void
++rq_unlock(struct rq *rq, struct rq_flags *rf)
++	__releases(rq->lock)
++{
++	raw_spin_unlock(&rq->lock);
++}
++
++static inline struct rq *
++this_rq_lock_irq(struct rq_flags *rf)
++	__acquires(rq->lock)
++{
++	struct rq *rq;
++
++	local_irq_disable();
++	rq = this_rq();
++	raw_spin_lock(&rq->lock);
++
++	return rq;
++}
++
++static inline raw_spinlock_t *__rq_lockp(struct rq *rq)
++{
++	return &rq->lock;
++}
++
++static inline raw_spinlock_t *rq_lockp(struct rq *rq)
++{
++	return __rq_lockp(rq);
++}
++
++static inline void lockdep_assert_rq_held(struct rq *rq)
++{
++	lockdep_assert_held(__rq_lockp(rq));
++}
++
++extern void raw_spin_rq_lock_nested(struct rq *rq, int subclass);
++extern void raw_spin_rq_unlock(struct rq *rq);
++
++static inline void raw_spin_rq_lock(struct rq *rq)
++{
++	raw_spin_rq_lock_nested(rq, 0);
++}
++
++static inline void raw_spin_rq_lock_irq(struct rq *rq)
++{
++	local_irq_disable();
++	raw_spin_rq_lock(rq);
++}
++
++static inline void raw_spin_rq_unlock_irq(struct rq *rq)
++{
++	raw_spin_rq_unlock(rq);
++	local_irq_enable();
++}
++
++static inline int task_current(struct rq *rq, struct task_struct *p)
++{
++	return rq->curr == p;
++}
++
++static inline bool task_running(struct task_struct *p)
++{
++	return p->on_cpu;
++}
++
++extern int task_running_nice(struct task_struct *p);
++
++extern struct static_key_false sched_schedstats;
++
++#ifdef CONFIG_CPU_IDLE
++static inline void idle_set_state(struct rq *rq,
++				  struct cpuidle_state *idle_state)
++{
++	rq->idle_state = idle_state;
++}
++
++static inline struct cpuidle_state *idle_get_state(struct rq *rq)
++{
++	WARN_ON(!rcu_read_lock_held());
++	return rq->idle_state;
++}
++#else
++static inline void idle_set_state(struct rq *rq,
++				  struct cpuidle_state *idle_state)
++{
++}
++
++static inline struct cpuidle_state *idle_get_state(struct rq *rq)
++{
++	return NULL;
++}
++#endif
++
++static inline int cpu_of(const struct rq *rq)
++{
++#ifdef CONFIG_SMP
++	return rq->cpu;
++#else
++	return 0;
++#endif
++}
++
++#include "stats.h"
++
++#ifdef CONFIG_NO_HZ_COMMON
++#define NOHZ_BALANCE_KICK_BIT	0
++#define NOHZ_STATS_KICK_BIT	1
++
++#define NOHZ_BALANCE_KICK	BIT(NOHZ_BALANCE_KICK_BIT)
++#define NOHZ_STATS_KICK		BIT(NOHZ_STATS_KICK_BIT)
++
++#define NOHZ_KICK_MASK	(NOHZ_BALANCE_KICK | NOHZ_STATS_KICK)
++
++#define nohz_flags(cpu)	(&cpu_rq(cpu)->nohz_flags)
++
++/* TODO: needed?
++extern void nohz_balance_exit_idle(struct rq *rq);
++#else
++static inline void nohz_balance_exit_idle(struct rq *rq) { }
++*/
++#endif
++
++#ifdef CONFIG_IRQ_TIME_ACCOUNTING
++struct irqtime {
++	u64			total;
++	u64			tick_delta;
++	u64			irq_start_time;
++	struct u64_stats_sync	sync;
++};
++
++DECLARE_PER_CPU(struct irqtime, cpu_irqtime);
++
++/*
++ * Returns the irqtime minus the softirq time computed by ksoftirqd.
++ * Otherwise ksoftirqd's sum_exec_runtime is substracted its own runtime
++ * and never move forward.
++ */
++static inline u64 irq_time_read(int cpu)
++{
++	struct irqtime *irqtime = &per_cpu(cpu_irqtime, cpu);
++	unsigned int seq;
++	u64 total;
++
++	do {
++		seq = __u64_stats_fetch_begin(&irqtime->sync);
++		total = irqtime->total;
++	} while (__u64_stats_fetch_retry(&irqtime->sync, seq));
++
++	return total;
++}
++#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
++
++#ifdef CONFIG_CPU_FREQ
++DECLARE_PER_CPU(struct update_util_data __rcu *, cpufreq_update_util_data);
++#endif /* CONFIG_CPU_FREQ */
++
++#ifdef CONFIG_NO_HZ_FULL
++extern int __init sched_tick_offload_init(void);
++#else
++static inline int sched_tick_offload_init(void) { return 0; }
++#endif
++
++#ifdef arch_scale_freq_capacity
++#ifndef arch_scale_freq_invariant
++#define arch_scale_freq_invariant()	(true)
++#endif
++#else /* arch_scale_freq_capacity */
++#define arch_scale_freq_invariant()	(false)
++#endif
++
++extern void schedule_idle(void);
++
++#define cap_scale(v, s) ((v)*(s) >> SCHED_CAPACITY_SHIFT)
++
++/*
++ * !! For sched_setattr_nocheck() (kernel) only !!
++ *
++ * This is actually gross. :(
++ *
++ * It is used to make schedutil kworker(s) higher priority than SCHED_DEADLINE
++ * tasks, but still be able to sleep. We need this on platforms that cannot
++ * atomically change clock frequency. Remove once fast switching will be
++ * available on such platforms.
++ *
++ * SUGOV stands for SchedUtil GOVernor.
++ */
++#define SCHED_FLAG_SUGOV	0x10000000
++
++#ifdef CONFIG_MEMBARRIER
++/*
++ * The scheduler provides memory barriers required by membarrier between:
++ * - prior user-space memory accesses and store to rq->membarrier_state,
++ * - store to rq->membarrier_state and following user-space memory accesses.
++ * In the same way it provides those guarantees around store to rq->curr.
++ */
++static inline void membarrier_switch_mm(struct rq *rq,
++					struct mm_struct *prev_mm,
++					struct mm_struct *next_mm)
++{
++	int membarrier_state;
++
++	if (prev_mm == next_mm)
++		return;
++
++	membarrier_state = atomic_read(&next_mm->membarrier_state);
++	if (READ_ONCE(rq->membarrier_state) == membarrier_state)
++		return;
++
++	WRITE_ONCE(rq->membarrier_state, membarrier_state);
++}
++#else
++static inline void membarrier_switch_mm(struct rq *rq,
++					struct mm_struct *prev_mm,
++					struct mm_struct *next_mm)
++{
++}
++#endif
++
++#ifdef CONFIG_NUMA
++extern int sched_numa_find_closest(const struct cpumask *cpus, int cpu);
++#else
++static inline int sched_numa_find_closest(const struct cpumask *cpus, int cpu)
++{
++	return nr_cpu_ids;
++}
++#endif
++
++extern void swake_up_all_locked(struct swait_queue_head *q);
++extern void __prepare_to_swait(struct swait_queue_head *q, struct swait_queue *wait);
++
++#ifdef CONFIG_PREEMPT_DYNAMIC
++extern int preempt_dynamic_mode;
++extern int sched_dynamic_mode(const char *str);
++extern void sched_dynamic_update(int mode);
++#endif
++
++static inline void nohz_run_idle_balance(int cpu) { }
++
++static inline
++unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
++				  struct task_struct *p)
++{
++	return util;
++}
++
++static inline bool uclamp_rq_is_capped(struct rq *rq) { return false; }
++
++#endif /* ALT_SCHED_H */
+diff --git a/kernel/sched/bmq.h b/kernel/sched/bmq.h
+new file mode 100644
+index 000000000000..66b77291b9d0
+--- /dev/null
++++ b/kernel/sched/bmq.h
+@@ -0,0 +1,110 @@
++#define ALT_SCHED_VERSION_MSG "sched/bmq: BMQ CPU Scheduler "ALT_SCHED_VERSION" by Alfred Chen.\n"
++
++/*
++ * BMQ only routines
++ */
++#define rq_switch_time(rq)	((rq)->clock - (rq)->last_ts_switch)
++#define boost_threshold(p)	(sched_timeslice_ns >>\
++				 (15 - MAX_PRIORITY_ADJ -  (p)->boost_prio))
++
++static inline void boost_task(struct task_struct *p)
++{
++	int limit;
++
++	switch (p->policy) {
++	case SCHED_NORMAL:
++		limit = -MAX_PRIORITY_ADJ;
++		break;
++	case SCHED_BATCH:
++	case SCHED_IDLE:
++		limit = 0;
++		break;
++	default:
++		return;
++	}
++
++	if (p->boost_prio > limit)
++		p->boost_prio--;
++}
++
++static inline void deboost_task(struct task_struct *p)
++{
++	if (p->boost_prio < MAX_PRIORITY_ADJ)
++		p->boost_prio++;
++}
++
++/*
++ * Common interfaces
++ */
++static inline void sched_timeslice_imp(const int timeslice_ms) {}
++
++static inline int
++task_sched_prio_normal(const struct task_struct *p, const struct rq *rq)
++{
++	return p->prio + p->boost_prio - MAX_RT_PRIO;
++}
++
++static inline int task_sched_prio(const struct task_struct *p)
++{
++	return (p->prio < MAX_RT_PRIO)? p->prio : MAX_RT_PRIO / 2 + (p->prio + p->boost_prio) / 2;
++}
++
++static inline int
++task_sched_prio_idx(const struct task_struct *p, const struct rq *rq)
++{
++	return task_sched_prio(p);
++}
++
++static inline int sched_prio2idx(int prio, struct rq *rq)
++{
++	return prio;
++}
++
++static inline int sched_idx2prio(int idx, struct rq *rq)
++{
++	return idx;
++}
++
++static inline void time_slice_expired(struct task_struct *p, struct rq *rq)
++{
++	p->time_slice = sched_timeslice_ns;
++
++	if (SCHED_FIFO != p->policy && task_on_rq_queued(p)) {
++		if (SCHED_RR != p->policy)
++			deboost_task(p);
++		requeue_task(p, rq, task_sched_prio_idx(p, rq));
++	}
++}
++
++static inline void sched_task_sanity_check(struct task_struct *p, struct rq *rq) {}
++
++inline int task_running_nice(struct task_struct *p)
++{
++	return (p->prio + p->boost_prio > DEFAULT_PRIO + MAX_PRIORITY_ADJ);
++}
++
++static void sched_task_fork(struct task_struct *p, struct rq *rq)
++{
++	p->boost_prio = MAX_PRIORITY_ADJ;
++}
++
++static inline void do_sched_yield_type_1(struct task_struct *p, struct rq *rq)
++{
++	p->boost_prio = MAX_PRIORITY_ADJ;
++}
++
++#ifdef CONFIG_SMP
++static inline void sched_task_ttwu(struct task_struct *p)
++{
++	if(this_rq()->clock_task - p->last_ran > sched_timeslice_ns)
++		boost_task(p);
++}
++#endif
++
++static inline void sched_task_deactivate(struct task_struct *p, struct rq *rq)
++{
++	if (rq_switch_time(rq) < boost_threshold(p))
++		boost_task(p);
++}
++
++static inline void update_rq_time_edge(struct rq *rq) {}
+diff --git a/kernel/sched/build_policy.c b/kernel/sched/build_policy.c
+index d9dc9ab3773f..71a25540d65e 100644
+--- a/kernel/sched/build_policy.c
++++ b/kernel/sched/build_policy.c
+@@ -42,13 +42,19 @@
+ 
+ #include "idle.c"
+ 
++#ifndef CONFIG_SCHED_ALT
+ #include "rt.c"
++#endif
+ 
+ #ifdef CONFIG_SMP
++#ifndef CONFIG_SCHED_ALT
+ # include "cpudeadline.c"
++#endif
+ # include "pelt.c"
+ #endif
+ 
+ #include "cputime.c"
+-#include "deadline.c"
+ 
++#ifndef CONFIG_SCHED_ALT
++#include "deadline.c"
++#endif
+diff --git a/kernel/sched/build_utility.c b/kernel/sched/build_utility.c
+index 99bdd96f454f..23f80a86d2d7 100644
+--- a/kernel/sched/build_utility.c
++++ b/kernel/sched/build_utility.c
+@@ -85,7 +85,9 @@
+ 
+ #ifdef CONFIG_SMP
+ # include "cpupri.c"
++#ifndef CONFIG_SCHED_ALT
+ # include "stop_task.c"
++#endif
+ # include "topology.c"
+ #endif
+ 
+diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
+index 1207c78f85c1..3ed06d7ef4f8 100644
+--- a/kernel/sched/cpufreq_schedutil.c
++++ b/kernel/sched/cpufreq_schedutil.c
+@@ -159,9 +159,14 @@ static void sugov_get_util(struct sugov_cpu *sg_cpu)
+ 	struct rq *rq = cpu_rq(sg_cpu->cpu);
+ 
+ 	sg_cpu->max = arch_scale_cpu_capacity(sg_cpu->cpu);
++#ifndef CONFIG_SCHED_ALT
+ 	sg_cpu->bw_dl = cpu_bw_dl(rq);
+ 	sg_cpu->util = effective_cpu_util(sg_cpu->cpu, cpu_util_cfs(sg_cpu->cpu),
+ 					  FREQUENCY_UTIL, NULL);
++#else
++	sg_cpu->bw_dl = 0;
++	sg_cpu->util = rq_load_util(cpu_of(rq));
++#endif /* CONFIG_SCHED_ALT */
+ }
+ 
+ /**
+@@ -305,8 +310,10 @@ static inline bool sugov_cpu_is_busy(struct sugov_cpu *sg_cpu) { return false; }
+  */
+ static inline void ignore_dl_rate_limit(struct sugov_cpu *sg_cpu)
+ {
++#ifndef CONFIG_SCHED_ALT
+ 	if (cpu_bw_dl(cpu_rq(sg_cpu->cpu)) > sg_cpu->bw_dl)
+ 		sg_cpu->sg_policy->limits_changed = true;
++#endif
+ }
+ 
+ static inline bool sugov_update_single_common(struct sugov_cpu *sg_cpu,
+@@ -606,6 +613,7 @@ static int sugov_kthread_create(struct sugov_policy *sg_policy)
+ 	}
+ 
+ 	ret = sched_setattr_nocheck(thread, &attr);
++
+ 	if (ret) {
+ 		kthread_stop(thread);
+ 		pr_warn("%s: failed to set SCHED_DEADLINE\n", __func__);
+@@ -838,7 +846,9 @@ cpufreq_governor_init(schedutil_gov);
+ #ifdef CONFIG_ENERGY_MODEL
+ static void rebuild_sd_workfn(struct work_struct *work)
+ {
++#ifndef CONFIG_SCHED_ALT
+ 	rebuild_sched_domains_energy();
++#endif /* CONFIG_SCHED_ALT */
+ }
+ static DECLARE_WORK(rebuild_sd_work, rebuild_sd_workfn);
+ 
+diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
+index 95fc77853743..b48b3f9ed47f 100644
+--- a/kernel/sched/cputime.c
++++ b/kernel/sched/cputime.c
+@@ -122,7 +122,7 @@ void account_user_time(struct task_struct *p, u64 cputime)
+ 	p->utime += cputime;
+ 	account_group_user_time(p, cputime);
+ 
+-	index = (task_nice(p) > 0) ? CPUTIME_NICE : CPUTIME_USER;
++	index = task_running_nice(p) ? CPUTIME_NICE : CPUTIME_USER;
+ 
+ 	/* Add user time to cpustat. */
+ 	task_group_account_field(p, index, cputime);
+@@ -146,7 +146,7 @@ void account_guest_time(struct task_struct *p, u64 cputime)
+ 	p->gtime += cputime;
+ 
+ 	/* Add guest time to cpustat. */
+-	if (task_nice(p) > 0) {
++	if (task_running_nice(p)) {
+ 		task_group_account_field(p, CPUTIME_NICE, cputime);
+ 		cpustat[CPUTIME_GUEST_NICE] += cputime;
+ 	} else {
+@@ -284,7 +284,7 @@ static inline u64 account_other_time(u64 max)
+ #ifdef CONFIG_64BIT
+ static inline u64 read_sum_exec_runtime(struct task_struct *t)
+ {
+-	return t->se.sum_exec_runtime;
++	return tsk_seruntime(t);
+ }
+ #else
+ static u64 read_sum_exec_runtime(struct task_struct *t)
+@@ -294,7 +294,7 @@ static u64 read_sum_exec_runtime(struct task_struct *t)
+ 	struct rq *rq;
+ 
+ 	rq = task_rq_lock(t, &rf);
+-	ns = t->se.sum_exec_runtime;
++	ns = tsk_seruntime(t);
+ 	task_rq_unlock(rq, t, &rf);
+ 
+ 	return ns;
+@@ -626,7 +626,7 @@ void cputime_adjust(struct task_cputime *curr, struct prev_cputime *prev,
+ void task_cputime_adjusted(struct task_struct *p, u64 *ut, u64 *st)
+ {
+ 	struct task_cputime cputime = {
+-		.sum_exec_runtime = p->se.sum_exec_runtime,
++		.sum_exec_runtime = tsk_seruntime(p),
+ 	};
+ 
+ 	if (task_cputime(p, &cputime.utime, &cputime.stime))
+diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
+index 667876da8382..a416d4bedd98 100644
+--- a/kernel/sched/debug.c
++++ b/kernel/sched/debug.c
+@@ -7,6 +7,7 @@
+  * Copyright(C) 2007, Red Hat, Inc., Ingo Molnar
+  */
+ 
++#ifndef CONFIG_SCHED_ALT
+ /*
+  * This allows printing both to /proc/sched_debug and
+  * to the console
+@@ -215,6 +216,7 @@ static const struct file_operations sched_scaling_fops = {
+ };
+ 
+ #endif /* SMP */
++#endif /* !CONFIG_SCHED_ALT */
+ 
+ #ifdef CONFIG_PREEMPT_DYNAMIC
+ 
+@@ -278,6 +280,7 @@ static const struct file_operations sched_dynamic_fops = {
+ 
+ #endif /* CONFIG_PREEMPT_DYNAMIC */
+ 
++#ifndef CONFIG_SCHED_ALT
+ __read_mostly bool sched_debug_verbose;
+ 
+ static const struct seq_operations sched_debug_sops;
+@@ -293,6 +296,7 @@ static const struct file_operations sched_debug_fops = {
+ 	.llseek		= seq_lseek,
+ 	.release	= seq_release,
+ };
++#endif /* !CONFIG_SCHED_ALT */
+ 
+ static struct dentry *debugfs_sched;
+ 
+@@ -302,12 +306,15 @@ static __init int sched_init_debug(void)
+ 
+ 	debugfs_sched = debugfs_create_dir("sched", NULL);
+ 
++#ifndef CONFIG_SCHED_ALT
+ 	debugfs_create_file("features", 0644, debugfs_sched, NULL, &sched_feat_fops);
+ 	debugfs_create_bool("verbose", 0644, debugfs_sched, &sched_debug_verbose);
++#endif /* !CONFIG_SCHED_ALT */
+ #ifdef CONFIG_PREEMPT_DYNAMIC
+ 	debugfs_create_file("preempt", 0644, debugfs_sched, NULL, &sched_dynamic_fops);
+ #endif
+ 
++#ifndef CONFIG_SCHED_ALT
+ 	debugfs_create_u32("latency_ns", 0644, debugfs_sched, &sysctl_sched_latency);
+ 	debugfs_create_u32("min_granularity_ns", 0644, debugfs_sched, &sysctl_sched_min_granularity);
+ 	debugfs_create_u32("idle_min_granularity_ns", 0644, debugfs_sched, &sysctl_sched_idle_min_granularity);
+@@ -336,11 +343,13 @@ static __init int sched_init_debug(void)
+ #endif
+ 
+ 	debugfs_create_file("debug", 0444, debugfs_sched, NULL, &sched_debug_fops);
++#endif /* !CONFIG_SCHED_ALT */
+ 
+ 	return 0;
+ }
+ late_initcall(sched_init_debug);
+ 
++#ifndef CONFIG_SCHED_ALT
+ #ifdef CONFIG_SMP
+ 
+ static cpumask_var_t		sd_sysctl_cpus;
+@@ -1067,6 +1076,7 @@ void proc_sched_set_task(struct task_struct *p)
+ 	memset(&p->stats, 0, sizeof(p->stats));
+ #endif
+ }
++#endif /* !CONFIG_SCHED_ALT */
+ 
+ void resched_latency_warn(int cpu, u64 latency)
+ {
+diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
+index f26ab2675f7d..480d4ad16d45 100644
+--- a/kernel/sched/idle.c
++++ b/kernel/sched/idle.c
+@@ -400,6 +400,7 @@ void cpu_startup_entry(enum cpuhp_state state)
+ 		do_idle();
+ }
+ 
++#ifndef CONFIG_SCHED_ALT
+ /*
+  * idle-task scheduling class.
+  */
+@@ -521,3 +522,4 @@ DEFINE_SCHED_CLASS(idle) = {
+ 	.switched_to		= switched_to_idle,
+ 	.update_curr		= update_curr_idle,
+ };
++#endif
+diff --git a/kernel/sched/pds.h b/kernel/sched/pds.h
+new file mode 100644
+index 000000000000..56a649d02e49
+--- /dev/null
++++ b/kernel/sched/pds.h
+@@ -0,0 +1,127 @@
++#define ALT_SCHED_VERSION_MSG "sched/pds: PDS CPU Scheduler "ALT_SCHED_VERSION" by Alfred Chen.\n"
++
++static int sched_timeslice_shift = 22;
++
++#define NORMAL_PRIO_MOD(x)	((x) & (NORMAL_PRIO_NUM - 1))
++
++/*
++ * Common interfaces
++ */
++static inline void sched_timeslice_imp(const int timeslice_ms)
++{
++	if (2 == timeslice_ms)
++		sched_timeslice_shift = 21;
++}
++
++static inline int
++task_sched_prio_normal(const struct task_struct *p, const struct rq *rq)
++{
++	s64 delta = p->deadline - rq->time_edge + NORMAL_PRIO_NUM - NICE_WIDTH;
++
++	if (WARN_ONCE(delta > NORMAL_PRIO_NUM - 1,
++		      "pds: task_sched_prio_normal() delta %lld\n", delta))
++		return NORMAL_PRIO_NUM - 1;
++
++	return (delta < 0) ? 0 : delta;
++}
++
++static inline int task_sched_prio(const struct task_struct *p)
++{
++	return (p->prio < MAX_RT_PRIO) ? p->prio :
++		MIN_NORMAL_PRIO + task_sched_prio_normal(p, task_rq(p));
++}
++
++static inline int
++task_sched_prio_idx(const struct task_struct *p, const struct rq *rq)
++{
++	return (p->prio < MAX_RT_PRIO) ? p->prio : MIN_NORMAL_PRIO +
++		NORMAL_PRIO_MOD(task_sched_prio_normal(p, rq) + rq->time_edge);
++}
++
++static inline int sched_prio2idx(int prio, struct rq *rq)
++{
++	return (IDLE_TASK_SCHED_PRIO == prio || prio < MAX_RT_PRIO) ? prio :
++		MIN_NORMAL_PRIO + NORMAL_PRIO_MOD((prio - MIN_NORMAL_PRIO) +
++						  rq->time_edge);
++}
++
++static inline int sched_idx2prio(int idx, struct rq *rq)
++{
++	return (idx < MAX_RT_PRIO) ? idx : MIN_NORMAL_PRIO +
++		NORMAL_PRIO_MOD((idx - MIN_NORMAL_PRIO) + NORMAL_PRIO_NUM -
++				NORMAL_PRIO_MOD(rq->time_edge));
++}
++
++static inline void sched_renew_deadline(struct task_struct *p, const struct rq *rq)
++{
++	if (p->prio >= MAX_RT_PRIO)
++		p->deadline = (rq->clock >> sched_timeslice_shift) +
++			p->static_prio - (MAX_PRIO - NICE_WIDTH);
++}
++
++int task_running_nice(struct task_struct *p)
++{
++	return (p->prio > DEFAULT_PRIO);
++}
++
++static inline void update_rq_time_edge(struct rq *rq)
++{
++	struct list_head head;
++	u64 old = rq->time_edge;
++	u64 now = rq->clock >> sched_timeslice_shift;
++	u64 prio, delta;
++
++	if (now == old)
++		return;
++
++	delta = min_t(u64, NORMAL_PRIO_NUM, now - old);
++	INIT_LIST_HEAD(&head);
++
++	for_each_set_bit(prio, &rq->queue.bitmap[2], delta)
++		list_splice_tail_init(rq->queue.heads + MIN_NORMAL_PRIO +
++				      NORMAL_PRIO_MOD(prio + old), &head);
++
++	rq->queue.bitmap[2] = (NORMAL_PRIO_NUM == delta) ? 0UL :
++		rq->queue.bitmap[2] >> delta;
++	rq->time_edge = now;
++	if (!list_empty(&head)) {
++		u64 idx = MIN_NORMAL_PRIO + NORMAL_PRIO_MOD(now);
++		struct task_struct *p;
++
++		list_for_each_entry(p, &head, sq_node)
++			p->sq_idx = idx;
++
++		list_splice(&head, rq->queue.heads + idx);
++		rq->queue.bitmap[2] |= 1UL;
++	}
++}
++
++static inline void time_slice_expired(struct task_struct *p, struct rq *rq)
++{
++	p->time_slice = sched_timeslice_ns;
++	sched_renew_deadline(p, rq);
++	if (SCHED_FIFO != p->policy && task_on_rq_queued(p))
++		requeue_task(p, rq, task_sched_prio_idx(p, rq));
++}
++
++static inline void sched_task_sanity_check(struct task_struct *p, struct rq *rq)
++{
++	u64 max_dl = rq->time_edge + NICE_WIDTH - 1;
++	if (unlikely(p->deadline > max_dl))
++		p->deadline = max_dl;
++}
++
++static void sched_task_fork(struct task_struct *p, struct rq *rq)
++{
++	sched_renew_deadline(p, rq);
++}
++
++static inline void do_sched_yield_type_1(struct task_struct *p, struct rq *rq)
++{
++	time_slice_expired(p, rq);
++}
++
++#ifdef CONFIG_SMP
++static inline void sched_task_ttwu(struct task_struct *p) {}
++#endif
++static inline void sched_task_deactivate(struct task_struct *p, struct rq *rq) {}
+diff --git a/kernel/sched/pelt.c b/kernel/sched/pelt.c
+index 0f310768260c..bd38bf738fe9 100644
+--- a/kernel/sched/pelt.c
++++ b/kernel/sched/pelt.c
+@@ -266,6 +266,7 @@ ___update_load_avg(struct sched_avg *sa, unsigned long load)
+ 	WRITE_ONCE(sa->util_avg, sa->util_sum / divider);
+ }
+ 
++#ifndef CONFIG_SCHED_ALT
+ /*
+  * sched_entity:
+  *
+@@ -383,8 +384,9 @@ int update_dl_rq_load_avg(u64 now, struct rq *rq, int running)
+ 
+ 	return 0;
+ }
++#endif
+ 
+-#ifdef CONFIG_SCHED_THERMAL_PRESSURE
++#if defined(CONFIG_SCHED_THERMAL_PRESSURE) && !defined(CONFIG_SCHED_ALT)
+ /*
+  * thermal:
+  *
+diff --git a/kernel/sched/pelt.h b/kernel/sched/pelt.h
+index 3a0e0dc28721..e8a7d84aa5a5 100644
+--- a/kernel/sched/pelt.h
++++ b/kernel/sched/pelt.h
+@@ -1,13 +1,15 @@
+ #ifdef CONFIG_SMP
+ #include "sched-pelt.h"
+ 
++#ifndef CONFIG_SCHED_ALT
+ int __update_load_avg_blocked_se(u64 now, struct sched_entity *se);
+ int __update_load_avg_se(u64 now, struct cfs_rq *cfs_rq, struct sched_entity *se);
+ int __update_load_avg_cfs_rq(u64 now, struct cfs_rq *cfs_rq);
+ int update_rt_rq_load_avg(u64 now, struct rq *rq, int running);
+ int update_dl_rq_load_avg(u64 now, struct rq *rq, int running);
++#endif
+ 
+-#ifdef CONFIG_SCHED_THERMAL_PRESSURE
++#if defined(CONFIG_SCHED_THERMAL_PRESSURE) && !defined(CONFIG_SCHED_ALT)
+ int update_thermal_load_avg(u64 now, struct rq *rq, u64 capacity);
+ 
+ static inline u64 thermal_load_avg(struct rq *rq)
+@@ -44,6 +46,7 @@ static inline u32 get_pelt_divider(struct sched_avg *avg)
+ 	return PELT_MIN_DIVIDER + avg->period_contrib;
+ }
+ 
++#ifndef CONFIG_SCHED_ALT
+ static inline void cfs_se_util_change(struct sched_avg *avg)
+ {
+ 	unsigned int enqueued;
+@@ -180,9 +183,11 @@ static inline u64 cfs_rq_clock_pelt(struct cfs_rq *cfs_rq)
+ 	return rq_clock_pelt(rq_of(cfs_rq));
+ }
+ #endif
++#endif /* CONFIG_SCHED_ALT */
+ 
+ #else
+ 
++#ifndef CONFIG_SCHED_ALT
+ static inline int
+ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
+ {
+@@ -200,6 +205,7 @@ update_dl_rq_load_avg(u64 now, struct rq *rq, int running)
+ {
+ 	return 0;
+ }
++#endif
+ 
+ static inline int
+ update_thermal_load_avg(u64 now, struct rq *rq, u64 capacity)
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index e26688d387ae..48d5823f9d84 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -5,6 +5,10 @@
+ #ifndef _KERNEL_SCHED_SCHED_H
+ #define _KERNEL_SCHED_SCHED_H
+ 
++#ifdef CONFIG_SCHED_ALT
++#include "alt_sched.h"
++#else
++
+ #include <linux/sched/affinity.h>
+ #include <linux/sched/autogroup.h>
+ #include <linux/sched/cpufreq.h>
+@@ -3157,4 +3161,9 @@ extern int sched_dynamic_mode(const char *str);
+ extern void sched_dynamic_update(int mode);
+ #endif
+ 
++static inline int task_running_nice(struct task_struct *p)
++{
++	return (task_nice(p) > 0);
++}
++#endif /* !CONFIG_SCHED_ALT */
+ #endif /* _KERNEL_SCHED_SCHED_H */
+diff --git a/kernel/sched/stats.c b/kernel/sched/stats.c
+index 857f837f52cb..5486c63e4790 100644
+--- a/kernel/sched/stats.c
++++ b/kernel/sched/stats.c
+@@ -125,8 +125,10 @@ static int show_schedstat(struct seq_file *seq, void *v)
+ 	} else {
+ 		struct rq *rq;
+ #ifdef CONFIG_SMP
++#ifndef CONFIG_SCHED_ALT
+ 		struct sched_domain *sd;
+ 		int dcount = 0;
++#endif
+ #endif
+ 		cpu = (unsigned long)(v - 2);
+ 		rq = cpu_rq(cpu);
+@@ -143,6 +145,7 @@ static int show_schedstat(struct seq_file *seq, void *v)
+ 		seq_printf(seq, "\n");
+ 
+ #ifdef CONFIG_SMP
++#ifndef CONFIG_SCHED_ALT
+ 		/* domain-specific stats */
+ 		rcu_read_lock();
+ 		for_each_domain(cpu, sd) {
+@@ -171,6 +174,7 @@ static int show_schedstat(struct seq_file *seq, void *v)
+ 			    sd->ttwu_move_balance);
+ 		}
+ 		rcu_read_unlock();
++#endif
+ #endif
+ 	}
+ 	return 0;
+diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h
+index baa839c1ba96..15238be0581b 100644
+--- a/kernel/sched/stats.h
++++ b/kernel/sched/stats.h
+@@ -89,6 +89,7 @@ static inline void rq_sched_info_depart  (struct rq *rq, unsigned long long delt
+ 
+ #endif /* CONFIG_SCHEDSTATS */
+ 
++#ifndef CONFIG_SCHED_ALT
+ #ifdef CONFIG_FAIR_GROUP_SCHED
+ struct sched_entity_stats {
+ 	struct sched_entity     se;
+@@ -105,6 +106,7 @@ __schedstats_from_se(struct sched_entity *se)
+ #endif
+ 	return &task_of(se)->stats;
+ }
++#endif /* CONFIG_SCHED_ALT */
+ 
+ #ifdef CONFIG_PSI
+ /*
+diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
+index 8739c2a5a54e..d8dd6c15eb47 100644
+--- a/kernel/sched/topology.c
++++ b/kernel/sched/topology.c
+@@ -3,6 +3,7 @@
+  * Scheduler topology setup/handling methods
+  */
+ 
++#ifndef CONFIG_SCHED_ALT
+ DEFINE_MUTEX(sched_domains_mutex);
+ 
+ /* Protected by sched_domains_mutex: */
+@@ -1413,8 +1414,10 @@ static void asym_cpu_capacity_scan(void)
+  */
+ 
+ static int default_relax_domain_level = -1;
++#endif /* CONFIG_SCHED_ALT */
+ int sched_domain_level_max;
+ 
++#ifndef CONFIG_SCHED_ALT
+ static int __init setup_relax_domain_level(char *str)
+ {
+ 	if (kstrtoint(str, 0, &default_relax_domain_level))
+@@ -1647,6 +1650,7 @@ sd_init(struct sched_domain_topology_level *tl,
+ 
+ 	return sd;
+ }
++#endif /* CONFIG_SCHED_ALT */
+ 
+ /*
+  * Topology list, bottom-up.
+@@ -1683,6 +1687,7 @@ void set_sched_topology(struct sched_domain_topology_level *tl)
+ 	sched_domain_topology_saved = NULL;
+ }
+ 
++#ifndef CONFIG_SCHED_ALT
+ #ifdef CONFIG_NUMA
+ 
+ static const struct cpumask *sd_numa_mask(int cpu)
+@@ -2645,3 +2650,15 @@ void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
+ 	partition_sched_domains_locked(ndoms_new, doms_new, dattr_new);
+ 	mutex_unlock(&sched_domains_mutex);
+ }
++#else /* CONFIG_SCHED_ALT */
++void partition_sched_domains(int ndoms_new, cpumask_var_t doms_new[],
++			     struct sched_domain_attr *dattr_new)
++{}
++
++#ifdef CONFIG_NUMA
++int sched_numa_find_closest(const struct cpumask *cpus, int cpu)
++{
++	return best_mask_cpu(cpu, cpus);
++}
++#endif /* CONFIG_NUMA */
++#endif
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index 205d605cacc5..7dd950601cca 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -86,6 +86,10 @@
+ 
+ /* Constants used for minimum and  maximum */
+ 
++#ifdef CONFIG_SCHED_ALT
++extern int sched_yield_type;
++#endif
++
+ #ifdef CONFIG_PERF_EVENTS
+ static const int six_hundred_forty_kb = 640 * 1024;
+ #endif
+@@ -1631,6 +1635,7 @@ int proc_do_static_key(struct ctl_table *table, int write,
+ }
+ 
+ static struct ctl_table kern_table[] = {
++#ifndef CONFIG_SCHED_ALT
+ #ifdef CONFIG_NUMA_BALANCING
+ 	{
+ 		.procname	= "numa_balancing",
+@@ -1642,6 +1647,7 @@ static struct ctl_table kern_table[] = {
+ 		.extra2		= SYSCTL_FOUR,
+ 	},
+ #endif /* CONFIG_NUMA_BALANCING */
++#endif /* !CONFIG_SCHED_ALT */
+ 	{
+ 		.procname	= "panic",
+ 		.data		= &panic_timeout,
+@@ -1943,6 +1949,17 @@ static struct ctl_table kern_table[] = {
+ 		.proc_handler	= proc_dointvec,
+ 	},
+ #endif
++#ifdef CONFIG_SCHED_ALT
++	{
++		.procname	= "yield_type",
++		.data		= &sched_yield_type,
++		.maxlen		= sizeof (int),
++		.mode		= 0644,
++		.proc_handler	= &proc_dointvec_minmax,
++		.extra1		= SYSCTL_ZERO,
++		.extra2		= SYSCTL_TWO,
++	},
++#endif
+ #if defined(CONFIG_S390) && defined(CONFIG_SMP)
+ 	{
+ 		.procname	= "spin_retry",
+diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
+index 23af5eca11b1..792f94ce4d80 100644
+--- a/kernel/time/hrtimer.c
++++ b/kernel/time/hrtimer.c
+@@ -2088,8 +2088,10 @@ long hrtimer_nanosleep(ktime_t rqtp, const enum hrtimer_mode mode,
+ 	int ret = 0;
+ 	u64 slack;
+ 
++#ifndef CONFIG_SCHED_ALT
+ 	slack = current->timer_slack_ns;
+ 	if (dl_task(current) || rt_task(current))
++#endif
+ 		slack = 0;
+ 
+ 	hrtimer_init_sleeper_on_stack(&t, clockid, mode);
+diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
+index cb925e8ef9a8..67d823510f5c 100644
+--- a/kernel/time/posix-cpu-timers.c
++++ b/kernel/time/posix-cpu-timers.c
+@@ -223,7 +223,7 @@ static void task_sample_cputime(struct task_struct *p, u64 *samples)
+ 	u64 stime, utime;
+ 
+ 	task_cputime(p, &utime, &stime);
+-	store_samples(samples, stime, utime, p->se.sum_exec_runtime);
++	store_samples(samples, stime, utime, tsk_seruntime(p));
+ }
+ 
+ static void proc_sample_cputime_atomic(struct task_cputime_atomic *at,
+@@ -866,6 +866,7 @@ static void collect_posix_cputimers(struct posix_cputimers *pct, u64 *samples,
+ 	}
+ }
+ 
++#ifndef CONFIG_SCHED_ALT
+ static inline void check_dl_overrun(struct task_struct *tsk)
+ {
+ 	if (tsk->dl.dl_overrun) {
+@@ -873,6 +874,7 @@ static inline void check_dl_overrun(struct task_struct *tsk)
+ 		send_signal_locked(SIGXCPU, SEND_SIG_PRIV, tsk, PIDTYPE_TGID);
+ 	}
+ }
++#endif
+ 
+ static bool check_rlimit(u64 time, u64 limit, int signo, bool rt, bool hard)
+ {
+@@ -900,8 +902,10 @@ static void check_thread_timers(struct task_struct *tsk,
+ 	u64 samples[CPUCLOCK_MAX];
+ 	unsigned long soft;
+ 
++#ifndef CONFIG_SCHED_ALT
+ 	if (dl_task(tsk))
+ 		check_dl_overrun(tsk);
++#endif
+ 
+ 	if (expiry_cache_is_inactive(pct))
+ 		return;
+@@ -915,7 +919,7 @@ static void check_thread_timers(struct task_struct *tsk,
+ 	soft = task_rlimit(tsk, RLIMIT_RTTIME);
+ 	if (soft != RLIM_INFINITY) {
+ 		/* Task RT timeout is accounted in jiffies. RTTIME is usec */
+-		unsigned long rttime = tsk->rt.timeout * (USEC_PER_SEC / HZ);
++		unsigned long rttime = tsk_rttimeout(tsk) * (USEC_PER_SEC / HZ);
+ 		unsigned long hard = task_rlimit_max(tsk, RLIMIT_RTTIME);
+ 
+ 		/* At the hard limit, send SIGKILL. No further action. */
+@@ -1151,8 +1155,10 @@ static inline bool fastpath_timer_check(struct task_struct *tsk)
+ 			return true;
+ 	}
+ 
++#ifndef CONFIG_SCHED_ALT
+ 	if (dl_task(tsk) && tsk->dl.dl_overrun)
+ 		return true;
++#endif
+ 
+ 	return false;
+ }
+diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
+index a2d301f58ced..2ccdede8585c 100644
+--- a/kernel/trace/trace_selftest.c
++++ b/kernel/trace/trace_selftest.c
+@@ -1143,10 +1143,15 @@ static int trace_wakeup_test_thread(void *data)
+ {
+ 	/* Make this a -deadline thread */
+ 	static const struct sched_attr attr = {
++#ifdef CONFIG_SCHED_ALT
++		/* No deadline on BMQ/PDS, use RR */
++		.sched_policy = SCHED_RR,
++#else
+ 		.sched_policy = SCHED_DEADLINE,
+ 		.sched_runtime = 100000ULL,
+ 		.sched_deadline = 10000000ULL,
+ 		.sched_period = 10000000ULL
++#endif
+ 	};
+ 	struct wakeup_test_data *x = data;
+ 


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-12-02 17:23 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-12-02 17:23 UTC (permalink / raw
  To: gentoo-commits

commit:     6bdec7c135eddb0a34e89f2eac3ef9628666542b
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Dec  2 17:23:34 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Dec  2 17:23:34 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=6bdec7c1

Linux patch 6.0.11

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

 0000_README             |     4 +
 1010_linux-6.0.11.patch | 10345 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 10349 insertions(+)

diff --git a/0000_README b/0000_README
index bf26e8c8..12c46dfc 100644
--- a/0000_README
+++ b/0000_README
@@ -83,6 +83,10 @@ Patch:  1009_linux-6.0.10.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.10
 
+Patch:  1010_linux-6.0.11.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.11
+
 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/1010_linux-6.0.11.patch b/1010_linux-6.0.11.patch
new file mode 100644
index 00000000..43ca90bb
--- /dev/null
+++ b/1010_linux-6.0.11.patch
@@ -0,0 +1,10345 @@
+diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
+index b283c8ca2bbfc..5c08d8b6e9951 100644
+--- a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
++++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
+@@ -62,13 +62,6 @@ properties:
+     description:
+       Inform the driver that last channel will be used to sensor battery.
+ 
+-  aspeed,trim-data-valid:
+-    type: boolean
+-    description: |
+-      The ADC reference voltage can be calibrated to obtain the trimming
+-      data which will be stored in otp. This property informs the driver that
+-      the data store in the otp is valid.
+-
+ required:
+   - compatible
+   - reg
+diff --git a/Makefile b/Makefile
+index 4f7da26fef784..9fecb094c28a2 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 10
++SUBLEVEL = 11
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/arm/boot/dts/am335x-pcm-953.dtsi b/arch/arm/boot/dts/am335x-pcm-953.dtsi
+index dae448040a97b..9474974139778 100644
+--- a/arch/arm/boot/dts/am335x-pcm-953.dtsi
++++ b/arch/arm/boot/dts/am335x-pcm-953.dtsi
+@@ -12,22 +12,20 @@
+ 	compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx";
+ 
+ 	/* Power */
+-	regulators {
+-		vcc3v3: fixedregulator@1 {
+-			compatible = "regulator-fixed";
+-			regulator-name = "vcc3v3";
+-			regulator-min-microvolt = <3300000>;
+-			regulator-max-microvolt = <3300000>;
+-			regulator-boot-on;
+-		};
++	vcc3v3: fixedregulator1 {
++		compatible = "regulator-fixed";
++		regulator-name = "vcc3v3";
++		regulator-min-microvolt = <3300000>;
++		regulator-max-microvolt = <3300000>;
++		regulator-boot-on;
++	};
+ 
+-		vcc1v8: fixedregulator@2 {
+-			compatible = "regulator-fixed";
+-			regulator-name = "vcc1v8";
+-			regulator-min-microvolt = <1800000>;
+-			regulator-max-microvolt = <1800000>;
+-			regulator-boot-on;
+-		};
++	vcc1v8: fixedregulator2 {
++		compatible = "regulator-fixed";
++		regulator-name = "vcc1v8";
++		regulator-min-microvolt = <1800000>;
++		regulator-max-microvolt = <1800000>;
++		regulator-boot-on;
+ 	};
+ 
+ 	/* User IO */
+diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+index 60d61291f3444..024af2db638eb 100644
+--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
++++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+@@ -39,6 +39,13 @@
+ 
+ 				};
+ 
++				usb1 {
++					pinctrl_usb1_vbus_gpio: usb1_vbus_gpio {
++						atmel,pins =
++							<AT91_PIOC 5 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;	/* PC5 GPIO */
++					};
++				};
++
+ 				mmc0_slot1 {
+ 					pinctrl_board_mmc0_slot1: mmc0_slot1-board {
+ 						atmel,pins =
+@@ -84,6 +91,8 @@
+ 			};
+ 
+ 			usb1: gadget@fffa4000 {
++				pinctrl-0 = <&pinctrl_usb1_vbus_gpio>;
++				pinctrl-names = "default";
+ 				atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
+ 				status = "okay";
+ 			};
+diff --git a/arch/arm/boot/dts/imx6q-prti6q.dts b/arch/arm/boot/dts/imx6q-prti6q.dts
+index b4605edfd2ab8..d8fa83effd638 100644
+--- a/arch/arm/boot/dts/imx6q-prti6q.dts
++++ b/arch/arm/boot/dts/imx6q-prti6q.dts
+@@ -364,8 +364,8 @@
+ 		pinctrl-names = "default";
+ 		pinctrl-0 = <&pinctrl_wifi>;
+ 		interrupts-extended = <&gpio1 30 IRQ_TYPE_LEVEL_HIGH>;
+-		ref-clock-frequency = "38400000";
+-		tcxo-clock-frequency = "19200000";
++		ref-clock-frequency = <38400000>;
++		tcxo-clock-frequency = <19200000>;
+ 	};
+ };
+ 
+diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
+index 25c9d184fa4c6..1c57ac4016493 100644
+--- a/arch/arm/mach-mxs/mach-mxs.c
++++ b/arch/arm/mach-mxs/mach-mxs.c
+@@ -393,8 +393,10 @@ static void __init mxs_machine_init(void)
+ 
+ 	root = of_find_node_by_path("/");
+ 	ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
+-	if (ret)
++	if (ret) {
++		kfree(soc_dev_attr);
+ 		return;
++	}
+ 
+ 	soc_dev_attr->family = "Freescale MXS Family";
+ 	soc_dev_attr->soc_id = mxs_get_soc_id();
+diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+index 04c752f49be98..115c14c0a3c68 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+@@ -207,7 +207,7 @@
+ 	cap-sd-highspeed;
+ 	cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+ 	disable-wp;
+-	max-frequency = <150000000>;
++	max-frequency = <40000000>;
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+ 	vmmc-supply = <&vcc3v3_baseboard>;
+diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+index a05460b924153..25a8c781f4e75 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+@@ -740,7 +740,7 @@
+ 
+ &uart1 {
+ 	pinctrl-names = "default";
+-	pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn>;
++	pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>;
+ 	status = "okay";
+ 	uart-has-rtscts;
+ 
+@@ -748,13 +748,14 @@
+ 		compatible = "brcm,bcm43438-bt";
+ 		clocks = <&rk817 1>;
+ 		clock-names = "lpo";
+-		device-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>;
+-		host-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
++		host-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>;
++		device-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
+ 		shutdown-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
+ 		pinctrl-names = "default";
+ 		pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>;
+ 		vbat-supply = <&vcc_sys>;
+ 		vddio-supply = <&vcca1v8_pmu>;
++		max-speed = <3000000>;
+ 	};
+ };
+ 
+diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
+index 528bb4e8ac776..a2d0524e0ec90 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
+@@ -176,7 +176,7 @@
+ 		compatible = "rockchip,rk809";
+ 		reg = <0x20>;
+ 		interrupt-parent = <&gpio0>;
+-		interrupts = <RK_PA7 IRQ_TYPE_LEVEL_LOW>;
++		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ 		clock-output-names = "rk808-clkout1", "rk808-clkout2";
+ 
+ 		pinctrl-names = "default";
+diff --git a/arch/arm64/include/asm/syscall_wrapper.h b/arch/arm64/include/asm/syscall_wrapper.h
+index b383b4802a7bd..d30217c21eff7 100644
+--- a/arch/arm64/include/asm/syscall_wrapper.h
++++ b/arch/arm64/include/asm/syscall_wrapper.h
+@@ -8,7 +8,7 @@
+ #ifndef __ASM_SYSCALL_WRAPPER_H
+ #define __ASM_SYSCALL_WRAPPER_H
+ 
+-struct pt_regs;
++#include <asm/ptrace.h>
+ 
+ #define SC_ARM64_REGS_TO_ARGS(x, ...)				\
+ 	__MAP(x,__SC_ARGS					\
+diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h
+index 8ea57e2f0e04c..cc0674d1b8f0f 100644
+--- a/arch/loongarch/include/asm/pgtable.h
++++ b/arch/loongarch/include/asm/pgtable.h
+@@ -349,7 +349,9 @@ static inline pte_t pte_mkclean(pte_t pte)
+ 
+ static inline pte_t pte_mkdirty(pte_t pte)
+ {
+-	pte_val(pte) |= (_PAGE_DIRTY | _PAGE_MODIFIED);
++	pte_val(pte) |= _PAGE_MODIFIED;
++	if (pte_val(pte) & _PAGE_WRITE)
++		pte_val(pte) |= _PAGE_DIRTY;
+ 	return pte;
+ }
+ 
+@@ -475,7 +477,9 @@ static inline pmd_t pmd_mkclean(pmd_t pmd)
+ 
+ static inline pmd_t pmd_mkdirty(pmd_t pmd)
+ {
+-	pmd_val(pmd) |= (_PAGE_DIRTY | _PAGE_MODIFIED);
++	pmd_val(pmd) |= _PAGE_MODIFIED;
++	if (pmd_val(pmd) & _PAGE_WRITE)
++		pmd_val(pmd) |= _PAGE_DIRTY;
+ 	return pmd;
+ }
+ 
+diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c
+index 660492f064e7e..6ae7c669ee642 100644
+--- a/arch/loongarch/kernel/process.c
++++ b/arch/loongarch/kernel/process.c
+@@ -152,7 +152,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
+ 		childregs->csr_crmd = p->thread.csr_crmd;
+ 		childregs->csr_prmd = p->thread.csr_prmd;
+ 		childregs->csr_ecfg = p->thread.csr_ecfg;
+-		return 0;
++		goto out;
+ 	}
+ 
+ 	/* user thread */
+@@ -171,14 +171,15 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
+ 	 */
+ 	childregs->csr_euen = 0;
+ 
++	if (clone_flags & CLONE_SETTLS)
++		childregs->regs[2] = tls;
++
++out:
+ 	clear_tsk_thread_flag(p, TIF_USEDFPU);
+ 	clear_tsk_thread_flag(p, TIF_USEDSIMD);
+ 	clear_tsk_thread_flag(p, TIF_LSX_CTX_LIVE);
+ 	clear_tsk_thread_flag(p, TIF_LASX_CTX_LIVE);
+ 
+-	if (clone_flags & CLONE_SETTLS)
+-		childregs->regs[2] = tls;
+-
+ 	return 0;
+ }
+ 
+diff --git a/arch/mips/include/asm/fw/fw.h b/arch/mips/include/asm/fw/fw.h
+index d0ef8b4892bbe..d0494ce4b3373 100644
+--- a/arch/mips/include/asm/fw/fw.h
++++ b/arch/mips/include/asm/fw/fw.h
+@@ -26,6 +26,6 @@ extern char *fw_getcmdline(void);
+ extern void fw_meminit(void);
+ extern char *fw_getenv(char *name);
+ extern unsigned long fw_getenvl(char *name);
+-extern void fw_init_early_console(char port);
++extern void fw_init_early_console(void);
+ 
+ #endif /* __ASM_FW_H_ */
+diff --git a/arch/mips/pic32/pic32mzda/early_console.c b/arch/mips/pic32/pic32mzda/early_console.c
+index 25372e62783b5..3cd1b408fa1cb 100644
+--- a/arch/mips/pic32/pic32mzda/early_console.c
++++ b/arch/mips/pic32/pic32mzda/early_console.c
+@@ -27,7 +27,7 @@
+ #define U_BRG(x)	(UART_BASE(x) + 0x40)
+ 
+ static void __iomem *uart_base;
+-static char console_port = -1;
++static int console_port = -1;
+ 
+ static int __init configure_uart_pins(int port)
+ {
+@@ -47,7 +47,7 @@ static int __init configure_uart_pins(int port)
+ 	return 0;
+ }
+ 
+-static void __init configure_uart(char port, int baud)
++static void __init configure_uart(int port, int baud)
+ {
+ 	u32 pbclk;
+ 
+@@ -60,7 +60,7 @@ static void __init configure_uart(char port, int baud)
+ 		     uart_base + PIC32_SET(U_STA(port)));
+ }
+ 
+-static void __init setup_early_console(char port, int baud)
++static void __init setup_early_console(int port, int baud)
+ {
+ 	if (configure_uart_pins(port))
+ 		return;
+@@ -130,16 +130,15 @@ _out:
+ 	return baud;
+ }
+ 
+-void __init fw_init_early_console(char port)
++void __init fw_init_early_console(void)
+ {
+ 	char *arch_cmdline = pic32_getcmdline();
+-	int baud = -1;
++	int baud, port;
+ 
+ 	uart_base = ioremap(PIC32_BASE_UART, 0xc00);
+ 
+ 	baud = get_baud_from_cmdline(arch_cmdline);
+-	if (port == -1)
+-		port = get_port_from_cmdline(arch_cmdline);
++	port = get_port_from_cmdline(arch_cmdline);
+ 
+ 	if (port == -1)
+ 		port = EARLY_CONSOLE_PORT;
+diff --git a/arch/mips/pic32/pic32mzda/init.c b/arch/mips/pic32/pic32mzda/init.c
+index d9c8c4e46aff9..58d8ca730df73 100644
+--- a/arch/mips/pic32/pic32mzda/init.c
++++ b/arch/mips/pic32/pic32mzda/init.c
+@@ -47,7 +47,7 @@ void __init plat_mem_setup(void)
+ 		strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
+ 
+ #ifdef CONFIG_EARLY_PRINTK
+-	fw_init_early_console(-1);
++	fw_init_early_console();
+ #endif
+ 	pic32_config_init();
+ }
+diff --git a/arch/nios2/boot/Makefile b/arch/nios2/boot/Makefile
+index 8c3ad76602f3e..29c11a06b750a 100644
+--- a/arch/nios2/boot/Makefile
++++ b/arch/nios2/boot/Makefile
+@@ -20,7 +20,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE
+ $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
+ 	$(call if_changed,gzip)
+ 
+-$(obj)/vmImage: $(obj)/vmlinux.gz
++$(obj)/vmImage: $(obj)/vmlinux.gz FORCE
+ 	$(call if_changed,uimage)
+ 	@$(kecho) 'Kernel: $@ is ready'
+ 
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+index ced0d4e479385..900a50526d771 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+@@ -3,6 +3,8 @@
+ 
+ #include "fu540-c000.dtsi"
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/leds/common.h>
++#include <dt-bindings/pwm/pwm.h>
+ 
+ /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
+ #define RTCCLK_FREQ		1000000
+@@ -42,6 +44,42 @@
+ 		compatible = "gpio-restart";
+ 		gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
+ 	};
++
++	led-controller {
++		compatible = "pwm-leds";
++
++		led-d1 {
++			pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
++			active-low;
++			color = <LED_COLOR_ID_GREEN>;
++			max-brightness = <255>;
++			label = "d1";
++		};
++
++		led-d2 {
++			pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>;
++			active-low;
++			color = <LED_COLOR_ID_GREEN>;
++			max-brightness = <255>;
++			label = "d2";
++		};
++
++		led-d3 {
++			pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>;
++			active-low;
++			color = <LED_COLOR_ID_GREEN>;
++			max-brightness = <255>;
++			label = "d3";
++		};
++
++		led-d4 {
++			pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
++			active-low;
++			color = <LED_COLOR_ID_GREEN>;
++			max-brightness = <255>;
++			label = "d4";
++		};
++	};
+ };
+ 
+ &uart0 {
+diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
+index 84ac0fe612e79..db6548509bb3e 100644
+--- a/arch/riscv/kernel/vdso/Makefile
++++ b/arch/riscv/kernel/vdso/Makefile
+@@ -28,6 +28,9 @@ obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
+ 
+ obj-y += vdso.o
+ CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
++ifneq ($(filter vgettimeofday, $(vdso-syms)),)
++CPPFLAGS_vdso.lds += -DHAS_VGETTIMEOFDAY
++endif
+ 
+ # Disable -pg to prevent insert call site
+ CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE)
+diff --git a/arch/riscv/kernel/vdso/vdso.lds.S b/arch/riscv/kernel/vdso/vdso.lds.S
+index 01d94aae5bf51..150b1a572e619 100644
+--- a/arch/riscv/kernel/vdso/vdso.lds.S
++++ b/arch/riscv/kernel/vdso/vdso.lds.S
+@@ -68,9 +68,11 @@ VERSION
+ 	LINUX_4.15 {
+ 	global:
+ 		__vdso_rt_sigreturn;
++#ifdef HAS_VGETTIMEOFDAY
+ 		__vdso_gettimeofday;
+ 		__vdso_clock_gettime;
+ 		__vdso_clock_getres;
++#endif
+ 		__vdso_getcpu;
+ 		__vdso_flush_icache;
+ 	local: *;
+diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
+index 318fce77601d3..de575af02ffea 100644
+--- a/arch/s390/Kconfig
++++ b/arch/s390/Kconfig
+@@ -568,8 +568,7 @@ config EXPOLINE_FULL
+ endchoice
+ 
+ config RELOCATABLE
+-	bool "Build a relocatable kernel"
+-	default y
++	def_bool y
+ 	help
+ 	  This builds a kernel image that retains relocation information
+ 	  so it can be loaded at an arbitrary address.
+@@ -578,10 +577,11 @@ config RELOCATABLE
+ 	  bootup process.
+ 	  The relocations make the kernel image about 15% larger (compressed
+ 	  10%), but are discarded at runtime.
++	  Note: this option exists only for documentation purposes, please do
++	  not remove it.
+ 
+ config RANDOMIZE_BASE
+ 	bool "Randomize the address of the kernel image (KASLR)"
+-	depends on RELOCATABLE
+ 	default y
+ 	help
+ 	  In support of Kernel Address Space Layout Randomization (KASLR),
+diff --git a/arch/s390/Makefile b/arch/s390/Makefile
+index 4cb5d17e7ead6..47bec926d6c09 100644
+--- a/arch/s390/Makefile
++++ b/arch/s390/Makefile
+@@ -14,10 +14,8 @@ KBUILD_AFLAGS_MODULE += -fPIC
+ KBUILD_CFLAGS_MODULE += -fPIC
+ KBUILD_AFLAGS	+= -m64
+ KBUILD_CFLAGS	+= -m64
+-ifeq ($(CONFIG_RELOCATABLE),y)
+ KBUILD_CFLAGS	+= -fPIE
+ LDFLAGS_vmlinux	:= -pie
+-endif
+ aflags_dwarf	:= -Wa,-gdwarf-2
+ KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__
+ ifndef CONFIG_AS_IS_LLVM
+diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
+index 883357a211a3b..d52c3e2e16bc5 100644
+--- a/arch/s390/boot/Makefile
++++ b/arch/s390/boot/Makefile
+@@ -37,9 +37,8 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
+ 
+ obj-y	:= head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o
+ obj-y	+= string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
+-obj-y	+= version.o pgm_check_info.o ctype.o ipl_data.o
++obj-y	+= version.o pgm_check_info.o ctype.o ipl_data.o machine_kexec_reloc.o
+ obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE))	+= uv.o
+-obj-$(CONFIG_RELOCATABLE)	+= machine_kexec_reloc.o
+ obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr.o
+ obj-y	+= $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
+ obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o
+diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
+index bc48fe82d949a..e5026e1d277fb 100644
+--- a/arch/s390/boot/startup.c
++++ b/arch/s390/boot/startup.c
+@@ -285,8 +285,7 @@ void startup_kernel(void)
+ 
+ 	clear_bss_section();
+ 	copy_bootdata();
+-	if (IS_ENABLED(CONFIG_RELOCATABLE))
+-		handle_relocs(__kaslr_offset);
++	handle_relocs(__kaslr_offset);
+ 
+ 	if (__kaslr_offset) {
+ 		/*
+diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
+index bad8f47fc5d69..c1b2b0d4af773 100644
+--- a/arch/s390/kernel/crash_dump.c
++++ b/arch/s390/kernel/crash_dump.c
+@@ -45,7 +45,7 @@ struct save_area {
+ 	u64 fprs[16];
+ 	u32 fpc;
+ 	u32 prefix;
+-	u64 todpreg;
++	u32 todpreg;
+ 	u64 timer;
+ 	u64 todcmp;
+ 	u64 vxrs_low[16];
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+index 3de6d8b533672..a0165df3c4d8c 100644
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -77,7 +77,7 @@ static int hyperv_init_ghcb(void)
+ static int hv_cpu_init(unsigned int cpu)
+ {
+ 	union hv_vp_assist_msr_contents msr = { 0 };
+-	struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()];
++	struct hv_vp_assist_page **hvp = &hv_vp_assist_page[cpu];
+ 	int ret;
+ 
+ 	ret = hv_common_cpu_init(cpu);
+@@ -87,34 +87,32 @@ static int hv_cpu_init(unsigned int cpu)
+ 	if (!hv_vp_assist_page)
+ 		return 0;
+ 
+-	if (!*hvp) {
+-		if (hv_root_partition) {
+-			/*
+-			 * For root partition we get the hypervisor provided VP assist
+-			 * page, instead of allocating a new page.
+-			 */
+-			rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
+-			*hvp = memremap(msr.pfn <<
+-					HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT,
+-					PAGE_SIZE, MEMREMAP_WB);
+-		} else {
+-			/*
+-			 * The VP assist page is an "overlay" page (see Hyper-V TLFS's
+-			 * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed
+-			 * out to make sure we always write the EOI MSR in
+-			 * hv_apic_eoi_write() *after* the EOI optimization is disabled
+-			 * in hv_cpu_die(), otherwise a CPU may not be stopped in the
+-			 * case of CPU offlining and the VM will hang.
+-			 */
++	if (hv_root_partition) {
++		/*
++		 * For root partition we get the hypervisor provided VP assist
++		 * page, instead of allocating a new page.
++		 */
++		rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
++		*hvp = memremap(msr.pfn << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT,
++				PAGE_SIZE, MEMREMAP_WB);
++	} else {
++		/*
++		 * The VP assist page is an "overlay" page (see Hyper-V TLFS's
++		 * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed
++		 * out to make sure we always write the EOI MSR in
++		 * hv_apic_eoi_write() *after* the EOI optimization is disabled
++		 * in hv_cpu_die(), otherwise a CPU may not be stopped in the
++		 * case of CPU offlining and the VM will hang.
++		 */
++		if (!*hvp)
+ 			*hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO);
+-			if (*hvp)
+-				msr.pfn = vmalloc_to_pfn(*hvp);
+-		}
+-		WARN_ON(!(*hvp));
+-		if (*hvp) {
+-			msr.enable = 1;
+-			wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
+-		}
++		if (*hvp)
++			msr.pfn = vmalloc_to_pfn(*hvp);
++
++	}
++	if (!WARN_ON(!(*hvp))) {
++		msr.enable = 1;
++		wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
+ 	}
+ 
+ 	return hyperv_init_ghcb();
+diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
+index ef4775c6db01c..dfa672bec6109 100644
+--- a/arch/x86/include/asm/cpufeatures.h
++++ b/arch/x86/include/asm/cpufeatures.h
+@@ -305,6 +305,9 @@
+ #define X86_FEATURE_USE_IBPB_FW		(11*32+16) /* "" Use IBPB during runtime firmware calls */
+ #define X86_FEATURE_RSB_VMEXIT_LITE	(11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */
+ 
++
++#define X86_FEATURE_MSR_TSX_CTRL	(11*32+20) /* "" MSR IA32_TSX_CTRL (Intel) implemented */
++
+ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
+ #define X86_FEATURE_AVX_VNNI		(12*32+ 4) /* AVX VNNI instructions */
+ #define X86_FEATURE_AVX512_BF16		(12*32+ 5) /* AVX512 BFLOAT16 instructions */
+diff --git a/arch/x86/kernel/cpu/tsx.c b/arch/x86/kernel/cpu/tsx.c
+index ec7bbac3a9f29..8009c8346d8f8 100644
+--- a/arch/x86/kernel/cpu/tsx.c
++++ b/arch/x86/kernel/cpu/tsx.c
+@@ -58,24 +58,6 @@ static void tsx_enable(void)
+ 	wrmsrl(MSR_IA32_TSX_CTRL, tsx);
+ }
+ 
+-static bool tsx_ctrl_is_supported(void)
+-{
+-	u64 ia32_cap = x86_read_arch_cap_msr();
+-
+-	/*
+-	 * TSX is controlled via MSR_IA32_TSX_CTRL.  However, support for this
+-	 * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES.
+-	 *
+-	 * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a
+-	 * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES
+-	 * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get
+-	 * MSR_IA32_TSX_CTRL support even after a microcode update. Thus,
+-	 * tsx= cmdline requests will do nothing on CPUs without
+-	 * MSR_IA32_TSX_CTRL support.
+-	 */
+-	return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR);
+-}
+-
+ static enum tsx_ctrl_states x86_get_tsx_auto_mode(void)
+ {
+ 	if (boot_cpu_has_bug(X86_BUG_TAA))
+@@ -135,7 +117,7 @@ static void tsx_clear_cpuid(void)
+ 		rdmsrl(MSR_TSX_FORCE_ABORT, msr);
+ 		msr |= MSR_TFA_TSX_CPUID_CLEAR;
+ 		wrmsrl(MSR_TSX_FORCE_ABORT, msr);
+-	} else if (tsx_ctrl_is_supported()) {
++	} else if (cpu_feature_enabled(X86_FEATURE_MSR_TSX_CTRL)) {
+ 		rdmsrl(MSR_IA32_TSX_CTRL, msr);
+ 		msr |= TSX_CTRL_CPUID_CLEAR;
+ 		wrmsrl(MSR_IA32_TSX_CTRL, msr);
+@@ -158,7 +140,8 @@ static void tsx_dev_mode_disable(void)
+ 	u64 mcu_opt_ctrl;
+ 
+ 	/* Check if RTM_ALLOW exists */
+-	if (!boot_cpu_has_bug(X86_BUG_TAA) || !tsx_ctrl_is_supported() ||
++	if (!boot_cpu_has_bug(X86_BUG_TAA) ||
++	    !cpu_feature_enabled(X86_FEATURE_MSR_TSX_CTRL) ||
+ 	    !cpu_feature_enabled(X86_FEATURE_SRBDS_CTRL))
+ 		return;
+ 
+@@ -191,7 +174,20 @@ void __init tsx_init(void)
+ 		return;
+ 	}
+ 
+-	if (!tsx_ctrl_is_supported()) {
++	/*
++	 * TSX is controlled via MSR_IA32_TSX_CTRL.  However, support for this
++	 * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES.
++	 *
++	 * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a
++	 * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES
++	 * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get
++	 * MSR_IA32_TSX_CTRL support even after a microcode update. Thus,
++	 * tsx= cmdline requests will do nothing on CPUs without
++	 * MSR_IA32_TSX_CTRL support.
++	 */
++	if (x86_read_arch_cap_msr() & ARCH_CAP_TSX_CTRL_MSR) {
++		setup_force_cpu_cap(X86_FEATURE_MSR_TSX_CTRL);
++	} else {
+ 		tsx_ctrl_state = TSX_CTRL_NOT_SUPPORTED;
+ 		return;
+ 	}
+diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
+index 83e30e4db2ae0..0a163ba9fa1a2 100644
+--- a/arch/x86/kvm/mmu/mmu.c
++++ b/arch/x86/kvm/mmu/mmu.c
+@@ -2431,6 +2431,7 @@ static bool __kvm_mmu_prepare_zap_page(struct kvm *kvm,
+ {
+ 	bool list_unstable, zapped_root = false;
+ 
++	lockdep_assert_held_write(&kvm->mmu_lock);
+ 	trace_kvm_mmu_prepare_zap_page(sp);
+ 	++kvm->stat.mmu_shadow_zapped;
+ 	*nr_zapped = mmu_zap_unsync_children(kvm, sp, invalid_list);
+@@ -4250,14 +4251,14 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
+ 	if (is_page_fault_stale(vcpu, fault, mmu_seq))
+ 		goto out_unlock;
+ 
+-	r = make_mmu_pages_available(vcpu);
+-	if (r)
+-		goto out_unlock;
+-
+-	if (is_tdp_mmu_fault)
++	if (is_tdp_mmu_fault) {
+ 		r = kvm_tdp_mmu_map(vcpu, fault);
+-	else
++	} else {
++		r = make_mmu_pages_available(vcpu);
++		if (r)
++			goto out_unlock;
+ 		r = __direct_map(vcpu, fault);
++	}
+ 
+ out_unlock:
+ 	if (is_tdp_mmu_fault)
+diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
+index 76dcc8a3e8496..630359bce06d4 100644
+--- a/arch/x86/kvm/svm/nested.c
++++ b/arch/x86/kvm/svm/nested.c
+@@ -1143,6 +1143,9 @@ void svm_free_nested(struct vcpu_svm *svm)
+ 	if (!svm->nested.initialized)
+ 		return;
+ 
++	if (WARN_ON_ONCE(svm->vmcb != svm->vmcb01.ptr))
++		svm_switch_vmcb(svm, &svm->vmcb01);
++
+ 	svm_vcpu_free_msrpm(svm->nested.msrpm);
+ 	svm->nested.msrpm = NULL;
+ 
+@@ -1161,9 +1164,6 @@ void svm_free_nested(struct vcpu_svm *svm)
+ 	svm->nested.initialized = false;
+ }
+ 
+-/*
+- * Forcibly leave nested mode in order to be able to reset the VCPU later on.
+- */
+ void svm_leave_nested(struct kvm_vcpu *vcpu)
+ {
+ 	struct vcpu_svm *svm = to_svm(vcpu);
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index e80756ab141bf..6431019d0eff0 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -346,12 +346,6 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
+ 	return 0;
+ }
+ 
+-static int is_external_interrupt(u32 info)
+-{
+-	info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID;
+-	return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR);
+-}
+-
+ static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu)
+ {
+ 	struct vcpu_svm *svm = to_svm(vcpu);
+@@ -1440,6 +1434,7 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu)
+ 	 */
+ 	svm_clear_current_vmcb(svm->vmcb);
+ 
++	svm_leave_nested(vcpu);
+ 	svm_free_nested(svm);
+ 
+ 	sev_free_vcpu(vcpu);
+@@ -3426,15 +3421,6 @@ static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
+ 		return 0;
+ 	}
+ 
+-	if (is_external_interrupt(svm->vmcb->control.exit_int_info) &&
+-	    exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR &&
+-	    exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH &&
+-	    exit_code != SVM_EXIT_INTR && exit_code != SVM_EXIT_NMI)
+-		printk(KERN_ERR "%s: unexpected exit_int_info 0x%x "
+-		       "exit_code 0x%x\n",
+-		       __func__, svm->vmcb->control.exit_int_info,
+-		       exit_code);
+-
+ 	if (exit_fastpath != EXIT_FASTPATH_NONE)
+ 		return 1;
+ 
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index 03d348fa6485a..f56cc2382edf9 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -6294,9 +6294,6 @@ out:
+ 	return kvm_state.size;
+ }
+ 
+-/*
+- * Forcibly leave nested mode in order to be able to reset the VCPU later on.
+- */
+ void vmx_leave_nested(struct kvm_vcpu *vcpu)
+ {
+ 	if (is_guest_mode(vcpu)) {
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 71cbafd67319b..5d38409913a9d 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -611,6 +611,12 @@ void kvm_deliver_exception_payload(struct kvm_vcpu *vcpu)
+ }
+ EXPORT_SYMBOL_GPL(kvm_deliver_exception_payload);
+ 
++/* Forcibly leave the nested mode in cases like a vCPU reset */
++static void kvm_leave_nested(struct kvm_vcpu *vcpu)
++{
++	kvm_x86_ops.nested_ops->leave_nested(vcpu);
++}
++
+ static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
+ 		unsigned nr, bool has_error, u32 error_code,
+ 	        bool has_payload, unsigned long payload, bool reinject)
+@@ -5154,7 +5160,7 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
+ 
+ 	if (events->flags & KVM_VCPUEVENT_VALID_SMM) {
+ 		if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) {
+-			kvm_x86_ops.nested_ops->leave_nested(vcpu);
++			kvm_leave_nested(vcpu);
+ 			kvm_smm_changed(vcpu, events->smi.smm);
+ 		}
+ 
+@@ -11789,8 +11795,18 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
+ 	WARN_ON_ONCE(!init_event &&
+ 		     (old_cr0 || kvm_read_cr3(vcpu) || kvm_read_cr4(vcpu)));
+ 
++	/*
++	 * SVM doesn't unconditionally VM-Exit on INIT and SHUTDOWN, thus it's
++	 * possible to INIT the vCPU while L2 is active.  Force the vCPU back
++	 * into L1 as EFER.SVME is cleared on INIT (along with all other EFER
++	 * bits), i.e. virtualization is disabled.
++	 */
++	if (is_guest_mode(vcpu))
++		kvm_leave_nested(vcpu);
++
+ 	kvm_lapic_reset(vcpu, init_event);
+ 
++	WARN_ON_ONCE(is_guest_mode(vcpu) || is_smm(vcpu));
+ 	vcpu->arch.hflags = 0;
+ 
+ 	vcpu->arch.smi_pending = 0;
+diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
+index 9a1950879fc44..8333b6c50e93c 100644
+--- a/arch/x86/kvm/xen.c
++++ b/arch/x86/kvm/xen.c
+@@ -954,6 +954,14 @@ static int kvm_xen_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
+ 	return kvm_xen_hypercall_set_result(vcpu, run->xen.u.hcall.result);
+ }
+ 
++static inline int max_evtchn_port(struct kvm *kvm)
++{
++	if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode)
++		return EVTCHN_2L_NR_CHANNELS;
++	else
++		return COMPAT_EVTCHN_2L_NR_CHANNELS;
++}
++
+ static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports,
+ 			       evtchn_port_t *ports)
+ {
+@@ -1042,6 +1050,10 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode,
+ 			*r = -EFAULT;
+ 			goto out;
+ 		}
++		if (ports[i] >= max_evtchn_port(vcpu->kvm)) {
++			*r = -EINVAL;
++			goto out;
++		}
+ 	}
+ 
+ 	if (sched_poll.nr_ports == 1)
+@@ -1216,6 +1228,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
+ 	bool longmode;
+ 	u64 input, params[6], r = -ENOSYS;
+ 	bool handled = false;
++	u8 cpl;
+ 
+ 	input = (u64)kvm_register_read(vcpu, VCPU_REGS_RAX);
+ 
+@@ -1243,9 +1256,17 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
+ 		params[5] = (u64)kvm_r9_read(vcpu);
+ 	}
+ #endif
++	cpl = static_call(kvm_x86_get_cpl)(vcpu);
+ 	trace_kvm_xen_hypercall(input, params[0], params[1], params[2],
+ 				params[3], params[4], params[5]);
+ 
++	/*
++	 * Only allow hypercall acceleration for CPL0. The rare hypercalls that
++	 * are permitted in guest userspace can be handled by the VMM.
++	 */
++	if (unlikely(cpl > 0))
++		goto handle_in_userspace;
++
+ 	switch (input) {
+ 	case __HYPERVISOR_xen_version:
+ 		if (params[0] == XENVER_version && vcpu->kvm->arch.xen.xen_version) {
+@@ -1280,10 +1301,11 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
+ 	if (handled)
+ 		return kvm_xen_hypercall_set_result(vcpu, r);
+ 
++handle_in_userspace:
+ 	vcpu->run->exit_reason = KVM_EXIT_XEN;
+ 	vcpu->run->xen.type = KVM_EXIT_XEN_HCALL;
+ 	vcpu->run->xen.u.hcall.longmode = longmode;
+-	vcpu->run->xen.u.hcall.cpl = static_call(kvm_x86_get_cpl)(vcpu);
++	vcpu->run->xen.u.hcall.cpl = cpl;
+ 	vcpu->run->xen.u.hcall.input = input;
+ 	vcpu->run->xen.u.hcall.params[0] = params[0];
+ 	vcpu->run->xen.u.hcall.params[1] = params[1];
+@@ -1298,14 +1320,6 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu)
+ 	return 0;
+ }
+ 
+-static inline int max_evtchn_port(struct kvm *kvm)
+-{
+-	if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode)
+-		return EVTCHN_2L_NR_CHANNELS;
+-	else
+-		return COMPAT_EVTCHN_2L_NR_CHANNELS;
+-}
+-
+ static void kvm_xen_check_poller(struct kvm_vcpu *vcpu, int port)
+ {
+ 	int poll_evtchn = vcpu->arch.xen.poll_evtchn;
+diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
+index 1ad0228f8ceb9..19058d7466957 100644
+--- a/arch/x86/mm/ioremap.c
++++ b/arch/x86/mm/ioremap.c
+@@ -216,9 +216,15 @@ __ioremap_caller(resource_size_t phys_addr, unsigned long size,
+ 	 * Mappings have to be page-aligned
+ 	 */
+ 	offset = phys_addr & ~PAGE_MASK;
+-	phys_addr &= PHYSICAL_PAGE_MASK;
++	phys_addr &= PAGE_MASK;
+ 	size = PAGE_ALIGN(last_addr+1) - phys_addr;
+ 
++	/*
++	 * Mask out any bits not part of the actual physical
++	 * address, like memory encryption bits.
++	 */
++	phys_addr &= PHYSICAL_PAGE_MASK;
++
+ 	retval = memtype_reserve(phys_addr, (u64)phys_addr + size,
+ 						pcm, &new_pcm);
+ 	if (retval) {
+diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
+index 4cd39f304e206..93ae33248f421 100644
+--- a/arch/x86/power/cpu.c
++++ b/arch/x86/power/cpu.c
+@@ -513,16 +513,23 @@ static int pm_cpu_check(const struct x86_cpu_id *c)
+ 
+ static void pm_save_spec_msr(void)
+ {
+-	u32 spec_msr_id[] = {
+-		MSR_IA32_SPEC_CTRL,
+-		MSR_IA32_TSX_CTRL,
+-		MSR_TSX_FORCE_ABORT,
+-		MSR_IA32_MCU_OPT_CTRL,
+-		MSR_AMD64_LS_CFG,
+-		MSR_AMD64_DE_CFG,
++	struct msr_enumeration {
++		u32 msr_no;
++		u32 feature;
++	} msr_enum[] = {
++		{ MSR_IA32_SPEC_CTRL,	 X86_FEATURE_MSR_SPEC_CTRL },
++		{ MSR_IA32_TSX_CTRL,	 X86_FEATURE_MSR_TSX_CTRL },
++		{ MSR_TSX_FORCE_ABORT,	 X86_FEATURE_TSX_FORCE_ABORT },
++		{ MSR_IA32_MCU_OPT_CTRL, X86_FEATURE_SRBDS_CTRL },
++		{ MSR_AMD64_LS_CFG,	 X86_FEATURE_LS_CFG_SSBD },
++		{ MSR_AMD64_DE_CFG,	 X86_FEATURE_LFENCE_RDTSC },
+ 	};
++	int i;
+ 
+-	msr_build_context(spec_msr_id, ARRAY_SIZE(spec_msr_id));
++	for (i = 0; i < ARRAY_SIZE(msr_enum); i++) {
++		if (boot_cpu_has(msr_enum[i].feature))
++			msr_build_context(&msr_enum[i].msr_no, 1);
++	}
+ }
+ 
+ static int pm_check_save_msr(void)
+diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
+index 30b15a9a47c4f..249f489d115f0 100644
+--- a/block/bfq-cgroup.c
++++ b/block/bfq-cgroup.c
+@@ -615,6 +615,10 @@ struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio)
+ 	struct bfq_group *bfqg;
+ 
+ 	while (blkg) {
++		if (!blkg->online) {
++			blkg = blkg->parent;
++			continue;
++		}
+ 		bfqg = blkg_to_bfqg(blkg);
+ 		if (bfqg->online) {
+ 			bio_associate_blkg_from_css(bio, &blkg->blkcg->css);
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 4402e4ecb8b11..3f1f5e3e0951d 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -3956,9 +3956,14 @@ EXPORT_SYMBOL(__blk_mq_alloc_disk);
+ struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q,
+ 		struct lock_class_key *lkclass)
+ {
++	struct gendisk *disk;
++
+ 	if (!blk_get_queue(q))
+ 		return NULL;
+-	return __alloc_disk_node(q, NUMA_NO_NODE, lkclass);
++	disk = __alloc_disk_node(q, NUMA_NO_NODE, lkclass);
++	if (!disk)
++		blk_put_queue(q);
++	return disk;
+ }
+ EXPORT_SYMBOL(blk_mq_alloc_disk_for_queue);
+ 
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index 4949ed3ce7c95..8ac1038d0c797 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -59,7 +59,6 @@ void blk_set_default_limits(struct queue_limits *lim)
+ 	lim->zone_write_granularity = 0;
+ 	lim->dma_alignment = 511;
+ }
+-EXPORT_SYMBOL(blk_set_default_limits);
+ 
+ /**
+  * blk_set_stacking_limits - set default limits for stacking devices
+diff --git a/block/blk.h b/block/blk.h
+index 52432eab621e5..ff0bec16f0fa0 100644
+--- a/block/blk.h
++++ b/block/blk.h
+@@ -324,6 +324,7 @@ void blk_rq_set_mixed_merge(struct request *rq);
+ bool blk_rq_merge_ok(struct request *rq, struct bio *bio);
+ enum elv_merge blk_try_merge(struct request *rq, struct bio *bio);
+ 
++void blk_set_default_limits(struct queue_limits *lim);
+ int blk_dev_init(void);
+ 
+ /*
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
+index 68a566f696845..aae9261c424a3 100644
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -578,6 +578,20 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
+ 		DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
+ 		},
+ 	},
++	/*
++	 * Models which have nvidia-ec-wmi support, but should not use it.
++	 * Note this indicates a likely firmware bug on these models and should
++	 * be revisited if/when Linux gets support for dynamic mux mode.
++	 */
++	{
++	 .callback = video_detect_force_native,
++	 /* Dell G15 5515 */
++	 .matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++		DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"),
++		},
++	},
++
+ 	/*
+ 	 * Desktops which falsely report a backlight and which our heuristics
+ 	 * for this do not catch.
+diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
+index 9b1778c006103..64999777e0bf5 100644
+--- a/drivers/android/binder_alloc.c
++++ b/drivers/android/binder_alloc.c
+@@ -760,6 +760,12 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
+ 	const char *failure_string;
+ 	struct binder_buffer *buffer;
+ 
++	if (unlikely(vma->vm_mm != alloc->vma_vm_mm)) {
++		ret = -EINVAL;
++		failure_string = "invalid vma->vm_mm";
++		goto err_invalid_mm;
++	}
++
+ 	mutex_lock(&binder_alloc_mmap_lock);
+ 	if (alloc->buffer_size) {
+ 		ret = -EBUSY;
+@@ -806,6 +812,7 @@ err_alloc_pages_failed:
+ 	alloc->buffer_size = 0;
+ err_already_mapped:
+ 	mutex_unlock(&binder_alloc_mmap_lock);
++err_invalid_mm:
+ 	binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
+ 			   "%s: %d %lx-%lx %s failed %d\n", __func__,
+ 			   alloc->pid, vma->vm_start, vma->vm_end,
+diff --git a/drivers/bus/intel-ixp4xx-eb.c b/drivers/bus/intel-ixp4xx-eb.c
+index a4388440aca7a..91db001eb69a6 100644
+--- a/drivers/bus/intel-ixp4xx-eb.c
++++ b/drivers/bus/intel-ixp4xx-eb.c
+@@ -49,7 +49,7 @@
+ #define IXP4XX_EXP_SIZE_SHIFT		10
+ #define IXP4XX_EXP_CNFG_0		BIT(9) /* Always zero */
+ #define IXP43X_EXP_SYNC_INTEL		BIT(8) /* Only on IXP43x */
+-#define IXP43X_EXP_EXP_CHIP		BIT(7) /* Only on IXP43x */
++#define IXP43X_EXP_EXP_CHIP		BIT(7) /* Only on IXP43x, dangerous to touch on IXP42x */
+ #define IXP4XX_EXP_BYTE_RD16		BIT(6)
+ #define IXP4XX_EXP_HRDY_POL		BIT(5) /* Only on IXP42x */
+ #define IXP4XX_EXP_MUX_EN		BIT(4)
+@@ -57,8 +57,6 @@
+ #define IXP4XX_EXP_WORD			BIT(2) /* Always zero */
+ #define IXP4XX_EXP_WR_EN		BIT(1)
+ #define IXP4XX_EXP_BYTE_EN		BIT(0)
+-#define IXP42X_RESERVED			(BIT(30)|IXP4XX_EXP_CNFG_0|BIT(8)|BIT(7)|IXP4XX_EXP_WORD)
+-#define IXP43X_RESERVED			(BIT(30)|IXP4XX_EXP_CNFG_0|BIT(5)|IXP4XX_EXP_WORD)
+ 
+ #define IXP4XX_EXP_CNFG0		0x20
+ #define IXP4XX_EXP_CNFG0_MEM_MAP	BIT(31)
+@@ -252,10 +250,9 @@ static void ixp4xx_exp_setup_chipselect(struct ixp4xx_eb *eb,
+ 		cs_cfg |= val << IXP4XX_EXP_CYC_TYPE_SHIFT;
+ 	}
+ 
+-	if (eb->is_42x)
+-		cs_cfg &= ~IXP42X_RESERVED;
+ 	if (eb->is_43x) {
+-		cs_cfg &= ~IXP43X_RESERVED;
++		/* Should always be zero */
++		cs_cfg &= ~IXP4XX_EXP_WORD;
+ 		/*
+ 		 * This bit for Intel strata flash is currently unused, but let's
+ 		 * report it if we find one.
+diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c
+index 4cd2e127946ea..3aa91aed3bf73 100644
+--- a/drivers/bus/sunxi-rsb.c
++++ b/drivers/bus/sunxi-rsb.c
+@@ -267,6 +267,9 @@ EXPORT_SYMBOL_GPL(sunxi_rsb_driver_register);
+ /* common code that starts a transfer */
+ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+ {
++	u32 int_mask, status;
++	bool timeout;
++
+ 	if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) {
+ 		dev_dbg(rsb->dev, "RSB transfer still in progress\n");
+ 		return -EBUSY;
+@@ -274,13 +277,23 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+ 
+ 	reinit_completion(&rsb->complete);
+ 
+-	writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER,
+-	       rsb->regs + RSB_INTE);
++	int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER;
++	writel(int_mask, rsb->regs + RSB_INTE);
+ 	writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB,
+ 	       rsb->regs + RSB_CTRL);
+ 
+-	if (!wait_for_completion_io_timeout(&rsb->complete,
+-					    msecs_to_jiffies(100))) {
++	if (irqs_disabled()) {
++		timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS,
++						    status, (status & int_mask),
++						    10, 100000);
++		writel(status, rsb->regs + RSB_INTS);
++	} else {
++		timeout = !wait_for_completion_io_timeout(&rsb->complete,
++							  msecs_to_jiffies(100));
++		status = rsb->status;
++	}
++
++	if (timeout) {
+ 		dev_dbg(rsb->dev, "RSB timeout\n");
+ 
+ 		/* abort the transfer */
+@@ -292,18 +305,18 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
+ 		return -ETIMEDOUT;
+ 	}
+ 
+-	if (rsb->status & RSB_INTS_LOAD_BSY) {
++	if (status & RSB_INTS_LOAD_BSY) {
+ 		dev_dbg(rsb->dev, "RSB busy\n");
+ 		return -EBUSY;
+ 	}
+ 
+-	if (rsb->status & RSB_INTS_TRANS_ERR) {
+-		if (rsb->status & RSB_INTS_TRANS_ERR_ACK) {
++	if (status & RSB_INTS_TRANS_ERR) {
++		if (status & RSB_INTS_TRANS_ERR_ACK) {
+ 			dev_dbg(rsb->dev, "RSB slave nack\n");
+ 			return -EINVAL;
+ 		}
+ 
+-		if (rsb->status & RSB_INTS_TRANS_ERR_DATA) {
++		if (status & RSB_INTS_TRANS_ERR_DATA) {
+ 			dev_dbg(rsb->dev, "RSB transfer data error\n");
+ 			return -EIO;
+ 		}
+@@ -812,14 +825,6 @@ static int sunxi_rsb_remove(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
+-static void sunxi_rsb_shutdown(struct platform_device *pdev)
+-{
+-	struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
+-
+-	pm_runtime_disable(&pdev->dev);
+-	sunxi_rsb_hw_exit(rsb);
+-}
+-
+ static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = {
+ 	SET_RUNTIME_PM_OPS(sunxi_rsb_runtime_suspend,
+ 			   sunxi_rsb_runtime_resume, NULL)
+@@ -835,7 +840,6 @@ MODULE_DEVICE_TABLE(of, sunxi_rsb_of_match_table);
+ static struct platform_driver sunxi_rsb_driver = {
+ 	.probe = sunxi_rsb_probe,
+ 	.remove	= sunxi_rsb_remove,
+-	.shutdown = sunxi_rsb_shutdown,
+ 	.driver	= {
+ 		.name = RSB_CTRL_NAME,
+ 		.of_match_table = sunxi_rsb_of_match_table,
+diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
+index 55516043b656b..8184378f67efa 100644
+--- a/drivers/cpufreq/Kconfig.x86
++++ b/drivers/cpufreq/Kconfig.x86
+@@ -35,7 +35,7 @@ config X86_PCC_CPUFREQ
+ 	  If in doubt, say N.
+ 
+ config X86_AMD_PSTATE
+-	tristate "AMD Processor P-State driver"
++	bool "AMD Processor P-State driver"
+ 	depends on X86 && ACPI
+ 	select ACPI_PROCESSOR
+ 	select ACPI_CPPC_LIB if X86_64
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index d63a28c5f95a9..5b788492ce5e7 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -483,12 +483,22 @@ static void amd_pstate_boost_init(struct amd_cpudata *cpudata)
+ 	amd_pstate_driver.boost_enabled = true;
+ }
+ 
++static void amd_perf_ctl_reset(unsigned int cpu)
++{
++	wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0);
++}
++
+ static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
+ {
+ 	int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret;
+ 	struct device *dev;
+ 	struct amd_cpudata *cpudata;
+ 
++	/*
++	 * Resetting PERF_CTL_MSR will put the CPU in P0 frequency,
++	 * which is ideal for initialization process.
++	 */
++	amd_perf_ctl_reset(policy->cpu);
+ 	dev = get_cpu_device(policy->cpu);
+ 	if (!dev)
+ 		return -ENODEV;
+@@ -718,16 +728,7 @@ static int __init amd_pstate_init(void)
+ 
+ 	return ret;
+ }
+-
+-static void __exit amd_pstate_exit(void)
+-{
+-	cpufreq_unregister_driver(&amd_pstate_driver);
+-
+-	amd_pstate_enable(false);
+-}
+-
+-module_init(amd_pstate_init);
+-module_exit(amd_pstate_exit);
++device_initcall(amd_pstate_init);
+ 
+ MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>");
+ MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver");
+diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
+index efb4990b29e10..c6f08066e1653 100644
+--- a/drivers/dma-buf/dma-buf.c
++++ b/drivers/dma-buf/dma-buf.c
+@@ -15,6 +15,7 @@
+ #include <linux/slab.h>
+ #include <linux/dma-buf.h>
+ #include <linux/dma-fence.h>
++#include <linux/dma-fence-unwrap.h>
+ #include <linux/anon_inodes.h>
+ #include <linux/export.h>
+ #include <linux/debugfs.h>
+@@ -391,8 +392,10 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
+ 				     const void __user *user_data)
+ {
+ 	struct dma_buf_import_sync_file arg;
+-	struct dma_fence *fence;
++	struct dma_fence *fence, *f;
+ 	enum dma_resv_usage usage;
++	struct dma_fence_unwrap iter;
++	unsigned int num_fences;
+ 	int ret = 0;
+ 
+ 	if (copy_from_user(&arg, user_data, sizeof(arg)))
+@@ -411,13 +414,21 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
+ 	usage = (arg.flags & DMA_BUF_SYNC_WRITE) ? DMA_RESV_USAGE_WRITE :
+ 						   DMA_RESV_USAGE_READ;
+ 
+-	dma_resv_lock(dmabuf->resv, NULL);
++	num_fences = 0;
++	dma_fence_unwrap_for_each(f, &iter, fence)
++		++num_fences;
+ 
+-	ret = dma_resv_reserve_fences(dmabuf->resv, 1);
+-	if (!ret)
+-		dma_resv_add_fence(dmabuf->resv, fence, usage);
++	if (num_fences > 0) {
++		dma_resv_lock(dmabuf->resv, NULL);
+ 
+-	dma_resv_unlock(dmabuf->resv);
++		ret = dma_resv_reserve_fences(dmabuf->resv, num_fences);
++		if (!ret) {
++			dma_fence_unwrap_for_each(f, &iter, fence)
++				dma_resv_add_fence(dmabuf->resv, f, usage);
++		}
++
++		dma_resv_unlock(dmabuf->resv);
++	}
+ 
+ 	dma_fence_put(fence);
+ 
+diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
+index 8f5848aa144fe..59d158873f4cb 100644
+--- a/drivers/dma-buf/dma-heap.c
++++ b/drivers/dma-buf/dma-heap.c
+@@ -233,18 +233,6 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
+ 		return ERR_PTR(-EINVAL);
+ 	}
+ 
+-	/* check the name is unique */
+-	mutex_lock(&heap_list_lock);
+-	list_for_each_entry(h, &heap_list, list) {
+-		if (!strcmp(h->name, exp_info->name)) {
+-			mutex_unlock(&heap_list_lock);
+-			pr_err("dma_heap: Already registered heap named %s\n",
+-			       exp_info->name);
+-			return ERR_PTR(-EINVAL);
+-		}
+-	}
+-	mutex_unlock(&heap_list_lock);
+-
+ 	heap = kzalloc(sizeof(*heap), GFP_KERNEL);
+ 	if (!heap)
+ 		return ERR_PTR(-ENOMEM);
+@@ -283,13 +271,27 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
+ 		err_ret = ERR_CAST(dev_ret);
+ 		goto err2;
+ 	}
+-	/* Add heap to the list */
++
+ 	mutex_lock(&heap_list_lock);
++	/* check the name is unique */
++	list_for_each_entry(h, &heap_list, list) {
++		if (!strcmp(h->name, exp_info->name)) {
++			mutex_unlock(&heap_list_lock);
++			pr_err("dma_heap: Already registered heap named %s\n",
++			       exp_info->name);
++			err_ret = ERR_PTR(-EINVAL);
++			goto err3;
++		}
++	}
++
++	/* Add heap to the list */
+ 	list_add(&heap->list, &heap_list);
+ 	mutex_unlock(&heap_list_lock);
+ 
+ 	return heap;
+ 
++err3:
++	device_destroy(dma_heap_class, heap->heap_devt);
+ err2:
+ 	cdev_del(&heap->heap_cdev);
+ err1:
+diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
+index 6c416955da532..bbe0a7cabb75f 100644
+--- a/drivers/fpga/Kconfig
++++ b/drivers/fpga/Kconfig
+@@ -246,7 +246,9 @@ config FPGA_MGR_VERSAL_FPGA
+ 
+ config FPGA_M10_BMC_SEC_UPDATE
+ 	tristate "Intel MAX10 BMC Secure Update driver"
+-	depends on MFD_INTEL_M10_BMC && FW_UPLOAD
++	depends on MFD_INTEL_M10_BMC
++	select FW_LOADER
++	select FW_UPLOAD
+ 	help
+ 	  Secure update support for the Intel MAX10 board management
+ 	  controller.
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
+index c8935d7182073..4485bb29bec96 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_aldebaran.c
+@@ -41,5 +41,6 @@ const struct kfd2kgd_calls aldebaran_kfd2kgd = {
+ 	.get_atc_vmid_pasid_mapping_info =
+ 				kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
+ 	.set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base,
++	.get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy,
+ 	.program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings
+ };
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 93ad00453f4b3..7db4aef9c45cb 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -170,9 +170,7 @@ int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
+ 	    (kfd_mem_limit.ttm_mem_used + ttm_mem_needed >
+ 	     kfd_mem_limit.max_ttm_mem_limit) ||
+ 	    (adev && adev->kfd.vram_used + vram_needed >
+-	     adev->gmc.real_vram_size -
+-	     atomic64_read(&adev->vram_pin_size) -
+-	     reserved_for_pt)) {
++	     adev->gmc.real_vram_size - reserved_for_pt)) {
+ 		ret = -ENOMEM;
+ 		goto release;
+ 	}
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+index 491d4846fc02c..cfb262911bfc7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+@@ -328,7 +328,6 @@ static void amdgpu_connector_free_edid(struct drm_connector *connector)
+ 
+ 	kfree(amdgpu_connector->edid);
+ 	amdgpu_connector->edid = NULL;
+-	drm_connector_update_edid_property(connector, NULL);
+ }
+ 
+ static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+index 8ef31d687ef3b..111484ceb47d7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+@@ -413,11 +413,9 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
+ 	if (r)
+ 		goto release_object;
+ 
+-	if (args->flags & AMDGPU_GEM_USERPTR_REGISTER) {
+-		r = amdgpu_mn_register(bo, args->addr);
+-		if (r)
+-			goto release_object;
+-	}
++	r = amdgpu_mn_register(bo, args->addr);
++	if (r)
++		goto release_object;
+ 
+ 	if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
+ 		r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+index aebc384531ac8..bff5d8c832add 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+@@ -479,6 +479,12 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
+ 	unsigned i;
+ 	unsigned vmhub, inv_eng;
+ 
++	if (adev->enable_mes) {
++		/* reserve engine 5 for firmware */
++		for (vmhub = 0; vmhub < AMDGPU_MAX_VMHUBS; vmhub++)
++			vm_inv_engs[vmhub] &= ~(1 << 5);
++	}
++
+ 	for (i = 0; i < adev->num_rings; ++i) {
+ 		ring = adev->rings[i];
+ 		vmhub = ring->funcs->vmhub;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+index c9dec2434f370..cfa45a697d241 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+@@ -171,6 +171,7 @@ void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx)
+ {
+ 	amdgpu_bo_free_kernel(&mem_ctx->shared_bo, &mem_ctx->shared_mc_addr,
+ 			      &mem_ctx->shared_buf);
++	mem_ctx->shared_bo = NULL;
+ }
+ 
+ static void psp_free_shared_bufs(struct psp_context *psp)
+@@ -181,6 +182,7 @@ static void psp_free_shared_bufs(struct psp_context *psp)
+ 	/* free TMR memory buffer */
+ 	pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
+ 	amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, pptr);
++	psp->tmr_bo = NULL;
+ 
+ 	/* free xgmi shared memory */
+ 	psp_ta_free_shared_buf(&psp->xgmi_context.context.mem_context);
+@@ -728,7 +730,7 @@ static int psp_load_toc(struct psp_context *psp,
+ /* Set up Trusted Memory Region */
+ static int psp_tmr_init(struct psp_context *psp)
+ {
+-	int ret;
++	int ret = 0;
+ 	int tmr_size;
+ 	void *tmr_buf;
+ 	void **pptr;
+@@ -755,10 +757,12 @@ static int psp_tmr_init(struct psp_context *psp)
+ 		}
+ 	}
+ 
+-	pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
+-	ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT,
+-				      AMDGPU_GEM_DOMAIN_VRAM,
+-				      &psp->tmr_bo, &psp->tmr_mc_addr, pptr);
++	if (!psp->tmr_bo) {
++		pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL;
++		ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT,
++					      AMDGPU_GEM_DOMAIN_VRAM,
++					      &psp->tmr_bo, &psp->tmr_mc_addr, pptr);
++	}
+ 
+ 	return ret;
+ }
+@@ -2720,8 +2724,6 @@ static int psp_suspend(void *handle)
+ 	}
+ 
+ out:
+-	psp_free_shared_bufs(psp);
+-
+ 	return ret;
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index 04130f8813ef1..369c0d03e3c6a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -143,32 +143,6 @@ int amdgpu_vm_set_pasid(struct amdgpu_device *adev, struct amdgpu_vm *vm,
+ 	return 0;
+ }
+ 
+-/*
+- * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS
+- * happens while holding this lock anywhere to prevent deadlocks when
+- * an MMU notifier runs in reclaim-FS context.
+- */
+-static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm)
+-{
+-	mutex_lock(&vm->eviction_lock);
+-	vm->saved_flags = memalloc_noreclaim_save();
+-}
+-
+-static inline int amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm)
+-{
+-	if (mutex_trylock(&vm->eviction_lock)) {
+-		vm->saved_flags = memalloc_noreclaim_save();
+-		return 1;
+-	}
+-	return 0;
+-}
+-
+-static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm)
+-{
+-	memalloc_noreclaim_restore(vm->saved_flags);
+-	mutex_unlock(&vm->eviction_lock);
+-}
+-
+ /**
+  * amdgpu_vm_bo_evicted - vm_bo is evicted
+  *
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+index 278512535b518..39d2898caedef 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+@@ -503,4 +503,30 @@ static inline uint64_t amdgpu_vm_tlb_seq(struct amdgpu_vm *vm)
+ 	return atomic64_read(&vm->tlb_seq);
+ }
+ 
++/*
++ * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS
++ * happens while holding this lock anywhere to prevent deadlocks when
++ * an MMU notifier runs in reclaim-FS context.
++ */
++static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm)
++{
++	mutex_lock(&vm->eviction_lock);
++	vm->saved_flags = memalloc_noreclaim_save();
++}
++
++static inline bool amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm)
++{
++	if (mutex_trylock(&vm->eviction_lock)) {
++		vm->saved_flags = memalloc_noreclaim_save();
++		return true;
++	}
++	return false;
++}
++
++static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm)
++{
++	memalloc_noreclaim_restore(vm->saved_flags);
++	mutex_unlock(&vm->eviction_lock);
++}
++
+ #endif
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+index 88de9f0d4728a..9838995744648 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+@@ -597,7 +597,9 @@ static int amdgpu_vm_pt_alloc(struct amdgpu_device *adev,
+ 	if (entry->bo)
+ 		return 0;
+ 
++	amdgpu_vm_eviction_unlock(vm);
+ 	r = amdgpu_vm_pt_create(adev, vm, cursor->level, immediate, &pt);
++	amdgpu_vm_eviction_lock(vm);
+ 	if (r)
+ 		return r;
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+index 3bff0ae15e64e..3175b9c1849dd 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+@@ -190,7 +190,11 @@ static int mes_v11_0_add_hw_queue(struct amdgpu_mes *mes,
+ 	mes_add_queue_pkt.trap_handler_addr = input->tba_addr;
+ 	mes_add_queue_pkt.tma_addr = input->tma_addr;
+ 	mes_add_queue_pkt.is_kfd_process = input->is_kfd_process;
+-	mes_add_queue_pkt.trap_en = 1;
++
++	if (!(((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 4) &&
++		  (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(11, 0, 0)) &&
++		  (adev->ip_versions[GC_HWIP][0] <= IP_VERSION(11, 0, 3))))
++		mes_add_queue_pkt.trap_en = 1;
+ 
+ 	/* For KFD, gds_size is re-used for queue size (needed in MES for AQL queues) */
+ 	mes_add_queue_pkt.is_aql_queue = input->is_aql_queue;
+diff --git a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
+index 60a81649cf128..0c4c5499bb5cc 100644
+--- a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
++++ b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h
+@@ -742,7 +742,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
+ 	0xbf88fffe, 0x877aff7f,
+ 	0x04000000, 0x8f7a857a,
+ 	0x886d7a6d, 0xb97b02dc,
+-	0x8f7b997b, 0xb97a2a05,
++	0x8f7b997b, 0xb97a3a05,
+ 	0x807a817a, 0xbf0d997b,
+ 	0xbf850002, 0x8f7a897a,
+ 	0xbf820001, 0x8f7a8a7a,
+@@ -819,7 +819,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
+ 	0xbefe037c, 0xbefc0370,
+ 	0xf4611c7a, 0xf8000000,
+ 	0x80708470, 0xbefc037e,
+-	0xb9702a05, 0x80708170,
++	0xb9703a05, 0x80708170,
+ 	0xbf0d9973, 0xbf850002,
+ 	0x8f708970, 0xbf820001,
+ 	0x8f708a70, 0xb97a1e06,
+@@ -1069,7 +1069,7 @@ static const uint32_t cwsr_trap_nv1x_hex[] = {
+ 	0xb9f9f816, 0x876f7bff,
+ 	0xfffff800, 0x906f8b6f,
+ 	0xb9efa2c3, 0xb9f3f801,
+-	0xb96e2a05, 0x806e816e,
++	0xb96e3a05, 0x806e816e,
+ 	0xbf0d9972, 0xbf850002,
+ 	0x8f6e896e, 0xbf820001,
+ 	0x8f6e8a6e, 0xb96f1e06,
+@@ -2114,7 +2114,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 	0x007a0000, 0x7e000280,
+ 	0xbefe037a, 0xbeff037b,
+ 	0xb97b02dc, 0x8f7b997b,
+-	0xb97a2a05, 0x807a817a,
++	0xb97a3a05, 0x807a817a,
+ 	0xbf0d997b, 0xbf850002,
+ 	0x8f7a897a, 0xbf820001,
+ 	0x8f7a8a7a, 0xb97b1e06,
+@@ -2157,7 +2157,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 	0x01000000, 0xe0704100,
+ 	0x705d0100, 0xe0704200,
+ 	0x705d0200, 0xe0704300,
+-	0x705d0300, 0xb9702a05,
++	0x705d0300, 0xb9703a05,
+ 	0x80708170, 0xbf0d9973,
+ 	0xbf850002, 0x8f708970,
+ 	0xbf820001, 0x8f708a70,
+@@ -2189,7 +2189,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 	0xbefe03ff, 0x0000ffff,
+ 	0xbeff0380, 0xe0704000,
+ 	0x705d0200, 0xbefe03c1,
+-	0xb9702a05, 0x80708170,
++	0xb9703a05, 0x80708170,
+ 	0xbf0d9973, 0xbf850002,
+ 	0x8f708970, 0xbf820001,
+ 	0x8f708a70, 0xb97a1e06,
+@@ -2475,7 +2475,7 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 	0xb9ef4803, 0x876f7bff,
+ 	0xfffff800, 0x906f8b6f,
+ 	0xb9efa2c3, 0xb9f3f801,
+-	0xb96e2a05, 0x806e816e,
++	0xb96e3a05, 0x806e816e,
+ 	0xbf0d9972, 0xbf850002,
+ 	0x8f6e896e, 0xbf820001,
+ 	0x8f6e8a6e, 0xb96f1e06,
+@@ -2494,11 +2494,13 @@ static const uint32_t cwsr_trap_gfx10_hex[] = {
+ 	0xbf9f0000, 0xbf9f0000,
+ 	0xbf9f0000, 0x00000000,
+ };
+-
+ static const uint32_t cwsr_trap_gfx11_hex[] = {
+-	0xbfa00001, 0xbfa0021b,
++	0xbfa00001, 0xbfa00221,
+ 	0xb0804006, 0xb8f8f802,
+-	0x91788678, 0xb8fbf803,
++	0x9178ff78, 0x00020006,
++	0xb8fbf803, 0xbf0d9e6d,
++	0xbfa10001, 0xbfbd0000,
++	0xbf0d9f6d, 0xbfa20006,
+ 	0x8b6eff78, 0x00002000,
+ 	0xbfa10009, 0x8b6eff6d,
+ 	0x00ff0000, 0xbfa2001e,
+@@ -2766,7 +2768,7 @@ static const uint32_t cwsr_trap_gfx11_hex[] = {
+ 	0x701d0000, 0x807d817d,
+ 	0x8070ff70, 0x00000080,
+ 	0xbf0a7b7d, 0xbfa2fff8,
+-	0xbfa00141, 0xbef4007e,
++	0xbfa00146, 0xbef4007e,
+ 	0x8b75ff7f, 0x0000ffff,
+ 	0x8c75ff75, 0x00040000,
+ 	0xbef60080, 0xbef700ff,
+@@ -2926,8 +2928,11 @@ static const uint32_t cwsr_trap_gfx11_hex[] = {
+ 	0xf8000074, 0xbf89fc07,
+ 	0x8b6dff6d, 0x0000ffff,
+ 	0x8bfe7e7e, 0x8bea6a6a,
+-	0xb97af802, 0xbe804a6c,
+-	0xbfb00000, 0xbf9f0000,
++	0xb8eef802, 0xbf0d866e,
++	0xbfa20002, 0xb97af802,
++	0xbe80486c, 0xb97af802,
++	0xbe804a6c, 0xbfb00000,
+ 	0xbf9f0000, 0xbf9f0000,
+ 	0xbf9f0000, 0xbf9f0000,
++	0xbf9f0000, 0x00000000,
+ };
+diff --git a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm
+index 250ab007399bd..8b92c33c2a7c5 100644
+--- a/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm
++++ b/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm
+@@ -43,12 +43,14 @@
+ #define HAVE_XNACK (ASIC_FAMILY < CHIP_SIENNA_CICHLID)
+ #define HAVE_SENDMSG_RTN (ASIC_FAMILY >= CHIP_PLUM_BONITO)
+ #define HAVE_BUFFER_LDS_LOAD (ASIC_FAMILY < CHIP_PLUM_BONITO)
++#define SW_SA_TRAP (ASIC_FAMILY >= CHIP_PLUM_BONITO)
+ 
+ var SINGLE_STEP_MISSED_WORKAROUND		= 1	//workaround for lost MODE.DEBUG_EN exception when SAVECTX raised
+ 
+ var SQ_WAVE_STATUS_SPI_PRIO_MASK		= 0x00000006
+ var SQ_WAVE_STATUS_HALT_MASK			= 0x2000
+ var SQ_WAVE_STATUS_ECC_ERR_MASK			= 0x20000
++var SQ_WAVE_STATUS_TRAP_EN_SHIFT		= 6
+ 
+ var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SHIFT		= 12
+ var SQ_WAVE_LDS_ALLOC_LDS_SIZE_SIZE		= 9
+@@ -183,6 +185,19 @@ L_SKIP_RESTORE:
+ 
+ 	s_getreg_b32	s_save_trapsts, hwreg(HW_REG_TRAPSTS)
+ 
++#if SW_SA_TRAP
++	// If ttmp1[30] is set then issue s_barrier to unblock dependent waves.
++	s_bitcmp1_b32	s_save_pc_hi, 30
++	s_cbranch_scc0	L_TRAP_NO_BARRIER
++	s_barrier
++
++L_TRAP_NO_BARRIER:
++	// If ttmp1[31] is set then trap may occur early.
++	// Spin wait until SAVECTX exception is raised.
++	s_bitcmp1_b32	s_save_pc_hi, 31
++	s_cbranch_scc1  L_CHECK_SAVE
++#endif
++
+ 	s_and_b32       ttmp2, s_save_status, SQ_WAVE_STATUS_HALT_MASK
+ 	s_cbranch_scc0	L_NOT_HALTED
+ 
+@@ -1061,8 +1076,20 @@ L_RESTORE_HWREG:
+ 	s_and_b32	s_restore_pc_hi, s_restore_pc_hi, 0x0000ffff		//pc[47:32] //Do it here in order not to affect STATUS
+ 	s_and_b64	exec, exec, exec					// Restore STATUS.EXECZ, not writable by s_setreg_b32
+ 	s_and_b64	vcc, vcc, vcc						// Restore STATUS.VCCZ, not writable by s_setreg_b32
++
++#if SW_SA_TRAP
++	// If traps are enabled then return to the shader with PRIV=0.
++	// Otherwise retain PRIV=1 for subsequent context save requests.
++	s_getreg_b32	s_restore_tmp, hwreg(HW_REG_STATUS)
++	s_bitcmp1_b32	s_restore_tmp, SQ_WAVE_STATUS_TRAP_EN_SHIFT
++	s_cbranch_scc1	L_RETURN_WITHOUT_PRIV
++
+ 	s_setreg_b32	hwreg(HW_REG_STATUS), s_restore_status			// SCC is included, which is changed by previous salu
++	s_setpc_b64	[s_restore_pc_lo, s_restore_pc_hi]
++L_RETURN_WITHOUT_PRIV:
++#endif
+ 
++	s_setreg_b32	hwreg(HW_REG_STATUS), s_restore_status			// SCC is included, which is changed by previous salu
+ 	s_rfe_b64	s_restore_pc_lo						//Return to the main shader program and resume execution
+ 
+ L_END_PGM:
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 7f8eb09b0b7cb..4b16d9d1e058c 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1371,7 +1371,44 @@ static const struct dmi_system_id hpd_disconnect_quirk_table[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"),
+ 		},
+ 	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"),
++		},
++	},
+ 	{}
++	/* TODO: refactor this from a fixed table to a dynamic option */
+ };
+ 
+ static void retrieve_dmi_info(struct amdgpu_display_manager *dm)
+@@ -7650,9 +7687,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
+ 		bundle->surface_updates[planes_count].plane_info =
+ 			&bundle->plane_infos[planes_count];
+ 
+-		fill_dc_dirty_rects(plane, old_plane_state, new_plane_state,
+-				    new_crtc_state,
+-				    &bundle->flip_addrs[planes_count]);
++		if (acrtc_state->stream->link->psr_settings.psr_feature_enabled)
++			fill_dc_dirty_rects(plane, old_plane_state,
++					    new_plane_state, new_crtc_state,
++					    &bundle->flip_addrs[planes_count]);
+ 
+ 		/*
+ 		 * Only allow immediate flips for fast updates that don't
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index dbf8158b832e4..fcddf60d3c10d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -746,6 +746,9 @@ struct dc_debug_options {
+ 	bool force_disable_subvp;
+ 	bool force_subvp_mclk_switch;
+ 	bool allow_sw_cursor_fallback;
++	unsigned int force_subvp_num_ways;
++	unsigned int force_mall_ss_num_ways;
++	bool alloc_extra_way_for_cursor;
+ 	bool force_usr_allow;
+ 	/* uses value at boot and disables switch */
+ 	bool disable_dtb_ref_clk_switch;
+diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
+index 1b70b78e2fa15..af631085e88c5 100644
+--- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
+@@ -359,7 +359,8 @@ static const struct dce_audio_registers audio_regs[] = {
+ 	audio_regs(2),
+ 	audio_regs(3),
+ 	audio_regs(4),
+-	audio_regs(5)
++	audio_regs(5),
++	audio_regs(6),
+ };
+ 
+ #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+index c72166e096bad..bbc0bfbec6c42 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -49,6 +49,7 @@
+ #include "dcn20/dcn20_optc.h"
+ #include "dmub_subvp_state.h"
+ #include "dce/dmub_hw_lock_mgr.h"
++#include "dcn32_resource.h"
+ #include "dc_link_dp.h"
+ #include "dmub/inc/dmub_subvp_state.h"
+ 
+@@ -198,42 +199,6 @@ static bool dcn32_check_no_memory_request_for_cab(struct dc *dc)
+ 	return false;
+ }
+ 
+-/* This function takes in the start address and surface size to be cached in CAB
+- * and calculates the total number of cache lines required to store the surface.
+- * The number of cache lines used for each surface is calculated independently of
+- * one another. For example, if there is a primary surface(1), meta surface(2), and
+- * cursor(3), this function should be called 3 times to calculate the number of cache
+- * lines used for each of those surfaces.
+- */
+-static uint32_t dcn32_cache_lines_for_surface(struct dc *dc, uint32_t surface_size, uint64_t start_address)
+-{
+-	uint32_t lines_used = 1;
+-	uint32_t num_cached_bytes = 0;
+-	uint32_t remaining_size = 0;
+-	uint32_t cache_line_size = dc->caps.cache_line_size;
+-	uint32_t remainder = 0;
+-
+-	/* 1. Calculate surface size minus the number of bytes stored
+-	 * in the first cache line (all bytes in first cache line might
+-	 * not be fully used).
+-	 */
+-	div_u64_rem(start_address, cache_line_size, &remainder);
+-	num_cached_bytes = cache_line_size - remainder;
+-	remaining_size = surface_size - num_cached_bytes;
+-
+-	/* 2. Calculate number of cache lines that will be fully used with
+-	 * the remaining number of bytes to be stored.
+-	 */
+-	lines_used += (remaining_size / cache_line_size);
+-
+-	/* 3. Check if we need an extra line due to the remaining size not being
+-	 * a multiple of CACHE_LINE_SIZE.
+-	 */
+-	if (remaining_size % cache_line_size > 0)
+-		lines_used++;
+-
+-	return lines_used;
+-}
+ 
+ /* This function loops through every surface that needs to be cached in CAB for SS,
+  * and calculates the total number of ways required to store all surfaces (primary,
+@@ -241,94 +206,115 @@ static uint32_t dcn32_cache_lines_for_surface(struct dc *dc, uint32_t surface_si
+  */
+ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *ctx)
+ {
+-	uint8_t i, j;
++	uint8_t i;
++	int j;
+ 	struct dc_stream_state *stream = NULL;
+ 	struct dc_plane_state *plane = NULL;
+-	uint32_t surface_size = 0;
+ 	uint32_t cursor_size = 0;
+-	uint32_t cache_lines_used = 0;
+ 	uint32_t total_lines = 0;
+ 	uint32_t lines_per_way = 0;
+-	uint32_t num_ways = 0;
+-	uint32_t prev_addr_low = 0;
++	uint8_t num_ways = 0;
++	uint8_t bytes_per_pixel = 0;
++	uint8_t cursor_bpp = 0;
++	uint16_t mblk_width = 0;
++	uint16_t mblk_height = 0;
++	uint16_t mall_alloc_width_blk_aligned = 0;
++	uint16_t mall_alloc_height_blk_aligned = 0;
++	uint16_t num_mblks = 0;
++	uint32_t bytes_in_mall = 0;
++	uint32_t cache_lines_used = 0;
++	uint32_t cache_lines_per_plane = 0;
+ 
+-	for (i = 0; i < ctx->stream_count; i++) {
+-		stream = ctx->streams[i];
++	for (i = 0; i < dc->res_pool->pipe_count; i++) {
++		struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+ 
+-		// Don't include PSR surface in the total surface size for CAB allocation
+-		if (stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED)
++		if (!pipe->stream || !pipe->plane_state ||
++				pipe->stream->link->psr_settings.psr_version != DC_PSR_VERSION_UNSUPPORTED ||
++				pipe->stream->mall_stream_config.type == SUBVP_PHANTOM)
+ 			continue;
+ 
+-		if (ctx->stream_status[i].plane_count == 0)
+-			continue;
++		bytes_per_pixel = pipe->plane_state->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4;
++		mblk_width = DCN3_2_MBLK_WIDTH;
++		mblk_height = bytes_per_pixel == 4 ? DCN3_2_MBLK_HEIGHT_4BPE : DCN3_2_MBLK_HEIGHT_8BPE;
+ 
+-		// For each stream, loop through each plane to calculate the number of cache
+-		// lines required to store the surface in CAB
+-		for (j = 0; j < ctx->stream_status[i].plane_count; j++) {
+-			plane = ctx->stream_status[i].plane_states[j];
++		/* full_vp_width_blk_aligned = FLOOR(vp_x_start + full_vp_width + blk_width - 1, blk_width) -
++		 * FLOOR(vp_x_start, blk_width)
++		 *
++		 * mall_alloc_width_blk_aligned_l/c = full_vp_width_blk_aligned_l/c
++		 */
++		mall_alloc_width_blk_aligned = ((pipe->plane_res.scl_data.viewport.x +
++				pipe->plane_res.scl_data.viewport.width + mblk_width - 1) / mblk_width * mblk_width) +
++						(pipe->plane_res.scl_data.viewport.x / mblk_width * mblk_width);
++
++		/* full_vp_height_blk_aligned = FLOOR(vp_y_start + full_vp_height + blk_height - 1, blk_height) -
++		 * FLOOR(vp_y_start, blk_height)
++		 *
++		 * mall_alloc_height_blk_aligned_l/c = full_vp_height_blk_aligned_l/c
++		 */
++		mall_alloc_height_blk_aligned = ((pipe->plane_res.scl_data.viewport.y +
++				pipe->plane_res.scl_data.viewport.height + mblk_height - 1) / mblk_height * mblk_height) +
++						(pipe->plane_res.scl_data.viewport.y / mblk_height * mblk_height);
+ 
+-			// Calculate total surface size
+-			if (prev_addr_low != plane->address.grph.addr.u.low_part) {
+-				/* if plane address are different from prev FB, then userspace allocated separate FBs*/
+-				surface_size += plane->plane_size.surface_pitch *
+-					plane->plane_size.surface_size.height *
+-					(plane->format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616 ? 8 : 4);
++		num_mblks = ((mall_alloc_width_blk_aligned + mblk_width - 1) / mblk_width) *
++				((mall_alloc_height_blk_aligned + mblk_height - 1) / mblk_height);
+ 
+-				prev_addr_low = plane->address.grph.addr.u.low_part;
+-			} else {
+-				/* We have the same fb for all the planes.
+-				 * Xorg always creates one giant fb that holds all surfaces,
+-				 * so allocating it once is sufficient.
+-				 * */
+-				continue;
+-			}
+-			// Convert surface size + starting address to number of cache lines required
+-			// (alignment accounted for)
+-			cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
+-					plane->address.grph.addr.quad_part);
+-
+-			if (plane->address.grph.meta_addr.quad_part) {
+-				// Meta surface
+-				cache_lines_used += dcn32_cache_lines_for_surface(dc, surface_size,
+-						plane->address.grph.meta_addr.quad_part);
+-			}
+-		}
++		/* For DCC:
++		 * meta_num_mblk = CEILING(full_mblk_width_ub_l*full_mblk_height_ub_l*Bpe/256/mblk_bytes, 1)
++		 */
++		if (pipe->plane_state->dcc.enable)
++			num_mblks += (mall_alloc_width_blk_aligned * mall_alloc_width_blk_aligned * bytes_per_pixel +
++					(256 * DCN3_2_MALL_MBLK_SIZE_BYTES) - 1) / (256 * DCN3_2_MALL_MBLK_SIZE_BYTES);
+ 
+-		// Include cursor size for CAB allocation
+-		for (j = 0; j < dc->res_pool->pipe_count; j++) {
+-			struct pipe_ctx *pipe = &ctx->res_ctx.pipe_ctx[j];
+-			struct hubp *hubp = pipe->plane_res.hubp;
++		bytes_in_mall = num_mblks * DCN3_2_MALL_MBLK_SIZE_BYTES;
+ 
+-			if (pipe->stream && pipe->plane_state && hubp)
+-				/* Find the cursor plane and use the exact size instead of
+-				 * using the max for calculation
+-				 */
+-				if (hubp->curs_attr.width > 0) {
+-					cursor_size = hubp->curs_attr.width * hubp->curs_attr.height;
+-					break;
+-				}
+-		}
++		/* (cache lines used is total bytes / cache_line size. Add +2 for worst case alignment
++		 * (MALL is 64-byte aligned)
++		 */
++		cache_lines_per_plane = bytes_in_mall / dc->caps.cache_line_size + 2;
++		cache_lines_used += cache_lines_per_plane;
++	}
+ 
+-		switch (stream->cursor_attributes.color_format) {
+-		case CURSOR_MODE_MONO:
+-			cursor_size /= 2;
+-			break;
+-		case CURSOR_MODE_COLOR_1BIT_AND:
+-		case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
+-		case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
+-			cursor_size *= 4;
+-			break;
++	// Include cursor size for CAB allocation
++	for (j = 0; j < dc->res_pool->pipe_count; j++) {
++		struct pipe_ctx *pipe = &ctx->res_ctx.pipe_ctx[j];
++		struct hubp *hubp = pipe->plane_res.hubp;
+ 
+-		case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
+-		case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
+-			cursor_size *= 8;
+-			break;
+-		}
++		if (pipe->stream && pipe->plane_state && hubp)
++			/* Find the cursor plane and use the exact size instead of
++			using the max for calculation */
+ 
+-		if (stream->cursor_position.enable && plane->address.grph.cursor_cache_addr.quad_part) {
+-			cache_lines_used += dcn32_cache_lines_for_surface(dc, cursor_size,
+-					plane->address.grph.cursor_cache_addr.quad_part);
+-		}
++		if (hubp->curs_attr.width > 0) {
++				cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height;
++
++				switch (pipe->stream->cursor_attributes.color_format) {
++				case CURSOR_MODE_MONO:
++					cursor_size /= 2;
++					cursor_bpp = 4;
++					break;
++				case CURSOR_MODE_COLOR_1BIT_AND:
++				case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
++				case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
++					cursor_size *= 4;
++					cursor_bpp = 4;
++					break;
++
++				case CURSOR_MODE_COLOR_64BIT_FP_PRE_MULTIPLIED:
++				case CURSOR_MODE_COLOR_64BIT_FP_UN_PRE_MULTIPLIED:
++					cursor_size *= 8;
++					cursor_bpp = 8;
++					break;
++				}
++
++				if (pipe->stream->cursor_position.enable && !dc->debug.alloc_extra_way_for_cursor &&
++						cursor_size > 16384) {
++					/* cursor_num_mblk = CEILING(num_cursors*cursor_width*cursor_width*cursor_Bpe/mblk_bytes, 1)
++					 */
++					cache_lines_used += (((cursor_size + DCN3_2_MALL_MBLK_SIZE_BYTES - 1) /
++							DCN3_2_MALL_MBLK_SIZE_BYTES) * DCN3_2_MALL_MBLK_SIZE_BYTES) /
++							dc->caps.cache_line_size + 2;
++				}
++				break;
++			}
+ 	}
+ 
+ 	// Convert number of cache lines required to number of ways
+@@ -345,8 +331,8 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
+ 			plane = ctx->stream_status[i].plane_states[j];
+ 
+ 			if (stream->cursor_position.enable && plane &&
+-				!plane->address.grph.cursor_cache_addr.quad_part &&
+-				cursor_size > 16384) {
++					dc->debug.alloc_extra_way_for_cursor &&
++					cursor_size > 16384) {
+ 				/* Cursor caching is not supported since it won't be on the same line.
+ 				 * So we need an extra line to accommodate it. With large cursors and a single 4k monitor
+ 				 * this case triggers corruption. If we're at the edge, then dont trigger display refresh
+@@ -358,7 +344,9 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c
+ 			}
+ 		}
+ 	}
+-
++	if (dc->debug.force_mall_ss_num_ways > 0) {
++		num_ways = dc->debug.force_mall_ss_num_ways;
++	}
+ 	return num_ways;
+ }
+ 
+@@ -741,10 +729,7 @@ void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context)
+ 		struct hubp *hubp = pipe->plane_res.hubp;
+ 
+ 		if (pipe->stream && pipe->plane_state && hubp && hubp->funcs->hubp_update_mall_sel) {
+-			//Round cursor width up to next multiple of 64
+-			int cursor_width = ((hubp->curs_attr.width + 63) / 64) * 64;
+-			int cursor_height = hubp->curs_attr.height;
+-			int cursor_size = cursor_width * cursor_height;
++			int cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height;
+ 
+ 			switch (hubp->curs_attr.color_format) {
+ 			case CURSOR_MODE_MONO:
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+index c3b783cea8a03..6f1bcb45a3b2d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource.c
+@@ -872,6 +872,7 @@ static const struct dc_debug_options debug_defaults_drv = {
+ 	.enable_single_display_2to1_odm_policy = true,
+ 	.enable_dp_dig_pixel_rate_div_policy = 1,
+ 	.allow_sw_cursor_fallback = false,
++	.alloc_extra_way_for_cursor = true,
+ };
+ 
+ static const struct dc_debug_options debug_defaults_diags = {
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+index 13cd1f2e50ca3..7c37575d69c73 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+@@ -54,13 +54,14 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
+ 	uint32_t num_mblks = 0;
+ 	uint32_t cache_lines_per_plane = 0;
+ 	uint32_t i = 0, j = 0;
+-	uint32_t mblk_width = 0;
+-	uint32_t mblk_height = 0;
++	uint16_t mblk_width = 0;
++	uint16_t mblk_height = 0;
+ 	uint32_t full_vp_width_blk_aligned = 0;
+ 	uint32_t full_vp_height_blk_aligned = 0;
+ 	uint32_t mall_alloc_width_blk_aligned = 0;
+ 	uint32_t mall_alloc_height_blk_aligned = 0;
+-	uint32_t full_vp_height = 0;
++	uint16_t full_vp_height = 0;
++	bool subvp_in_use = false;
+ 
+ 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ 		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+@@ -70,6 +71,7 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
+ 				pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) {
+ 			struct pipe_ctx *main_pipe = NULL;
+ 
++			subvp_in_use = true;
+ 			/* Get full viewport height from main pipe (required for MBLK calculation) */
+ 			for (j = 0; j < dc->res_pool->pipe_count; j++) {
+ 				main_pipe = &context->res_ctx.pipe_ctx[j];
+@@ -129,6 +131,9 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat
+ 	if (cache_lines_used % lines_per_way > 0)
+ 		num_ways++;
+ 
++	if (subvp_in_use && dc->debug.force_subvp_num_ways > 0)
++		num_ways = dc->debug.force_subvp_num_ways;
++
+ 	return num_ways;
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
+index 7309eed33a61c..d074716dc1972 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn321/dcn321_resource.c
+@@ -873,6 +873,7 @@ static const struct dc_debug_options debug_defaults_drv = {
+ 	.enable_single_display_2to1_odm_policy = true,
+ 	.enable_dp_dig_pixel_rate_div_policy = 1,
+ 	.allow_sw_cursor_fallback = false,
++	.alloc_extra_way_for_cursor = true,
+ };
+ 
+ static const struct dc_debug_options debug_defaults_diags = {
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+index b9d3a4000c3d4..2f996fdaa70dd 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+@@ -157,7 +157,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = {
+ 	.dispclk_dppclk_vco_speed_mhz = 4300.0,
+ 	.do_urgent_latency_adjustment = true,
+ 	.urgent_latency_adjustment_fabric_clock_component_us = 1.0,
+-	.urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
++	.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
+ };
+ 
+ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
+@@ -211,7 +211,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
+ 	/* 'DalDummyClockChangeLatencyNs' registry key option set to 0x7FFFFFFF can be used to disable Set C for dummy p-state */
+ 	if (clk_mgr->base.ctx->dc->bb_overrides.dummy_clock_change_latency_ns != 0x7FFFFFFF) {
+ 		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].valid = true;
+-		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 38;
++		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 50;
+ 		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.fclk_change_latency_us = fclk_change_latency_us;
+ 		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us;
+ 		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us;
+@@ -221,7 +221,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr)
+ 		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz;
+ 		clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF;
+ 		clk_mgr->base.bw_params->dummy_pstate_table[0].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[0].memclk_mhz * 16;
+-		clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 38;
++		clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 50;
+ 		clk_mgr->base.bw_params->dummy_pstate_table[1].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[1].memclk_mhz * 16;
+ 		clk_mgr->base.bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9;
+ 		clk_mgr->base.bw_params->dummy_pstate_table[2].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[2].memclk_mhz * 16;
+@@ -1700,6 +1700,12 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
+ 			 */
+ 			context->bw_ctx.dml.soc.dram_clock_change_latency_us =
+ 					dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
++			/* For DCN32/321 need to validate with fclk pstate change latency equal to dummy so
++			 * prefetch is scheduled correctly to account for dummy pstate.
++			 */
++			if (dummy_latency_index == 0)
++				context->bw_ctx.dml.soc.fclk_change_latency_us =
++						dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
+ 			dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false);
+ 			maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
+ 			dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb];
+@@ -1879,6 +1885,10 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
+ 
+ 	context->perf_params.stutter_period_us = context->bw_ctx.dml.vba.StutterPeriod;
+ 
++	if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && dummy_latency_index == 0)
++		context->bw_ctx.dml.soc.fclk_change_latency_us =
++				dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us;
++
+ 	dcn32_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
+ 
+ 	if (!pstate_en)
+@@ -1886,8 +1896,12 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
+ 		context->bw_ctx.dml.soc.dram_clock_change_latency_us =
+ 				dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us;
+ 
+-	if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching)
++	if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
+ 		dcn30_setup_mclk_switch_using_fw_based_vblank_stretch(dc, context);
++		if (dummy_latency_index == 0)
++			context->bw_ctx.dml.soc.fclk_change_latency_us =
++					dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.fclk_change_latency_us;
++	}
+ }
+ 
+ static void dcn32_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts,
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+index bea380407151a..042f9a62c4c50 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+@@ -3197,6 +3197,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
+ 							mode_lib->vba.FCLKChangeLatency, mode_lib->vba.UrgLatency[i],
+ 							mode_lib->vba.SREnterPlusExitTime);
+ 
++					memset(&v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull, 0, sizeof(DmlPipe));
+ 					v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.Dppclk = mode_lib->vba.RequiredDPPCLK[i][j][k];
+ 					v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.Dispclk = mode_lib->vba.RequiredDISPCLK[i][j];
+ 					v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.PixelClock = mode_lib->vba.PixelClock[k];
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+index 67af8f4df8b8f..d9141ef2fefdd 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+@@ -4396,7 +4396,7 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport(
+ 
+ 		if (v->NumberOfActiveSurfaces > 1) {
+ 			ActiveClockChangeLatencyHidingY = ActiveClockChangeLatencyHidingY
+-					- (1 - 1 / v->NumberOfActiveSurfaces) * SwathHeightY[k] * v->HTotal[k]
++					- (1.0 - 1.0 / v->NumberOfActiveSurfaces) * SwathHeightY[k] * v->HTotal[k]
+ 							/ v->PixelClock[k] / v->VRatio[k];
+ 		}
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
+index 0b427d89b3c5d..f174f5c5ff921 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h
+@@ -30,7 +30,7 @@
+ #include "os_types.h"
+ #include "../dc_features.h"
+ #include "../display_mode_structs.h"
+-#include "dml/display_mode_vba.h"
++#include "../display_mode_vba.h"
+ 
+ unsigned int dml32_dscceComputeDelay(
+ 		unsigned int bpc,
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+index aa976fe4d426d..0ab8e48b68416 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+@@ -125,9 +125,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
+ 	.sr_enter_plus_exit_z8_time_us = 320,
+ 	.writeback_latency_us = 12.0,
+ 	.round_trip_ping_latency_dcfclk_cycles = 263,
+-	.urgent_latency_pixel_data_only_us = 9.35,
+-	.urgent_latency_pixel_mixed_with_vm_data_us = 9.35,
+-	.urgent_latency_vm_data_only_us = 9.35,
++	.urgent_latency_pixel_data_only_us = 4,
++	.urgent_latency_pixel_mixed_with_vm_data_us = 4,
++	.urgent_latency_vm_data_only_us = 4,
+ 	.fclk_change_latency_us = 20,
+ 	.usr_retraining_latency_us = 2,
+ 	.smn_latency_us = 2,
+@@ -155,7 +155,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
+ 	.dispclk_dppclk_vco_speed_mhz = 4300.0,
+ 	.do_urgent_latency_adjustment = true,
+ 	.urgent_latency_adjustment_fabric_clock_component_us = 1.0,
+-	.urgent_latency_adjustment_fabric_clock_reference_mhz = 1000,
++	.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
+ };
+ 
+ static void get_optimal_ntuple(struct _vcs_dpi_voltage_scaling_st *entry)
+diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c
+index d635b73af46fe..0ea52ba5ac827 100644
+--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c
++++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_factory_dcn32.c
+@@ -107,6 +107,13 @@ static const struct ddc_registers ddc_data_regs_dcn[] = {
+ 	ddc_data_regs_dcn2(3),
+ 	ddc_data_regs_dcn2(4),
+ 	ddc_data_regs_dcn2(5),
++	{
++		// add a dummy entry for cases no such port
++		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
++		.ddc_setup = 0,
++		.phy_aux_cntl = 0,
++		.dc_gpio_aux_ctrl_5 = 0
++	},
+ 	{
+ 			DDC_GPIO_VGA_REG_LIST(DATA),
+ 			.ddc_setup = 0,
+@@ -121,6 +128,13 @@ static const struct ddc_registers ddc_clk_regs_dcn[] = {
+ 	ddc_clk_regs_dcn2(3),
+ 	ddc_clk_regs_dcn2(4),
+ 	ddc_clk_regs_dcn2(5),
++	{
++		// add a dummy entry for cases no such port
++		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
++		.ddc_setup = 0,
++		.phy_aux_cntl = 0,
++		.dc_gpio_aux_ctrl_5 = 0
++	},
+ 	{
+ 			DDC_GPIO_VGA_REG_LIST(CLK),
+ 			.ddc_setup = 0,
+diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
+index 6fd38cdd68c0c..525bc8881950d 100644
+--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
++++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
+@@ -94,11 +94,14 @@ static enum gpio_result set_config(
+ 		 * is required for detection of AUX mode */
+ 		if (hw_gpio->base.en != GPIO_DDC_LINE_VIP_PAD) {
+ 			if (!ddc_data_pd_en || !ddc_clk_pd_en) {
+-
+-				REG_SET_2(gpio.MASK_reg, regval,
++				if (hw_gpio->base.en == GPIO_DDC_LINE_DDC_VGA) {
++					// bit 4 of mask has different usage in some cases
++					REG_SET(gpio.MASK_reg, regval, DC_GPIO_DDC1DATA_PD_EN, 1);
++				} else {
++					REG_SET_2(gpio.MASK_reg, regval,
+ 						DC_GPIO_DDC1DATA_PD_EN, 1,
+ 						DC_GPIO_DDC1CLK_PD_EN, 1);
+-
++				}
+ 				if (config_data->type ==
+ 						GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE)
+ 					msleep(3);
+diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
+index dad3e3741a4e8..190af79f3236f 100644
+--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_thermal.c
+@@ -67,22 +67,21 @@ int vega10_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
+ int vega10_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr,
+ 		uint32_t *speed)
+ {
+-	uint32_t current_rpm;
+-	uint32_t percent = 0;
+-
+-	if (hwmgr->thermal_controller.fanInfo.bNoFan)
+-		return 0;
++	struct amdgpu_device *adev = hwmgr->adev;
++	uint32_t duty100, duty;
++	uint64_t tmp64;
+ 
+-	if (vega10_get_current_rpm(hwmgr, &current_rpm))
+-		return -1;
++	duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
++				CG_FDO_CTRL1, FMAX_DUTY100);
++	duty = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_THERMAL_STATUS),
++				CG_THERMAL_STATUS, FDO_PWM_DUTY);
+ 
+-	if (hwmgr->thermal_controller.
+-			advanceFanControlParameters.usMaxFanRPM != 0)
+-		percent = current_rpm * 255 /
+-			hwmgr->thermal_controller.
+-			advanceFanControlParameters.usMaxFanRPM;
++	if (!duty100)
++		return -EINVAL;
+ 
+-	*speed = MIN(percent, 255);
++	tmp64 = (uint64_t)duty * 255;
++	do_div(tmp64, duty100);
++	*speed = MIN((uint32_t)tmp64, 255);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+index 8292839bc42a9..9ce0dcc5bb90a 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+@@ -378,6 +378,10 @@ static void sienna_cichlid_check_bxco_support(struct smu_context *smu)
+ 		    ((adev->pdev->device == 0x73BF) &&
+ 		    (adev->pdev->revision == 0xCF)) ||
+ 		    ((adev->pdev->device == 0x7422) &&
++		    (adev->pdev->revision == 0x00)) ||
++		    ((adev->pdev->device == 0x73A3) &&
++		    (adev->pdev->revision == 0x00)) ||
++		    ((adev->pdev->device == 0x73E3) &&
+ 		    (adev->pdev->revision == 0x00)))
+ 			smu_baco->platform_support = false;
+ 
+diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
+index 7a94a5288e8d7..855297e69f04c 100644
+--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
++++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
+@@ -5293,7 +5293,7 @@ int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm
+ 	mst_state = drm_atomic_get_mst_topology_state(state, mgr);
+ 
+ 	if (IS_ERR(mst_state))
+-		return -EINVAL;
++		return PTR_ERR(mst_state);
+ 
+ 	list_for_each_entry(pos, &mst_state->vcpis, next) {
+ 
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+index 8a0c0e0bb5bd2..52d8800a8ab86 100644
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+@@ -134,6 +134,12 @@ static const struct dmi_system_id orientation_data[] = {
+ 		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
+ 		},
+ 		.driver_data = (void *)&lcd800x1280_rightside_up,
++	}, {	/* Acer Switch V 10 (SW5-017) */
++		.matches = {
++		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
++		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
++		},
++		.driver_data = (void *)&lcd800x1280_rightside_up,
+ 	}, {	/* Anbernic Win600 */
+ 		.matches = {
+ 		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"),
+@@ -319,6 +325,12 @@ static const struct dmi_system_id orientation_data[] = {
+ 		 DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
+ 		},
+ 		.driver_data = (void *)&lcd1200x1920_rightside_up,
++	}, {	/* Nanote UMPC-01 */
++		.matches = {
++		 DMI_MATCH(DMI_SYS_VENDOR, "RWC CO.,LTD"),
++		 DMI_MATCH(DMI_PRODUCT_NAME, "UMPC-01"),
++		},
++		.driver_data = (void *)&lcd1200x1920_rightside_up,
+ 	}, {	/* OneGX1 Pro */
+ 		.matches = {
+ 		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"),
+diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
+index 589af257edebc..3bb113b42cfa2 100644
+--- a/drivers/gpu/drm/i915/display/intel_display_power.c
++++ b/drivers/gpu/drm/i915/display/intel_display_power.c
+@@ -2427,7 +2427,7 @@ intel_display_power_ddi_io_domain(struct drm_i915_private *i915, enum port port)
+ {
+ 	const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port);
+ 
+-	if (drm_WARN_ON(&i915->drm, !domains) || domains->ddi_io == POWER_DOMAIN_INVALID)
++	if (drm_WARN_ON(&i915->drm, !domains || domains->ddi_io == POWER_DOMAIN_INVALID))
+ 		return POWER_DOMAIN_PORT_DDI_IO_A;
+ 
+ 	return domains->ddi_io + (int)(port - domains->port_start);
+@@ -2438,7 +2438,7 @@ intel_display_power_ddi_lanes_domain(struct drm_i915_private *i915, enum port po
+ {
+ 	const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port);
+ 
+-	if (drm_WARN_ON(&i915->drm, !domains) || domains->ddi_lanes == POWER_DOMAIN_INVALID)
++	if (drm_WARN_ON(&i915->drm, !domains || domains->ddi_lanes == POWER_DOMAIN_INVALID))
+ 		return POWER_DOMAIN_PORT_DDI_LANES_A;
+ 
+ 	return domains->ddi_lanes + (int)(port - domains->port_start);
+@@ -2464,7 +2464,7 @@ intel_display_power_legacy_aux_domain(struct drm_i915_private *i915, enum aux_ch
+ {
+ 	const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch);
+ 
+-	if (drm_WARN_ON(&i915->drm, !domains) || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID)
++	if (drm_WARN_ON(&i915->drm, !domains || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID))
+ 		return POWER_DOMAIN_AUX_A;
+ 
+ 	return domains->aux_legacy_usbc + (int)(aux_ch - domains->aux_ch_start);
+@@ -2475,7 +2475,7 @@ intel_display_power_tbt_aux_domain(struct drm_i915_private *i915, enum aux_ch au
+ {
+ 	const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch);
+ 
+-	if (drm_WARN_ON(&i915->drm, !domains) || domains->aux_tbt == POWER_DOMAIN_INVALID)
++	if (drm_WARN_ON(&i915->drm, !domains || domains->aux_tbt == POWER_DOMAIN_INVALID))
+ 		return POWER_DOMAIN_AUX_TBT1;
+ 
+ 	return domains->aux_tbt + (int)(aux_ch - domains->aux_ch_start);
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+index e85cfc36359a4..f5a803060515c 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+@@ -642,6 +642,10 @@ static int i915_ttm_truncate(struct drm_i915_gem_object *obj)
+ 
+ 	WARN_ON_ONCE(obj->mm.madv == I915_MADV_WILLNEED);
+ 
++	err = ttm_bo_wait(bo, true, false);
++	if (err)
++		return err;
++
+ 	err = i915_ttm_move_notify(bo);
+ 	if (err)
+ 		return err;
+diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
+index f435e06125aab..f158f6a08e757 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gt.c
++++ b/drivers/gpu/drm/i915/gt/intel_gt.c
+@@ -961,6 +961,11 @@ static void mmio_invalidate_full(struct intel_gt *gt)
+ 		if (!i915_mmio_reg_offset(rb.reg))
+ 			continue;
+ 
++		if (GRAPHICS_VER(i915) == 12 && (engine->class == VIDEO_DECODE_CLASS ||
++		    engine->class == VIDEO_ENHANCEMENT_CLASS ||
++		    engine->class == COMPUTE_CLASS))
++			rb.bit = _MASKED_BIT_ENABLE(rb.bit);
++
+ 		intel_uncore_write_fw(uncore, rb.reg, rb.bit);
+ 		awake |= engine->mask;
+ 	}
+diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
+index de89946c4817f..f671ae5a3b7b4 100644
+--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
++++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
+@@ -765,8 +765,6 @@ static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
+ 		return -ESRCH;
+ 	}
+ 
+-	kvm_get_kvm(vgpu->vfio_device.kvm);
+-
+ 	if (__kvmgt_vgpu_exist(vgpu))
+ 		return -EEXIST;
+ 
+@@ -777,6 +775,7 @@ static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
+ 
+ 	vgpu->track_node.track_write = kvmgt_page_track_write;
+ 	vgpu->track_node.track_flush_slot = kvmgt_page_track_flush_slot;
++	kvm_get_kvm(vgpu->vfio_device.kvm);
+ 	kvm_page_track_register_notifier(vgpu->vfio_device.kvm,
+ 					 &vgpu->track_node);
+ 
+diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
+index 6748ec1e00057..a1f909dac89a7 100644
+--- a/drivers/gpu/drm/tegra/drm.c
++++ b/drivers/gpu/drm/tegra/drm.c
+@@ -1093,6 +1093,10 @@ static bool host1x_drm_wants_iommu(struct host1x_device *dev)
+ 	struct host1x *host1x = dev_get_drvdata(dev->dev.parent);
+ 	struct iommu_domain *domain;
+ 
++	/* Our IOMMU usage policy doesn't currently play well with GART */
++	if (of_machine_is_compatible("nvidia,tegra20"))
++		return false;
++
+ 	/*
+ 	 * If the Tegra DRM clients are backed by an IOMMU, push buffers are
+ 	 * likely to be allocated beyond the 32-bit boundary if sufficient
+diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
+index 0cd3f97e7e49f..f60ea24db0ec8 100644
+--- a/drivers/gpu/host1x/dev.c
++++ b/drivers/gpu/host1x/dev.c
+@@ -292,6 +292,10 @@ static void host1x_setup_virtualization_tables(struct host1x *host)
+ 
+ static bool host1x_wants_iommu(struct host1x *host1x)
+ {
++	/* Our IOMMU usage policy doesn't currently play well with GART */
++	if (of_machine_is_compatible("nvidia,tegra20"))
++		return false;
++
+ 	/*
+ 	 * If we support addressing a maximum of 32 bits of physical memory
+ 	 * and if the host1x firewall is enabled, there's no need to enable
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index 5b120402d4057..cc23b90cae02f 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -533,13 +533,17 @@ static void vmbus_add_channel_work(struct work_struct *work)
+ 	 * Add the new device to the bus. This will kick off device-driver
+ 	 * binding which eventually invokes the device driver's AddDevice()
+ 	 * method.
++	 *
++	 * If vmbus_device_register() fails, the 'device_obj' is freed in
++	 * vmbus_device_release() as called by device_unregister() in the
++	 * error path of vmbus_device_register(). In the outside error
++	 * path, there's no need to free it.
+ 	 */
+ 	ret = vmbus_device_register(newchannel->device_obj);
+ 
+ 	if (ret != 0) {
+ 		pr_err("unable to add child device object (relid %d)\n",
+ 			newchannel->offermsg.child_relid);
+-		kfree(newchannel->device_obj);
+ 		goto err_deq_chan;
+ 	}
+ 
+diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
+index 3c833ea60db65..939ccf921e71b 100644
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -2083,6 +2083,7 @@ int vmbus_device_register(struct hv_device *child_device_obj)
+ 	ret = device_register(&child_device_obj->device);
+ 	if (ret) {
+ 		pr_err("Unable to register child device\n");
++		put_device(&child_device_obj->device);
+ 		return ret;
+ 	}
+ 
+diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
+index 29c9fa99c2bd3..dea438b9eb9e3 100644
+--- a/drivers/iio/accel/bma400_core.c
++++ b/drivers/iio/accel/bma400_core.c
+@@ -673,8 +673,10 @@ static int bma400_get_steps_reg(struct bma400_data *data, int *val)
+ 
+ 	ret = regmap_bulk_read(data->regmap, BMA400_STEP_CNT0_REG,
+ 			       steps_raw, BMA400_STEP_RAW_LEN);
+-	if (ret)
++	if (ret) {
++		kfree(steps_raw);
+ 		return ret;
++	}
+ 	*val = get_unaligned_le24(steps_raw);
+ 	kfree(steps_raw);
+ 	return IIO_VAL_INT;
+diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
+index 9341e0e0eb556..998e8bcc06e1d 100644
+--- a/drivers/iio/adc/aspeed_adc.c
++++ b/drivers/iio/adc/aspeed_adc.c
+@@ -202,6 +202,8 @@ static int aspeed_adc_set_trim_data(struct iio_dev *indio_dev)
+ 				((scu_otp) &
+ 				 (data->model_data->trim_locate->field)) >>
+ 				__ffs(data->model_data->trim_locate->field);
++			if (!trimming_val)
++				trimming_val = 0x8;
+ 		}
+ 		dev_dbg(data->dev,
+ 			"trimming val = %d, offset = %08x, fields = %08x\n",
+@@ -563,12 +565,9 @@ static int aspeed_adc_probe(struct platform_device *pdev)
+ 	if (ret)
+ 		return ret;
+ 
+-	if (of_find_property(data->dev->of_node, "aspeed,trim-data-valid",
+-			     NULL)) {
+-		ret = aspeed_adc_set_trim_data(indio_dev);
+-		if (ret)
+-			return ret;
+-	}
++	ret = aspeed_adc_set_trim_data(indio_dev);
++	if (ret)
++		return ret;
+ 
+ 	if (of_find_property(data->dev->of_node, "aspeed,battery-sensing",
+ 			     NULL)) {
+diff --git a/drivers/iio/industrialio-sw-trigger.c b/drivers/iio/industrialio-sw-trigger.c
+index 994f03a715204..d86a3305d9e8d 100644
+--- a/drivers/iio/industrialio-sw-trigger.c
++++ b/drivers/iio/industrialio-sw-trigger.c
+@@ -58,8 +58,12 @@ int iio_register_sw_trigger_type(struct iio_sw_trigger_type *t)
+ 
+ 	t->group = configfs_register_default_group(iio_triggers_group, t->name,
+ 						&iio_trigger_type_group_type);
+-	if (IS_ERR(t->group))
++	if (IS_ERR(t->group)) {
++		mutex_lock(&iio_trigger_types_lock);
++		list_del(&t->list);
++		mutex_unlock(&iio_trigger_types_lock);
+ 		ret = PTR_ERR(t->group);
++	}
+ 
+ 	return ret;
+ }
+diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c
+index 09b831f9f40b6..795224a38bef8 100644
+--- a/drivers/iio/light/apds9960.c
++++ b/drivers/iio/light/apds9960.c
+@@ -54,9 +54,6 @@
+ #define APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT	2
+ 
+ #define APDS9960_REG_CONFIG_2	0x90
+-#define APDS9960_REG_CONFIG_2_GGAIN_MASK	0x60
+-#define APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT	5
+-
+ #define APDS9960_REG_ID		0x92
+ 
+ #define APDS9960_REG_STATUS	0x93
+@@ -77,6 +74,9 @@
+ #define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT	6
+ 
+ #define APDS9960_REG_GCONF_2	0xa3
++#define APDS9960_REG_GCONF_2_GGAIN_MASK			0x60
++#define APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT		5
++
+ #define APDS9960_REG_GOFFSET_U	0xa4
+ #define APDS9960_REG_GOFFSET_D	0xa5
+ #define APDS9960_REG_GPULSE	0xa6
+@@ -396,9 +396,9 @@ static int apds9960_set_pxs_gain(struct apds9960_data *data, int val)
+ 			}
+ 
+ 			ret = regmap_update_bits(data->regmap,
+-				APDS9960_REG_CONFIG_2,
+-				APDS9960_REG_CONFIG_2_GGAIN_MASK,
+-				idx << APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT);
++				APDS9960_REG_GCONF_2,
++				APDS9960_REG_GCONF_2_GGAIN_MASK,
++				idx << APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT);
+ 			if (!ret)
+ 				data->pxs_gain = idx;
+ 			mutex_unlock(&data->lock);
+diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
+index 480476121c010..09489380afda7 100644
+--- a/drivers/input/misc/soc_button_array.c
++++ b/drivers/input/misc/soc_button_array.c
+@@ -18,6 +18,10 @@
+ #include <linux/gpio.h>
+ #include <linux/platform_device.h>
+ 
++static bool use_low_level_irq;
++module_param(use_low_level_irq, bool, 0444);
++MODULE_PARM_DESC(use_low_level_irq, "Use low-level triggered IRQ instead of edge triggered");
++
+ struct soc_button_info {
+ 	const char *name;
+ 	int acpi_index;
+@@ -73,6 +77,13 @@ static const struct dmi_system_id dmi_use_low_level_irq[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
+ 		},
+ 	},
++	{
++		/* Acer Switch V 10 SW5-017, same issue as Acer Switch 10 SW5-012. */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
++		},
++	},
+ 	{
+ 		/*
+ 		 * Acer One S1003. _LID method messes with power-button GPIO
+@@ -164,7 +175,8 @@ soc_button_device_create(struct platform_device *pdev,
+ 		}
+ 
+ 		/* See dmi_use_low_level_irq[] comment */
+-		if (!autorepeat && dmi_check_system(dmi_use_low_level_irq)) {
++		if (!autorepeat && (use_low_level_irq ||
++				    dmi_check_system(dmi_use_low_level_irq))) {
+ 			irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
+ 			gpio_keys[n_buttons].irq = irq;
+ 			gpio_keys[n_buttons].gpio = -ENOENT;
+diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
+index ffad142801b39..973a4c1d5d09f 100644
+--- a/drivers/input/mouse/synaptics.c
++++ b/drivers/input/mouse/synaptics.c
+@@ -191,6 +191,7 @@ static const char * const smbus_pnp_ids[] = {
+ 	"SYN3221", /* HP 15-ay000 */
+ 	"SYN323d", /* HP Spectre X360 13-w013dx */
+ 	"SYN3257", /* HP Envy 13-ad105ng */
++	"SYN3286", /* HP Laptop 15-da3001TU */
+ 	NULL
+ };
+ 
+diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
+index 4fbec7bbeccaa..5043dc7b8fb3a 100644
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -114,18 +114,18 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
+ 		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER)
+ 	},
+ 	{
+-		/* ASUS ZenBook UX425UA */
++		/* ASUS ZenBook UX425UA/QA */
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425"),
+ 		},
+ 		.driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
+ 	},
+ 	{
+-		/* ASUS ZenBook UM325UA */
++		/* ASUS ZenBook UM325UA/QA */
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+-			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325"),
+ 		},
+ 		.driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
+ 	},
+diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c
+index 21c0dddbe41d4..25e6ba132bbc2 100644
+--- a/drivers/input/touchscreen/goodix.c
++++ b/drivers/input/touchscreen/goodix.c
+@@ -1158,6 +1158,7 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
+ 	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
+ 	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+ 
++retry_read_config:
+ 	/* Read configuration and apply touchscreen parameters */
+ 	goodix_read_config(ts);
+ 
+@@ -1165,6 +1166,16 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
+ 	touchscreen_parse_properties(ts->input_dev, true, &ts->prop);
+ 
+ 	if (!ts->prop.max_x || !ts->prop.max_y || !ts->max_touch_num) {
++		if (!ts->reset_controller_at_probe &&
++		    ts->irq_pin_access_method != IRQ_PIN_ACCESS_NONE) {
++			dev_info(&ts->client->dev, "Config not set, resetting controller\n");
++			/* Retry after a controller reset */
++			ts->reset_controller_at_probe = true;
++			error = goodix_reset(ts);
++			if (error)
++				return error;
++			goto retry_read_config;
++		}
+ 		dev_err(&ts->client->dev,
+ 			"Invalid config (%d, %d, %d), using defaults\n",
+ 			ts->prop.max_x, ts->prop.max_y, ts->max_touch_num);
+diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
+index aaf2472df6e58..e97e9f97456d4 100644
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -263,6 +263,7 @@ struct dm_integrity_c {
+ 
+ 	struct completion crypto_backoff;
+ 
++	bool wrote_to_journal;
+ 	bool journal_uptodate;
+ 	bool just_formatted;
+ 	bool recalculate_flag;
+@@ -2375,6 +2376,8 @@ static void integrity_commit(struct work_struct *w)
+ 	if (!commit_sections)
+ 		goto release_flush_bios;
+ 
++	ic->wrote_to_journal = true;
++
+ 	i = commit_start;
+ 	for (n = 0; n < commit_sections; n++) {
+ 		for (j = 0; j < ic->journal_section_entries; j++) {
+@@ -2591,10 +2594,6 @@ static void integrity_writer(struct work_struct *w)
+ 
+ 	unsigned prev_free_sectors;
+ 
+-	/* the following test is not needed, but it tests the replay code */
+-	if (unlikely(dm_post_suspending(ic->ti)) && !ic->meta_dev)
+-		return;
+-
+ 	spin_lock_irq(&ic->endio_wait.lock);
+ 	write_start = ic->committed_section;
+ 	write_sections = ic->n_committed_sections;
+@@ -3101,10 +3100,17 @@ static void dm_integrity_postsuspend(struct dm_target *ti)
+ 	drain_workqueue(ic->commit_wq);
+ 
+ 	if (ic->mode == 'J') {
+-		if (ic->meta_dev)
+-			queue_work(ic->writer_wq, &ic->writer_work);
++		queue_work(ic->writer_wq, &ic->writer_work);
+ 		drain_workqueue(ic->writer_wq);
+ 		dm_integrity_flush_buffers(ic, true);
++		if (ic->wrote_to_journal) {
++			init_journal(ic, ic->free_section,
++				     ic->journal_sections - ic->free_section, ic->commit_seq);
++			if (ic->free_section) {
++				init_journal(ic, 0, ic->free_section,
++					     next_commit_seq(ic->commit_seq));
++			}
++		}
+ 	}
+ 
+ 	if (ic->mode == 'B') {
+@@ -3132,6 +3138,8 @@ static void dm_integrity_resume(struct dm_target *ti)
+ 
+ 	DEBUG_print("resume\n");
+ 
++	ic->wrote_to_journal = false;
++
+ 	if (ic->provided_data_sectors != old_provided_data_sectors) {
+ 		if (ic->provided_data_sectors > old_provided_data_sectors &&
+ 		    ic->mode == 'B' &&
+@@ -3370,6 +3378,7 @@ static void dm_integrity_io_hints(struct dm_target *ti, struct queue_limits *lim
+ 		limits->logical_block_size = ic->sectors_per_block << SECTOR_SHIFT;
+ 		limits->physical_block_size = ic->sectors_per_block << SECTOR_SHIFT;
+ 		blk_limits_io_min(limits, ic->sectors_per_block << SECTOR_SHIFT);
++		limits->dma_alignment = limits->logical_block_size - 1;
+ 	}
+ }
+ 
+diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c
+index 20fd688f72e7c..178e13a5b059f 100644
+--- a/drivers/md/dm-log-writes.c
++++ b/drivers/md/dm-log-writes.c
+@@ -875,6 +875,7 @@ static void log_writes_io_hints(struct dm_target *ti, struct queue_limits *limit
+ 	limits->logical_block_size = bdev_logical_block_size(lc->dev->bdev);
+ 	limits->physical_block_size = bdev_physical_block_size(lc->dev->bdev);
+ 	limits->io_min = limits->physical_block_size;
++	limits->dma_alignment = limits->logical_block_size - 1;
+ }
+ 
+ #if IS_ENABLED(CONFIG_FS_DAX)
+diff --git a/drivers/net/arcnet/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c
+index 24150c933fcbe..dc3253b318daf 100644
+--- a/drivers/net/arcnet/com20020_cs.c
++++ b/drivers/net/arcnet/com20020_cs.c
+@@ -113,6 +113,7 @@ static int com20020_probe(struct pcmcia_device *p_dev)
+ 	struct com20020_dev *info;
+ 	struct net_device *dev;
+ 	struct arcnet_local *lp;
++	int ret = -ENOMEM;
+ 
+ 	dev_dbg(&p_dev->dev, "com20020_attach()\n");
+ 
+@@ -142,12 +143,18 @@ static int com20020_probe(struct pcmcia_device *p_dev)
+ 	info->dev = dev;
+ 	p_dev->priv = info;
+ 
+-	return com20020_config(p_dev);
++	ret = com20020_config(p_dev);
++	if (ret)
++		goto fail_config;
++
++	return 0;
+ 
++fail_config:
++	free_arcdev(dev);
+ fail_alloc_dev:
+ 	kfree(info);
+ fail_alloc_info:
+-	return -ENOMEM;
++	return ret;
+ } /* com20020_attach */
+ 
+ static void com20020_detach(struct pcmcia_device *link)
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 86d42306aa5ee..76dd5ff1d99d5 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -3231,16 +3231,23 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
+ 		       struct slave *slave)
+ {
+ 	struct slave *curr_active_slave, *curr_arp_slave;
+-	struct icmp6hdr *hdr = icmp6_hdr(skb);
+ 	struct in6_addr *saddr, *daddr;
++	struct {
++		struct ipv6hdr ip6;
++		struct icmp6hdr icmp6;
++	} *combined, _combined;
+ 
+ 	if (skb->pkt_type == PACKET_OTHERHOST ||
+-	    skb->pkt_type == PACKET_LOOPBACK ||
+-	    hdr->icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
++	    skb->pkt_type == PACKET_LOOPBACK)
++		goto out;
++
++	combined = skb_header_pointer(skb, 0, sizeof(_combined), &_combined);
++	if (!combined || combined->ip6.nexthdr != NEXTHDR_ICMP ||
++	    combined->icmp6.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
+ 		goto out;
+ 
+-	saddr = &ipv6_hdr(skb)->saddr;
+-	daddr = &ipv6_hdr(skb)->daddr;
++	saddr = &combined->ip6.saddr;
++	daddr = &combined->ip6.saddr;
+ 
+ 	slave_dbg(bond->dev, slave->dev, "%s: %s/%d av %d sv %d sip %pI6c tip %pI6c\n",
+ 		  __func__, slave->dev->name, bond_slave_state(slave),
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index cd4115a1b81c6..0deac073d9cfa 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -268,8 +268,6 @@ struct gs_can {
+ 
+ 	struct usb_anchor tx_submitted;
+ 	atomic_t active_tx_urbs;
+-	void *rxbuf[GS_MAX_RX_URBS];
+-	dma_addr_t rxbuf_dma[GS_MAX_RX_URBS];
+ };
+ 
+ /* usb interface struct */
+@@ -587,9 +585,6 @@ static void gs_usb_xmit_callback(struct urb *urb)
+ 
+ 	if (urb->status)
+ 		netdev_info(netdev, "usb xmit fail %u\n", txc->echo_id);
+-
+-	usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+-			  urb->transfer_buffer, urb->transfer_dma);
+ }
+ 
+ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+@@ -618,8 +613,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ 	if (!urb)
+ 		goto nomem_urb;
+ 
+-	hf = usb_alloc_coherent(dev->udev, dev->hf_size_tx, GFP_ATOMIC,
+-				&urb->transfer_dma);
++	hf = kmalloc(dev->hf_size_tx, GFP_ATOMIC);
+ 	if (!hf) {
+ 		netdev_err(netdev, "No memory left for USB buffer\n");
+ 		goto nomem_hf;
+@@ -663,7 +657,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ 			  hf, dev->hf_size_tx,
+ 			  gs_usb_xmit_callback, txc);
+ 
+-	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++	urb->transfer_flags |= URB_FREE_BUFFER;
+ 	usb_anchor_urb(urb, &dev->tx_submitted);
+ 
+ 	can_put_echo_skb(skb, netdev, idx, 0);
+@@ -678,8 +672,6 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ 		gs_free_tx_context(txc);
+ 
+ 		usb_unanchor_urb(urb);
+-		usb_free_coherent(dev->udev, urb->transfer_buffer_length,
+-				  urb->transfer_buffer, urb->transfer_dma);
+ 
+ 		if (rc == -ENODEV) {
+ 			netif_device_detach(netdev);
+@@ -699,8 +691,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ 	return NETDEV_TX_OK;
+ 
+  badidx:
+-	usb_free_coherent(dev->udev, urb->transfer_buffer_length,
+-			  urb->transfer_buffer, urb->transfer_dma);
++	kfree(hf);
+  nomem_hf:
+ 	usb_free_urb(urb);
+ 
+@@ -744,7 +735,6 @@ static int gs_can_open(struct net_device *netdev)
+ 		for (i = 0; i < GS_MAX_RX_URBS; i++) {
+ 			struct urb *urb;
+ 			u8 *buf;
+-			dma_addr_t buf_dma;
+ 
+ 			/* alloc rx urb */
+ 			urb = usb_alloc_urb(0, GFP_KERNEL);
+@@ -752,10 +742,8 @@ static int gs_can_open(struct net_device *netdev)
+ 				return -ENOMEM;
+ 
+ 			/* alloc rx buffer */
+-			buf = usb_alloc_coherent(dev->udev,
+-						 dev->parent->hf_size_rx,
+-						 GFP_KERNEL,
+-						 &buf_dma);
++			buf = kmalloc(dev->parent->hf_size_rx,
++				      GFP_KERNEL);
+ 			if (!buf) {
+ 				netdev_err(netdev,
+ 					   "No memory left for USB buffer\n");
+@@ -763,8 +751,6 @@ static int gs_can_open(struct net_device *netdev)
+ 				return -ENOMEM;
+ 			}
+ 
+-			urb->transfer_dma = buf_dma;
+-
+ 			/* fill, anchor, and submit rx urb */
+ 			usb_fill_bulk_urb(urb,
+ 					  dev->udev,
+@@ -773,7 +759,7 @@ static int gs_can_open(struct net_device *netdev)
+ 					  buf,
+ 					  dev->parent->hf_size_rx,
+ 					  gs_usb_receive_bulk_callback, parent);
+-			urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
++			urb->transfer_flags |= URB_FREE_BUFFER;
+ 
+ 			usb_anchor_urb(urb, &parent->rx_submitted);
+ 
+@@ -786,17 +772,10 @@ static int gs_can_open(struct net_device *netdev)
+ 					   "usb_submit failed (err=%d)\n", rc);
+ 
+ 				usb_unanchor_urb(urb);
+-				usb_free_coherent(dev->udev,
+-						  sizeof(struct gs_host_frame),
+-						  buf,
+-						  buf_dma);
+ 				usb_free_urb(urb);
+ 				break;
+ 			}
+ 
+-			dev->rxbuf[i] = buf;
+-			dev->rxbuf_dma[i] = buf_dma;
+-
+ 			/* Drop reference,
+ 			 * USB core will take care of freeing it
+ 			 */
+@@ -854,7 +833,6 @@ static int gs_can_close(struct net_device *netdev)
+ 	int rc;
+ 	struct gs_can *dev = netdev_priv(netdev);
+ 	struct gs_usb *parent = dev->parent;
+-	unsigned int i;
+ 
+ 	netif_stop_queue(netdev);
+ 
+@@ -862,11 +840,6 @@ static int gs_can_close(struct net_device *netdev)
+ 	parent->active_channels--;
+ 	if (!parent->active_channels) {
+ 		usb_kill_anchored_urbs(&parent->rx_submitted);
+-		for (i = 0; i < GS_MAX_RX_URBS; i++)
+-			usb_free_coherent(dev->udev,
+-					  sizeof(struct gs_host_frame),
+-					  dev->rxbuf[i],
+-					  dev->rxbuf_dma[i]);
+ 	}
+ 
+ 	/* Stop sending URBs */
+diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c
+index 215dd17ca7906..4059fcc8c8326 100644
+--- a/drivers/net/dsa/sja1105/sja1105_mdio.c
++++ b/drivers/net/dsa/sja1105/sja1105_mdio.c
+@@ -256,6 +256,9 @@ static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg)
+ 	u32 tmp;
+ 	int rc;
+ 
++	if (reg & MII_ADDR_C45)
++		return -EOPNOTSUPP;
++
+ 	rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg,
+ 			      &tmp, NULL);
+ 	if (rc < 0)
+@@ -272,6 +275,9 @@ static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg,
+ 	const struct sja1105_regs *regs = priv->info->regs;
+ 	u32 tmp = val;
+ 
++	if (reg & MII_ADDR_C45)
++		return -EOPNOTSUPP;
++
+ 	return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg,
+ 				&tmp, NULL);
+ }
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+index 11d15cd036005..77d4cb4ad7823 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+@@ -795,16 +795,20 @@ static void bnx2x_vf_enable_traffic(struct bnx2x *bp, struct bnx2x_virtf *vf)
+ 
+ static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid)
+ {
+-	struct pci_dev *dev;
+ 	struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid);
++	struct pci_dev *dev;
++	bool pending;
+ 
+ 	if (!vf)
+ 		return false;
+ 
+ 	dev = pci_get_domain_bus_and_slot(vf->domain, vf->bus, vf->devfn);
+-	if (dev)
+-		return bnx2x_is_pcie_pending(dev);
+-	return false;
++	if (!dev)
++		return false;
++	pending = bnx2x_is_pcie_pending(dev);
++	pci_dev_put(dev);
++
++	return pending;
+ }
+ 
+ int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid)
+diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
+index bf6a721430400..1e5dc0ea0e311 100644
+--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
++++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
+@@ -1799,7 +1799,7 @@ static int liquidio_open(struct net_device *netdev)
+ 
+ 	ifstate_set(lio, LIO_IFSTATE_RUNNING);
+ 
+-	if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on)) {
++	if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on) {
+ 		ret = setup_tx_poll_fn(netdev);
+ 		if (ret)
+ 			goto err_poll;
+@@ -1829,7 +1829,7 @@ static int liquidio_open(struct net_device *netdev)
+ 	return 0;
+ 
+ err_rx_ctrl:
+-	if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on))
++	if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on)
+ 		cleanup_tx_poll_fn(netdev);
+ err_poll:
+ 	if (lio->ptp_clock) {
+diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+index 2f6484dc186ab..7eb2ddbe9bad6 100644
+--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
++++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+@@ -1436,8 +1436,10 @@ static acpi_status bgx_acpi_match_id(acpi_handle handle, u32 lvl,
+ 		return AE_OK;
+ 	}
+ 
+-	if (strncmp(string.pointer, bgx_sel, 4))
++	if (strncmp(string.pointer, bgx_sel, 4)) {
++		kfree(string.pointer);
+ 		return AE_OK;
++	}
+ 
+ 	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+ 			    bgx_acpi_register_phy, NULL, bgx, NULL);
+diff --git a/drivers/net/ethernet/davicom/dm9051.c b/drivers/net/ethernet/davicom/dm9051.c
+index a523ddda76093..de7105a847479 100644
+--- a/drivers/net/ethernet/davicom/dm9051.c
++++ b/drivers/net/ethernet/davicom/dm9051.c
+@@ -798,8 +798,10 @@ static int dm9051_loop_rx(struct board_info *db)
+ 		}
+ 
+ 		ret = dm9051_stop_mrcmd(db);
+-		if (ret)
++		if (ret) {
++			dev_kfree_skb(skb);
+ 			return ret;
++		}
+ 
+ 		skb->protocol = eth_type_trans(skb, db->ndev);
+ 		if (db->ndev->features & NETIF_F_RXCSUM)
+diff --git a/drivers/net/ethernet/engleder/tsnep_main.c b/drivers/net/ethernet/engleder/tsnep_main.c
+index a5f7152a17160..6a2617cc54908 100644
+--- a/drivers/net/ethernet/engleder/tsnep_main.c
++++ b/drivers/net/ethernet/engleder/tsnep_main.c
+@@ -504,6 +504,27 @@ static bool tsnep_tx_poll(struct tsnep_tx *tx, int napi_budget)
+ 	return (budget != 0);
+ }
+ 
++static bool tsnep_tx_pending(struct tsnep_tx *tx)
++{
++	unsigned long flags;
++	struct tsnep_tx_entry *entry;
++	bool pending = false;
++
++	spin_lock_irqsave(&tx->lock, flags);
++
++	if (tx->read != tx->write) {
++		entry = &tx->entry[tx->read];
++		if ((__le32_to_cpu(entry->desc_wb->properties) &
++		     TSNEP_TX_DESC_OWNER_MASK) ==
++		    (entry->properties & TSNEP_TX_DESC_OWNER_MASK))
++			pending = true;
++	}
++
++	spin_unlock_irqrestore(&tx->lock, flags);
++
++	return pending;
++}
++
+ static int tsnep_tx_open(struct tsnep_adapter *adapter, void __iomem *addr,
+ 			 struct tsnep_tx *tx)
+ {
+@@ -751,6 +772,19 @@ static int tsnep_rx_poll(struct tsnep_rx *rx, struct napi_struct *napi,
+ 	return done;
+ }
+ 
++static bool tsnep_rx_pending(struct tsnep_rx *rx)
++{
++	struct tsnep_rx_entry *entry;
++
++	entry = &rx->entry[rx->read];
++	if ((__le32_to_cpu(entry->desc_wb->properties) &
++	     TSNEP_DESC_OWNER_COUNTER_MASK) ==
++	    (entry->properties & TSNEP_DESC_OWNER_COUNTER_MASK))
++		return true;
++
++	return false;
++}
++
+ static int tsnep_rx_open(struct tsnep_adapter *adapter, void __iomem *addr,
+ 			 struct tsnep_rx *rx)
+ {
+@@ -795,6 +829,17 @@ static void tsnep_rx_close(struct tsnep_rx *rx)
+ 	tsnep_rx_ring_cleanup(rx);
+ }
+ 
++static bool tsnep_pending(struct tsnep_queue *queue)
++{
++	if (queue->tx && tsnep_tx_pending(queue->tx))
++		return true;
++
++	if (queue->rx && tsnep_rx_pending(queue->rx))
++		return true;
++
++	return false;
++}
++
+ static int tsnep_poll(struct napi_struct *napi, int budget)
+ {
+ 	struct tsnep_queue *queue = container_of(napi, struct tsnep_queue,
+@@ -815,9 +860,19 @@ static int tsnep_poll(struct napi_struct *napi, int budget)
+ 	if (!complete)
+ 		return budget;
+ 
+-	if (likely(napi_complete_done(napi, done)))
++	if (likely(napi_complete_done(napi, done))) {
+ 		tsnep_enable_irq(queue->adapter, queue->irq_mask);
+ 
++		/* reschedule if work is already pending, prevent rotten packets
++		 * which are transmitted or received after polling but before
++		 * interrupt enable
++		 */
++		if (tsnep_pending(queue)) {
++			tsnep_disable_irq(queue->adapter, queue->irq_mask);
++			napi_schedule(napi);
++		}
++	}
++
+ 	return min(done, budget - 1);
+ }
+ 
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index d0fd3045ce111..1d8ec1b120a13 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -2058,7 +2058,7 @@ static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+ 	/* enable Tx ints by setting pkt thr to 1 */
+ 	enetc_txbdr_wr(hw, idx, ENETC_TBICR0, ENETC_TBICR0_ICEN | 0x1);
+ 
+-	tbmr = ENETC_TBMR_EN;
++	tbmr = ENETC_TBMR_EN | ENETC_TBMR_SET_PRIO(tx_ring->prio);
+ 	if (tx_ring->ndev->features & NETIF_F_HW_VLAN_CTAG_TX)
+ 		tbmr |= ENETC_TBMR_VIH;
+ 
+@@ -2121,13 +2121,14 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
+ 
+ static void enetc_setup_bdrs(struct enetc_ndev_priv *priv)
+ {
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int i;
+ 
+ 	for (i = 0; i < priv->num_tx_rings; i++)
+-		enetc_setup_txbdr(&priv->si->hw, priv->tx_ring[i]);
++		enetc_setup_txbdr(hw, priv->tx_ring[i]);
+ 
+ 	for (i = 0; i < priv->num_rx_rings; i++)
+-		enetc_setup_rxbdr(&priv->si->hw, priv->rx_ring[i]);
++		enetc_setup_rxbdr(hw, priv->rx_ring[i]);
+ }
+ 
+ static void enetc_clear_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
+@@ -2160,13 +2161,14 @@ static void enetc_clear_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
+ 
+ static void enetc_clear_bdrs(struct enetc_ndev_priv *priv)
+ {
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int i;
+ 
+ 	for (i = 0; i < priv->num_tx_rings; i++)
+-		enetc_clear_txbdr(&priv->si->hw, priv->tx_ring[i]);
++		enetc_clear_txbdr(hw, priv->tx_ring[i]);
+ 
+ 	for (i = 0; i < priv->num_rx_rings; i++)
+-		enetc_clear_rxbdr(&priv->si->hw, priv->rx_ring[i]);
++		enetc_clear_rxbdr(hw, priv->rx_ring[i]);
+ 
+ 	udelay(1);
+ }
+@@ -2174,13 +2176,13 @@ static void enetc_clear_bdrs(struct enetc_ndev_priv *priv)
+ static int enetc_setup_irqs(struct enetc_ndev_priv *priv)
+ {
+ 	struct pci_dev *pdev = priv->si->pdev;
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int i, j, err;
+ 
+ 	for (i = 0; i < priv->bdr_int_num; i++) {
+ 		int irq = pci_irq_vector(pdev, ENETC_BDR_INT_BASE_IDX + i);
+ 		struct enetc_int_vector *v = priv->int_vector[i];
+ 		int entry = ENETC_BDR_INT_BASE_IDX + i;
+-		struct enetc_hw *hw = &priv->si->hw;
+ 
+ 		snprintf(v->name, sizeof(v->name), "%s-rxtx%d",
+ 			 priv->ndev->name, i);
+@@ -2268,13 +2270,14 @@ static void enetc_setup_interrupts(struct enetc_ndev_priv *priv)
+ 
+ static void enetc_clear_interrupts(struct enetc_ndev_priv *priv)
+ {
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int i;
+ 
+ 	for (i = 0; i < priv->num_tx_rings; i++)
+-		enetc_txbdr_wr(&priv->si->hw, i, ENETC_TBIER, 0);
++		enetc_txbdr_wr(hw, i, ENETC_TBIER, 0);
+ 
+ 	for (i = 0; i < priv->num_rx_rings; i++)
+-		enetc_rxbdr_wr(&priv->si->hw, i, ENETC_RBIER, 0);
++		enetc_rxbdr_wr(hw, i, ENETC_RBIER, 0);
+ }
+ 
+ static int enetc_phylink_connect(struct net_device *ndev)
+@@ -2441,6 +2444,7 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+ {
+ 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ 	struct tc_mqprio_qopt *mqprio = type_data;
++	struct enetc_hw *hw = &priv->si->hw;
+ 	struct enetc_bdr *tx_ring;
+ 	int num_stack_tx_queues;
+ 	u8 num_tc;
+@@ -2457,7 +2461,8 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+ 		/* Reset all ring priorities to 0 */
+ 		for (i = 0; i < priv->num_tx_rings; i++) {
+ 			tx_ring = priv->tx_ring[i];
+-			enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, 0);
++			tx_ring->prio = 0;
++			enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
+ 		}
+ 
+ 		return 0;
+@@ -2476,7 +2481,8 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
+ 	 */
+ 	for (i = 0; i < num_tc; i++) {
+ 		tx_ring = priv->tx_ring[i];
+-		enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, i);
++		tx_ring->prio = i;
++		enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
+ 	}
+ 
+ 	/* Reset the number of netdev queues based on the TC count */
+@@ -2589,19 +2595,21 @@ static int enetc_set_rss(struct net_device *ndev, int en)
+ static void enetc_enable_rxvlan(struct net_device *ndev, bool en)
+ {
+ 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int i;
+ 
+ 	for (i = 0; i < priv->num_rx_rings; i++)
+-		enetc_bdr_enable_rxvlan(&priv->si->hw, i, en);
++		enetc_bdr_enable_rxvlan(hw, i, en);
+ }
+ 
+ static void enetc_enable_txvlan(struct net_device *ndev, bool en)
+ {
+ 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int i;
+ 
+ 	for (i = 0; i < priv->num_tx_rings; i++)
+-		enetc_bdr_enable_txvlan(&priv->si->hw, i, en);
++		enetc_bdr_enable_txvlan(hw, i, en);
+ }
+ 
+ void enetc_set_features(struct net_device *ndev, netdev_features_t features)
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.h b/drivers/net/ethernet/freescale/enetc/enetc.h
+index 2cfe6944ebd32..bb1b3b0e40e4d 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.h
++++ b/drivers/net/ethernet/freescale/enetc/enetc.h
+@@ -95,6 +95,7 @@ struct enetc_bdr {
+ 		void __iomem *rcir;
+ 	};
+ 	u16 index;
++	u16 prio;
+ 	int bd_count; /* # of BDs */
+ 	int next_to_use;
+ 	int next_to_clean;
+@@ -467,19 +468,20 @@ int enetc_set_psfp(struct net_device *ndev, bool en);
+ 
+ static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv)
+ {
++	struct enetc_hw *hw = &priv->si->hw;
+ 	u32 reg;
+ 
+-	reg = enetc_port_rd(&priv->si->hw, ENETC_PSIDCAPR);
++	reg = enetc_port_rd(hw, ENETC_PSIDCAPR);
+ 	priv->psfp_cap.max_streamid = reg & ENETC_PSIDCAPR_MSK;
+ 	/* Port stream filter capability */
+-	reg = enetc_port_rd(&priv->si->hw, ENETC_PSFCAPR);
++	reg = enetc_port_rd(hw, ENETC_PSFCAPR);
+ 	priv->psfp_cap.max_psfp_filter = reg & ENETC_PSFCAPR_MSK;
+ 	/* Port stream gate capability */
+-	reg = enetc_port_rd(&priv->si->hw, ENETC_PSGCAPR);
++	reg = enetc_port_rd(hw, ENETC_PSGCAPR);
+ 	priv->psfp_cap.max_psfp_gate = (reg & ENETC_PSGCAPR_SGIT_MSK);
+ 	priv->psfp_cap.max_psfp_gatelist = (reg & ENETC_PSGCAPR_GCL_MSK) >> 16;
+ 	/* Port flow meter capability */
+-	reg = enetc_port_rd(&priv->si->hw, ENETC_PFMCAPR);
++	reg = enetc_port_rd(hw, ENETC_PFMCAPR);
+ 	priv->psfp_cap.max_psfp_meter = reg & ENETC_PFMCAPR_MSK;
+ }
+ 
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+index f8a2f02ce22de..5fcb02b006999 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c
+@@ -17,8 +17,9 @@ static u16 enetc_get_max_gcl_len(struct enetc_hw *hw)
+ 
+ void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed)
+ {
++	struct enetc_hw *hw = &priv->si->hw;
+ 	u32 old_speed = priv->speed;
+-	u32 pspeed;
++	u32 pspeed, tmp;
+ 
+ 	if (speed == old_speed)
+ 		return;
+@@ -39,16 +40,15 @@ void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed)
+ 	}
+ 
+ 	priv->speed = speed;
+-	enetc_port_wr(&priv->si->hw, ENETC_PMR,
+-		      (enetc_port_rd(&priv->si->hw, ENETC_PMR)
+-		      & (~ENETC_PMR_PSPEED_MASK))
+-		      | pspeed);
++	tmp = enetc_port_rd(hw, ENETC_PMR);
++	enetc_port_wr(hw, ENETC_PMR, (tmp & ~ENETC_PMR_PSPEED_MASK) | pspeed);
+ }
+ 
+ static int enetc_setup_taprio(struct net_device *ndev,
+ 			      struct tc_taprio_qopt_offload *admin_conf)
+ {
+ 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
++	struct enetc_hw *hw = &priv->si->hw;
+ 	struct enetc_cbd cbd = {.cmd = 0};
+ 	struct tgs_gcl_conf *gcl_config;
+ 	struct tgs_gcl_data *gcl_data;
+@@ -61,15 +61,13 @@ static int enetc_setup_taprio(struct net_device *ndev,
+ 	int err;
+ 	int i;
+ 
+-	if (admin_conf->num_entries > enetc_get_max_gcl_len(&priv->si->hw))
++	if (admin_conf->num_entries > enetc_get_max_gcl_len(hw))
+ 		return -EINVAL;
+ 	gcl_len = admin_conf->num_entries;
+ 
+-	tge = enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET);
++	tge = enetc_rd(hw, ENETC_QBV_PTGCR_OFFSET);
+ 	if (!admin_conf->enable) {
+-		enetc_wr(&priv->si->hw,
+-			 ENETC_QBV_PTGCR_OFFSET,
+-			 tge & (~ENETC_QBV_TGE));
++		enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge & ~ENETC_QBV_TGE);
+ 
+ 		priv->active_offloads &= ~ENETC_F_QBV;
+ 
+@@ -117,14 +115,11 @@ static int enetc_setup_taprio(struct net_device *ndev,
+ 	cbd.cls = BDCR_CMD_PORT_GCL;
+ 	cbd.status_flags = 0;
+ 
+-	enetc_wr(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET,
+-		 tge | ENETC_QBV_TGE);
++	enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge | ENETC_QBV_TGE);
+ 
+ 	err = enetc_send_cmd(priv->si, &cbd);
+ 	if (err)
+-		enetc_wr(&priv->si->hw,
+-			 ENETC_QBV_PTGCR_OFFSET,
+-			 tge & (~ENETC_QBV_TGE));
++		enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge & ~ENETC_QBV_TGE);
+ 
+ 	enetc_cbd_free_data_mem(priv->si, data_size, tmp, &dma);
+ 
+@@ -138,6 +133,8 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
+ {
+ 	struct tc_taprio_qopt_offload *taprio = type_data;
+ 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
++	struct enetc_hw *hw = &priv->si->hw;
++	struct enetc_bdr *tx_ring;
+ 	int err;
+ 	int i;
+ 
+@@ -146,18 +143,20 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
+ 		if (priv->tx_ring[i]->tsd_enable)
+ 			return -EBUSY;
+ 
+-	for (i = 0; i < priv->num_tx_rings; i++)
+-		enetc_set_bdr_prio(&priv->si->hw,
+-				   priv->tx_ring[i]->index,
+-				   taprio->enable ? i : 0);
++	for (i = 0; i < priv->num_tx_rings; i++) {
++		tx_ring = priv->tx_ring[i];
++		tx_ring->prio = taprio->enable ? i : 0;
++		enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
++	}
+ 
+ 	err = enetc_setup_taprio(ndev, taprio);
+-
+-	if (err)
+-		for (i = 0; i < priv->num_tx_rings; i++)
+-			enetc_set_bdr_prio(&priv->si->hw,
+-					   priv->tx_ring[i]->index,
+-					   taprio->enable ? 0 : i);
++	if (err) {
++		for (i = 0; i < priv->num_tx_rings; i++) {
++			tx_ring = priv->tx_ring[i];
++			tx_ring->prio = taprio->enable ? 0 : i;
++			enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
++		}
++	}
+ 
+ 	return err;
+ }
+@@ -178,7 +177,7 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ 	struct tc_cbs_qopt_offload *cbs = type_data;
+ 	u32 port_transmit_rate = priv->speed;
+ 	u8 tc_nums = netdev_get_num_tc(ndev);
+-	struct enetc_si *si = priv->si;
++	struct enetc_hw *hw = &priv->si->hw;
+ 	u32 hi_credit_bit, hi_credit_reg;
+ 	u32 max_interference_size;
+ 	u32 port_frame_max_size;
+@@ -199,15 +198,15 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ 		 * lower than this TC have been disabled.
+ 		 */
+ 		if (tc == prio_top &&
+-		    enetc_get_cbs_enable(&si->hw, prio_next)) {
++		    enetc_get_cbs_enable(hw, prio_next)) {
+ 			dev_err(&ndev->dev,
+ 				"Disable TC%d before disable TC%d\n",
+ 				prio_next, tc);
+ 			return -EINVAL;
+ 		}
+ 
+-		enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), 0);
+-		enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), 0);
++		enetc_port_wr(hw, ENETC_PTCCBSR1(tc), 0);
++		enetc_port_wr(hw, ENETC_PTCCBSR0(tc), 0);
+ 
+ 		return 0;
+ 	}
+@@ -224,13 +223,13 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ 	 * higher than this TC have been enabled.
+ 	 */
+ 	if (tc == prio_next) {
+-		if (!enetc_get_cbs_enable(&si->hw, prio_top)) {
++		if (!enetc_get_cbs_enable(hw, prio_top)) {
+ 			dev_err(&ndev->dev,
+ 				"Enable TC%d first before enable TC%d\n",
+ 				prio_top, prio_next);
+ 			return -EINVAL;
+ 		}
+-		bw_sum += enetc_get_cbs_bw(&si->hw, prio_top);
++		bw_sum += enetc_get_cbs_bw(hw, prio_top);
+ 	}
+ 
+ 	if (bw_sum + bw >= 100) {
+@@ -239,7 +238,7 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ 		return -EINVAL;
+ 	}
+ 
+-	enetc_port_rd(&si->hw, ENETC_PTCMSDUR(tc));
++	enetc_port_rd(hw, ENETC_PTCMSDUR(tc));
+ 
+ 	/* For top prio TC, the max_interfrence_size is maxSizedFrame.
+ 	 *
+@@ -259,8 +258,8 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ 		u32 m0, ma, r0, ra;
+ 
+ 		m0 = port_frame_max_size * 8;
+-		ma = enetc_port_rd(&si->hw, ENETC_PTCMSDUR(prio_top)) * 8;
+-		ra = enetc_get_cbs_bw(&si->hw, prio_top) *
++		ma = enetc_port_rd(hw, ENETC_PTCMSDUR(prio_top)) * 8;
++		ra = enetc_get_cbs_bw(hw, prio_top) *
+ 			port_transmit_rate * 10000ULL;
+ 		r0 = port_transmit_rate * 1000000ULL;
+ 		max_interference_size = m0 + ma +
+@@ -280,10 +279,10 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
+ 	hi_credit_reg = (u32)div_u64((ENETC_CLK * 100ULL) * hi_credit_bit,
+ 				     port_transmit_rate * 1000000ULL);
+ 
+-	enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), hi_credit_reg);
++	enetc_port_wr(hw, ENETC_PTCCBSR1(tc), hi_credit_reg);
+ 
+ 	/* Set bw register and enable this traffic class */
+-	enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE);
++	enetc_port_wr(hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE);
+ 
+ 	return 0;
+ }
+@@ -293,6 +292,7 @@ int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
+ 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ 	struct tc_etf_qopt_offload *qopt = type_data;
+ 	u8 tc_nums = netdev_get_num_tc(ndev);
++	struct enetc_hw *hw = &priv->si->hw;
+ 	int tc;
+ 
+ 	if (!tc_nums)
+@@ -304,12 +304,11 @@ int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
+ 		return -EINVAL;
+ 
+ 	/* TSD and Qbv are mutually exclusive in hardware */
+-	if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
++	if (enetc_rd(hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
+ 		return -EBUSY;
+ 
+ 	priv->tx_ring[tc]->tsd_enable = qopt->enable;
+-	enetc_port_wr(&priv->si->hw, ENETC_PTCTSDR(tc),
+-		      qopt->enable ? ENETC_TSDE : 0);
++	enetc_port_wr(hw, ENETC_PTCTSDR(tc), qopt->enable ? ENETC_TSDE : 0);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 3f6187c164240..0d1bab4ac1b07 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -298,7 +298,6 @@ struct iavf_adapter {
+ #define IAVF_FLAG_QUEUES_DISABLED		BIT(17)
+ #define IAVF_FLAG_SETUP_NETDEV_FEATURES		BIT(18)
+ #define IAVF_FLAG_REINIT_MSIX_NEEDED		BIT(20)
+-#define IAVF_FLAG_INITIAL_MAC_SET		BIT(23)
+ /* duplicates for common code */
+ #define IAVF_FLAG_DCB_ENABLED			0
+ 	/* flags for admin queue service task */
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 79fef8c59d652..cff03723f4f9f 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -1087,12 +1087,6 @@ static int iavf_set_mac(struct net_device *netdev, void *p)
+ 	if (ret)
+ 		return ret;
+ 
+-	/* If this is an initial set MAC during VF spawn do not wait */
+-	if (adapter->flags & IAVF_FLAG_INITIAL_MAC_SET) {
+-		adapter->flags &= ~IAVF_FLAG_INITIAL_MAC_SET;
+-		return 0;
+-	}
+-
+ 	ret = wait_event_interruptible_timeout(adapter->vc_waitqueue,
+ 					       iavf_is_mac_set_handled(netdev, addr->sa_data),
+ 					       msecs_to_jiffies(2500));
+@@ -2605,8 +2599,6 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter)
+ 		ether_addr_copy(netdev->perm_addr, adapter->hw.mac.addr);
+ 	}
+ 
+-	adapter->flags |= IAVF_FLAG_INITIAL_MAC_SET;
+-
+ 	adapter->tx_desc_count = IAVF_DEFAULT_TXD;
+ 	adapter->rx_desc_count = IAVF_DEFAULT_RXD;
+ 	err = iavf_init_interrupt_scheme(adapter);
+@@ -2921,7 +2913,6 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
+ 	iavf_free_queues(adapter);
+ 	memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE);
+ 	iavf_shutdown_adminq(&adapter->hw);
+-	adapter->netdev->flags &= ~IFF_UP;
+ 	adapter->flags &= ~IAVF_FLAG_RESET_PENDING;
+ 	iavf_change_state(adapter, __IAVF_DOWN);
+ 	wake_up(&adapter->down_waitqueue);
+@@ -3021,6 +3012,11 @@ static void iavf_reset_task(struct work_struct *work)
+ 		iavf_disable_vf(adapter);
+ 		mutex_unlock(&adapter->client_lock);
+ 		mutex_unlock(&adapter->crit_lock);
++		if (netif_running(netdev)) {
++			rtnl_lock();
++			dev_close(netdev);
++			rtnl_unlock();
++		}
+ 		return; /* Do not attempt to reinit. It's dead, Jim. */
+ 	}
+ 
+@@ -3033,6 +3029,7 @@ continue_reset:
+ 
+ 	if (running) {
+ 		netif_carrier_off(netdev);
++		netif_tx_stop_all_queues(netdev);
+ 		adapter->link_up = false;
+ 		iavf_napi_disable_all(adapter);
+ 	}
+@@ -3172,6 +3169,16 @@ reset_err:
+ 
+ 	mutex_unlock(&adapter->client_lock);
+ 	mutex_unlock(&adapter->crit_lock);
++
++	if (netif_running(netdev)) {
++		/* Close device to ensure that Tx queues will not be started
++		 * during netif_device_attach() at the end of the reset task.
++		 */
++		rtnl_lock();
++		dev_close(netdev);
++		rtnl_unlock();
++	}
++
+ 	dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
+ reset_finish:
+ 	rtnl_lock();
+@@ -5035,23 +5042,21 @@ static int __maybe_unused iavf_resume(struct device *dev_d)
+ static void iavf_remove(struct pci_dev *pdev)
+ {
+ 	struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
+-	struct net_device *netdev = adapter->netdev;
+ 	struct iavf_fdir_fltr *fdir, *fdirtmp;
+ 	struct iavf_vlan_filter *vlf, *vlftmp;
++	struct iavf_cloud_filter *cf, *cftmp;
+ 	struct iavf_adv_rss *rss, *rsstmp;
+ 	struct iavf_mac_filter *f, *ftmp;
+-	struct iavf_cloud_filter *cf, *cftmp;
+-	struct iavf_hw *hw = &adapter->hw;
++	struct net_device *netdev;
++	struct iavf_hw *hw;
+ 	int err;
+ 
+-	/* When reboot/shutdown is in progress no need to do anything
+-	 * as the adapter is already REMOVE state that was set during
+-	 * iavf_shutdown() callback.
+-	 */
+-	if (adapter->state == __IAVF_REMOVE)
++	netdev = adapter->netdev;
++	hw = &adapter->hw;
++
++	if (test_and_set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))
+ 		return;
+ 
+-	set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section);
+ 	/* Wait until port initialization is complete.
+ 	 * There are flows where register/unregister netdev may race.
+ 	 */
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index eaa51cd7456b6..8f86be995092b 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -7352,6 +7352,7 @@ static int mvpp2_get_sram(struct platform_device *pdev,
+ 			  struct mvpp2 *priv)
+ {
+ 	struct resource *res;
++	void __iomem *base;
+ 
+ 	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ 	if (!res) {
+@@ -7362,9 +7363,12 @@ static int mvpp2_get_sram(struct platform_device *pdev,
+ 		return 0;
+ 	}
+ 
+-	priv->cm3_base = devm_ioremap_resource(&pdev->dev, res);
++	base = devm_ioremap_resource(&pdev->dev, res);
++	if (IS_ERR(base))
++		return PTR_ERR(base);
+ 
+-	return PTR_ERR_OR_ZERO(priv->cm3_base);
++	priv->cm3_base = base;
++	return 0;
+ }
+ 
+ static int mvpp2_probe(struct platform_device *pdev)
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+index f42a09f04b256..70cda15713245 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+@@ -535,6 +535,8 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused)
+ 		sprintf(lmac, "LMAC%d", lmac_id);
+ 		seq_printf(filp, "%s\t0x%x\t\tNIX%d\t\t%s\t%s\n",
+ 			   dev_name(&pdev->dev), pcifunc, blkid, cgx, lmac);
++
++		pci_dev_put(pdev);
+ 	}
+ 	return 0;
+ }
+@@ -2221,6 +2223,7 @@ static int cgx_print_dmac_flt(struct seq_file *s, int lmac_id)
+ 		}
+ 	}
+ 
++	pci_dev_put(pdev);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+index 0879a48411f31..3dc90060d70d7 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+@@ -4979,6 +4979,8 @@ static int nix_setup_ipolicers(struct rvu *rvu,
+ 		ipolicer->ref_count = devm_kcalloc(rvu->dev,
+ 						   ipolicer->band_prof.max,
+ 						   sizeof(u16), GFP_KERNEL);
++		if (!ipolicer->ref_count)
++			return -ENOMEM;
+ 	}
+ 
+ 	/* Set policer timeunit to 2us ie  (19 + 1) * 100 nsec = 2us */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
+index b04fb226f708a..ae50d56258ec6 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_sdp.c
+@@ -62,15 +62,18 @@ int rvu_sdp_init(struct rvu *rvu)
+ 		pfvf->sdp_info = devm_kzalloc(rvu->dev,
+ 					      sizeof(struct sdp_node_info),
+ 					      GFP_KERNEL);
+-		if (!pfvf->sdp_info)
++		if (!pfvf->sdp_info) {
++			pci_dev_put(pdev);
+ 			return -ENOMEM;
++		}
+ 
+ 		dev_info(rvu->dev, "SDP PF number:%d\n", sdp_pf_num[i]);
+ 
+-		put_device(&pdev->dev);
+ 		i++;
+ 	}
+ 
++	pci_dev_put(pdev);
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_main.c b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+index a0ad0bcbf89f4..9f588ecba93e2 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+@@ -730,6 +730,7 @@ static int prestera_port_create(struct prestera_switch *sw, u32 id)
+ 	return 0;
+ 
+ err_sfp_bind:
++	unregister_netdev(dev);
+ err_register_netdev:
+ 	prestera_port_list_del(port);
+ err_port_init:
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 84433f3a3e228..5380caf0acc2f 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -2363,8 +2363,10 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
+ 				data + NET_SKB_PAD + eth->ip_align,
+ 				ring->buf_size, DMA_FROM_DEVICE);
+ 			if (unlikely(dma_mapping_error(eth->dma_dev,
+-						       dma_addr)))
++						       dma_addr))) {
++				skb_free_frag(data);
+ 				return -ENOMEM;
++			}
+ 		}
+ 		rxd->rxd1 = (unsigned int)dma_addr;
+ 		ring->data[i] = data;
+@@ -2979,8 +2981,10 @@ static int mtk_open(struct net_device *dev)
+ 		u32 gdm_config = MTK_GDMA_TO_PDMA;
+ 
+ 		err = mtk_start_dma(eth);
+-		if (err)
++		if (err) {
++			phylink_disconnect_phy(mac->phylink);
+ 			return err;
++		}
+ 
+ 		if (eth->soc->offload_version && mtk_ppe_start(eth->ppe) == 0)
+ 			gdm_config = MTK_GDMA_TO_PPE;
+@@ -4103,12 +4107,12 @@ static int mtk_probe(struct platform_device *pdev)
+ 		eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2);
+ 		if (!eth->ppe) {
+ 			err = -ENOMEM;
+-			goto err_free_dev;
++			goto err_deinit_mdio;
+ 		}
+ 
+ 		err = mtk_eth_offload_init(eth);
+ 		if (err)
+-			goto err_free_dev;
++			goto err_deinit_mdio;
+ 	}
+ 
+ 	for (i = 0; i < MTK_MAX_DEVS; i++) {
+diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c
+index b149e601f6737..48cfaa7eaf50c 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/qp.c
++++ b/drivers/net/ethernet/mellanox/mlx4/qp.c
+@@ -697,7 +697,8 @@ static int mlx4_create_zones(struct mlx4_dev *dev,
+ 			err = mlx4_bitmap_init(*bitmap + k, 1,
+ 					       MLX4_QP_TABLE_RAW_ETH_SIZE - 1, 0,
+ 					       0);
+-			mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0);
++			if (!err)
++				mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0);
+ 		}
+ 
+ 		if (err)
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 2e0d59ca62b50..74bd05e5dda23 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -45,6 +45,8 @@
+ #include "mlx5_core.h"
+ #include "lib/eq.h"
+ #include "lib/tout.h"
++#define CREATE_TRACE_POINTS
++#include "diag/cmd_tracepoint.h"
+ 
+ enum {
+ 	CMD_IF_REV = 5,
+@@ -785,27 +787,14 @@ EXPORT_SYMBOL(mlx5_cmd_out_err);
+ static void cmd_status_print(struct mlx5_core_dev *dev, void *in, void *out)
+ {
+ 	u16 opcode, op_mod;
+-	u32 syndrome;
+-	u8  status;
+ 	u16 uid;
+-	int err;
+-
+-	syndrome = MLX5_GET(mbox_out, out, syndrome);
+-	status = MLX5_GET(mbox_out, out, status);
+ 
+ 	opcode = MLX5_GET(mbox_in, in, opcode);
+ 	op_mod = MLX5_GET(mbox_in, in, op_mod);
+ 	uid    = MLX5_GET(mbox_in, in, uid);
+ 
+-	err = cmd_status_to_err(status);
+-
+ 	if (!uid && opcode != MLX5_CMD_OP_DESTROY_MKEY)
+ 		mlx5_cmd_out_err(dev, opcode, op_mod, out);
+-	else
+-		mlx5_core_dbg(dev,
+-			"%s(0x%x) op_mod(0x%x) uid(%d) failed, status %s(0x%x), syndrome (0x%x), err(%d)\n",
+-			mlx5_command_str(opcode), opcode, op_mod, uid,
+-			cmd_status_str(status), status, syndrome, err);
+ }
+ 
+ int mlx5_cmd_check(struct mlx5_core_dev *dev, int err, void *in, void *out)
+@@ -1016,6 +1005,7 @@ static void cmd_work_handler(struct work_struct *work)
+ 		cmd_ent_get(ent);
+ 	set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state);
+ 
++	cmd_ent_get(ent); /* for the _real_ FW event on completion */
+ 	/* Skip sending command to fw if internal error */
+ 	if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, ent->op)) {
+ 		ent->ret = -ENXIO;
+@@ -1023,7 +1013,6 @@ static void cmd_work_handler(struct work_struct *work)
+ 		return;
+ 	}
+ 
+-	cmd_ent_get(ent); /* for the _real_ FW event on completion */
+ 	/* ring doorbell after the descriptor is valid */
+ 	mlx5_core_dbg(dev, "writing 0x%x to command doorbell\n", 1 << ent->idx);
+ 	wmb();
+@@ -1672,8 +1661,8 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
+ 				cmd_ent_put(ent); /* timeout work was canceled */
+ 
+ 			if (!forced || /* Real FW completion */
+-			    pci_channel_offline(dev->pdev) || /* FW is inaccessible */
+-			    dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
++			     mlx5_cmd_is_down(dev) || /* No real FW completion is expected */
++			     !opcode_allowed(cmd, ent->op))
+ 				cmd_ent_put(ent);
+ 
+ 			ent->ts2 = ktime_get_ns();
+@@ -1892,6 +1881,16 @@ out_in:
+ 	return err;
+ }
+ 
++static void mlx5_cmd_err_trace(struct mlx5_core_dev *dev, u16 opcode, u16 op_mod, void *out)
++{
++	u32 syndrome = MLX5_GET(mbox_out, out, syndrome);
++	u8 status = MLX5_GET(mbox_out, out, status);
++
++	trace_mlx5_cmd(mlx5_command_str(opcode), opcode, op_mod,
++		       cmd_status_str(status), status, syndrome,
++		       cmd_status_to_err(status));
++}
++
+ static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status,
+ 			   u32 syndrome, int err)
+ {
+@@ -1914,7 +1913,7 @@ static void cmd_status_log(struct mlx5_core_dev *dev, u16 opcode, u8 status,
+ }
+ 
+ /* preserve -EREMOTEIO for outbox.status != OK, otherwise return err as is */
+-static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, void *out)
++static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, u16 op_mod, void *out)
+ {
+ 	u32 syndrome = MLX5_GET(mbox_out, out, syndrome);
+ 	u8 status = MLX5_GET(mbox_out, out, status);
+@@ -1922,8 +1921,10 @@ static int cmd_status_err(struct mlx5_core_dev *dev, int err, u16 opcode, void *
+ 	if (err == -EREMOTEIO) /* -EREMOTEIO is preserved */
+ 		err = -EIO;
+ 
+-	if (!err && status != MLX5_CMD_STAT_OK)
++	if (!err && status != MLX5_CMD_STAT_OK) {
+ 		err = -EREMOTEIO;
++		mlx5_cmd_err_trace(dev, opcode, op_mod, out);
++	}
+ 
+ 	cmd_status_log(dev, opcode, status, syndrome, err);
+ 	return err;
+@@ -1951,9 +1952,9 @@ int mlx5_cmd_do(struct mlx5_core_dev *dev, void *in, int in_size, void *out, int
+ {
+ 	int err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, false);
+ 	u16 opcode = MLX5_GET(mbox_in, in, opcode);
++	u16 op_mod = MLX5_GET(mbox_in, in, op_mod);
+ 
+-	err = cmd_status_err(dev, err, opcode, out);
+-	return err;
++	return cmd_status_err(dev, err, opcode, op_mod, out);
+ }
+ EXPORT_SYMBOL(mlx5_cmd_do);
+ 
+@@ -1997,8 +1998,9 @@ int mlx5_cmd_exec_polling(struct mlx5_core_dev *dev, void *in, int in_size,
+ {
+ 	int err = cmd_exec(dev, in, in_size, out, out_size, NULL, NULL, true);
+ 	u16 opcode = MLX5_GET(mbox_in, in, opcode);
++	u16 op_mod = MLX5_GET(mbox_in, in, op_mod);
+ 
+-	err = cmd_status_err(dev, err, opcode, out);
++	err = cmd_status_err(dev, err, opcode, op_mod, out);
+ 	return mlx5_cmd_check(dev, err, in, out);
+ }
+ EXPORT_SYMBOL(mlx5_cmd_exec_polling);
+@@ -2034,7 +2036,7 @@ static void mlx5_cmd_exec_cb_handler(int status, void *_work)
+ 	struct mlx5_async_ctx *ctx;
+ 
+ 	ctx = work->ctx;
+-	status = cmd_status_err(ctx->dev, status, work->opcode, work->out);
++	status = cmd_status_err(ctx->dev, status, work->opcode, work->op_mod, work->out);
+ 	work->user_callback(status, work);
+ 	if (atomic_dec_and_test(&ctx->num_inflight))
+ 		complete(&ctx->inflight_done);
+@@ -2049,6 +2051,7 @@ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
+ 	work->ctx = ctx;
+ 	work->user_callback = callback;
+ 	work->opcode = MLX5_GET(mbox_in, in, opcode);
++	work->op_mod = MLX5_GET(mbox_in, in, op_mod);
+ 	work->out = out;
+ 	if (WARN_ON(!atomic_inc_not_zero(&ctx->num_inflight)))
+ 		return -EIO;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h b/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h
+new file mode 100644
+index 0000000000000..406ebe17405f9
+--- /dev/null
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/cmd_tracepoint.h
+@@ -0,0 +1,45 @@
++/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
++/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
++
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM mlx5
++
++#if !defined(_MLX5_CMD_TP_H_) || defined(TRACE_HEADER_MULTI_READ)
++#define _MLX5_CMD_TP_H_
++
++#include <linux/tracepoint.h>
++#include <linux/trace_seq.h>
++
++TRACE_EVENT(mlx5_cmd,
++	    TP_PROTO(const char *command_str, u16 opcode, u16 op_mod,
++		     const char *status_str, u8 status, u32 syndrome, int err),
++	    TP_ARGS(command_str, opcode, op_mod, status_str, status, syndrome, err),
++	    TP_STRUCT__entry(__string(command_str, command_str)
++			     __field(u16, opcode)
++			     __field(u16, op_mod)
++			    __string(status_str, status_str)
++			    __field(u8, status)
++			    __field(u32, syndrome)
++			    __field(int, err)
++			    ),
++	    TP_fast_assign(__assign_str(command_str, command_str);
++			__entry->opcode = opcode;
++			__entry->op_mod = op_mod;
++			__assign_str(status_str, status_str);
++			__entry->status = status;
++			__entry->syndrome = syndrome;
++			__entry->err = err;
++	    ),
++	    TP_printk("%s(0x%x) op_mod(0x%x) failed, status %s(0x%x), syndrome (0x%x), err(%d)",
++		      __get_str(command_str), __entry->opcode, __entry->op_mod,
++		      __get_str(status_str), __entry->status, __entry->syndrome,
++		      __entry->err)
++);
++
++#endif /* _MLX5_CMD_TP_H_ */
++
++#undef TRACE_INCLUDE_PATH
++#define TRACE_INCLUDE_PATH ./diag
++#undef TRACE_INCLUDE_FILE
++#define TRACE_INCLUDE_FILE cmd_tracepoint
++#include <trace/define_trace.h>
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+index 978a2bb8e1220..21831386b26e8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c
+@@ -638,7 +638,7 @@ static void mlx5_tracer_handle_timestamp_trace(struct mlx5_fw_tracer *tracer,
+ 			trace_timestamp = (timestamp_event.timestamp & MASK_52_7) |
+ 					  (str_frmt->timestamp & MASK_6_0);
+ 		else
+-			trace_timestamp = ((timestamp_event.timestamp & MASK_52_7) - 1) |
++			trace_timestamp = ((timestamp_event.timestamp - 1) & MASK_52_7) |
+ 					  (str_frmt->timestamp & MASK_6_0);
+ 
+ 		mlx5_tracer_print_trace(str_frmt, dev, trace_timestamp);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+index 5aff979143678..ff73d25bc6eb8 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+@@ -224,15 +224,16 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
+ 	list_for_each_entry(flow, flow_list, tmp_list) {
+ 		if (!mlx5e_is_offloaded_flow(flow) || flow_flag_test(flow, SLOW))
+ 			continue;
+-		spec = &flow->attr->parse_attr->spec;
+-
+-		/* update from encap rule to slow path rule */
+-		rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec);
+ 
+ 		attr = mlx5e_tc_get_encap_attr(flow);
+ 		esw_attr = attr->esw_attr;
+ 		/* mark the flow's encap dest as non-valid */
+ 		esw_attr->dests[flow->tmp_entry_index].flags &= ~MLX5_ESW_DEST_ENCAP_VALID;
++		esw_attr->dests[flow->tmp_entry_index].pkt_reformat = NULL;
++
++		/* update from encap rule to slow path rule */
++		spec = &flow->attr->parse_attr->spec;
++		rule = mlx5e_tc_offload_to_slow_path(esw, flow, spec);
+ 
+ 		if (IS_ERR(rule)) {
+ 			err = PTR_ERR(rule);
+@@ -251,6 +252,7 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
+ 	/* we know that the encap is valid */
+ 	e->flags &= ~MLX5_ENCAP_ENTRY_VALID;
+ 	mlx5_packet_reformat_dealloc(priv->mdev, e->pkt_reformat);
++	e->pkt_reformat = NULL;
+ }
+ 
+ static void mlx5e_take_tmp_flow(struct mlx5e_tc_flow *flow,
+@@ -762,8 +764,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
+ 		       struct net_device *mirred_dev,
+ 		       int out_index,
+ 		       struct netlink_ext_ack *extack,
+-		       struct net_device **encap_dev,
+-		       bool *encap_valid)
++		       struct net_device **encap_dev)
+ {
+ 	struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
+ 	struct mlx5e_tc_flow_parse_attr *parse_attr;
+@@ -878,9 +879,8 @@ attach_flow:
+ 	if (e->flags & MLX5_ENCAP_ENTRY_VALID) {
+ 		attr->esw_attr->dests[out_index].pkt_reformat = e->pkt_reformat;
+ 		attr->esw_attr->dests[out_index].flags |= MLX5_ESW_DEST_ENCAP_VALID;
+-		*encap_valid = true;
+ 	} else {
+-		*encap_valid = false;
++		flow_flag_set(flow, SLOW);
+ 	}
+ 	mutex_unlock(&esw->offloads.encap_tbl_lock);
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h
+index d542b8476491e..8ad273dde40ee 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.h
+@@ -17,8 +17,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
+ 		       struct net_device *mirred_dev,
+ 		       int out_index,
+ 		       struct netlink_ext_ack *extack,
+-		       struct net_device **encap_dev,
+-		       bool *encap_valid);
++		       struct net_device **encap_dev);
+ 
+ int mlx5e_attach_decap(struct mlx5e_priv *priv,
+ 		       struct mlx5e_tc_flow *flow,
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+index 229c14b1af004..949ef560df787 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+@@ -1620,7 +1620,6 @@ set_encap_dests(struct mlx5e_priv *priv,
+ 		struct mlx5e_tc_flow *flow,
+ 		struct mlx5_flow_attr *attr,
+ 		struct netlink_ext_ack *extack,
+-		bool *encap_valid,
+ 		bool *vf_tun)
+ {
+ 	struct mlx5e_tc_flow_parse_attr *parse_attr;
+@@ -1637,7 +1636,6 @@ set_encap_dests(struct mlx5e_priv *priv,
+ 	parse_attr = attr->parse_attr;
+ 	esw_attr = attr->esw_attr;
+ 	*vf_tun = false;
+-	*encap_valid = true;
+ 
+ 	for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) {
+ 		struct net_device *out_dev;
+@@ -1654,7 +1652,7 @@ set_encap_dests(struct mlx5e_priv *priv,
+ 			goto out;
+ 		}
+ 		err = mlx5e_attach_encap(priv, flow, attr, out_dev, out_index,
+-					 extack, &encap_dev, encap_valid);
++					 extack, &encap_dev);
+ 		dev_put(out_dev);
+ 		if (err)
+ 			goto out;
+@@ -1718,8 +1716,8 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ 	struct mlx5e_tc_flow_parse_attr *parse_attr;
+ 	struct mlx5_flow_attr *attr = flow->attr;
+ 	struct mlx5_esw_flow_attr *esw_attr;
+-	bool vf_tun, encap_valid;
+ 	u32 max_prio, max_chain;
++	bool vf_tun;
+ 	int err = 0;
+ 
+ 	parse_attr = attr->parse_attr;
+@@ -1809,7 +1807,7 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ 		esw_attr->int_port = int_port;
+ 	}
+ 
+-	err = set_encap_dests(priv, flow, attr, extack, &encap_valid, &vf_tun);
++	err = set_encap_dests(priv, flow, attr, extack, &vf_tun);
+ 	if (err)
+ 		goto err_out;
+ 
+@@ -1839,7 +1837,7 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
+ 	 * (1) there's no error
+ 	 * (2) there's an encap action and we don't have valid neigh
+ 	 */
+-	if (!encap_valid || flow_flag_test(flow, SLOW))
++	if (flow_flag_test(flow, SLOW))
+ 		flow->rule[0] = mlx5e_tc_offload_to_slow_path(esw, flow, &parse_attr->spec);
+ 	else
+ 		flow->rule[0] = mlx5e_tc_offload_fdb_rules(esw, flow, &parse_attr->spec, attr);
+@@ -3737,7 +3735,7 @@ alloc_flow_post_acts(struct mlx5e_tc_flow *flow, struct netlink_ext_ack *extack)
+ 	struct mlx5e_post_act *post_act = get_post_action(flow->priv);
+ 	struct mlx5_flow_attr *attr, *next_attr = NULL;
+ 	struct mlx5e_post_act_handle *handle;
+-	bool vf_tun, encap_valid = true;
++	bool vf_tun;
+ 	int err;
+ 
+ 	/* This is going in reverse order as needed.
+@@ -3759,13 +3757,10 @@ alloc_flow_post_acts(struct mlx5e_tc_flow *flow, struct netlink_ext_ack *extack)
+ 		if (list_is_last(&attr->list, &flow->attrs))
+ 			break;
+ 
+-		err = set_encap_dests(flow->priv, flow, attr, extack, &encap_valid, &vf_tun);
++		err = set_encap_dests(flow->priv, flow, attr, extack, &vf_tun);
+ 		if (err)
+ 			goto out_free;
+ 
+-		if (!encap_valid)
+-			flow_flag_set(flow, SLOW);
+-
+ 		err = actions_prepare_mod_hdr_actions(flow->priv, flow, attr, extack);
+ 		if (err)
+ 			goto out_free;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index 3c68cac4a9c2c..061ac87993546 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -431,7 +431,7 @@ esw_setup_vport_dest(struct mlx5_flow_destination *dest, struct mlx5_flow_act *f
+ 		    mlx5_lag_mpesw_is_activated(esw->dev))
+ 			dest[dest_idx].type = MLX5_FLOW_DESTINATION_TYPE_UPLINK;
+ 	}
+-	if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP) {
++	if (esw_attr->dests[attr_idx].flags & MLX5_ESW_DEST_ENCAP_VALID) {
+ 		if (pkt_reformat) {
+ 			flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
+ 			flow_act->pkt_reformat = esw_attr->dests[attr_idx].pkt_reformat;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 9d908a0ccfef1..1e46f9afa40e0 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -9,7 +9,8 @@ enum {
+ 	MLX5_FW_RESET_FLAGS_RESET_REQUESTED,
+ 	MLX5_FW_RESET_FLAGS_NACK_RESET_REQUEST,
+ 	MLX5_FW_RESET_FLAGS_PENDING_COMP,
+-	MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS
++	MLX5_FW_RESET_FLAGS_DROP_NEW_REQUESTS,
++	MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED
+ };
+ 
+ struct mlx5_fw_reset {
+@@ -406,7 +407,7 @@ static void mlx5_sync_reset_now_event(struct work_struct *work)
+ 	err = mlx5_pci_link_toggle(dev);
+ 	if (err) {
+ 		mlx5_core_warn(dev, "mlx5_pci_link_toggle failed, no reset done, err %d\n", err);
+-		goto done;
++		set_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags);
+ 	}
+ 
+ 	mlx5_enter_error_state(dev, true);
+@@ -482,6 +483,10 @@ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev)
+ 		goto out;
+ 	}
+ 	err = fw_reset->ret;
++	if (test_and_clear_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags)) {
++		mlx5_unload_one_devl_locked(dev);
++		mlx5_load_one_devl_locked(dev, false);
++	}
+ out:
+ 	clear_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags);
+ 	return err;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index e5e32430b6afd..ac178796e484f 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1759,7 +1759,8 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev,
+ 	res = state == pci_channel_io_perm_failure ?
+ 		PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
+ 
+-	mlx5_pci_trace(dev, "Exit, result = %d, %s\n",  res, result2str(res));
++	mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, result = %d, %s\n",
++		       __func__, dev->state, dev->pci_status, res, result2str(res));
+ 	return res;
+ }
+ 
+@@ -1798,7 +1799,8 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
+ 	struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
+ 	int err;
+ 
+-	mlx5_pci_trace(dev, "Enter\n");
++	mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Enter\n",
++		       __func__, dev->state, dev->pci_status);
+ 
+ 	err = mlx5_pci_enable_device(dev);
+ 	if (err) {
+@@ -1820,7 +1822,8 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
+ 
+ 	res = PCI_ERS_RESULT_RECOVERED;
+ out:
+-	mlx5_pci_trace(dev, "Exit, err = %d, result = %d, %s\n", err, res, result2str(res));
++	mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, err = %d, result = %d, %s\n",
++		       __func__, dev->state, dev->pci_status, err, res, result2str(res));
+ 	return res;
+ }
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c
+index 7da012ff0d419..8e2abbab05f04 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c
+@@ -18,6 +18,10 @@ struct mlx5_sf_dev_table {
+ 	phys_addr_t base_address;
+ 	u64 sf_bar_length;
+ 	struct notifier_block nb;
++	struct mutex table_lock; /* Serializes sf life cycle and vhca state change handler */
++	struct workqueue_struct *active_wq;
++	struct work_struct work;
++	u8 stop_active_wq:1;
+ 	struct mlx5_core_dev *dev;
+ };
+ 
+@@ -168,6 +172,7 @@ mlx5_sf_dev_state_change_handler(struct notifier_block *nb, unsigned long event_
+ 		return 0;
+ 
+ 	sf_index = event->function_id - base_id;
++	mutex_lock(&table->table_lock);
+ 	sf_dev = xa_load(&table->devices, sf_index);
+ 	switch (event->new_vhca_state) {
+ 	case MLX5_VHCA_STATE_INVALID:
+@@ -191,6 +196,7 @@ mlx5_sf_dev_state_change_handler(struct notifier_block *nb, unsigned long event_
+ 	default:
+ 		break;
+ 	}
++	mutex_unlock(&table->table_lock);
+ 	return 0;
+ }
+ 
+@@ -215,6 +221,78 @@ static int mlx5_sf_dev_vhca_arm_all(struct mlx5_sf_dev_table *table)
+ 	return 0;
+ }
+ 
++static void mlx5_sf_dev_add_active_work(struct work_struct *work)
++{
++	struct mlx5_sf_dev_table *table = container_of(work, struct mlx5_sf_dev_table, work);
++	u32 out[MLX5_ST_SZ_DW(query_vhca_state_out)] = {};
++	struct mlx5_core_dev *dev = table->dev;
++	u16 max_functions;
++	u16 function_id;
++	u16 sw_func_id;
++	int err = 0;
++	u8 state;
++	int i;
++
++	max_functions = mlx5_sf_max_functions(dev);
++	function_id = MLX5_CAP_GEN(dev, sf_base_id);
++	for (i = 0; i < max_functions; i++, function_id++) {
++		if (table->stop_active_wq)
++			return;
++		err = mlx5_cmd_query_vhca_state(dev, function_id, out, sizeof(out));
++		if (err)
++			/* A failure of specific vhca doesn't mean others will
++			 * fail as well.
++			 */
++			continue;
++		state = MLX5_GET(query_vhca_state_out, out, vhca_state_context.vhca_state);
++		if (state != MLX5_VHCA_STATE_ACTIVE)
++			continue;
++
++		sw_func_id = MLX5_GET(query_vhca_state_out, out, vhca_state_context.sw_function_id);
++		mutex_lock(&table->table_lock);
++		/* Don't probe device which is already probe */
++		if (!xa_load(&table->devices, i))
++			mlx5_sf_dev_add(dev, i, function_id, sw_func_id);
++		/* There is a race where SF got inactive after the query
++		 * above. e.g.: the query returns that the state of the
++		 * SF is active, and after that the eswitch manager set it to
++		 * inactive.
++		 * This case cannot be managed in SW, since the probing of the
++		 * SF is on one system, and the inactivation is on a different
++		 * system.
++		 * If the inactive is done after the SF perform init_hca(),
++		 * the SF will fully probe and then removed. If it was
++		 * done before init_hca(), the SF probe will fail.
++		 */
++		mutex_unlock(&table->table_lock);
++	}
++}
++
++/* In case SFs are generated externally, probe active SFs */
++static int mlx5_sf_dev_queue_active_work(struct mlx5_sf_dev_table *table)
++{
++	if (MLX5_CAP_GEN(table->dev, eswitch_manager))
++		return 0; /* the table is local */
++
++	/* Use a workqueue to probe active SFs, which are in large
++	 * quantity and may take up to minutes to probe.
++	 */
++	table->active_wq = create_singlethread_workqueue("mlx5_active_sf");
++	if (!table->active_wq)
++		return -ENOMEM;
++	INIT_WORK(&table->work, &mlx5_sf_dev_add_active_work);
++	queue_work(table->active_wq, &table->work);
++	return 0;
++}
++
++static void mlx5_sf_dev_destroy_active_work(struct mlx5_sf_dev_table *table)
++{
++	if (table->active_wq) {
++		table->stop_active_wq = true;
++		destroy_workqueue(table->active_wq);
++	}
++}
++
+ void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev)
+ {
+ 	struct mlx5_sf_dev_table *table;
+@@ -240,11 +318,17 @@ void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev)
+ 	table->base_address = pci_resource_start(dev->pdev, 2);
+ 	table->max_sfs = max_sfs;
+ 	xa_init(&table->devices);
++	mutex_init(&table->table_lock);
+ 	dev->priv.sf_dev_table = table;
+ 
+ 	err = mlx5_vhca_event_notifier_register(dev, &table->nb);
+ 	if (err)
+ 		goto vhca_err;
++
++	err = mlx5_sf_dev_queue_active_work(table);
++	if (err)
++		goto add_active_err;
++
+ 	err = mlx5_sf_dev_vhca_arm_all(table);
+ 	if (err)
+ 		goto arm_err;
+@@ -252,6 +336,8 @@ void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev)
+ 	return;
+ 
+ arm_err:
++	mlx5_sf_dev_destroy_active_work(table);
++add_active_err:
+ 	mlx5_vhca_event_notifier_unregister(dev, &table->nb);
+ vhca_err:
+ 	table->max_sfs = 0;
+@@ -279,7 +365,9 @@ void mlx5_sf_dev_table_destroy(struct mlx5_core_dev *dev)
+ 	if (!table)
+ 		return;
+ 
++	mlx5_sf_dev_destroy_active_work(table);
+ 	mlx5_vhca_event_notifier_unregister(dev, &table->nb);
++	mutex_destroy(&table->table_lock);
+ 
+ 	/* Now that event handler is not running, it is safe to destroy
+ 	 * the sf device without race.
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
+index af4d3e1f1a6d9..3f112a897a601 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
+@@ -103,7 +103,7 @@ static int sparx5_port_open(struct net_device *ndev)
+ 	err = phylink_of_phy_connect(port->phylink, port->of_node, 0);
+ 	if (err) {
+ 		netdev_err(ndev, "Could not attach to PHY\n");
+-		return err;
++		goto err_connect;
+ 	}
+ 
+ 	phylink_start(port->phylink);
+@@ -115,10 +115,20 @@ static int sparx5_port_open(struct net_device *ndev)
+ 			err = sparx5_serdes_set(port->sparx5, port, &port->conf);
+ 		else
+ 			err = phy_power_on(port->serdes);
+-		if (err)
++		if (err) {
+ 			netdev_err(ndev, "%s failed\n", __func__);
++			goto out_power;
++		}
+ 	}
+ 
++	return 0;
++
++out_power:
++	phylink_stop(port->phylink);
++	phylink_disconnect_phy(port->phylink);
++err_connect:
++	sparx5_port_enable(port, false);
++
+ 	return err;
+ }
+ 
+diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+index 405786c003347..cb08d7bf95241 100644
+--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
++++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+@@ -341,7 +341,7 @@ int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
+ 		return ret;
+ 
+ 	attrs.split = eth_port.is_split;
+-	attrs.splittable = !attrs.split;
++	attrs.splittable = eth_port.port_lanes > 1 && !attrs.split;
+ 	attrs.lanes = eth_port.port_lanes;
+ 	attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ 	attrs.phys.port_number = eth_port.label_port;
+diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+index b19bff0db1fdc..400b22ad6a346 100644
+--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+@@ -1395,6 +1395,9 @@ nfp_port_get_module_info(struct net_device *netdev,
+ 	u8 data;
+ 
+ 	port = nfp_port_from_netdev(netdev);
++	if (!port)
++		return -EOPNOTSUPP;
++
+ 	/* update port state to get latest interface */
+ 	set_bit(NFP_PORT_CHANGED, &port->flags);
+ 	eth_port = nfp_port_get_eth_port(port);
+diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+index 46da937ad27f8..63b6b7d86ccbe 100644
+--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
++++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+@@ -1143,6 +1143,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
+ 		buffer_info->dma = 0;
+ 		buffer_info->time_stamp = 0;
+ 		tx_ring->next_to_use = ring_num;
++		dev_kfree_skb_any(skb);
+ 		return;
+ 	}
+ 	buffer_info->mapped = true;
+@@ -2459,6 +2460,7 @@ static void pch_gbe_remove(struct pci_dev *pdev)
+ 	unregister_netdev(netdev);
+ 
+ 	pch_gbe_phy_hw_reset(&adapter->hw);
++	pci_dev_put(adapter->ptp_pdev);
+ 
+ 	free_netdev(netdev);
+ }
+@@ -2534,7 +2536,7 @@ static int pch_gbe_probe(struct pci_dev *pdev,
+ 	/* setup the private structure */
+ 	ret = pch_gbe_sw_init(adapter);
+ 	if (ret)
+-		goto err_free_netdev;
++		goto err_put_dev;
+ 
+ 	/* Initialize PHY */
+ 	ret = pch_gbe_init_phy(adapter);
+@@ -2592,6 +2594,8 @@ static int pch_gbe_probe(struct pci_dev *pdev,
+ 
+ err_free_adapter:
+ 	pch_gbe_phy_hw_reset(&adapter->hw);
++err_put_dev:
++	pci_dev_put(adapter->ptp_pdev);
+ err_free_netdev:
+ 	free_netdev(netdev);
+ 	return ret;
+diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c
+index 06f4d9a9e9388..5a2d70a91868e 100644
+--- a/drivers/net/ethernet/qlogic/qla3xxx.c
++++ b/drivers/net/ethernet/qlogic/qla3xxx.c
+@@ -2471,6 +2471,7 @@ static netdev_tx_t ql3xxx_send(struct sk_buff *skb,
+ 					     skb_shinfo(skb)->nr_frags);
+ 	if (tx_cb->seg_count == -1) {
+ 		netdev_err(ndev, "%s: invalid segment count!\n", __func__);
++		dev_kfree_skb_any(skb);
+ 		return NETDEV_TX_OK;
+ 	}
+ 
+diff --git a/drivers/net/ethernet/sfc/ef100_netdev.c b/drivers/net/ethernet/sfc/ef100_netdev.c
+index 17b9d37218cbc..4c33c3b5f32b5 100644
+--- a/drivers/net/ethernet/sfc/ef100_netdev.c
++++ b/drivers/net/ethernet/sfc/ef100_netdev.c
+@@ -217,6 +217,7 @@ netdev_tx_t __ef100_hard_start_xmit(struct sk_buff *skb,
+ 		   skb->len, skb->data_len, channel->channel);
+ 	if (!efx->n_channels || !efx->n_tx_channels || !channel) {
+ 		netif_stop_queue(net_dev);
++		dev_kfree_skb_any(skb);
+ 		goto err;
+ 	}
+ 
+diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
+index de94921cbef9f..025e0c19ec255 100644
+--- a/drivers/net/ipvlan/ipvlan.h
++++ b/drivers/net/ipvlan/ipvlan.h
+@@ -98,6 +98,7 @@ struct ipvl_port {
+ 	struct sk_buff_head	backlog;
+ 	int			count;
+ 	struct ida		ida;
++	netdevice_tracker	dev_tracker;
+ };
+ 
+ struct ipvl_skb_cb {
+diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
+index 49ba8a50dfb1e..9043bcd1b41db 100644
+--- a/drivers/net/ipvlan/ipvlan_main.c
++++ b/drivers/net/ipvlan/ipvlan_main.c
+@@ -83,6 +83,7 @@ static int ipvlan_port_create(struct net_device *dev)
+ 	if (err)
+ 		goto err;
+ 
++	netdev_hold(dev, &port->dev_tracker, GFP_KERNEL);
+ 	return 0;
+ 
+ err:
+@@ -95,6 +96,7 @@ static void ipvlan_port_destroy(struct net_device *dev)
+ 	struct ipvl_port *port = ipvlan_port_get_rtnl(dev);
+ 	struct sk_buff *skb;
+ 
++	netdev_put(dev, &port->dev_tracker);
+ 	if (port->mode == IPVLAN_MODE_L3S)
+ 		ipvlan_l3s_unregister(port);
+ 	netdev_rx_handler_unregister(dev);
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index ddfa853ec9b53..104fc564a766e 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -2685,11 +2685,6 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
+ 	if (ret)
+ 		goto rollback;
+ 
+-	/* Force features update, since they are different for SW MACSec and
+-	 * HW offloading cases.
+-	 */
+-	netdev_update_features(dev);
+-
+ 	rtnl_unlock();
+ 	return 0;
+ 
+@@ -3457,16 +3452,9 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
+ 	return ret;
+ }
+ 
+-#define SW_MACSEC_FEATURES \
++#define MACSEC_FEATURES \
+ 	(NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
+ 
+-/* If h/w offloading is enabled, use real device features save for
+- *   VLAN_FEATURES - they require additional ops
+- *   HW_MACSEC - no reason to report it
+- */
+-#define REAL_DEV_FEATURES(dev) \
+-	((dev)->features & ~(NETIF_F_VLAN_FEATURES | NETIF_F_HW_MACSEC))
+-
+ static int macsec_dev_init(struct net_device *dev)
+ {
+ 	struct macsec_dev *macsec = macsec_priv(dev);
+@@ -3483,12 +3471,8 @@ static int macsec_dev_init(struct net_device *dev)
+ 		return err;
+ 	}
+ 
+-	if (macsec_is_offloaded(macsec)) {
+-		dev->features = REAL_DEV_FEATURES(real_dev);
+-	} else {
+-		dev->features = real_dev->features & SW_MACSEC_FEATURES;
+-		dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
+-	}
++	dev->features = real_dev->features & MACSEC_FEATURES;
++	dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
+ 
+ 	dev->needed_headroom = real_dev->needed_headroom +
+ 			       MACSEC_NEEDED_HEADROOM;
+@@ -3520,10 +3504,7 @@ static netdev_features_t macsec_fix_features(struct net_device *dev,
+ 	struct macsec_dev *macsec = macsec_priv(dev);
+ 	struct net_device *real_dev = macsec->real_dev;
+ 
+-	if (macsec_is_offloaded(macsec))
+-		return REAL_DEV_FEATURES(real_dev);
+-
+-	features &= (real_dev->features & SW_MACSEC_FEATURES) |
++	features &= (real_dev->features & MACSEC_FEATURES) |
+ 		    NETIF_F_GSO_SOFTWARE | NETIF_F_SOFT_FEATURES;
+ 	features |= NETIF_F_LLTX;
+ 
+@@ -3874,7 +3855,6 @@ static int macsec_changelink(struct net_device *dev, struct nlattr *tb[],
+ 	if (macsec_is_offloaded(macsec)) {
+ 		const struct macsec_ops *ops;
+ 		struct macsec_context ctx;
+-		int ret;
+ 
+ 		ops = macsec_get_ops(netdev_priv(dev), &ctx);
+ 		if (!ops) {
+diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
+index 59fe356942b51..249e7ee4a2bb9 100644
+--- a/drivers/net/phy/at803x.c
++++ b/drivers/net/phy/at803x.c
+@@ -862,8 +862,10 @@ static int at803x_probe(struct phy_device *phydev)
+ 			.wolopts = 0,
+ 		};
+ 
+-		if (ccr < 0)
++		if (ccr < 0) {
++			ret = ccr;
+ 			goto err;
++		}
+ 		mode_cfg = ccr & AT803X_MODE_CFG_MASK;
+ 
+ 		switch (mode_cfg) {
+diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
+index 8d5cbda33f66f..0897fdb6254b8 100644
+--- a/drivers/net/usb/cdc_ncm.c
++++ b/drivers/net/usb/cdc_ncm.c
+@@ -1915,6 +1915,7 @@ static const struct driver_info cdc_ncm_zlp_info = {
+ 	.status = cdc_ncm_status,
+ 	.rx_fixup = cdc_ncm_rx_fixup,
+ 	.tx_fixup = cdc_ncm_tx_fixup,
++	.set_rx_mode = usbnet_cdc_update_filter,
+ };
+ 
+ /* Same as cdc_ncm_info, but with FLAG_WWAN */
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index 26c34a7c21bdd..afd6faa4c2ec9 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -1357,6 +1357,7 @@ static const struct usb_device_id products[] = {
+ 	{QMI_FIXED_INTF(0x2357, 0x0201, 4)},	/* TP-LINK HSUPA Modem MA180 */
+ 	{QMI_FIXED_INTF(0x2357, 0x9000, 4)},	/* TP-LINK MA260 */
+ 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1031, 3)}, /* Telit LE910C1-EUX */
++	{QMI_QUIRK_SET_DTR(0x1bc7, 0x103a, 0)}, /* Telit LE910C4-WWX */
+ 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)},	/* Telit LE922A */
+ 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)},	/* Telit FN980 */
+ 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1057, 2)},	/* Telit FN980 */
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index 9cce7dec7366d..f5c88d232b110 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -3933,12 +3933,11 @@ static int virtnet_probe(struct virtio_device *vdev)
+ 	return 0;
+ 
+ free_unregister_netdev:
+-	virtio_reset_device(vdev);
+-
+ 	unregister_netdev(dev);
+ free_failover:
+ 	net_failover_destroy(vi->failover);
+ free_vqs:
++	virtio_reset_device(vdev);
+ 	cancel_delayed_work_sync(&vi->refill);
+ 	free_receive_page_frags(vi);
+ 	virtnet_del_vqs(vi);
+diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h
+index 2ec56a34fa810..0909d53cefebc 100644
+--- a/drivers/net/wireless/ath/ath11k/qmi.h
++++ b/drivers/net/wireless/ath/ath11k/qmi.h
+@@ -27,7 +27,7 @@
+ #define ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01	52
+ #define ATH11K_QMI_CALDB_SIZE			0x480000
+ #define ATH11K_QMI_BDF_EXT_STR_LENGTH		0x20
+-#define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT	3
++#define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT	5
+ 
+ #define QMI_WLFW_REQUEST_MEM_IND_V01		0x0035
+ #define QMI_WLFW_FW_MEM_READY_IND_V01		0x0037
+diff --git a/drivers/net/wireless/cisco/airo.c b/drivers/net/wireless/cisco/airo.c
+index 10daef81c3553..fb2c35bd73bb1 100644
+--- a/drivers/net/wireless/cisco/airo.c
++++ b/drivers/net/wireless/cisco/airo.c
+@@ -5232,7 +5232,7 @@ static int get_wep_tx_idx(struct airo_info *ai)
+ 	return -1;
+ }
+ 
+-static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
++static int set_wep_key(struct airo_info *ai, u16 index, const u8 *key,
+ 		       u16 keylen, int perm, int lock)
+ {
+ 	static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
+@@ -5283,7 +5283,7 @@ static void proc_wepkey_on_close(struct inode *inode, struct file *file)
+ 	struct net_device *dev = pde_data(inode);
+ 	struct airo_info *ai = dev->ml_priv;
+ 	int i, rc;
+-	char key[16];
++	u8 key[16];
+ 	u16 index = 0;
+ 	int j = 0;
+ 
+@@ -5311,12 +5311,22 @@ static void proc_wepkey_on_close(struct inode *inode, struct file *file)
+ 	}
+ 
+ 	for (i = 0; i < 16*3 && data->wbuffer[i+j]; i++) {
++		int val;
++
++		if (i % 3 == 2)
++			continue;
++
++		val = hex_to_bin(data->wbuffer[i+j]);
++		if (val < 0) {
++			airo_print_err(ai->dev->name, "WebKey passed invalid key hex");
++			return;
++		}
+ 		switch(i%3) {
+ 		case 0:
+-			key[i/3] = hex_to_bin(data->wbuffer[i+j])<<4;
++			key[i/3] = (u8)val << 4;
+ 			break;
+ 		case 1:
+-			key[i/3] |= hex_to_bin(data->wbuffer[i+j]);
++			key[i/3] |= (u8)val;
+ 			break;
+ 		}
+ 	}
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index a074552bcec3d..3179682daca70 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -910,6 +910,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
+ 	struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
+ 	struct sk_buff *skb;
+ 	struct ieee80211_hdr *hdr;
++	struct ieee80211_tx_info *cb;
+ 
+ 	if (!vp->assoc)
+ 		return;
+@@ -931,6 +932,10 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
+ 	memcpy(hdr->addr2, mac, ETH_ALEN);
+ 	memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
+ 
++	cb = IEEE80211_SKB_CB(skb);
++	cb->control.rates[0].count = 1;
++	cb->control.rates[1].idx = -1;
++
+ 	rcu_read_lock();
+ 	mac80211_hwsim_tx_frame(data->hw, skb,
+ 				rcu_dereference(vif->bss_conf.chanctx_conf)->def.chan);
+diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+index 3ac373d29d936..7362d4d5ea852 100644
+--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
++++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+@@ -956,30 +956,51 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
+ 		return;
+ 
+ 	while (index + sizeof(*e) <= len) {
++		u16 attr_size;
++
+ 		e = (struct wilc_attr_entry *)&buf[index];
+-		if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST)
++		attr_size = le16_to_cpu(e->attr_len);
++
++		if (index + sizeof(*e) + attr_size > len)
++			return;
++
++		if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST &&
++		    attr_size >= (sizeof(struct wilc_attr_ch_list) - sizeof(*e)))
+ 			ch_list_idx = index;
+-		else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL)
++		else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL &&
++			 attr_size == (sizeof(struct wilc_attr_oper_ch) - sizeof(*e)))
+ 			op_ch_idx = index;
++
+ 		if (ch_list_idx && op_ch_idx)
+ 			break;
+-		index += le16_to_cpu(e->attr_len) + sizeof(*e);
++
++		index += sizeof(*e) + attr_size;
+ 	}
+ 
+ 	if (ch_list_idx) {
+-		u16 attr_size;
+-		struct wilc_ch_list_elem *e;
+-		int i;
++		u16 elem_size;
+ 
+ 		ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
+-		attr_size = le16_to_cpu(ch_list->attr_len);
+-		for (i = 0; i < attr_size;) {
++		/* the number of bytes following the final 'elem' member */
++		elem_size = le16_to_cpu(ch_list->attr_len) -
++			(sizeof(*ch_list) - sizeof(struct wilc_attr_entry));
++		for (unsigned int i = 0; i < elem_size;) {
++			struct wilc_ch_list_elem *e;
++
+ 			e = (struct wilc_ch_list_elem *)(ch_list->elem + i);
++
++			i += sizeof(*e);
++			if (i > elem_size)
++				break;
++
++			i += e->no_of_channels;
++			if (i > elem_size)
++				break;
++
+ 			if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
+ 				memset(e->ch_list, sta_ch, e->no_of_channels);
+ 				break;
+ 			}
+-			i += e->no_of_channels;
+ 		}
+ 	}
+ 
+diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
+index eb1d1ba3a443a..67df8221b5aeb 100644
+--- a/drivers/net/wireless/microchip/wilc1000/hif.c
++++ b/drivers/net/wireless/microchip/wilc1000/hif.c
+@@ -482,14 +482,25 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
+ 
+ 	rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len);
+ 	if (rsn_ie) {
++		int rsn_ie_len = sizeof(struct element) + rsn_ie[1];
+ 		int offset = 8;
+ 
+-		param->mode_802_11i = 2;
+-		param->rsn_found = true;
+ 		/* extract RSN capabilities */
+-		offset += (rsn_ie[offset] * 4) + 2;
+-		offset += (rsn_ie[offset] * 4) + 2;
+-		memcpy(param->rsn_cap, &rsn_ie[offset], 2);
++		if (offset < rsn_ie_len) {
++			/* skip over pairwise suites */
++			offset += (rsn_ie[offset] * 4) + 2;
++
++			if (offset < rsn_ie_len) {
++				/* skip over authentication suites */
++				offset += (rsn_ie[offset] * 4) + 2;
++
++				if (offset + 1 < rsn_ie_len) {
++					param->mode_802_11i = 2;
++					param->rsn_found = true;
++					memcpy(param->rsn_cap, &rsn_ie[offset], 2);
++				}
++			}
++		}
+ 	}
+ 
+ 	if (param->rsn_found) {
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_coredump.c b/drivers/net/wwan/iosm/iosm_ipc_coredump.c
+index 9acd87724c9de..26ca30476f409 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_coredump.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_coredump.c
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (C) 2020-2021 Intel Corporation.
+  */
++#include <linux/vmalloc.h>
+ 
+ #include "iosm_ipc_coredump.h"
+ 
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_devlink.c b/drivers/net/wwan/iosm/iosm_ipc_devlink.c
+index 17da85a8f3371..2fe724d623c06 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_devlink.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_devlink.c
+@@ -2,6 +2,7 @@
+ /*
+  * Copyright (C) 2020-2021 Intel Corporation.
+  */
++#include <linux/vmalloc.h>
+ 
+ #include "iosm_ipc_chnl_cfg.h"
+ #include "iosm_ipc_coredump.h"
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_pcie.c b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+index 97cb6846c6ae2..f604d4a01e1b2 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_pcie.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+@@ -249,7 +249,7 @@ static enum ipc_pcie_sleep_state ipc_pcie_read_bios_cfg(struct device *dev)
+ 	if (object->integer.value == 3)
+ 		sleep_state = IPC_PCIE_D3L2;
+ 
+-	kfree(object);
++	ACPI_FREE(object);
+ 
+ default_ret:
+ 	return sleep_state;
+diff --git a/drivers/net/wwan/t7xx/t7xx_modem_ops.c b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
+index 3458af31e8647..7d0f5e4f0a781 100644
+--- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c
++++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
+@@ -165,6 +165,8 @@ static int t7xx_acpi_reset(struct t7xx_pci_dev *t7xx_dev, char *fn_name)
+ 		return -EFAULT;
+ 	}
+ 
++	kfree(buffer.pointer);
++
+ #endif
+ 	return 0;
+ }
+diff --git a/drivers/nfc/st-nci/se.c b/drivers/nfc/st-nci/se.c
+index 7764b1a4c3cf8..ec87dd21e054a 100644
+--- a/drivers/nfc/st-nci/se.c
++++ b/drivers/nfc/st-nci/se.c
+@@ -312,6 +312,8 @@ static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
+ 	int r = 0;
+ 	struct device *dev = &ndev->nfc_dev->dev;
+ 	struct nfc_evt_transaction *transaction;
++	u32 aid_len;
++	u8 params_len;
+ 
+ 	pr_debug("connectivity gate event: %x\n", event);
+ 
+@@ -325,26 +327,47 @@ static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
+ 		 * Description  Tag     Length
+ 		 * AID          81      5 to 16
+ 		 * PARAMETERS   82      0 to 255
++		 *
++		 * The key differences are aid storage length is variably sized
++		 * in the packet, but fixed in nfc_evt_transaction, and that
++		 * the aid_len is u8 in the packet, but u32 in the structure,
++		 * and the tags in the packet are not included in
++		 * nfc_evt_transaction.
++		 *
++		 * size(b):  1          1       5-16 1             1           0-255
++		 * offset:   0          1       2    aid_len + 2   aid_len + 3 aid_len + 4
++		 * mem name: aid_tag(M) aid_len aid  params_tag(M) params_len  params
++		 * example:  0x81       5-16    X    0x82          0-255       X
+ 		 */
+-		if (skb->len < NFC_MIN_AID_LENGTH + 2 &&
+-		    skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
++		if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
+ 			return -EPROTO;
+ 
+-		transaction = devm_kzalloc(dev, skb->len - 2, GFP_KERNEL);
+-		if (!transaction)
+-			return -ENOMEM;
++		aid_len = skb->data[1];
+ 
+-		transaction->aid_len = skb->data[1];
+-		memcpy(transaction->aid, &skb->data[2], transaction->aid_len);
++		if (skb->len < aid_len + 4 ||
++		    aid_len > sizeof(transaction->aid))
++			return -EPROTO;
+ 
+-		/* Check next byte is PARAMETERS tag (82) */
+-		if (skb->data[transaction->aid_len + 2] !=
+-		    NFC_EVT_TRANSACTION_PARAMS_TAG)
++		params_len = skb->data[aid_len + 3];
++
++		/* Verify PARAMETERS tag is (82), and final check that there is
++		 * enough space in the packet to read everything.
++		 */
++		if (skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG ||
++		    skb->len < aid_len + 4 + params_len)
+ 			return -EPROTO;
+ 
+-		transaction->params_len = skb->data[transaction->aid_len + 3];
+-		memcpy(transaction->params, skb->data +
+-		       transaction->aid_len + 4, transaction->params_len);
++		transaction = devm_kzalloc(dev, sizeof(*transaction) +
++					   params_len, GFP_KERNEL);
++		if (!transaction)
++			return -ENOMEM;
++
++		transaction->aid_len = aid_len;
++		transaction->params_len = params_len;
++
++		memcpy(transaction->aid, &skb->data[2], aid_len);
++		memcpy(transaction->params, &skb->data[aid_len + 4],
++		       params_len);
+ 
+ 		r = nfc_se_transaction(ndev->nfc_dev, host, transaction);
+ 		break;
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index ed47c256dbd27..01c36284e5428 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -675,6 +675,7 @@ void nvme_init_request(struct request *req, struct nvme_command *cmd)
+ 	if (req->mq_hctx->type == HCTX_TYPE_POLL)
+ 		req->cmd_flags |= REQ_POLLED;
+ 	nvme_clear_nvme_request(req);
++	req->rq_flags |= RQF_QUIET;
+ 	memcpy(nvme_req(req)->cmd, cmd, sizeof(*cmd));
+ }
+ EXPORT_SYMBOL_GPL(nvme_init_request);
+@@ -1037,7 +1038,6 @@ int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
+ 			goto out;
+ 	}
+ 
+-	req->rq_flags |= RQF_QUIET;
+ 	ret = nvme_execute_rq(req, at_head);
+ 	if (result && ret >= 0)
+ 		*result = nvme_req(req)->result;
+@@ -1225,7 +1225,6 @@ static void nvme_keep_alive_work(struct work_struct *work)
+ 	rq->timeout = ctrl->kato * HZ;
+ 	rq->end_io = nvme_keep_alive_end_io;
+ 	rq->end_io_data = ctrl;
+-	rq->rq_flags |= RQF_QUIET;
+ 	blk_execute_rq_nowait(rq, false);
+ }
+ 
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 1a6423e94eb30..0f34114c4596d 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -1438,7 +1438,6 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
+ 
+ 	abort_req->end_io = abort_endio;
+ 	abort_req->end_io_data = NULL;
+-	abort_req->rq_flags |= RQF_QUIET;
+ 	blk_execute_rq_nowait(abort_req, false);
+ 
+ 	/*
+@@ -2489,7 +2488,6 @@ static int nvme_delete_queue(struct nvme_queue *nvmeq, u8 opcode)
+ 	req->end_io_data = nvmeq;
+ 
+ 	init_completion(&nvmeq->delete_done);
+-	req->rq_flags |= RQF_QUIET;
+ 	blk_execute_rq_nowait(req, false);
+ 	return 0;
+ }
+diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
+index 7f52d9dac4432..a79eadb953de9 100644
+--- a/drivers/nvme/target/configfs.c
++++ b/drivers/nvme/target/configfs.c
+@@ -1215,6 +1215,7 @@ static ssize_t nvmet_subsys_attr_model_store_locked(struct nvmet_subsys *subsys,
+ 		const char *page, size_t count)
+ {
+ 	int pos = 0, len;
++	char *val;
+ 
+ 	if (subsys->subsys_discovered) {
+ 		pr_err("Can't set model number. %s is already assigned\n",
+@@ -1237,9 +1238,11 @@ static ssize_t nvmet_subsys_attr_model_store_locked(struct nvmet_subsys *subsys,
+ 			return -EINVAL;
+ 	}
+ 
+-	subsys->model_number = kmemdup_nul(page, len, GFP_KERNEL);
+-	if (!subsys->model_number)
++	val = kmemdup_nul(page, len, GFP_KERNEL);
++	if (!val)
+ 		return -ENOMEM;
++	kfree(subsys->model_number);
++	subsys->model_number = val;
+ 	return count;
+ }
+ 
+diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
+index ba64284eaf9fa..f1ec8931dfbc5 100644
+--- a/drivers/pci/controller/pci-hyperv.c
++++ b/drivers/pci/controller/pci-hyperv.c
+@@ -1613,7 +1613,7 @@ out:
+ }
+ 
+ static u32 hv_compose_msi_req_v1(
+-	struct pci_create_interrupt *int_pkt, const struct cpumask *affinity,
++	struct pci_create_interrupt *int_pkt,
+ 	u32 slot, u8 vector, u16 vector_count)
+ {
+ 	int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE;
+@@ -1631,6 +1631,35 @@ static u32 hv_compose_msi_req_v1(
+ 	return sizeof(*int_pkt);
+ }
+ 
++/*
++ * The vCPU selected by hv_compose_multi_msi_req_get_cpu() and
++ * hv_compose_msi_req_get_cpu() is a "dummy" vCPU because the final vCPU to be
++ * interrupted is specified later in hv_irq_unmask() and communicated to Hyper-V
++ * via the HVCALL_RETARGET_INTERRUPT hypercall. But the choice of dummy vCPU is
++ * not irrelevant because Hyper-V chooses the physical CPU to handle the
++ * interrupts based on the vCPU specified in message sent to the vPCI VSP in
++ * hv_compose_msi_msg(). Hyper-V's choice of pCPU is not visible to the guest,
++ * but assigning too many vPCI device interrupts to the same pCPU can cause a
++ * performance bottleneck. So we spread out the dummy vCPUs to influence Hyper-V
++ * to spread out the pCPUs that it selects.
++ *
++ * For the single-MSI and MSI-X cases, it's OK for hv_compose_msi_req_get_cpu()
++ * to always return the same dummy vCPU, because a second call to
++ * hv_compose_msi_msg() contains the "real" vCPU, causing Hyper-V to choose a
++ * new pCPU for the interrupt. But for the multi-MSI case, the second call to
++ * hv_compose_msi_msg() exits without sending a message to the vPCI VSP, so the
++ * original dummy vCPU is used. This dummy vCPU must be round-robin'ed so that
++ * the pCPUs are spread out. All interrupts for a multi-MSI device end up using
++ * the same pCPU, even though the vCPUs will be spread out by later calls
++ * to hv_irq_unmask(), but that is the best we can do now.
++ *
++ * With Hyper-V in Nov 2022, the HVCALL_RETARGET_INTERRUPT hypercall does *not*
++ * cause Hyper-V to reselect the pCPU based on the specified vCPU. Such an
++ * enhancement is planned for a future version. With that enhancement, the
++ * dummy vCPU selection won't matter, and interrupts for the same multi-MSI
++ * device will be spread across multiple pCPUs.
++ */
++
+ /*
+  * Create MSI w/ dummy vCPU set targeting just one vCPU, overwritten
+  * by subsequent retarget in hv_irq_unmask().
+@@ -1640,18 +1669,39 @@ static int hv_compose_msi_req_get_cpu(const struct cpumask *affinity)
+ 	return cpumask_first_and(affinity, cpu_online_mask);
+ }
+ 
+-static u32 hv_compose_msi_req_v2(
+-	struct pci_create_interrupt2 *int_pkt, const struct cpumask *affinity,
+-	u32 slot, u8 vector, u16 vector_count)
++/*
++ * Make sure the dummy vCPU values for multi-MSI don't all point to vCPU0.
++ */
++static int hv_compose_multi_msi_req_get_cpu(void)
+ {
++	static DEFINE_SPINLOCK(multi_msi_cpu_lock);
++
++	/* -1 means starting with CPU 0 */
++	static int cpu_next = -1;
++
++	unsigned long flags;
+ 	int cpu;
+ 
++	spin_lock_irqsave(&multi_msi_cpu_lock, flags);
++
++	cpu_next = cpumask_next_wrap(cpu_next, cpu_online_mask, nr_cpu_ids,
++				     false);
++	cpu = cpu_next;
++
++	spin_unlock_irqrestore(&multi_msi_cpu_lock, flags);
++
++	return cpu;
++}
++
++static u32 hv_compose_msi_req_v2(
++	struct pci_create_interrupt2 *int_pkt, int cpu,
++	u32 slot, u8 vector, u16 vector_count)
++{
+ 	int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE2;
+ 	int_pkt->wslot.slot = slot;
+ 	int_pkt->int_desc.vector = vector;
+ 	int_pkt->int_desc.vector_count = vector_count;
+ 	int_pkt->int_desc.delivery_mode = DELIVERY_MODE;
+-	cpu = hv_compose_msi_req_get_cpu(affinity);
+ 	int_pkt->int_desc.processor_array[0] =
+ 		hv_cpu_number_to_vp_number(cpu);
+ 	int_pkt->int_desc.processor_count = 1;
+@@ -1660,18 +1710,15 @@ static u32 hv_compose_msi_req_v2(
+ }
+ 
+ static u32 hv_compose_msi_req_v3(
+-	struct pci_create_interrupt3 *int_pkt, const struct cpumask *affinity,
++	struct pci_create_interrupt3 *int_pkt, int cpu,
+ 	u32 slot, u32 vector, u16 vector_count)
+ {
+-	int cpu;
+-
+ 	int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE3;
+ 	int_pkt->wslot.slot = slot;
+ 	int_pkt->int_desc.vector = vector;
+ 	int_pkt->int_desc.reserved = 0;
+ 	int_pkt->int_desc.vector_count = vector_count;
+ 	int_pkt->int_desc.delivery_mode = DELIVERY_MODE;
+-	cpu = hv_compose_msi_req_get_cpu(affinity);
+ 	int_pkt->int_desc.processor_array[0] =
+ 		hv_cpu_number_to_vp_number(cpu);
+ 	int_pkt->int_desc.processor_count = 1;
+@@ -1715,12 +1762,18 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 			struct pci_create_interrupt3 v3;
+ 		} int_pkts;
+ 	} __packed ctxt;
++	bool multi_msi;
+ 	u64 trans_id;
+ 	u32 size;
+ 	int ret;
++	int cpu;
++
++	msi_desc  = irq_data_get_msi_desc(data);
++	multi_msi = !msi_desc->pci.msi_attrib.is_msix &&
++		    msi_desc->nvec_used > 1;
+ 
+ 	/* Reuse the previous allocation */
+-	if (data->chip_data) {
++	if (data->chip_data && multi_msi) {
+ 		int_desc = data->chip_data;
+ 		msg->address_hi = int_desc->address >> 32;
+ 		msg->address_lo = int_desc->address & 0xffffffff;
+@@ -1728,7 +1781,6 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 		return;
+ 	}
+ 
+-	msi_desc  = irq_data_get_msi_desc(data);
+ 	pdev = msi_desc_to_pci_dev(msi_desc);
+ 	dest = irq_data_get_effective_affinity_mask(data);
+ 	pbus = pdev->bus;
+@@ -1738,11 +1790,18 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 	if (!hpdev)
+ 		goto return_null_message;
+ 
++	/* Free any previous message that might have already been composed. */
++	if (data->chip_data && !multi_msi) {
++		int_desc = data->chip_data;
++		data->chip_data = NULL;
++		hv_int_desc_free(hpdev, int_desc);
++	}
++
+ 	int_desc = kzalloc(sizeof(*int_desc), GFP_ATOMIC);
+ 	if (!int_desc)
+ 		goto drop_reference;
+ 
+-	if (!msi_desc->pci.msi_attrib.is_msix && msi_desc->nvec_used > 1) {
++	if (multi_msi) {
+ 		/*
+ 		 * If this is not the first MSI of Multi MSI, we already have
+ 		 * a mapping.  Can exit early.
+@@ -1767,9 +1826,11 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 		 */
+ 		vector = 32;
+ 		vector_count = msi_desc->nvec_used;
++		cpu = hv_compose_multi_msi_req_get_cpu();
+ 	} else {
+ 		vector = hv_msi_get_int_vector(data);
+ 		vector_count = 1;
++		cpu = hv_compose_msi_req_get_cpu(dest);
+ 	}
+ 
+ 	/*
+@@ -1785,7 +1846,6 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 	switch (hbus->protocol_version) {
+ 	case PCI_PROTOCOL_VERSION_1_1:
+ 		size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1,
+-					dest,
+ 					hpdev->desc.win_slot.slot,
+ 					(u8)vector,
+ 					vector_count);
+@@ -1794,7 +1854,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 	case PCI_PROTOCOL_VERSION_1_2:
+ 	case PCI_PROTOCOL_VERSION_1_3:
+ 		size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2,
+-					dest,
++					cpu,
+ 					hpdev->desc.win_slot.slot,
+ 					(u8)vector,
+ 					vector_count);
+@@ -1802,7 +1862,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 
+ 	case PCI_PROTOCOL_VERSION_1_4:
+ 		size = hv_compose_msi_req_v3(&ctxt.int_pkts.v3,
+-					dest,
++					cpu,
+ 					hpdev->desc.win_slot.slot,
+ 					vector,
+ 					vector_count);
+diff --git a/drivers/pinctrl/qcom/pinctrl-sc8280xp.c b/drivers/pinctrl/qcom/pinctrl-sc8280xp.c
+index aa2075390f3eb..e96c00686a25b 100644
+--- a/drivers/pinctrl/qcom/pinctrl-sc8280xp.c
++++ b/drivers/pinctrl/qcom/pinctrl-sc8280xp.c
+@@ -1873,8 +1873,8 @@ static const struct msm_pingroup sc8280xp_groups[] = {
+ 	[225] = PINGROUP(225, hs3_mi2s, phase_flag, _, _, _, _, egpio),
+ 	[226] = PINGROUP(226, hs3_mi2s, phase_flag, _, _, _, _, egpio),
+ 	[227] = PINGROUP(227, hs3_mi2s, phase_flag, _, _, _, _, egpio),
+-	[228] = UFS_RESET(ufs_reset, 0xf1004),
+-	[229] = UFS_RESET(ufs1_reset, 0xf3004),
++	[228] = UFS_RESET(ufs_reset, 0xf1000),
++	[229] = UFS_RESET(ufs1_reset, 0xf3000),
+ 	[230] = SDC_QDSD_PINGROUP(sdc2_clk, 0xe8000, 14, 6),
+ 	[231] = SDC_QDSD_PINGROUP(sdc2_cmd, 0xe8000, 11, 3),
+ 	[232] = SDC_QDSD_PINGROUP(sdc2_data, 0xe8000, 9, 0),
+diff --git a/drivers/platform/surface/surface_aggregator_registry.c b/drivers/platform/surface/surface_aggregator_registry.c
+index 585911020cea0..023f126121d7d 100644
+--- a/drivers/platform/surface/surface_aggregator_registry.c
++++ b/drivers/platform/surface/surface_aggregator_registry.c
+@@ -234,6 +234,19 @@ static const struct software_node *ssam_node_group_sl3[] = {
+ 	NULL,
+ };
+ 
++/* Devices for Surface Laptop 5. */
++static const struct software_node *ssam_node_group_sl5[] = {
++	&ssam_node_root,
++	&ssam_node_bat_ac,
++	&ssam_node_bat_main,
++	&ssam_node_tmp_pprof,
++	&ssam_node_hid_main_keyboard,
++	&ssam_node_hid_main_touchpad,
++	&ssam_node_hid_main_iid5,
++	&ssam_node_hid_sam_ucm_ucsi,
++	NULL,
++};
++
+ /* Devices for Surface Laptop Studio. */
+ static const struct software_node *ssam_node_group_sls[] = {
+ 	&ssam_node_root,
+@@ -268,6 +281,7 @@ static const struct software_node *ssam_node_group_sp7[] = {
+ 	NULL,
+ };
+ 
++/* Devices for Surface Pro 8 */
+ static const struct software_node *ssam_node_group_sp8[] = {
+ 	&ssam_node_root,
+ 	&ssam_node_hub_kip,
+@@ -284,6 +298,23 @@ static const struct software_node *ssam_node_group_sp8[] = {
+ 	NULL,
+ };
+ 
++/* Devices for Surface Pro 9 */
++static const struct software_node *ssam_node_group_sp9[] = {
++	&ssam_node_root,
++	&ssam_node_hub_kip,
++	&ssam_node_bat_ac,
++	&ssam_node_bat_main,
++	&ssam_node_tmp_pprof,
++	/* TODO: Tablet mode switch (via POS subsystem) */
++	&ssam_node_hid_kip_keyboard,
++	&ssam_node_hid_kip_penstash,
++	&ssam_node_hid_kip_touchpad,
++	&ssam_node_hid_kip_fwupd,
++	&ssam_node_hid_sam_sensors,
++	&ssam_node_hid_sam_ucm_ucsi,
++	NULL,
++};
++
+ 
+ /* -- SSAM platform/meta-hub driver. ---------------------------------------- */
+ 
+@@ -303,6 +334,9 @@ static const struct acpi_device_id ssam_platform_hub_match[] = {
+ 	/* Surface Pro 8 */
+ 	{ "MSHW0263", (unsigned long)ssam_node_group_sp8 },
+ 
++	/* Surface Pro 9 */
++	{ "MSHW0343", (unsigned long)ssam_node_group_sp9 },
++
+ 	/* Surface Book 2 */
+ 	{ "MSHW0107", (unsigned long)ssam_node_group_gen5 },
+ 
+@@ -324,6 +358,9 @@ static const struct acpi_device_id ssam_platform_hub_match[] = {
+ 	/* Surface Laptop 4 (13", Intel) */
+ 	{ "MSHW0250", (unsigned long)ssam_node_group_sl3 },
+ 
++	/* Surface Laptop 5 */
++	{ "MSHW0350", (unsigned long)ssam_node_group_sl5 },
++
+ 	/* Surface Laptop Go 1 */
+ 	{ "MSHW0118", (unsigned long)ssam_node_group_slg1 },
+ 
+diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
+index f1259d81d86da..df4c1f08f0c6a 100644
+--- a/drivers/platform/x86/acer-wmi.c
++++ b/drivers/platform/x86/acer-wmi.c
+@@ -564,6 +564,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
+ 		},
+ 		.driver_data = (void *)ACER_CAP_KBD_DOCK,
+ 	},
++	{
++		.callback = set_force_caps,
++		.ident = "Acer Aspire Switch V 10 SW5-017",
++		.matches = {
++			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
++			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
++		},
++		.driver_data = (void *)ACER_CAP_KBD_DOCK,
++	},
+ 	{
+ 		.callback = set_force_caps,
+ 		.ident = "Acer One 10 (S1003)",
+diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
+index eec7d0ed7cf21..8e1979b477a7d 100644
+--- a/drivers/platform/x86/asus-wmi.c
++++ b/drivers/platform/x86/asus-wmi.c
+@@ -1656,6 +1656,8 @@ static void asus_wmi_set_xusb2pr(struct asus_wmi *asus)
+ 	pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
+ 				cpu_to_le32(ports_available));
+ 
++	pci_dev_put(xhci_pdev);
++
+ 	pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n",
+ 			orig_ports_available, ports_available);
+ }
+diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
+index 4fbe91769c915..788381e4c6a64 100644
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -90,6 +90,7 @@ enum hp_wmi_event_ids {
+ 	HPWMI_PEAKSHIFT_PERIOD		= 0x0F,
+ 	HPWMI_BATTERY_CHARGE_PERIOD	= 0x10,
+ 	HPWMI_SANITIZATION_MODE		= 0x17,
++	HPWMI_SMART_EXPERIENCE_APP	= 0x21,
+ };
+ 
+ /*
+@@ -857,6 +858,8 @@ static void hp_wmi_notify(u32 value, void *context)
+ 		break;
+ 	case HPWMI_SANITIZATION_MODE:
+ 		break;
++	case HPWMI_SMART_EXPERIENCE_APP:
++		break;
+ 	default:
+ 		pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
+ 		break;
+diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
+index abd0c81d62c40..3ea8fc6a9ca36 100644
+--- a/drivers/platform/x86/ideapad-laptop.c
++++ b/drivers/platform/x86/ideapad-laptop.c
+@@ -136,6 +136,7 @@ struct ideapad_private {
+ 		bool dytc                 : 1;
+ 		bool fan_mode             : 1;
+ 		bool fn_lock              : 1;
++		bool set_fn_lock_led      : 1;
+ 		bool hw_rfkill_switch     : 1;
+ 		bool kbd_bl               : 1;
+ 		bool touchpad_ctrl_via_ec : 1;
+@@ -154,7 +155,21 @@ MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth.");
+ 
+ static bool allow_v4_dytc;
+ module_param(allow_v4_dytc, bool, 0444);
+-MODULE_PARM_DESC(allow_v4_dytc, "Enable DYTC version 4 platform-profile support.");
++MODULE_PARM_DESC(allow_v4_dytc,
++	"Enable DYTC version 4 platform-profile support. "
++	"If you need this please report this to: platform-driver-x86@vger.kernel.org");
++
++static bool hw_rfkill_switch;
++module_param(hw_rfkill_switch, bool, 0444);
++MODULE_PARM_DESC(hw_rfkill_switch,
++	"Enable rfkill support for laptops with a hw on/off wifi switch/slider. "
++	"If you need this please report this to: platform-driver-x86@vger.kernel.org");
++
++static bool set_fn_lock_led;
++module_param(set_fn_lock_led, bool, 0444);
++MODULE_PARM_DESC(set_fn_lock_led,
++	"Enable driver based updates of the fn-lock LED on fn-lock changes. "
++	"If you need this please report this to: platform-driver-x86@vger.kernel.org");
+ 
+ /*
+  * ACPI Helpers
+@@ -1501,6 +1516,9 @@ static void ideapad_wmi_notify(u32 value, void *context)
+ 		ideapad_input_report(priv, value);
+ 		break;
+ 	case 208:
++		if (!priv->features.set_fn_lock_led)
++			break;
++
+ 		if (!eval_hals(priv->adev->handle, &result)) {
+ 			bool state = test_bit(HALS_FNLOCK_STATE_BIT, &result);
+ 
+@@ -1514,6 +1532,18 @@ static void ideapad_wmi_notify(u32 value, void *context)
+ }
+ #endif
+ 
++/* On some models we need to call exec_sals(SALS_FNLOCK_ON/OFF) to set the LED */
++static const struct dmi_system_id set_fn_lock_led_list[] = {
++	{
++		/* https://bugzilla.kernel.org/show_bug.cgi?id=212671 */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++			DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Legion R7000P2020H"),
++		}
++	},
++	{}
++};
++
+ /*
+  * Some ideapads have a hardware rfkill switch, but most do not have one.
+  * Reading VPCCMD_R_RF always results in 0 on models without a hardware rfkill,
+@@ -1533,15 +1563,41 @@ static const struct dmi_system_id hw_rfkill_list[] = {
+ 	{}
+ };
+ 
++static const struct dmi_system_id no_touchpad_switch_list[] = {
++	{
++	.ident = "Lenovo Yoga 3 Pro 1370",
++	.matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++		DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 3"),
++		},
++	},
++	{
++	.ident = "ZhaoYang K4e-IML",
++	.matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++		DMI_MATCH(DMI_PRODUCT_VERSION, "ZhaoYang K4e-IML"),
++		},
++	},
++	{}
++};
++
+ static void ideapad_check_features(struct ideapad_private *priv)
+ {
+ 	acpi_handle handle = priv->adev->handle;
+ 	unsigned long val;
+ 
+-	priv->features.hw_rfkill_switch = dmi_check_system(hw_rfkill_list);
++	priv->features.set_fn_lock_led =
++		set_fn_lock_led || dmi_check_system(set_fn_lock_led_list);
++	priv->features.hw_rfkill_switch =
++		hw_rfkill_switch || dmi_check_system(hw_rfkill_list);
+ 
+ 	/* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */
+-	priv->features.touchpad_ctrl_via_ec = !acpi_dev_present("ELAN0634", NULL, -1);
++	if (acpi_dev_present("ELAN0634", NULL, -1))
++		priv->features.touchpad_ctrl_via_ec = 0;
++	else if (dmi_check_system(no_touchpad_switch_list))
++		priv->features.touchpad_ctrl_via_ec = 0;
++	else
++		priv->features.touchpad_ctrl_via_ec = 1;
+ 
+ 	if (!read_ec_data(handle, VPCCMD_R_FAN, &val))
+ 		priv->features.fan_mode = true;
+diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c
+index 79cff1fc675c2..b6313ecd190c0 100644
+--- a/drivers/platform/x86/intel/hid.c
++++ b/drivers/platform/x86/intel/hid.c
+@@ -27,6 +27,9 @@ static const struct acpi_device_id intel_hid_ids[] = {
+ 	{"INTC1051", 0},
+ 	{"INTC1054", 0},
+ 	{"INTC1070", 0},
++	{"INTC1076", 0},
++	{"INTC1077", 0},
++	{"INTC1078", 0},
+ 	{"", 0},
+ };
+ MODULE_DEVICE_TABLE(acpi, intel_hid_ids);
+diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
+index 53d7fd2943b4c..46598dcb634aa 100644
+--- a/drivers/platform/x86/intel/pmt/class.c
++++ b/drivers/platform/x86/intel/pmt/class.c
+@@ -9,6 +9,7 @@
+  */
+ 
+ #include <linux/kernel.h>
++#include <linux/io-64-nonatomic-lo-hi.h>
+ #include <linux/module.h>
+ #include <linux/mm.h>
+ #include <linux/pci.h>
+@@ -19,6 +20,7 @@
+ #define PMT_XA_START		0
+ #define PMT_XA_MAX		INT_MAX
+ #define PMT_XA_LIMIT		XA_LIMIT(PMT_XA_START, PMT_XA_MAX)
++#define GUID_SPR_PUNIT		0x9956f43f
+ 
+ bool intel_pmt_is_early_client_hw(struct device *dev)
+ {
+@@ -33,6 +35,29 @@ bool intel_pmt_is_early_client_hw(struct device *dev)
+ }
+ EXPORT_SYMBOL_GPL(intel_pmt_is_early_client_hw);
+ 
++static inline int
++pmt_memcpy64_fromio(void *to, const u64 __iomem *from, size_t count)
++{
++	int i, remain;
++	u64 *buf = to;
++
++	if (!IS_ALIGNED((unsigned long)from, 8))
++		return -EFAULT;
++
++	for (i = 0; i < count/8; i++)
++		buf[i] = readq(&from[i]);
++
++	/* Copy any remaining bytes */
++	remain = count % 8;
++	if (remain) {
++		u64 tmp = readq(&from[i]);
++
++		memcpy(&buf[i], &tmp, remain);
++	}
++
++	return count;
++}
++
+ /*
+  * sysfs
+  */
+@@ -54,7 +79,11 @@ intel_pmt_read(struct file *filp, struct kobject *kobj,
+ 	if (count > entry->size - off)
+ 		count = entry->size - off;
+ 
+-	memcpy_fromio(buf, entry->base + off, count);
++	if (entry->guid == GUID_SPR_PUNIT)
++		/* PUNIT on SPR only supports aligned 64-bit read */
++		count = pmt_memcpy64_fromio(buf, entry->base + off, count);
++	else
++		memcpy_fromio(buf, entry->base + off, count);
+ 
+ 	return count;
+ }
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index 353507d18e11c..67dc335fca0c6 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -4497,6 +4497,14 @@ static const struct dmi_system_id fwbug_list[] __initconst = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "21A0"),
+ 		}
+ 	},
++	{
++		.ident = "P14s Gen2 AMD",
++		.driver_data = &quirk_s2idle_bug,
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "21A1"),
++		}
++	},
+ 	{}
+ };
+ 
+diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c
+index bc97bfa8e8a65..baae3120efd05 100644
+--- a/drivers/platform/x86/touchscreen_dmi.c
++++ b/drivers/platform/x86/touchscreen_dmi.c
+@@ -770,6 +770,22 @@ static const struct ts_dmi_data predia_basic_data = {
+ 	.properties	= predia_basic_props,
+ };
+ 
++static const struct property_entry rca_cambio_w101_v2_props[] = {
++	PROPERTY_ENTRY_U32("touchscreen-min-x", 4),
++	PROPERTY_ENTRY_U32("touchscreen-min-y", 20),
++	PROPERTY_ENTRY_U32("touchscreen-size-x", 1644),
++	PROPERTY_ENTRY_U32("touchscreen-size-y", 874),
++	PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
++	PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-rca-cambio-w101-v2.fw"),
++	PROPERTY_ENTRY_U32("silead,max-fingers", 10),
++	{ }
++};
++
++static const struct ts_dmi_data rca_cambio_w101_v2_data = {
++	.acpi_name = "MSSL1680:00",
++	.properties = rca_cambio_w101_v2_props,
++};
++
+ static const struct property_entry rwc_nanote_p8_props[] = {
+ 	PROPERTY_ENTRY_U32("touchscreen-min-y", 46),
+ 	PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
+@@ -1409,6 +1425,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
+ 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "0E57"),
+ 		},
+ 	},
++	{
++		/* RCA Cambio W101 v2 */
++		/* https://github.com/onitake/gsl-firmware/discussions/193 */
++		.driver_data = (void *)&rca_cambio_w101_v2_data,
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "RCA"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "W101SA23T1"),
++		},
++	},
+ 	{
+ 		/* RWC NANOTE P8 */
+ 		.driver_data = (void *)&rwc_nanote_p8_data,
+diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c
+index 863fabe05bdcf..307ee6f71042e 100644
+--- a/drivers/power/supply/ab8500_btemp.c
++++ b/drivers/power/supply/ab8500_btemp.c
+@@ -725,7 +725,14 @@ static int ab8500_btemp_probe(struct platform_device *pdev)
+ 	/* Get thermal zone and ADC */
+ 	di->tz = thermal_zone_get_zone_by_name("battery-thermal");
+ 	if (IS_ERR(di->tz)) {
+-		return dev_err_probe(dev, PTR_ERR(di->tz),
++		ret = PTR_ERR(di->tz);
++		/*
++		 * This usually just means we are probing before the thermal
++		 * zone, so just defer.
++		 */
++		if (ret == -ENODEV)
++			ret = -EPROBE_DEFER;
++		return dev_err_probe(dev, ret,
+ 				     "failed to get battery thermal zone\n");
+ 	}
+ 	di->bat_ctrl = devm_iio_channel_get(dev, "bat_ctrl");
+diff --git a/drivers/power/supply/ip5xxx_power.c b/drivers/power/supply/ip5xxx_power.c
+index 218e8e689a3fb..00221e9c0bfcc 100644
+--- a/drivers/power/supply/ip5xxx_power.c
++++ b/drivers/power/supply/ip5xxx_power.c
+@@ -352,7 +352,7 @@ static int ip5xxx_battery_get_property(struct power_supply *psy,
+ 		ret = ip5xxx_battery_read_adc(ip5xxx, IP5XXX_BATIADC_DAT0,
+ 					      IP5XXX_BATIADC_DAT1, &raw);
+ 
+-		val->intval = DIV_ROUND_CLOSEST(raw * 745985, 1000);
++		val->intval = DIV_ROUND_CLOSEST(raw * 149197, 200);
+ 		return 0;
+ 
+ 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index c3871565fd7d2..c0f368f1b49f7 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -5138,6 +5138,7 @@ static void regulator_dev_release(struct device *dev)
+ {
+ 	struct regulator_dev *rdev = dev_get_drvdata(dev);
+ 
++	debugfs_remove_recursive(rdev->debugfs);
+ 	kfree(rdev->constraints);
+ 	of_node_put(rdev->dev.of_node);
+ 	kfree(rdev);
+@@ -5616,11 +5617,15 @@ wash:
+ 	mutex_lock(&regulator_list_mutex);
+ 	regulator_ena_gpio_free(rdev);
+ 	mutex_unlock(&regulator_list_mutex);
++	put_device(&rdev->dev);
++	rdev = NULL;
+ clean:
+ 	if (dangling_of_gpiod)
+ 		gpiod_put(config->ena_gpiod);
++	if (rdev && rdev->dev.of_node)
++		of_node_put(rdev->dev.of_node);
++	kfree(rdev);
+ 	kfree(config);
+-	put_device(&rdev->dev);
+ rinse:
+ 	if (dangling_cfg_gpiod)
+ 		gpiod_put(cfg->ena_gpiod);
+@@ -5649,7 +5654,6 @@ void regulator_unregister(struct regulator_dev *rdev)
+ 
+ 	mutex_lock(&regulator_list_mutex);
+ 
+-	debugfs_remove_recursive(rdev->debugfs);
+ 	WARN_ON(rdev->open_count);
+ 	regulator_remove_coupling(rdev);
+ 	unset_regulator_supplies(rdev);
+diff --git a/drivers/regulator/rt5759-regulator.c b/drivers/regulator/rt5759-regulator.c
+index 6b96899eb27e3..8488417f4b2cf 100644
+--- a/drivers/regulator/rt5759-regulator.c
++++ b/drivers/regulator/rt5759-regulator.c
+@@ -243,6 +243,7 @@ static int rt5759_regulator_register(struct rt5759_priv *priv)
+ 	if (priv->chip_type == CHIP_TYPE_RT5759A)
+ 		reg_desc->uV_step = RT5759A_STEP_UV;
+ 
++	memset(&reg_cfg, 0, sizeof(reg_cfg));
+ 	reg_cfg.dev = priv->dev;
+ 	reg_cfg.of_node = np;
+ 	reg_cfg.init_data = of_get_regulator_init_data(priv->dev, np, reg_desc);
+diff --git a/drivers/regulator/twl6030-regulator.c b/drivers/regulator/twl6030-regulator.c
+index 430265c404d65..7c7e3648ea4bf 100644
+--- a/drivers/regulator/twl6030-regulator.c
++++ b/drivers/regulator/twl6030-regulator.c
+@@ -530,6 +530,7 @@ static const struct twlreg_info TWL6030_INFO_##label = { \
+ #define TWL6032_ADJUSTABLE_LDO(label, offset) \
+ static const struct twlreg_info TWL6032_INFO_##label = { \
+ 	.base = offset, \
++	.features = TWL6032_SUBCLASS, \
+ 	.desc = { \
+ 		.name = #label, \
+ 		.id = TWL6032_REG_##label, \
+@@ -562,6 +563,7 @@ static const struct twlreg_info TWLFIXED_INFO_##label = { \
+ #define TWL6032_ADJUSTABLE_SMPS(label, offset) \
+ static const struct twlreg_info TWLSMPS_INFO_##label = { \
+ 	.base = offset, \
++	.features = TWL6032_SUBCLASS, \
+ 	.desc = { \
+ 		.name = #label, \
+ 		.id = TWL6032_REG_##label, \
+diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
+index 3cc93e2e4e15a..2dec81e7e6ab1 100644
+--- a/drivers/s390/block/dasd_eckd.c
++++ b/drivers/s390/block/dasd_eckd.c
+@@ -4681,7 +4681,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
+ 	struct dasd_device *basedev;
+ 	struct req_iterator iter;
+ 	struct dasd_ccw_req *cqr;
+-	unsigned int first_offs;
+ 	unsigned int trkcount;
+ 	unsigned long *idaws;
+ 	unsigned int size;
+@@ -4715,7 +4714,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
+ 	last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) /
+ 		DASD_RAW_SECTORS_PER_TRACK;
+ 	trkcount = last_trk - first_trk + 1;
+-	first_offs = 0;
+ 
+ 	if (rq_data_dir(req) == READ)
+ 		cmd = DASD_ECKD_CCW_READ_TRACK;
+@@ -4759,13 +4757,13 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,
+ 
+ 	if (use_prefix) {
+ 		prefix_LRE(ccw++, data, first_trk, last_trk, cmd, basedev,
+-			   startdev, 1, first_offs + 1, trkcount, 0, 0);
++			   startdev, 1, 0, trkcount, 0, 0);
+ 	} else {
+ 		define_extent(ccw++, data, first_trk, last_trk, cmd, basedev, 0);
+ 		ccw[-1].flags |= CCW_FLAG_CC;
+ 
+ 		data += sizeof(struct DE_eckd_data);
+-		locate_record_ext(ccw++, data, first_trk, first_offs + 1,
++		locate_record_ext(ccw++, data, first_trk, 0,
+ 				  trkcount, cmd, basedev, 0, 0);
+ 	}
+ 
+diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
+index 59ac98f2bd275..b02c631f3b71a 100644
+--- a/drivers/s390/crypto/ap_bus.c
++++ b/drivers/s390/crypto/ap_bus.c
+@@ -233,8 +233,11 @@ static void __init ap_init_qci_info(void)
+ 	if (!ap_qci_info)
+ 		return;
+ 	ap_qci_info_old = kzalloc(sizeof(*ap_qci_info_old), GFP_KERNEL);
+-	if (!ap_qci_info_old)
++	if (!ap_qci_info_old) {
++		kfree(ap_qci_info);
++		ap_qci_info = NULL;
+ 		return;
++	}
+ 	if (ap_fetch_qci_info(ap_qci_info) != 0) {
+ 		kfree(ap_qci_info);
+ 		kfree(ap_qci_info_old);
+diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
+index 8fb34b8eeb189..5ad2514775931 100644
+--- a/drivers/s390/crypto/zcrypt_msgtype6.c
++++ b/drivers/s390/crypto/zcrypt_msgtype6.c
+@@ -342,7 +342,10 @@ static int xcrb_msg_to_type6cprb_msgx(bool userspace, struct ap_message *ap_msg,
+ 	};
+ 	struct {
+ 		struct type6_hdr hdr;
+-		struct CPRBX cprbx;
++		union {
++			struct CPRBX cprbx;
++			DECLARE_FLEX_ARRAY(u8, userdata);
++		};
+ 	} __packed * msg = ap_msg->msg;
+ 
+ 	int rcblen = CEIL4(xcrb->request_control_blk_length);
+@@ -403,7 +406,8 @@ static int xcrb_msg_to_type6cprb_msgx(bool userspace, struct ap_message *ap_msg,
+ 	msg->hdr.fromcardlen2 = xcrb->reply_data_length;
+ 
+ 	/* prepare CPRB */
+-	if (z_copy_from_user(userspace, &msg->cprbx, xcrb->request_control_blk_addr,
++	if (z_copy_from_user(userspace, msg->userdata,
++			     xcrb->request_control_blk_addr,
+ 			     xcrb->request_control_blk_length))
+ 		return -EFAULT;
+ 	if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
+@@ -469,9 +473,14 @@ static int xcrb_msg_to_type6_ep11cprb_msgx(bool userspace, struct ap_message *ap
+ 
+ 	struct {
+ 		struct type6_hdr hdr;
+-		struct ep11_cprb cprbx;
+-		unsigned char	pld_tag;	/* fixed value 0x30 */
+-		unsigned char	pld_lenfmt;	/* payload length format */
++		union {
++			struct {
++				struct ep11_cprb cprbx;
++				unsigned char pld_tag;    /* fixed value 0x30 */
++				unsigned char pld_lenfmt; /* length format */
++			} __packed;
++			DECLARE_FLEX_ARRAY(u8, userdata);
++		};
+ 	} __packed * msg = ap_msg->msg;
+ 
+ 	struct pld_hdr {
+@@ -500,7 +509,7 @@ static int xcrb_msg_to_type6_ep11cprb_msgx(bool userspace, struct ap_message *ap
+ 	msg->hdr.fromcardlen1 = xcrb->resp_len;
+ 
+ 	/* Import CPRB data from the ioctl input parameter */
+-	if (z_copy_from_user(userspace, &msg->cprbx.cprb_len,
++	if (z_copy_from_user(userspace, msg->userdata,
+ 			     (char __force __user *)xcrb->req, xcrb->req_len)) {
+ 		return -EFAULT;
+ 	}
+diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
+index 00684e11976be..1a0c0b7289d26 100644
+--- a/drivers/scsi/ibmvscsi/ibmvfc.c
++++ b/drivers/scsi/ibmvscsi/ibmvfc.c
+@@ -708,8 +708,13 @@ static void ibmvfc_init_host(struct ibmvfc_host *vhost)
+ 		memset(vhost->async_crq.msgs.async, 0, PAGE_SIZE);
+ 		vhost->async_crq.cur = 0;
+ 
+-		list_for_each_entry(tgt, &vhost->targets, queue)
+-			ibmvfc_del_tgt(tgt);
++		list_for_each_entry(tgt, &vhost->targets, queue) {
++			if (vhost->client_migrated)
++				tgt->need_login = 1;
++			else
++				ibmvfc_del_tgt(tgt);
++		}
++
+ 		scsi_block_requests(vhost->host);
+ 		ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT);
+ 		vhost->job_step = ibmvfc_npiv_login;
+@@ -3235,9 +3240,12 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost,
+ 			/* We need to re-setup the interpartition connection */
+ 			dev_info(vhost->dev, "Partition migrated, Re-enabling adapter\n");
+ 			vhost->client_migrated = 1;
++
++			scsi_block_requests(vhost->host);
+ 			ibmvfc_purge_requests(vhost, DID_REQUEUE);
+-			ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN);
++			ibmvfc_set_host_state(vhost, IBMVFC_LINK_DOWN);
+ 			ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_REENABLE);
++			wake_up(&vhost->work_wait_q);
+ 		} else if (crq->format == IBMVFC_PARTNER_FAILED || crq->format == IBMVFC_PARTNER_DEREGISTER) {
+ 			dev_err(vhost->dev, "Host partner adapter deregistered or failed (rc=%d)\n", crq->format);
+ 			ibmvfc_purge_requests(vhost, DID_ERROR);
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
+index bfa1165e23b67..1b4d1e562de86 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
+@@ -2930,7 +2930,8 @@ void mpi3mr_process_op_reply_desc(struct mpi3mr_ioc *mrioc,
+ 	}
+ 
+ 	if (scmd->result != (DID_OK << 16) && (scmd->cmnd[0] != ATA_12) &&
+-	    (scmd->cmnd[0] != ATA_16)) {
++	    (scmd->cmnd[0] != ATA_16) &&
++	    mrioc->logging_level & MPI3_DEBUG_SCSI_ERROR) {
+ 		ioc_info(mrioc, "%s :scmd->result 0x%x\n", __func__,
+ 		    scmd->result);
+ 		scsi_print_command(scmd);
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index 95f940f5c996d..7346098c1c68f 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -1899,6 +1899,13 @@ static int resp_readcap16(struct scsi_cmnd *scp,
+ 			arr[14] |= 0x40;
+ 	}
+ 
++	/*
++	 * Since the scsi_debug READ CAPACITY implementation always reports the
++	 * total disk capacity, set RC BASIS = 1 for host-managed ZBC devices.
++	 */
++	if (devip->zmodel == BLK_ZONED_HM)
++		arr[12] |= 1 << 4;
++
+ 	arr[15] = sdebug_lowest_aligned & 0xff;
+ 
+ 	if (have_dif_prot) {
+diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
+index cd3db9684e52d..f473c002fa4d6 100644
+--- a/drivers/scsi/scsi_transport_iscsi.c
++++ b/drivers/scsi/scsi_transport_iscsi.c
+@@ -231,7 +231,7 @@ iscsi_create_endpoint(int dd_size)
+ 	dev_set_name(&ep->dev, "ep-%d", id);
+ 	err = device_register(&ep->dev);
+         if (err)
+-		goto free_id;
++		goto put_dev;
+ 
+ 	err = sysfs_create_group(&ep->dev.kobj, &iscsi_endpoint_group);
+ 	if (err)
+@@ -245,10 +245,12 @@ unregister_dev:
+ 	device_unregister(&ep->dev);
+ 	return NULL;
+ 
+-free_id:
++put_dev:
+ 	mutex_lock(&iscsi_ep_idr_mutex);
+ 	idr_remove(&iscsi_ep_idr, id);
+ 	mutex_unlock(&iscsi_ep_idr_mutex);
++	put_device(&ep->dev);
++	return NULL;
+ free_ep:
+ 	kfree(ep);
+ 	return NULL;
+@@ -766,7 +768,7 @@ iscsi_create_iface(struct Scsi_Host *shost, struct iscsi_transport *transport,
+ 
+ 	err = device_register(&iface->dev);
+ 	if (err)
+-		goto free_iface;
++		goto put_dev;
+ 
+ 	err = sysfs_create_group(&iface->dev.kobj, &iscsi_iface_group);
+ 	if (err)
+@@ -780,9 +782,8 @@ unreg_iface:
+ 	device_unregister(&iface->dev);
+ 	return NULL;
+ 
+-free_iface:
+-	put_device(iface->dev.parent);
+-	kfree(iface);
++put_dev:
++	put_device(&iface->dev);
+ 	return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_create_iface);
+@@ -1251,15 +1252,15 @@ iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index,
+ 
+ 	err = device_register(&fnode_sess->dev);
+ 	if (err)
+-		goto free_fnode_sess;
++		goto put_dev;
+ 
+ 	if (dd_size)
+ 		fnode_sess->dd_data = &fnode_sess[1];
+ 
+ 	return fnode_sess;
+ 
+-free_fnode_sess:
+-	kfree(fnode_sess);
++put_dev:
++	put_device(&fnode_sess->dev);
+ 	return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_create_flashnode_sess);
+@@ -1299,15 +1300,15 @@ iscsi_create_flashnode_conn(struct Scsi_Host *shost,
+ 
+ 	err = device_register(&fnode_conn->dev);
+ 	if (err)
+-		goto free_fnode_conn;
++		goto put_dev;
+ 
+ 	if (dd_size)
+ 		fnode_conn->dd_data = &fnode_conn[1];
+ 
+ 	return fnode_conn;
+ 
+-free_fnode_conn:
+-	kfree(fnode_conn);
++put_dev:
++	put_device(&fnode_conn->dev);
+ 	return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn);
+@@ -4815,7 +4816,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
+ 	dev_set_name(&priv->dev, "%s", tt->name);
+ 	err = device_register(&priv->dev);
+ 	if (err)
+-		goto free_priv;
++		goto put_dev;
+ 
+ 	err = sysfs_create_group(&priv->dev.kobj, &iscsi_transport_group);
+ 	if (err)
+@@ -4850,8 +4851,8 @@ iscsi_register_transport(struct iscsi_transport *tt)
+ unregister_dev:
+ 	device_unregister(&priv->dev);
+ 	return NULL;
+-free_priv:
+-	kfree(priv);
++put_dev:
++	put_device(&priv->dev);
+ 	return NULL;
+ }
+ EXPORT_SYMBOL_GPL(iscsi_register_transport);
+diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
+index 8ced292c4b962..d93604318ecd3 100644
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -300,16 +300,21 @@ enum storvsc_request_type {
+ };
+ 
+ /*
+- * SRB status codes and masks; a subset of the codes used here.
++ * SRB status codes and masks. In the 8-bit field, the two high order bits
++ * are flags, while the remaining 6 bits are an integer status code.  The
++ * definitions here include only the subset of the integer status codes that
++ * are tested for in this driver.
+  */
+-
+ #define SRB_STATUS_AUTOSENSE_VALID	0x80
+ #define SRB_STATUS_QUEUE_FROZEN		0x40
+-#define SRB_STATUS_INVALID_LUN	0x20
+-#define SRB_STATUS_SUCCESS	0x01
+-#define SRB_STATUS_ABORTED	0x02
+-#define SRB_STATUS_ERROR	0x04
+-#define SRB_STATUS_DATA_OVERRUN	0x12
++
++/* SRB status integer codes */
++#define SRB_STATUS_SUCCESS		0x01
++#define SRB_STATUS_ABORTED		0x02
++#define SRB_STATUS_ERROR		0x04
++#define SRB_STATUS_INVALID_REQUEST	0x06
++#define SRB_STATUS_DATA_OVERRUN		0x12
++#define SRB_STATUS_INVALID_LUN		0x20
+ 
+ #define SRB_STATUS(status) \
+ 	(status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
+@@ -966,38 +971,25 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
+ 	void (*process_err_fn)(struct work_struct *work);
+ 	struct hv_host_device *host_dev = shost_priv(host);
+ 
+-	/*
+-	 * In some situations, Hyper-V sets multiple bits in the
+-	 * srb_status, such as ABORTED and ERROR. So process them
+-	 * individually, with the most specific bits first.
+-	 */
+-
+-	if (vm_srb->srb_status & SRB_STATUS_INVALID_LUN) {
+-		set_host_byte(scmnd, DID_NO_CONNECT);
+-		process_err_fn = storvsc_remove_lun;
+-		goto do_work;
+-	}
++	switch (SRB_STATUS(vm_srb->srb_status)) {
++	case SRB_STATUS_ERROR:
++	case SRB_STATUS_ABORTED:
++	case SRB_STATUS_INVALID_REQUEST:
++		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID) {
++			/* Check for capacity change */
++			if ((asc == 0x2a) && (ascq == 0x9)) {
++				process_err_fn = storvsc_device_scan;
++				/* Retry the I/O that triggered this. */
++				set_host_byte(scmnd, DID_REQUEUE);
++				goto do_work;
++			}
+ 
+-	if (vm_srb->srb_status & SRB_STATUS_ABORTED) {
+-		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID &&
+-		    /* Capacity data has changed */
+-		    (asc == 0x2a) && (ascq == 0x9)) {
+-			process_err_fn = storvsc_device_scan;
+ 			/*
+-			 * Retry the I/O that triggered this.
++			 * Otherwise, let upper layer deal with the
++			 * error when sense message is present
+ 			 */
+-			set_host_byte(scmnd, DID_REQUEUE);
+-			goto do_work;
+-		}
+-	}
+-
+-	if (vm_srb->srb_status & SRB_STATUS_ERROR) {
+-		/*
+-		 * Let upper layer deal with error when
+-		 * sense message is present.
+-		 */
+-		if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID)
+ 			return;
++		}
+ 
+ 		/*
+ 		 * If there is an error; offline the device since all
+@@ -1020,6 +1012,13 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
+ 		default:
+ 			set_host_byte(scmnd, DID_ERROR);
+ 		}
++		return;
++
++	case SRB_STATUS_INVALID_LUN:
++		set_host_byte(scmnd, DID_NO_CONNECT);
++		process_err_fn = storvsc_remove_lun;
++		goto do_work;
++
+ 	}
+ 	return;
+ 
+diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c
+index 1322b8cce5b7c..ababb910b3914 100644
+--- a/drivers/spi/spi-dw-dma.c
++++ b/drivers/spi/spi-dw-dma.c
+@@ -128,12 +128,15 @@ static int dw_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
+ 
+ 	dw_spi_dma_sg_burst_init(dws);
+ 
++	pci_dev_put(dma_dev);
++
+ 	return 0;
+ 
+ free_rxchan:
+ 	dma_release_channel(dws->rxchan);
+ 	dws->rxchan = NULL;
+ err_exit:
++	pci_dev_put(dma_dev);
+ 	return -EBUSY;
+ }
+ 
+diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
+index 30d82cc7300b2..d209930069cf3 100644
+--- a/drivers/spi/spi-imx.c
++++ b/drivers/spi/spi-imx.c
+@@ -444,8 +444,7 @@ static unsigned int mx51_ecspi_clkdiv(struct spi_imx_data *spi_imx,
+ 	unsigned int pre, post;
+ 	unsigned int fin = spi_imx->spi_clk;
+ 
+-	if (unlikely(fspi > fin))
+-		return 0;
++	fspi = min(fspi, fin);
+ 
+ 	post = fls(fin) - fls(fspi);
+ 	if (fin > fspi << post)
+@@ -1607,6 +1606,13 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
+ 	if (spi_imx->slave_mode)
+ 		return spi_imx_pio_transfer_slave(spi, transfer);
+ 
++	/*
++	 * If we decided in spi_imx_can_dma() that we want to do a DMA
++	 * transfer, the SPI transfer has already been mapped, so we
++	 * have to do the DMA transfer here.
++	 */
++	if (spi_imx->usedma)
++		return spi_imx_dma_transfer(spi_imx, transfer);
+ 	/*
+ 	 * Calculate the estimated time in us the transfer runs. Find
+ 	 * the number of Hz per byte per polling limit.
+@@ -1618,9 +1624,6 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
+ 	if (transfer->len < byte_limit)
+ 		return spi_imx_poll_transfer(spi, transfer);
+ 
+-	if (spi_imx->usedma)
+-		return spi_imx_dma_transfer(spi_imx, transfer);
+-
+ 	return spi_imx_pio_transfer(spi, transfer);
+ }
+ 
+diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
+index 3c2fa2e2f94a3..def09cf0dc147 100644
+--- a/drivers/spi/spi-stm32.c
++++ b/drivers/spi/spi-stm32.c
+@@ -434,7 +434,7 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
+ 	u32 div, mbrdiv;
+ 
+ 	/* Ensure spi->clk_rate is even */
+-	div = DIV_ROUND_UP(spi->clk_rate & ~0x1, speed_hz);
++	div = DIV_ROUND_CLOSEST(spi->clk_rate & ~0x1, speed_hz);
+ 
+ 	/*
+ 	 * SPI framework set xfer->speed_hz to master->max_speed_hz if
+diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
+index 904972606bd45..9f356612ba7e5 100644
+--- a/drivers/spi/spi-tegra210-quad.c
++++ b/drivers/spi/spi-tegra210-quad.c
+@@ -720,6 +720,9 @@ static int tegra_qspi_start_cpu_based_transfer(struct tegra_qspi *qspi, struct s
+ 
+ static void tegra_qspi_deinit_dma(struct tegra_qspi *tqspi)
+ {
++	if (!tqspi->soc_data->has_dma)
++		return;
++
+ 	if (tqspi->tx_dma_buf) {
+ 		dma_free_coherent(tqspi->dev, tqspi->dma_buf_size,
+ 				  tqspi->tx_dma_buf, tqspi->tx_dma_phys);
+@@ -750,6 +753,9 @@ static int tegra_qspi_init_dma(struct tegra_qspi *tqspi)
+ 	u32 *dma_buf;
+ 	int err;
+ 
++	if (!tqspi->soc_data->has_dma)
++		return 0;
++
+ 	dma_chan = dma_request_chan(tqspi->dev, "rx");
+ 	if (IS_ERR(dma_chan)) {
+ 		err = PTR_ERR(dma_chan);
+@@ -918,8 +924,9 @@ static int tegra_qspi_start_transfer_one(struct spi_device *spi,
+ static struct tegra_qspi_client_data *tegra_qspi_parse_cdata_dt(struct spi_device *spi)
+ {
+ 	struct tegra_qspi_client_data *cdata;
++	struct tegra_qspi *tqspi = spi_master_get_devdata(spi->master);
+ 
+-	cdata = devm_kzalloc(&spi->dev, sizeof(*cdata), GFP_KERNEL);
++	cdata = devm_kzalloc(tqspi->dev, sizeof(*cdata), GFP_KERNEL);
+ 	if (!cdata)
+ 		return NULL;
+ 
+diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c
+index f3947be13e2e5..64f0e047c23d2 100644
+--- a/drivers/tee/optee/device.c
++++ b/drivers/tee/optee/device.c
+@@ -80,7 +80,7 @@ static int optee_register_device(const uuid_t *device_uuid)
+ 	rc = device_register(&optee_device->dev);
+ 	if (rc) {
+ 		pr_err("device registration failed, err: %d\n", rc);
+-		kfree(optee_device);
++		put_device(&optee_device->dev);
+ 	}
+ 
+ 	return rc;
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 2a0de70e0be41..ae02aed6bd0c2 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -248,7 +248,7 @@ struct gsm_mux {
+ 	bool constipated;		/* Asked by remote to shut up */
+ 	bool has_devices;		/* Devices were registered */
+ 
+-	struct mutex tx_mutex;
++	spinlock_t tx_lock;
+ 	unsigned int tx_bytes;		/* TX data outstanding */
+ #define TX_THRESH_HI		8192
+ #define TX_THRESH_LO		2048
+@@ -256,7 +256,7 @@ struct gsm_mux {
+ 	struct list_head tx_data_list;	/* Pending data packets */
+ 
+ 	/* Control messages */
+-	struct delayed_work kick_timeout;	/* Kick TX queuing on timeout */
++	struct timer_list kick_timer;	/* Kick TX queuing on timeout */
+ 	struct timer_list t2_timer;	/* Retransmit timer for commands */
+ 	int cretries;			/* Command retry counter */
+ 	struct gsm_control *pending_cmd;/* Our current pending command */
+@@ -680,6 +680,7 @@ static int gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
+ 	struct gsm_msg *msg;
+ 	u8 *dp;
+ 	int ocr;
++	unsigned long flags;
+ 
+ 	msg = gsm_data_alloc(gsm, addr, 0, control);
+ 	if (!msg)
+@@ -701,10 +702,10 @@ static int gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
+ 
+ 	gsm_print_packet("Q->", addr, cr, control, NULL, 0);
+ 
+-	mutex_lock(&gsm->tx_mutex);
++	spin_lock_irqsave(&gsm->tx_lock, flags);
+ 	list_add_tail(&msg->list, &gsm->tx_ctrl_list);
+ 	gsm->tx_bytes += msg->len;
+-	mutex_unlock(&gsm->tx_mutex);
++	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ 	gsmld_write_trigger(gsm);
+ 
+ 	return 0;
+@@ -729,7 +730,7 @@ static void gsm_dlci_clear_queues(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+ 	spin_unlock_irqrestore(&dlci->lock, flags);
+ 
+ 	/* Clear data packets in MUX write queue */
+-	mutex_lock(&gsm->tx_mutex);
++	spin_lock_irqsave(&gsm->tx_lock, flags);
+ 	list_for_each_entry_safe(msg, nmsg, &gsm->tx_data_list, list) {
+ 		if (msg->addr != addr)
+ 			continue;
+@@ -737,7 +738,7 @@ static void gsm_dlci_clear_queues(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+ 		list_del(&msg->list);
+ 		kfree(msg);
+ 	}
+-	mutex_unlock(&gsm->tx_mutex);
++	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ }
+ 
+ /**
+@@ -1008,7 +1009,7 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+ 	gsm->tx_bytes += msg->len;
+ 
+ 	gsmld_write_trigger(gsm);
+-	schedule_delayed_work(&gsm->kick_timeout, 10 * gsm->t1 * HZ / 100);
++	mod_timer(&gsm->kick_timer, jiffies + 10 * gsm->t1 * HZ / 100);
+ }
+ 
+ /**
+@@ -1023,9 +1024,10 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+ 
+ static void gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+ {
+-	mutex_lock(&dlci->gsm->tx_mutex);
++	unsigned long flags;
++	spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
+ 	__gsm_data_queue(dlci, msg);
+-	mutex_unlock(&dlci->gsm->tx_mutex);
++	spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags);
+ }
+ 
+ /**
+@@ -1037,7 +1039,7 @@ static void gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg)
+  *	is data. Keep to the MRU of the mux. This path handles the usual tty
+  *	interface which is a byte stream with optional modem data.
+  *
+- *	Caller must hold the tx_mutex of the mux.
++ *	Caller must hold the tx_lock of the mux.
+  */
+ 
+ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+@@ -1097,7 +1099,7 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
+  *	is data. Keep to the MRU of the mux. This path handles framed data
+  *	queued as skbuffs to the DLCI.
+  *
+- *	Caller must hold the tx_mutex of the mux.
++ *	Caller must hold the tx_lock of the mux.
+  */
+ 
+ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
+@@ -1113,7 +1115,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
+ 	if (dlci->adaption == 4)
+ 		overhead = 1;
+ 
+-	/* dlci->skb is locked by tx_mutex */
++	/* dlci->skb is locked by tx_lock */
+ 	if (dlci->skb == NULL) {
+ 		dlci->skb = skb_dequeue_tail(&dlci->skb_list);
+ 		if (dlci->skb == NULL)
+@@ -1167,7 +1169,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
+  *	Push an empty frame in to the transmit queue to update the modem status
+  *	bits and to transmit an optional break.
+  *
+- *	Caller must hold the tx_mutex of the mux.
++ *	Caller must hold the tx_lock of the mux.
+  */
+ 
+ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci,
+@@ -1281,12 +1283,13 @@ static int gsm_dlci_data_sweep(struct gsm_mux *gsm)
+ 
+ static void gsm_dlci_data_kick(struct gsm_dlci *dlci)
+ {
++	unsigned long flags;
+ 	int sweep;
+ 
+ 	if (dlci->constipated)
+ 		return;
+ 
+-	mutex_lock(&dlci->gsm->tx_mutex);
++	spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
+ 	/* If we have nothing running then we need to fire up */
+ 	sweep = (dlci->gsm->tx_bytes < TX_THRESH_LO);
+ 	if (dlci->gsm->tx_bytes == 0) {
+@@ -1297,7 +1300,7 @@ static void gsm_dlci_data_kick(struct gsm_dlci *dlci)
+ 	}
+ 	if (sweep)
+ 		gsm_dlci_data_sweep(dlci->gsm);
+-	mutex_unlock(&dlci->gsm->tx_mutex);
++	spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags);
+ }
+ 
+ /*
+@@ -1981,23 +1984,24 @@ static void gsm_dlci_command(struct gsm_dlci *dlci, const u8 *data, int len)
+ }
+ 
+ /**
+- *	gsm_kick_timeout	-	transmit if possible
+- *	@work: work contained in our gsm object
++ *	gsm_kick_timer	-	transmit if possible
++ *	@t: timer contained in our gsm object
+  *
+  *	Transmit data from DLCIs if the queue is empty. We can't rely on
+  *	a tty wakeup except when we filled the pipe so we need to fire off
+  *	new data ourselves in other cases.
+  */
+-static void gsm_kick_timeout(struct work_struct *work)
++static void gsm_kick_timer(struct timer_list *t)
+ {
+-	struct gsm_mux *gsm = container_of(work, struct gsm_mux, kick_timeout.work);
++	struct gsm_mux *gsm = from_timer(gsm, t, kick_timer);
++	unsigned long flags;
+ 	int sent = 0;
+ 
+-	mutex_lock(&gsm->tx_mutex);
++	spin_lock_irqsave(&gsm->tx_lock, flags);
+ 	/* If we have nothing running then we need to fire up */
+ 	if (gsm->tx_bytes < TX_THRESH_LO)
+ 		sent = gsm_dlci_data_sweep(gsm);
+-	mutex_unlock(&gsm->tx_mutex);
++	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ 
+ 	if (sent && debug & 4)
+ 		pr_info("%s TX queue stalled\n", __func__);
+@@ -2454,7 +2458,7 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
+ 	}
+ 
+ 	/* Finish outstanding timers, making sure they are done */
+-	cancel_delayed_work_sync(&gsm->kick_timeout);
++	del_timer_sync(&gsm->kick_timer);
+ 	del_timer_sync(&gsm->t2_timer);
+ 
+ 	/* Finish writing to ldisc */
+@@ -2527,7 +2531,6 @@ static void gsm_free_mux(struct gsm_mux *gsm)
+ 			break;
+ 		}
+ 	}
+-	mutex_destroy(&gsm->tx_mutex);
+ 	mutex_destroy(&gsm->mutex);
+ 	kfree(gsm->txframe);
+ 	kfree(gsm->buf);
+@@ -2599,15 +2602,15 @@ static struct gsm_mux *gsm_alloc_mux(void)
+ 	}
+ 	spin_lock_init(&gsm->lock);
+ 	mutex_init(&gsm->mutex);
+-	mutex_init(&gsm->tx_mutex);
+ 	kref_init(&gsm->ref);
+ 	INIT_LIST_HEAD(&gsm->tx_ctrl_list);
+ 	INIT_LIST_HEAD(&gsm->tx_data_list);
+-	INIT_DELAYED_WORK(&gsm->kick_timeout, gsm_kick_timeout);
++	timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+ 	timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
+ 	INIT_WORK(&gsm->tx_work, gsmld_write_task);
+ 	init_waitqueue_head(&gsm->event);
+ 	spin_lock_init(&gsm->control_lock);
++	spin_lock_init(&gsm->tx_lock);
+ 
+ 	gsm->t1 = T1;
+ 	gsm->t2 = T2;
+@@ -2632,7 +2635,6 @@ static struct gsm_mux *gsm_alloc_mux(void)
+ 	}
+ 	spin_unlock(&gsm_mux_lock);
+ 	if (i == MAX_MUX) {
+-		mutex_destroy(&gsm->tx_mutex);
+ 		mutex_destroy(&gsm->mutex);
+ 		kfree(gsm->txframe);
+ 		kfree(gsm->buf);
+@@ -2788,16 +2790,17 @@ static void gsmld_write_trigger(struct gsm_mux *gsm)
+ static void gsmld_write_task(struct work_struct *work)
+ {
+ 	struct gsm_mux *gsm = container_of(work, struct gsm_mux, tx_work);
++	unsigned long flags;
+ 	int i, ret;
+ 
+ 	/* All outstanding control channel and control messages and one data
+ 	 * frame is sent.
+ 	 */
+ 	ret = -ENODEV;
+-	mutex_lock(&gsm->tx_mutex);
++	spin_lock_irqsave(&gsm->tx_lock, flags);
+ 	if (gsm->tty)
+ 		ret = gsm_data_kick(gsm);
+-	mutex_unlock(&gsm->tx_mutex);
++	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ 
+ 	if (ret >= 0)
+ 		for (i = 0; i < NUM_DLCI; i++)
+@@ -3005,6 +3008,7 @@ static ssize_t gsmld_write(struct tty_struct *tty, struct file *file,
+ 			   const unsigned char *buf, size_t nr)
+ {
+ 	struct gsm_mux *gsm = tty->disc_data;
++	unsigned long flags;
+ 	int space;
+ 	int ret;
+ 
+@@ -3012,13 +3016,13 @@ static ssize_t gsmld_write(struct tty_struct *tty, struct file *file,
+ 		return -ENODEV;
+ 
+ 	ret = -ENOBUFS;
+-	mutex_lock(&gsm->tx_mutex);
++	spin_lock_irqsave(&gsm->tx_lock, flags);
+ 	space = tty_write_room(tty);
+ 	if (space >= nr)
+ 		ret = tty->ops->write(tty, buf, nr);
+ 	else
+ 		set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+-	mutex_unlock(&gsm->tx_mutex);
++	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ 
+ 	return ret;
+ }
+@@ -3315,13 +3319,14 @@ static struct tty_ldisc_ops tty_ldisc_packet = {
+ static void gsm_modem_upd_via_data(struct gsm_dlci *dlci, u8 brk)
+ {
+ 	struct gsm_mux *gsm = dlci->gsm;
++	unsigned long flags;
+ 
+ 	if (dlci->state != DLCI_OPEN || dlci->adaption != 2)
+ 		return;
+ 
+-	mutex_lock(&gsm->tx_mutex);
++	spin_lock_irqsave(&gsm->tx_lock, flags);
+ 	gsm_dlci_modem_output(gsm, dlci, brk);
+-	mutex_unlock(&gsm->tx_mutex);
++	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ }
+ 
+ /**
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
+index b96fbf8d31df7..2ad735dd6c05d 100644
+--- a/drivers/tty/serial/8250/8250_omap.c
++++ b/drivers/tty/serial/8250/8250_omap.c
+@@ -293,6 +293,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+ {
+ 	struct omap8250_priv *priv = up->port.private_data;
+ 	struct uart_8250_dma	*dma = up->dma;
++	u8 mcr = serial8250_in_MCR(up);
+ 
+ 	if (dma && dma->tx_running) {
+ 		/*
+@@ -309,7 +310,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+ 	serial_out(up, UART_EFR, UART_EFR_ECB);
+ 
+ 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
+-	serial8250_out_MCR(up, UART_MCR_TCRTLR);
++	serial8250_out_MCR(up, mcr | UART_MCR_TCRTLR);
+ 	serial_out(up, UART_FCR, up->fcr);
+ 
+ 	omap8250_update_scr(up, priv);
+@@ -325,7 +326,8 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+ 	serial_out(up, UART_LCR, 0);
+ 
+ 	/* drop TCR + TLR access, we setup XON/XOFF later */
+-	serial8250_out_MCR(up, up->mcr);
++	serial8250_out_MCR(up, mcr);
++
+ 	serial_out(up, UART_IER, up->ier);
+ 
+ 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+@@ -670,7 +672,6 @@ static int omap_8250_startup(struct uart_port *port)
+ 
+ 	pm_runtime_get_sync(port->dev);
+ 
+-	up->mcr = 0;
+ 	serial_out(up, UART_FCR, UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+ 
+ 	serial_out(up, UART_LCR, UART_LCR_WLEN8);
+diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c
+index c67715f6f756d..f9aa50ff14d42 100644
+--- a/drivers/usb/cdns3/cdnsp-gadget.c
++++ b/drivers/usb/cdns3/cdnsp-gadget.c
+@@ -600,11 +600,11 @@ int cdnsp_halt_endpoint(struct cdnsp_device *pdev,
+ 
+ 	trace_cdnsp_ep_halt(value ? "Set" : "Clear");
+ 
+-	if (value) {
+-		ret = cdnsp_cmd_stop_ep(pdev, pep);
+-		if (ret)
+-			return ret;
++	ret = cdnsp_cmd_stop_ep(pdev, pep);
++	if (ret)
++		return ret;
+ 
++	if (value) {
+ 		if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_STOPPED) {
+ 			cdnsp_queue_halt_endpoint(pdev, pep->idx);
+ 			cdnsp_ring_cmd_db(pdev);
+@@ -613,10 +613,6 @@ int cdnsp_halt_endpoint(struct cdnsp_device *pdev,
+ 
+ 		pep->ep_state |= EP_HALTED;
+ 	} else {
+-		/*
+-		 * In device mode driver can call reset endpoint command
+-		 * from any endpoint state.
+-		 */
+ 		cdnsp_queue_reset_ep(pdev, pep->idx);
+ 		cdnsp_ring_cmd_db(pdev);
+ 		ret = cdnsp_wait_for_cmd_compl(pdev);
+diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c
+index 794e413800ae8..2f29431f612e0 100644
+--- a/drivers/usb/cdns3/cdnsp-ring.c
++++ b/drivers/usb/cdns3/cdnsp-ring.c
+@@ -1763,10 +1763,15 @@ static u32 cdnsp_td_remainder(struct cdnsp_device *pdev,
+ 			      int trb_buff_len,
+ 			      unsigned int td_total_len,
+ 			      struct cdnsp_request *preq,
+-			      bool more_trbs_coming)
++			      bool more_trbs_coming,
++			      bool zlp)
+ {
+ 	u32 maxp, total_packet_count;
+ 
++	/* Before ZLP driver needs set TD_SIZE = 1. */
++	if (zlp)
++		return 1;
++
+ 	/* One TRB with a zero-length data packet. */
+ 	if (!more_trbs_coming || (transferred == 0 && trb_buff_len == 0) ||
+ 	    trb_buff_len == td_total_len)
+@@ -1960,7 +1965,8 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+ 		/* Set the TRB length, TD size, and interrupter fields. */
+ 		remainder = cdnsp_td_remainder(pdev, enqd_len, trb_buff_len,
+ 					       full_len, preq,
+-					       more_trbs_coming);
++					       more_trbs_coming,
++					       zero_len_trb);
+ 
+ 		length_field = TRB_LEN(trb_buff_len) | TRB_TD_SIZE(remainder) |
+ 			TRB_INTR_TARGET(0);
+@@ -2025,7 +2031,7 @@ int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
+ 
+ 	if (preq->request.length > 0) {
+ 		remainder = cdnsp_td_remainder(pdev, 0, preq->request.length,
+-					       preq->request.length, preq, 1);
++					       preq->request.length, preq, 1, 0);
+ 
+ 		length_field = TRB_LEN(preq->request.length) |
+ 				TRB_TD_SIZE(remainder) | TRB_INTR_TARGET(0);
+@@ -2076,7 +2082,8 @@ int cdnsp_cmd_stop_ep(struct cdnsp_device *pdev, struct cdnsp_ep *pep)
+ 	u32 ep_state = GET_EP_CTX_STATE(pep->out_ctx);
+ 	int ret = 0;
+ 
+-	if (ep_state == EP_STATE_STOPPED || ep_state == EP_STATE_DISABLED) {
++	if (ep_state == EP_STATE_STOPPED || ep_state == EP_STATE_DISABLED ||
++	    ep_state == EP_STATE_HALTED) {
+ 		trace_cdnsp_ep_stopped_or_disabled(pep->out_ctx);
+ 		goto ep_stopped;
+ 	}
+@@ -2225,7 +2232,7 @@ static int cdnsp_queue_isoc_tx(struct cdnsp_device *pdev,
+ 		/* Set the TRB length, TD size, & interrupter fields. */
+ 		remainder = cdnsp_td_remainder(pdev, running_total,
+ 					       trb_buff_len, td_len, preq,
+-					       more_trbs_coming);
++					       more_trbs_coming, 0);
+ 
+ 		length_field = TRB_LEN(trb_buff_len) | TRB_INTR_TARGET(0);
+ 
+diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
+index 0ecf20eeceee9..4be6a873bd071 100644
+--- a/drivers/usb/dwc3/dwc3-exynos.c
++++ b/drivers/usb/dwc3/dwc3-exynos.c
+@@ -37,15 +37,6 @@ struct dwc3_exynos {
+ 	struct regulator	*vdd10;
+ };
+ 
+-static int dwc3_exynos_remove_child(struct device *dev, void *unused)
+-{
+-	struct platform_device *pdev = to_platform_device(dev);
+-
+-	platform_device_unregister(pdev);
+-
+-	return 0;
+-}
+-
+ static int dwc3_exynos_probe(struct platform_device *pdev)
+ {
+ 	struct dwc3_exynos	*exynos;
+@@ -142,7 +133,7 @@ static int dwc3_exynos_remove(struct platform_device *pdev)
+ 	struct dwc3_exynos	*exynos = platform_get_drvdata(pdev);
+ 	int i;
+ 
+-	device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
++	of_platform_depopulate(&pdev->dev);
+ 
+ 	for (i = exynos->num_clks - 1; i >= 0; i--)
+ 		clk_disable_unprepare(exynos->clks[i]);
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 0ed9826a4c470..6f61a288073bb 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -965,7 +965,7 @@ out:
+ 	return 0;
+ }
+ 
+-static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
++static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep, int status)
+ {
+ 	struct dwc3_request		*req;
+ 
+@@ -975,19 +975,19 @@ static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
+ 	while (!list_empty(&dep->started_list)) {
+ 		req = next_request(&dep->started_list);
+ 
+-		dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
++		dwc3_gadget_giveback(dep, req, status);
+ 	}
+ 
+ 	while (!list_empty(&dep->pending_list)) {
+ 		req = next_request(&dep->pending_list);
+ 
+-		dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
++		dwc3_gadget_giveback(dep, req, status);
+ 	}
+ 
+ 	while (!list_empty(&dep->cancelled_list)) {
+ 		req = next_request(&dep->cancelled_list);
+ 
+-		dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
++		dwc3_gadget_giveback(dep, req, status);
+ 	}
+ }
+ 
+@@ -1016,18 +1016,18 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
+ 	reg &= ~DWC3_DALEPENA_EP(dep->number);
+ 	dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
+ 
++	dwc3_remove_requests(dwc, dep, -ESHUTDOWN);
++
++	dep->stream_capable = false;
++	dep->type = 0;
++	dep->flags &= DWC3_EP_TXFIFO_RESIZED;
++
+ 	/* Clear out the ep descriptors for non-ep0 */
+ 	if (dep->number > 1) {
+ 		dep->endpoint.comp_desc = NULL;
+ 		dep->endpoint.desc = NULL;
+ 	}
+ 
+-	dwc3_remove_requests(dwc, dep);
+-
+-	dep->stream_capable = false;
+-	dep->type = 0;
+-	dep->flags &= DWC3_EP_TXFIFO_RESIZED;
+-
+ 	return 0;
+ }
+ 
+@@ -2350,7 +2350,7 @@ static void dwc3_stop_active_transfers(struct dwc3 *dwc)
+ 		if (!dep)
+ 			continue;
+ 
+-		dwc3_remove_requests(dwc, dep);
++		dwc3_remove_requests(dwc, dep, -ESHUTDOWN);
+ 	}
+ }
+ 
+diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c
+index f422f9c58ba79..1ea6d2e5b2187 100644
+--- a/drivers/virt/coco/sev-guest/sev-guest.c
++++ b/drivers/virt/coco/sev-guest/sev-guest.c
+@@ -67,8 +67,27 @@ static bool is_vmpck_empty(struct snp_guest_dev *snp_dev)
+ 	return true;
+ }
+ 
++/*
++ * If an error is received from the host or AMD Secure Processor (ASP) there
++ * are two options. Either retry the exact same encrypted request or discontinue
++ * using the VMPCK.
++ *
++ * This is because in the current encryption scheme GHCB v2 uses AES-GCM to
++ * encrypt the requests. The IV for this scheme is the sequence number. GCM
++ * cannot tolerate IV reuse.
++ *
++ * The ASP FW v1.51 only increments the sequence numbers on a successful
++ * guest<->ASP back and forth and only accepts messages at its exact sequence
++ * number.
++ *
++ * So if the sequence number were to be reused the encryption scheme is
++ * vulnerable. If the sequence number were incremented for a fresh IV the ASP
++ * will reject the request.
++ */
+ static void snp_disable_vmpck(struct snp_guest_dev *snp_dev)
+ {
++	dev_alert(snp_dev->dev, "Disabling vmpck_id %d to prevent IV reuse.\n",
++		  vmpck_id);
+ 	memzero_explicit(snp_dev->vmpck, VMPCK_KEY_LEN);
+ 	snp_dev->vmpck = NULL;
+ }
+@@ -321,34 +340,71 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in
+ 	if (rc)
+ 		return rc;
+ 
+-	/* Call firmware to process the request */
++	/*
++	 * Call firmware to process the request. In this function the encrypted
++	 * message enters shared memory with the host. So after this call the
++	 * sequence number must be incremented or the VMPCK must be deleted to
++	 * prevent reuse of the IV.
++	 */
+ 	rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err);
++
++	/*
++	 * If the extended guest request fails due to having too small of a
++	 * certificate data buffer, retry the same guest request without the
++	 * extended data request in order to increment the sequence number
++	 * and thus avoid IV reuse.
++	 */
++	if (exit_code == SVM_VMGEXIT_EXT_GUEST_REQUEST &&
++	    err == SNP_GUEST_REQ_INVALID_LEN) {
++		const unsigned int certs_npages = snp_dev->input.data_npages;
++
++		exit_code = SVM_VMGEXIT_GUEST_REQUEST;
++
++		/*
++		 * If this call to the firmware succeeds, the sequence number can
++		 * be incremented allowing for continued use of the VMPCK. If
++		 * there is an error reflected in the return value, this value
++		 * is checked further down and the result will be the deletion
++		 * of the VMPCK and the error code being propagated back to the
++		 * user as an ioctl() return code.
++		 */
++		rc = snp_issue_guest_request(exit_code, &snp_dev->input, &err);
++
++		/*
++		 * Override the error to inform callers the given extended
++		 * request buffer size was too small and give the caller the
++		 * required buffer size.
++		 */
++		err = SNP_GUEST_REQ_INVALID_LEN;
++		snp_dev->input.data_npages = certs_npages;
++	}
++
+ 	if (fw_err)
+ 		*fw_err = err;
+ 
+-	if (rc)
+-		return rc;
++	if (rc) {
++		dev_alert(snp_dev->dev,
++			  "Detected error from ASP request. rc: %d, fw_err: %llu\n",
++			  rc, *fw_err);
++		goto disable_vmpck;
++	}
+ 
+-	/*
+-	 * The verify_and_dec_payload() will fail only if the hypervisor is
+-	 * actively modifying the message header or corrupting the encrypted payload.
+-	 * This hints that hypervisor is acting in a bad faith. Disable the VMPCK so that
+-	 * the key cannot be used for any communication. The key is disabled to ensure
+-	 * that AES-GCM does not use the same IV while encrypting the request payload.
+-	 */
+ 	rc = verify_and_dec_payload(snp_dev, resp_buf, resp_sz);
+ 	if (rc) {
+ 		dev_alert(snp_dev->dev,
+-			  "Detected unexpected decode failure, disabling the vmpck_id %d\n",
+-			  vmpck_id);
+-		snp_disable_vmpck(snp_dev);
+-		return rc;
++			  "Detected unexpected decode failure from ASP. rc: %d\n",
++			  rc);
++		goto disable_vmpck;
+ 	}
+ 
+ 	/* Increment to new message sequence after payload decryption was successful. */
+ 	snp_inc_msg_seqno(snp_dev);
+ 
+ 	return 0;
++
++disable_vmpck:
++	snp_disable_vmpck(snp_dev);
++	return rc;
+ }
+ 
+ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
+diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c
+index 18f0ed8b1f93b..6ebd819338ecb 100644
+--- a/drivers/xen/platform-pci.c
++++ b/drivers/xen/platform-pci.c
+@@ -144,7 +144,7 @@ static int platform_pci_probe(struct pci_dev *pdev,
+ 		if (ret) {
+ 			dev_warn(&pdev->dev, "Unable to set the evtchn callback "
+ 					 "err=%d\n", ret);
+-			goto out;
++			goto irq_out;
+ 		}
+ 	}
+ 
+@@ -152,13 +152,16 @@ static int platform_pci_probe(struct pci_dev *pdev,
+ 	grant_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes);
+ 	ret = gnttab_setup_auto_xlat_frames(grant_frames);
+ 	if (ret)
+-		goto out;
++		goto irq_out;
+ 	ret = gnttab_init();
+ 	if (ret)
+ 		goto grant_out;
+ 	return 0;
+ grant_out:
+ 	gnttab_free_auto_xlat_frames();
++irq_out:
++	if (!xen_have_vector_callback)
++		free_irq(pdev->irq, pdev);
+ out:
+ 	pci_release_region(pdev, 0);
+ mem_out:
+diff --git a/drivers/xen/xen-pciback/conf_space_capability.c b/drivers/xen/xen-pciback/conf_space_capability.c
+index 5e53b4817f167..097316a741268 100644
+--- a/drivers/xen/xen-pciback/conf_space_capability.c
++++ b/drivers/xen/xen-pciback/conf_space_capability.c
+@@ -190,13 +190,16 @@ static const struct config_field caplist_pm[] = {
+ };
+ 
+ static struct msi_msix_field_config {
+-	u16          enable_bit; /* bit for enabling MSI/MSI-X */
+-	unsigned int int_type;   /* interrupt type for exclusiveness check */
++	u16          enable_bit;   /* bit for enabling MSI/MSI-X */
++	u16          allowed_bits; /* bits allowed to be changed */
++	unsigned int int_type;     /* interrupt type for exclusiveness check */
+ } msi_field_config = {
+ 	.enable_bit	= PCI_MSI_FLAGS_ENABLE,
++	.allowed_bits	= PCI_MSI_FLAGS_ENABLE,
+ 	.int_type	= INTERRUPT_TYPE_MSI,
+ }, msix_field_config = {
+ 	.enable_bit	= PCI_MSIX_FLAGS_ENABLE,
++	.allowed_bits	= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL,
+ 	.int_type	= INTERRUPT_TYPE_MSIX,
+ };
+ 
+@@ -229,7 +232,7 @@ static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value,
+ 		return 0;
+ 
+ 	if (!dev_data->allow_interrupt_control ||
+-	    (new_value ^ old_value) & ~field_config->enable_bit)
++	    (new_value ^ old_value) & ~field_config->allowed_bits)
+ 		return PCIBIOS_SET_FAILED;
+ 
+ 	if (new_value & field_config->enable_bit) {
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index fe0cc816b4eba..4fff0067bd2a9 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3105,6 +3105,8 @@ static int btrfs_ioctl_get_subvol_info(struct inode *inode, void __user *argp)
+ 		}
+ 	}
+ 
++	btrfs_free_path(path);
++	path = NULL;
+ 	if (copy_to_user(argp, subvol_info, sizeof(*subvol_info)))
+ 		ret = -EFAULT;
+ 
+@@ -3194,6 +3196,8 @@ static int btrfs_ioctl_get_subvol_rootref(struct btrfs_root *root,
+ 	}
+ 
+ out:
++	btrfs_free_path(path);
++
+ 	if (!ret || ret == -EOVERFLOW) {
+ 		rootrefs->num_items = found;
+ 		/* update min_treeid for next search */
+@@ -3205,7 +3209,6 @@ out:
+ 	}
+ 
+ 	kfree(rootrefs);
+-	btrfs_free_path(path);
+ 
+ 	return ret;
+ }
+@@ -4231,6 +4234,8 @@ static long btrfs_ioctl_ino_to_path(struct btrfs_root *root, void __user *arg)
+ 		ipath->fspath->val[i] = rel_ptr;
+ 	}
+ 
++	btrfs_free_path(path);
++	path = NULL;
+ 	ret = copy_to_user((void __user *)(unsigned long)ipa->fspath,
+ 			   ipath->fspath, size);
+ 	if (ret) {
+@@ -4281,21 +4286,20 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_fs_info *fs_info,
+ 		size = min_t(u32, loi->size, SZ_16M);
+ 	}
+ 
+-	path = btrfs_alloc_path();
+-	if (!path) {
+-		ret = -ENOMEM;
+-		goto out;
+-	}
+-
+ 	inodes = init_data_container(size);
+ 	if (IS_ERR(inodes)) {
+ 		ret = PTR_ERR(inodes);
+-		inodes = NULL;
+-		goto out;
++		goto out_loi;
+ 	}
+ 
++	path = btrfs_alloc_path();
++	if (!path) {
++		ret = -ENOMEM;
++		goto out;
++	}
+ 	ret = iterate_inodes_from_logical(loi->logical, fs_info, path,
+ 					  inodes, ignore_offset);
++	btrfs_free_path(path);
+ 	if (ret == -EINVAL)
+ 		ret = -ENOENT;
+ 	if (ret < 0)
+@@ -4307,7 +4311,6 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_fs_info *fs_info,
+ 		ret = -EFAULT;
+ 
+ out:
+-	btrfs_free_path(path);
+ 	kvfree(inodes);
+ out_loi:
+ 	kfree(loi);
+diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
+index d5d0717fd09a3..00b97e6eb5078 100644
+--- a/fs/btrfs/sysfs.c
++++ b/fs/btrfs/sysfs.c
+@@ -2251,8 +2251,11 @@ int __init btrfs_init_sysfs(void)
+ 
+ #ifdef CONFIG_BTRFS_DEBUG
+ 	ret = sysfs_create_group(&btrfs_kset->kobj, &btrfs_debug_feature_attr_group);
+-	if (ret)
+-		goto out2;
++	if (ret) {
++		sysfs_unmerge_group(&btrfs_kset->kobj,
++				    &btrfs_static_feature_attr_group);
++		goto out_remove_group;
++	}
+ #endif
+ 
+ 	return 0;
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index 9205c4a5ca81d..11f70ba981407 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -3834,15 +3834,29 @@ static int process_dir_items_leaf(struct btrfs_trans_handle *trans,
+ 				  u64 *last_old_dentry_offset)
+ {
+ 	struct btrfs_root *log = inode->root->log_root;
+-	struct extent_buffer *src = path->nodes[0];
+-	const int nritems = btrfs_header_nritems(src);
++	struct extent_buffer *src;
++	const int nritems = btrfs_header_nritems(path->nodes[0]);
+ 	const u64 ino = btrfs_ino(inode);
+ 	bool last_found = false;
+ 	int batch_start = 0;
+ 	int batch_size = 0;
+ 	int i;
+ 
+-	for (i = path->slots[0]; i < nritems; i++) {
++	/*
++	 * We need to clone the leaf, release the read lock on it, and use the
++	 * clone before modifying the log tree. See the comment at copy_items()
++	 * about why we need to do this.
++	 */
++	src = btrfs_clone_extent_buffer(path->nodes[0]);
++	if (!src)
++		return -ENOMEM;
++
++	i = path->slots[0];
++	btrfs_release_path(path);
++	path->nodes[0] = src;
++	path->slots[0] = i;
++
++	for (; i < nritems; i++) {
+ 		struct btrfs_dir_item *di;
+ 		struct btrfs_key key;
+ 		int ret;
+@@ -4414,7 +4428,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
+ {
+ 	struct btrfs_root *log = inode->root->log_root;
+ 	struct btrfs_file_extent_item *extent;
+-	struct extent_buffer *src = src_path->nodes[0];
++	struct extent_buffer *src;
+ 	int ret = 0;
+ 	struct btrfs_key *ins_keys;
+ 	u32 *ins_sizes;
+@@ -4425,6 +4439,43 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
+ 	const bool skip_csum = (inode->flags & BTRFS_INODE_NODATASUM);
+ 	const u64 i_size = i_size_read(&inode->vfs_inode);
+ 
++	/*
++	 * To keep lockdep happy and avoid deadlocks, clone the source leaf and
++	 * use the clone. This is because otherwise we would be changing the log
++	 * tree, to insert items from the subvolume tree or insert csum items,
++	 * while holding a read lock on a leaf from the subvolume tree, which
++	 * creates a nasty lock dependency when COWing log tree nodes/leaves:
++	 *
++	 * 1) Modifying the log tree triggers an extent buffer allocation while
++	 *    holding a write lock on a parent extent buffer from the log tree.
++	 *    Allocating the pages for an extent buffer, or the extent buffer
++	 *    struct, can trigger inode eviction and finally the inode eviction
++	 *    will trigger a release/remove of a delayed node, which requires
++	 *    taking the delayed node's mutex;
++	 *
++	 * 2) Allocating a metadata extent for a log tree can trigger the async
++	 *    reclaim thread and make us wait for it to release enough space and
++	 *    unblock our reservation ticket. The reclaim thread can start
++	 *    flushing delayed items, and that in turn results in the need to
++	 *    lock delayed node mutexes and in the need to write lock extent
++	 *    buffers of a subvolume tree - all this while holding a write lock
++	 *    on the parent extent buffer in the log tree.
++	 *
++	 * So one task in scenario 1) running in parallel with another task in
++	 * scenario 2) could lead to a deadlock, one wanting to lock a delayed
++	 * node mutex while having a read lock on a leaf from the subvolume,
++	 * while the other is holding the delayed node's mutex and wants to
++	 * write lock the same subvolume leaf for flushing delayed items.
++	 */
++	src = btrfs_clone_extent_buffer(src_path->nodes[0]);
++	if (!src)
++		return -ENOMEM;
++
++	i = src_path->slots[0];
++	btrfs_release_path(src_path);
++	src_path->nodes[0] = src;
++	src_path->slots[0] = i;
++
+ 	ins_data = kmalloc(nr * sizeof(struct btrfs_key) +
+ 			   nr * sizeof(u32), GFP_NOFS);
+ 	if (!ins_data)
+diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
+index a227d27a63bfd..9ea40ddcc4251 100644
+--- a/fs/btrfs/zoned.c
++++ b/fs/btrfs/zoned.c
+@@ -134,7 +134,8 @@ static int sb_write_pointer(struct block_device *bdev, struct blk_zone *zones,
+ 			super[i] = page_address(page[i]);
+ 		}
+ 
+-		if (super[0]->generation > super[1]->generation)
++		if (btrfs_super_generation(super[0]) >
++		    btrfs_super_generation(super[1]))
+ 			sector = zones[1].start;
+ 		else
+ 			sector = zones[0].start;
+@@ -466,7 +467,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
+ 		goto out;
+ 	}
+ 
+-	zones = kcalloc(BTRFS_REPORT_NR_ZONES, sizeof(struct blk_zone), GFP_KERNEL);
++	zones = kvcalloc(BTRFS_REPORT_NR_ZONES, sizeof(struct blk_zone), GFP_KERNEL);
+ 	if (!zones) {
+ 		ret = -ENOMEM;
+ 		goto out;
+@@ -585,7 +586,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
+ 	}
+ 
+ 
+-	kfree(zones);
++	kvfree(zones);
+ 
+ 	switch (bdev_zoned_model(bdev)) {
+ 	case BLK_ZONED_HM:
+@@ -617,7 +618,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache)
+ 	return 0;
+ 
+ out:
+-	kfree(zones);
++	kvfree(zones);
+ out_free_zone_info:
+ 	btrfs_destroy_dev_zone_info(device);
+ 
+diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
+index 53cfe026b3ea5..02b5c0ac56547 100644
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -2247,7 +2247,6 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)
+ 	struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc;
+ 	struct ceph_inode_info *ci = ceph_inode(inode);
+ 	struct ceph_mds_request *req1 = NULL, *req2 = NULL;
+-	unsigned int max_sessions;
+ 	int ret, err = 0;
+ 
+ 	spin_lock(&ci->i_unsafe_lock);
+@@ -2265,28 +2264,24 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode)
+ 	}
+ 	spin_unlock(&ci->i_unsafe_lock);
+ 
+-	/*
+-	 * The mdsc->max_sessions is unlikely to be changed
+-	 * mostly, here we will retry it by reallocating the
+-	 * sessions array memory to get rid of the mdsc->mutex
+-	 * lock.
+-	 */
+-retry:
+-	max_sessions = mdsc->max_sessions;
+-
+ 	/*
+ 	 * Trigger to flush the journal logs in all the relevant MDSes
+ 	 * manually, or in the worst case we must wait at most 5 seconds
+ 	 * to wait the journal logs to be flushed by the MDSes periodically.
+ 	 */
+-	if ((req1 || req2) && likely(max_sessions)) {
+-		struct ceph_mds_session **sessions = NULL;
+-		struct ceph_mds_session *s;
++	if (req1 || req2) {
+ 		struct ceph_mds_request *req;
++		struct ceph_mds_session **sessions;
++		struct ceph_mds_session *s;
++		unsigned int max_sessions;
+ 		int i;
+ 
+-		sessions = kzalloc(max_sessions * sizeof(s), GFP_KERNEL);
++		mutex_lock(&mdsc->mutex);
++		max_sessions = mdsc->max_sessions;
++
++		sessions = kcalloc(max_sessions, sizeof(s), GFP_KERNEL);
+ 		if (!sessions) {
++			mutex_unlock(&mdsc->mutex);
+ 			err = -ENOMEM;
+ 			goto out;
+ 		}
+@@ -2298,16 +2293,6 @@ retry:
+ 				s = req->r_session;
+ 				if (!s)
+ 					continue;
+-				if (unlikely(s->s_mds >= max_sessions)) {
+-					spin_unlock(&ci->i_unsafe_lock);
+-					for (i = 0; i < max_sessions; i++) {
+-						s = sessions[i];
+-						if (s)
+-							ceph_put_mds_session(s);
+-					}
+-					kfree(sessions);
+-					goto retry;
+-				}
+ 				if (!sessions[s->s_mds]) {
+ 					s = ceph_get_mds_session(s);
+ 					sessions[s->s_mds] = s;
+@@ -2320,16 +2305,6 @@ retry:
+ 				s = req->r_session;
+ 				if (!s)
+ 					continue;
+-				if (unlikely(s->s_mds >= max_sessions)) {
+-					spin_unlock(&ci->i_unsafe_lock);
+-					for (i = 0; i < max_sessions; i++) {
+-						s = sessions[i];
+-						if (s)
+-							ceph_put_mds_session(s);
+-					}
+-					kfree(sessions);
+-					goto retry;
+-				}
+ 				if (!sessions[s->s_mds]) {
+ 					s = ceph_get_mds_session(s);
+ 					sessions[s->s_mds] = s;
+@@ -2341,11 +2316,12 @@ retry:
+ 		/* the auth MDS */
+ 		spin_lock(&ci->i_ceph_lock);
+ 		if (ci->i_auth_cap) {
+-		      s = ci->i_auth_cap->session;
+-		      if (!sessions[s->s_mds])
+-			      sessions[s->s_mds] = ceph_get_mds_session(s);
++			s = ci->i_auth_cap->session;
++			if (!sessions[s->s_mds])
++				sessions[s->s_mds] = ceph_get_mds_session(s);
+ 		}
+ 		spin_unlock(&ci->i_ceph_lock);
++		mutex_unlock(&mdsc->mutex);
+ 
+ 		/* send flush mdlog request to MDSes */
+ 		for (i = 0; i < max_sessions; i++) {
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index 6bc8be9ed2a56..ccad85feb24e8 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -1252,7 +1252,7 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
+ 	rc = filemap_write_and_wait_range(src_inode->i_mapping, off,
+ 					  off + len - 1);
+ 	if (rc)
+-		goto out;
++		goto unlock;
+ 
+ 	/* should we flush first and last page first */
+ 	truncate_inode_pages(&target_inode->i_data, 0);
+@@ -1268,6 +1268,8 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
+ 	 * that target is updated on the server
+ 	 */
+ 	CIFS_I(target_inode)->time = 0;
++
++unlock:
+ 	/* although unlocking in the reverse order from locking is not
+ 	 * strictly necessary here it is a little cleaner to be consistent
+ 	 */
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index 11cd06aa74f0a..6a85136da27ce 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -302,14 +302,14 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
+ 
+ 	/* now drop the ref to the current iface */
+ 	if (old_iface && iface) {
+-		kref_put(&old_iface->refcount, release_iface);
+ 		cifs_dbg(FYI, "replacing iface: %pIS with %pIS\n",
+ 			 &old_iface->sockaddr,
+ 			 &iface->sockaddr);
+-	} else if (old_iface) {
+ 		kref_put(&old_iface->refcount, release_iface);
++	} else if (old_iface) {
+ 		cifs_dbg(FYI, "releasing ref to iface: %pIS\n",
+ 			 &old_iface->sockaddr);
++		kref_put(&old_iface->refcount, release_iface);
+ 	} else {
+ 		WARN_ON(!iface);
+ 		cifs_dbg(FYI, "adding new iface: %pIS\n", &iface->sockaddr);
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 5235974126bd3..8378b86c1b496 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5183,6 +5183,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
+ 	 * and it is decreased till we reach start.
+ 	 */
+ again:
++	ret = 0;
+ 	if (SHIFT == SHIFT_LEFT)
+ 		iterator = &start;
+ 	else
+@@ -5226,14 +5227,21 @@ again:
+ 					ext4_ext_get_actual_len(extent);
+ 		} else {
+ 			extent = EXT_FIRST_EXTENT(path[depth].p_hdr);
+-			if (le32_to_cpu(extent->ee_block) > 0)
++			if (le32_to_cpu(extent->ee_block) > start)
+ 				*iterator = le32_to_cpu(extent->ee_block) - 1;
+-			else
+-				/* Beginning is reached, end of the loop */
++			else if (le32_to_cpu(extent->ee_block) == start)
+ 				iterator = NULL;
+-			/* Update path extent in case we need to stop */
+-			while (le32_to_cpu(extent->ee_block) < start)
++			else {
++				extent = EXT_LAST_EXTENT(path[depth].p_hdr);
++				while (le32_to_cpu(extent->ee_block) >= start)
++					extent--;
++
++				if (extent == EXT_LAST_EXTENT(path[depth].p_hdr))
++					break;
++
+ 				extent++;
++				iterator = NULL;
++			}
+ 			path[depth].p_ext = extent;
+ 		}
+ 		ret = ext4_ext_shift_path_extents(path, shift, inode,
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 443f83382b9bd..9958d40207712 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1712,18 +1712,26 @@ static int writeback_single_inode(struct inode *inode,
+ 	wb = inode_to_wb_and_lock_list(inode);
+ 	spin_lock(&inode->i_lock);
+ 	/*
+-	 * If the inode is now fully clean, then it can be safely removed from
+-	 * its writeback list (if any).  Otherwise the flusher threads are
+-	 * responsible for the writeback lists.
++	 * If the inode is freeing, its i_io_list shoudn't be updated
++	 * as it can be finally deleted at this moment.
+ 	 */
+-	if (!(inode->i_state & I_DIRTY_ALL))
+-		inode_cgwb_move_to_attached(inode, wb);
+-	else if (!(inode->i_state & I_SYNC_QUEUED)) {
+-		if ((inode->i_state & I_DIRTY))
+-			redirty_tail_locked(inode, wb);
+-		else if (inode->i_state & I_DIRTY_TIME) {
+-			inode->dirtied_when = jiffies;
+-			inode_io_list_move_locked(inode, wb, &wb->b_dirty_time);
++	if (!(inode->i_state & I_FREEING)) {
++		/*
++		 * If the inode is now fully clean, then it can be safely
++		 * removed from its writeback list (if any). Otherwise the
++		 * flusher threads are responsible for the writeback lists.
++		 */
++		if (!(inode->i_state & I_DIRTY_ALL))
++			inode_cgwb_move_to_attached(inode, wb);
++		else if (!(inode->i_state & I_SYNC_QUEUED)) {
++			if ((inode->i_state & I_DIRTY))
++				redirty_tail_locked(inode, wb);
++			else if (inode->i_state & I_DIRTY_TIME) {
++				inode->dirtied_when = jiffies;
++				inode_io_list_move_locked(inode,
++							  wb,
++							  &wb->b_dirty_time);
++			}
+ 		}
+ 	}
+ 
+diff --git a/fs/fscache/volume.c b/fs/fscache/volume.c
+index a058e0136bfeb..ab8ceddf9efad 100644
+--- a/fs/fscache/volume.c
++++ b/fs/fscache/volume.c
+@@ -203,7 +203,11 @@ static struct fscache_volume *fscache_alloc_volume(const char *volume_key,
+ 	struct fscache_volume *volume;
+ 	struct fscache_cache *cache;
+ 	size_t klen, hlen;
+-	char *key;
++	u8 *key;
++
++	klen = strlen(volume_key);
++	if (klen > NAME_MAX)
++		return NULL;
+ 
+ 	if (!coherency_data)
+ 		coherency_len = 0;
+@@ -229,7 +233,6 @@ static struct fscache_volume *fscache_alloc_volume(const char *volume_key,
+ 	/* Stick the length on the front of the key and pad it out to make
+ 	 * hashing easier.
+ 	 */
+-	klen = strlen(volume_key);
+ 	hlen = round_up(1 + klen + 1, sizeof(__le32));
+ 	key = kzalloc(hlen, GFP_KERNEL);
+ 	if (!key)
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 71bfb663aac58..89f4741728ba3 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -2963,11 +2963,9 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
+ 		.mode = mode
+ 	};
+ 	int err;
+-	bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) ||
+-			   (mode & (FALLOC_FL_PUNCH_HOLE |
+-				    FALLOC_FL_ZERO_RANGE));
+-
+-	bool block_faults = FUSE_IS_DAX(inode) && lock_inode;
++	bool block_faults = FUSE_IS_DAX(inode) &&
++		(!(mode & FALLOC_FL_KEEP_SIZE) ||
++		 (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)));
+ 
+ 	if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE |
+ 		     FALLOC_FL_ZERO_RANGE))
+@@ -2976,22 +2974,20 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
+ 	if (fm->fc->no_fallocate)
+ 		return -EOPNOTSUPP;
+ 
+-	if (lock_inode) {
+-		inode_lock(inode);
+-		if (block_faults) {
+-			filemap_invalidate_lock(inode->i_mapping);
+-			err = fuse_dax_break_layouts(inode, 0, 0);
+-			if (err)
+-				goto out;
+-		}
++	inode_lock(inode);
++	if (block_faults) {
++		filemap_invalidate_lock(inode->i_mapping);
++		err = fuse_dax_break_layouts(inode, 0, 0);
++		if (err)
++			goto out;
++	}
+ 
+-		if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) {
+-			loff_t endbyte = offset + length - 1;
++	if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_ZERO_RANGE)) {
++		loff_t endbyte = offset + length - 1;
+ 
+-			err = fuse_writeback_range(inode, offset, endbyte);
+-			if (err)
+-				goto out;
+-		}
++		err = fuse_writeback_range(inode, offset, endbyte);
++		if (err)
++			goto out;
+ 	}
+ 
+ 	if (!(mode & FALLOC_FL_KEEP_SIZE) &&
+@@ -3039,8 +3035,7 @@ out:
+ 	if (block_faults)
+ 		filemap_invalidate_unlock(inode->i_mapping);
+ 
+-	if (lock_inode)
+-		inode_unlock(inode);
++	inode_unlock(inode);
+ 
+ 	fuse_flush_time_update(inode);
+ 
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index fc17b0ac87297..f3cd614e1f1e9 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -847,10 +847,11 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
+ 	struct svc_rqst *rqstp = sd->u.data;
+ 	struct page *page = buf->page;	// may be a compound one
+ 	unsigned offset = buf->offset;
++	struct page *last_page;
+ 
+-	page += offset / PAGE_SIZE;
+-	for (int i = sd->len; i > 0; i -= PAGE_SIZE)
+-		svc_rqst_replace_page(rqstp, page++);
++	last_page = page + (offset + sd->len - 1) / PAGE_SIZE;
++	for (page += offset / PAGE_SIZE; page <= last_page; page++)
++		svc_rqst_replace_page(rqstp, page);
+ 	if (rqstp->rq_res.page_len == 0)	// first call
+ 		rqstp->rq_res.page_base = offset % PAGE_SIZE;
+ 	rqstp->rq_res.page_len += sd->len;
+diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
+index 77ff8e95421fa..dc359b56fdfac 100644
+--- a/fs/nilfs2/sufile.c
++++ b/fs/nilfs2/sufile.c
+@@ -495,14 +495,22 @@ void nilfs_sufile_do_free(struct inode *sufile, __u64 segnum,
+ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
+ {
+ 	struct buffer_head *bh;
++	void *kaddr;
++	struct nilfs_segment_usage *su;
+ 	int ret;
+ 
++	down_write(&NILFS_MDT(sufile)->mi_sem);
+ 	ret = nilfs_sufile_get_segment_usage_block(sufile, segnum, 0, &bh);
+ 	if (!ret) {
+ 		mark_buffer_dirty(bh);
+ 		nilfs_mdt_mark_dirty(sufile);
++		kaddr = kmap_atomic(bh->b_page);
++		su = nilfs_sufile_block_get_segment_usage(sufile, segnum, bh, kaddr);
++		nilfs_segment_usage_set_dirty(su);
++		kunmap_atomic(kaddr);
+ 		brelse(bh);
+ 	}
++	up_write(&NILFS_MDT(sufile)->mi_sem);
+ 	return ret;
+ }
+ 
+diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c
+index 860f0b1032c65..2c53fbb8d918e 100644
+--- a/fs/zonefs/super.c
++++ b/fs/zonefs/super.c
+@@ -40,6 +40,13 @@ static void zonefs_account_active(struct inode *inode)
+ 	if (zi->i_ztype != ZONEFS_ZTYPE_SEQ)
+ 		return;
+ 
++	/*
++	 * For zones that transitioned to the offline or readonly condition,
++	 * we only need to clear the active state.
++	 */
++	if (zi->i_flags & (ZONEFS_ZONE_OFFLINE | ZONEFS_ZONE_READONLY))
++		goto out;
++
+ 	/*
+ 	 * If the zone is active, that is, if it is explicitly open or
+ 	 * partially written, check if it was already accounted as active.
+@@ -53,6 +60,7 @@ static void zonefs_account_active(struct inode *inode)
+ 		return;
+ 	}
+ 
++out:
+ 	/* The zone is not active. If it was, update the active count */
+ 	if (zi->i_flags & ZONEFS_ZONE_ACTIVE) {
+ 		zi->i_flags &= ~ZONEFS_ZONE_ACTIVE;
+@@ -324,6 +332,7 @@ static loff_t zonefs_check_zone_condition(struct inode *inode,
+ 		inode->i_flags |= S_IMMUTABLE;
+ 		inode->i_mode &= ~0777;
+ 		zone->wp = zone->start;
++		zi->i_flags |= ZONEFS_ZONE_OFFLINE;
+ 		return 0;
+ 	case BLK_ZONE_COND_READONLY:
+ 		/*
+@@ -342,8 +351,10 @@ static loff_t zonefs_check_zone_condition(struct inode *inode,
+ 			zone->cond = BLK_ZONE_COND_OFFLINE;
+ 			inode->i_mode &= ~0777;
+ 			zone->wp = zone->start;
++			zi->i_flags |= ZONEFS_ZONE_OFFLINE;
+ 			return 0;
+ 		}
++		zi->i_flags |= ZONEFS_ZONE_READONLY;
+ 		inode->i_mode &= ~0222;
+ 		return i_size_read(inode);
+ 	case BLK_ZONE_COND_FULL:
+@@ -478,14 +489,22 @@ static void __zonefs_io_error(struct inode *inode, bool write)
+ 	struct super_block *sb = inode->i_sb;
+ 	struct zonefs_sb_info *sbi = ZONEFS_SB(sb);
+ 	unsigned int noio_flag;
+-	unsigned int nr_zones =
+-		zi->i_zone_size >> (sbi->s_zone_sectors_shift + SECTOR_SHIFT);
++	unsigned int nr_zones = 1;
+ 	struct zonefs_ioerr_data err = {
+ 		.inode = inode,
+ 		.write = write,
+ 	};
+ 	int ret;
+ 
++	/*
++	 * The only files that have more than one zone are conventional zone
++	 * files with aggregated conventional zones, for which the inode zone
++	 * size is always larger than the device zone size.
++	 */
++	if (zi->i_zone_size > bdev_zone_sectors(sb->s_bdev))
++		nr_zones = zi->i_zone_size >>
++			(sbi->s_zone_sectors_shift + SECTOR_SHIFT);
++
+ 	/*
+ 	 * Memory allocations in blkdev_report_zones() can trigger a memory
+ 	 * reclaim which may in turn cause a recursion into zonefs as well as
+@@ -1407,6 +1426,14 @@ static int zonefs_init_file_inode(struct inode *inode, struct blk_zone *zone,
+ 	zi->i_ztype = type;
+ 	zi->i_zsector = zone->start;
+ 	zi->i_zone_size = zone->len << SECTOR_SHIFT;
++	if (zi->i_zone_size > bdev_zone_sectors(sb->s_bdev) << SECTOR_SHIFT &&
++	    !(sbi->s_features & ZONEFS_F_AGGRCNV)) {
++		zonefs_err(sb,
++			   "zone size %llu doesn't match device's zone sectors %llu\n",
++			   zi->i_zone_size,
++			   bdev_zone_sectors(sb->s_bdev) << SECTOR_SHIFT);
++		return -EINVAL;
++	}
+ 
+ 	zi->i_max_size = min_t(loff_t, MAX_LFS_FILESIZE,
+ 			       zone->capacity << SECTOR_SHIFT);
+@@ -1456,11 +1483,11 @@ static struct dentry *zonefs_create_inode(struct dentry *parent,
+ 	struct inode *dir = d_inode(parent);
+ 	struct dentry *dentry;
+ 	struct inode *inode;
+-	int ret;
++	int ret = -ENOMEM;
+ 
+ 	dentry = d_alloc_name(parent, name);
+ 	if (!dentry)
+-		return NULL;
++		return ERR_PTR(ret);
+ 
+ 	inode = new_inode(parent->d_sb);
+ 	if (!inode)
+@@ -1485,7 +1512,7 @@ static struct dentry *zonefs_create_inode(struct dentry *parent,
+ dput:
+ 	dput(dentry);
+ 
+-	return NULL;
++	return ERR_PTR(ret);
+ }
+ 
+ struct zonefs_zone_data {
+@@ -1505,7 +1532,7 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd,
+ 	struct blk_zone *zone, *next, *end;
+ 	const char *zgroup_name;
+ 	char *file_name;
+-	struct dentry *dir;
++	struct dentry *dir, *dent;
+ 	unsigned int n = 0;
+ 	int ret;
+ 
+@@ -1523,8 +1550,8 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd,
+ 		zgroup_name = "seq";
+ 
+ 	dir = zonefs_create_inode(sb->s_root, zgroup_name, NULL, type);
+-	if (!dir) {
+-		ret = -ENOMEM;
++	if (IS_ERR(dir)) {
++		ret = PTR_ERR(dir);
+ 		goto free;
+ 	}
+ 
+@@ -1570,8 +1597,9 @@ static int zonefs_create_zgroup(struct zonefs_zone_data *zd,
+ 		 * Use the file number within its group as file name.
+ 		 */
+ 		snprintf(file_name, ZONEFS_NAME_MAX - 1, "%u", n);
+-		if (!zonefs_create_inode(dir, file_name, zone, type)) {
+-			ret = -ENOMEM;
++		dent = zonefs_create_inode(dir, file_name, zone, type);
++		if (IS_ERR(dent)) {
++			ret = PTR_ERR(dent);
+ 			goto free;
+ 		}
+ 
+@@ -1905,18 +1933,18 @@ static int __init zonefs_init(void)
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = register_filesystem(&zonefs_type);
++	ret = zonefs_sysfs_init();
+ 	if (ret)
+ 		goto destroy_inodecache;
+ 
+-	ret = zonefs_sysfs_init();
++	ret = register_filesystem(&zonefs_type);
+ 	if (ret)
+-		goto unregister_fs;
++		goto sysfs_exit;
+ 
+ 	return 0;
+ 
+-unregister_fs:
+-	unregister_filesystem(&zonefs_type);
++sysfs_exit:
++	zonefs_sysfs_exit();
+ destroy_inodecache:
+ 	zonefs_destroy_inodecache();
+ 
+@@ -1925,9 +1953,9 @@ destroy_inodecache:
+ 
+ static void __exit zonefs_exit(void)
+ {
++	unregister_filesystem(&zonefs_type);
+ 	zonefs_sysfs_exit();
+ 	zonefs_destroy_inodecache();
+-	unregister_filesystem(&zonefs_type);
+ }
+ 
+ MODULE_AUTHOR("Damien Le Moal");
+diff --git a/fs/zonefs/zonefs.h b/fs/zonefs/zonefs.h
+index 4b3de66c32334..1dbe78119ff16 100644
+--- a/fs/zonefs/zonefs.h
++++ b/fs/zonefs/zonefs.h
+@@ -39,8 +39,10 @@ static inline enum zonefs_ztype zonefs_zone_type(struct blk_zone *zone)
+ 	return ZONEFS_ZTYPE_SEQ;
+ }
+ 
+-#define ZONEFS_ZONE_OPEN	(1 << 0)
+-#define ZONEFS_ZONE_ACTIVE	(1 << 1)
++#define ZONEFS_ZONE_OPEN	(1U << 0)
++#define ZONEFS_ZONE_ACTIVE	(1U << 1)
++#define ZONEFS_ZONE_OFFLINE	(1U << 2)
++#define ZONEFS_ZONE_READONLY	(1U << 3)
+ 
+ /*
+  * In-memory inode data.
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 79624711fda7c..e6bf06dc07704 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -946,7 +946,6 @@ extern void blk_queue_io_min(struct request_queue *q, unsigned int min);
+ extern void blk_limits_io_opt(struct queue_limits *limits, unsigned int opt);
+ extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt);
+ extern void blk_set_queue_depth(struct request_queue *q, unsigned int depth);
+-extern void blk_set_default_limits(struct queue_limits *lim);
+ extern void blk_set_stacking_limits(struct queue_limits *lim);
+ extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+ 			    sector_t offset);
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 73662fbabd78f..e811e2f99a617 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -27,6 +27,7 @@
+ #include <linux/bpfptr.h>
+ #include <linux/btf.h>
+ #include <linux/rcupdate_trace.h>
++#include <linux/static_call.h>
+ 
+ struct bpf_verifier_env;
+ struct bpf_verifier_log;
+@@ -894,6 +895,10 @@ struct bpf_dispatcher {
+ 	void *rw_image;
+ 	u32 image_off;
+ 	struct bpf_ksym ksym;
++#ifdef CONFIG_HAVE_STATIC_CALL
++	struct static_call_key *sc_key;
++	void *sc_tramp;
++#endif
+ };
+ 
+ static __always_inline __nocfi unsigned int bpf_dispatcher_nop_func(
+@@ -911,6 +916,34 @@ struct bpf_trampoline *bpf_trampoline_get(u64 key,
+ 					  struct bpf_attach_target_info *tgt_info);
+ void bpf_trampoline_put(struct bpf_trampoline *tr);
+ int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs);
++
++/*
++ * When the architecture supports STATIC_CALL replace the bpf_dispatcher_fn
++ * indirection with a direct call to the bpf program. If the architecture does
++ * not have STATIC_CALL, avoid a double-indirection.
++ */
++#ifdef CONFIG_HAVE_STATIC_CALL
++
++#define __BPF_DISPATCHER_SC_INIT(_name)				\
++	.sc_key = &STATIC_CALL_KEY(_name),			\
++	.sc_tramp = STATIC_CALL_TRAMP_ADDR(_name),
++
++#define __BPF_DISPATCHER_SC(name)				\
++	DEFINE_STATIC_CALL(bpf_dispatcher_##name##_call, bpf_dispatcher_nop_func)
++
++#define __BPF_DISPATCHER_CALL(name)				\
++	static_call(bpf_dispatcher_##name##_call)(ctx, insnsi, bpf_func)
++
++#define __BPF_DISPATCHER_UPDATE(_d, _new)			\
++	__static_call_update((_d)->sc_key, (_d)->sc_tramp, (_new))
++
++#else
++#define __BPF_DISPATCHER_SC_INIT(name)
++#define __BPF_DISPATCHER_SC(name)
++#define __BPF_DISPATCHER_CALL(name)		bpf_func(ctx, insnsi)
++#define __BPF_DISPATCHER_UPDATE(_d, _new)
++#endif
++
+ #define BPF_DISPATCHER_INIT(_name) {				\
+ 	.mutex = __MUTEX_INITIALIZER(_name.mutex),		\
+ 	.func = &_name##_func,					\
+@@ -922,25 +955,29 @@ int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_func
+ 		.name  = #_name,				\
+ 		.lnode = LIST_HEAD_INIT(_name.ksym.lnode),	\
+ 	},							\
++	__BPF_DISPATCHER_SC_INIT(_name##_call)			\
+ }
+ 
+ #define DEFINE_BPF_DISPATCHER(name)					\
++	__BPF_DISPATCHER_SC(name);					\
+ 	noinline __nocfi unsigned int bpf_dispatcher_##name##_func(	\
+ 		const void *ctx,					\
+ 		const struct bpf_insn *insnsi,				\
+ 		bpf_func_t bpf_func)					\
+ 	{								\
+-		return bpf_func(ctx, insnsi);				\
++		return __BPF_DISPATCHER_CALL(name);			\
+ 	}								\
+ 	EXPORT_SYMBOL(bpf_dispatcher_##name##_func);			\
+ 	struct bpf_dispatcher bpf_dispatcher_##name =			\
+ 		BPF_DISPATCHER_INIT(bpf_dispatcher_##name);
++
+ #define DECLARE_BPF_DISPATCHER(name)					\
+ 	unsigned int bpf_dispatcher_##name##_func(			\
+ 		const void *ctx,					\
+ 		const struct bpf_insn *insnsi,				\
+ 		bpf_func_t bpf_func);					\
+ 	extern struct bpf_dispatcher bpf_dispatcher_##name;
++
+ #define BPF_DISPATCHER_FUNC(name) bpf_dispatcher_##name##_func
+ #define BPF_DISPATCHER_PTR(name) (&bpf_dispatcher_##name)
+ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
+diff --git a/include/linux/fault-inject.h b/include/linux/fault-inject.h
+index 9f6e25467844a..444236dadcf08 100644
+--- a/include/linux/fault-inject.h
++++ b/include/linux/fault-inject.h
+@@ -20,7 +20,6 @@ struct fault_attr {
+ 	atomic_t space;
+ 	unsigned long verbose;
+ 	bool task_filter;
+-	bool no_warn;
+ 	unsigned long stacktrace_depth;
+ 	unsigned long require_start;
+ 	unsigned long require_end;
+@@ -32,6 +31,10 @@ struct fault_attr {
+ 	struct dentry *dname;
+ };
+ 
++enum fault_flags {
++	FAULT_NOWARN =	1 << 0,
++};
++
+ #define FAULT_ATTR_INITIALIZER {					\
+ 		.interval = 1,						\
+ 		.times = ATOMIC_INIT(1),				\
+@@ -40,11 +43,11 @@ struct fault_attr {
+ 		.ratelimit_state = RATELIMIT_STATE_INIT_DISABLED,	\
+ 		.verbose = 2,						\
+ 		.dname = NULL,						\
+-		.no_warn = false,					\
+ 	}
+ 
+ #define DECLARE_FAULT_ATTR(name) struct fault_attr name = FAULT_ATTR_INITIALIZER
+ int setup_fault_attr(struct fault_attr *attr, char *str);
++bool should_fail_ex(struct fault_attr *attr, ssize_t size, int flags);
+ bool should_fail(struct fault_attr *attr, ssize_t size);
+ 
+ #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+diff --git a/include/linux/fscache.h b/include/linux/fscache.h
+index 36e5dd84cf599..8e312c8323a8e 100644
+--- a/include/linux/fscache.h
++++ b/include/linux/fscache.h
+@@ -75,7 +75,7 @@ struct fscache_volume {
+ 	atomic_t			n_accesses;	/* Number of cache accesses in progress */
+ 	unsigned int			debug_id;
+ 	unsigned int			key_hash;	/* Hash of key string */
+-	char				*key;		/* Volume ID, eg. "afs@example.com@1234" */
++	u8				*key;		/* Volume ID, eg. "afs@example.com@1234" */
+ 	struct list_head		proc_link;	/* Link in /proc/fs/fscache/volumes */
+ 	struct hlist_bl_node		hash_link;	/* Link in hash table */
+ 	struct work_struct		work;
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index 454dab40baf69..2d56cfe0911d7 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -984,6 +984,7 @@ struct mlx5_async_work {
+ 	struct mlx5_async_ctx *ctx;
+ 	mlx5_async_cbk_t user_callback;
+ 	u16 opcode; /* cmd opcode */
++	u16 op_mod; /* cmd op_mod */
+ 	void *out; /* pointer to the cmd output buffer */
+ };
+ 
+diff --git a/include/net/neighbour.h b/include/net/neighbour.h
+index 3827a6b395fdb..bce6b228cf56e 100644
+--- a/include/net/neighbour.h
++++ b/include/net/neighbour.h
+@@ -83,7 +83,7 @@ struct neigh_parms {
+ 	struct rcu_head rcu_head;
+ 
+ 	int	reachable_time;
+-	int	qlen;
++	u32	qlen;
+ 	int	data[NEIGH_VAR_DATA_MAX];
+ 	DECLARE_BITMAP(data_state, NEIGH_VAR_DATA_MAX);
+ };
+diff --git a/include/sound/sof/info.h b/include/sound/sof/info.h
+index 65e86e4e9fd8e..75193850ead0c 100644
+--- a/include/sound/sof/info.h
++++ b/include/sound/sof/info.h
+@@ -36,6 +36,10 @@ enum sof_ipc_ext_data {
+ 	SOF_IPC_EXT_USER_ABI_INFO	= 4,
+ };
+ 
++/* Build u32 number in format MMmmmppp */
++#define SOF_FW_VER(MAJOR, MINOR, PATCH) ((uint32_t)( \
++	((MAJOR) << 24) | ((MINOR) << 12) | (PATCH)))
++
+ /* FW version - SOF_IPC_GLB_VERSION */
+ struct sof_ipc_fw_version {
+ 	struct sof_ipc_hdr hdr;
+diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
+index 7c1dc818b1d56..d676ed2b246ec 100644
+--- a/include/uapi/linux/audit.h
++++ b/include/uapi/linux/audit.h
+@@ -187,7 +187,7 @@
+ #define AUDIT_MAX_KEY_LEN  256
+ #define AUDIT_BITMASK_SIZE 64
+ #define AUDIT_WORD(nr) ((__u32)((nr)/32))
+-#define AUDIT_BIT(nr)  (1 << ((nr) - AUDIT_WORD(nr)*32))
++#define AUDIT_BIT(nr)  (1U << ((nr) - AUDIT_WORD(nr)*32))
+ 
+ #define AUDIT_SYSCALL_CLASSES 16
+ #define AUDIT_CLASS_DIR_WRITE 0
+diff --git a/init/Kconfig b/init/Kconfig
+index 532362fcfe31f..d1d779d6ba430 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -76,7 +76,7 @@ config CC_HAS_ASM_GOTO_OUTPUT
+ config CC_HAS_ASM_GOTO_TIED_OUTPUT
+ 	depends on CC_HAS_ASM_GOTO_OUTPUT
+ 	# Detect buggy gcc and clang, fixed in gcc-11 clang-14.
+-	def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .\n": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null)
++	def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null)
+ 
+ config TOOLS_SUPPORT_RELR
+ 	def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh)
+diff --git a/io_uring/filetable.c b/io_uring/filetable.c
+index 7b473259f3f45..68dfc6936aa72 100644
+--- a/io_uring/filetable.c
++++ b/io_uring/filetable.c
+@@ -101,8 +101,6 @@ static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file,
+ err:
+ 	if (needs_switch)
+ 		io_rsrc_node_switch(ctx, ctx->file_data);
+-	if (ret)
+-		fput(file);
+ 	return ret;
+ }
+ 
+diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
+index 1b552d2137635..585f97b31a93d 100644
+--- a/io_uring/io_uring.h
++++ b/io_uring/io_uring.h
+@@ -229,9 +229,14 @@ static inline unsigned int io_sqring_entries(struct io_ring_ctx *ctx)
+ 
+ static inline bool io_run_task_work(void)
+ {
++	/*
++	 * Always check-and-clear the task_work notification signal. With how
++	 * signaling works for task_work, we can find it set with nothing to
++	 * run. We need to clear it for that case, like get_signal() does.
++	 */
++	if (test_thread_flag(TIF_NOTIFY_SIGNAL))
++		clear_notify_signal();
+ 	if (task_work_pending(current)) {
+-		if (test_thread_flag(TIF_NOTIFY_SIGNAL))
+-			clear_notify_signal();
+ 		__set_current_state(TASK_RUNNING);
+ 		task_work_run();
+ 		return 1;
+diff --git a/io_uring/poll.c b/io_uring/poll.c
+index ba0f684669306..d9bf1767867e6 100644
+--- a/io_uring/poll.c
++++ b/io_uring/poll.c
+@@ -40,7 +40,14 @@ struct io_poll_table {
+ };
+ 
+ #define IO_POLL_CANCEL_FLAG	BIT(31)
+-#define IO_POLL_REF_MASK	GENMASK(30, 0)
++#define IO_POLL_RETRY_FLAG	BIT(30)
++#define IO_POLL_REF_MASK	GENMASK(29, 0)
++
++/*
++ * We usually have 1-2 refs taken, 128 is more than enough and we want to
++ * maximise the margin between this amount and the moment when it overflows.
++ */
++#define IO_POLL_REF_BIAS	128
+ 
+ #define IO_WQE_F_DOUBLE		1
+ 
+@@ -58,6 +65,21 @@ static inline bool wqe_is_double(struct wait_queue_entry *wqe)
+ 	return priv & IO_WQE_F_DOUBLE;
+ }
+ 
++static bool io_poll_get_ownership_slowpath(struct io_kiocb *req)
++{
++	int v;
++
++	/*
++	 * poll_refs are already elevated and we don't have much hope for
++	 * grabbing the ownership. Instead of incrementing set a retry flag
++	 * to notify the loop that there might have been some change.
++	 */
++	v = atomic_fetch_or(IO_POLL_RETRY_FLAG, &req->poll_refs);
++	if (v & IO_POLL_REF_MASK)
++		return false;
++	return !(atomic_fetch_inc(&req->poll_refs) & IO_POLL_REF_MASK);
++}
++
+ /*
+  * If refs part of ->poll_refs (see IO_POLL_REF_MASK) is 0, it's free. We can
+  * bump it and acquire ownership. It's disallowed to modify requests while not
+@@ -66,6 +88,8 @@ static inline bool wqe_is_double(struct wait_queue_entry *wqe)
+  */
+ static inline bool io_poll_get_ownership(struct io_kiocb *req)
+ {
++	if (unlikely(atomic_read(&req->poll_refs) >= IO_POLL_REF_BIAS))
++		return io_poll_get_ownership_slowpath(req);
+ 	return !(atomic_fetch_inc(&req->poll_refs) & IO_POLL_REF_MASK);
+ }
+ 
+@@ -116,6 +140,8 @@ static void io_poll_req_insert_locked(struct io_kiocb *req)
+ 	struct io_hash_table *table = &req->ctx->cancel_table_locked;
+ 	u32 index = hash_long(req->cqe.user_data, table->hash_bits);
+ 
++	lockdep_assert_held(&req->ctx->uring_lock);
++
+ 	hlist_add_head(&req->hash_node, &table->hbs[index].list);
+ }
+ 
+@@ -233,6 +259,16 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+ 		 */
+ 		if ((v & IO_POLL_REF_MASK) != 1)
+ 			req->cqe.res = 0;
++		if (v & IO_POLL_RETRY_FLAG) {
++			req->cqe.res = 0;
++			/*
++			 * We won't find new events that came in between
++			 * vfs_poll and the ref put unless we clear the flag
++			 * in advance.
++			 */
++			atomic_andnot(IO_POLL_RETRY_FLAG, &req->poll_refs);
++			v &= ~IO_POLL_RETRY_FLAG;
++		}
+ 
+ 		/* the mask was stashed in __io_poll_execute */
+ 		if (!req->cqe.res) {
+@@ -272,7 +308,8 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+ 		 * Release all references, retry if someone tried to restart
+ 		 * task_work while we were executing it.
+ 		 */
+-	} while (atomic_sub_return(v & IO_POLL_REF_MASK, &req->poll_refs));
++	} while (atomic_sub_return(v & IO_POLL_REF_MASK, &req->poll_refs) &
++					IO_POLL_REF_MASK);
+ 
+ 	return IOU_POLL_NO_ACTION;
+ }
+@@ -516,7 +553,6 @@ static int __io_arm_poll_handler(struct io_kiocb *req,
+ 				 unsigned issue_flags)
+ {
+ 	struct io_ring_ctx *ctx = req->ctx;
+-	int v;
+ 
+ 	INIT_HLIST_NODE(&req->hash_node);
+ 	req->work.cancel_seq = atomic_read(&ctx->cancel_seq);
+@@ -584,11 +620,10 @@ static int __io_arm_poll_handler(struct io_kiocb *req,
+ 
+ 	if (ipt->owning) {
+ 		/*
+-		 * Release ownership. If someone tried to queue a tw while it was
+-		 * locked, kick it off for them.
++		 * Try to release ownership. If we see a change of state, e.g.
++		 * poll was waken up, queue up a tw, it'll deal with it.
+ 		 */
+-		v = atomic_dec_return(&req->poll_refs);
+-		if (unlikely(v & IO_POLL_REF_MASK))
++		if (atomic_cmpxchg(&req->poll_refs, 1, 0) != 1)
+ 			__io_poll_execute(req, 0);
+ 	}
+ 	return 0;
+diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
+index fa64b80b8bcab..c19719f48ce06 100644
+--- a/kernel/bpf/dispatcher.c
++++ b/kernel/bpf/dispatcher.c
+@@ -4,6 +4,7 @@
+ #include <linux/hash.h>
+ #include <linux/bpf.h>
+ #include <linux/filter.h>
++#include <linux/static_call.h>
+ 
+ /* The BPF dispatcher is a multiway branch code generator. The
+  * dispatcher is a mechanism to avoid the performance penalty of an
+@@ -104,17 +105,11 @@ static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image, void *b
+ 
+ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
+ {
+-	void *old, *new, *tmp;
+-	u32 noff;
+-	int err;
+-
+-	if (!prev_num_progs) {
+-		old = NULL;
+-		noff = 0;
+-	} else {
+-		old = d->image + d->image_off;
++	void *new, *tmp;
++	u32 noff = 0;
++
++	if (prev_num_progs)
+ 		noff = d->image_off ^ (PAGE_SIZE / 2);
+-	}
+ 
+ 	new = d->num_progs ? d->image + noff : NULL;
+ 	tmp = d->num_progs ? d->rw_image + noff : NULL;
+@@ -128,11 +123,10 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
+ 			return;
+ 	}
+ 
+-	err = bpf_arch_text_poke(d->func, BPF_MOD_JUMP, old, new);
+-	if (err || !new)
+-		return;
++	__BPF_DISPATCHER_UPDATE(d, new ?: (void *)&bpf_dispatcher_nop_func);
+ 
+-	d->image_off = noff;
++	if (new)
++		d->image_off = noff;
+ }
+ 
+ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
+diff --git a/kernel/gcov/clang.c b/kernel/gcov/clang.c
+index cbb0bed958abd..7670a811a5657 100644
+--- a/kernel/gcov/clang.c
++++ b/kernel/gcov/clang.c
+@@ -280,6 +280,8 @@ void gcov_info_add(struct gcov_info *dst, struct gcov_info *src)
+ 
+ 		for (i = 0; i < sfn_ptr->num_counters; i++)
+ 			dfn_ptr->counters[i] += sfn_ptr->counters[i];
++
++		sfn_ptr = list_next_entry(sfn_ptr, head);
+ 	}
+ }
+ 
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index cb131fad117cc..997d23641448a 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -2095,6 +2095,7 @@ config KPROBES_SANITY_TEST
+ 	depends on DEBUG_KERNEL
+ 	depends on KPROBES
+ 	depends on KUNIT
++	select STACKTRACE if ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
+ 	default KUNIT_ALL_TESTS
+ 	help
+ 	  This option provides for testing basic kprobes functionality on
+diff --git a/lib/fault-inject.c b/lib/fault-inject.c
+index 423784d9c058e..70768d8a2200b 100644
+--- a/lib/fault-inject.c
++++ b/lib/fault-inject.c
+@@ -41,9 +41,6 @@ EXPORT_SYMBOL_GPL(setup_fault_attr);
+ 
+ static void fail_dump(struct fault_attr *attr)
+ {
+-	if (attr->no_warn)
+-		return;
+-
+ 	if (attr->verbose > 0 && __ratelimit(&attr->ratelimit_state)) {
+ 		printk(KERN_NOTICE "FAULT_INJECTION: forcing a failure.\n"
+ 		       "name %pd, interval %lu, probability %lu, "
+@@ -103,7 +100,7 @@ static inline bool fail_stacktrace(struct fault_attr *attr)
+  * http://www.nongnu.org/failmalloc/
+  */
+ 
+-bool should_fail(struct fault_attr *attr, ssize_t size)
++bool should_fail_ex(struct fault_attr *attr, ssize_t size, int flags)
+ {
+ 	if (in_task()) {
+ 		unsigned int fail_nth = READ_ONCE(current->fail_nth);
+@@ -146,13 +143,19 @@ bool should_fail(struct fault_attr *attr, ssize_t size)
+ 		return false;
+ 
+ fail:
+-	fail_dump(attr);
++	if (!(flags & FAULT_NOWARN))
++		fail_dump(attr);
+ 
+ 	if (atomic_read(&attr->times) != -1)
+ 		atomic_dec_not_zero(&attr->times);
+ 
+ 	return true;
+ }
++
++bool should_fail(struct fault_attr *attr, ssize_t size)
++{
++	return should_fail_ex(attr, size, 0);
++}
+ EXPORT_SYMBOL_GPL(should_fail);
+ 
+ #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+diff --git a/lib/vdso/Makefile b/lib/vdso/Makefile
+index c415a685d61bb..e814061d6aa01 100644
+--- a/lib/vdso/Makefile
++++ b/lib/vdso/Makefile
+@@ -17,6 +17,6 @@ $(error ARCH_REL_TYPE_ABS is not set)
+ endif
+ 
+ quiet_cmd_vdso_check = VDSOCHK $@
+-      cmd_vdso_check = if $(OBJDUMP) -R $@ | egrep -h "$(ARCH_REL_TYPE_ABS)"; \
++      cmd_vdso_check = if $(OBJDUMP) -R $@ | grep -E -h "$(ARCH_REL_TYPE_ABS)"; \
+ 		       then (echo >&2 "$@: dynamic relocations are not supported"; \
+ 			     rm -f $@; /bin/false); fi
+diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c
+index bdef9682d0a00..b4b9614eecbed 100644
+--- a/mm/damon/sysfs.c
++++ b/mm/damon/sysfs.c
+@@ -2342,6 +2342,10 @@ static int damon_sysfs_upd_schemes_stats(struct damon_sysfs_kdamond *kdamond)
+ 	damon_for_each_scheme(scheme, ctx) {
+ 		struct damon_sysfs_stats *sysfs_stats;
+ 
++		/* user could have removed the scheme sysfs dir */
++		if (schemes_idx >= sysfs_schemes->nr)
++			break;
++
+ 		sysfs_stats = sysfs_schemes->schemes_arr[schemes_idx++]->stats;
+ 		sysfs_stats->nr_tried = scheme->stat.nr_tried;
+ 		sysfs_stats->sz_tried = scheme->stat.sz_tried;
+diff --git a/mm/failslab.c b/mm/failslab.c
+index 58df9789f1d22..ffc420c0e767f 100644
+--- a/mm/failslab.c
++++ b/mm/failslab.c
+@@ -16,6 +16,8 @@ static struct {
+ 
+ bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags)
+ {
++	int flags = 0;
++
+ 	/* No fault-injection for bootstrap cache */
+ 	if (unlikely(s == kmem_cache))
+ 		return false;
+@@ -30,10 +32,16 @@ bool __should_failslab(struct kmem_cache *s, gfp_t gfpflags)
+ 	if (failslab.cache_filter && !(s->flags & SLAB_FAILSLAB))
+ 		return false;
+ 
++	/*
++	 * In some cases, it expects to specify __GFP_NOWARN
++	 * to avoid printing any information(not just a warning),
++	 * thus avoiding deadlocks. See commit 6b9dbedbe349 for
++	 * details.
++	 */
+ 	if (gfpflags & __GFP_NOWARN)
+-		failslab.attr.no_warn = true;
++		flags |= FAULT_NOWARN;
+ 
+-	return should_fail(&failslab.attr, s->object_size);
++	return should_fail_ex(&failslab.attr, s->object_size, flags);
+ }
+ 
+ static int __init setup_failslab(char *str)
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index b69979c9ced5c..6a95ea7c5ee70 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -2971,7 +2971,7 @@ struct obj_cgroup *get_obj_cgroup_from_page(struct page *page)
+ {
+ 	struct obj_cgroup *objcg;
+ 
+-	if (!memcg_kmem_enabled() || memcg_kmem_bypass())
++	if (!memcg_kmem_enabled())
+ 		return NULL;
+ 
+ 	if (PageMemcgKmem(page)) {
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 19749f5409e72..5d9b98774a826 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -3883,6 +3883,8 @@ __setup("fail_page_alloc=", setup_fail_page_alloc);
+ 
+ static bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
+ {
++	int flags = 0;
++
+ 	if (order < fail_page_alloc.min_order)
+ 		return false;
+ 	if (gfp_mask & __GFP_NOFAIL)
+@@ -3893,10 +3895,11 @@ static bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
+ 			(gfp_mask & __GFP_DIRECT_RECLAIM))
+ 		return false;
+ 
++	/* See comment in __should_failslab() */
+ 	if (gfp_mask & __GFP_NOWARN)
+-		fail_page_alloc.attr.no_warn = true;
++		flags |= FAULT_NOWARN;
+ 
+-	return should_fail(&fail_page_alloc.attr, 1 << order);
++	return should_fail_ex(&fail_page_alloc.attr, 1 << order, flags);
+ }
+ 
+ #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 382dbe97329f3..a69f32dd5ce5d 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -2472,8 +2472,20 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec,
+ 	 * the flushers simply cannot keep up with the allocation
+ 	 * rate. Nudge the flusher threads in case they are asleep.
+ 	 */
+-	if (stat.nr_unqueued_dirty == nr_taken)
++	if (stat.nr_unqueued_dirty == nr_taken) {
+ 		wakeup_flusher_threads(WB_REASON_VMSCAN);
++		/*
++		 * For cgroupv1 dirty throttling is achieved by waking up
++		 * the kernel flusher here and later waiting on folios
++		 * which are in writeback to finish (see shrink_folio_list()).
++		 *
++		 * Flusher may not be able to issue writeback quickly
++		 * enough for cgroupv1 writeback throttling to work
++		 * on a large system.
++		 */
++		if (!writeback_throttling_sane(sc))
++			reclaim_throttle(pgdat, VMSCAN_THROTTLE_WRITEBACK);
++	}
+ 
+ 	sc->nr.dirty += stat.nr_dirty;
+ 	sc->nr.congested += stat.nr_congested;
+@@ -2955,8 +2967,8 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+ 	enum lru_list lru;
+ 	unsigned long nr_reclaimed = 0;
+ 	unsigned long nr_to_reclaim = sc->nr_to_reclaim;
++	bool proportional_reclaim;
+ 	struct blk_plug plug;
+-	bool scan_adjusted;
+ 
+ 	get_scan_count(lruvec, sc, nr);
+ 
+@@ -2974,8 +2986,8 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+ 	 * abort proportional reclaim if either the file or anon lru has already
+ 	 * dropped to zero at the first pass.
+ 	 */
+-	scan_adjusted = (!cgroup_reclaim(sc) && !current_is_kswapd() &&
+-			 sc->priority == DEF_PRIORITY);
++	proportional_reclaim = (!cgroup_reclaim(sc) && !current_is_kswapd() &&
++				sc->priority == DEF_PRIORITY);
+ 
+ 	blk_start_plug(&plug);
+ 	while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
+@@ -2995,7 +3007,7 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+ 
+ 		cond_resched();
+ 
+-		if (nr_reclaimed < nr_to_reclaim || scan_adjusted)
++		if (nr_reclaimed < nr_to_reclaim || proportional_reclaim)
+ 			continue;
+ 
+ 		/*
+@@ -3046,8 +3058,6 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+ 		nr_scanned = targets[lru] - nr[lru];
+ 		nr[lru] = targets[lru] * (100 - percentage) / 100;
+ 		nr[lru] -= min(nr[lru], nr_scanned);
+-
+-		scan_adjusted = true;
+ 	}
+ 	blk_finish_plug(&plug);
+ 	sc->nr_reclaimed += nr_reclaimed;
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index 0191f22d1ec35..8487321c1fc78 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -202,9 +202,11 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
+ 
+ 	list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
+ 		list_move(&req->req_list, &cancel_list);
++		req->status = REQ_STATUS_ERROR;
+ 	}
+ 	list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
+ 		list_move(&req->req_list, &cancel_list);
++		req->status = REQ_STATUS_ERROR;
+ 	}
+ 
+ 	spin_unlock(&m->req_lock);
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 7105529abb0f6..c433b1fb961ab 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -272,7 +272,7 @@ skb_flow_dissect_ct(const struct sk_buff *skb,
+ 	key->ct_zone = ct->zone.id;
+ #endif
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+-	key->ct_mark = ct->mark;
++	key->ct_mark = READ_ONCE(ct->mark);
+ #endif
+ 
+ 	cl = nf_ct_labels_find(ct);
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index 84755db81e9d9..35f5a3125808d 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -307,7 +307,31 @@ static int neigh_del_timer(struct neighbour *n)
+ 	return 0;
+ }
+ 
+-static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net)
++static struct neigh_parms *neigh_get_dev_parms_rcu(struct net_device *dev,
++						   int family)
++{
++	switch (family) {
++	case AF_INET:
++		return __in_dev_arp_parms_get_rcu(dev);
++	case AF_INET6:
++		return __in6_dev_nd_parms_get_rcu(dev);
++	}
++	return NULL;
++}
++
++static void neigh_parms_qlen_dec(struct net_device *dev, int family)
++{
++	struct neigh_parms *p;
++
++	rcu_read_lock();
++	p = neigh_get_dev_parms_rcu(dev, family);
++	if (p)
++		p->qlen--;
++	rcu_read_unlock();
++}
++
++static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net,
++			       int family)
+ {
+ 	struct sk_buff_head tmp;
+ 	unsigned long flags;
+@@ -321,13 +345,7 @@ static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net)
+ 		struct net_device *dev = skb->dev;
+ 
+ 		if (net == NULL || net_eq(dev_net(dev), net)) {
+-			struct in_device *in_dev;
+-
+-			rcu_read_lock();
+-			in_dev = __in_dev_get_rcu(dev);
+-			if (in_dev)
+-				in_dev->arp_parms->qlen--;
+-			rcu_read_unlock();
++			neigh_parms_qlen_dec(dev, family);
+ 			__skb_unlink(skb, list);
+ 			__skb_queue_tail(&tmp, skb);
+ 		}
+@@ -409,7 +427,8 @@ static int __neigh_ifdown(struct neigh_table *tbl, struct net_device *dev,
+ 	write_lock_bh(&tbl->lock);
+ 	neigh_flush_dev(tbl, dev, skip_perm);
+ 	pneigh_ifdown_and_unlock(tbl, dev);
+-	pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL);
++	pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL,
++			   tbl->family);
+ 	if (skb_queue_empty_lockless(&tbl->proxy_queue))
+ 		del_timer_sync(&tbl->proxy_timer);
+ 	return 0;
+@@ -1621,13 +1640,8 @@ static void neigh_proxy_process(struct timer_list *t)
+ 
+ 		if (tdif <= 0) {
+ 			struct net_device *dev = skb->dev;
+-			struct in_device *in_dev;
+ 
+-			rcu_read_lock();
+-			in_dev = __in_dev_get_rcu(dev);
+-			if (in_dev)
+-				in_dev->arp_parms->qlen--;
+-			rcu_read_unlock();
++			neigh_parms_qlen_dec(dev, tbl->family);
+ 			__skb_unlink(skb, &tbl->proxy_queue);
+ 
+ 			if (tbl->proxy_redo && netif_running(dev)) {
+@@ -1821,7 +1835,7 @@ int neigh_table_clear(int index, struct neigh_table *tbl)
+ 	cancel_delayed_work_sync(&tbl->managed_work);
+ 	cancel_delayed_work_sync(&tbl->gc_work);
+ 	del_timer_sync(&tbl->proxy_timer);
+-	pneigh_queue_purge(&tbl->proxy_queue, NULL);
++	pneigh_queue_purge(&tbl->proxy_queue, NULL, tbl->family);
+ 	neigh_ifdown(tbl, NULL);
+ 	if (atomic_read(&tbl->entries))
+ 		pr_crit("neighbour leakage\n");
+@@ -3542,18 +3556,6 @@ static int proc_unres_qlen(struct ctl_table *ctl, int write,
+ 	return ret;
+ }
+ 
+-static struct neigh_parms *neigh_get_dev_parms_rcu(struct net_device *dev,
+-						   int family)
+-{
+-	switch (family) {
+-	case AF_INET:
+-		return __in_dev_arp_parms_get_rcu(dev);
+-	case AF_INET6:
+-		return __in6_dev_nd_parms_get_rcu(dev);
+-	}
+-	return NULL;
+-}
+-
+ static void neigh_copy_dflt_parms(struct net *net, struct neigh_parms *p,
+ 				  int index)
+ {
+diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
+index da6e3b20cd758..60379ad7ae06d 100644
+--- a/net/dccp/ipv4.c
++++ b/net/dccp/ipv4.c
+@@ -136,6 +136,8 @@ failure:
+ 	 * This unhashes the socket and releases the local port, if necessary.
+ 	 */
+ 	dccp_set_state(sk, DCCP_CLOSED);
++	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++		inet_reset_saddr(sk);
+ 	ip_rt_put(rt);
+ 	sk->sk_route_caps = 0;
+ 	inet->inet_dport = 0;
+diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
+index fd44638ec16b8..f9ed81a0ddbb9 100644
+--- a/net/dccp/ipv6.c
++++ b/net/dccp/ipv6.c
+@@ -967,6 +967,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
+ 
+ late_failure:
+ 	dccp_set_state(sk, DCCP_CLOSED);
++	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++		inet_reset_saddr(sk);
+ 	__sk_dst_reset(sk);
+ failure:
+ 	inet->inet_dport = 0;
+diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
+index e983bb0c50127..2dfb12230f089 100644
+--- a/net/ipv4/Kconfig
++++ b/net/ipv4/Kconfig
+@@ -402,6 +402,16 @@ config INET_IPCOMP
+ 
+ 	  If unsure, say Y.
+ 
++config INET_TABLE_PERTURB_ORDER
++	int "INET: Source port perturbation table size (as power of 2)" if EXPERT
++	default 16
++	help
++	  Source port perturbation table size (as power of 2) for
++	  RFC 6056 3.3.4.  Algorithm 4: Double-Hash Port Selection Algorithm.
++
++	  The default is almost always what you want.
++	  Only change this if you know what you are doing.
++
+ config INET_XFRM_TUNNEL
+ 	tristate
+ 	select INET_TUNNEL
+diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
+index 170152772d332..3969fa805679c 100644
+--- a/net/ipv4/esp4_offload.c
++++ b/net/ipv4/esp4_offload.c
+@@ -314,6 +314,9 @@ static int esp_xmit(struct xfrm_state *x, struct sk_buff *skb,  netdev_features_
+ 			xo->seq.low += skb_shinfo(skb)->gso_segs;
+ 	}
+ 
++	if (xo->seq.low < seq)
++		xo->seq.hi++;
++
+ 	esp.seqno = cpu_to_be64(seq + ((u64)xo->seq.hi << 32));
+ 
+ 	ip_hdr(skb)->tot_len = htons(skb->len);
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index 452ff177e4da9..f26d5ac117d62 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -1381,8 +1381,10 @@ int fib_table_insert(struct net *net, struct fib_table *tb,
+ 
+ 	/* The alias was already inserted, so the node must exist. */
+ 	l = l ? l : fib_find_node(t, &tp, key);
+-	if (WARN_ON_ONCE(!l))
++	if (WARN_ON_ONCE(!l)) {
++		err = -ENOENT;
+ 		goto out_free_new_fa;
++	}
+ 
+ 	if (fib_find_alias(&l->leaf, new_fa->fa_slen, 0, 0, tb->tb_id, true) ==
+ 	    new_fa) {
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index f5950a7172d61..1e45fe6276f72 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -679,13 +679,13 @@ EXPORT_SYMBOL_GPL(inet_unhash);
+  * Note that we use 32bit integers (vs RFC 'short integers')
+  * because 2^16 is not a multiple of num_ephemeral and this
+  * property might be used by clever attacker.
++ *
+  * RFC claims using TABLE_LENGTH=10 buckets gives an improvement, though
+- * attacks were since demonstrated, thus we use 65536 instead to really
+- * give more isolation and privacy, at the expense of 256kB of kernel
+- * memory.
++ * attacks were since demonstrated, thus we use 65536 by default instead
++ * to really give more isolation and privacy, at the expense of 256kB
++ * of kernel memory.
+  */
+-#define INET_TABLE_PERTURB_SHIFT 16
+-#define INET_TABLE_PERTURB_SIZE (1 << INET_TABLE_PERTURB_SHIFT)
++#define INET_TABLE_PERTURB_SIZE (1 << CONFIG_INET_TABLE_PERTURB_ORDER)
+ static u32 *table_perturb;
+ 
+ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
+index 1b512390b3cf3..e880ce77322aa 100644
+--- a/net/ipv4/ip_input.c
++++ b/net/ipv4/ip_input.c
+@@ -366,6 +366,11 @@ static int ip_rcv_finish_core(struct net *net, struct sock *sk,
+ 					   iph->tos, dev);
+ 		if (unlikely(err))
+ 			goto drop_error;
++	} else {
++		struct in_device *in_dev = __in_dev_get_rcu(dev);
++
++		if (in_dev && IN_DEV_ORCONF(in_dev, NOPOLICY))
++			IPCB(skb)->flags |= IPSKB_NOPOLICY;
+ 	}
+ 
+ #ifdef CONFIG_IP_ROUTE_CLASSID
+diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
+index f8e176c77d1c1..b3cc416ed2923 100644
+--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
++++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
+@@ -435,7 +435,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ 
+ 	switch (ctinfo) {
+ 	case IP_CT_NEW:
+-		ct->mark = hash;
++		WRITE_ONCE(ct->mark, hash);
+ 		break;
+ 	case IP_CT_RELATED:
+ 	case IP_CT_RELATED_REPLY:
+@@ -452,7 +452,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ #ifdef DEBUG
+ 	nf_ct_dump_tuple_ip(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+ #endif
+-	pr_debug("hash=%u ct_hash=%u ", hash, ct->mark);
++	pr_debug("hash=%u ct_hash=%u ", hash, READ_ONCE(ct->mark));
+ 	if (!clusterip_responsible(cipinfo->config, hash)) {
+ 		pr_debug("not responsible\n");
+ 		return NF_DROP;
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index fe9a6022db66d..ef8013e2134fd 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -323,6 +323,8 @@ failure:
+ 	 * if necessary.
+ 	 */
+ 	tcp_set_state(sk, TCP_CLOSE);
++	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++		inet_reset_saddr(sk);
+ 	ip_rt_put(rt);
+ 	sk->sk_route_caps = 0;
+ 	inet->inet_dport = 0;
+diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
+index 79d43548279cb..242f4295940e6 100644
+--- a/net/ipv6/esp6_offload.c
++++ b/net/ipv6/esp6_offload.c
+@@ -346,6 +346,9 @@ static int esp6_xmit(struct xfrm_state *x, struct sk_buff *skb,  netdev_features
+ 			xo->seq.low += skb_shinfo(skb)->gso_segs;
+ 	}
+ 
++	if (xo->seq.low < seq)
++		xo->seq.hi++;
++
+ 	esp.seqno = cpu_to_be64(xo->seq.low + ((u64)xo->seq.hi << 32));
+ 
+ 	len = skb->len - sizeof(struct ipv6hdr);
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index e54eee80ce5f3..5516cfb96c488 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -340,6 +340,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
+ 
+ late_failure:
+ 	tcp_set_state(sk, TCP_CLOSE);
++	if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
++		inet_reset_saddr(sk);
+ failure:
+ 	inet->inet_dport = 0;
+ 	sk->sk_route_caps = 0;
+diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
+index 4a4b0e49ec92d..ea435eba30534 100644
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -287,9 +287,13 @@ int __init xfrm6_init(void)
+ 	if (ret)
+ 		goto out_state;
+ 
+-	register_pernet_subsys(&xfrm6_net_ops);
++	ret = register_pernet_subsys(&xfrm6_net_ops);
++	if (ret)
++		goto out_protocol;
+ out:
+ 	return ret;
++out_protocol:
++	xfrm6_protocol_fini();
+ out_state:
+ 	xfrm6_state_fini();
+ out_policy:
+diff --git a/net/key/af_key.c b/net/key/af_key.c
+index c85df5b958d26..95edcbedf6ef2 100644
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -2905,7 +2905,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t)
+ 			break;
+ 		if (!aalg->pfkey_supported)
+ 			continue;
+-		if (aalg_tmpl_set(t, aalg) && aalg->available)
++		if (aalg_tmpl_set(t, aalg))
+ 			sz += sizeof(struct sadb_comb);
+ 	}
+ 	return sz + sizeof(struct sadb_prop);
+@@ -2923,7 +2923,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
+ 		if (!ealg->pfkey_supported)
+ 			continue;
+ 
+-		if (!(ealg_tmpl_set(t, ealg) && ealg->available))
++		if (!(ealg_tmpl_set(t, ealg)))
+ 			continue;
+ 
+ 		for (k = 1; ; k++) {
+@@ -2934,16 +2934,17 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
+ 			if (!aalg->pfkey_supported)
+ 				continue;
+ 
+-			if (aalg_tmpl_set(t, aalg) && aalg->available)
++			if (aalg_tmpl_set(t, aalg))
+ 				sz += sizeof(struct sadb_comb);
+ 		}
+ 	}
+ 	return sz + sizeof(struct sadb_prop);
+ }
+ 
+-static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
++static int dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ {
+ 	struct sadb_prop *p;
++	int sz = 0;
+ 	int i;
+ 
+ 	p = skb_put(skb, sizeof(struct sadb_prop));
+@@ -2971,13 +2972,17 @@ static void dump_ah_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ 			c->sadb_comb_soft_addtime = 20*60*60;
+ 			c->sadb_comb_hard_usetime = 8*60*60;
+ 			c->sadb_comb_soft_usetime = 7*60*60;
++			sz += sizeof(*c);
+ 		}
+ 	}
++
++	return sz + sizeof(*p);
+ }
+ 
+-static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
++static int dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ {
+ 	struct sadb_prop *p;
++	int sz = 0;
+ 	int i, k;
+ 
+ 	p = skb_put(skb, sizeof(struct sadb_prop));
+@@ -3019,8 +3024,11 @@ static void dump_esp_combs(struct sk_buff *skb, const struct xfrm_tmpl *t)
+ 			c->sadb_comb_soft_addtime = 20*60*60;
+ 			c->sadb_comb_hard_usetime = 8*60*60;
+ 			c->sadb_comb_soft_usetime = 7*60*60;
++			sz += sizeof(*c);
+ 		}
+ 	}
++
++	return sz + sizeof(*p);
+ }
+ 
+ static int key_notify_policy_expire(struct xfrm_policy *xp, const struct km_event *c)
+@@ -3150,6 +3158,7 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
+ 	struct sadb_x_sec_ctx *sec_ctx;
+ 	struct xfrm_sec_ctx *xfrm_ctx;
+ 	int ctx_size = 0;
++	int alg_size = 0;
+ 
+ 	sockaddr_size = pfkey_sockaddr_size(x->props.family);
+ 	if (!sockaddr_size)
+@@ -3161,16 +3170,16 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
+ 		sizeof(struct sadb_x_policy);
+ 
+ 	if (x->id.proto == IPPROTO_AH)
+-		size += count_ah_combs(t);
++		alg_size = count_ah_combs(t);
+ 	else if (x->id.proto == IPPROTO_ESP)
+-		size += count_esp_combs(t);
++		alg_size = count_esp_combs(t);
+ 
+ 	if ((xfrm_ctx = x->security)) {
+ 		ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len);
+ 		size +=  sizeof(struct sadb_x_sec_ctx) + ctx_size;
+ 	}
+ 
+-	skb =  alloc_skb(size + 16, GFP_ATOMIC);
++	skb =  alloc_skb(size + alg_size + 16, GFP_ATOMIC);
+ 	if (skb == NULL)
+ 		return -ENOMEM;
+ 
+@@ -3224,10 +3233,13 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
+ 	pol->sadb_x_policy_priority = xp->priority;
+ 
+ 	/* Set sadb_comb's. */
++	alg_size = 0;
+ 	if (x->id.proto == IPPROTO_AH)
+-		dump_ah_combs(skb, t);
++		alg_size = dump_ah_combs(skb, t);
+ 	else if (x->id.proto == IPPROTO_ESP)
+-		dump_esp_combs(skb, t);
++		alg_size = dump_esp_combs(skb, t);
++
++	hdr->sadb_msg_len += alg_size / 8;
+ 
+ 	/* security context */
+ 	if (xfrm_ctx) {
+@@ -3382,7 +3394,7 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
+ 	hdr->sadb_msg_len = size / sizeof(uint64_t);
+ 	hdr->sadb_msg_errno = 0;
+ 	hdr->sadb_msg_reserved = 0;
+-	hdr->sadb_msg_seq = x->km.seq = get_acqseq();
++	hdr->sadb_msg_seq = x->km.seq;
+ 	hdr->sadb_msg_pid = 0;
+ 
+ 	/* SA */
+diff --git a/net/mac80211/main.c b/net/mac80211/main.c
+index 5b1c47ed0cc08..87e24bba4c673 100644
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -1437,8 +1437,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
+ 	ieee80211_led_exit(local);
+ 	destroy_workqueue(local->workqueue);
+  fail_workqueue:
+-	if (local->wiphy_ciphers_allocated)
++	if (local->wiphy_ciphers_allocated) {
+ 		kfree(local->hw.wiphy->cipher_suites);
++		local->wiphy_ciphers_allocated = false;
++	}
+ 	kfree(local->int_scan_req);
+ 	return result;
+ }
+@@ -1506,8 +1508,10 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
+ 	mutex_destroy(&local->iflist_mtx);
+ 	mutex_destroy(&local->mtx);
+ 
+-	if (local->wiphy_ciphers_allocated)
++	if (local->wiphy_ciphers_allocated) {
+ 		kfree(local->hw.wiphy->cipher_suites);
++		local->wiphy_ciphers_allocated = false;
++	}
+ 
+ 	idr_for_each(&local->ack_status_frames,
+ 		     ieee80211_free_ack_frame, NULL);
+diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
+index acc1c299f1ae5..69d5e1ec6edef 100644
+--- a/net/mac80211/mesh_pathtbl.c
++++ b/net/mac80211/mesh_pathtbl.c
+@@ -710,7 +710,7 @@ int mesh_path_send_to_gates(struct mesh_path *mpath)
+ void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata,
+ 			     struct sk_buff *skb)
+ {
+-	kfree_skb(skb);
++	ieee80211_free_txskb(&sdata->local->hw, skb);
+ 	sdata->u.mesh.mshstats.dropped_frames_no_route++;
+ }
+ 
+diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
+index 3adc291d9ce18..7499192af5866 100644
+--- a/net/netfilter/ipset/ip_set_hash_gen.h
++++ b/net/netfilter/ipset/ip_set_hash_gen.h
+@@ -916,7 +916,7 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
+ #ifdef IP_SET_HASH_WITH_MULTI
+ 		if (h->bucketsize >= AHASH_MAX_TUNED)
+ 			goto set_full;
+-		else if (h->bucketsize < multi)
++		else if (h->bucketsize <= multi)
+ 			h->bucketsize += AHASH_INIT_SIZE;
+ #endif
+ 		if (n->size >= AHASH_MAX(h)) {
+diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
+index dd30c03d5a23f..75d556d71652d 100644
+--- a/net/netfilter/ipset/ip_set_hash_ip.c
++++ b/net/netfilter/ipset/ip_set_hash_ip.c
+@@ -151,18 +151,16 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
+ 	if (((u64)ip_to - ip + 1) >> (32 - h->netmask) > IPSET_MAX_RANGE)
+ 		return -ERANGE;
+ 
+-	if (retried) {
++	if (retried)
+ 		ip = ntohl(h->next.ip);
+-		e.ip = htonl(ip);
+-	}
+ 	for (; ip <= ip_to;) {
++		e.ip = htonl(ip);
+ 		ret = adtfn(set, &e, &ext, &ext, flags);
+ 		if (ret && !ip_set_eexist(ret, flags))
+ 			return ret;
+ 
+ 		ip += hosts;
+-		e.ip = htonl(ip);
+-		if (e.ip == 0)
++		if (ip == 0)
+ 			return 0;
+ 
+ 		ret = 0;
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 8f261cd5b3a50..60289c074eef4 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -1781,7 +1781,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
+ 			}
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-			ct->mark = exp->master->mark;
++			ct->mark = READ_ONCE(exp->master->mark);
+ #endif
+ #ifdef CONFIG_NF_CONNTRACK_SECMARK
+ 			ct->secmark = exp->master->secmark;
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index 7562b215b932a..d71150a40fb08 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -328,9 +328,9 @@ nla_put_failure:
+ }
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
++static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark)
+ {
+-	if (nla_put_be32(skb, CTA_MARK, htonl(ct->mark)))
++	if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
+ 		goto nla_put_failure;
+ 	return 0;
+ 
+@@ -543,7 +543,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
+ static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ 	if (ctnetlink_dump_status(skb, ct) < 0 ||
+-	    ctnetlink_dump_mark(skb, ct) < 0 ||
++	    ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 ||
+ 	    ctnetlink_dump_secctx(skb, ct) < 0 ||
+ 	    ctnetlink_dump_id(skb, ct) < 0 ||
+ 	    ctnetlink_dump_use(skb, ct) < 0 ||
+@@ -722,6 +722,7 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ 	struct sk_buff *skb;
+ 	unsigned int type;
+ 	unsigned int flags = 0, group;
++	u32 mark;
+ 	int err;
+ 
+ 	if (events & (1 << IPCT_DESTROY)) {
+@@ -826,8 +827,9 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
+ 	}
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-	if ((events & (1 << IPCT_MARK) || ct->mark)
+-	    && ctnetlink_dump_mark(skb, ct) < 0)
++	mark = READ_ONCE(ct->mark);
++	if ((events & (1 << IPCT_MARK) || mark) &&
++	    ctnetlink_dump_mark(skb, mark) < 0)
+ 		goto nla_put_failure;
+ #endif
+ 	nlmsg_end(skb, nlh);
+@@ -1154,7 +1156,7 @@ static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
+ 	}
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-	if ((ct->mark & filter->mark.mask) != filter->mark.val)
++	if ((READ_ONCE(ct->mark) & filter->mark.mask) != filter->mark.val)
+ 		goto ignore_entry;
+ #endif
+ 	status = (u32)READ_ONCE(ct->status);
+@@ -2002,9 +2004,9 @@ static void ctnetlink_change_mark(struct nf_conn *ct,
+ 		mask = ~ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
+ 
+ 	mark = ntohl(nla_get_be32(cda[CTA_MARK]));
+-	newmark = (ct->mark & mask) ^ mark;
+-	if (newmark != ct->mark)
+-		ct->mark = newmark;
++	newmark = (READ_ONCE(ct->mark) & mask) ^ mark;
++	if (newmark != READ_ONCE(ct->mark))
++		WRITE_ONCE(ct->mark, newmark);
+ }
+ #endif
+ 
+@@ -2669,6 +2671,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ {
+ 	const struct nf_conntrack_zone *zone;
+ 	struct nlattr *nest_parms;
++	u32 mark;
+ 
+ 	zone = nf_ct_zone(ct);
+ 
+@@ -2730,7 +2733,8 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
+ 		goto nla_put_failure;
+ 
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+-	if (ct->mark && ctnetlink_dump_mark(skb, ct) < 0)
++	mark = READ_ONCE(ct->mark);
++	if (mark && ctnetlink_dump_mark(skb, mark) < 0)
+ 		goto nla_put_failure;
+ #endif
+ 	if (ctnetlink_dump_labels(skb, ct) < 0)
+diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
+index 4ffe84c5a82cb..bca839ab1ae8d 100644
+--- a/net/netfilter/nf_conntrack_standalone.c
++++ b/net/netfilter/nf_conntrack_standalone.c
+@@ -366,7 +366,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
+ 		goto release;
+ 
+ #if defined(CONFIG_NF_CONNTRACK_MARK)
+-	seq_printf(s, "mark=%u ", ct->mark);
++	seq_printf(s, "mark=%u ", READ_ONCE(ct->mark));
+ #endif
+ 
+ 	ct_show_secctx(s, ct);
+diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
+index b04645ced89ba..00b522890d77b 100644
+--- a/net/netfilter/nf_flow_table_offload.c
++++ b/net/netfilter/nf_flow_table_offload.c
+@@ -1098,6 +1098,7 @@ static int nf_flow_table_block_setup(struct nf_flowtable *flowtable,
+ 	struct flow_block_cb *block_cb, *next;
+ 	int err = 0;
+ 
++	down_write(&flowtable->flow_block_lock);
+ 	switch (cmd) {
+ 	case FLOW_BLOCK_BIND:
+ 		list_splice(&bo->cb_list, &flowtable->flow_block.cb_list);
+@@ -1112,6 +1113,7 @@ static int nf_flow_table_block_setup(struct nf_flowtable *flowtable,
+ 		WARN_ON_ONCE(1);
+ 		err = -EOPNOTSUPP;
+ 	}
++	up_write(&flowtable->flow_block_lock);
+ 
+ 	return err;
+ }
+@@ -1168,7 +1170,9 @@ static int nf_flow_table_offload_cmd(struct flow_block_offload *bo,
+ 
+ 	nf_flow_table_block_offload_init(bo, dev_net(dev), cmd, flowtable,
+ 					 extack);
++	down_write(&flowtable->flow_block_lock);
+ 	err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_FT, bo);
++	up_write(&flowtable->flow_block_lock);
+ 	if (err < 0)
+ 		return err;
+ 
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 42e370575c304..0a6f3c1e9ab75 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5958,7 +5958,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ 					    &timeout);
+ 		if (err)
+ 			return err;
+-	} else if (set->flags & NFT_SET_TIMEOUT) {
++	} else if (set->flags & NFT_SET_TIMEOUT &&
++		   !(flags & NFT_SET_ELEM_INTERVAL_END)) {
+ 		timeout = set->timeout;
+ 	}
+ 
+@@ -6024,7 +6025,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
+ 			err = -EOPNOTSUPP;
+ 			goto err_set_elem_expr;
+ 		}
+-	} else if (set->num_exprs > 0) {
++	} else if (set->num_exprs > 0 &&
++		   !(flags & NFT_SET_ELEM_INTERVAL_END)) {
+ 		err = nft_set_elem_expr_clone(ctx, set, expr_array);
+ 		if (err < 0)
+ 			goto err_set_elem_expr_clone;
+diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
+index a3f01f209a533..641dc21f92b43 100644
+--- a/net/netfilter/nft_ct.c
++++ b/net/netfilter/nft_ct.c
+@@ -98,7 +98,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
+ 		return;
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+ 	case NFT_CT_MARK:
+-		*dest = ct->mark;
++		*dest = READ_ONCE(ct->mark);
+ 		return;
+ #endif
+ #ifdef CONFIG_NF_CONNTRACK_SECMARK
+@@ -297,8 +297,8 @@ static void nft_ct_set_eval(const struct nft_expr *expr,
+ 	switch (priv->key) {
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+ 	case NFT_CT_MARK:
+-		if (ct->mark != value) {
+-			ct->mark = value;
++		if (READ_ONCE(ct->mark) != value) {
++			WRITE_ONCE(ct->mark, value);
+ 			nf_conntrack_event_cache(IPCT_MARK, ct);
+ 		}
+ 		break;
+diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
+index e5ebc0810675a..ad3c033db64e7 100644
+--- a/net/netfilter/xt_connmark.c
++++ b/net/netfilter/xt_connmark.c
+@@ -30,6 +30,7 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
+ 	u_int32_t new_targetmark;
+ 	struct nf_conn *ct;
+ 	u_int32_t newmark;
++	u_int32_t oldmark;
+ 
+ 	ct = nf_ct_get(skb, &ctinfo);
+ 	if (ct == NULL)
+@@ -37,14 +38,15 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
+ 
+ 	switch (info->mode) {
+ 	case XT_CONNMARK_SET:
+-		newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
++		oldmark = READ_ONCE(ct->mark);
++		newmark = (oldmark & ~info->ctmask) ^ info->ctmark;
+ 		if (info->shift_dir == D_SHIFT_RIGHT)
+ 			newmark >>= info->shift_bits;
+ 		else
+ 			newmark <<= info->shift_bits;
+ 
+-		if (ct->mark != newmark) {
+-			ct->mark = newmark;
++		if (READ_ONCE(ct->mark) != newmark) {
++			WRITE_ONCE(ct->mark, newmark);
+ 			nf_conntrack_event_cache(IPCT_MARK, ct);
+ 		}
+ 		break;
+@@ -55,15 +57,15 @@ connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
+ 		else
+ 			new_targetmark <<= info->shift_bits;
+ 
+-		newmark = (ct->mark & ~info->ctmask) ^
++		newmark = (READ_ONCE(ct->mark) & ~info->ctmask) ^
+ 			  new_targetmark;
+-		if (ct->mark != newmark) {
+-			ct->mark = newmark;
++		if (READ_ONCE(ct->mark) != newmark) {
++			WRITE_ONCE(ct->mark, newmark);
+ 			nf_conntrack_event_cache(IPCT_MARK, ct);
+ 		}
+ 		break;
+ 	case XT_CONNMARK_RESTORE:
+-		new_targetmark = (ct->mark & info->ctmask);
++		new_targetmark = (READ_ONCE(ct->mark) & info->ctmask);
+ 		if (info->shift_dir == D_SHIFT_RIGHT)
+ 			new_targetmark >>= info->shift_bits;
+ 		else
+@@ -126,7 +128,7 @@ connmark_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ 	if (ct == NULL)
+ 		return false;
+ 
+-	return ((ct->mark & info->mask) == info->mark) ^ info->invert;
++	return ((READ_ONCE(ct->mark) & info->mask) == info->mark) ^ info->invert;
+ }
+ 
+ static int connmark_mt_check(const struct xt_mtchk_param *par)
+diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
+index 6a193cce2a754..4ffdf2f45c444 100644
+--- a/net/nfc/nci/core.c
++++ b/net/nfc/nci/core.c
+@@ -542,7 +542,7 @@ static int nci_open_device(struct nci_dev *ndev)
+ 		skb_queue_purge(&ndev->tx_q);
+ 
+ 		ndev->ops->close(ndev);
+-		ndev->flags = 0;
++		ndev->flags &= BIT(NCI_UNREG);
+ 	}
+ 
+ done:
+diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c
+index aa5e712adf078..3d36ea5701f02 100644
+--- a/net/nfc/nci/data.c
++++ b/net/nfc/nci/data.c
+@@ -279,8 +279,10 @@ void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb)
+ 		 nci_plen(skb->data));
+ 
+ 	conn_info = nci_get_conn_info_by_conn_id(ndev, nci_conn_id(skb->data));
+-	if (!conn_info)
++	if (!conn_info) {
++		kfree_skb(skb);
+ 		return;
++	}
+ 
+ 	/* strip the nci data header */
+ 	skb_pull(skb, NCI_DATA_HDR_SIZE);
+diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
+index 4e70df91d0f2a..fc5b374fe5686 100644
+--- a/net/openvswitch/conntrack.c
++++ b/net/openvswitch/conntrack.c
+@@ -152,7 +152,7 @@ static u8 ovs_ct_get_state(enum ip_conntrack_info ctinfo)
+ static u32 ovs_ct_get_mark(const struct nf_conn *ct)
+ {
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+-	return ct ? ct->mark : 0;
++	return ct ? READ_ONCE(ct->mark) : 0;
+ #else
+ 	return 0;
+ #endif
+@@ -340,9 +340,9 @@ static int ovs_ct_set_mark(struct nf_conn *ct, struct sw_flow_key *key,
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+ 	u32 new_mark;
+ 
+-	new_mark = ct_mark | (ct->mark & ~(mask));
+-	if (ct->mark != new_mark) {
+-		ct->mark = new_mark;
++	new_mark = ct_mark | (READ_ONCE(ct->mark) & ~(mask));
++	if (READ_ONCE(ct->mark) != new_mark) {
++		WRITE_ONCE(ct->mark, new_mark);
+ 		if (nf_ct_is_confirmed(ct))
+ 			nf_conntrack_event_cache(IPCT_MARK, ct);
+ 		key->ct.mark = new_mark;
+diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
+index 62c70709d7980..e0123efa2a623 100644
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -399,6 +399,7 @@ enum rxrpc_conn_proto_state {
+ struct rxrpc_bundle {
+ 	struct rxrpc_conn_parameters params;
+ 	refcount_t		ref;
++	atomic_t		active;		/* Number of active users */
+ 	unsigned int		debug_id;
+ 	bool			try_upgrade;	/* True if the bundle is attempting upgrade */
+ 	bool			alloc_conn;	/* True if someone's getting a conn */
+diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
+index 3c9eeb5b750c1..bdb335cb2d057 100644
+--- a/net/rxrpc/conn_client.c
++++ b/net/rxrpc/conn_client.c
+@@ -40,6 +40,8 @@ __read_mostly unsigned long rxrpc_conn_idle_client_fast_expiry = 2 * HZ;
+ DEFINE_IDR(rxrpc_client_conn_ids);
+ static DEFINE_SPINLOCK(rxrpc_conn_id_lock);
+ 
++static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle);
++
+ /*
+  * Get a connection ID and epoch for a client connection from the global pool.
+  * The connection struct pointer is then recorded in the idr radix tree.  The
+@@ -123,6 +125,7 @@ static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_conn_parameters *cp,
+ 		bundle->params = *cp;
+ 		rxrpc_get_peer(bundle->params.peer);
+ 		refcount_set(&bundle->ref, 1);
++		atomic_set(&bundle->active, 1);
+ 		spin_lock_init(&bundle->channel_lock);
+ 		INIT_LIST_HEAD(&bundle->waiting_calls);
+ 	}
+@@ -149,7 +152,7 @@ void rxrpc_put_bundle(struct rxrpc_bundle *bundle)
+ 
+ 	dead = __refcount_dec_and_test(&bundle->ref, &r);
+ 
+-	_debug("PUT B=%x %d", d, r);
++	_debug("PUT B=%x %d", d, r - 1);
+ 	if (dead)
+ 		rxrpc_free_bundle(bundle);
+ }
+@@ -338,6 +341,7 @@ found_bundle_free:
+ 	rxrpc_free_bundle(candidate);
+ found_bundle:
+ 	rxrpc_get_bundle(bundle);
++	atomic_inc(&bundle->active);
+ 	spin_unlock(&local->client_bundles_lock);
+ 	_leave(" = %u [found]", bundle->debug_id);
+ 	return bundle;
+@@ -435,6 +439,7 @@ static void rxrpc_add_conn_to_bundle(struct rxrpc_bundle *bundle, gfp_t gfp)
+ 			if (old)
+ 				trace_rxrpc_client(old, -1, rxrpc_client_replace);
+ 			candidate->bundle_shift = shift;
++			atomic_inc(&bundle->active);
+ 			bundle->conns[i] = candidate;
+ 			for (j = 0; j < RXRPC_MAXCALLS; j++)
+ 				set_bit(shift + j, &bundle->avail_chans);
+@@ -725,6 +730,7 @@ granted_channel:
+ 	smp_rmb();
+ 
+ out_put_bundle:
++	rxrpc_deactivate_bundle(bundle);
+ 	rxrpc_put_bundle(bundle);
+ out:
+ 	_leave(" = %d", ret);
+@@ -900,9 +906,8 @@ out:
+ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
+ {
+ 	struct rxrpc_bundle *bundle = conn->bundle;
+-	struct rxrpc_local *local = bundle->params.local;
+ 	unsigned int bindex;
+-	bool need_drop = false, need_put = false;
++	bool need_drop = false;
+ 	int i;
+ 
+ 	_enter("C=%x", conn->debug_id);
+@@ -921,15 +926,22 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
+ 	}
+ 	spin_unlock(&bundle->channel_lock);
+ 
+-	/* If there are no more connections, remove the bundle */
+-	if (!bundle->avail_chans) {
+-		_debug("maybe unbundle");
+-		spin_lock(&local->client_bundles_lock);
++	if (need_drop) {
++		rxrpc_deactivate_bundle(bundle);
++		rxrpc_put_connection(conn);
++	}
++}
+ 
+-		for (i = 0; i < ARRAY_SIZE(bundle->conns); i++)
+-			if (bundle->conns[i])
+-				break;
+-		if (i == ARRAY_SIZE(bundle->conns) && !bundle->params.exclusive) {
++/*
++ * Drop the active count on a bundle.
++ */
++static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle)
++{
++	struct rxrpc_local *local = bundle->params.local;
++	bool need_put = false;
++
++	if (atomic_dec_and_lock(&bundle->active, &local->client_bundles_lock)) {
++		if (!bundle->params.exclusive) {
+ 			_debug("erase bundle");
+ 			rb_erase(&bundle->local_node, &local->client_bundles);
+ 			need_put = true;
+@@ -939,10 +951,6 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
+ 		if (need_put)
+ 			rxrpc_put_bundle(bundle);
+ 	}
+-
+-	if (need_drop)
+-		rxrpc_put_connection(conn);
+-	_leave("");
+ }
+ 
+ /*
+diff --git a/net/sched/Kconfig b/net/sched/Kconfig
+index 1e8ab4749c6c3..4662a6ce8a7e7 100644
+--- a/net/sched/Kconfig
++++ b/net/sched/Kconfig
+@@ -976,7 +976,7 @@ config NET_ACT_TUNNEL_KEY
+ 
+ config NET_ACT_CT
+ 	tristate "connection tracking tc action"
+-	depends on NET_CLS_ACT && NF_CONNTRACK && NF_NAT && NF_FLOW_TABLE
++	depends on NET_CLS_ACT && NF_CONNTRACK && (!NF_NAT || NF_NAT) && NF_FLOW_TABLE
+ 	help
+ 	  Say Y here to allow sending the packets to conntrack module.
+ 
+diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
+index 09e2aafc8943b..0deb4e96a6c2e 100644
+--- a/net/sched/act_connmark.c
++++ b/net/sched/act_connmark.c
+@@ -62,7 +62,7 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+ 
+ 	c = nf_ct_get(skb, &ctinfo);
+ 	if (c) {
+-		skb->mark = c->mark;
++		skb->mark = READ_ONCE(c->mark);
+ 		/* using overlimits stats to count how many packets marked */
+ 		ca->tcf_qstats.overlimits++;
+ 		goto out;
+@@ -82,7 +82,7 @@ static int tcf_connmark_act(struct sk_buff *skb, const struct tc_action *a,
+ 	c = nf_ct_tuplehash_to_ctrack(thash);
+ 	/* using overlimits stats to count how many packets marked */
+ 	ca->tcf_qstats.overlimits++;
+-	skb->mark = c->mark;
++	skb->mark = READ_ONCE(c->mark);
+ 	nf_ct_put(c);
+ 
+ out:
+diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
+index 5950974ae8f64..a015915e5b726 100644
+--- a/net/sched/act_ct.c
++++ b/net/sched/act_ct.c
+@@ -178,7 +178,7 @@ static void tcf_ct_flow_table_add_action_meta(struct nf_conn *ct,
+ 	entry = tcf_ct_flow_table_flow_action_get_next(action);
+ 	entry->id = FLOW_ACTION_CT_METADATA;
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
+-	entry->ct_metadata.mark = ct->mark;
++	entry->ct_metadata.mark = READ_ONCE(ct->mark);
+ #endif
+ 	ctinfo = dir == IP_CT_DIR_ORIGINAL ? IP_CT_ESTABLISHED :
+ 					     IP_CT_ESTABLISHED_REPLY;
+@@ -940,9 +940,9 @@ static void tcf_ct_act_set_mark(struct nf_conn *ct, u32 mark, u32 mask)
+ 	if (!mask)
+ 		return;
+ 
+-	new_mark = mark | (ct->mark & ~(mask));
+-	if (ct->mark != new_mark) {
+-		ct->mark = new_mark;
++	new_mark = mark | (READ_ONCE(ct->mark) & ~(mask));
++	if (READ_ONCE(ct->mark) != new_mark) {
++		WRITE_ONCE(ct->mark, new_mark);
+ 		if (nf_ct_is_confirmed(ct))
+ 			nf_conntrack_event_cache(IPCT_MARK, ct);
+ 	}
+diff --git a/net/sched/act_ctinfo.c b/net/sched/act_ctinfo.c
+index 0281e45987a47..65a20f3c9514e 100644
+--- a/net/sched/act_ctinfo.c
++++ b/net/sched/act_ctinfo.c
+@@ -33,7 +33,7 @@ static void tcf_ctinfo_dscp_set(struct nf_conn *ct, struct tcf_ctinfo *ca,
+ {
+ 	u8 dscp, newdscp;
+ 
+-	newdscp = (((ct->mark & cp->dscpmask) >> cp->dscpmaskshift) << 2) &
++	newdscp = (((READ_ONCE(ct->mark) & cp->dscpmask) >> cp->dscpmaskshift) << 2) &
+ 		     ~INET_ECN_MASK;
+ 
+ 	switch (proto) {
+@@ -73,7 +73,7 @@ static void tcf_ctinfo_cpmark_set(struct nf_conn *ct, struct tcf_ctinfo *ca,
+ 				  struct sk_buff *skb)
+ {
+ 	ca->stats_cpmark_set++;
+-	skb->mark = ct->mark & cp->cpmarkmask;
++	skb->mark = READ_ONCE(ct->mark) & cp->cpmarkmask;
+ }
+ 
+ static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a,
+@@ -131,7 +131,7 @@ static int tcf_ctinfo_act(struct sk_buff *skb, const struct tc_action *a,
+ 	}
+ 
+ 	if (cp->mode & CTINFO_MODE_DSCP)
+-		if (!cp->dscpstatemask || (ct->mark & cp->dscpstatemask))
++		if (!cp->dscpstatemask || (READ_ONCE(ct->mark) & cp->dscpstatemask))
+ 			tcf_ctinfo_dscp_set(ct, ca, cp, skb, wlen, proto);
+ 
+ 	if (cp->mode & CTINFO_MODE_CPMARK)
+diff --git a/net/tipc/discover.c b/net/tipc/discover.c
+index e8630707901e3..e8dcdf267c0c3 100644
+--- a/net/tipc/discover.c
++++ b/net/tipc/discover.c
+@@ -211,7 +211,10 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
+ 	u32 self;
+ 	int err;
+ 
+-	skb_linearize(skb);
++	if (skb_linearize(skb)) {
++		kfree_skb(skb);
++		return;
++	}
+ 	hdr = buf_msg(skb);
+ 
+ 	if (caps & TIPC_NODE_ID128)
+diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
+index d92ec92f0b71d..e3b427a703980 100644
+--- a/net/tipc/topsrv.c
++++ b/net/tipc/topsrv.c
+@@ -176,7 +176,7 @@ static void tipc_conn_close(struct tipc_conn *con)
+ 	conn_put(con);
+ }
+ 
+-static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
++static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s, struct socket *sock)
+ {
+ 	struct tipc_conn *con;
+ 	int ret;
+@@ -202,10 +202,12 @@ static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s)
+ 	}
+ 	con->conid = ret;
+ 	s->idr_in_use++;
+-	spin_unlock_bh(&s->idr_lock);
+ 
+ 	set_bit(CF_CONNECTED, &con->flags);
+ 	con->server = s;
++	con->sock = sock;
++	conn_get(con);
++	spin_unlock_bh(&s->idr_lock);
+ 
+ 	return con;
+ }
+@@ -467,7 +469,7 @@ static void tipc_topsrv_accept(struct work_struct *work)
+ 		ret = kernel_accept(lsock, &newsock, O_NONBLOCK);
+ 		if (ret < 0)
+ 			return;
+-		con = tipc_conn_alloc(srv);
++		con = tipc_conn_alloc(srv, newsock);
+ 		if (IS_ERR(con)) {
+ 			ret = PTR_ERR(con);
+ 			sock_release(newsock);
+@@ -479,11 +481,11 @@ static void tipc_topsrv_accept(struct work_struct *work)
+ 		newsk->sk_data_ready = tipc_conn_data_ready;
+ 		newsk->sk_write_space = tipc_conn_write_space;
+ 		newsk->sk_user_data = con;
+-		con->sock = newsock;
+ 		write_unlock_bh(&newsk->sk_callback_lock);
+ 
+ 		/* Wake up receive process in case of 'SYN+' message */
+ 		newsk->sk_data_ready(newsk);
++		conn_put(con);
+ 	}
+ }
+ 
+@@ -577,17 +579,17 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
+ 	sub.filter = filter;
+ 	*(u64 *)&sub.usr_handle = (u64)port;
+ 
+-	con = tipc_conn_alloc(tipc_topsrv(net));
++	con = tipc_conn_alloc(tipc_topsrv(net), NULL);
+ 	if (IS_ERR(con))
+ 		return false;
+ 
+ 	*conid = con->conid;
+-	con->sock = NULL;
+ 	rc = tipc_conn_rcv_sub(tipc_topsrv(net), con, &sub);
+-	if (rc >= 0)
+-		return true;
++	if (rc)
++		conn_put(con);
++
+ 	conn_put(con);
+-	return false;
++	return !rc;
+ }
+ 
+ void tipc_topsrv_kern_unsubscr(struct net *net, int conid)
+diff --git a/net/wireless/util.c b/net/wireless/util.c
+index 775836f6785ab..450d609b512a1 100644
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -1555,10 +1555,12 @@ static u32 cfg80211_calculate_bitrate_eht(struct rate_info *rate)
+ 	tmp = result;
+ 	tmp *= SCALE;
+ 	do_div(tmp, mcs_divisors[rate->mcs]);
+-	result = tmp;
+ 
+ 	/* and take NSS */
+-	result = (result * rate->nss) / 8;
++	tmp *= rate->nss;
++	do_div(tmp, 8);
++
++	result = tmp;
+ 
+ 	return result / 10000;
+ }
+diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
+index 637ca88384368..9af6bf1652e48 100644
+--- a/net/xfrm/xfrm_device.c
++++ b/net/xfrm/xfrm_device.c
+@@ -97,6 +97,18 @@ static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb)
+ 	}
+ }
+ 
++static inline bool xmit_xfrm_check_overflow(struct sk_buff *skb)
++{
++	struct xfrm_offload *xo = xfrm_offload(skb);
++	__u32 seq = xo->seq.low;
++
++	seq += skb_shinfo(skb)->gso_segs;
++	if (unlikely(seq < xo->seq.low))
++		return true;
++
++	return false;
++}
++
+ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again)
+ {
+ 	int err;
+@@ -134,7 +146,8 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
+ 		return skb;
+ 	}
+ 
+-	if (skb_is_gso(skb) && unlikely(x->xso.dev != dev)) {
++	if (skb_is_gso(skb) && (unlikely(x->xso.dev != dev) ||
++				unlikely(xmit_xfrm_check_overflow(skb)))) {
+ 		struct sk_buff *segs;
+ 
+ 		/* Packet got rerouted, fixup features and segment it. */
+diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
+index 9277d81b344cb..49dd788859d8b 100644
+--- a/net/xfrm/xfrm_replay.c
++++ b/net/xfrm/xfrm_replay.c
+@@ -714,7 +714,7 @@ static int xfrm_replay_overflow_offload_esn(struct xfrm_state *x, struct sk_buff
+ 			oseq += skb_shinfo(skb)->gso_segs;
+ 		}
+ 
+-		if (unlikely(oseq < replay_esn->oseq)) {
++		if (unlikely(xo->seq.low < replay_esn->oseq)) {
+ 			XFRM_SKB_CB(skb)->seq.output.hi = ++oseq_hi;
+ 			xo->seq.hi = oseq_hi;
+ 			replay_esn->oseq_hi = oseq_hi;
+diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c
+index b9eb3208f2888..ae31bb1275940 100644
+--- a/sound/hda/intel-dsp-config.c
++++ b/sound/hda/intel-dsp-config.c
+@@ -320,6 +320,11 @@ static const struct config_entry config_table[] = {
+ 			{}
+ 		}
+ 	},
++	{
++		.flags = FLAG_SOF,
++		.device = 0x34c8,
++		.codec_hid =  &essx_83x6,
++	},
+ 	{
+ 		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+ 		.device = 0x34c8,
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index 6c0f1de10429a..d9715bea965e1 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -206,6 +206,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"),
+ 		}
+ 	},
++	{
++		.driver_data = &acp6x_card,
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "Alienware"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
++		}
++	},
+ 	{}
+ };
+ 
+diff --git a/sound/soc/codecs/hdac_hda.h b/sound/soc/codecs/hdac_hda.h
+index d0efc5e254ae9..da0ed74758b05 100644
+--- a/sound/soc/codecs/hdac_hda.h
++++ b/sound/soc/codecs/hdac_hda.h
+@@ -14,7 +14,7 @@ enum {
+ 	HDAC_HDMI_1_DAI_ID,
+ 	HDAC_HDMI_2_DAI_ID,
+ 	HDAC_HDMI_3_DAI_ID,
+-	HDAC_LAST_DAI_ID = HDAC_HDMI_3_DAI_ID,
++	HDAC_DAI_ID_NUM
+ };
+ 
+ struct hdac_hda_pcm {
+@@ -24,7 +24,7 @@ struct hdac_hda_pcm {
+ 
+ struct hdac_hda_priv {
+ 	struct hda_codec codec;
+-	struct hdac_hda_pcm pcm[HDAC_LAST_DAI_ID];
++	struct hdac_hda_pcm pcm[HDAC_DAI_ID_NUM];
+ 	bool need_display_power;
+ };
+ 
+diff --git a/sound/soc/codecs/max98373-i2c.c b/sound/soc/codecs/max98373-i2c.c
+index 3e04c7f0cce43..ec0905df65d18 100644
+--- a/sound/soc/codecs/max98373-i2c.c
++++ b/sound/soc/codecs/max98373-i2c.c
+@@ -549,6 +549,10 @@ static int max98373_i2c_probe(struct i2c_client *i2c)
+ 	max98373->cache = devm_kcalloc(&i2c->dev, max98373->cache_num,
+ 				       sizeof(*max98373->cache),
+ 				       GFP_KERNEL);
++	if (!max98373->cache) {
++		ret = -ENOMEM;
++		return ret;
++	}
+ 
+ 	for (i = 0; i < max98373->cache_num; i++)
+ 		max98373->cache[i].reg = max98373_i2c_cache_reg[i];
+diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
+index 3fafd9fc5cfd6..75a45ad55aa87 100644
+--- a/sound/soc/codecs/sgtl5000.c
++++ b/sound/soc/codecs/sgtl5000.c
+@@ -1794,6 +1794,7 @@ static int sgtl5000_i2c_remove(struct i2c_client *client)
+ {
+ 	struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client);
+ 
++	regmap_write(sgtl5000->regmap, SGTL5000_CHIP_CLK_CTRL, SGTL5000_CHIP_CLK_CTRL_DEFAULT);
+ 	regmap_write(sgtl5000->regmap, SGTL5000_CHIP_DIG_POWER, SGTL5000_DIG_POWER_DEFAULT);
+ 	regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, SGTL5000_ANA_POWER_DEFAULT);
+ 
+diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c
+index 6432b83f616f3..a935c5fd9edbc 100644
+--- a/sound/soc/intel/boards/bytcht_es8316.c
++++ b/sound/soc/intel/boards/bytcht_es8316.c
+@@ -443,6 +443,13 @@ static const struct dmi_system_id byt_cht_es8316_quirk_table[] = {
+ 					| BYT_CHT_ES8316_INTMIC_IN2_MAP
+ 					| BYT_CHT_ES8316_JD_INVERTED),
+ 	},
++	{	/* Nanote UMPC-01 */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "RWC CO.,LTD"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "UMPC-01"),
++		},
++		.driver_data = (void *)BYT_CHT_ES8316_INTMIC_IN1_MAP,
++	},
+ 	{	/* Teclast X98 Plus II */
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
+diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
+index 606cc3242a60f..5c218a39ca201 100644
+--- a/sound/soc/intel/boards/sof_es8336.c
++++ b/sound/soc/intel/boards/sof_es8336.c
+@@ -63,6 +63,7 @@ struct sof_es8336_private {
+ 	struct snd_soc_jack jack;
+ 	struct list_head hdmi_pcm_list;
+ 	bool speaker_en;
++	struct delayed_work pcm_pop_work;
+ };
+ 
+ struct sof_hdmi_pcm {
+@@ -111,6 +112,46 @@ static void log_quirks(struct device *dev)
+ 		dev_info(dev, "quirk headset at mic1 port enabled\n");
+ }
+ 
++static void pcm_pop_work_events(struct work_struct *work)
++{
++	struct sof_es8336_private *priv =
++		container_of(work, struct sof_es8336_private, pcm_pop_work.work);
++
++	gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en);
++
++	if (quirk & SOF_ES8336_HEADPHONE_GPIO)
++		gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en);
++
++}
++
++static int sof_8336_trigger(struct snd_pcm_substream *substream, int cmd)
++{
++	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
++	struct snd_soc_card *card = rtd->card;
++	struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
++
++	switch (cmd) {
++	case SNDRV_PCM_TRIGGER_START:
++	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++	case SNDRV_PCM_TRIGGER_RESUME:
++		break;
++
++	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++	case SNDRV_PCM_TRIGGER_SUSPEND:
++	case SNDRV_PCM_TRIGGER_STOP:
++		if (priv->speaker_en == false)
++			if (substream->stream == 0) {
++				cancel_delayed_work(&priv->pcm_pop_work);
++				gpiod_set_value_cansleep(priv->gpio_speakers, true);
++			}
++		break;
++	default:
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
+ static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
+ 					  struct snd_kcontrol *kcontrol, int event)
+ {
+@@ -122,19 +163,7 @@ static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
+ 
+ 	priv->speaker_en = !SND_SOC_DAPM_EVENT_ON(event);
+ 
+-	if (SND_SOC_DAPM_EVENT_ON(event))
+-		msleep(70);
+-
+-	gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en);
+-
+-	if (!(quirk & SOF_ES8336_HEADPHONE_GPIO))
+-		return 0;
+-
+-	if (SND_SOC_DAPM_EVENT_ON(event))
+-		msleep(70);
+-
+-	gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en);
+-
++	queue_delayed_work(system_wq, &priv->pcm_pop_work, msecs_to_jiffies(70));
+ 	return 0;
+ }
+ 
+@@ -344,6 +373,7 @@ static int sof_es8336_hw_params(struct snd_pcm_substream *substream,
+ /* machine stream operations */
+ static struct snd_soc_ops sof_es8336_ops = {
+ 	.hw_params = sof_es8336_hw_params,
++	.trigger = sof_8336_trigger,
+ };
+ 
+ static struct snd_soc_dai_link_component platform_component[] = {
+@@ -722,7 +752,8 @@ static int sof_es8336_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	INIT_LIST_HEAD(&priv->hdmi_pcm_list);
+-
++	INIT_DELAYED_WORK(&priv->pcm_pop_work,
++				pcm_pop_work_events);
+ 	snd_soc_card_set_drvdata(card, priv);
+ 
+ 	if (mach->mach_params.dmic_num > 0) {
+@@ -751,6 +782,7 @@ static int sof_es8336_remove(struct platform_device *pdev)
+ 	struct snd_soc_card *card = platform_get_drvdata(pdev);
+ 	struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
+ 
++	cancel_delayed_work(&priv->pcm_pop_work);
+ 	gpiod_put(priv->gpio_speakers);
+ 	device_remove_software_node(priv->codec_dev);
+ 	put_device(priv->codec_dev);
+diff --git a/sound/soc/intel/common/soc-acpi-intel-icl-match.c b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
+index b032bc07de8bf..d0062f2cd2566 100644
+--- a/sound/soc/intel/common/soc-acpi-intel-icl-match.c
++++ b/sound/soc/intel/common/soc-acpi-intel-icl-match.c
+@@ -10,6 +10,11 @@
+ #include <sound/soc-acpi-intel-match.h>
+ #include "../skylake/skl.h"
+ 
++static const struct snd_soc_acpi_codecs essx_83x6 = {
++	.num_codecs = 3,
++	.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
++};
++
+ static struct skl_machine_pdata icl_pdata = {
+ 	.use_tplg_pcm = true,
+ };
+@@ -27,6 +32,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[] = {
+ 		.drv_name = "sof_rt5682",
+ 		.sof_tplg_filename = "sof-icl-rt5682.tplg",
+ 	},
++	{
++		.comp_ids = &essx_83x6,
++		.drv_name = "sof-essx8336",
++		.sof_tplg_filename = "sof-icl-es8336", /* the tplg suffix is added at run time */
++		.tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
++					SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
++					SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
++	},
+ 	{},
+ };
+ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines);
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index 4d9b91e7e14f1..f6a996f0f9c74 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -800,11 +800,6 @@ static int __soc_pcm_open(struct snd_soc_pcm_runtime *rtd,
+ 		ret = snd_soc_dai_startup(dai, substream);
+ 		if (ret < 0)
+ 			goto err;
+-
+-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+-			dai->tx_mask = 0;
+-		else
+-			dai->rx_mask = 0;
+ 	}
+ 
+ 	/* Dynamic PCM DAI links compat checks use dynamic capabilities */
+diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c
+index a39b43850f0ed..bf8a46463cec7 100644
+--- a/sound/soc/sof/ipc3-topology.c
++++ b/sound/soc/sof/ipc3-topology.c
+@@ -2242,6 +2242,7 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
+ 	struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
+ 	struct snd_sof_widget *swidget;
+ 	struct snd_sof_route *sroute;
++	bool dyn_widgets = false;
+ 	int ret;
+ 
+ 	/*
+@@ -2251,12 +2252,14 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
+ 	 * topology loading the sound card unavailable to open PCMs.
+ 	 */
+ 	list_for_each_entry(swidget, &sdev->widget_list, list) {
+-		if (swidget->dynamic_pipeline_widget)
++		if (swidget->dynamic_pipeline_widget) {
++			dyn_widgets = true;
+ 			continue;
++		}
+ 
+-		/* Do not free widgets for static pipelines with FW ABI older than 3.19 */
++		/* Do not free widgets for static pipelines with FW older than SOF2.2 */
+ 		if (!verify && !swidget->dynamic_pipeline_widget &&
+-		    v->abi_version < SOF_ABI_VER(3, 19, 0)) {
++		    SOF_FW_VER(v->major, v->minor, v->micro) < SOF_FW_VER(2, 2, 0)) {
+ 			swidget->use_count = 0;
+ 			swidget->complete = 0;
+ 			continue;
+@@ -2270,9 +2273,11 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
+ 	/*
+ 	 * Tear down all pipelines associated with PCMs that did not get suspended
+ 	 * and unset the prepare flag so that they can be set up again during resume.
+-	 * Skip this step for older firmware.
++	 * Skip this step for older firmware unless topology has any
++	 * dynamic pipeline (in which case the step is mandatory).
+ 	 */
+-	if (!verify && v->abi_version >= SOF_ABI_VER(3, 19, 0)) {
++	if (!verify && (dyn_widgets || SOF_FW_VER(v->major, v->minor, v->micro) >=
++	    SOF_FW_VER(2, 2, 0))) {
+ 		ret = sof_tear_down_left_over_pipelines(sdev);
+ 		if (ret < 0) {
+ 			dev_err(sdev->dev, "failed to tear down paused pipelines\n");
+diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
+index 643fc8a170184..837c1848d9bff 100644
+--- a/sound/soc/stm/stm32_adfsdm.c
++++ b/sound/soc/stm/stm32_adfsdm.c
+@@ -304,6 +304,11 @@ static int stm32_adfsdm_dummy_cb(const void *data, void *private)
+ 	return 0;
+ }
+ 
++static void stm32_adfsdm_cleanup(void *data)
++{
++	iio_channel_release_all_cb(data);
++}
++
+ static struct snd_soc_component_driver stm32_adfsdm_soc_platform = {
+ 	.open		= stm32_adfsdm_pcm_open,
+ 	.close		= stm32_adfsdm_pcm_close,
+@@ -350,6 +355,12 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
+ 	if (IS_ERR(priv->iio_cb))
+ 		return PTR_ERR(priv->iio_cb);
+ 
++	ret = devm_add_action_or_reset(&pdev->dev, stm32_adfsdm_cleanup, priv->iio_cb);
++	if (ret < 0)  {
++		dev_err(&pdev->dev, "Unable to add action\n");
++		return ret;
++	}
++
+ 	component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL);
+ 	if (!component)
+ 		return -ENOMEM;
+diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
+index 2420dc994632a..4c9ea13f72d48 100644
+--- a/sound/usb/endpoint.c
++++ b/sound/usb/endpoint.c
+@@ -923,7 +923,8 @@ void snd_usb_endpoint_close(struct snd_usb_audio *chip,
+ 	usb_audio_dbg(chip, "Closing EP 0x%x (count %d)\n",
+ 		      ep->ep_num, ep->opened);
+ 
+-	if (!--ep->iface_ref->opened)
++	if (!--ep->iface_ref->opened &&
++		!(chip->quirk_flags & QUIRK_FLAG_IFACE_SKIP_CLOSE))
+ 		endpoint_set_interface(chip, ep, false);
+ 
+ 	if (!--ep->opened) {
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 250bda7cda075..4f914dce6bbf9 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -2186,6 +2186,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
+ 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
+ 	DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */
+ 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
++	DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */
++		   QUIRK_FLAG_IFACE_SKIP_CLOSE),
+ 
+ 	/* Vendor matches */
+ 	VENDOR_FLG(0x045e, /* MS Lifecam */
+diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
+index 2c6575029b1cd..e97141ef730ad 100644
+--- a/sound/usb/usbaudio.h
++++ b/sound/usb/usbaudio.h
+@@ -170,6 +170,8 @@ extern bool snd_usb_skip_validation;
+  *  Apply the generic implicit feedback sync mode (same as implicit_fb=1 option)
+  * QUIRK_FLAG_SKIP_IMPLICIT_FB
+  *  Don't apply implicit feedback sync mode
++ * QUIRK_FLAG_IFACE_SKIP_CLOSE
++ *  Don't closed interface during setting sample rate
+  */
+ 
+ #define QUIRK_FLAG_GET_SAMPLE_RATE	(1U << 0)
+@@ -191,5 +193,6 @@ extern bool snd_usb_skip_validation;
+ #define QUIRK_FLAG_SET_IFACE_FIRST	(1U << 16)
+ #define QUIRK_FLAG_GENERIC_IMPLICIT_FB	(1U << 17)
+ #define QUIRK_FLAG_SKIP_IMPLICIT_FB	(1U << 18)
++#define QUIRK_FLAG_IFACE_SKIP_CLOSE	(1U << 19)
+ 
+ #endif /* __USBAUDIO_H */
+diff --git a/tools/iio/iio_generic_buffer.c b/tools/iio/iio_generic_buffer.c
+index 2491c54a5e4fb..f8deae4e26a15 100644
+--- a/tools/iio/iio_generic_buffer.c
++++ b/tools/iio/iio_generic_buffer.c
+@@ -715,12 +715,12 @@ int main(int argc, char **argv)
+ 				continue;
+ 			}
+ 
+-			toread = buf_len;
+ 		} else {
+ 			usleep(timedelay);
+-			toread = 64;
+ 		}
+ 
++		toread = buf_len;
++
+ 		read_size = read(buf_fd, data, toread * scan_size);
+ 		if (read_size < 0) {
+ 			if (errno == EAGAIN) {
+diff --git a/tools/testing/selftests/bpf/verifier/ref_tracking.c b/tools/testing/selftests/bpf/verifier/ref_tracking.c
+index 57a83d763ec17..6dc65b2501ed2 100644
+--- a/tools/testing/selftests/bpf/verifier/ref_tracking.c
++++ b/tools/testing/selftests/bpf/verifier/ref_tracking.c
+@@ -905,3 +905,39 @@
+ 	.result_unpriv = REJECT,
+ 	.errstr_unpriv = "unknown func",
+ },
++{
++	"reference tracking: try to leak released ptr reg",
++	.insns = {
++		BPF_MOV64_IMM(BPF_REG_0, 0),
++		BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4),
++		BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
++		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
++		BPF_LD_MAP_FD(BPF_REG_1, 0),
++		BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
++		BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
++		BPF_EXIT_INSN(),
++		BPF_MOV64_REG(BPF_REG_9, BPF_REG_0),
++
++		BPF_MOV64_IMM(BPF_REG_0, 0),
++		BPF_LD_MAP_FD(BPF_REG_1, 0),
++		BPF_MOV64_IMM(BPF_REG_2, 8),
++		BPF_MOV64_IMM(BPF_REG_3, 0),
++		BPF_EMIT_CALL(BPF_FUNC_ringbuf_reserve),
++		BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
++		BPF_EXIT_INSN(),
++		BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
++
++		BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
++		BPF_MOV64_IMM(BPF_REG_2, 0),
++		BPF_EMIT_CALL(BPF_FUNC_ringbuf_discard),
++		BPF_MOV64_IMM(BPF_REG_0, 0),
++
++		BPF_STX_MEM(BPF_DW, BPF_REG_9, BPF_REG_8, 0),
++		BPF_EXIT_INSN()
++	},
++	.fixup_map_array_48b = { 4 },
++	.fixup_map_ringbuf = { 11 },
++	.result = ACCEPT,
++	.result_unpriv = REJECT,
++	.errstr_unpriv = "R8 !read_ok"
++},
+diff --git a/tools/testing/selftests/net/io_uring_zerocopy_tx.sh b/tools/testing/selftests/net/io_uring_zerocopy_tx.sh
+index 32aa6e9dacc26..9ac4456d48fcc 100755
+--- a/tools/testing/selftests/net/io_uring_zerocopy_tx.sh
++++ b/tools/testing/selftests/net/io_uring_zerocopy_tx.sh
+@@ -29,7 +29,7 @@ if [[ "$#" -eq "0" ]]; then
+ 	for IP in "${IPs[@]}"; do
+ 		for mode in $(seq 1 3); do
+ 			$0 "$IP" udp -m "$mode" -t 1 -n 32
+-			$0 "$IP" tcp -m "$mode" -t 1 -n 32
++			$0 "$IP" tcp -m "$mode" -t 1 -n 1
+ 		done
+ 	done
+ 
+diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+index ff83ef426df52..e52b794401239 100755
+--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
+@@ -2105,7 +2105,7 @@ remove_tests()
+ 		pm_nl_set_limits $ns2 1 3
+ 		pm_nl_add_endpoint $ns2 10.0.3.2 flags subflow
+ 		pm_nl_add_endpoint $ns2 10.0.4.2 flags subflow
+-		run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 slow
++		run_tests $ns1 $ns2 10.0.1.1 0 -1 -2 speed_10
+ 		chk_join_nr 3 3 3
+ 		chk_add_nr 1 1
+ 		chk_rm_nr 2 2
+@@ -2118,7 +2118,7 @@ remove_tests()
+ 		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
+ 		pm_nl_add_endpoint $ns1 10.0.4.1 flags signal
+ 		pm_nl_set_limits $ns2 3 3
+-		run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
++		run_tests $ns1 $ns2 10.0.1.1 0 -3 0 speed_10
+ 		chk_join_nr 3 3 3
+ 		chk_add_nr 3 3
+ 		chk_rm_nr 3 3 invert
+@@ -2131,7 +2131,7 @@ remove_tests()
+ 		pm_nl_add_endpoint $ns1 10.0.3.1 flags signal
+ 		pm_nl_add_endpoint $ns1 10.0.14.1 flags signal
+ 		pm_nl_set_limits $ns2 3 3
+-		run_tests $ns1 $ns2 10.0.1.1 0 -3 0 slow
++		run_tests $ns1 $ns2 10.0.1.1 0 -3 0 speed_10
+ 		chk_join_nr 1 1 1
+ 		chk_add_nr 3 3
+ 		chk_rm_nr 3 1 invert
+diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+index 0879da915014f..80d36f7cfee8a 100755
+--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+@@ -35,8 +35,9 @@ init()
+ 
+ 	ns1="ns1-$rndh"
+ 	ns2="ns2-$rndh"
++	ns_sbox="ns_sbox-$rndh"
+ 
+-	for netns in "$ns1" "$ns2";do
++	for netns in "$ns1" "$ns2" "$ns_sbox";do
+ 		ip netns add $netns || exit $ksft_skip
+ 		ip -net $netns link set lo up
+ 		ip netns exec $netns sysctl -q net.mptcp.enabled=1
+@@ -73,7 +74,7 @@ init()
+ 
+ cleanup()
+ {
+-	for netns in "$ns1" "$ns2"; do
++	for netns in "$ns1" "$ns2" "$ns_sbox"; do
+ 		ip netns del $netns
+ 	done
+ 	rm -f "$cin" "$cout"
+@@ -243,7 +244,7 @@ do_mptcp_sockopt_tests()
+ {
+ 	local lret=0
+ 
+-	./mptcp_sockopt
++	ip netns exec "$ns_sbox" ./mptcp_sockopt
+ 	lret=$?
+ 
+ 	if [ $lret -ne 0 ]; then
+@@ -252,7 +253,7 @@ do_mptcp_sockopt_tests()
+ 		return
+ 	fi
+ 
+-	./mptcp_sockopt -6
++	ip netns exec "$ns_sbox" ./mptcp_sockopt -6
+ 	lret=$?
+ 
+ 	if [ $lret -ne 0 ]; then
+diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh
+index ffa13a957a363..40aeb5a71a2a6 100755
+--- a/tools/testing/selftests/net/mptcp/simult_flows.sh
++++ b/tools/testing/selftests/net/mptcp/simult_flows.sh
+@@ -247,9 +247,10 @@ run_test()
+ 	tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1
+ 	tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2
+ 
+-	# time is measured in ms, account for transfer size, affegated link speed
++	# time is measured in ms, account for transfer size, aggregated link speed
+ 	# and header overhead (10%)
+-	local time=$((size * 8 * 1000 * 10 / (( $rate1 + $rate2) * 1024 *1024 * 9) ))
++	#              ms    byte -> bit   10%        mbit      -> kbit -> bit  10%
++	local time=$((1000 * size  *  8  * 10 / ((rate1 + rate2) * 1000 * 1000 * 9) ))
+ 
+ 	# mptcp_connect will do some sleeps to allow the mp_join handshake
+ 	# completion (see mptcp_connect): 200ms on each side, add some slack
+diff --git a/tools/testing/selftests/net/udpgro.sh b/tools/testing/selftests/net/udpgro.sh
+index ebbd0b2824327..6a443ca3cd3a4 100755
+--- a/tools/testing/selftests/net/udpgro.sh
++++ b/tools/testing/selftests/net/udpgro.sh
+@@ -50,7 +50,7 @@ run_one() {
+ 		echo "failed" &
+ 
+ 	# Hack: let bg programs complete the startup
+-	sleep 0.1
++	sleep 0.2
+ 	./udpgso_bench_tx ${tx_args}
+ 	ret=$?
+ 	wait $(jobs -p)
+@@ -117,7 +117,7 @@ run_one_2sock() {
+ 		echo "failed" &
+ 
+ 	# Hack: let bg programs complete the startup
+-	sleep 0.1
++	sleep 0.2
+ 	./udpgso_bench_tx ${tx_args} -p 12345
+ 	sleep 0.1
+ 	# first UDP GSO socket should be closed at this point
+diff --git a/tools/testing/selftests/net/udpgro_bench.sh b/tools/testing/selftests/net/udpgro_bench.sh
+index fad2d1a71cac3..8a1109a545dba 100755
+--- a/tools/testing/selftests/net/udpgro_bench.sh
++++ b/tools/testing/selftests/net/udpgro_bench.sh
+@@ -39,7 +39,7 @@ run_one() {
+ 	ip netns exec "${PEER_NS}" ./udpgso_bench_rx -t ${rx_args} -r &
+ 
+ 	# Hack: let bg programs complete the startup
+-	sleep 0.1
++	sleep 0.2
+ 	./udpgso_bench_tx ${tx_args}
+ }
+ 
+diff --git a/tools/testing/selftests/net/udpgro_frglist.sh b/tools/testing/selftests/net/udpgro_frglist.sh
+index 832c738cc3c29..7fe85ba51075d 100755
+--- a/tools/testing/selftests/net/udpgro_frglist.sh
++++ b/tools/testing/selftests/net/udpgro_frglist.sh
+@@ -44,7 +44,7 @@ run_one() {
+ 	ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} -r &
+ 
+ 	# Hack: let bg programs complete the startup
+-	sleep 0.1
++	sleep 0.2
+ 	./udpgso_bench_tx ${tx_args}
+ }
+ 
+diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c
+index 346e47f155724..7c248193ca26e 100644
+--- a/virt/kvm/pfncache.c
++++ b/virt/kvm/pfncache.c
+@@ -297,7 +297,12 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ 	if (!gpc->valid || old_uhva != gpc->uhva) {
+ 		ret = hva_to_pfn_retry(kvm, gpc);
+ 	} else {
+-		/* If the HVA→PFN mapping was already valid, don't unmap it. */
++		/*
++		 * If the HVA→PFN mapping was already valid, don't unmap it.
++		 * But do update gpc->khva because the offset within the page
++		 * may have changed.
++		 */
++		gpc->khva = old_khva + page_offset;
+ 		old_pfn = KVM_PFN_ERR_FAULT;
+ 		old_khva = NULL;
+ 		ret = 0;


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-26 11:55 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-11-26 11:55 UTC (permalink / raw
  To: gentoo-commits

commit:     1137db9487524d1e9d14c4ae6ab65a07d73cfdfe
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Nov 26 11:55:30 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Nov 26 11:55:30 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=1137db94

Linux patch 6.0.10

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

 0000_README             |     4 +
 1009_linux-6.0.10.patch | 10001 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 10005 insertions(+)

diff --git a/0000_README b/0000_README
index bda6a465..bf26e8c8 100644
--- a/0000_README
+++ b/0000_README
@@ -79,6 +79,10 @@ Patch:  1008_linux-6.0.9.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.9
 
+Patch:  1009_linux-6.0.10.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.10
+
 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/1009_linux-6.0.10.patch b/1009_linux-6.0.10.patch
new file mode 100644
index 00000000..4342593b
--- /dev/null
+++ b/1009_linux-6.0.10.patch
@@ -0,0 +1,10001 @@
+diff --git a/Documentation/driver-api/miscellaneous.rst b/Documentation/driver-api/miscellaneous.rst
+index 304ffb146cf9c..4a5104a368ac6 100644
+--- a/Documentation/driver-api/miscellaneous.rst
++++ b/Documentation/driver-api/miscellaneous.rst
+@@ -16,12 +16,11 @@ Parallel Port Devices
+ 16x50 UART Driver
+ =================
+ 
+-.. kernel-doc:: drivers/tty/serial/serial_core.c
+-   :export:
+-
+ .. kernel-doc:: drivers/tty/serial/8250/8250_core.c
+    :export:
+ 
++See serial/driver.rst for related APIs.
++
+ Pulse-Width Modulation (PWM)
+ ============================
+ 
+diff --git a/Documentation/process/code-of-conduct-interpretation.rst b/Documentation/process/code-of-conduct-interpretation.rst
+index 4f8a06b00f608..43da2cc2e3b9b 100644
+--- a/Documentation/process/code-of-conduct-interpretation.rst
++++ b/Documentation/process/code-of-conduct-interpretation.rst
+@@ -51,7 +51,7 @@ the Technical Advisory Board (TAB) or other maintainers if you're
+ uncertain how to handle situations that come up.  It will not be
+ considered a violation report unless you want it to be.  If you are
+ uncertain about approaching the TAB or any other maintainers, please
+-reach out to our conflict mediator, Joanna Lee <joanna.lee@gesmer.com>.
++reach out to our conflict mediator, Joanna Lee <jlee@linuxfoundation.org>.
+ 
+ In the end, "be kind to each other" is really what the end goal is for
+ everybody.  We know everyone is human and we all fail at times, but the
+diff --git a/Makefile b/Makefile
+index a234f16783ede..4f7da26fef784 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 9
++SUBLEVEL = 10
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
+index 29148285f9fc8..1dc3bfac30b68 100644
+--- a/arch/arm/boot/dts/imx7s.dtsi
++++ b/arch/arm/boot/dts/imx7s.dtsi
+@@ -1270,10 +1270,10 @@
+ 			clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>;
+ 		};
+ 
+-		gpmi: nand-controller@33002000{
++		gpmi: nand-controller@33002000 {
+ 			compatible = "fsl,imx7d-gpmi-nand";
+ 			#address-cells = <1>;
+-			#size-cells = <1>;
++			#size-cells = <0>;
+ 			reg = <0x33002000 0x2000>, <0x33004000 0x4000>;
+ 			reg-names = "gpmi-nand", "bch";
+ 			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+diff --git a/arch/arm/boot/dts/sama7g5-pinfunc.h b/arch/arm/boot/dts/sama7g5-pinfunc.h
+index 4eb30445d2057..6e87f0d4b8fce 100644
+--- a/arch/arm/boot/dts/sama7g5-pinfunc.h
++++ b/arch/arm/boot/dts/sama7g5-pinfunc.h
+@@ -261,7 +261,7 @@
+ #define PIN_PB2__FLEXCOM6_IO0		PINMUX_PIN(PIN_PB2, 2, 1)
+ #define PIN_PB2__ADTRG			PINMUX_PIN(PIN_PB2, 3, 1)
+ #define PIN_PB2__A20			PINMUX_PIN(PIN_PB2, 4, 1)
+-#define PIN_PB2__FLEXCOM11_IO0		PINMUX_PIN(PIN_PB2, 6, 3)
++#define PIN_PB2__FLEXCOM11_IO1		PINMUX_PIN(PIN_PB2, 6, 3)
+ #define PIN_PB3				35
+ #define PIN_PB3__GPIO			PINMUX_PIN(PIN_PB3, 0, 0)
+ #define PIN_PB3__RF1			PINMUX_PIN(PIN_PB3, 1, 1)
+diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
+index ffed4d9490428..e4904faf17532 100644
+--- a/arch/arm/mach-at91/pm_suspend.S
++++ b/arch/arm/mach-at91/pm_suspend.S
+@@ -169,10 +169,15 @@ sr_ena_2:
+ 	cmp	tmp1, #UDDRC_STAT_SELFREF_TYPE_SW
+ 	bne	sr_ena_2
+ 
+-	/* Put DDR PHY's DLL in bypass mode for non-backup modes. */
++	/* Disable DX DLLs for non-backup modes. */
+ 	cmp	r7, #AT91_PM_BACKUP
+ 	beq	sr_ena_3
+ 
++	/* Do not soft reset the AC DLL. */
++	ldr	tmp1, [r3, DDR3PHY_ACDLLCR]
++	bic	tmp1, tmp1, DDR3PHY_ACDLLCR_DLLSRST
++	str	tmp1, [r3, DDR3PHY_ACDLLCR]
++
+ 	/* Disable DX DLLs. */
+ 	ldr	tmp1, [r3, #DDR3PHY_DX0DLLCR]
+ 	orr	tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
+index 7e0aeb2db3054..a0aeac6199299 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
+@@ -34,11 +34,25 @@
+ 		off-on-delay-us = <12000>;
+ 	};
+ 
+-	extcon_usbotg1: extcon-usbotg1 {
+-		compatible = "linux,extcon-usb-gpio";
++	connector {
++		compatible = "gpio-usb-b-connector", "usb-b-connector";
++		type = "micro";
++		label = "X19";
+ 		pinctrl-names = "default";
+-		pinctrl-0 = <&pinctrl_usb1_extcon>;
+-		id-gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>;
++		pinctrl-0 = <&pinctrl_usb1_connector>;
++		id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
++
++		ports {
++			#address-cells = <1>;
++			#size-cells = <0>;
++
++			port@0 {
++				reg = <0>;
++				usb_dr_connector: endpoint {
++					remote-endpoint = <&usb1_drd_sw>;
++				};
++			};
++		};
+ 	};
+ };
+ 
+@@ -105,13 +119,19 @@
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&pinctrl_usbotg1>;
+ 	dr_mode = "otg";
+-	extcon = <&extcon_usbotg1>;
+ 	srp-disable;
+ 	hnp-disable;
+ 	adp-disable;
+ 	power-active-high;
+ 	over-current-active-low;
++	usb-role-switch;
+ 	status = "okay";
++
++	port {
++		usb1_drd_sw: endpoint {
++			remote-endpoint = <&usb_dr_connector>;
++		};
++	};
+ };
+ 
+ &usbotg2 {
+@@ -231,7 +251,7 @@
+ 			   <MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC		0x84>;
+ 	};
+ 
+-	pinctrl_usb1_extcon: usb1-extcongrp {
++	pinctrl_usb1_connector: usb1-connectorgrp {
+ 		fsl,pins = <MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10		0x1c0>;
+ 	};
+ 
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+index dabd94dc30c4b..50ef92915c671 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+@@ -1244,10 +1244,10 @@
+ 			clocks = <&clk IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK>;
+ 		};
+ 
+-		gpmi: nand-controller@33002000{
++		gpmi: nand-controller@33002000 {
+ 			compatible = "fsl,imx8mm-gpmi-nand", "fsl,imx7d-gpmi-nand";
+ 			#address-cells = <1>;
+-			#size-cells = <1>;
++			#size-cells = <0>;
+ 			reg = <0x33002000 0x2000>, <0x33004000 0x4000>;
+ 			reg-names = "gpmi-nand", "bch";
+ 			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+index ad0b99adf6911..67b554ba690ca 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+@@ -1102,7 +1102,7 @@
+ 		gpmi: nand-controller@33002000 {
+ 			compatible = "fsl,imx8mn-gpmi-nand", "fsl,imx7d-gpmi-nand";
+ 			#address-cells = <1>;
+-			#size-cells = <1>;
++			#size-cells = <0>;
+ 			reg = <0x33002000 0x2000>, <0x33004000 0x4000>;
+ 			reg-names = "gpmi-nand", "bch";
+ 			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+diff --git a/arch/arm64/boot/dts/freescale/imx93-pinfunc.h b/arch/arm64/boot/dts/freescale/imx93-pinfunc.h
+old mode 100755
+new mode 100644
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index b9bf43215ada9..79351c6157eaa 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -668,7 +668,7 @@
+ 
+ 		apcs_glb: mailbox@b111000 {
+ 			compatible = "qcom,ipq8074-apcs-apps-global";
+-			reg = <0x0b111000 0x6000>;
++			reg = <0x0b111000 0x1000>;
+ 
+ 			#clock-cells = <1>;
+ 			#mbox-cells = <1>;
+diff --git a/arch/arm64/boot/dts/qcom/sa8155p-adp.dts b/arch/arm64/boot/dts/qcom/sa8155p-adp.dts
+index ba547ca9fc6bd..ddb9cb1821520 100644
+--- a/arch/arm64/boot/dts/qcom/sa8155p-adp.dts
++++ b/arch/arm64/boot/dts/qcom/sa8155p-adp.dts
+@@ -43,7 +43,6 @@
+ 
+ 		regulator-always-on;
+ 		regulator-boot-on;
+-		regulator-allow-set-load;
+ 
+ 		vin-supply = <&vreg_3p3>;
+ 	};
+@@ -137,6 +136,9 @@
+ 			regulator-max-microvolt = <880000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l7a_1p8: ldo7 {
+@@ -152,6 +154,9 @@
+ 			regulator-max-microvolt = <2960000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l11a_0p8: ldo11 {
+@@ -258,6 +263,9 @@
+ 			regulator-max-microvolt = <1200000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l7c_1p8: ldo7 {
+@@ -273,6 +281,9 @@
+ 			regulator-max-microvolt = <1200000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l10c_3p3: ldo10 {
+diff --git a/arch/arm64/boot/dts/qcom/sa8295p-adp.dts b/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
+index ca5f5ad32ce5f..5b16ac76fefbc 100644
+--- a/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
++++ b/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
+@@ -83,6 +83,9 @@
+ 			regulator-max-microvolt = <1200000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l4c: ldo4 {
+@@ -98,6 +101,9 @@
+ 			regulator-max-microvolt = <1200000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l7c: ldo7 {
+@@ -113,6 +119,9 @@
+ 			regulator-max-microvolt = <2504000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l17c: ldo17 {
+@@ -121,6 +130,9 @@
+ 			regulator-max-microvolt = <2504000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 	};
+ 
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+index 51ed691075ad3..b3c3844f97a01 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+@@ -2177,7 +2177,8 @@
+ 
+ 		lpass_audiocc: clock-controller@3300000 {
+ 			compatible = "qcom,sc7280-lpassaudiocc";
+-			reg = <0 0x03300000 0 0x30000>;
++			reg = <0 0x03300000 0 0x30000>,
++			      <0 0x032a9000 0 0x1000>;
+ 			clocks = <&rpmhcc RPMH_CXO_CLK>,
+ 			       <&lpass_aon LPASS_AON_CC_MAIN_RCG_CLK_SRC>;
+ 			clock-names = "bi_tcxo", "lpass_aon_cc_main_rcg_clk_src";
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
+index 6792e88b2c6c5..a3796502d4255 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
++++ b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
+@@ -124,6 +124,9 @@
+ 			regulator-max-microvolt = <2504000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l13c: ldo13 {
+@@ -146,6 +149,9 @@
+ 			regulator-max-microvolt = <1200000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l4d: ldo4 {
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+index 49ea8b5612fc2..6d82dea3675b1 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+@@ -885,13 +885,13 @@
+ 
+ 		ufs_mem_phy: phy@1d87000 {
+ 			compatible = "qcom,sc8280xp-qmp-ufs-phy";
+-			reg = <0 0x01d87000 0 0xe10>;
++			reg = <0 0x01d87000 0 0x1c8>;
+ 			#address-cells = <2>;
+ 			#size-cells = <2>;
+ 			ranges;
+ 			clock-names = "ref",
+ 				      "ref_aux";
+-			clocks = <&rpmhcc RPMH_CXO_CLK>,
++			clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>,
+ 				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+ 
+ 			resets = <&ufs_mem_hc 0>;
+@@ -953,13 +953,13 @@
+ 
+ 		ufs_card_phy: phy@1da7000 {
+ 			compatible = "qcom,sc8280xp-qmp-ufs-phy";
+-			reg = <0 0x01da7000 0 0xe10>;
++			reg = <0 0x01da7000 0 0x1c8>;
+ 			#address-cells = <2>;
+ 			#size-cells = <2>;
+ 			ranges;
+ 			clock-names = "ref",
+ 				      "ref_aux";
+-			clocks = <&gcc GCC_UFS_1_CARD_CLKREF_CLK>,
++			clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>,
+ 				 <&gcc GCC_UFS_CARD_PHY_AUX_CLK>;
+ 
+ 			resets = <&ufs_card_hc 0>;
+@@ -1181,26 +1181,16 @@
+ 			usb_0_ssphy: usb3-phy@88eb400 {
+ 				reg = <0 0x088eb400 0 0x100>,
+ 				      <0 0x088eb600 0 0x3ec>,
+-				      <0 0x088ec400 0 0x1f0>,
++				      <0 0x088ec400 0 0x364>,
+ 				      <0 0x088eba00 0 0x100>,
+ 				      <0 0x088ebc00 0 0x3ec>,
+-				      <0 0x088ec700 0 0x64>;
++				      <0 0x088ec200 0 0x18>;
+ 				#phy-cells = <0>;
+ 				#clock-cells = <0>;
+ 				clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+ 				clock-names = "pipe0";
+ 				clock-output-names = "usb0_phy_pipe_clk_src";
+ 			};
+-
+-			usb_0_dpphy: dp-phy@88ed200 {
+-				reg = <0 0x088ed200 0 0x200>,
+-				      <0 0x088ed400 0 0x200>,
+-				      <0 0x088eda00 0 0x200>,
+-				      <0 0x088ea600 0 0x200>,
+-				      <0 0x088ea800 0 0x200>;
+-				#clock-cells = <1>;
+-				#phy-cells = <0>;
+-			};
+ 		};
+ 
+ 		usb_1_hsphy: phy@8902000 {
+@@ -1242,8 +1232,8 @@
+ 
+ 			usb_1_ssphy: usb3-phy@8903400 {
+ 				reg = <0 0x08903400 0 0x100>,
+-				      <0 0x08903c00 0 0x3ec>,
+-				      <0 0x08904400 0 0x1f0>,
++				      <0 0x08903600 0 0x3ec>,
++				      <0 0x08904400 0 0x364>,
+ 				      <0 0x08903a00 0 0x100>,
+ 				      <0 0x08903c00 0 0x3ec>,
+ 				      <0 0x08904200 0 0x18>;
+@@ -1253,16 +1243,6 @@
+ 				clock-names = "pipe0";
+ 				clock-output-names = "usb1_phy_pipe_clk_src";
+ 			};
+-
+-			usb_1_dpphy: dp-phy@8904200 {
+-				reg = <0 0x08904200 0 0x200>,
+-				      <0 0x08904400 0 0x200>,
+-				      <0 0x08904a00 0 0x200>,
+-				      <0 0x08904600 0 0x200>,
+-				      <0 0x08904800 0 0x200>;
+-				#clock-cells = <1>;
+-				#phy-cells = <0>;
+-			};
+ 		};
+ 
+ 		system-cache-controller@9200000 {
+diff --git a/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi b/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi
+index 014fe3a315489..fb6e5a140c9f6 100644
+--- a/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi
+@@ -348,6 +348,9 @@
+ 			regulator-max-microvolt = <2960000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l7c_3p0: ldo7 {
+@@ -367,6 +370,9 @@
+ 			regulator-max-microvolt = <2960000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l10c_3p3: ldo10 {
+diff --git a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+index 549e0a2aa9fe4..5428aab3058dd 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi
+@@ -317,6 +317,9 @@
+ 			regulator-max-microvolt = <2960000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l7c_2p85: ldo7 {
+@@ -339,6 +342,9 @@
+ 			regulator-max-microvolt = <2960000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l10c_3p3: ldo10 {
+diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+index bc773e210023c..052b4dbc1ee44 100644
+--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
+@@ -334,6 +334,7 @@
+ 				exit-latency-us = <6562>;
+ 				min-residency-us = <9987>;
+ 				local-timer-stop;
++				status = "disabled";
+ 			};
+ 		};
+ 	};
+diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
+index 0fcf5bd88fc7d..69ae6503c2f66 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
++++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
+@@ -107,6 +107,9 @@
+ 			regulator-max-microvolt = <888000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l6b_1p2: ldo6 {
+@@ -115,6 +118,9 @@
+ 			regulator-max-microvolt = <1208000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l7b_2p96: ldo7 {
+@@ -123,6 +129,9 @@
+ 			regulator-max-microvolt = <2504000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 
+ 		vreg_l9b_1p2: ldo9 {
+@@ -131,6 +140,9 @@
+ 			regulator-max-microvolt = <1200000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+ 			regulator-allow-set-load;
++			regulator-allowed-modes =
++			    <RPMH_REGULATOR_MODE_LPM
++			     RPMH_REGULATOR_MODE_HPM>;
+ 		};
+ 	};
+ 
+diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
+index abc418650fec0..65e53ef5a3960 100644
+--- a/arch/arm64/include/asm/cputype.h
++++ b/arch/arm64/include/asm/cputype.h
+@@ -41,7 +41,7 @@
+ 	(((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT)
+ 
+ #define MIDR_CPU_MODEL(imp, partnum) \
+-	(((imp)			<< MIDR_IMPLEMENTOR_SHIFT) | \
++	((_AT(u32, imp)		<< MIDR_IMPLEMENTOR_SHIFT) | \
+ 	(0xf			<< MIDR_ARCHITECTURE_SHIFT) | \
+ 	((partnum)		<< MIDR_PARTNUM_SHIFT))
+ 
+diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
+index b5df82aa99e64..d78e69293d127 100644
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte)
+ 
+ static inline bool pmd_user_accessible_page(pmd_t pmd)
+ {
+-	return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
++	return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
+ }
+ 
+ static inline bool pud_user_accessible_page(pud_t pud)
+ {
+-	return pud_present(pud) && pud_user(pud);
++	return pud_leaf(pud) && pud_user(pud);
+ }
+ #endif
+ 
+diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
+index eb489302c28a4..e8de94dd5a606 100644
+--- a/arch/arm64/mm/mmu.c
++++ b/arch/arm64/mm/mmu.c
+@@ -539,7 +539,7 @@ static void __init map_mem(pgd_t *pgdp)
+ 	 */
+ 	BUILD_BUG_ON(pgd_index(direct_map_end - 1) == pgd_index(direct_map_end));
+ 
+-	if (can_set_direct_map() || IS_ENABLED(CONFIG_KFENCE))
++	if (can_set_direct_map())
+ 		flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
+ 
+ 	/*
+@@ -1551,11 +1551,7 @@ int arch_add_memory(int nid, u64 start, u64 size,
+ 
+ 	VM_BUG_ON(!mhp_range_allowed(start, size, true));
+ 
+-	/*
+-	 * KFENCE requires linear map to be mapped at page granularity, so that
+-	 * it is possible to protect/unprotect single pages in the KFENCE pool.
+-	 */
+-	if (can_set_direct_map() || IS_ENABLED(CONFIG_KFENCE))
++	if (can_set_direct_map())
+ 		flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS;
+ 
+ 	__create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start),
+diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
+index 64e985eaa52d8..5922178d7a064 100644
+--- a/arch/arm64/mm/pageattr.c
++++ b/arch/arm64/mm/pageattr.c
+@@ -21,7 +21,13 @@ bool rodata_full __ro_after_init = IS_ENABLED(CONFIG_RODATA_FULL_DEFAULT_ENABLED
+ 
+ bool can_set_direct_map(void)
+ {
+-	return rodata_full || debug_pagealloc_enabled();
++	/*
++	 * rodata_full, DEBUG_PAGEALLOC and KFENCE require linear map to be
++	 * mapped at page granularity, so that it is possible to
++	 * protect/unprotect single pages.
++	 */
++	return (rodata_enabled && rodata_full) || debug_pagealloc_enabled() ||
++		IS_ENABLED(CONFIG_KFENCE);
+ }
+ 
+ static int change_page_range(pte_t *ptep, unsigned long addr, void *data)
+@@ -96,7 +102,8 @@ static int change_memory_common(unsigned long addr, int numpages,
+ 	 * If we are manipulating read-only permissions, apply the same
+ 	 * change to the linear mapping of the pages that back this VM area.
+ 	 */
+-	if (rodata_full && (pgprot_val(set_mask) == PTE_RDONLY ||
++	if (rodata_enabled &&
++	    rodata_full && (pgprot_val(set_mask) == PTE_RDONLY ||
+ 			    pgprot_val(clear_mask) == PTE_RDONLY)) {
+ 		for (i = 0; i < area->nr_pages; i++) {
+ 			__change_memory_common((u64)page_address(area->pages[i]),
+diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S
+index cfde14b48fd8d..f5b2ef979b437 100644
+--- a/arch/mips/kernel/relocate_kernel.S
++++ b/arch/mips/kernel/relocate_kernel.S
+@@ -145,8 +145,7 @@ LEAF(kexec_smp_wait)
+  * kexec_args[0..3] are used to prepare register values.
+  */
+ 
+-kexec_args:
+-	EXPORT(kexec_args)
++EXPORT(kexec_args)
+ arg0:	PTR_WD		0x0
+ arg1:	PTR_WD		0x0
+ arg2:	PTR_WD		0x0
+@@ -159,8 +158,7 @@ arg3:	PTR_WD		0x0
+  * their registers a0-a3. secondary_kexec_args[0..3] are used
+  * to prepare register values.
+  */
+-secondary_kexec_args:
+-	EXPORT(secondary_kexec_args)
++EXPORT(secondary_kexec_args)
+ s_arg0: PTR_WD		0x0
+ s_arg1: PTR_WD		0x0
+ s_arg2: PTR_WD		0x0
+@@ -171,19 +169,16 @@ kexec_flag:
+ 
+ #endif
+ 
+-kexec_start_address:
+-	EXPORT(kexec_start_address)
++EXPORT(kexec_start_address)
+ 	PTR_WD		0x0
+ 	.size		kexec_start_address, PTRSIZE
+ 
+-kexec_indirection_page:
+-	EXPORT(kexec_indirection_page)
++EXPORT(kexec_indirection_page)
+ 	PTR_WD		0
+ 	.size		kexec_indirection_page, PTRSIZE
+ 
+ relocate_new_kernel_end:
+ 
+-relocate_new_kernel_size:
+-	EXPORT(relocate_new_kernel_size)
++EXPORT(relocate_new_kernel_size)
+ 	PTR_WD		relocate_new_kernel_end - relocate_new_kernel
+ 	.size		relocate_new_kernel_size, PTRSIZE
+diff --git a/arch/mips/loongson64/reset.c b/arch/mips/loongson64/reset.c
+index 758d5d26aaaa2..e420800043b08 100644
+--- a/arch/mips/loongson64/reset.c
++++ b/arch/mips/loongson64/reset.c
+@@ -16,6 +16,7 @@
+ #include <asm/bootinfo.h>
+ #include <asm/idle.h>
+ #include <asm/reboot.h>
++#include <asm/bug.h>
+ 
+ #include <loongson.h>
+ #include <boot_param.h>
+@@ -159,8 +160,17 @@ static int __init mips_reboot_setup(void)
+ 
+ #ifdef CONFIG_KEXEC
+ 	kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL);
++	if (WARN_ON(!kexec_argv))
++		return -ENOMEM;
++
+ 	kdump_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL);
++	if (WARN_ON(!kdump_argv))
++		return -ENOMEM;
++
+ 	kexec_envp = kmalloc(KEXEC_ENVP_SIZE, GFP_KERNEL);
++	if (WARN_ON(!kexec_envp))
++		return -ENOMEM;
++
+ 	fw_arg1 = KEXEC_ARGV_ADDR;
+ 	memcpy(kexec_envp, (void *)fw_arg2, KEXEC_ENVP_SIZE);
+ 
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index cbe7bb029aec8..c1d36a22de308 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -284,7 +284,7 @@ config PPC
+ 	#
+ 
+ config PPC_LONG_DOUBLE_128
+-	depends on PPC64
++	depends on PPC64 && ALTIVEC
+ 	def_bool $(success,test "$(shell,echo __LONG_DOUBLE_128__ | $(CC) -E -P -)" = 1)
+ 
+ config PPC_BARRIER_NOSPEC
+diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
+index bd66f8e349492..00f45d8f1efa0 100644
+--- a/arch/s390/include/asm/processor.h
++++ b/arch/s390/include/asm/processor.h
+@@ -202,7 +202,16 @@ unsigned long __get_wchan(struct task_struct *p);
+ /* Has task runtime instrumentation enabled ? */
+ #define is_ri_task(tsk) (!!(tsk)->thread.ri_cb)
+ 
+-register unsigned long current_stack_pointer asm("r15");
++/* avoid using global register due to gcc bug in versions < 8.4 */
++#define current_stack_pointer (__current_stack_pointer())
++
++static __always_inline unsigned long __current_stack_pointer(void)
++{
++	unsigned long sp;
++
++	asm volatile("lgr %0,15" : "=d" (sp));
++	return sp;
++}
+ 
+ static __always_inline unsigned short stap(void)
+ {
+diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
+index 9ac3718410ce4..7e39c47d7759b 100644
+--- a/arch/x86/events/amd/core.c
++++ b/arch/x86/events/amd/core.c
+@@ -896,8 +896,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs)
+ 	pmu_enabled = cpuc->enabled;
+ 	cpuc->enabled = 0;
+ 
+-	/* stop everything (includes BRS) */
+-	amd_pmu_disable_all();
++	amd_brs_disable_all();
+ 
+ 	/* Drain BRS is in use (could be inactive) */
+ 	if (cpuc->lbr_users)
+@@ -908,7 +907,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs)
+ 
+ 	cpuc->enabled = pmu_enabled;
+ 	if (pmu_enabled)
+-		amd_pmu_enable_all(0);
++		amd_brs_enable_all();
+ 
+ 	return amd_pmu_adjust_nmi_window(handled);
+ }
+diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
+index d568afc705d2e..83f15fe411b3f 100644
+--- a/arch/x86/events/amd/uncore.c
++++ b/arch/x86/events/amd/uncore.c
+@@ -553,6 +553,7 @@ static void uncore_clean_online(void)
+ 
+ 	hlist_for_each_entry_safe(uncore, n, &uncore_unused_list, node) {
+ 		hlist_del(&uncore->node);
++		kfree(uncore->events);
+ 		kfree(uncore);
+ 	}
+ }
+diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
+index 82ef87e9a897c..42a55794004a7 100644
+--- a/arch/x86/events/intel/pt.c
++++ b/arch/x86/events/intel/pt.c
+@@ -1263,6 +1263,15 @@ static int pt_buffer_try_single(struct pt_buffer *buf, int nr_pages)
+ 	if (1 << order != nr_pages)
+ 		goto out;
+ 
++	/*
++	 * Some processors cannot always support single range for more than
++	 * 4KB - refer errata TGL052, ADL037 and RPL017. Future processors might
++	 * also be affected, so for now rather than trying to keep track of
++	 * which ones, just disable it for all.
++	 */
++	if (nr_pages > 1)
++		goto out;
++
+ 	buf->single = true;
+ 	buf->nr_pages = nr_pages;
+ 	ret = 0;
+diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
+index 5d75fe2293421..347707d459c67 100644
+--- a/arch/x86/include/asm/intel-family.h
++++ b/arch/x86/include/asm/intel-family.h
+@@ -107,6 +107,11 @@
+ 
+ #define INTEL_FAM6_SAPPHIRERAPIDS_X	0x8F	/* Golden Cove */
+ 
++#define INTEL_FAM6_EMERALDRAPIDS_X	0xCF
++
++#define INTEL_FAM6_GRANITERAPIDS_X	0xAD
++#define INTEL_FAM6_GRANITERAPIDS_D	0xAE
++
+ #define INTEL_FAM6_ALDERLAKE		0x97	/* Golden Cove / Gracemont */
+ #define INTEL_FAM6_ALDERLAKE_L		0x9A	/* Golden Cove / Gracemont */
+ #define INTEL_FAM6_ALDERLAKE_N		0xBE
+@@ -118,7 +123,7 @@
+ #define INTEL_FAM6_METEORLAKE		0xAC
+ #define INTEL_FAM6_METEORLAKE_L		0xAA
+ 
+-/* "Small Core" Processors (Atom) */
++/* "Small Core" Processors (Atom/E-Core) */
+ 
+ #define INTEL_FAM6_ATOM_BONNELL		0x1C /* Diamondville, Pineview */
+ #define INTEL_FAM6_ATOM_BONNELL_MID	0x26 /* Silverthorne, Lincroft */
+@@ -145,6 +150,10 @@
+ #define INTEL_FAM6_ATOM_TREMONT		0x96 /* Elkhart Lake */
+ #define INTEL_FAM6_ATOM_TREMONT_L	0x9C /* Jasper Lake */
+ 
++#define INTEL_FAM6_SIERRAFOREST_X	0xAF
++
++#define INTEL_FAM6_GRANDRIDGE		0xB6
++
+ /* Xeon Phi */
+ 
+ #define INTEL_FAM6_XEON_PHI_KNL		0x57 /* Knights Landing */
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index da7c361f47e0d..6ec0b7ce74531 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -196,22 +196,15 @@ void __init check_bugs(void)
+ }
+ 
+ /*
+- * NOTE: This function is *only* called for SVM.  VMX spec_ctrl handling is
+- * done in vmenter.S.
++ * NOTE: This function is *only* called for SVM, since Intel uses
++ * MSR_IA32_SPEC_CTRL for SSBD.
+  */
+ void
+ x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest)
+ {
+-	u64 msrval, guestval = guest_spec_ctrl, hostval = spec_ctrl_current();
++	u64 guestval, hostval;
+ 	struct thread_info *ti = current_thread_info();
+ 
+-	if (static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) {
+-		if (hostval != guestval) {
+-			msrval = setguest ? guestval : hostval;
+-			wrmsrl(MSR_IA32_SPEC_CTRL, msrval);
+-		}
+-	}
+-
+ 	/*
+ 	 * If SSBD is not handled in MSR_SPEC_CTRL on AMD, update
+ 	 * MSR_AMD64_L2_CFG or MSR_VIRT_SPEC_CTRL if supported.
+diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
+index ebe79d60619f2..da8b8ea6b063d 100644
+--- a/arch/x86/kernel/cpu/sgx/ioctl.c
++++ b/arch/x86/kernel/cpu/sgx/ioctl.c
+@@ -356,6 +356,9 @@ static int sgx_validate_offset_length(struct sgx_encl *encl,
+ 	if (!length || !IS_ALIGNED(length, PAGE_SIZE))
+ 		return -EINVAL;
+ 
++	if (offset + length < offset)
++		return -EINVAL;
++
+ 	if (offset + length - PAGE_SIZE >= encl->size)
+ 		return -EINVAL;
+ 
+diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
+index 3b28c5b25e12c..d00db56a88682 100644
+--- a/arch/x86/kernel/fpu/core.c
++++ b/arch/x86/kernel/fpu/core.c
+@@ -605,9 +605,9 @@ int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal)
+ 	if (test_thread_flag(TIF_NEED_FPU_LOAD))
+ 		fpregs_restore_userregs();
+ 	save_fpregs_to_fpstate(dst_fpu);
++	fpregs_unlock();
+ 	if (!(clone_flags & CLONE_THREAD))
+ 		fpu_inherit_perms(dst_fpu);
+-	fpregs_unlock();
+ 
+ 	/*
+ 	 * Children never inherit PASID state.
+diff --git a/arch/x86/kvm/kvm-asm-offsets.c b/arch/x86/kvm/kvm-asm-offsets.c
+index f83e88b85bf21..24a710d373238 100644
+--- a/arch/x86/kvm/kvm-asm-offsets.c
++++ b/arch/x86/kvm/kvm-asm-offsets.c
+@@ -16,8 +16,10 @@ static void __used common(void)
+ 		BLANK();
+ 		OFFSET(SVM_vcpu_arch_regs, vcpu_svm, vcpu.arch.regs);
+ 		OFFSET(SVM_current_vmcb, vcpu_svm, current_vmcb);
++		OFFSET(SVM_spec_ctrl, vcpu_svm, spec_ctrl);
+ 		OFFSET(SVM_vmcb01, vcpu_svm, vmcb01);
+ 		OFFSET(KVM_VMCB_pa, kvm_vmcb_info, pa);
++		OFFSET(SD_save_area_pa, svm_cpu_data, save_area_pa);
+ 	}
+ 
+ 	if (IS_ENABLED(CONFIG_KVM_INTEL)) {
+diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
+index c9c9bd453a97d..efaaef2b7ae11 100644
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -196,7 +196,7 @@ static void sev_asid_free(struct kvm_sev_info *sev)
+ 	__set_bit(sev->asid, sev_reclaim_asid_bitmap);
+ 
+ 	for_each_possible_cpu(cpu) {
+-		sd = per_cpu(svm_data, cpu);
++		sd = per_cpu_ptr(&svm_data, cpu);
+ 		sd->sev_vmcbs[sev->asid] = NULL;
+ 	}
+ 
+@@ -2600,7 +2600,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm)
+ 
+ void pre_sev_run(struct vcpu_svm *svm, int cpu)
+ {
+-	struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
++	struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
+ 	int asid = sev_get_asid(svm->vcpu.kvm);
+ 
+ 	/* Assign the asid allocated with this SEV guest */
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index 454746641a483..e80756ab141bf 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -245,7 +245,7 @@ struct kvm_ldttss_desc {
+ 	u32 zero1;
+ } __attribute__((packed));
+ 
+-DEFINE_PER_CPU(struct svm_cpu_data *, svm_data);
++DEFINE_PER_CPU(struct svm_cpu_data, svm_data);
+ 
+ /*
+  * Only MSR_TSC_AUX is switched via the user return hook.  EFER is switched via
+@@ -583,12 +583,7 @@ static int svm_hardware_enable(void)
+ 		pr_err("%s: err EOPNOTSUPP on %d\n", __func__, me);
+ 		return -EINVAL;
+ 	}
+-	sd = per_cpu(svm_data, me);
+-	if (!sd) {
+-		pr_err("%s: svm_data is NULL on %d\n", __func__, me);
+-		return -EINVAL;
+-	}
+-
++	sd = per_cpu_ptr(&svm_data, me);
+ 	sd->asid_generation = 1;
+ 	sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
+ 	sd->next_asid = sd->max_asid + 1;
+@@ -599,7 +594,7 @@ static int svm_hardware_enable(void)
+ 
+ 	wrmsrl(MSR_EFER, efer | EFER_SVME);
+ 
+-	wrmsrl(MSR_VM_HSAVE_PA, __sme_page_pa(sd->save_area));
++	wrmsrl(MSR_VM_HSAVE_PA, sd->save_area_pa);
+ 
+ 	if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) {
+ 		/*
+@@ -648,42 +643,37 @@ static int svm_hardware_enable(void)
+ 
+ static void svm_cpu_uninit(int cpu)
+ {
+-	struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
++	struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
+ 
+-	if (!sd)
++	if (!sd->save_area)
+ 		return;
+ 
+-	per_cpu(svm_data, cpu) = NULL;
+ 	kfree(sd->sev_vmcbs);
+ 	__free_page(sd->save_area);
+-	kfree(sd);
++	sd->save_area_pa = 0;
++	sd->save_area = NULL;
+ }
+ 
+ static int svm_cpu_init(int cpu)
+ {
+-	struct svm_cpu_data *sd;
++	struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
+ 	int ret = -ENOMEM;
+ 
+-	sd = kzalloc(sizeof(struct svm_cpu_data), GFP_KERNEL);
+-	if (!sd)
+-		return ret;
+-	sd->cpu = cpu;
++	memset(sd, 0, sizeof(struct svm_cpu_data));
+ 	sd->save_area = alloc_page(GFP_KERNEL | __GFP_ZERO);
+ 	if (!sd->save_area)
+-		goto free_cpu_data;
++		return ret;
+ 
+ 	ret = sev_cpu_init(sd);
+ 	if (ret)
+ 		goto free_save_area;
+ 
+-	per_cpu(svm_data, cpu) = sd;
+-
++	sd->save_area_pa = __sme_page_pa(sd->save_area);
+ 	return 0;
+ 
+ free_save_area:
+ 	__free_page(sd->save_area);
+-free_cpu_data:
+-	kfree(sd);
++	sd->save_area = NULL;
+ 	return ret;
+ 
+ }
+@@ -732,6 +722,15 @@ static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr)
+ 	u32 offset;
+ 	u32 *msrpm;
+ 
++	/*
++	 * For non-nested case:
++	 * If the L01 MSR bitmap does not intercept the MSR, then we need to
++	 * save it.
++	 *
++	 * For nested case:
++	 * If the L02 MSR bitmap does not intercept the MSR, then we need to
++	 * save it.
++	 */
+ 	msrpm = is_guest_mode(vcpu) ? to_svm(vcpu)->nested.msrpm:
+ 				      to_svm(vcpu)->msrpm;
+ 
+@@ -1427,7 +1426,7 @@ static void svm_clear_current_vmcb(struct vmcb *vmcb)
+ 	int i;
+ 
+ 	for_each_online_cpu(i)
+-		cmpxchg(&per_cpu(svm_data, i)->current_vmcb, vmcb, NULL);
++		cmpxchg(per_cpu_ptr(&svm_data.current_vmcb, i), vmcb, NULL);
+ }
+ 
+ static void svm_vcpu_free(struct kvm_vcpu *vcpu)
+@@ -1452,7 +1451,7 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu)
+ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
+ {
+ 	struct vcpu_svm *svm = to_svm(vcpu);
+-	struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
++	struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu);
+ 
+ 	if (sev_es_guest(vcpu->kvm))
+ 		sev_es_unmap_ghcb(svm);
+@@ -1464,7 +1463,7 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
+ 	 * Save additional host state that will be restored on VMEXIT (sev-es)
+ 	 * or subsequent vmload of host save area.
+ 	 */
+-	vmsave(__sme_page_pa(sd->save_area));
++	vmsave(sd->save_area_pa);
+ 	if (sev_es_guest(vcpu->kvm)) {
+ 		struct sev_es_save_area *hostsa;
+ 		hostsa = (struct sev_es_save_area *)(page_address(sd->save_area) + 0x400);
+@@ -1489,7 +1488,7 @@ static void svm_prepare_host_switch(struct kvm_vcpu *vcpu)
+ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+ {
+ 	struct vcpu_svm *svm = to_svm(vcpu);
+-	struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
++	struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
+ 
+ 	if (sd->current_vmcb != svm->vmcb) {
+ 		sd->current_vmcb = svm->vmcb;
+@@ -3444,7 +3443,7 @@ static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
+ 
+ static void reload_tss(struct kvm_vcpu *vcpu)
+ {
+-	struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
++	struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu);
+ 
+ 	sd->tss_desc->type = 9; /* available 32/64-bit TSS */
+ 	load_TR_desc();
+@@ -3452,7 +3451,7 @@ static void reload_tss(struct kvm_vcpu *vcpu)
+ 
+ static void pre_svm_run(struct kvm_vcpu *vcpu)
+ {
+-	struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
++	struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu);
+ 	struct vcpu_svm *svm = to_svm(vcpu);
+ 
+ 	/*
+@@ -3912,20 +3911,16 @@ static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
+ 	return EXIT_FASTPATH_NONE;
+ }
+ 
+-static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
++static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, bool spec_ctrl_intercepted)
+ {
+ 	struct vcpu_svm *svm = to_svm(vcpu);
+ 
+ 	guest_state_enter_irqoff();
+ 
+-	if (sev_es_guest(vcpu->kvm)) {
+-		__svm_sev_es_vcpu_run(svm);
+-	} else {
+-		struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
+-
+-		__svm_vcpu_run(svm);
+-		vmload(__sme_page_pa(sd->save_area));
+-	}
++	if (sev_es_guest(vcpu->kvm))
++		__svm_sev_es_vcpu_run(svm, spec_ctrl_intercepted);
++	else
++		__svm_vcpu_run(svm, spec_ctrl_intercepted);
+ 
+ 	guest_state_exit_irqoff();
+ }
+@@ -3933,6 +3928,7 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
+ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
+ {
+ 	struct vcpu_svm *svm = to_svm(vcpu);
++	bool spec_ctrl_intercepted = msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL);
+ 
+ 	trace_kvm_entry(vcpu);
+ 
+@@ -3991,26 +3987,7 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
+ 	if (!static_cpu_has(X86_FEATURE_V_SPEC_CTRL))
+ 		x86_spec_ctrl_set_guest(svm->spec_ctrl, svm->virt_spec_ctrl);
+ 
+-	svm_vcpu_enter_exit(vcpu);
+-
+-	/*
+-	 * We do not use IBRS in the kernel. If this vCPU has used the
+-	 * SPEC_CTRL MSR it may have left it on; save the value and
+-	 * turn it off. This is much more efficient than blindly adding
+-	 * it to the atomic save/restore list. Especially as the former
+-	 * (Saving guest MSRs on vmexit) doesn't even exist in KVM.
+-	 *
+-	 * For non-nested case:
+-	 * If the L01 MSR bitmap does not intercept the MSR, then we need to
+-	 * save it.
+-	 *
+-	 * For nested case:
+-	 * If the L02 MSR bitmap does not intercept the MSR, then we need to
+-	 * save it.
+-	 */
+-	if (!static_cpu_has(X86_FEATURE_V_SPEC_CTRL) &&
+-	    unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL)))
+-		svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
++	svm_vcpu_enter_exit(vcpu, spec_ctrl_intercepted);
+ 
+ 	if (!sev_es_guest(vcpu->kvm))
+ 		reload_tss(vcpu);
+diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
+index 7ff1879e73c56..ea3049b978eab 100644
+--- a/arch/x86/kvm/svm/svm.h
++++ b/arch/x86/kvm/svm/svm.h
+@@ -281,8 +281,6 @@ struct vcpu_svm {
+ };
+ 
+ struct svm_cpu_data {
+-	int cpu;
+-
+ 	u64 asid_generation;
+ 	u32 max_asid;
+ 	u32 next_asid;
+@@ -290,13 +288,15 @@ struct svm_cpu_data {
+ 	struct kvm_ldttss_desc *tss_desc;
+ 
+ 	struct page *save_area;
++	unsigned long save_area_pa;
++
+ 	struct vmcb *current_vmcb;
+ 
+ 	/* index = sev_asid, value = vmcb pointer */
+ 	struct vmcb **sev_vmcbs;
+ };
+ 
+-DECLARE_PER_CPU(struct svm_cpu_data *, svm_data);
++DECLARE_PER_CPU(struct svm_cpu_data, svm_data);
+ 
+ void recalc_intercepts(struct vcpu_svm *svm);
+ 
+@@ -683,7 +683,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm);
+ 
+ /* vmenter.S */
+ 
+-void __svm_sev_es_vcpu_run(struct vcpu_svm *svm);
+-void __svm_vcpu_run(struct vcpu_svm *svm);
++void __svm_sev_es_vcpu_run(struct vcpu_svm *svm, bool spec_ctrl_intercepted);
++void __svm_vcpu_run(struct vcpu_svm *svm, bool spec_ctrl_intercepted);
+ 
+ #endif
+diff --git a/arch/x86/kvm/svm/svm_ops.h b/arch/x86/kvm/svm/svm_ops.h
+index 9430d6437c9f6..36c8af87a707a 100644
+--- a/arch/x86/kvm/svm/svm_ops.h
++++ b/arch/x86/kvm/svm/svm_ops.h
+@@ -61,9 +61,4 @@ static __always_inline void vmsave(unsigned long pa)
+ 	svm_asm1(vmsave, "a" (pa), "memory");
+ }
+ 
+-static __always_inline void vmload(unsigned long pa)
+-{
+-	svm_asm1(vmload, "a" (pa), "memory");
+-}
+-
+ #endif /* __KVM_X86_SVM_OPS_H */
+diff --git a/arch/x86/kvm/svm/vmenter.S b/arch/x86/kvm/svm/vmenter.S
+index 5bc2ed7d79c07..34367dc203f21 100644
+--- a/arch/x86/kvm/svm/vmenter.S
++++ b/arch/x86/kvm/svm/vmenter.S
+@@ -32,9 +32,69 @@
+ 
+ .section .noinstr.text, "ax"
+ 
++.macro RESTORE_GUEST_SPEC_CTRL
++	/* No need to do anything if SPEC_CTRL is unset or V_SPEC_CTRL is set */
++	ALTERNATIVE_2 "", \
++		"jmp 800f", X86_FEATURE_MSR_SPEC_CTRL, \
++		"", X86_FEATURE_V_SPEC_CTRL
++801:
++.endm
++.macro RESTORE_GUEST_SPEC_CTRL_BODY
++800:
++	/*
++	 * SPEC_CTRL handling: if the guest's SPEC_CTRL value differs from the
++	 * host's, write the MSR.  This is kept out-of-line so that the common
++	 * case does not have to jump.
++	 *
++	 * IMPORTANT: To avoid RSB underflow attacks and any other nastiness,
++	 * there must not be any returns or indirect branches between this code
++	 * and vmentry.
++	 */
++	movl SVM_spec_ctrl(%_ASM_DI), %eax
++	cmp PER_CPU_VAR(x86_spec_ctrl_current), %eax
++	je 801b
++	mov $MSR_IA32_SPEC_CTRL, %ecx
++	xor %edx, %edx
++	wrmsr
++	jmp 801b
++.endm
++
++.macro RESTORE_HOST_SPEC_CTRL
++	/* No need to do anything if SPEC_CTRL is unset or V_SPEC_CTRL is set */
++	ALTERNATIVE_2 "", \
++		"jmp 900f", X86_FEATURE_MSR_SPEC_CTRL, \
++		"", X86_FEATURE_V_SPEC_CTRL
++901:
++.endm
++.macro RESTORE_HOST_SPEC_CTRL_BODY
++900:
++	/* Same for after vmexit.  */
++	mov $MSR_IA32_SPEC_CTRL, %ecx
++
++	/*
++	 * Load the value that the guest had written into MSR_IA32_SPEC_CTRL,
++	 * if it was not intercepted during guest execution.
++	 */
++	cmpb $0, (%_ASM_SP)
++	jnz 998f
++	rdmsr
++	movl %eax, SVM_spec_ctrl(%_ASM_DI)
++998:
++
++	/* Now restore the host value of the MSR if different from the guest's.  */
++	movl PER_CPU_VAR(x86_spec_ctrl_current), %eax
++	cmp SVM_spec_ctrl(%_ASM_DI), %eax
++	je 901b
++	xor %edx, %edx
++	wrmsr
++	jmp 901b
++.endm
++
++
+ /**
+  * __svm_vcpu_run - Run a vCPU via a transition to SVM guest mode
+  * @svm:	struct vcpu_svm *
++ * @spec_ctrl_intercepted: bool
+  */
+ SYM_FUNC_START(__svm_vcpu_run)
+ 	push %_ASM_BP
+@@ -49,14 +109,31 @@ SYM_FUNC_START(__svm_vcpu_run)
+ #endif
+ 	push %_ASM_BX
+ 
+-	/* Save @svm. */
++	/*
++	 * Save variables needed after vmexit on the stack, in inverse
++	 * order compared to when they are needed.
++	 */
++
++	/* Accessed directly from the stack in RESTORE_HOST_SPEC_CTRL.  */
++	push %_ASM_ARG2
++
++	/* Needed to restore access to percpu variables.  */
++	__ASM_SIZE(push) PER_CPU_VAR(svm_data + SD_save_area_pa)
++
++	/* Finally save @svm. */
+ 	push %_ASM_ARG1
+ 
+ .ifnc _ASM_ARG1, _ASM_DI
+-	/* Move @svm to RDI. */
++	/*
++	 * Stash @svm in RDI early. On 32-bit, arguments are in RAX, RCX
++	 * and RDX which are clobbered by RESTORE_GUEST_SPEC_CTRL.
++	 */
+ 	mov %_ASM_ARG1, %_ASM_DI
+ .endif
+ 
++	/* Clobbers RAX, RCX, RDX.  */
++	RESTORE_GUEST_SPEC_CTRL
++
+ 	/*
+ 	 * Use a single vmcb (vmcb01 because it's always valid) for
+ 	 * context switching guest state via VMLOAD/VMSAVE, that way
+@@ -124,11 +201,19 @@ SYM_FUNC_START(__svm_vcpu_run)
+ 5:	vmsave %_ASM_AX
+ 6:
+ 
++	/* Restores GSBASE among other things, allowing access to percpu data.  */
++	pop %_ASM_AX
++7:	vmload %_ASM_AX
++8:
++
+ #ifdef CONFIG_RETPOLINE
+ 	/* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
+ 	FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
+ #endif
+ 
++	/* Clobbers RAX, RCX, RDX.  */
++	RESTORE_HOST_SPEC_CTRL
++
+ 	/*
+ 	 * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be
+ 	 * untrained as soon as we exit the VM and are back to the
+@@ -164,6 +249,9 @@ SYM_FUNC_START(__svm_vcpu_run)
+ 	xor %r15d, %r15d
+ #endif
+ 
++	/* "Pop" @spec_ctrl_intercepted.  */
++	pop %_ASM_BX
++
+ 	pop %_ASM_BX
+ 
+ #ifdef CONFIG_X86_64
+@@ -178,6 +266,9 @@ SYM_FUNC_START(__svm_vcpu_run)
+ 	pop %_ASM_BP
+ 	RET
+ 
++	RESTORE_GUEST_SPEC_CTRL_BODY
++	RESTORE_HOST_SPEC_CTRL_BODY
++
+ 10:	cmpb $0, kvm_rebooting
+ 	jne 2b
+ 	ud2
+@@ -187,16 +278,21 @@ SYM_FUNC_START(__svm_vcpu_run)
+ 50:	cmpb $0, kvm_rebooting
+ 	jne 6b
+ 	ud2
++70:	cmpb $0, kvm_rebooting
++	jne 8b
++	ud2
+ 
+ 	_ASM_EXTABLE(1b, 10b)
+ 	_ASM_EXTABLE(3b, 30b)
+ 	_ASM_EXTABLE(5b, 50b)
++	_ASM_EXTABLE(7b, 70b)
+ 
+ SYM_FUNC_END(__svm_vcpu_run)
+ 
+ /**
+  * __svm_sev_es_vcpu_run - Run a SEV-ES vCPU via a transition to SVM guest mode
+  * @svm:	struct vcpu_svm *
++ * @spec_ctrl_intercepted: bool
+  */
+ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ 	push %_ASM_BP
+@@ -211,8 +307,30 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ #endif
+ 	push %_ASM_BX
+ 
++	/*
++	 * Save variables needed after vmexit on the stack, in inverse
++	 * order compared to when they are needed.
++	 */
++
++	/* Accessed directly from the stack in RESTORE_HOST_SPEC_CTRL.  */
++	push %_ASM_ARG2
++
++	/* Save @svm. */
++	push %_ASM_ARG1
++
++.ifnc _ASM_ARG1, _ASM_DI
++	/*
++	 * Stash @svm in RDI early. On 32-bit, arguments are in RAX, RCX
++	 * and RDX which are clobbered by RESTORE_GUEST_SPEC_CTRL.
++	 */
++	mov %_ASM_ARG1, %_ASM_DI
++.endif
++
++	/* Clobbers RAX, RCX, RDX.  */
++	RESTORE_GUEST_SPEC_CTRL
++
+ 	/* Get svm->current_vmcb->pa into RAX. */
+-	mov SVM_current_vmcb(%_ASM_ARG1), %_ASM_AX
++	mov SVM_current_vmcb(%_ASM_DI), %_ASM_AX
+ 	mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX
+ 
+ 	/* Enter guest mode */
+@@ -222,11 +340,17 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ 
+ 2:	cli
+ 
++	/* Pop @svm to RDI, guest registers have been saved already. */
++	pop %_ASM_DI
++
+ #ifdef CONFIG_RETPOLINE
+ 	/* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
+ 	FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
+ #endif
+ 
++	/* Clobbers RAX, RCX, RDX.  */
++	RESTORE_HOST_SPEC_CTRL
++
+ 	/*
+ 	 * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be
+ 	 * untrained as soon as we exit the VM and are back to the
+@@ -236,6 +360,9 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ 	 */
+ 	UNTRAIN_RET
+ 
++	/* "Pop" @spec_ctrl_intercepted.  */
++	pop %_ASM_BX
++
+ 	pop %_ASM_BX
+ 
+ #ifdef CONFIG_X86_64
+@@ -250,6 +377,9 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ 	pop %_ASM_BP
+ 	RET
+ 
++	RESTORE_GUEST_SPEC_CTRL_BODY
++	RESTORE_HOST_SPEC_CTRL_BODY
++
+ 3:	cmpb $0, kvm_rebooting
+ 	jne 2b
+ 	ud2
+diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
+index cecf8299b187b..9a1950879fc44 100644
+--- a/arch/x86/kvm/xen.c
++++ b/arch/x86/kvm/xen.c
+@@ -1667,18 +1667,18 @@ static int kvm_xen_eventfd_assign(struct kvm *kvm,
+ 	case EVTCHNSTAT_ipi:
+ 		/* IPI  must map back to the same port# */
+ 		if (data->u.evtchn.deliver.port.port != data->u.evtchn.send_port)
+-			goto out; /* -EINVAL */
++			goto out_noeventfd; /* -EINVAL */
+ 		break;
+ 
+ 	case EVTCHNSTAT_interdomain:
+ 		if (data->u.evtchn.deliver.port.port) {
+ 			if (data->u.evtchn.deliver.port.port >= max_evtchn_port(kvm))
+-				goto out; /* -EINVAL */
++				goto out_noeventfd; /* -EINVAL */
+ 		} else {
+ 			eventfd = eventfd_ctx_fdget(data->u.evtchn.deliver.eventfd.fd);
+ 			if (IS_ERR(eventfd)) {
+ 				ret = PTR_ERR(eventfd);
+-				goto out;
++				goto out_noeventfd;
+ 			}
+ 		}
+ 		break;
+@@ -1718,6 +1718,7 @@ static int kvm_xen_eventfd_assign(struct kvm *kvm,
+ out:
+ 	if (eventfd)
+ 		eventfd_ctx_put(eventfd);
++out_noeventfd:
+ 	kfree(evtchnfd);
+ 	return ret;
+ }
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index 869af9d72bcf8..c8f0c865bf4ed 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -1251,7 +1251,7 @@ static int blkcg_css_online(struct cgroup_subsys_state *css)
+ 	 * parent so that offline always happens towards the root.
+ 	 */
+ 	if (parent)
+-		blkcg_pin_online(css);
++		blkcg_pin_online(&parent->css);
+ 	return 0;
+ }
+ 
+diff --git a/block/blk-core.c b/block/blk-core.c
+index 651057c4146b2..2fbdf17f2206e 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -426,7 +426,6 @@ struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu)
+ 				PERCPU_REF_INIT_ATOMIC, GFP_KERNEL))
+ 		goto fail_stats;
+ 
+-	blk_queue_dma_alignment(q, 511);
+ 	blk_set_default_limits(&q->limits);
+ 	q->nr_requests = BLKDEV_DEFAULT_RQ;
+ 
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index edf41959a705f..4402e4ecb8b11 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -1183,6 +1183,7 @@ static void blk_add_rq_to_plug(struct blk_plug *plug, struct request *rq)
+ 		   (!blk_queue_nomerges(rq->q) &&
+ 		    blk_rq_bytes(last) >= BLK_PLUG_FLUSH_SIZE)) {
+ 		blk_mq_flush_plug_list(plug, false);
++		last = NULL;
+ 		trace_block_plug(rq->q);
+ 	}
+ 
+diff --git a/block/blk-settings.c b/block/blk-settings.c
+index 8bb9eef5310eb..4949ed3ce7c95 100644
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -57,6 +57,7 @@ void blk_set_default_limits(struct queue_limits *lim)
+ 	lim->misaligned = 0;
+ 	lim->zoned = BLK_ZONED_NONE;
+ 	lim->zone_write_granularity = 0;
++	lim->dma_alignment = 511;
+ }
+ EXPORT_SYMBOL(blk_set_default_limits);
+ 
+@@ -600,6 +601,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
+ 
+ 	t->io_min = max(t->io_min, b->io_min);
+ 	t->io_opt = lcm_not_zero(t->io_opt, b->io_opt);
++	t->dma_alignment = max(t->dma_alignment, b->dma_alignment);
+ 
+ 	/* Set non-power-of-2 compatible chunk_sectors boundary */
+ 	if (b->chunk_sectors)
+@@ -773,7 +775,7 @@ EXPORT_SYMBOL(blk_queue_virt_boundary);
+  **/
+ void blk_queue_dma_alignment(struct request_queue *q, int mask)
+ {
+-	q->dma_alignment = mask;
++	q->limits.dma_alignment = mask;
+ }
+ EXPORT_SYMBOL(blk_queue_dma_alignment);
+ 
+@@ -795,8 +797,8 @@ void blk_queue_update_dma_alignment(struct request_queue *q, int mask)
+ {
+ 	BUG_ON(mask > PAGE_SIZE);
+ 
+-	if (mask > q->dma_alignment)
+-		q->dma_alignment = mask;
++	if (mask > q->limits.dma_alignment)
++		q->limits.dma_alignment = mask;
+ }
+ EXPORT_SYMBOL(blk_queue_update_dma_alignment);
+ 
+diff --git a/block/sed-opal.c b/block/sed-opal.c
+index 9700197000f20..55cd37e868c0e 100644
+--- a/block/sed-opal.c
++++ b/block/sed-opal.c
+@@ -88,8 +88,8 @@ struct opal_dev {
+ 	u64 lowest_lba;
+ 
+ 	size_t pos;
+-	u8 cmd[IO_BUFFER_LENGTH];
+-	u8 resp[IO_BUFFER_LENGTH];
++	u8 *cmd;
++	u8 *resp;
+ 
+ 	struct parsed_resp parsed;
+ 	size_t prev_d_len;
+@@ -2134,6 +2134,8 @@ void free_opal_dev(struct opal_dev *dev)
+ 		return;
+ 
+ 	clean_opal_dev(dev);
++	kfree(dev->resp);
++	kfree(dev->cmd);
+ 	kfree(dev);
+ }
+ EXPORT_SYMBOL(free_opal_dev);
+@@ -2146,17 +2148,39 @@ struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv)
+ 	if (!dev)
+ 		return NULL;
+ 
++	/*
++	 * Presumably DMA-able buffers must be cache-aligned. Kmalloc makes
++	 * sure the allocated buffer is DMA-safe in that regard.
++	 */
++	dev->cmd = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL);
++	if (!dev->cmd)
++		goto err_free_dev;
++
++	dev->resp = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL);
++	if (!dev->resp)
++		goto err_free_cmd;
++
+ 	INIT_LIST_HEAD(&dev->unlk_lst);
+ 	mutex_init(&dev->dev_lock);
+ 	dev->data = data;
+ 	dev->send_recv = send_recv;
+ 	if (check_opal_support(dev) != 0) {
+ 		pr_debug("Opal is not supported on this device\n");
+-		kfree(dev);
+-		return NULL;
++		goto err_free_resp;
+ 	}
+ 
+ 	return dev;
++
++err_free_resp:
++	kfree(dev->resp);
++
++err_free_cmd:
++	kfree(dev->cmd);
++
++err_free_dev:
++	kfree(dev);
++
++	return NULL;
+ }
+ EXPORT_SYMBOL(init_opal_dev);
+ 
+diff --git a/drivers/accessibility/speakup/main.c b/drivers/accessibility/speakup/main.c
+index f52265293482e..73db0cb44fc7b 100644
+--- a/drivers/accessibility/speakup/main.c
++++ b/drivers/accessibility/speakup/main.c
+@@ -1778,7 +1778,7 @@ static void speakup_con_update(struct vc_data *vc)
+ {
+ 	unsigned long flags;
+ 
+-	if (!speakup_console[vc->vc_num] || spk_parked)
++	if (!speakup_console[vc->vc_num] || spk_parked || !synth)
+ 		return;
+ 	if (!spin_trylock_irqsave(&speakup_info.spinlock, flags))
+ 		/* Speakup output, discard */
+diff --git a/drivers/accessibility/speakup/utils.h b/drivers/accessibility/speakup/utils.h
+index 4bf2ee8ac246a..4ce9a12f7664d 100644
+--- a/drivers/accessibility/speakup/utils.h
++++ b/drivers/accessibility/speakup/utils.h
+@@ -54,7 +54,7 @@ static inline int oops(const char *msg, const char *info)
+ 
+ static inline struct st_key *hash_name(char *name)
+ {
+-	u_char *pn = (u_char *)name;
++	unsigned char *pn = (unsigned char *)name;
+ 	int hash = 0;
+ 
+ 	while (*pn) {
+diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
+index 42cec8120f18e..adfeb5770efde 100644
+--- a/drivers/acpi/scan.c
++++ b/drivers/acpi/scan.c
+@@ -796,6 +796,7 @@ static bool acpi_info_matches_ids(struct acpi_device_info *info,
+ static const char * const acpi_ignore_dep_ids[] = {
+ 	"PNP0D80", /* Windows-compatible System Power Management Controller */
+ 	"INT33BD", /* Intel Baytrail Mailbox Device */
++	"LATT2021", /* Lattice FW Update Client Driver */
+ 	NULL
+ };
+ 
+diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
+index d7cdd8406c84f..950a93922ca8f 100644
+--- a/drivers/acpi/x86/utils.c
++++ b/drivers/acpi/x86/utils.c
+@@ -219,6 +219,12 @@ static const struct dmi_system_id force_storage_d3_dmi[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 14 7425 2-in-1"),
+ 		}
+ 	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 16 5625"),
++		}
++	},
+ 	{}
+ };
+ 
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index b0e442a75690a..d86e32b71efa8 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -3966,9 +3966,19 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
+ 
+ int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev)
+ {
++	struct ata_port *ap = dev->link->ap;
+ 	u8 scsi_op = scmd->cmnd[0];
+ 	ata_xlat_func_t xlat_func;
+ 
++	/*
++	 * scsi_queue_rq() will defer commands if scsi_host_in_recovery().
++	 * However, this check is done without holding the ap->lock (a libata
++	 * specific lock), so we can have received an error irq since then,
++	 * therefore we must check if EH is pending, while holding ap->lock.
++	 */
++	if (ap->pflags & (ATA_PFLAG_EH_PENDING | ATA_PFLAG_EH_IN_PROGRESS))
++		return SCSI_MLQUEUE_DEVICE_BUSY;
++
+ 	if (unlikely(!scmd->cmd_len))
+ 		goto bad_cdb_len;
+ 
+diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
+index a7e9a75410a35..e4fb9d1b9b398 100644
+--- a/drivers/ata/libata-transport.c
++++ b/drivers/ata/libata-transport.c
+@@ -301,7 +301,9 @@ int ata_tport_add(struct device *parent,
+ 	pm_runtime_enable(dev);
+ 	pm_runtime_forbid(dev);
+ 
+-	transport_add_device(dev);
++	error = transport_add_device(dev);
++	if (error)
++		goto tport_transport_add_err;
+ 	transport_configure_device(dev);
+ 
+ 	error = ata_tlink_add(&ap->link);
+@@ -312,12 +314,12 @@ int ata_tport_add(struct device *parent,
+ 
+  tport_link_err:
+ 	transport_remove_device(dev);
++ tport_transport_add_err:
+ 	device_del(dev);
+ 
+  tport_err:
+ 	transport_destroy_device(dev);
+ 	put_device(dev);
+-	ata_host_put(ap->host);
+ 	return error;
+ }
+ 
+@@ -456,7 +458,9 @@ int ata_tlink_add(struct ata_link *link)
+ 		goto tlink_err;
+ 	}
+ 
+-	transport_add_device(dev);
++	error = transport_add_device(dev);
++	if (error)
++		goto tlink_transport_err;
+ 	transport_configure_device(dev);
+ 
+ 	ata_for_each_dev(ata_dev, link, ALL) {
+@@ -471,6 +475,7 @@ int ata_tlink_add(struct ata_link *link)
+ 		ata_tdev_delete(ata_dev);
+ 	}
+ 	transport_remove_device(dev);
++  tlink_transport_err:
+ 	device_del(dev);
+   tlink_err:
+ 	transport_destroy_device(dev);
+@@ -708,7 +713,13 @@ static int ata_tdev_add(struct ata_device *ata_dev)
+ 		return error;
+ 	}
+ 
+-	transport_add_device(dev);
++	error = transport_add_device(dev);
++	if (error) {
++		device_del(dev);
++		ata_tdev_free(ata_dev);
++		return error;
++	}
++
+ 	transport_configure_device(dev);
+ 	return 0;
+ }
+diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
+index f3e4db16fd07b..8532b839a3435 100644
+--- a/drivers/block/drbd/drbd_main.c
++++ b/drivers/block/drbd/drbd_main.c
+@@ -2672,7 +2672,7 @@ static int init_submitter(struct drbd_device *device)
+ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor)
+ {
+ 	struct drbd_resource *resource = adm_ctx->resource;
+-	struct drbd_connection *connection;
++	struct drbd_connection *connection, *n;
+ 	struct drbd_device *device;
+ 	struct drbd_peer_device *peer_device, *tmp_peer_device;
+ 	struct gendisk *disk;
+@@ -2789,7 +2789,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
+ 	return NO_ERROR;
+ 
+ out_idr_remove_from_resource:
+-	for_each_connection(connection, resource) {
++	for_each_connection_safe(connection, n, resource) {
+ 		peer_device = idr_remove(&connection->peer_devices, vnr);
+ 		if (peer_device)
+ 			kref_put(&connection->kref, drbd_destroy_connection);
+diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
+index 16176b9278b4e..0c90f13870a43 100644
+--- a/drivers/cxl/core/mbox.c
++++ b/drivers/cxl/core/mbox.c
+@@ -174,7 +174,7 @@ int cxl_mbox_send_cmd(struct cxl_dev_state *cxlds, u16 opcode, void *in,
+ 	};
+ 	int rc;
+ 
+-	if (out_size > cxlds->payload_size)
++	if (in_size > cxlds->payload_size || out_size > cxlds->payload_size)
+ 		return -E2BIG;
+ 
+ 	rc = cxlds->mbox_send(cxlds, &mbox_cmd);
+diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c
+index faade12279f02..e0646097a3d4b 100644
+--- a/drivers/cxl/pmem.c
++++ b/drivers/cxl/pmem.c
+@@ -151,7 +151,7 @@ static int cxl_pmem_set_config_data(struct cxl_dev_state *cxlds,
+ 		return -EINVAL;
+ 
+ 	/* 4-byte status follows the input data in the payload */
+-	if (struct_size(cmd, in_buf, cmd->in_length) + 4 > buf_len)
++	if (size_add(struct_size(cmd, in_buf, cmd->in_length), 4) > buf_len)
+ 		return -EINVAL;
+ 
+ 	set_lsa =
+diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
+index d4e23101448ae..35bb70724d44b 100644
+--- a/drivers/firmware/arm_scmi/bus.c
++++ b/drivers/firmware/arm_scmi/bus.c
+@@ -216,9 +216,20 @@ void scmi_device_destroy(struct scmi_device *scmi_dev)
+ 	device_unregister(&scmi_dev->dev);
+ }
+ 
++void scmi_device_link_add(struct device *consumer, struct device *supplier)
++{
++	struct device_link *link;
++
++	link = device_link_add(consumer, supplier, DL_FLAG_AUTOREMOVE_CONSUMER);
++
++	WARN_ON(!link);
++}
++
+ void scmi_set_handle(struct scmi_device *scmi_dev)
+ {
+ 	scmi_dev->handle = scmi_handle_get(&scmi_dev->dev);
++	if (scmi_dev->handle)
++		scmi_device_link_add(&scmi_dev->dev, scmi_dev->handle->dev);
+ }
+ 
+ int scmi_protocol_register(const struct scmi_protocol *proto)
+diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
+index 61aba7447c32a..a1c0154c31c6f 100644
+--- a/drivers/firmware/arm_scmi/common.h
++++ b/drivers/firmware/arm_scmi/common.h
+@@ -97,6 +97,7 @@ static inline void unpack_scmi_header(u32 msg_hdr, struct scmi_msg_hdr *hdr)
+ struct scmi_revision_info *
+ scmi_revision_area_get(const struct scmi_protocol_handle *ph);
+ int scmi_handle_put(const struct scmi_handle *handle);
++void scmi_device_link_add(struct device *consumer, struct device *supplier);
+ struct scmi_handle *scmi_handle_get(struct device *dev);
+ void scmi_set_handle(struct scmi_device *scmi_dev);
+ void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph,
+@@ -117,6 +118,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
+  *
+  * @dev: Reference to device in the SCMI hierarchy corresponding to this
+  *	 channel
++ * @rx_timeout_ms: The configured RX timeout in milliseconds.
+  * @handle: Pointer to SCMI entity handle
+  * @no_completion_irq: Flag to indicate that this channel has no completion
+  *		       interrupt mechanism for synchronous commands.
+@@ -126,6 +128,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id);
+  */
+ struct scmi_chan_info {
+ 	struct device *dev;
++	unsigned int rx_timeout_ms;
+ 	struct scmi_handle *handle;
+ 	bool no_completion_irq;
+ 	void *transport_info;
+@@ -232,7 +235,7 @@ void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id);
+ struct scmi_shared_mem;
+ 
+ void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
+-		      struct scmi_xfer *xfer);
++		      struct scmi_xfer *xfer, struct scmi_chan_info *cinfo);
+ u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem);
+ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem,
+ 			  struct scmi_xfer *xfer);
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index 9022f5ee29aa8..f818d00bb2c69 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -2013,6 +2013,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev,
+ 		return -ENOMEM;
+ 
+ 	cinfo->dev = dev;
++	cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms;
+ 
+ 	ret = info->desc->ops->chan_setup(cinfo, info->dev, tx);
+ 	if (ret)
+@@ -2277,10 +2278,16 @@ int scmi_protocol_device_request(const struct scmi_device_id *id_table)
+ 			sdev = scmi_get_protocol_device(child, info,
+ 							id_table->protocol_id,
+ 							id_table->name);
+-			/* Set handle if not already set: device existed */
+-			if (sdev && !sdev->handle)
+-				sdev->handle =
+-					scmi_handle_get_from_info_unlocked(info);
++			if (sdev) {
++				/* Set handle if not already set: device existed */
++				if (!sdev->handle)
++					sdev->handle =
++						scmi_handle_get_from_info_unlocked(info);
++				/* Relink consumer and suppliers */
++				if (sdev->handle)
++					scmi_device_link_add(&sdev->dev,
++							     sdev->handle->dev);
++			}
+ 		} else {
+ 			dev_err(info->dev,
+ 				"Failed. SCMI protocol %d not active.\n",
+@@ -2479,20 +2486,17 @@ void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id)
+ 
+ static int scmi_remove(struct platform_device *pdev)
+ {
+-	int ret = 0, id;
++	int ret, id;
+ 	struct scmi_info *info = platform_get_drvdata(pdev);
+ 	struct device_node *child;
+ 
+ 	mutex_lock(&scmi_list_mutex);
+ 	if (info->users)
+-		ret = -EBUSY;
+-	else
+-		list_del(&info->node);
++		dev_warn(&pdev->dev,
++			 "Still active SCMI users will be forcibly unbound.\n");
++	list_del(&info->node);
+ 	mutex_unlock(&scmi_list_mutex);
+ 
+-	if (ret)
+-		return ret;
+-
+ 	scmi_notification_exit(&info->handle);
+ 
+ 	mutex_lock(&info->protocols_mtx);
+@@ -2504,7 +2508,11 @@ static int scmi_remove(struct platform_device *pdev)
+ 	idr_destroy(&info->active_protocols);
+ 
+ 	/* Safe to free channels since no more users */
+-	return scmi_cleanup_txrx_channels(info);
++	ret = scmi_cleanup_txrx_channels(info);
++	if (ret)
++		dev_warn(&pdev->dev, "Failed to cleanup SCMI channels.\n");
++
++	return 0;
+ }
+ 
+ static ssize_t protocol_version_show(struct device *dev,
+diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c
+index 08ff4d110beb4..1e40cb035044d 100644
+--- a/drivers/firmware/arm_scmi/mailbox.c
++++ b/drivers/firmware/arm_scmi/mailbox.c
+@@ -36,7 +36,7 @@ static void tx_prepare(struct mbox_client *cl, void *m)
+ {
+ 	struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);
+ 
+-	shmem_tx_prepare(smbox->shmem, m);
++	shmem_tx_prepare(smbox->shmem, m, smbox->cinfo);
+ }
+ 
+ static void rx_callback(struct mbox_client *cl, void *m)
+diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c
+index f42dad997ac9a..2a7aeab40e543 100644
+--- a/drivers/firmware/arm_scmi/optee.c
++++ b/drivers/firmware/arm_scmi/optee.c
+@@ -498,7 +498,7 @@ static int scmi_optee_send_message(struct scmi_chan_info *cinfo,
+ 		msg_tx_prepare(channel->req.msg, xfer);
+ 		ret = invoke_process_msg_channel(channel, msg_command_size(xfer));
+ 	} else {
+-		shmem_tx_prepare(channel->req.shmem, xfer);
++		shmem_tx_prepare(channel->req.shmem, xfer, cinfo);
+ 		ret = invoke_process_smt_channel(channel);
+ 	}
+ 
+diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/shmem.c
+index 0e3eaea5d8526..1dfe534b85184 100644
+--- a/drivers/firmware/arm_scmi/shmem.c
++++ b/drivers/firmware/arm_scmi/shmem.c
+@@ -5,10 +5,13 @@
+  * Copyright (C) 2019 ARM Ltd.
+  */
+ 
++#include <linux/ktime.h>
+ #include <linux/io.h>
+ #include <linux/processor.h>
+ #include <linux/types.h>
+ 
++#include <asm-generic/bug.h>
++
+ #include "common.h"
+ 
+ /*
+@@ -30,16 +33,36 @@ struct scmi_shared_mem {
+ };
+ 
+ void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem,
+-		      struct scmi_xfer *xfer)
++		      struct scmi_xfer *xfer, struct scmi_chan_info *cinfo)
+ {
++	ktime_t stop;
++
+ 	/*
+ 	 * Ideally channel must be free by now unless OS timeout last
+ 	 * request and platform continued to process the same, wait
+ 	 * until it releases the shared memory, otherwise we may endup
+-	 * overwriting its response with new message payload or vice-versa
++	 * overwriting its response with new message payload or vice-versa.
++	 * Giving up anyway after twice the expected channel timeout so as
++	 * not to bail-out on intermittent issues where the platform is
++	 * occasionally a bit slower to answer.
++	 *
++	 * Note that after a timeout is detected we bail-out and carry on but
++	 * the transport functionality is probably permanently compromised:
++	 * this is just to ease debugging and avoid complete hangs on boot
++	 * due to a misbehaving SCMI firmware.
+ 	 */
+-	spin_until_cond(ioread32(&shmem->channel_status) &
+-			SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
++	stop = ktime_add_ms(ktime_get(), 2 * cinfo->rx_timeout_ms);
++	spin_until_cond((ioread32(&shmem->channel_status) &
++			 SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE) ||
++			 ktime_after(ktime_get(), stop));
++	if (!(ioread32(&shmem->channel_status) &
++	      SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE)) {
++		WARN_ON_ONCE(1);
++		dev_err(cinfo->dev,
++			"Timeout waiting for a free TX channel !\n");
++		return;
++	}
++
+ 	/* Mark channel busy + clear error */
+ 	iowrite32(0x0, &shmem->channel_status);
+ 	iowrite32(xfer->hdr.poll_completion ? 0 : SCMI_SHMEM_FLAG_INTR_ENABLED,
+diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c
+index 745acfdd0b3df..87a7b13cf868b 100644
+--- a/drivers/firmware/arm_scmi/smc.c
++++ b/drivers/firmware/arm_scmi/smc.c
+@@ -188,7 +188,7 @@ static int smc_send_message(struct scmi_chan_info *cinfo,
+ 	 */
+ 	smc_channel_lock_acquire(scmi_info, xfer);
+ 
+-	shmem_tx_prepare(scmi_info->shmem, xfer);
++	shmem_tx_prepare(scmi_info->shmem, xfer, cinfo);
+ 
+ 	arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
+ 
+diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
+index c52bcaa9def60..9ca21feb9d454 100644
+--- a/drivers/firmware/google/coreboot_table.c
++++ b/drivers/firmware/google/coreboot_table.c
+@@ -149,12 +149,8 @@ static int coreboot_table_probe(struct platform_device *pdev)
+ 	if (!ptr)
+ 		return -ENOMEM;
+ 
+-	ret = bus_register(&coreboot_bus_type);
+-	if (!ret) {
+-		ret = coreboot_table_populate(dev, ptr);
+-		if (ret)
+-			bus_unregister(&coreboot_bus_type);
+-	}
++	ret = coreboot_table_populate(dev, ptr);
++
+ 	memunmap(ptr);
+ 
+ 	return ret;
+@@ -169,7 +165,6 @@ static int __cb_dev_unregister(struct device *dev, void *dummy)
+ static int coreboot_table_remove(struct platform_device *pdev)
+ {
+ 	bus_for_each_dev(&coreboot_bus_type, NULL, NULL, __cb_dev_unregister);
+-	bus_unregister(&coreboot_bus_type);
+ 	return 0;
+ }
+ 
+@@ -199,6 +194,32 @@ static struct platform_driver coreboot_table_driver = {
+ 		.of_match_table = of_match_ptr(coreboot_of_match),
+ 	},
+ };
+-module_platform_driver(coreboot_table_driver);
++
++static int __init coreboot_table_driver_init(void)
++{
++	int ret;
++
++	ret = bus_register(&coreboot_bus_type);
++	if (ret)
++		return ret;
++
++	ret = platform_driver_register(&coreboot_table_driver);
++	if (ret) {
++		bus_unregister(&coreboot_bus_type);
++		return ret;
++	}
++
++	return 0;
++}
++
++static void __exit coreboot_table_driver_exit(void)
++{
++	platform_driver_unregister(&coreboot_table_driver);
++	bus_unregister(&coreboot_bus_type);
++}
++
++module_init(coreboot_table_driver_init);
++module_exit(coreboot_table_driver_exit);
++
+ MODULE_AUTHOR("Google, Inc.");
+ MODULE_LICENSE("GPL");
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 9170aeaad93e7..e0c960cc1d2e1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -4055,15 +4055,18 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev)
+  * at suspend time.
+  *
+  */
+-static void amdgpu_device_evict_resources(struct amdgpu_device *adev)
++static int amdgpu_device_evict_resources(struct amdgpu_device *adev)
+ {
++	int ret;
++
+ 	/* No need to evict vram on APUs for suspend to ram or s2idle */
+ 	if ((adev->in_s3 || adev->in_s0ix) && (adev->flags & AMD_IS_APU))
+-		return;
++		return 0;
+ 
+-	if (amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM))
++	ret = amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM);
++	if (ret)
+ 		DRM_WARN("evicting device resources failed\n");
+-
++	return ret;
+ }
+ 
+ /*
+@@ -4113,7 +4116,9 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
+ 	if (!adev->in_s0ix)
+ 		amdgpu_amdkfd_suspend(adev, adev->in_runpm);
+ 
+-	amdgpu_device_evict_resources(adev);
++	r = amdgpu_device_evict_resources(adev);
++	if (r)
++		return r;
+ 
+ 	amdgpu_fence_driver_hw_fini(adev);
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
+index 576849e952964..f69827aefb571 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
+@@ -500,6 +500,8 @@ static int amdgpu_vkms_sw_init(void *handle)
+ 
+ 	adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base;
+ 
++	adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true;
++
+ 	r = amdgpu_display_modeset_create_props(adev);
+ 	if (r)
+ 		return r;
+diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+index 2dd827472d6e4..3bff0ae15e64e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+@@ -96,7 +96,14 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
+ 	struct amdgpu_device *adev = mes->adev;
+ 	struct amdgpu_ring *ring = &mes->ring;
+ 	unsigned long flags;
++	signed long timeout = adev->usec_timeout;
+ 
++	if (amdgpu_emu_mode) {
++		timeout *= 100;
++	} else if (amdgpu_sriov_vf(adev)) {
++		/* Worst case in sriov where all other 15 VF timeout, each VF needs about 600ms */
++		timeout = 15 * 600 * 1000;
++	}
+ 	BUG_ON(size % 4 != 0);
+ 
+ 	spin_lock_irqsave(&mes->ring_lock, flags);
+@@ -116,7 +123,7 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
+ 	DRM_DEBUG("MES msg=%d was emitted\n", x_pkt->header.opcode);
+ 
+ 	r = amdgpu_fence_wait_polling(ring, ring->fence_drv.sync_seq,
+-		      adev->usec_timeout * (amdgpu_emu_mode ? 100 : 1));
++		      timeout);
+ 	if (r < 1) {
+ 		DRM_ERROR("MES failed to response msg=%d\n",
+ 			  x_pkt->header.opcode);
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 3be70848b2020..7f8eb09b0b7cb 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -146,6 +146,14 @@ MODULE_FIRMWARE(FIRMWARE_NAVI12_DMCU);
+ /* Number of bytes in PSP footer for firmware. */
+ #define PSP_FOOTER_BYTES 0x100
+ 
++/*
++ * DMUB Async to Sync Mechanism Status
++ */
++#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1
++#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2
++#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3
++#define DMUB_ASYNC_TO_SYNC_ACCESS_INVALID 4
++
+ /**
+  * DOC: overview
+  *
+@@ -1549,6 +1557,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
+ 
+ 	adev->dm.dc->debug.visual_confirm = amdgpu_dc_visual_confirm;
+ 
++	/* TODO: Remove after DP2 receiver gets proper support of Cable ID feature */
++	adev->dm.dc->debug.ignore_cable_id = true;
++
+ 	r = dm_dmub_hw_init(adev);
+ 	if (r) {
+ 		DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
+@@ -1634,12 +1645,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
+ 		}
+ 	}
+ 
+-	if (amdgpu_dm_initialize_drm_device(adev)) {
+-		DRM_ERROR(
+-		"amdgpu: failed to initialize sw for display support.\n");
+-		goto error;
+-	}
+-
+ 	/* Enable outbox notification only after IRQ handlers are registered and DMUB is alive.
+ 	 * It is expected that DMUB will resend any pending notifications at this point, for
+ 	 * example HPD from DPIA.
+@@ -1647,6 +1652,12 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
+ 	if (dc_is_dmub_outbox_supported(adev->dm.dc))
+ 		dc_enable_dmub_outbox(adev->dm.dc);
+ 
++	if (amdgpu_dm_initialize_drm_device(adev)) {
++		DRM_ERROR(
++		"amdgpu: failed to initialize sw for display support.\n");
++		goto error;
++	}
++
+ 	/* create fake encoders for MST */
+ 	dm_dp_create_fake_mst_encoders(adev);
+ 
+@@ -10146,6 +10157,8 @@ static int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux,
+ 			*operation_result = AUX_RET_ERROR_TIMEOUT;
+ 		} else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_FAIL) {
+ 			*operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE;
++		} else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_INVALID) {
++			*operation_result = AUX_RET_ERROR_INVALID_REPLY;
+ 		} else {
+ 			*operation_result = AUX_RET_ERROR_UNKNOWN;
+ 		}
+@@ -10193,6 +10206,16 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux, struct dc_context
+ 			payload->reply[0] = adev->dm.dmub_notify->aux_reply.command;
+ 			if (!payload->write && adev->dm.dmub_notify->aux_reply.length &&
+ 			    payload->reply[0] == AUX_TRANSACTION_REPLY_AUX_ACK) {
++
++				if (payload->length != adev->dm.dmub_notify->aux_reply.length) {
++					DRM_WARN("invalid read from DPIA AUX %x(%d) got length %d!\n",
++							payload->address, payload->length,
++							adev->dm.dmub_notify->aux_reply.length);
++					return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux, ctx,
++							DMUB_ASYNC_TO_SYNC_ACCESS_INVALID,
++							(uint32_t *)operation_result);
++				}
++
+ 				memcpy(payload->data, adev->dm.dmub_notify->aux_reply.data,
+ 				       adev->dm.dmub_notify->aux_reply.length);
+ 			}
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+index 90b306a1dd687..4f2228d742f44 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+@@ -50,12 +50,6 @@
+ 
+ #define AMDGPU_DMUB_NOTIFICATION_MAX 5
+ 
+-/*
+- * DMUB Async to Sync Mechanism Status
+- */
+-#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1
+-#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2
+-#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3
+ /*
+ #include "include/amdgpu_dal_power_if.h"
+ #include "amdgpu_dm_irq.h"
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+index 594fe8a4d02b0..64dd029702926 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+@@ -412,7 +412,7 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
+ {
+ 	struct amdgpu_crtc *acrtc = NULL;
+ 	struct drm_plane *cursor_plane;
+-
++	bool is_dcn;
+ 	int res = -ENOMEM;
+ 
+ 	cursor_plane = kzalloc(sizeof(*cursor_plane), GFP_KERNEL);
+@@ -450,8 +450,14 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
+ 	acrtc->otg_inst = -1;
+ 
+ 	dm->adev->mode_info.crtcs[crtc_index] = acrtc;
+-	drm_crtc_enable_color_mgmt(&acrtc->base, MAX_COLOR_LUT_ENTRIES,
++
++	/* Don't enable DRM CRTC degamma property for DCE since it doesn't
++	 * support programmable degamma anywhere.
++	 */
++	is_dcn = dm->adev->dm.dc->caps.color.dpp.dcn_arch;
++	drm_crtc_enable_color_mgmt(&acrtc->base, is_dcn ? MAX_COLOR_LUT_ENTRIES : 0,
+ 				   true, MAX_COLOR_LUT_ENTRIES);
++
+ 	drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES);
+ 
+ 	return 0;
+diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+index 09fbb7ad53629..de3a1f3fd4f1a 100644
+--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+@@ -2392,6 +2392,26 @@ static enum bp_result get_vram_info_v25(
+ 	return result;
+ }
+ 
++static enum bp_result get_vram_info_v30(
++	struct bios_parser *bp,
++	struct dc_vram_info *info)
++{
++	struct atom_vram_info_header_v3_0 *info_v30;
++	enum bp_result result = BP_RESULT_OK;
++
++	info_v30 = GET_IMAGE(struct atom_vram_info_header_v3_0,
++						DATA_TABLES(vram_info));
++
++	if (info_v30 == NULL)
++		return BP_RESULT_BADBIOSTABLE;
++
++	info->num_chans = info_v30->channel_num;
++	info->dram_channel_width_bytes = (1 << info_v30->channel_width) / 8;
++
++	return result;
++}
++
++
+ /*
+  * get_integrated_info_v11
+  *
+@@ -3025,6 +3045,16 @@ static enum bp_result bios_parser_get_vram_info(
+ 			}
+ 			break;
+ 
++		case 3:
++			switch (revision.minor) {
++			case 0:
++				result = get_vram_info_v30(bp, info);
++				break;
++			default:
++				break;
++			}
++			break;
++
+ 		default:
+ 			return result;
+ 		}
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+index 598ce872a8d7b..0f30df523fdf5 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+@@ -1262,16 +1262,6 @@ void dcn20_pipe_control_lock(
+ 					lock,
+ 					&hw_locks,
+ 					&inst_flags);
+-	} else if (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_MAIN) {
+-		union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 };
+-		hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK;
+-		hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER;
+-		hw_lock_cmd.bits.lock_pipe = 1;
+-		hw_lock_cmd.bits.otg_inst = pipe->stream_res.tg->inst;
+-		hw_lock_cmd.bits.lock = lock;
+-		if (!lock)
+-			hw_lock_cmd.bits.should_release = 1;
+-		dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd);
+ 	} else if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {
+ 		if (lock)
+ 			pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);
+@@ -1848,7 +1838,7 @@ void dcn20_post_unlock_program_front_end(
+ 
+ 			for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_MS*1000
+ 					&& hubp->funcs->hubp_is_flip_pending(hubp); j++)
+-				mdelay(1);
++				udelay(1);
+ 		}
+ 	}
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c
+index 84e1486f3d515..39a57bcd78667 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c
+@@ -87,6 +87,7 @@ static struct hubp_funcs dcn31_hubp_funcs = {
+ 	.hubp_init = hubp3_init,
+ 	.set_unbounded_requesting = hubp31_set_unbounded_requesting,
+ 	.hubp_soft_reset = hubp31_soft_reset,
++	.hubp_set_flip_int = hubp1_set_flip_int,
+ 	.hubp_in_blank = hubp1_in_blank,
+ 	.program_extended_blank = hubp31_program_extended_blank,
+ };
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c
+index 38aa28ec6b130..9c95ad1454205 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_optc.c
+@@ -237,7 +237,7 @@ static struct timing_generator_funcs dcn314_tg_funcs = {
+ 		.clear_optc_underflow = optc1_clear_optc_underflow,
+ 		.setup_global_swap_lock = NULL,
+ 		.get_crc = optc1_get_crc,
+-		.configure_crc = optc2_configure_crc,
++		.configure_crc = optc1_configure_crc,
+ 		.set_dsc_config = optc3_set_dsc_config,
+ 		.get_dsc_status = optc2_get_dsc_status,
+ 		.set_dwb_source = NULL,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+index 1f195c5b3377d..13cd1f2e50ca3 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+@@ -187,7 +187,7 @@ bool dcn32_all_pipes_have_stream_and_plane(struct dc *dc,
+ 		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+ 
+ 		if (!pipe->stream)
+-			return false;
++			continue;
+ 
+ 		if (!pipe->plane_state)
+ 			return false;
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
+index d34e0f1314d91..bc4f48ea8d4cc 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
+@@ -1228,6 +1228,7 @@ int dcn20_populate_dml_pipes_from_context(
+ 		pipes[pipe_cnt].pipe.src.dcc = false;
+ 		pipes[pipe_cnt].pipe.src.dcc_rate = 1;
+ 		pipes[pipe_cnt].pipe.dest.synchronized_vblank_all_planes = synchronized_vblank;
++		pipes[pipe_cnt].pipe.dest.synchronize_timings = synchronized_vblank;
+ 		pipes[pipe_cnt].pipe.dest.hblank_start = timing->h_total - timing->h_front_porch;
+ 		pipes[pipe_cnt].pipe.dest.hblank_end = pipes[pipe_cnt].pipe.dest.hblank_start
+ 				- timing->h_addressable
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+index 52525833a99b9..bea380407151a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+@@ -364,7 +364,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
+ 	for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) {
+ 		v->DSCDelay[k] = dml32_DSCDelayRequirement(mode_lib->vba.DSCEnabled[k],
+ 				mode_lib->vba.ODMCombineEnabled[k], mode_lib->vba.DSCInputBitPerComponent[k],
+-				mode_lib->vba.OutputBpp[k], mode_lib->vba.HActive[k], mode_lib->vba.HTotal[k],
++				mode_lib->vba.OutputBppPerState[mode_lib->vba.VoltageLevel][k],
++				mode_lib->vba.HActive[k], mode_lib->vba.HTotal[k],
+ 				mode_lib->vba.NumberOfDSCSlices[k], mode_lib->vba.OutputFormat[k],
+ 				mode_lib->vba.Output[k], mode_lib->vba.PixelClock[k],
+ 				mode_lib->vba.PixelClockBackEnd[k]);
+@@ -717,6 +718,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
+ 
+ 	do {
+ 		MaxTotalRDBandwidth = 0;
++		DestinationLineTimesForPrefetchLessThan2 = false;
++		VRatioPrefetchMoreThanMax = false;
+ #ifdef __DML_VBA_DEBUG__
+ 		dml_print("DML::%s: Start loop: VStartup = %d\n", __func__, mode_lib->vba.VStartupLines);
+ #endif
+@@ -1627,7 +1630,7 @@ static void mode_support_configuration(struct vba_vars_st *v,
+ 				&& !mode_lib->vba.MSOOrODMSplitWithNonDPLink
+ 				&& !mode_lib->vba.NotEnoughLanesForMSO
+ 				&& mode_lib->vba.LinkCapacitySupport[i] == true && !mode_lib->vba.P2IWith420
+-				&& !mode_lib->vba.DSCOnlyIfNecessaryWithBPP
++				//&& !mode_lib->vba.DSCOnlyIfNecessaryWithBPP
+ 				&& !mode_lib->vba.DSC422NativeNotSupported
+ 				&& !mode_lib->vba.MPCCombineMethodIncompatible
+ 				&& mode_lib->vba.ODMCombine2To1SupportCheckOK[i] == true
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+index 365d290bba99e..67af8f4df8b8f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
+@@ -1746,7 +1746,7 @@ unsigned int dml32_DSCDelayRequirement(bool DSCEnabled,
+ 		}
+ 
+ 		DSCDelayRequirement_val = DSCDelayRequirement_val + (HTotal - HActive) *
+-				dml_ceil(DSCDelayRequirement_val / HActive, 1);
++				dml_ceil((double)DSCDelayRequirement_val / HActive, 1);
+ 
+ 		DSCDelayRequirement_val = DSCDelayRequirement_val * PixelClock / PixelClockBackEnd;
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c
+index a1276f6b9581b..395ae8761980f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_rq_dlg_calc_32.c
+@@ -291,8 +291,8 @@ void dml32_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib,
+ 
+ 	dml_print("DML_DLG: %s: vready_after_vcount0 = %d\n", __func__, dlg_regs->vready_after_vcount0);
+ 
+-	dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
+-	dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);
++	dst_x_after_scaler = dml_ceil(get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx), 1);
++	dst_y_after_scaler = dml_ceil(get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx), 1);
+ 
+ 	// do some adjustment on the dst_after scaler to account for odm combine mode
+ 	dml_print("DML_DLG: %s: input dst_x_after_scaler   = %d\n", __func__, dst_x_after_scaler);
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
+index 503e7d984ff03..cb34ac0af349f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
+@@ -624,7 +624,7 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib)
+ 		mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] =
+ 				dout->is_virtual;
+ 
+-		if (!dout->dsc_enable)
++		if (dout->dsc_enable)
+ 			mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp;
+ 		else
+ 			mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = 0.0;
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+index 7510d470b8643..2347f7bb73d76 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+@@ -1131,22 +1131,21 @@ static int smu_smc_hw_setup(struct smu_context *smu)
+ 	uint64_t features_supported;
+ 	int ret = 0;
+ 
+-	if (adev->in_suspend && smu_is_dpm_running(smu)) {
+-		dev_info(adev->dev, "dpm has been enabled\n");
+-		/* this is needed specifically */
+-		switch (adev->ip_versions[MP1_HWIP][0]) {
+-		case IP_VERSION(11, 0, 7):
+-		case IP_VERSION(11, 0, 11):
+-		case IP_VERSION(11, 5, 0):
+-		case IP_VERSION(11, 0, 12):
++	switch (adev->ip_versions[MP1_HWIP][0]) {
++	case IP_VERSION(11, 0, 7):
++	case IP_VERSION(11, 0, 11):
++	case IP_VERSION(11, 5, 0):
++	case IP_VERSION(11, 0, 12):
++		if (adev->in_suspend && smu_is_dpm_running(smu)) {
++			dev_info(adev->dev, "dpm has been enabled\n");
+ 			ret = smu_system_features_control(smu, true);
+ 			if (ret)
+ 				dev_err(adev->dev, "Failed system features control!\n");
+-			break;
+-		default:
+-			break;
++			return ret;
+ 		}
+-		return ret;
++		break;
++	default:
++		break;
+ 	}
+ 
+ 	ret = smu_init_display_count(smu, 0);
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+index b81c657c73860..d63cf9e3676d4 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+@@ -1372,6 +1372,14 @@ enum smu_cmn2asic_mapping_type {
+ 	CMN2ASIC_MAPPING_WORKLOAD,
+ };
+ 
++enum smu_baco_seq {
++	BACO_SEQ_BACO = 0,
++	BACO_SEQ_MSR,
++	BACO_SEQ_BAMACO,
++	BACO_SEQ_ULPS,
++	BACO_SEQ_COUNT,
++};
++
+ #define MSG_MAP(msg, index, valid_in_vf) \
+ 	[SMU_MSG_##msg] = {1, (index), (valid_in_vf)}
+ 
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h
+index a9215494dcddb..d466db6f0ad4f 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v11_0.h
+@@ -147,14 +147,6 @@ struct smu_11_5_power_context {
+ 	uint32_t	max_fast_ppt_limit;
+ };
+ 
+-enum smu_v11_0_baco_seq {
+-	BACO_SEQ_BACO = 0,
+-	BACO_SEQ_MSR,
+-	BACO_SEQ_BAMACO,
+-	BACO_SEQ_ULPS,
+-	BACO_SEQ_COUNT,
+-};
+-
+ #if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3)
+ 
+ int smu_v11_0_init_microcode(struct smu_context *smu);
+@@ -257,7 +249,7 @@ int smu_v11_0_baco_enter(struct smu_context *smu);
+ int smu_v11_0_baco_exit(struct smu_context *smu);
+ 
+ int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu,
+-				      enum smu_v11_0_baco_seq baco_seq);
++				      enum smu_baco_seq baco_seq);
+ 
+ int smu_v11_0_mode1_reset(struct smu_context *smu);
+ 
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+index f75b9688f5129..3e29fe4cc4ae4 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+@@ -123,14 +123,6 @@ struct smu_13_0_power_context {
+ 	enum smu_13_0_power_state power_state;
+ };
+ 
+-enum smu_v13_0_baco_seq {
+-	BACO_SEQ_BACO = 0,
+-	BACO_SEQ_MSR,
+-	BACO_SEQ_BAMACO,
+-	BACO_SEQ_ULPS,
+-	BACO_SEQ_COUNT,
+-};
+-
+ #if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3)
+ 
+ int smu_v13_0_init_microcode(struct smu_context *smu);
+@@ -217,6 +209,9 @@ int smu_v13_0_set_azalia_d3_pme(struct smu_context *smu);
+ int smu_v13_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu,
+ 					       struct pp_smu_nv_clock_table *max_clocks);
+ 
++int smu_v13_0_baco_set_armd3_sequence(struct smu_context *smu,
++				      enum smu_baco_seq baco_seq);
++
+ bool smu_v13_0_baco_is_support(struct smu_context *smu);
+ 
+ enum smu_baco_state smu_v13_0_baco_get_state(struct smu_context *smu);
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+index dccbd9f707238..70b560737687e 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+@@ -1576,7 +1576,7 @@ int smu_v11_0_set_azalia_d3_pme(struct smu_context *smu)
+ }
+ 
+ int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu,
+-				      enum smu_v11_0_baco_seq baco_seq)
++				      enum smu_baco_seq baco_seq)
+ {
+ 	return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ArmD3, baco_seq, NULL);
+ }
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+index 750d8da84fac4..33710dcf1eb16 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+@@ -2219,6 +2219,15 @@ int smu_v13_0_gfx_ulv_control(struct smu_context *smu,
+ 	return ret;
+ }
+ 
++int smu_v13_0_baco_set_armd3_sequence(struct smu_context *smu,
++				      enum smu_baco_seq baco_seq)
++{
++	return smu_cmn_send_smc_msg_with_param(smu,
++					       SMU_MSG_ArmD3,
++					       baco_seq,
++					       NULL);
++}
++
+ bool smu_v13_0_baco_is_support(struct smu_context *smu)
+ {
+ 	struct smu_baco_context *smu_baco = &smu->smu_baco;
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+index 29529328152d0..f0121d1716301 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+@@ -120,6 +120,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] =
+ 	MSG_MAP(Mode1Reset,			PPSMC_MSG_Mode1Reset,                  0),
+ 	MSG_MAP(PrepareMp1ForUnload,		PPSMC_MSG_PrepareMp1ForUnload,         0),
+ 	MSG_MAP(DFCstateControl,		PPSMC_MSG_SetExternalClientDfCstateAllow, 0),
++	MSG_MAP(ArmD3,				PPSMC_MSG_ArmD3,                       0),
+ };
+ 
+ static struct cmn2asic_mapping smu_v13_0_0_clk_map[SMU_CLK_COUNT] = {
+@@ -1566,6 +1567,31 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
+ 					       NULL);
+ }
+ 
++static int smu_v13_0_0_baco_enter(struct smu_context *smu)
++{
++	struct smu_baco_context *smu_baco = &smu->smu_baco;
++	struct amdgpu_device *adev = smu->adev;
++
++	if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev))
++		return smu_v13_0_baco_set_armd3_sequence(smu,
++				smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO);
++	else
++		return smu_v13_0_baco_enter(smu);
++}
++
++static int smu_v13_0_0_baco_exit(struct smu_context *smu)
++{
++	struct amdgpu_device *adev = smu->adev;
++
++	if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) {
++		/* Wait for PMFW handling for the Dstate change */
++		usleep_range(10000, 11000);
++		return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
++	} else {
++		return smu_v13_0_baco_exit(smu);
++	}
++}
++
+ static bool smu_v13_0_0_is_mode1_reset_supported(struct smu_context *smu)
+ {
+ 	struct amdgpu_device *adev = smu->adev;
+@@ -1827,8 +1853,8 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
+ 	.baco_is_support = smu_v13_0_baco_is_support,
+ 	.baco_get_state = smu_v13_0_baco_get_state,
+ 	.baco_set_state = smu_v13_0_baco_set_state,
+-	.baco_enter = smu_v13_0_baco_enter,
+-	.baco_exit = smu_v13_0_baco_exit,
++	.baco_enter = smu_v13_0_0_baco_enter,
++	.baco_exit = smu_v13_0_0_baco_exit,
+ 	.mode1_reset_is_support = smu_v13_0_0_is_mode1_reset_supported,
+ 	.mode1_reset = smu_v13_0_mode1_reset,
+ 	.set_mp1_state = smu_v13_0_0_set_mp1_state,
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+index c4102cfb734c2..d74debc584f89 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+@@ -122,6 +122,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_7_message_map[SMU_MSG_MAX_COUNT] =
+ 	MSG_MAP(PrepareMp1ForUnload,		PPSMC_MSG_PrepareMp1ForUnload,         0),
+ 	MSG_MAP(SetMGpuFanBoostLimitRpm,	PPSMC_MSG_SetMGpuFanBoostLimitRpm,     0),
+ 	MSG_MAP(DFCstateControl,		PPSMC_MSG_SetExternalClientDfCstateAllow, 0),
++	MSG_MAP(ArmD3,				PPSMC_MSG_ArmD3,                       0),
+ };
+ 
+ static struct cmn2asic_mapping smu_v13_0_7_clk_map[SMU_CLK_COUNT] = {
+@@ -1578,6 +1579,31 @@ static int smu_v13_0_7_set_mp1_state(struct smu_context *smu,
+ 	return ret;
+ }
+ 
++static int smu_v13_0_7_baco_enter(struct smu_context *smu)
++{
++	struct smu_baco_context *smu_baco = &smu->smu_baco;
++	struct amdgpu_device *adev = smu->adev;
++
++	if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev))
++		return smu_v13_0_baco_set_armd3_sequence(smu,
++				smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO);
++	else
++		return smu_v13_0_baco_enter(smu);
++}
++
++static int smu_v13_0_7_baco_exit(struct smu_context *smu)
++{
++	struct amdgpu_device *adev = smu->adev;
++
++	if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) {
++		/* Wait for PMFW handling for the Dstate change */
++		usleep_range(10000, 11000);
++		return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS);
++	} else {
++		return smu_v13_0_baco_exit(smu);
++	}
++}
++
+ static bool smu_v13_0_7_is_mode1_reset_supported(struct smu_context *smu)
+ {
+ 	struct amdgpu_device *adev = smu->adev;
+@@ -1655,8 +1681,8 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
+ 	.baco_is_support = smu_v13_0_baco_is_support,
+ 	.baco_get_state = smu_v13_0_baco_get_state,
+ 	.baco_set_state = smu_v13_0_baco_set_state,
+-	.baco_enter = smu_v13_0_baco_enter,
+-	.baco_exit = smu_v13_0_baco_exit,
++	.baco_enter = smu_v13_0_7_baco_enter,
++	.baco_exit = smu_v13_0_7_baco_exit,
+ 	.mode1_reset_is_support = smu_v13_0_7_is_mode1_reset_supported,
+ 	.mode1_reset = smu_v13_0_mode1_reset,
+ 	.set_mp1_state = smu_v13_0_7_set_mp1_state,
+diff --git a/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c b/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c
+index 3ea53bb67d3bd..bd61e20770a5b 100644
+--- a/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c
++++ b/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c
+@@ -63,23 +63,45 @@
+ ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
+ 			      u8 offset, void *buffer, size_t size)
+ {
++	u8 zero = 0;
++	char *tmpbuf = NULL;
++	/*
++	 * As sub-addressing is not supported by all adaptors,
++	 * always explicitly read from the start and discard
++	 * any bytes that come before the requested offset.
++	 * This way, no matter whether the adaptor supports it
++	 * or not, we'll end up reading the proper data.
++	 */
+ 	struct i2c_msg msgs[] = {
+ 		{
+ 			.addr = DP_DUAL_MODE_SLAVE_ADDRESS,
+ 			.flags = 0,
+ 			.len = 1,
+-			.buf = &offset,
++			.buf = &zero,
+ 		},
+ 		{
+ 			.addr = DP_DUAL_MODE_SLAVE_ADDRESS,
+ 			.flags = I2C_M_RD,
+-			.len = size,
++			.len = size + offset,
+ 			.buf = buffer,
+ 		},
+ 	};
+ 	int ret;
+ 
++	if (offset) {
++		tmpbuf = kmalloc(size + offset, GFP_KERNEL);
++		if (!tmpbuf)
++			return -ENOMEM;
++
++		msgs[1].buf = tmpbuf;
++	}
++
+ 	ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
++	if (tmpbuf)
++		memcpy(buffer, tmpbuf + offset, size);
++
++	kfree(tmpbuf);
++
+ 	if (ret < 0)
+ 		return ret;
+ 	if (ret != ARRAY_SIZE(msgs))
+@@ -208,18 +230,6 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(const struct drm_device *dev,
+ 	if (ret)
+ 		return DRM_DP_DUAL_MODE_UNKNOWN;
+ 
+-	/*
+-	 * Sigh. Some (maybe all?) type 1 adaptors are broken and ack
+-	 * the offset but ignore it, and instead they just always return
+-	 * data from the start of the HDMI ID buffer. So for a broken
+-	 * type 1 HDMI adaptor a single byte read will always give us
+-	 * 0x44, and for a type 1 DVI adaptor it should give 0x00
+-	 * (assuming it implements any registers). Fortunately neither
+-	 * of those values will match the type 2 signature of the
+-	 * DP_DUAL_MODE_ADAPTOR_ID register so we can proceed with
+-	 * the type 2 adaptor detection safely even in the presence
+-	 * of broken type 1 adaptors.
+-	 */
+ 	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_ADAPTOR_ID,
+ 				    &adaptor_id, sizeof(adaptor_id));
+ 	drm_dbg_kms(dev, "DP dual mode adaptor ID: %02x (err %zd)\n", adaptor_id, ret);
+@@ -233,11 +243,10 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(const struct drm_device *dev,
+ 				return DRM_DP_DUAL_MODE_TYPE2_DVI;
+ 		}
+ 		/*
+-		 * If neither a proper type 1 ID nor a broken type 1 adaptor
+-		 * as described above, assume type 1, but let the user know
+-		 * that we may have misdetected the type.
++		 * If not a proper type 1 ID, still assume type 1, but let
++		 * the user know that we may have misdetected the type.
+ 		 */
+-		if (!is_type1_adaptor(adaptor_id) && adaptor_id != hdmi_id[0])
++		if (!is_type1_adaptor(adaptor_id))
+ 			drm_err(dev, "Unexpected DP dual mode adaptor ID %02x\n", adaptor_id);
+ 
+ 	}
+@@ -343,10 +352,8 @@ EXPORT_SYMBOL(drm_dp_dual_mode_get_tmds_output);
+  * @enable: enable (as opposed to disable) the TMDS output buffers
+  *
+  * Set the state of the TMDS output buffers in the adaptor. For
+- * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register. As
+- * some type 1 adaptors have problems with registers (see comments
+- * in drm_dp_dual_mode_detect()) we avoid touching the register,
+- * making this function a no-op on type 1 adaptors.
++ * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register.
++ * Type1 adaptors do not support any register writes.
+  *
+  * Returns:
+  * 0 on success, negative error code on failure
+diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
+index 8214a0b1ab7f1..203bf8d6c34c4 100644
+--- a/drivers/gpu/drm/drm_drv.c
++++ b/drivers/gpu/drm/drm_drv.c
+@@ -615,7 +615,7 @@ static int drm_dev_init(struct drm_device *dev,
+ 	mutex_init(&dev->clientlist_mutex);
+ 	mutex_init(&dev->master_mutex);
+ 
+-	ret = drmm_add_action(dev, drm_dev_init_release, NULL);
++	ret = drmm_add_action_or_reset(dev, drm_dev_init_release, NULL);
+ 	if (ret)
+ 		return ret;
+ 
+diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
+index 7bb98e6a446d0..5ea5e260118c2 100644
+--- a/drivers/gpu/drm/drm_internal.h
++++ b/drivers/gpu/drm/drm_internal.h
+@@ -104,7 +104,8 @@ static inline void drm_vblank_flush_worker(struct drm_vblank_crtc *vblank)
+ 
+ static inline void drm_vblank_destroy_worker(struct drm_vblank_crtc *vblank)
+ {
+-	kthread_destroy_worker(vblank->worker);
++	if (vblank->worker)
++		kthread_destroy_worker(vblank->worker);
+ }
+ 
+ int drm_vblank_worker_init(struct drm_vblank_crtc *vblank);
+diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
+index 6b34fac3f73a0..ab4d1c878fda3 100644
+--- a/drivers/gpu/drm/imx/imx-tve.c
++++ b/drivers/gpu/drm/imx/imx-tve.c
+@@ -218,8 +218,9 @@ static int imx_tve_connector_get_modes(struct drm_connector *connector)
+ 	return ret;
+ }
+ 
+-static int imx_tve_connector_mode_valid(struct drm_connector *connector,
+-					struct drm_display_mode *mode)
++static enum drm_mode_status
++imx_tve_connector_mode_valid(struct drm_connector *connector,
++			     struct drm_display_mode *mode)
+ {
+ 	struct imx_tve *tve = con_to_tve(connector);
+ 	unsigned long rate;
+diff --git a/drivers/gpu/drm/lima/lima_devfreq.c b/drivers/gpu/drm/lima/lima_devfreq.c
+index 011be7ff51e1a..bc8fb4e38d0a7 100644
+--- a/drivers/gpu/drm/lima/lima_devfreq.c
++++ b/drivers/gpu/drm/lima/lima_devfreq.c
+@@ -112,11 +112,6 @@ int lima_devfreq_init(struct lima_device *ldev)
+ 	unsigned long cur_freq;
+ 	int ret;
+ 	const char *regulator_names[] = { "mali", NULL };
+-	const char *clk_names[] = { "core", NULL };
+-	struct dev_pm_opp_config config = {
+-		.regulator_names = regulator_names,
+-		.clk_names = clk_names,
+-	};
+ 
+ 	if (!device_property_present(dev, "operating-points-v2"))
+ 		/* Optional, continue without devfreq */
+@@ -124,7 +119,15 @@ int lima_devfreq_init(struct lima_device *ldev)
+ 
+ 	spin_lock_init(&ldevfreq->lock);
+ 
+-	ret = devm_pm_opp_set_config(dev, &config);
++	/*
++	 * clkname is set separately so it is not affected by the optional
++	 * regulator setting which may return error.
++	 */
++	ret = devm_pm_opp_set_clkname(dev, "core");
++	if (ret)
++		return ret;
++
++	ret = devm_pm_opp_set_regulators(dev, regulator_names);
+ 	if (ret) {
+ 		/* Continue if the optional regulator is missing */
+ 		if (ret != -ENODEV)
+diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c
+index 24b489b6129a0..628806423f7d2 100644
+--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
++++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
+@@ -679,6 +679,9 @@ static int adreno_system_suspend(struct device *dev)
+ 	struct msm_gpu *gpu = dev_to_gpu(dev);
+ 	int remaining, ret;
+ 
++	if (!gpu)
++		return 0;
++
+ 	suspend_scheduler(gpu);
+ 
+ 	remaining = wait_event_timeout(gpu->retire_event,
+@@ -700,7 +703,12 @@ out:
+ 
+ static int adreno_system_resume(struct device *dev)
+ {
+-	resume_scheduler(dev_to_gpu(dev));
++	struct msm_gpu *gpu = dev_to_gpu(dev);
++
++	if (!gpu)
++		return 0;
++
++	resume_scheduler(gpu);
+ 	return pm_runtime_force_resume(dev);
+ }
+ 
+diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
+index c2bfcf3f1f403..01aae792ffa98 100644
+--- a/drivers/gpu/drm/msm/msm_gpu.c
++++ b/drivers/gpu/drm/msm/msm_gpu.c
+@@ -993,4 +993,6 @@ void msm_gpu_cleanup(struct msm_gpu *gpu)
+ 	}
+ 
+ 	msm_devfreq_cleanup(gpu);
++
++	platform_set_drvdata(gpu->pdev, NULL);
+ }
+diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
+index 4d935fedd2acc..fd22cf4041af5 100644
+--- a/drivers/gpu/drm/msm/msm_gpu.h
++++ b/drivers/gpu/drm/msm/msm_gpu.h
+@@ -282,6 +282,10 @@ struct msm_gpu {
+ static inline struct msm_gpu *dev_to_gpu(struct device *dev)
+ {
+ 	struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(dev);
++
++	if (!adreno_smmu)
++		return NULL;
++
+ 	return container_of(adreno_smmu, struct msm_gpu, adreno_smmu);
+ }
+ 
+diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
+index 1e716c23019a1..eb938bfb0573c 100644
+--- a/drivers/gpu/drm/panel/panel-simple.c
++++ b/drivers/gpu/drm/panel/panel-simple.c
+@@ -2505,6 +2505,7 @@ static const struct display_timing logictechno_lt161010_2nh_timing = {
+ static const struct panel_desc logictechno_lt161010_2nh = {
+ 	.timings = &logictechno_lt161010_2nh_timing,
+ 	.num_timings = 1,
++	.bpc = 6,
+ 	.size = {
+ 		.width = 154,
+ 		.height = 86,
+@@ -2534,6 +2535,7 @@ static const struct display_timing logictechno_lt170410_2whc_timing = {
+ static const struct panel_desc logictechno_lt170410_2whc = {
+ 	.timings = &logictechno_lt170410_2whc_timing,
+ 	.num_timings = 1,
++	.bpc = 8,
+ 	.size = {
+ 		.width = 217,
+ 		.height = 136,
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+index f9aa8b96c6952..1fc04019dfd83 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+@@ -878,10 +878,14 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
+ {
+ 	struct vop2_video_port *vp = to_vop2_video_port(crtc);
+ 	struct vop2 *vop2 = vp->vop2;
++	struct drm_crtc_state *old_crtc_state;
+ 	int ret;
+ 
+ 	vop2_lock(vop2);
+ 
++	old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
++	drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
++
+ 	drm_crtc_vblank_off(crtc);
+ 
+ 	/*
+@@ -997,13 +1001,15 @@ static int vop2_plane_atomic_check(struct drm_plane *plane,
+ static void vop2_plane_atomic_disable(struct drm_plane *plane,
+ 				      struct drm_atomic_state *state)
+ {
+-	struct drm_plane_state *old_pstate = drm_atomic_get_old_plane_state(state, plane);
++	struct drm_plane_state *old_pstate = NULL;
+ 	struct vop2_win *win = to_vop2_win(plane);
+ 	struct vop2 *vop2 = win->vop2;
+ 
+ 	drm_dbg(vop2->drm, "%s disable\n", win->data->name);
+ 
+-	if (!old_pstate->crtc)
++	if (state)
++		old_pstate = drm_atomic_get_old_plane_state(state, plane);
++	if (old_pstate && !old_pstate->crtc)
+ 		return;
+ 
+ 	vop2_win_disable(win);
+diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
+index 6b25b2f4f5a30..7ef1a086a6fb9 100644
+--- a/drivers/gpu/drm/scheduler/sched_entity.c
++++ b/drivers/gpu/drm/scheduler/sched_entity.c
+@@ -207,6 +207,7 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f,
+ 	struct drm_sched_job *job = container_of(cb, struct drm_sched_job,
+ 						 finish_cb);
+ 
++	dma_fence_put(f);
+ 	INIT_WORK(&job->work, drm_sched_entity_kill_jobs_work);
+ 	schedule_work(&job->work);
+ }
+@@ -234,8 +235,10 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity)
+ 		struct drm_sched_fence *s_fence = job->s_fence;
+ 
+ 		/* Wait for all dependencies to avoid data corruptions */
+-		while ((f = drm_sched_job_dependency(job, entity)))
++		while ((f = drm_sched_job_dependency(job, entity))) {
+ 			dma_fence_wait(f, false);
++			dma_fence_put(f);
++		}
+ 
+ 		drm_sched_fence_scheduled(s_fence);
+ 		dma_fence_set_error(&s_fence->finished, -ESRCH);
+@@ -250,6 +253,7 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity)
+ 			continue;
+ 		}
+ 
++		dma_fence_get(entity->last_scheduled);
+ 		r = dma_fence_add_callback(entity->last_scheduled,
+ 					   &job->finish_cb,
+ 					   drm_sched_entity_kill_jobs_cb);
+diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
+index b45dcdfd73064..a3678178b022c 100644
+--- a/drivers/gpu/drm/vc4/vc4_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_kms.c
+@@ -198,8 +198,8 @@ vc4_hvs_get_new_global_state(struct drm_atomic_state *state)
+ 	struct drm_private_state *priv_state;
+ 
+ 	priv_state = drm_atomic_get_new_private_obj_state(state, &vc4->hvs_channels);
+-	if (IS_ERR(priv_state))
+-		return ERR_CAST(priv_state);
++	if (!priv_state)
++		return ERR_PTR(-EINVAL);
+ 
+ 	return to_vc4_hvs_state(priv_state);
+ }
+@@ -211,8 +211,8 @@ vc4_hvs_get_old_global_state(struct drm_atomic_state *state)
+ 	struct drm_private_state *priv_state;
+ 
+ 	priv_state = drm_atomic_get_old_private_obj_state(state, &vc4->hvs_channels);
+-	if (IS_ERR(priv_state))
+-		return ERR_CAST(priv_state);
++	if (!priv_state)
++		return ERR_PTR(-EINVAL);
+ 
+ 	return to_vc4_hvs_state(priv_state);
+ }
+diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
+index a176296f4fff1..e46561e095c62 100644
+--- a/drivers/i2c/busses/i2c-i801.c
++++ b/drivers/i2c/busses/i2c-i801.c
+@@ -1243,6 +1243,7 @@ static const struct {
+ 	 */
+ 	{ "Latitude 5480",      0x29 },
+ 	{ "Vostro V131",        0x1d },
++	{ "Vostro 5568",        0x29 },
+ };
+ 
+ static void register_dell_lis3lv02d_i2c_device(struct i801_priv *priv)
+diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
+index 031c78ac42e67..a24cc413c89b3 100644
+--- a/drivers/i2c/busses/i2c-tegra.c
++++ b/drivers/i2c/busses/i2c-tegra.c
+@@ -284,6 +284,7 @@ struct tegra_i2c_dev {
+ 	struct dma_chan *tx_dma_chan;
+ 	struct dma_chan *rx_dma_chan;
+ 	unsigned int dma_buf_size;
++	struct device *dma_dev;
+ 	dma_addr_t dma_phys;
+ 	void *dma_buf;
+ 
+@@ -420,7 +421,7 @@ static int tegra_i2c_dma_submit(struct tegra_i2c_dev *i2c_dev, size_t len)
+ static void tegra_i2c_release_dma(struct tegra_i2c_dev *i2c_dev)
+ {
+ 	if (i2c_dev->dma_buf) {
+-		dma_free_coherent(i2c_dev->dev, i2c_dev->dma_buf_size,
++		dma_free_coherent(i2c_dev->dma_dev, i2c_dev->dma_buf_size,
+ 				  i2c_dev->dma_buf, i2c_dev->dma_phys);
+ 		i2c_dev->dma_buf = NULL;
+ 	}
+@@ -467,10 +468,13 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
+ 
+ 	i2c_dev->tx_dma_chan = chan;
+ 
++	WARN_ON(i2c_dev->tx_dma_chan->device != i2c_dev->rx_dma_chan->device);
++	i2c_dev->dma_dev = chan->device->dev;
++
+ 	i2c_dev->dma_buf_size = i2c_dev->hw->quirks->max_write_len +
+ 				I2C_PACKET_HEADER_SIZE;
+ 
+-	dma_buf = dma_alloc_coherent(i2c_dev->dev, i2c_dev->dma_buf_size,
++	dma_buf = dma_alloc_coherent(i2c_dev->dma_dev, i2c_dev->dma_buf_size,
+ 				     &dma_phys, GFP_KERNEL | __GFP_NOWARN);
+ 	if (!dma_buf) {
+ 		dev_err(i2c_dev->dev, "failed to allocate DMA buffer\n");
+@@ -1267,7 +1271,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
+ 
+ 	if (i2c_dev->dma_mode) {
+ 		if (i2c_dev->msg_read) {
+-			dma_sync_single_for_device(i2c_dev->dev,
++			dma_sync_single_for_device(i2c_dev->dma_dev,
+ 						   i2c_dev->dma_phys,
+ 						   xfer_size, DMA_FROM_DEVICE);
+ 
+@@ -1275,7 +1279,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
+ 			if (err)
+ 				return err;
+ 		} else {
+-			dma_sync_single_for_cpu(i2c_dev->dev,
++			dma_sync_single_for_cpu(i2c_dev->dma_dev,
+ 						i2c_dev->dma_phys,
+ 						xfer_size, DMA_TO_DEVICE);
+ 		}
+@@ -1288,7 +1292,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
+ 			memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE,
+ 			       msg->buf, msg->len);
+ 
+-			dma_sync_single_for_device(i2c_dev->dev,
++			dma_sync_single_for_device(i2c_dev->dma_dev,
+ 						   i2c_dev->dma_phys,
+ 						   xfer_size, DMA_TO_DEVICE);
+ 
+@@ -1339,7 +1343,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
+ 		}
+ 
+ 		if (i2c_dev->msg_read && i2c_dev->msg_err == I2C_ERR_NONE) {
+-			dma_sync_single_for_cpu(i2c_dev->dev,
++			dma_sync_single_for_cpu(i2c_dev->dma_dev,
+ 						i2c_dev->dma_phys,
+ 						xfer_size, DMA_FROM_DEVICE);
+ 
+diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
+index c31bdd9b168e9..29c9fa99c2bd3 100644
+--- a/drivers/iio/accel/bma400_core.c
++++ b/drivers/iio/accel/bma400_core.c
+@@ -737,18 +737,6 @@ static int bma400_init(struct bma400_data *data)
+ 	unsigned int val;
+ 	int ret;
+ 
+-	/* Try to read chip_id register. It must return 0x90. */
+-	ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val);
+-	if (ret) {
+-		dev_err(data->dev, "Failed to read chip id register\n");
+-		return ret;
+-	}
+-
+-	if (val != BMA400_ID_REG_VAL) {
+-		dev_err(data->dev, "Chip ID mismatch\n");
+-		return -ENODEV;
+-	}
+-
+ 	data->regulators[BMA400_VDD_REGULATOR].supply = "vdd";
+ 	data->regulators[BMA400_VDDIO_REGULATOR].supply = "vddio";
+ 	ret = devm_regulator_bulk_get(data->dev,
+@@ -774,6 +762,18 @@ static int bma400_init(struct bma400_data *data)
+ 	if (ret)
+ 		return ret;
+ 
++	/* Try to read chip_id register. It must return 0x90. */
++	ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val);
++	if (ret) {
++		dev_err(data->dev, "Failed to read chip id register\n");
++		return ret;
++	}
++
++	if (val != BMA400_ID_REG_VAL) {
++		dev_err(data->dev, "Chip ID mismatch\n");
++		return -ENODEV;
++	}
++
+ 	ret = bma400_get_power_mode(data);
+ 	if (ret) {
+ 		dev_err(data->dev, "Failed to get the initial power-mode\n");
+diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
+index 532daaa6f943c..366e252ebeb07 100644
+--- a/drivers/iio/adc/at91_adc.c
++++ b/drivers/iio/adc/at91_adc.c
+@@ -634,8 +634,10 @@ static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *idev,
+ 	trig->ops = &at91_adc_trigger_ops;
+ 
+ 	ret = iio_trigger_register(trig);
+-	if (ret)
++	if (ret) {
++		iio_trigger_free(trig);
+ 		return NULL;
++	}
+ 
+ 	return trig;
+ }
+diff --git a/drivers/iio/adc/mp2629_adc.c b/drivers/iio/adc/mp2629_adc.c
+index 30a31f185d08d..88e947f300cfd 100644
+--- a/drivers/iio/adc/mp2629_adc.c
++++ b/drivers/iio/adc/mp2629_adc.c
+@@ -57,7 +57,8 @@ static struct iio_map mp2629_adc_maps[] = {
+ 	MP2629_MAP(SYSTEM_VOLT, "system-volt"),
+ 	MP2629_MAP(INPUT_VOLT, "input-volt"),
+ 	MP2629_MAP(BATT_CURRENT, "batt-current"),
+-	MP2629_MAP(INPUT_CURRENT, "input-current")
++	MP2629_MAP(INPUT_CURRENT, "input-current"),
++	{ }
+ };
+ 
+ static int mp2629_read_raw(struct iio_dev *indio_dev,
+@@ -74,7 +75,7 @@ static int mp2629_read_raw(struct iio_dev *indio_dev,
+ 		if (ret)
+ 			return ret;
+ 
+-		if (chan->address == MP2629_INPUT_VOLT)
++		if (chan->channel == MP2629_INPUT_VOLT)
+ 			rval &= GENMASK(6, 0);
+ 		*val = rval;
+ 		return IIO_VAL_INT;
+diff --git a/drivers/iio/pressure/ms5611.h b/drivers/iio/pressure/ms5611.h
+index cbc9349c342a9..550b75b7186fb 100644
+--- a/drivers/iio/pressure/ms5611.h
++++ b/drivers/iio/pressure/ms5611.h
+@@ -25,13 +25,6 @@ enum {
+ 	MS5607,
+ };
+ 
+-struct ms5611_chip_info {
+-	u16 prom[MS5611_PROM_WORDS_NB];
+-
+-	int (*temp_and_pressure_compensate)(struct ms5611_chip_info *chip_info,
+-					    s32 *temp, s32 *pressure);
+-};
+-
+ /*
+  * OverSampling Rate descriptor.
+  * Warning: cmd MUST be kept aligned on a word boundary (see
+@@ -50,12 +43,15 @@ struct ms5611_state {
+ 	const struct ms5611_osr *pressure_osr;
+ 	const struct ms5611_osr *temp_osr;
+ 
++	u16 prom[MS5611_PROM_WORDS_NB];
++
+ 	int (*reset)(struct ms5611_state *st);
+ 	int (*read_prom_word)(struct ms5611_state *st, int index, u16 *word);
+ 	int (*read_adc_temp_and_pressure)(struct ms5611_state *st,
+ 					  s32 *temp, s32 *pressure);
+ 
+-	struct ms5611_chip_info *chip_info;
++	int (*compensate_temp_and_pressure)(struct ms5611_state *st, s32 *temp,
++					  s32 *pressure);
+ 	struct regulator *vdd;
+ };
+ 
+diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c
+index 717521de66c47..c564a1d6cafe8 100644
+--- a/drivers/iio/pressure/ms5611_core.c
++++ b/drivers/iio/pressure/ms5611_core.c
+@@ -85,7 +85,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
+ 	struct ms5611_state *st = iio_priv(indio_dev);
+ 
+ 	for (i = 0; i < MS5611_PROM_WORDS_NB; i++) {
+-		ret = st->read_prom_word(st, i, &st->chip_info->prom[i]);
++		ret = st->read_prom_word(st, i, &st->prom[i]);
+ 		if (ret < 0) {
+ 			dev_err(&indio_dev->dev,
+ 				"failed to read prom at %d\n", i);
+@@ -93,7 +93,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
+ 		}
+ 	}
+ 
+-	if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) {
++	if (!ms5611_prom_is_valid(st->prom, MS5611_PROM_WORDS_NB)) {
+ 		dev_err(&indio_dev->dev, "PROM integrity check failed\n");
+ 		return -ENODEV;
+ 	}
+@@ -114,21 +114,20 @@ static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev,
+ 		return ret;
+ 	}
+ 
+-	return st->chip_info->temp_and_pressure_compensate(st->chip_info,
+-							   temp, pressure);
++	return st->compensate_temp_and_pressure(st, temp, pressure);
+ }
+ 
+-static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
++static int ms5611_temp_and_pressure_compensate(struct ms5611_state *st,
+ 					       s32 *temp, s32 *pressure)
+ {
+ 	s32 t = *temp, p = *pressure;
+ 	s64 off, sens, dt;
+ 
+-	dt = t - (chip_info->prom[5] << 8);
+-	off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7);
+-	sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8);
++	dt = t - (st->prom[5] << 8);
++	off = ((s64)st->prom[2] << 16) + ((st->prom[4] * dt) >> 7);
++	sens = ((s64)st->prom[1] << 15) + ((st->prom[3] * dt) >> 8);
+ 
+-	t = 2000 + ((chip_info->prom[6] * dt) >> 23);
++	t = 2000 + ((st->prom[6] * dt) >> 23);
+ 	if (t < 2000) {
+ 		s64 off2, sens2, t2;
+ 
+@@ -154,17 +153,17 @@ static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_inf
+ 	return 0;
+ }
+ 
+-static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info,
++static int ms5607_temp_and_pressure_compensate(struct ms5611_state *st,
+ 					       s32 *temp, s32 *pressure)
+ {
+ 	s32 t = *temp, p = *pressure;
+ 	s64 off, sens, dt;
+ 
+-	dt = t - (chip_info->prom[5] << 8);
+-	off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6);
+-	sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7);
++	dt = t - (st->prom[5] << 8);
++	off = ((s64)st->prom[2] << 17) + ((st->prom[4] * dt) >> 6);
++	sens = ((s64)st->prom[1] << 16) + ((st->prom[3] * dt) >> 7);
+ 
+-	t = 2000 + ((chip_info->prom[6] * dt) >> 23);
++	t = 2000 + ((st->prom[6] * dt) >> 23);
+ 	if (t < 2000) {
+ 		s64 off2, sens2, t2, tmp;
+ 
+@@ -342,15 +341,6 @@ static int ms5611_write_raw(struct iio_dev *indio_dev,
+ 
+ static const unsigned long ms5611_scan_masks[] = {0x3, 0};
+ 
+-static struct ms5611_chip_info chip_info_tbl[] = {
+-	[MS5611] = {
+-		.temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate,
+-	},
+-	[MS5607] = {
+-		.temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate,
+-	}
+-};
+-
+ static const struct iio_chan_spec ms5611_channels[] = {
+ 	{
+ 		.type = IIO_PRESSURE,
+@@ -433,7 +423,20 @@ int ms5611_probe(struct iio_dev *indio_dev, struct device *dev,
+ 	struct ms5611_state *st = iio_priv(indio_dev);
+ 
+ 	mutex_init(&st->lock);
+-	st->chip_info = &chip_info_tbl[type];
++
++	switch (type) {
++	case MS5611:
++		st->compensate_temp_and_pressure =
++			ms5611_temp_and_pressure_compensate;
++		break;
++	case MS5607:
++		st->compensate_temp_and_pressure =
++			ms5607_temp_and_pressure_compensate;
++		break;
++	default:
++		return -EINVAL;
++	}
++
+ 	st->temp_osr =
+ 		&ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1];
+ 	st->pressure_osr =
+diff --git a/drivers/iio/pressure/ms5611_spi.c b/drivers/iio/pressure/ms5611_spi.c
+index 432e912096f42..a0a7205c9c3a4 100644
+--- a/drivers/iio/pressure/ms5611_spi.c
++++ b/drivers/iio/pressure/ms5611_spi.c
+@@ -91,7 +91,7 @@ static int ms5611_spi_probe(struct spi_device *spi)
+ 	spi_set_drvdata(spi, indio_dev);
+ 
+ 	spi->mode = SPI_MODE_0;
+-	spi->max_speed_hz = 20000000;
++	spi->max_speed_hz = min(spi->max_speed_hz, 20000000U);
+ 	spi->bits_per_word = 8;
+ 	ret = spi_setup(spi);
+ 	if (ret < 0)
+diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c
+index d6c5e96447383..6b05eed41612b 100644
+--- a/drivers/iio/trigger/iio-trig-sysfs.c
++++ b/drivers/iio/trigger/iio-trig-sysfs.c
+@@ -203,9 +203,13 @@ static int iio_sysfs_trigger_remove(int id)
+ 
+ static int __init iio_sysfs_trig_init(void)
+ {
++	int ret;
+ 	device_initialize(&iio_sysfs_trig_dev);
+ 	dev_set_name(&iio_sysfs_trig_dev, "iio_sysfs_trigger");
+-	return device_add(&iio_sysfs_trig_dev);
++	ret = device_add(&iio_sysfs_trig_dev);
++	if (ret)
++		put_device(&iio_sysfs_trig_dev);
++	return ret;
+ }
+ module_init(iio_sysfs_trig_init);
+ 
+diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c
+index 94b94cca48709..15ee920811187 100644
+--- a/drivers/infiniband/hw/efa/efa_main.c
++++ b/drivers/infiniband/hw/efa/efa_main.c
+@@ -1,6 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+ /*
+- * Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved.
++ * Copyright 2018-2022 Amazon.com, Inc. or its affiliates. All rights reserved.
+  */
+ 
+ #include <linux/module.h>
+@@ -14,10 +14,12 @@
+ 
+ #define PCI_DEV_ID_EFA0_VF 0xefa0
+ #define PCI_DEV_ID_EFA1_VF 0xefa1
++#define PCI_DEV_ID_EFA2_VF 0xefa2
+ 
+ static const struct pci_device_id efa_pci_tbl[] = {
+ 	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA0_VF) },
+ 	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA1_VF) },
++	{ PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA2_VF) },
+ 	{ }
+ };
+ 
+diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
+index b86de1312512b..84b87526b7ba3 100644
+--- a/drivers/input/joystick/iforce/iforce-main.c
++++ b/drivers/input/joystick/iforce/iforce-main.c
+@@ -273,22 +273,22 @@ int iforce_init_device(struct device *parent, u16 bustype,
+  * Get device info.
+  */
+ 
+-	if (!iforce_get_id_packet(iforce, 'M', buf, &len) || len < 3)
++	if (!iforce_get_id_packet(iforce, 'M', buf, &len) && len >= 3)
+ 		input_dev->id.vendor = get_unaligned_le16(buf + 1);
+ 	else
+ 		dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n");
+ 
+-	if (!iforce_get_id_packet(iforce, 'P', buf, &len) || len < 3)
++	if (!iforce_get_id_packet(iforce, 'P', buf, &len) && len >= 3)
+ 		input_dev->id.product = get_unaligned_le16(buf + 1);
+ 	else
+ 		dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n");
+ 
+-	if (!iforce_get_id_packet(iforce, 'B', buf, &len) || len < 3)
++	if (!iforce_get_id_packet(iforce, 'B', buf, &len) && len >= 3)
+ 		iforce->device_memory.end = get_unaligned_le16(buf + 1);
+ 	else
+ 		dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n");
+ 
+-	if (!iforce_get_id_packet(iforce, 'N', buf, &len) || len < 2)
++	if (!iforce_get_id_packet(iforce, 'N', buf, &len) && len >= 2)
+ 		ff_effects = buf[1];
+ 	else
+ 		dev_warn(&iforce->dev->dev, "Device does not respond to id packet N\n");
+diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
+index 3fc0a89cc785c..f132d6dfc25eb 100644
+--- a/drivers/input/serio/i8042.c
++++ b/drivers/input/serio/i8042.c
+@@ -1543,8 +1543,6 @@ static int i8042_probe(struct platform_device *dev)
+ {
+ 	int error;
+ 
+-	i8042_platform_device = dev;
+-
+ 	if (i8042_reset == I8042_RESET_ALWAYS) {
+ 		error = i8042_controller_selftest();
+ 		if (error)
+@@ -1582,7 +1580,6 @@ static int i8042_probe(struct platform_device *dev)
+ 	i8042_free_aux_ports();	/* in case KBD failed but AUX not */
+ 	i8042_free_irqs();
+ 	i8042_controller_reset(false);
+-	i8042_platform_device = NULL;
+ 
+ 	return error;
+ }
+@@ -1592,7 +1589,6 @@ static int i8042_remove(struct platform_device *dev)
+ 	i8042_unregister_ports();
+ 	i8042_free_irqs();
+ 	i8042_controller_reset(false);
+-	i8042_platform_device = NULL;
+ 
+ 	return 0;
+ }
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index ecc0b05b2796c..e47700674978c 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -954,11 +954,9 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
+ 
+ 			domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
+ 			pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
+-			if (domain_use_first_level(domain)) {
+-				pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US;
+-				if (iommu_is_dma_domain(&domain->domain))
+-					pteval |= DMA_FL_PTE_ACCESS;
+-			}
++			if (domain_use_first_level(domain))
++				pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US | DMA_FL_PTE_ACCESS;
++
+ 			if (cmpxchg64(&pte->val, 0ULL, pteval))
+ 				/* Someone else set it while we were thinking; use theirs. */
+ 				free_pgtable_page(tmp_page);
+diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
+index c5e7e8b020a57..12584c7981ac4 100644
+--- a/drivers/iommu/intel/pasid.c
++++ b/drivers/iommu/intel/pasid.c
+@@ -652,7 +652,7 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
+ 	 * Since it is a second level only translation setup, we should
+ 	 * set SRE bit as well (addresses are expected to be GPAs).
+ 	 */
+-	if (pasid != PASID_RID2PASID)
++	if (pasid != PASID_RID2PASID && ecap_srs(iommu->ecap))
+ 		pasid_set_sre(pte);
+ 	pasid_set_present(pte);
+ 	spin_unlock(&iommu->lock);
+@@ -695,7 +695,8 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
+ 	 * We should set SRE bit as well since the addresses are expected
+ 	 * to be GPAs.
+ 	 */
+-	pasid_set_sre(pte);
++	if (ecap_srs(iommu->ecap))
++		pasid_set_sre(pte);
+ 	pasid_set_present(pte);
+ 	spin_unlock(&iommu->lock);
+ 
+diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
+index 7ea0100f218a0..90ee56d07a6e9 100644
+--- a/drivers/isdn/mISDN/core.c
++++ b/drivers/isdn/mISDN/core.c
+@@ -222,7 +222,7 @@ mISDN_register_device(struct mISDNdevice *dev,
+ 
+ 	err = get_free_devid();
+ 	if (err < 0)
+-		goto error1;
++		return err;
+ 	dev->id = err;
+ 
+ 	device_initialize(&dev->dev);
+diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c
+index c3b2c99b5cd5c..cfbcd9e973c2e 100644
+--- a/drivers/isdn/mISDN/dsp_pipeline.c
++++ b/drivers/isdn/mISDN/dsp_pipeline.c
+@@ -77,6 +77,7 @@ int mISDN_dsp_element_register(struct mISDN_dsp_element *elem)
+ 	if (!entry)
+ 		return -ENOMEM;
+ 
++	INIT_LIST_HEAD(&entry->list);
+ 	entry->elem = elem;
+ 
+ 	entry->dev.class = elements_class;
+@@ -107,7 +108,7 @@ err2:
+ 	device_unregister(&entry->dev);
+ 	return ret;
+ err1:
+-	kfree(entry);
++	put_device(&entry->dev);
+ 	return ret;
+ }
+ EXPORT_SYMBOL(mISDN_dsp_element_register);
+diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
+index 9c5ef818ca365..bb786c39545ec 100644
+--- a/drivers/md/dm-bufio.c
++++ b/drivers/md/dm-bufio.c
+@@ -1858,6 +1858,8 @@ bad:
+ 	dm_io_client_destroy(c->dm_io);
+ bad_dm_io:
+ 	mutex_destroy(&c->lock);
++	if (c->no_sleep)
++		static_branch_dec(&no_sleep_enabled);
+ 	kfree(c);
+ bad_client:
+ 	return ERR_PTR(r);
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index 159c6806c19b8..2653516bcdef5 100644
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -3630,6 +3630,7 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits)
+ 	limits->physical_block_size =
+ 		max_t(unsigned, limits->physical_block_size, cc->sector_size);
+ 	limits->io_min = max_t(unsigned, limits->io_min, cc->sector_size);
++	limits->dma_alignment = limits->logical_block_size - 1;
+ }
+ 
+ static struct target_type crypt_target = {
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 98976aaa9db9a..9cd410d8fbeb4 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -655,7 +655,7 @@ static void list_version_get_needed(struct target_type *tt, void *needed_param)
+     size_t *needed = needed_param;
+ 
+     *needed += sizeof(struct dm_target_versions);
+-    *needed += strlen(tt->name);
++    *needed += strlen(tt->name) + 1;
+     *needed += ALIGN_MASK;
+ }
+ 
+@@ -720,7 +720,7 @@ static int __list_versions(struct dm_ioctl *param, size_t param_size, const char
+ 	iter_info.old_vers = NULL;
+ 	iter_info.vers = vers;
+ 	iter_info.flags = 0;
+-	iter_info.end = (char *)vers+len;
++	iter_info.end = (char *)vers + needed;
+ 
+ 	/*
+ 	 * Now loop through filling out the names & versions.
+diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c
+index 8f2de1893245a..8f970fe9bb6e4 100644
+--- a/drivers/misc/vmw_vmci/vmci_queue_pair.c
++++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c
+@@ -854,6 +854,7 @@ static int qp_notify_peer_local(bool attach, struct vmci_handle handle)
+ 	u32 context_id = vmci_get_context_id();
+ 	struct vmci_event_qp ev;
+ 
++	memset(&ev, 0, sizeof(ev));
+ 	ev.msg.hdr.dst = vmci_make_handle(context_id, VMCI_EVENT_HANDLER);
+ 	ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID,
+ 					  VMCI_CONTEXT_RESOURCE_ID);
+@@ -1467,6 +1468,7 @@ static int qp_notify_peer(bool attach,
+ 	 * kernel.
+ 	 */
+ 
++	memset(&ev, 0, sizeof(ev));
+ 	ev.msg.hdr.dst = vmci_make_handle(peer_id, VMCI_EVENT_HANDLER);
+ 	ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID,
+ 					  VMCI_CONTEXT_RESOURCE_ID);
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index ef53a25788248..3d96493257257 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -1134,7 +1134,13 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
+ 		mmc_power_cycle(host, ocr);
+ 	} else {
+ 		bit = fls(ocr) - 1;
+-		ocr &= 3 << bit;
++		/*
++		 * The bit variable represents the highest voltage bit set in
++		 * the OCR register.
++		 * To keep a range of 2 values (e.g. 3.2V/3.3V and 3.3V/3.4V),
++		 * we must shift the mask '3' with (bit - 1).
++		 */
++		ocr &= 3 << (bit - 1);
+ 		if (bit != host->ios.vdd)
+ 			dev_warn(mmc_dev(host), "exceeding card's volts\n");
+ 	}
+diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
+index b6f4bd3d93cd8..c55a77a10c632 100644
+--- a/drivers/mmc/host/sdhci-pci-core.c
++++ b/drivers/mmc/host/sdhci-pci-core.c
+@@ -1728,6 +1728,8 @@ static int amd_probe(struct sdhci_pci_chip *chip)
+ 		}
+ 	}
+ 
++	pci_dev_put(smbus_dev);
++
+ 	if (gen == AMD_CHIPSET_BEFORE_ML || gen == AMD_CHIPSET_CZ)
+ 		chip->quirks2 |= SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD;
+ 
+diff --git a/drivers/mmc/host/sdhci-pci-o2micro.c b/drivers/mmc/host/sdhci-pci-o2micro.c
+index 0d4d343dbb77d..7a7cce6bc44d2 100644
+--- a/drivers/mmc/host/sdhci-pci-o2micro.c
++++ b/drivers/mmc/host/sdhci-pci-o2micro.c
+@@ -32,6 +32,7 @@
+ #define O2_SD_CAPS		0xE0
+ #define O2_SD_ADMA1		0xE2
+ #define O2_SD_ADMA2		0xE7
++#define O2_SD_MISC_CTRL2	0xF0
+ #define O2_SD_INF_MOD		0xF1
+ #define O2_SD_MISC_CTRL4	0xFC
+ #define O2_SD_MISC_CTRL		0x1C0
+@@ -874,6 +875,12 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip)
+ 		/* Set Tuning Windows to 5 */
+ 		pci_write_config_byte(chip->pdev,
+ 				O2_SD_TUNING_CTRL, 0x55);
++		//Adjust 1st and 2nd CD debounce time
++		pci_read_config_dword(chip->pdev, O2_SD_MISC_CTRL2, &scratch_32);
++		scratch_32 &= 0xFFE7FFFF;
++		scratch_32 |= 0x00180000;
++		pci_write_config_dword(chip->pdev, O2_SD_MISC_CTRL2, scratch_32);
++		pci_write_config_dword(chip->pdev, O2_SD_DETECT_SETTING, 1);
+ 		/* Lock WP */
+ 		ret = pci_read_config_byte(chip->pdev,
+ 					   O2_SD_LOCK_WP, &scratch);
+diff --git a/drivers/mtd/nand/onenand/Kconfig b/drivers/mtd/nand/onenand/Kconfig
+index 34d9a7a82ad4e..c94bf483541e1 100644
+--- a/drivers/mtd/nand/onenand/Kconfig
++++ b/drivers/mtd/nand/onenand/Kconfig
+@@ -26,6 +26,7 @@ config MTD_ONENAND_OMAP2
+ 	tristate "OneNAND on OMAP2/OMAP3 support"
+ 	depends on ARCH_OMAP2 || ARCH_OMAP3 || (COMPILE_TEST && ARM)
+ 	depends on OF || COMPILE_TEST
++	depends on OMAP_GPMC
+ 	help
+ 	  Support for a OneNAND flash device connected to an OMAP2/OMAP3 SoC
+ 	  via the GPMC memory controller.
+diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
+index 8f80019a9f016..198a44794d2dc 100644
+--- a/drivers/mtd/nand/raw/qcom_nandc.c
++++ b/drivers/mtd/nand/raw/qcom_nandc.c
+@@ -3167,16 +3167,18 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
+ 
+ 	ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
+ 	if (ret)
+-		nand_cleanup(chip);
++		goto err;
+ 
+ 	if (nandc->props->use_codeword_fixup) {
+ 		ret = qcom_nand_host_parse_boot_partitions(nandc, host, dn);
+-		if (ret) {
+-			nand_cleanup(chip);
+-			return ret;
+-		}
++		if (ret)
++			goto err;
+ 	}
+ 
++	return 0;
++
++err:
++	nand_cleanup(chip);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+index 6a356a6cee15a..41c8213484769 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -4545,13 +4545,19 @@ static struct pci_driver ena_pci_driver = {
+ 
+ static int __init ena_init(void)
+ {
++	int ret;
++
+ 	ena_wq = create_singlethread_workqueue(DRV_MODULE_NAME);
+ 	if (!ena_wq) {
+ 		pr_err("Failed to create workqueue\n");
+ 		return -ENOMEM;
+ 	}
+ 
+-	return pci_register_driver(&ena_pci_driver);
++	ret = pci_register_driver(&ena_pci_driver);
++	if (ret)
++		destroy_workqueue(ena_wq);
++
++	return ret;
+ }
+ 
+ static void __exit ena_cleanup(void)
+diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c
+index e461f47640660..e23d8734d4e44 100644
+--- a/drivers/net/ethernet/atheros/ag71xx.c
++++ b/drivers/net/ethernet/atheros/ag71xx.c
+@@ -1427,7 +1427,7 @@ static int ag71xx_open(struct net_device *ndev)
+ 	if (ret) {
+ 		netif_err(ag, link, ndev, "phylink_of_phy_connect filed with err: %i\n",
+ 			  ret);
+-		goto err;
++		return ret;
+ 	}
+ 
+ 	max_frame_len = ag71xx_max_frame_len(ndev->mtu);
+@@ -1448,6 +1448,7 @@ static int ag71xx_open(struct net_device *ndev)
+ 
+ err:
+ 	ag71xx_rings_cleanup(ag);
++	phylink_disconnect_phy(ag->phylink);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
+index 93580484a3f4e..91c054eef7018 100644
+--- a/drivers/net/ethernet/broadcom/bgmac.c
++++ b/drivers/net/ethernet/broadcom/bgmac.c
+@@ -1568,7 +1568,6 @@ void bgmac_enet_remove(struct bgmac *bgmac)
+ 	phy_disconnect(bgmac->net_dev->phydev);
+ 	netif_napi_del(&bgmac->napi);
+ 	bgmac_dma_free(bgmac);
+-	free_netdev(bgmac->net_dev);
+ }
+ EXPORT_SYMBOL_GPL(bgmac_enet_remove);
+ 
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index be5df8fca264e..57cabe20aa122 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -9983,17 +9983,12 @@ static int bnxt_try_recover_fw(struct bnxt *bp)
+ 	return -ENODEV;
+ }
+ 
+-int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset)
++static void bnxt_clear_reservations(struct bnxt *bp, bool fw_reset)
+ {
+ 	struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
+-	int rc;
+ 
+ 	if (!BNXT_NEW_RM(bp))
+-		return 0; /* no resource reservations required */
+-
+-	rc = bnxt_hwrm_func_resc_qcaps(bp, true);
+-	if (rc)
+-		netdev_err(bp->dev, "resc_qcaps failed\n");
++		return; /* no resource reservations required */
+ 
+ 	hw_resc->resv_cp_rings = 0;
+ 	hw_resc->resv_stat_ctxs = 0;
+@@ -10006,6 +10001,20 @@ int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset)
+ 		bp->tx_nr_rings = 0;
+ 		bp->rx_nr_rings = 0;
+ 	}
++}
++
++int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset)
++{
++	int rc;
++
++	if (!BNXT_NEW_RM(bp))
++		return 0; /* no resource reservations required */
++
++	rc = bnxt_hwrm_func_resc_qcaps(bp, true);
++	if (rc)
++		netdev_err(bp->dev, "resc_qcaps failed\n");
++
++	bnxt_clear_reservations(bp, fw_reset);
+ 
+ 	return rc;
+ }
+@@ -13913,7 +13922,9 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
+ 	pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT;
+ 	struct net_device *netdev = pci_get_drvdata(pdev);
+ 	struct bnxt *bp = netdev_priv(netdev);
+-	int err = 0, off;
++	int retry = 0;
++	int err = 0;
++	int off;
+ 
+ 	netdev_info(bp->dev, "PCI Slot Reset\n");
+ 
+@@ -13941,11 +13952,36 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
+ 		pci_restore_state(pdev);
+ 		pci_save_state(pdev);
+ 
++		bnxt_inv_fw_health_reg(bp);
++		bnxt_try_map_fw_health_reg(bp);
++
++		/* In some PCIe AER scenarios, firmware may take up to
++		 * 10 seconds to become ready in the worst case.
++		 */
++		do {
++			err = bnxt_try_recover_fw(bp);
++			if (!err)
++				break;
++			retry++;
++		} while (retry < BNXT_FW_SLOT_RESET_RETRY);
++
++		if (err) {
++			dev_err(&pdev->dev, "Firmware not ready\n");
++			goto reset_exit;
++		}
++
+ 		err = bnxt_hwrm_func_reset(bp);
+ 		if (!err)
+ 			result = PCI_ERS_RESULT_RECOVERED;
++
++		bnxt_ulp_irq_stop(bp);
++		bnxt_clear_int_mode(bp);
++		err = bnxt_init_int_mode(bp);
++		bnxt_ulp_irq_restart(bp, err);
+ 	}
+ 
++reset_exit:
++	bnxt_clear_reservations(bp, true);
+ 	rtnl_unlock();
+ 
+ 	return result;
+@@ -14001,8 +14037,16 @@ static struct pci_driver bnxt_pci_driver = {
+ 
+ static int __init bnxt_init(void)
+ {
++	int err;
++
+ 	bnxt_debug_init();
+-	return pci_register_driver(&bnxt_pci_driver);
++	err = pci_register_driver(&bnxt_pci_driver);
++	if (err) {
++		bnxt_debug_exit();
++		return err;
++	}
++
++	return 0;
+ }
+ 
+ static void __exit bnxt_exit(void)
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+index b1b17f9113006..d5fa43cfe5248 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+@@ -1621,6 +1621,7 @@ struct bnxt_fw_health {
+ 
+ #define BNXT_FW_RETRY			5
+ #define BNXT_FW_IF_RETRY		10
++#define BNXT_FW_SLOT_RESET_RETRY	4
+ 
+ enum board_idx {
+ 	BCM57301,
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
+index b01d42928a53c..132442f16fe67 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
+@@ -476,7 +476,8 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx)
+ 		memset(ctx->resp, 0, PAGE_SIZE);
+ 
+ 	req_type = le16_to_cpu(ctx->req->req_type);
+-	if (BNXT_NO_FW_ACCESS(bp) && req_type != HWRM_FUNC_RESET) {
++	if (BNXT_NO_FW_ACCESS(bp) &&
++	    (req_type != HWRM_FUNC_RESET && req_type != HWRM_VER_GET)) {
+ 		netdev_dbg(bp->dev, "hwrm req_type 0x%x skipped, FW channel down\n",
+ 			   req_type);
+ 		goto exit;
+diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
+index bee35ce601710..bf6a721430400 100644
+--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
++++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
+@@ -1799,13 +1799,10 @@ static int liquidio_open(struct net_device *netdev)
+ 
+ 	ifstate_set(lio, LIO_IFSTATE_RUNNING);
+ 
+-	if (OCTEON_CN23XX_PF(oct)) {
+-		if (!oct->msix_on)
+-			if (setup_tx_poll_fn(netdev))
+-				return -1;
+-	} else {
+-		if (setup_tx_poll_fn(netdev))
+-			return -1;
++	if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on)) {
++		ret = setup_tx_poll_fn(netdev);
++		if (ret)
++			goto err_poll;
+ 	}
+ 
+ 	netif_tx_start_all_queues(netdev);
+@@ -1818,7 +1815,7 @@ static int liquidio_open(struct net_device *netdev)
+ 	/* tell Octeon to start forwarding packets to host */
+ 	ret = send_rx_ctrl_cmd(lio, 1);
+ 	if (ret)
+-		return ret;
++		goto err_rx_ctrl;
+ 
+ 	/* start periodical statistics fetch */
+ 	INIT_DELAYED_WORK(&lio->stats_wk.work, lio_fetch_stats);
+@@ -1829,6 +1826,27 @@ static int liquidio_open(struct net_device *netdev)
+ 	dev_info(&oct->pci_dev->dev, "%s interface is opened\n",
+ 		 netdev->name);
+ 
++	return 0;
++
++err_rx_ctrl:
++	if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on))
++		cleanup_tx_poll_fn(netdev);
++err_poll:
++	if (lio->ptp_clock) {
++		ptp_clock_unregister(lio->ptp_clock);
++		lio->ptp_clock = NULL;
++	}
++
++	if (oct->props[lio->ifidx].napi_enabled == 1) {
++		list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list)
++			napi_disable(napi);
++
++		oct->props[lio->ifidx].napi_enabled = 0;
++
++		if (OCTEON_CN23XX_PF(oct))
++			oct->droq[0]->ops.poll_mode = 0;
++	}
++
+ 	return ret;
+ }
+ 
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+index 94f80e1c4020c..bf7daab886895 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+@@ -790,7 +790,6 @@ struct hnae3_knic_private_info {
+ 	const struct hnae3_dcb_ops *dcb_ops;
+ 
+ 	u16 int_rl_setting;
+-	enum pkt_hash_types rss_type;
+ 	void __iomem *io_base;
+ };
+ 
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c
+index e23729ac3bb85..ae2736549526b 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c
+@@ -191,23 +191,6 @@ u32 hclge_comm_get_rss_key_size(struct hnae3_handle *handle)
+ 	return HCLGE_COMM_RSS_KEY_SIZE;
+ }
+ 
+-void hclge_comm_get_rss_type(struct hnae3_handle *nic,
+-			     struct hclge_comm_rss_tuple_cfg *rss_tuple_sets)
+-{
+-	if (rss_tuple_sets->ipv4_tcp_en ||
+-	    rss_tuple_sets->ipv4_udp_en ||
+-	    rss_tuple_sets->ipv4_sctp_en ||
+-	    rss_tuple_sets->ipv6_tcp_en ||
+-	    rss_tuple_sets->ipv6_udp_en ||
+-	    rss_tuple_sets->ipv6_sctp_en)
+-		nic->kinfo.rss_type = PKT_HASH_TYPE_L4;
+-	else if (rss_tuple_sets->ipv4_fragment_en ||
+-		 rss_tuple_sets->ipv6_fragment_en)
+-		nic->kinfo.rss_type = PKT_HASH_TYPE_L3;
+-	else
+-		nic->kinfo.rss_type = PKT_HASH_TYPE_NONE;
+-}
+-
+ int hclge_comm_parse_rss_hfunc(struct hclge_comm_rss_cfg *rss_cfg,
+ 			       const u8 hfunc, u8 *hash_algo)
+ {
+@@ -344,9 +327,6 @@ int hclge_comm_set_rss_input_tuple(struct hnae3_handle *nic,
+ 	req->ipv6_sctp_en = rss_cfg->rss_tuple_sets.ipv6_sctp_en;
+ 	req->ipv6_fragment_en = rss_cfg->rss_tuple_sets.ipv6_fragment_en;
+ 
+-	if (is_pf)
+-		hclge_comm_get_rss_type(nic, &rss_cfg->rss_tuple_sets);
+-
+ 	ret = hclge_comm_cmd_send(hw, &desc, 1);
+ 	if (ret)
+ 		dev_err(&hw->cmq.csq.pdev->dev,
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.h b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.h
+index 946d166a452db..92af3d2980d3c 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.h
+@@ -95,8 +95,6 @@ struct hclge_comm_rss_tc_mode_cmd {
+ };
+ 
+ u32 hclge_comm_get_rss_key_size(struct hnae3_handle *handle);
+-void hclge_comm_get_rss_type(struct hnae3_handle *nic,
+-			     struct hclge_comm_rss_tuple_cfg *rss_tuple_sets);
+ void hclge_comm_rss_indir_init_cfg(struct hnae3_ae_dev *ae_dev,
+ 				   struct hclge_comm_rss_cfg *rss_cfg);
+ int hclge_comm_get_rss_tuple(struct hclge_comm_rss_cfg *rss_cfg, int flow_type,
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+index 35d70041b9e84..44d4265f109a8 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -105,26 +105,28 @@ static const struct pci_device_id hns3_pci_tbl[] = {
+ };
+ MODULE_DEVICE_TABLE(pci, hns3_pci_tbl);
+ 
+-#define HNS3_RX_PTYPE_ENTRY(ptype, l, s, t) \
++#define HNS3_RX_PTYPE_ENTRY(ptype, l, s, t, h) \
+ 	{	ptype, \
+ 		l, \
+ 		CHECKSUM_##s, \
+ 		HNS3_L3_TYPE_##t, \
+-		1 }
++		1, \
++		h}
+ 
+ #define HNS3_RX_PTYPE_UNUSED_ENTRY(ptype) \
+-		{ ptype, 0, CHECKSUM_NONE, HNS3_L3_TYPE_PARSE_FAIL, 0 }
++		{ ptype, 0, CHECKSUM_NONE, HNS3_L3_TYPE_PARSE_FAIL, 0, \
++		  PKT_HASH_TYPE_NONE }
+ 
+ static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = {
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(0),
+-	HNS3_RX_PTYPE_ENTRY(1, 0, COMPLETE, ARP),
+-	HNS3_RX_PTYPE_ENTRY(2, 0, COMPLETE, RARP),
+-	HNS3_RX_PTYPE_ENTRY(3, 0, COMPLETE, LLDP),
+-	HNS3_RX_PTYPE_ENTRY(4, 0, COMPLETE, PARSE_FAIL),
+-	HNS3_RX_PTYPE_ENTRY(5, 0, COMPLETE, PARSE_FAIL),
+-	HNS3_RX_PTYPE_ENTRY(6, 0, COMPLETE, PARSE_FAIL),
+-	HNS3_RX_PTYPE_ENTRY(7, 0, COMPLETE, CNM),
+-	HNS3_RX_PTYPE_ENTRY(8, 0, NONE, PARSE_FAIL),
++	HNS3_RX_PTYPE_ENTRY(1, 0, COMPLETE, ARP, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(2, 0, COMPLETE, RARP, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(3, 0, COMPLETE, LLDP, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(4, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(5, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(6, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(7, 0, COMPLETE, CNM, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(8, 0, NONE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(9),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(10),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(11),
+@@ -132,36 +134,36 @@ static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = {
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(13),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(14),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(15),
+-	HNS3_RX_PTYPE_ENTRY(16, 0, COMPLETE, PARSE_FAIL),
+-	HNS3_RX_PTYPE_ENTRY(17, 0, COMPLETE, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(18, 0, COMPLETE, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(19, 0, UNNECESSARY, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(20, 0, UNNECESSARY, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(21, 0, NONE, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(22, 0, UNNECESSARY, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(23, 0, NONE, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(24, 0, NONE, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(25, 0, UNNECESSARY, IPV4),
++	HNS3_RX_PTYPE_ENTRY(16, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(17, 0, COMPLETE, IPV4, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(18, 0, COMPLETE, IPV4, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(19, 0, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(20, 0, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(21, 0, NONE, IPV4, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(22, 0, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(23, 0, NONE, IPV4, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(24, 0, NONE, IPV4, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(25, 0, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(26),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(27),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(28),
+-	HNS3_RX_PTYPE_ENTRY(29, 0, COMPLETE, PARSE_FAIL),
+-	HNS3_RX_PTYPE_ENTRY(30, 0, COMPLETE, PARSE_FAIL),
+-	HNS3_RX_PTYPE_ENTRY(31, 0, COMPLETE, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(32, 0, COMPLETE, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(33, 1, UNNECESSARY, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(34, 1, UNNECESSARY, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(35, 1, UNNECESSARY, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(36, 0, COMPLETE, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(37, 0, COMPLETE, IPV4),
++	HNS3_RX_PTYPE_ENTRY(29, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(30, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(31, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(32, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(33, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(34, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(35, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(36, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(37, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(38),
+-	HNS3_RX_PTYPE_ENTRY(39, 0, COMPLETE, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(40, 0, COMPLETE, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(41, 1, UNNECESSARY, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(42, 1, UNNECESSARY, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(43, 1, UNNECESSARY, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(44, 0, COMPLETE, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(45, 0, COMPLETE, IPV6),
++	HNS3_RX_PTYPE_ENTRY(39, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(40, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(41, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(42, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(43, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(44, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(45, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(46),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(47),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(48),
+@@ -227,35 +229,35 @@ static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = {
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(108),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(109),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(110),
+-	HNS3_RX_PTYPE_ENTRY(111, 0, COMPLETE, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(112, 0, COMPLETE, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(113, 0, UNNECESSARY, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(114, 0, UNNECESSARY, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(115, 0, NONE, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(116, 0, UNNECESSARY, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(117, 0, NONE, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(118, 0, NONE, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(119, 0, UNNECESSARY, IPV6),
++	HNS3_RX_PTYPE_ENTRY(111, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(112, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(113, 0, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(114, 0, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(115, 0, NONE, IPV6, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(116, 0, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(117, 0, NONE, IPV6, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(118, 0, NONE, IPV6, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(119, 0, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(120),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(121),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(122),
+-	HNS3_RX_PTYPE_ENTRY(123, 0, COMPLETE, PARSE_FAIL),
+-	HNS3_RX_PTYPE_ENTRY(124, 0, COMPLETE, PARSE_FAIL),
+-	HNS3_RX_PTYPE_ENTRY(125, 0, COMPLETE, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(126, 0, COMPLETE, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(127, 1, UNNECESSARY, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(128, 1, UNNECESSARY, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(129, 1, UNNECESSARY, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(130, 0, COMPLETE, IPV4),
+-	HNS3_RX_PTYPE_ENTRY(131, 0, COMPLETE, IPV4),
++	HNS3_RX_PTYPE_ENTRY(123, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(124, 0, COMPLETE, PARSE_FAIL, PKT_HASH_TYPE_NONE),
++	HNS3_RX_PTYPE_ENTRY(125, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(126, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(127, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(128, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(129, 1, UNNECESSARY, IPV4, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(130, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(131, 0, COMPLETE, IPV4, PKT_HASH_TYPE_L3),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(132),
+-	HNS3_RX_PTYPE_ENTRY(133, 0, COMPLETE, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(134, 0, COMPLETE, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(135, 1, UNNECESSARY, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(136, 1, UNNECESSARY, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(137, 1, UNNECESSARY, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(138, 0, COMPLETE, IPV6),
+-	HNS3_RX_PTYPE_ENTRY(139, 0, COMPLETE, IPV6),
++	HNS3_RX_PTYPE_ENTRY(133, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(134, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(135, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(136, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(137, 1, UNNECESSARY, IPV6, PKT_HASH_TYPE_L4),
++	HNS3_RX_PTYPE_ENTRY(138, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
++	HNS3_RX_PTYPE_ENTRY(139, 0, COMPLETE, IPV6, PKT_HASH_TYPE_L3),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(140),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(141),
+ 	HNS3_RX_PTYPE_UNUSED_ENTRY(142),
+@@ -3734,8 +3736,8 @@ static void hns3_nic_reuse_page(struct sk_buff *skb, int i,
+ 		desc_cb->reuse_flag = 1;
+ 	} else if (frag_size <= ring->rx_copybreak) {
+ 		ret = hns3_handle_rx_copybreak(skb, i, ring, pull_len, desc_cb);
+-		if (ret)
+-			goto out;
++		if (!ret)
++			return;
+ 	}
+ 
+ out:
+@@ -4129,15 +4131,35 @@ static int hns3_set_gro_and_checksum(struct hns3_enet_ring *ring,
+ }
+ 
+ static void hns3_set_rx_skb_rss_type(struct hns3_enet_ring *ring,
+-				     struct sk_buff *skb, u32 rss_hash)
++				     struct sk_buff *skb, u32 rss_hash,
++				     u32 l234info, u32 ol_info)
+ {
+-	struct hnae3_handle *handle = ring->tqp->handle;
+-	enum pkt_hash_types rss_type;
++	enum pkt_hash_types rss_type = PKT_HASH_TYPE_NONE;
++	struct net_device *netdev = ring_to_netdev(ring);
++	struct hns3_nic_priv *priv = netdev_priv(netdev);
+ 
+-	if (rss_hash)
+-		rss_type = handle->kinfo.rss_type;
+-	else
+-		rss_type = PKT_HASH_TYPE_NONE;
++	if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) {
++		u32 ptype = hnae3_get_field(ol_info, HNS3_RXD_PTYPE_M,
++					    HNS3_RXD_PTYPE_S);
++
++		rss_type = hns3_rx_ptype_tbl[ptype].hash_type;
++	} else {
++		int l3_type = hnae3_get_field(l234info, HNS3_RXD_L3ID_M,
++					      HNS3_RXD_L3ID_S);
++		int l4_type = hnae3_get_field(l234info, HNS3_RXD_L4ID_M,
++					      HNS3_RXD_L4ID_S);
++
++		if (l3_type == HNS3_L3_TYPE_IPV4 ||
++		    l3_type == HNS3_L3_TYPE_IPV6) {
++			if (l4_type == HNS3_L4_TYPE_UDP ||
++			    l4_type == HNS3_L4_TYPE_TCP ||
++			    l4_type == HNS3_L4_TYPE_SCTP)
++				rss_type = PKT_HASH_TYPE_L4;
++			else if (l4_type == HNS3_L4_TYPE_IGMP ||
++				 l4_type == HNS3_L4_TYPE_ICMP)
++				rss_type = PKT_HASH_TYPE_L3;
++		}
++	}
+ 
+ 	skb_set_hash(skb, rss_hash, rss_type);
+ }
+@@ -4240,7 +4262,8 @@ static int hns3_handle_bdinfo(struct hns3_enet_ring *ring, struct sk_buff *skb)
+ 
+ 	ring->tqp_vector->rx_group.total_bytes += len;
+ 
+-	hns3_set_rx_skb_rss_type(ring, skb, le32_to_cpu(desc->rx.rss_hash));
++	hns3_set_rx_skb_rss_type(ring, skb, le32_to_cpu(desc->rx.rss_hash),
++				 l234info, ol_info);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+index 4a3253692dcc8..408635d11a24d 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+@@ -404,6 +404,7 @@ struct hns3_rx_ptype {
+ 	u32 ip_summed : 2;
+ 	u32 l3_type : 4;
+ 	u32 valid : 1;
++	u32 hash_type: 3;
+ };
+ 
+ struct ring_stats {
+diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+index fae79764dc442..7e8a60f2401c9 100644
+--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -3246,6 +3246,7 @@ static int hclge_update_tp_port_info(struct hclge_dev *hdev)
+ 	hdev->hw.mac.autoneg = cmd.base.autoneg;
+ 	hdev->hw.mac.speed = cmd.base.speed;
+ 	hdev->hw.mac.duplex = cmd.base.duplex;
++	linkmode_copy(hdev->hw.mac.advertising, cmd.link_modes.advertising);
+ 
+ 	return 0;
+ }
+@@ -4662,7 +4663,6 @@ static int hclge_set_rss_tuple(struct hnae3_handle *handle,
+ 		return ret;
+ 	}
+ 
+-	hclge_comm_get_rss_type(&vport->nic, &hdev->rss_cfg.rss_tuple_sets);
+ 	return 0;
+ }
+ 
+@@ -11374,9 +11374,12 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
+ 	if (ret)
+ 		goto err_msi_irq_uninit;
+ 
+-	if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER &&
+-	    !hnae3_dev_phy_imp_supported(hdev)) {
+-		ret = hclge_mac_mdio_config(hdev);
++	if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER) {
++		if (hnae3_dev_phy_imp_supported(hdev))
++			ret = hclge_update_tp_port_info(hdev);
++		else
++			ret = hclge_mac_mdio_config(hdev);
++
+ 		if (ret)
+ 			goto err_msi_irq_uninit;
+ 	}
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+index c23ee2ddbce3e..1a6534c35ef30 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_main.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c
+@@ -1478,8 +1478,15 @@ static struct pci_driver hinic_driver = {
+ 
+ static int __init hinic_module_init(void)
+ {
++	int ret;
++
+ 	hinic_dbg_register_debugfs(HINIC_DRV_NAME);
+-	return pci_register_driver(&hinic_driver);
++
++	ret = pci_register_driver(&hinic_driver);
++	if (ret)
++		hinic_dbg_unregister_debugfs();
++
++	return ret;
+ }
+ 
+ static void __exit hinic_module_exit(void)
+diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+index 97f080c66dd47..8a6a81bcec5cc 100644
+--- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
++++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+@@ -521,14 +521,12 @@ static int octep_open(struct net_device *netdev)
+ 	octep_oq_dbell_init(oct);
+ 
+ 	ret = octep_get_link_status(oct);
+-	if (ret)
++	if (ret > 0)
+ 		octep_link_up(netdev);
+ 
+ 	return 0;
+ 
+ set_queues_err:
+-	octep_napi_disable(oct);
+-	octep_napi_delete(oct);
+ 	octep_clean_irqs(oct);
+ setup_irq_err:
+ 	octep_free_oqs(oct);
+@@ -958,7 +956,7 @@ int octep_device_setup(struct octep_device *oct)
+ 	ret = octep_ctrl_mbox_init(ctrl_mbox);
+ 	if (ret) {
+ 		dev_err(&pdev->dev, "Failed to initialize control mbox\n");
+-		return -1;
++		goto unsupported_dev;
+ 	}
+ 	oct->ctrl_mbox_ifstats_offset = OCTEP_CTRL_MBOX_SZ(ctrl_mbox->h2fq.elem_sz,
+ 							   ctrl_mbox->h2fq.elem_cnt,
+@@ -968,6 +966,10 @@ int octep_device_setup(struct octep_device *oct)
+ 	return 0;
+ 
+ unsupported_dev:
++	for (i = 0; i < OCTEP_MMIO_REGIONS; i++)
++		iounmap(oct->mmio[i].hw_addr);
++
++	kfree(oct->conf);
+ 	return -1;
+ }
+ 
+@@ -1070,7 +1072,11 @@ static int octep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	netdev->max_mtu = OCTEP_MAX_MTU;
+ 	netdev->mtu = OCTEP_DEFAULT_MTU;
+ 
+-	octep_get_mac_addr(octep_dev, octep_dev->mac_addr);
++	err = octep_get_mac_addr(octep_dev, octep_dev->mac_addr);
++	if (err) {
++		dev_err(&pdev->dev, "Failed to get mac address\n");
++		goto register_dev_err;
++	}
+ 	eth_hw_addr_set(netdev, octep_dev->mac_addr);
+ 
+ 	err = register_netdev(netdev);
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+index 4efccd942fb89..1290b2d3eae6b 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+@@ -3470,6 +3470,8 @@ mlxsw_sp_switchdev_vxlan_fdb_del(struct mlxsw_sp *mlxsw_sp,
+ 	u16 vid;
+ 
+ 	vxlan_fdb_info = &switchdev_work->vxlan_fdb_info;
++	if (!vxlan_fdb_info->offloaded)
++		return;
+ 
+ 	bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
+ 	if (!bridge_device)
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
+index fea42542be280..06811c60d598e 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
+@@ -716,6 +716,9 @@ int lan966x_stats_init(struct lan966x *lan966x)
+ 	snprintf(queue_name, sizeof(queue_name), "%s-stats",
+ 		 dev_name(lan966x->dev));
+ 	lan966x->stats_queue = create_singlethread_workqueue(queue_name);
++	if (!lan966x->stats_queue)
++		return -ENOMEM;
++
+ 	INIT_DELAYED_WORK(&lan966x->stats_work, lan966x_check_stats_work);
+ 	queue_delayed_work(lan966x->stats_queue, &lan966x->stats_work,
+ 			   LAN966X_STATS_CHECK_DELAY);
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
+index 6b0febcb7fa99..01f3a3a41cdb3 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c
+@@ -1253,6 +1253,9 @@ int sparx_stats_init(struct sparx5 *sparx5)
+ 	snprintf(queue_name, sizeof(queue_name), "%s-stats",
+ 		 dev_name(sparx5->dev));
+ 	sparx5->stats_queue = create_singlethread_workqueue(queue_name);
++	if (!sparx5->stats_queue)
++		return -ENOMEM;
++
+ 	INIT_DELAYED_WORK(&sparx5->stats_work, sparx5_check_stats_work);
+ 	queue_delayed_work(sparx5->stats_queue, &sparx5->stats_work,
+ 			   SPX5_STATS_CHECK_DELAY);
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+index 01be7bd841813..30815c0e3f76a 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+@@ -657,6 +657,9 @@ static int sparx5_start(struct sparx5 *sparx5)
+ 	snprintf(queue_name, sizeof(queue_name), "%s-mact",
+ 		 dev_name(sparx5->dev));
+ 	sparx5->mact_queue = create_singlethread_workqueue(queue_name);
++	if (!sparx5->mact_queue)
++		return -ENOMEM;
++
+ 	INIT_DELAYED_WORK(&sparx5->mact_work, sparx5_mact_pull_work);
+ 	queue_delayed_work(sparx5->mact_queue, &sparx5->mact_work,
+ 			   SPX5_MACT_PULL_DELAY);
+diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+index b1b1b648e40cb..b19bff0db1fdc 100644
+--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+@@ -1440,15 +1440,15 @@ nfp_port_get_module_info(struct net_device *netdev,
+ 
+ 		if (data < 0x3) {
+ 			modinfo->type = ETH_MODULE_SFF_8436;
+-			modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
++			modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
+ 		} else {
+ 			modinfo->type = ETH_MODULE_SFF_8636;
+-			modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
++			modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ 		}
+ 		break;
+ 	case NFP_INTERFACE_QSFP28:
+ 		modinfo->type = ETH_MODULE_SFF_8636;
+-		modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
++		modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
+ 		break;
+ 	default:
+ 		netdev_err(netdev, "Unsupported module 0x%x detected\n",
+diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c
+index 56f93b0305519..5456c2b15d9bd 100644
+--- a/drivers/net/ethernet/pensando/ionic/ionic_main.c
++++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c
+@@ -687,8 +687,14 @@ int ionic_port_reset(struct ionic *ionic)
+ 
+ static int __init ionic_init_module(void)
+ {
++	int ret;
++
+ 	ionic_debugfs_create();
+-	return ionic_bus_register_driver();
++	ret = ionic_bus_register_driver();
++	if (ret)
++		ionic_debugfs_destroy();
++
++	return ret;
+ }
+ 
+ static void __exit ionic_cleanup_module(void)
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index bc060ef558d37..02827829463f6 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -6564,6 +6564,9 @@ void stmmac_xdp_release(struct net_device *dev)
+ 	struct stmmac_priv *priv = netdev_priv(dev);
+ 	u32 chan;
+ 
++	/* Ensure tx function is not running */
++	netif_tx_disable(dev);
++
+ 	/* Disable NAPI process */
+ 	stmmac_disable_all_queues(priv);
+ 
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index 9983d37ee87d9..0a0c4d0ffc198 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -141,7 +141,7 @@ static struct macvlan_source_entry *macvlan_hash_lookup_source(
+ 	u32 idx = macvlan_eth_hash(addr);
+ 	struct hlist_head *h = &vlan->port->vlan_source_hash[idx];
+ 
+-	hlist_for_each_entry_rcu(entry, h, hlist) {
++	hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) {
+ 		if (ether_addr_equal_64bits(entry->addr, addr) &&
+ 		    entry->vlan == vlan)
+ 			return entry;
+@@ -1192,7 +1192,7 @@ void macvlan_common_setup(struct net_device *dev)
+ {
+ 	ether_setup(dev);
+ 
+-	dev->min_mtu		= 0;
++	/* ether_setup() has set dev->min_mtu to ETH_MIN_MTU. */
+ 	dev->max_mtu		= ETH_MAX_MTU;
+ 	dev->priv_flags	       &= ~IFF_TX_SKB_SHARING;
+ 	netif_keep_dst(dev);
+@@ -1647,7 +1647,7 @@ static int macvlan_fill_info_macaddr(struct sk_buff *skb,
+ 	struct hlist_head *h = &vlan->port->vlan_source_hash[i];
+ 	struct macvlan_source_entry *entry;
+ 
+-	hlist_for_each_entry_rcu(entry, h, hlist) {
++	hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) {
+ 		if (entry->vlan != vlan)
+ 			continue;
+ 		if (nla_put(skb, IFLA_MACVLAN_MACADDR, ETH_ALEN, entry->addr))
+diff --git a/drivers/net/mctp/mctp-i2c.c b/drivers/net/mctp/mctp-i2c.c
+index 53846c6b56ca2..aca3697b09620 100644
+--- a/drivers/net/mctp/mctp-i2c.c
++++ b/drivers/net/mctp/mctp-i2c.c
+@@ -43,6 +43,7 @@
+ enum {
+ 	MCTP_I2C_FLOW_STATE_NEW = 0,
+ 	MCTP_I2C_FLOW_STATE_ACTIVE,
++	MCTP_I2C_FLOW_STATE_INVALID,
+ };
+ 
+ /* List of all struct mctp_i2c_client
+@@ -374,12 +375,18 @@ mctp_i2c_get_tx_flow_state(struct mctp_i2c_dev *midev, struct sk_buff *skb)
+ 	 */
+ 	if (!key->valid) {
+ 		state = MCTP_I2C_TX_FLOW_INVALID;
+-
+-	} else if (key->dev_flow_state == MCTP_I2C_FLOW_STATE_NEW) {
+-		key->dev_flow_state = MCTP_I2C_FLOW_STATE_ACTIVE;
+-		state = MCTP_I2C_TX_FLOW_NEW;
+ 	} else {
+-		state = MCTP_I2C_TX_FLOW_EXISTING;
++		switch (key->dev_flow_state) {
++		case MCTP_I2C_FLOW_STATE_NEW:
++			key->dev_flow_state = MCTP_I2C_FLOW_STATE_ACTIVE;
++			state = MCTP_I2C_TX_FLOW_NEW;
++			break;
++		case MCTP_I2C_FLOW_STATE_ACTIVE:
++			state = MCTP_I2C_TX_FLOW_EXISTING;
++			break;
++		default:
++			state = MCTP_I2C_TX_FLOW_INVALID;
++		}
+ 	}
+ 
+ 	spin_unlock_irqrestore(&key->lock, flags);
+@@ -617,21 +624,31 @@ static void mctp_i2c_release_flow(struct mctp_dev *mdev,
+ 
+ {
+ 	struct mctp_i2c_dev *midev = netdev_priv(mdev->dev);
++	bool queue_release = false;
+ 	unsigned long flags;
+ 
+ 	spin_lock_irqsave(&midev->lock, flags);
+-	midev->release_count++;
+-	spin_unlock_irqrestore(&midev->lock, flags);
+-
+-	/* Ensure we have a release operation queued, through the fake
+-	 * marker skb
++	/* if we have seen the flow/key previously, we need to pair the
++	 * original lock with a release
+ 	 */
+-	spin_lock(&midev->tx_queue.lock);
+-	if (!midev->unlock_marker.next)
+-		__skb_queue_tail(&midev->tx_queue, &midev->unlock_marker);
+-	spin_unlock(&midev->tx_queue.lock);
++	if (key->dev_flow_state == MCTP_I2C_FLOW_STATE_ACTIVE) {
++		midev->release_count++;
++		queue_release = true;
++	}
++	key->dev_flow_state = MCTP_I2C_FLOW_STATE_INVALID;
++	spin_unlock_irqrestore(&midev->lock, flags);
+ 
+-	wake_up(&midev->tx_wq);
++	if (queue_release) {
++		/* Ensure we have a release operation queued, through the fake
++		 * marker skb
++		 */
++		spin_lock(&midev->tx_queue.lock);
++		if (!midev->unlock_marker.next)
++			__skb_queue_tail(&midev->tx_queue,
++					 &midev->unlock_marker);
++		spin_unlock(&midev->tx_queue.lock);
++		wake_up(&midev->tx_wq);
++	}
+ }
+ 
+ static const struct net_device_ops mctp_i2c_ops = {
+diff --git a/drivers/net/mhi_net.c b/drivers/net/mhi_net.c
+index 0b1b6f650104b..0b9d379791332 100644
+--- a/drivers/net/mhi_net.c
++++ b/drivers/net/mhi_net.c
+@@ -343,6 +343,8 @@ static void mhi_net_dellink(struct mhi_device *mhi_dev, struct net_device *ndev)
+ 
+ 	kfree_skb(mhi_netdev->skbagg_head);
+ 
++	free_netdev(ndev);
++
+ 	dev_set_drvdata(&mhi_dev->dev, NULL);
+ }
+ 
+diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
+index b17e4e94a060e..38562ed833dae 100644
+--- a/drivers/net/netdevsim/dev.c
++++ b/drivers/net/netdevsim/dev.c
+@@ -1675,6 +1675,7 @@ void nsim_drv_remove(struct nsim_bus_dev *nsim_bus_dev)
+ 				  ARRAY_SIZE(nsim_devlink_params));
+ 	devl_resources_unregister(devlink);
+ 	kfree(nsim_dev->vfconfigs);
++	kfree(nsim_dev->fa_cookie);
+ 	devl_unlock(devlink);
+ 	devlink_free(devlink);
+ 	dev_set_drvdata(&nsim_bus_dev->dev, NULL);
+diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
+index 417527f8bbf55..7446d5c6c7146 100644
+--- a/drivers/net/phy/dp83867.c
++++ b/drivers/net/phy/dp83867.c
+@@ -682,6 +682,13 @@ static int dp83867_of_init(struct phy_device *phydev)
+ 	 */
+ 	dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN / 2;
+ 
++	/* For non-OF device, the RX and TX FIFO depths are taken from
++	 * default value. So, we init RX & TX FIFO depths here
++	 * so that it is configured correctly later in dp83867_config_init();
++	 */
++	dp83867->tx_fifo_depth = DP83867_PHYCR_FIFO_DEPTH_4_B_NIB;
++	dp83867->rx_fifo_depth = DP83867_PHYCR_FIFO_DEPTH_4_B_NIB;
++
+ 	return 0;
+ }
+ #endif /* CONFIG_OF_MDIO */
+diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
+index a714150f5e8cd..7c292a3d83d49 100644
+--- a/drivers/net/phy/marvell.c
++++ b/drivers/net/phy/marvell.c
+@@ -2015,14 +2015,16 @@ static int m88e1510_loopback(struct phy_device *phydev, bool enable)
+ 		if (err < 0)
+ 			return err;
+ 
+-		/* FIXME: Based on trial and error test, it seem 1G need to have
+-		 * delay between soft reset and loopback enablement.
+-		 */
+-		if (phydev->speed == SPEED_1000)
+-			msleep(1000);
++		err = phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK,
++				 BMCR_LOOPBACK);
+ 
+-		return phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK,
+-				  BMCR_LOOPBACK);
++		if (!err) {
++			/* It takes some time for PHY device to switch
++			 * into/out-of loopback mode.
++			 */
++			msleep(1000);
++		}
++		return err;
+ 	} else {
+ 		err = phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, 0);
+ 		if (err < 0)
+diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c
+index ab3f045629802..8391f83034992 100644
+--- a/drivers/net/thunderbolt.c
++++ b/drivers/net/thunderbolt.c
+@@ -1379,12 +1379,21 @@ static int __init tbnet_init(void)
+ 				  TBNET_MATCH_FRAGS_ID | TBNET_64K_FRAMES);
+ 
+ 	ret = tb_register_property_dir("network", tbnet_dir);
+-	if (ret) {
+-		tb_property_free_dir(tbnet_dir);
+-		return ret;
+-	}
++	if (ret)
++		goto err_free_dir;
++
++	ret = tb_register_service_driver(&tbnet_driver);
++	if (ret)
++		goto err_unregister;
+ 
+-	return tb_register_service_driver(&tbnet_driver);
++	return 0;
++
++err_unregister:
++	tb_unregister_property_dir("network", tbnet_dir);
++err_free_dir:
++	tb_property_free_dir(tbnet_dir);
++
++	return ret;
+ }
+ module_init(tbnet_init);
+ 
+diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
+index bfb58c91db047..32d2c60d334dc 100644
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -66,6 +66,7 @@ struct smsc95xx_priv {
+ 	spinlock_t mac_cr_lock;
+ 	u8 features;
+ 	u8 suspend_flags;
++	bool is_internal_phy;
+ 	struct irq_chip irqchip;
+ 	struct irq_domain *irqdomain;
+ 	struct fwnode_handle *irqfwnode;
+@@ -252,6 +253,43 @@ done:
+ 	mutex_unlock(&dev->phy_mutex);
+ }
+ 
++static int smsc95xx_mdiobus_reset(struct mii_bus *bus)
++{
++	struct smsc95xx_priv *pdata;
++	struct usbnet *dev;
++	u32 val;
++	int ret;
++
++	dev = bus->priv;
++	pdata = dev->driver_priv;
++
++	if (pdata->is_internal_phy)
++		return 0;
++
++	mutex_lock(&dev->phy_mutex);
++
++	ret = smsc95xx_read_reg(dev, PM_CTRL, &val);
++	if (ret < 0)
++		goto reset_out;
++
++	val |= PM_CTL_PHY_RST_;
++
++	ret = smsc95xx_write_reg(dev, PM_CTRL, val);
++	if (ret < 0)
++		goto reset_out;
++
++	/* Driver has no knowledge at this point about the external PHY.
++	 * The 802.3 specifies that the reset process shall
++	 * be completed within 0.5 s.
++	 */
++	fsleep(500000);
++
++reset_out:
++	mutex_unlock(&dev->phy_mutex);
++
++	return 0;
++}
++
+ static int smsc95xx_mdiobus_read(struct mii_bus *bus, int phy_id, int idx)
+ {
+ 	struct usbnet *dev = bus->priv;
+@@ -1052,7 +1090,6 @@ static void smsc95xx_handle_link_change(struct net_device *net)
+ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
+ {
+ 	struct smsc95xx_priv *pdata;
+-	bool is_internal_phy;
+ 	char usb_path[64];
+ 	int ret, phy_irq;
+ 	u32 val;
+@@ -1133,13 +1170,14 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
+ 	if (ret < 0)
+ 		goto free_mdio;
+ 
+-	is_internal_phy = !(val & HW_CFG_PSEL_);
+-	if (is_internal_phy)
++	pdata->is_internal_phy = !(val & HW_CFG_PSEL_);
++	if (pdata->is_internal_phy)
+ 		pdata->mdiobus->phy_mask = ~(1u << SMSC95XX_INTERNAL_PHY_ID);
+ 
+ 	pdata->mdiobus->priv = dev;
+ 	pdata->mdiobus->read = smsc95xx_mdiobus_read;
+ 	pdata->mdiobus->write = smsc95xx_mdiobus_write;
++	pdata->mdiobus->reset = smsc95xx_mdiobus_reset;
+ 	pdata->mdiobus->name = "smsc95xx-mdiobus";
+ 	pdata->mdiobus->parent = &dev->udev->dev;
+ 
+@@ -1160,7 +1198,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
+ 	}
+ 
+ 	pdata->phydev->irq = phy_irq;
+-	pdata->phydev->is_internal = is_internal_phy;
++	pdata->phydev->is_internal = pdata->is_internal_phy;
+ 
+ 	/* detect device revision as different features may be available */
+ 	ret = smsc95xx_read_reg(dev, ID_REV, &val);
+diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
+index d3281f87cd6e4..a48a79ed5c4c5 100644
+--- a/drivers/nvme/host/ioctl.c
++++ b/drivers/nvme/host/ioctl.c
+@@ -764,11 +764,17 @@ long nvme_dev_ioctl(struct file *file, unsigned int cmd,
+ 	case NVME_IOCTL_IO_CMD:
+ 		return nvme_dev_user_cmd(ctrl, argp);
+ 	case NVME_IOCTL_RESET:
++		if (!capable(CAP_SYS_ADMIN))
++			return -EACCES;
+ 		dev_warn(ctrl->device, "resetting controller\n");
+ 		return nvme_reset_ctrl_sync(ctrl);
+ 	case NVME_IOCTL_SUBSYS_RESET:
++		if (!capable(CAP_SYS_ADMIN))
++			return -EACCES;
+ 		return nvme_reset_subsystem(ctrl);
+ 	case NVME_IOCTL_RESCAN:
++		if (!capable(CAP_SYS_ADMIN))
++			return -EACCES;
+ 		nvme_queue_scan(ctrl);
+ 		return 0;
+ 	default:
+diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
+index a0bf9560cf678..70555022cb445 100644
+--- a/drivers/nvme/host/nvme.h
++++ b/drivers/nvme/host/nvme.h
+@@ -602,11 +602,23 @@ static inline void nvme_fault_inject_fini(struct nvme_fault_inject *fault_inj)
+ static inline void nvme_should_fail(struct request *req) {}
+ #endif
+ 
++bool nvme_wait_reset(struct nvme_ctrl *ctrl);
++int nvme_try_sched_reset(struct nvme_ctrl *ctrl);
++
+ static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl)
+ {
++	int ret;
++
+ 	if (!ctrl->subsystem)
+ 		return -ENOTTY;
+-	return ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65);
++	if (!nvme_wait_reset(ctrl))
++		return -EBUSY;
++
++	ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65);
++	if (ret)
++		return ret;
++
++	return nvme_try_sched_reset(ctrl);
+ }
+ 
+ /*
+@@ -712,7 +724,6 @@ void nvme_cancel_tagset(struct nvme_ctrl *ctrl);
+ void nvme_cancel_admin_tagset(struct nvme_ctrl *ctrl);
+ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
+ 		enum nvme_ctrl_state new_state);
+-bool nvme_wait_reset(struct nvme_ctrl *ctrl);
+ int nvme_disable_ctrl(struct nvme_ctrl *ctrl);
+ int nvme_enable_ctrl(struct nvme_ctrl *ctrl);
+ int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl);
+@@ -802,7 +813,6 @@ int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count);
+ void nvme_stop_keep_alive(struct nvme_ctrl *ctrl);
+ int nvme_reset_ctrl(struct nvme_ctrl *ctrl);
+ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl);
+-int nvme_try_sched_reset(struct nvme_ctrl *ctrl);
+ int nvme_delete_ctrl(struct nvme_ctrl *ctrl);
+ void nvme_queue_scan(struct nvme_ctrl *ctrl);
+ int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, u8 csi,
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 554468ea5a2a9..1a6423e94eb30 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -3488,6 +3488,8 @@ static const struct pci_device_id nvme_id_table[] = {
+ 				NVME_QUIRK_IGNORE_DEV_SUBNQN, },
+ 	 { PCI_DEVICE(0x1344, 0x5407), /* Micron Technology Inc NVMe SSD */
+ 		.driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN },
++	 { PCI_DEVICE(0x1344, 0x6001),   /* Micron Nitro NVMe */
++		 .driver_data = NVME_QUIRK_BOGUS_NID, },
+ 	{ PCI_DEVICE(0x1c5c, 0x1504),   /* SK Hynix PC400 */
+ 		.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+ 	{ PCI_DEVICE(0x1c5c, 0x174a),   /* SK Hynix P31 SSD */
+@@ -3518,6 +3520,8 @@ static const struct pci_device_id nvme_id_table[] = {
+ 		.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+ 	{ PCI_DEVICE(0x2646, 0x501E),   /* KINGSTON OM3PGP4xxxxQ OS21011 NVMe SSD */
+ 		.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
++	{ PCI_DEVICE(0x1f40, 0x5236),   /* Netac Technologies Co. NV7000 NVMe SSD */
++		.driver_data = NVME_QUIRK_BOGUS_NID, },
+ 	{ PCI_DEVICE(0x1e4B, 0x1001),   /* MAXIO MAP1001 */
+ 		.driver_data = NVME_QUIRK_BOGUS_NID, },
+ 	{ PCI_DEVICE(0x1e4B, 0x1002),   /* MAXIO MAP1002 */
+diff --git a/drivers/nvme/target/auth.c b/drivers/nvme/target/auth.c
+index c4113b43dbfee..4dcddcf95279b 100644
+--- a/drivers/nvme/target/auth.c
++++ b/drivers/nvme/target/auth.c
+@@ -45,9 +45,11 @@ int nvmet_auth_set_key(struct nvmet_host *host, const char *secret,
+ 	if (!dhchap_secret)
+ 		return -ENOMEM;
+ 	if (set_ctrl) {
++		kfree(host->dhchap_ctrl_secret);
+ 		host->dhchap_ctrl_secret = strim(dhchap_secret);
+ 		host->dhchap_ctrl_key_hash = key_hash;
+ 	} else {
++		kfree(host->dhchap_secret);
+ 		host->dhchap_secret = strim(dhchap_secret);
+ 		host->dhchap_key_hash = key_hash;
+ 	}
+diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
+index 2bcd60758919b..7f52d9dac4432 100644
+--- a/drivers/nvme/target/configfs.c
++++ b/drivers/nvme/target/configfs.c
+@@ -1811,6 +1811,7 @@ static void nvmet_host_release(struct config_item *item)
+ 
+ #ifdef CONFIG_NVME_TARGET_AUTH
+ 	kfree(host->dhchap_secret);
++	kfree(host->dhchap_ctrl_secret);
+ #endif
+ 	kfree(host);
+ }
+diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
+index eda4ded4d5e52..925be41eeebec 100644
+--- a/drivers/parport/parport_pc.c
++++ b/drivers/parport/parport_pc.c
+@@ -468,7 +468,7 @@ static size_t parport_pc_fifo_write_block_pio(struct parport *port,
+ 	const unsigned char *bufp = buf;
+ 	size_t left = length;
+ 	unsigned long expire = jiffies + port->physport->cad->timeout;
+-	const int fifo = FIFO(port);
++	const unsigned long fifo = FIFO(port);
+ 	int poll_for = 8; /* 80 usecs */
+ 	const struct parport_pc_private *priv = port->physport->private_data;
+ 	const int fifo_depth = priv->fifo_depth;
+diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
+index ef898ee8ca6bd..6e0a40962f384 100644
+--- a/drivers/pinctrl/devicetree.c
++++ b/drivers/pinctrl/devicetree.c
+@@ -220,6 +220,8 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
+ 	for (state = 0; ; state++) {
+ 		/* Retrieve the pinctrl-* property */
+ 		propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
++		if (!propname)
++			return -ENOMEM;
+ 		prop = of_find_property(np, propname, &size);
+ 		kfree(propname);
+ 		if (!prop) {
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+index e1ae3beb9f72b..b7921b59eb7b1 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+@@ -709,6 +709,9 @@ static int mtk_pinconf_bias_set_rsel(struct mtk_pinctrl *hw,
+ {
+ 	int err, rsel_val;
+ 
++	if (!pullup && arg == MTK_DISABLE)
++		return 0;
++
+ 	if (hw->rsel_si_unit) {
+ 		/* find pin rsel_index from pin_rsel array*/
+ 		err = mtk_hw_pin_rsel_lookup(hw, desc, pullup, arg, &rsel_val);
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
+index c84bd0e1ce5a6..f4d2b64c06709 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -632,14 +632,54 @@ static void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
+ }
+ 
+ static struct rockchip_mux_route_data px30_mux_route_data[] = {
++	RK_MUXROUTE_SAME(2, RK_PB4, 1, 0x184, BIT(16 + 7)), /* cif-d0m0 */
++	RK_MUXROUTE_SAME(3, RK_PA1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d0m1 */
++	RK_MUXROUTE_SAME(2, RK_PB6, 1, 0x184, BIT(16 + 7)), /* cif-d1m0 */
++	RK_MUXROUTE_SAME(3, RK_PA2, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d1m1 */
+ 	RK_MUXROUTE_SAME(2, RK_PA0, 1, 0x184, BIT(16 + 7)), /* cif-d2m0 */
+ 	RK_MUXROUTE_SAME(3, RK_PA3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d2m1 */
++	RK_MUXROUTE_SAME(2, RK_PA1, 1, 0x184, BIT(16 + 7)), /* cif-d3m0 */
++	RK_MUXROUTE_SAME(3, RK_PA5, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d3m1 */
++	RK_MUXROUTE_SAME(2, RK_PA2, 1, 0x184, BIT(16 + 7)), /* cif-d4m0 */
++	RK_MUXROUTE_SAME(3, RK_PA7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d4m1 */
++	RK_MUXROUTE_SAME(2, RK_PA3, 1, 0x184, BIT(16 + 7)), /* cif-d5m0 */
++	RK_MUXROUTE_SAME(3, RK_PB0, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d5m1 */
++	RK_MUXROUTE_SAME(2, RK_PA4, 1, 0x184, BIT(16 + 7)), /* cif-d6m0 */
++	RK_MUXROUTE_SAME(3, RK_PB1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d6m1 */
++	RK_MUXROUTE_SAME(2, RK_PA5, 1, 0x184, BIT(16 + 7)), /* cif-d7m0 */
++	RK_MUXROUTE_SAME(3, RK_PB4, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d7m1 */
++	RK_MUXROUTE_SAME(2, RK_PA6, 1, 0x184, BIT(16 + 7)), /* cif-d8m0 */
++	RK_MUXROUTE_SAME(3, RK_PB6, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d8m1 */
++	RK_MUXROUTE_SAME(2, RK_PA7, 1, 0x184, BIT(16 + 7)), /* cif-d9m0 */
++	RK_MUXROUTE_SAME(3, RK_PB7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d9m1 */
++	RK_MUXROUTE_SAME(2, RK_PB7, 1, 0x184, BIT(16 + 7)), /* cif-d10m0 */
++	RK_MUXROUTE_SAME(3, RK_PC6, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d10m1 */
++	RK_MUXROUTE_SAME(2, RK_PC0, 1, 0x184, BIT(16 + 7)), /* cif-d11m0 */
++	RK_MUXROUTE_SAME(3, RK_PC7, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-d11m1 */
++	RK_MUXROUTE_SAME(2, RK_PB0, 1, 0x184, BIT(16 + 7)), /* cif-vsyncm0 */
++	RK_MUXROUTE_SAME(3, RK_PD1, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-vsyncm1 */
++	RK_MUXROUTE_SAME(2, RK_PB1, 1, 0x184, BIT(16 + 7)), /* cif-hrefm0 */
++	RK_MUXROUTE_SAME(3, RK_PD2, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-hrefm1 */
++	RK_MUXROUTE_SAME(2, RK_PB2, 1, 0x184, BIT(16 + 7)), /* cif-clkinm0 */
++	RK_MUXROUTE_SAME(3, RK_PD3, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-clkinm1 */
++	RK_MUXROUTE_SAME(2, RK_PB3, 1, 0x184, BIT(16 + 7)), /* cif-clkoutm0 */
++	RK_MUXROUTE_SAME(3, RK_PD0, 3, 0x184, BIT(16 + 7) | BIT(7)), /* cif-clkoutm1 */
+ 	RK_MUXROUTE_SAME(3, RK_PC6, 2, 0x184, BIT(16 + 8)), /* pdm-m0 */
+ 	RK_MUXROUTE_SAME(2, RK_PC6, 1, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-m1 */
++	RK_MUXROUTE_SAME(3, RK_PD3, 2, 0x184, BIT(16 + 8)), /* pdm-sdi0m0 */
++	RK_MUXROUTE_SAME(2, RK_PC5, 2, 0x184, BIT(16 + 8) | BIT(8)), /* pdm-sdi0m1 */
+ 	RK_MUXROUTE_SAME(1, RK_PD3, 2, 0x184, BIT(16 + 10)), /* uart2-rxm0 */
+ 	RK_MUXROUTE_SAME(2, RK_PB6, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-rxm1 */
++	RK_MUXROUTE_SAME(1, RK_PD2, 2, 0x184, BIT(16 + 10)), /* uart2-txm0 */
++	RK_MUXROUTE_SAME(2, RK_PB4, 2, 0x184, BIT(16 + 10) | BIT(10)), /* uart2-txm1 */
+ 	RK_MUXROUTE_SAME(0, RK_PC1, 2, 0x184, BIT(16 + 9)), /* uart3-rxm0 */
+ 	RK_MUXROUTE_SAME(1, RK_PB7, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rxm1 */
++	RK_MUXROUTE_SAME(0, RK_PC0, 2, 0x184, BIT(16 + 9)), /* uart3-txm0 */
++	RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-txm1 */
++	RK_MUXROUTE_SAME(0, RK_PC2, 2, 0x184, BIT(16 + 9)), /* uart3-ctsm0 */
++	RK_MUXROUTE_SAME(1, RK_PB4, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-ctsm1 */
++	RK_MUXROUTE_SAME(0, RK_PC3, 2, 0x184, BIT(16 + 9)), /* uart3-rtsm0 */
++	RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x184, BIT(16 + 9) | BIT(9)), /* uart3-rtsm1 */
+ };
+ 
+ static struct rockchip_mux_route_data rk3128_mux_route_data[] = {
+diff --git a/drivers/platform/surface/aggregator/ssh_packet_layer.c b/drivers/platform/surface/aggregator/ssh_packet_layer.c
+index 6748fe4ac5d5f..def8d7ac541f7 100644
+--- a/drivers/platform/surface/aggregator/ssh_packet_layer.c
++++ b/drivers/platform/surface/aggregator/ssh_packet_layer.c
+@@ -1596,16 +1596,32 @@ static void ssh_ptl_timeout_reap(struct work_struct *work)
+ 		ssh_ptl_tx_wakeup_packet(ptl);
+ }
+ 
+-static bool ssh_ptl_rx_retransmit_check(struct ssh_ptl *ptl, u8 seq)
++static bool ssh_ptl_rx_retransmit_check(struct ssh_ptl *ptl, const struct ssh_frame *frame)
+ {
+ 	int i;
+ 
++	/*
++	 * Ignore unsequenced packets. On some devices (notably Surface Pro 9),
++	 * unsequenced events will always be sent with SEQ=0x00. Attempting to
++	 * detect retransmission would thus just block all events.
++	 *
++	 * While sequence numbers would also allow detection of retransmitted
++	 * packets in unsequenced communication, they have only ever been used
++	 * to cover edge-cases in sequenced transmission. In particular, the
++	 * only instance of packets being retransmitted (that we are aware of)
++	 * is due to an ACK timeout. As this does not happen in unsequenced
++	 * communication, skip the retransmission check for those packets
++	 * entirely.
++	 */
++	if (frame->type == SSH_FRAME_TYPE_DATA_NSQ)
++		return false;
++
+ 	/*
+ 	 * Check if SEQ has been seen recently (i.e. packet was
+ 	 * re-transmitted and we should ignore it).
+ 	 */
+ 	for (i = 0; i < ARRAY_SIZE(ptl->rx.blocked.seqs); i++) {
+-		if (likely(ptl->rx.blocked.seqs[i] != seq))
++		if (likely(ptl->rx.blocked.seqs[i] != frame->seq))
+ 			continue;
+ 
+ 		ptl_dbg(ptl, "ptl: ignoring repeated data packet\n");
+@@ -1613,7 +1629,7 @@ static bool ssh_ptl_rx_retransmit_check(struct ssh_ptl *ptl, u8 seq)
+ 	}
+ 
+ 	/* Update list of blocked sequence IDs. */
+-	ptl->rx.blocked.seqs[ptl->rx.blocked.offset] = seq;
++	ptl->rx.blocked.seqs[ptl->rx.blocked.offset] = frame->seq;
+ 	ptl->rx.blocked.offset = (ptl->rx.blocked.offset + 1)
+ 				  % ARRAY_SIZE(ptl->rx.blocked.seqs);
+ 
+@@ -1624,7 +1640,7 @@ static void ssh_ptl_rx_dataframe(struct ssh_ptl *ptl,
+ 				 const struct ssh_frame *frame,
+ 				 const struct ssam_span *payload)
+ {
+-	if (ssh_ptl_rx_retransmit_check(ptl, frame->seq))
++	if (ssh_ptl_rx_retransmit_check(ptl, frame))
+ 		return;
+ 
+ 	ptl->ops.data_received(ptl, payload);
+diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c
+index 6ccb9b38483ca..a838197f88962 100644
+--- a/drivers/platform/x86/amd/pmc.c
++++ b/drivers/platform/x86/amd/pmc.c
+@@ -274,7 +274,6 @@ static const struct file_operations amd_pmc_stb_debugfs_fops_v2 = {
+ 	.release = amd_pmc_stb_debugfs_release_v2,
+ };
+ 
+-#if defined(CONFIG_SUSPEND) || defined(CONFIG_DEBUG_FS)
+ static int amd_pmc_setup_smu_logging(struct amd_pmc_dev *dev)
+ {
+ 	if (dev->cpu_id == AMD_CPU_ID_PCO) {
+@@ -349,7 +348,6 @@ static int get_metrics_table(struct amd_pmc_dev *pdev, struct smu_metrics *table
+ 	memcpy_fromio(table, pdev->smu_virt_addr, sizeof(struct smu_metrics));
+ 	return 0;
+ }
+-#endif /* CONFIG_SUSPEND || CONFIG_DEBUG_FS */
+ 
+ #ifdef CONFIG_SUSPEND
+ static void amd_pmc_validate_deepest(struct amd_pmc_dev *pdev)
+@@ -920,6 +918,7 @@ static const struct acpi_device_id amd_pmc_acpi_ids[] = {
+ 	{"AMDI0006", 0},
+ 	{"AMDI0007", 0},
+ 	{"AMDI0008", 0},
++	{"AMDI0009", 0},
+ 	{"AMD0004", 0},
+ 	{"AMD0005", 0},
+ 	{ }
+diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c
+index a1fe1e0dcf4a5..17ec5825d13d7 100644
+--- a/drivers/platform/x86/intel/pmc/core.c
++++ b/drivers/platform/x86/intel/pmc/core.c
+@@ -1914,6 +1914,8 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = {
+ 	X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N,		&tgl_reg_map),
+ 	X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE,		&adl_reg_map),
+ 	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P,        &tgl_reg_map),
++	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE,		&adl_reg_map),
++	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S,	&adl_reg_map),
+ 	{}
+ };
+ 
+diff --git a/drivers/platform/x86/intel/pmc/pltdrv.c b/drivers/platform/x86/intel/pmc/pltdrv.c
+index 15ca8afdd973d..ddfba38c21044 100644
+--- a/drivers/platform/x86/intel/pmc/pltdrv.c
++++ b/drivers/platform/x86/intel/pmc/pltdrv.c
+@@ -18,6 +18,8 @@
+ #include <asm/cpu_device_id.h>
+ #include <asm/intel-family.h>
+ 
++#include <xen/xen.h>
++
+ static void intel_pmc_core_release(struct device *dev)
+ {
+ 	kfree(dev);
+@@ -53,6 +55,13 @@ static int __init pmc_core_platform_init(void)
+ 	if (acpi_dev_present("INT33A1", NULL, -1))
+ 		return -ENODEV;
+ 
++	/*
++	 * Skip forcefully attaching the device for VMs. Make an exception for
++	 * Xen dom0, which does have full hardware access.
++	 */
++	if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR) && !xen_initial_domain())
++		return -ENODEV;
++
+ 	if (!x86_match_cpu(intel_pmc_core_platform_ids))
+ 		return -ENODEV;
+ 
+diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
+index 2dbb9fc011a7a..353507d18e11c 100644
+--- a/drivers/platform/x86/thinkpad_acpi.c
++++ b/drivers/platform/x86/thinkpad_acpi.c
+@@ -263,6 +263,8 @@ enum tpacpi_hkey_event_t {
+ #define TPACPI_DBG_BRGHT	0x0020
+ #define TPACPI_DBG_MIXER	0x0040
+ 
++#define FAN_NOT_PRESENT		65535
++
+ #define strlencmp(a, b) (strncmp((a), (b), strlen(b)))
+ 
+ 
+@@ -8876,7 +8878,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
+ 			/* Try and probe the 2nd fan */
+ 			tp_features.second_fan = 1; /* needed for get_speed to work */
+ 			res = fan2_get_speed(&speed);
+-			if (res >= 0) {
++			if (res >= 0 && speed != FAN_NOT_PRESENT) {
+ 				/* It responded - so let's assume it's there */
+ 				tp_features.second_fan = 1;
+ 				tp_features.second_fan_ctl = 1;
+diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
+index 5187705bd0f39..d961f80c0e362 100644
+--- a/drivers/s390/block/dcssblk.c
++++ b/drivers/s390/block/dcssblk.c
+@@ -636,6 +636,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
+ 	dev_info->gd->minors = DCSSBLK_MINORS_PER_DISK;
+ 	dev_info->gd->fops = &dcssblk_devops;
+ 	dev_info->gd->private_data = dev_info;
++	dev_info->gd->flags |= GENHD_FL_NO_PART;
+ 	blk_queue_logical_block_size(dev_info->gd->queue, 4096);
+ 	blk_queue_flag_set(QUEUE_FLAG_DAX, dev_info->gd->queue);
+ 
+diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
+index 19223b0755686..ab3ea529cca70 100644
+--- a/drivers/s390/scsi/zfcp_fsf.c
++++ b/drivers/s390/scsi/zfcp_fsf.c
+@@ -884,7 +884,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
+ 	const bool is_srb = zfcp_fsf_req_is_status_read_buffer(req);
+ 	struct zfcp_adapter *adapter = req->adapter;
+ 	struct zfcp_qdio *qdio = adapter->qdio;
+-	int req_id = req->req_id;
++	unsigned long req_id = req->req_id;
+ 
+ 	zfcp_reqlist_add(adapter->req_list, req);
+ 
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index b8a76b89f85a3..95f940f5c996d 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -7316,8 +7316,12 @@ static int sdebug_add_host_helper(int per_host_idx)
+ 	dev_set_name(&sdbg_host->dev, "adapter%d", sdebug_num_hosts);
+ 
+ 	error = device_register(&sdbg_host->dev);
+-	if (error)
++	if (error) {
++		spin_lock(&sdebug_host_list_lock);
++		list_del(&sdbg_host->host_list);
++		spin_unlock(&sdebug_host_list_lock);
+ 		goto clean;
++	}
+ 
+ 	++sdebug_num_hosts;
+ 	return 0;
+diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
+index 2f88c61216eea..74b99f2b0b74a 100644
+--- a/drivers/scsi/scsi_transport_sas.c
++++ b/drivers/scsi/scsi_transport_sas.c
+@@ -722,12 +722,17 @@ int sas_phy_add(struct sas_phy *phy)
+ 	int error;
+ 
+ 	error = device_add(&phy->dev);
+-	if (!error) {
+-		transport_add_device(&phy->dev);
+-		transport_configure_device(&phy->dev);
++	if (error)
++		return error;
++
++	error = transport_add_device(&phy->dev);
++	if (error) {
++		device_del(&phy->dev);
++		return error;
+ 	}
++	transport_configure_device(&phy->dev);
+ 
+-	return error;
++	return 0;
+ }
+ EXPORT_SYMBOL(sas_phy_add);
+ 
+diff --git a/drivers/siox/siox-core.c b/drivers/siox/siox-core.c
+index 7c4f32d769666..561408583b2bf 100644
+--- a/drivers/siox/siox-core.c
++++ b/drivers/siox/siox-core.c
+@@ -839,6 +839,8 @@ static struct siox_device *siox_device_add(struct siox_master *smaster,
+ 
+ err_device_register:
+ 	/* don't care to make the buffer smaller again */
++	put_device(&sdevice->dev);
++	sdevice = NULL;
+ 
+ err_buf_alloc:
+ 	siox_master_unlock(smaster);
+diff --git a/drivers/slimbus/Kconfig b/drivers/slimbus/Kconfig
+index 1235b7dc8496c..e25d280a68eee 100644
+--- a/drivers/slimbus/Kconfig
++++ b/drivers/slimbus/Kconfig
+@@ -23,7 +23,7 @@ config SLIM_QCOM_CTRL
+ config SLIM_QCOM_NGD_CTRL
+ 	tristate "Qualcomm SLIMbus Satellite Non-Generic Device Component"
+ 	depends on HAS_IOMEM && DMA_ENGINE && NET && QCOM_RPROC_COMMON
+-	depends on ARCH_QCOM || COMPILE_TEST
++	depends on ARCH_QCOM || (COMPILE_TEST && !QCOM_RPROC_COMMON)
+ 	select QCOM_QMI_HELPERS
+ 	select QCOM_PDR_HELPERS
+ 	help
+diff --git a/drivers/slimbus/stream.c b/drivers/slimbus/stream.c
+index 75f87b3d8b953..73a2aa3629572 100644
+--- a/drivers/slimbus/stream.c
++++ b/drivers/slimbus/stream.c
+@@ -67,10 +67,10 @@ static const int slim_presence_rate_table[] = {
+ 	384000,
+ 	768000,
+ 	0, /* Reserved */
+-	110250,
+-	220500,
+-	441000,
+-	882000,
++	11025,
++	22050,
++	44100,
++	88200,
+ 	176400,
+ 	352800,
+ 	705600,
+diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c
+index cc57a384d74d2..28144c699b0c3 100644
+--- a/drivers/soc/imx/soc-imx8m.c
++++ b/drivers/soc/imx/soc-imx8m.c
+@@ -11,6 +11,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/arm-smccc.h>
+ #include <linux/of.h>
++#include <linux/clk.h>
+ 
+ #define REV_B1				0x21
+ 
+@@ -56,6 +57,7 @@ static u32 __init imx8mq_soc_revision(void)
+ 	void __iomem *ocotp_base;
+ 	u32 magic;
+ 	u32 rev;
++	struct clk *clk;
+ 
+ 	np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
+ 	if (!np)
+@@ -63,6 +65,13 @@ static u32 __init imx8mq_soc_revision(void)
+ 
+ 	ocotp_base = of_iomap(np, 0);
+ 	WARN_ON(!ocotp_base);
++	clk = of_clk_get_by_name(np, NULL);
++	if (!clk) {
++		WARN_ON(!clk);
++		return 0;
++	}
++
++	clk_prepare_enable(clk);
+ 
+ 	/*
+ 	 * SOC revision on older imx8mq is not available in fuses so query
+@@ -79,6 +88,8 @@ static u32 __init imx8mq_soc_revision(void)
+ 	soc_uid <<= 32;
+ 	soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW);
+ 
++	clk_disable_unprepare(clk);
++	clk_put(clk);
+ 	iounmap(ocotp_base);
+ 	of_node_put(np);
+ 
+diff --git a/drivers/spi/spi-intel.c b/drivers/spi/spi-intel.c
+index 3f6db482b6c71..a1dbd71bf83ef 100644
+--- a/drivers/spi/spi-intel.c
++++ b/drivers/spi/spi-intel.c
+@@ -114,7 +114,7 @@
+ #define ERASE_OPCODE_SHIFT		8
+ #define ERASE_OPCODE_MASK		(0xff << ERASE_OPCODE_SHIFT)
+ #define ERASE_64K_OPCODE_SHIFT		16
+-#define ERASE_64K_OPCODE_MASK		(0xff << ERASE_OPCODE_SHIFT)
++#define ERASE_64K_OPCODE_MASK		(0xff << ERASE_64K_OPCODE_SHIFT)
+ 
+ #define INTEL_SPI_TIMEOUT		5000 /* ms */
+ #define INTEL_SPI_FIFO_SZ		64
+diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
+index 6fe617b445a59..3c2fa2e2f94a3 100644
+--- a/drivers/spi/spi-stm32.c
++++ b/drivers/spi/spi-stm32.c
+@@ -886,6 +886,7 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
+ 		static DEFINE_RATELIMIT_STATE(rs,
+ 					      DEFAULT_RATELIMIT_INTERVAL * 10,
+ 					      1);
++		ratelimit_set_flags(&rs, RATELIMIT_MSG_ON_RELEASE);
+ 		if (__ratelimit(&rs))
+ 			dev_dbg_ratelimited(spi->dev, "Communication suspended\n");
+ 		if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
+diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
+index c89592b21ffc5..904972606bd45 100644
+--- a/drivers/spi/spi-tegra210-quad.c
++++ b/drivers/spi/spi-tegra210-quad.c
+@@ -1157,6 +1157,11 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
+ 		msg->actual_length += xfer->len;
+ 		transfer_phase++;
+ 	}
++	if (!xfer->cs_change) {
++		tegra_qspi_transfer_end(spi);
++		spi_transfer_delay_exec(xfer);
++	}
++	ret = 0;
+ 
+ exit:
+ 	msg->status = ret;
+diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
+index 4407b56aa6d1a..139031ccb700a 100644
+--- a/drivers/target/loopback/tcm_loop.c
++++ b/drivers/target/loopback/tcm_loop.c
+@@ -397,6 +397,7 @@ static int tcm_loop_setup_hba_bus(struct tcm_loop_hba *tl_hba, int tcm_loop_host
+ 	ret = device_register(&tl_hba->dev);
+ 	if (ret) {
+ 		pr_err("device_register() failed for tl_hba->dev: %d\n", ret);
++		put_device(&tl_hba->dev);
+ 		return -ENODEV;
+ 	}
+ 
+@@ -1073,7 +1074,7 @@ check_len:
+ 	 */
+ 	ret = tcm_loop_setup_hba_bus(tl_hba, tcm_loop_hba_no_cnt);
+ 	if (ret)
+-		goto out;
++		return ERR_PTR(ret);
+ 
+ 	sh = tl_hba->sh;
+ 	tcm_loop_hba_no_cnt++;
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index 01c112e2e2142..2a0de70e0be41 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -1670,7 +1670,7 @@ static struct gsm_control *gsm_control_send(struct gsm_mux *gsm,
+ 		unsigned int command, u8 *data, int clen)
+ {
+ 	struct gsm_control *ctrl = kzalloc(sizeof(struct gsm_control),
+-						GFP_KERNEL);
++						GFP_ATOMIC);
+ 	unsigned long flags;
+ 	if (ctrl == NULL)
+ 		return NULL;
+diff --git a/drivers/tty/serial/8250/8250_lpss.c b/drivers/tty/serial/8250/8250_lpss.c
+index 4ba43bef99336..93643fe6fd9c6 100644
+--- a/drivers/tty/serial/8250/8250_lpss.c
++++ b/drivers/tty/serial/8250/8250_lpss.c
+@@ -174,6 +174,8 @@ static int ehl_serial_setup(struct lpss8250 *lpss, struct uart_port *port)
+ 	 */
+ 	up->dma = dma;
+ 
++	lpss->dma_maxburst = 16;
++
+ 	port->set_termios = dw8250_do_set_termios;
+ 
+ 	return 0;
+@@ -277,8 +279,13 @@ static int lpss8250_dma_setup(struct lpss8250 *lpss, struct uart_8250_port *port
+ 	struct dw_dma_slave *rx_param, *tx_param;
+ 	struct device *dev = port->port.dev;
+ 
+-	if (!lpss->dma_param.dma_dev)
++	if (!lpss->dma_param.dma_dev) {
++		dma = port->dma;
++		if (dma)
++			goto out_configuration_only;
++
+ 		return 0;
++	}
+ 
+ 	rx_param = devm_kzalloc(dev, sizeof(*rx_param), GFP_KERNEL);
+ 	if (!rx_param)
+@@ -289,16 +296,18 @@ static int lpss8250_dma_setup(struct lpss8250 *lpss, struct uart_8250_port *port
+ 		return -ENOMEM;
+ 
+ 	*rx_param = lpss->dma_param;
+-	dma->rxconf.src_maxburst = lpss->dma_maxburst;
+-
+ 	*tx_param = lpss->dma_param;
+-	dma->txconf.dst_maxburst = lpss->dma_maxburst;
+ 
+ 	dma->fn = lpss8250_dma_filter;
+ 	dma->rx_param = rx_param;
+ 	dma->tx_param = tx_param;
+ 
+ 	port->dma = dma;
++
++out_configuration_only:
++	dma->rxconf.src_maxburst = lpss->dma_maxburst;
++	dma->txconf.dst_maxburst = lpss->dma_maxburst;
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
+index 38ee3e42251af..b96fbf8d31df7 100644
+--- a/drivers/tty/serial/8250/8250_omap.c
++++ b/drivers/tty/serial/8250/8250_omap.c
+@@ -157,7 +157,11 @@ static u32 uart_read(struct uart_8250_port *up, u32 reg)
+ 	return readl(up->port.membase + (reg << up->port.regshift));
+ }
+ 
+-static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
++/*
++ * Called on runtime PM resume path from omap8250_restore_regs(), and
++ * omap8250_set_mctrl().
++ */
++static void __omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ {
+ 	struct uart_8250_port *up = up_to_u8250p(port);
+ 	struct omap8250_priv *priv = up->port.private_data;
+@@ -181,6 +185,20 @@ static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ 	}
+ }
+ 
++static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
++{
++	int err;
++
++	err = pm_runtime_resume_and_get(port->dev);
++	if (err)
++		return;
++
++	__omap8250_set_mctrl(port, mctrl);
++
++	pm_runtime_mark_last_busy(port->dev);
++	pm_runtime_put_autosuspend(port->dev);
++}
++
+ /*
+  * Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460)
+  * The access to uart register after MDR1 Access
+@@ -193,27 +211,10 @@ static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ static void omap_8250_mdr1_errataset(struct uart_8250_port *up,
+ 				     struct omap8250_priv *priv)
+ {
+-	u8 timeout = 255;
+-
+ 	serial_out(up, UART_OMAP_MDR1, priv->mdr1);
+ 	udelay(2);
+ 	serial_out(up, UART_FCR, up->fcr | UART_FCR_CLEAR_XMIT |
+ 			UART_FCR_CLEAR_RCVR);
+-	/*
+-	 * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
+-	 * TX_FIFO_E bit is 1.
+-	 */
+-	while (UART_LSR_THRE != (serial_in(up, UART_LSR) &
+-				(UART_LSR_THRE | UART_LSR_DR))) {
+-		timeout--;
+-		if (!timeout) {
+-			/* Should *never* happen. we warn and carry on */
+-			dev_crit(up->port.dev, "Errata i202: timedout %x\n",
+-				 serial_in(up, UART_LSR));
+-			break;
+-		}
+-		udelay(1);
+-	}
+ }
+ 
+ static void omap_8250_get_divisor(struct uart_port *port, unsigned int baud,
+@@ -341,7 +342,7 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+ 
+ 	omap8250_update_mdr1(up, priv);
+ 
+-	up->port.ops->set_mctrl(&up->port, up->port.mctrl);
++	__omap8250_set_mctrl(&up->port, up->port.mctrl);
+ 
+ 	if (up->port.rs485.flags & SER_RS485_ENABLED)
+ 		serial8250_em485_stop_tx(up);
+@@ -1460,9 +1461,15 @@ err:
+ static int omap8250_remove(struct platform_device *pdev)
+ {
+ 	struct omap8250_priv *priv = platform_get_drvdata(pdev);
++	int err;
++
++	err = pm_runtime_resume_and_get(&pdev->dev);
++	if (err)
++		return err;
+ 
+ 	pm_runtime_dont_use_autosuspend(&pdev->dev);
+ 	pm_runtime_put_sync(&pdev->dev);
++	flush_work(&priv->qos_work);
+ 	pm_runtime_disable(&pdev->dev);
+ 	serial8250_unregister_port(priv->line);
+ 	cpu_latency_qos_remove_request(&priv->pm_qos_request);
+diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
+index 2030a92ac66e7..ca7415360f106 100644
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -1892,10 +1892,13 @@ EXPORT_SYMBOL_GPL(serial8250_modem_status);
+ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
+ {
+ 	switch (iir & 0x3f) {
+-	case UART_IIR_RX_TIMEOUT:
+-		serial8250_rx_dma_flush(up);
++	case UART_IIR_RDI:
++		if (!up->dma->rx_running)
++			break;
+ 		fallthrough;
+ 	case UART_IIR_RLSI:
++	case UART_IIR_RX_TIMEOUT:
++		serial8250_rx_dma_flush(up);
+ 		return true;
+ 	}
+ 	return up->dma->rx_dma(up);
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index 34990901c805e..c8297102e087a 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -12,6 +12,7 @@
+ #include <linux/dmaengine.h>
+ #include <linux/dmapool.h>
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/irq.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+@@ -404,33 +405,6 @@ static unsigned int lpuart_get_baud_clk_rate(struct lpuart_port *sport)
+ #define lpuart_enable_clks(x)	__lpuart_enable_clks(x, true)
+ #define lpuart_disable_clks(x)	__lpuart_enable_clks(x, false)
+ 
+-static int lpuart_global_reset(struct lpuart_port *sport)
+-{
+-	struct uart_port *port = &sport->port;
+-	void __iomem *global_addr;
+-	int ret;
+-
+-	if (uart_console(port))
+-		return 0;
+-
+-	ret = clk_prepare_enable(sport->ipg_clk);
+-	if (ret) {
+-		dev_err(sport->port.dev, "failed to enable uart ipg clk: %d\n", ret);
+-		return ret;
+-	}
+-
+-	if (is_imx7ulp_lpuart(sport) || is_imx8qxp_lpuart(sport)) {
+-		global_addr = port->membase + UART_GLOBAL - IMX_REG_OFF;
+-		writel(UART_GLOBAL_RST, global_addr);
+-		usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US);
+-		writel(0, global_addr);
+-		usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US);
+-	}
+-
+-	clk_disable_unprepare(sport->ipg_clk);
+-	return 0;
+-}
+-
+ static void lpuart_stop_tx(struct uart_port *port)
+ {
+ 	unsigned char temp;
+@@ -2641,6 +2615,54 @@ static const struct serial_rs485 lpuart_rs485_supported = {
+ 	/* delay_rts_* and RX_DURING_TX are not supported */
+ };
+ 
++static int lpuart_global_reset(struct lpuart_port *sport)
++{
++	struct uart_port *port = &sport->port;
++	void __iomem *global_addr;
++	unsigned long ctrl, bd;
++	unsigned int val = 0;
++	int ret;
++
++	ret = clk_prepare_enable(sport->ipg_clk);
++	if (ret) {
++		dev_err(sport->port.dev, "failed to enable uart ipg clk: %d\n", ret);
++		return ret;
++	}
++
++	if (is_imx7ulp_lpuart(sport) || is_imx8qxp_lpuart(sport)) {
++		/*
++		 * If the transmitter is used by earlycon, wait for transmit engine to
++		 * complete and then reset.
++		 */
++		ctrl = lpuart32_read(port, UARTCTRL);
++		if (ctrl & UARTCTRL_TE) {
++			bd = lpuart32_read(&sport->port, UARTBAUD);
++			if (read_poll_timeout(lpuart32_tx_empty, val, val, 1, 100000, false,
++					      port)) {
++				dev_warn(sport->port.dev,
++					 "timeout waiting for transmit engine to complete\n");
++				clk_disable_unprepare(sport->ipg_clk);
++				return 0;
++			}
++		}
++
++		global_addr = port->membase + UART_GLOBAL - IMX_REG_OFF;
++		writel(UART_GLOBAL_RST, global_addr);
++		usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US);
++		writel(0, global_addr);
++		usleep_range(GLOBAL_RST_MIN_US, GLOBAL_RST_MAX_US);
++
++		/* Recover the transmitter for earlycon. */
++		if (ctrl & UARTCTRL_TE) {
++			lpuart32_write(port, bd, UARTBAUD);
++			lpuart32_write(port, ctrl, UARTCTRL);
++		}
++	}
++
++	clk_disable_unprepare(sport->ipg_clk);
++	return 0;
++}
++
+ static int lpuart_probe(struct platform_device *pdev)
+ {
+ 	const struct lpuart_soc_data *sdata = of_device_get_match_data(&pdev->dev);
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index 278b4033a3cce..57e3fda979eae 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -2594,6 +2594,7 @@ static const struct dev_pm_ops imx_uart_pm_ops = {
+ 	.suspend_noirq = imx_uart_suspend_noirq,
+ 	.resume_noirq = imx_uart_resume_noirq,
+ 	.freeze_noirq = imx_uart_suspend_noirq,
++	.thaw_noirq = imx_uart_resume_noirq,
+ 	.restore_noirq = imx_uart_resume_noirq,
+ 	.suspend = imx_uart_suspend,
+ 	.resume = imx_uart_resume,
+diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c
+index 9643b905e2d8b..6164fc4c96a49 100644
+--- a/drivers/usb/cdns3/host.c
++++ b/drivers/usb/cdns3/host.c
+@@ -24,11 +24,37 @@
+ #define CFG_RXDET_P3_EN		BIT(15)
+ #define LPM_2_STB_SWITCH_EN	BIT(25)
+ 
+-static int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd);
++static void xhci_cdns3_plat_start(struct usb_hcd *hcd)
++{
++	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
++	u32 value;
++
++	/* set usbcmd.EU3S */
++	value = readl(&xhci->op_regs->command);
++	value |= CMD_PM_INDEX;
++	writel(value, &xhci->op_regs->command);
++
++	if (hcd->regs) {
++		value = readl(hcd->regs + XECP_AUX_CTRL_REG1);
++		value |= CFG_RXDET_P3_EN;
++		writel(value, hcd->regs + XECP_AUX_CTRL_REG1);
++
++		value = readl(hcd->regs + XECP_PORT_CAP_REG);
++		value |= LPM_2_STB_SWITCH_EN;
++		writel(value, hcd->regs + XECP_PORT_CAP_REG);
++	}
++}
++
++static int xhci_cdns3_resume_quirk(struct usb_hcd *hcd)
++{
++	xhci_cdns3_plat_start(hcd);
++	return 0;
++}
+ 
+ static const struct xhci_plat_priv xhci_plat_cdns3_xhci = {
+ 	.quirks = XHCI_SKIP_PHY_INIT | XHCI_AVOID_BEI,
+-	.suspend_quirk = xhci_cdns3_suspend_quirk,
++	.plat_start = xhci_cdns3_plat_start,
++	.resume_quirk = xhci_cdns3_resume_quirk,
+ };
+ 
+ static int __cdns_host_init(struct cdns *cdns)
+@@ -90,32 +116,6 @@ err1:
+ 	return ret;
+ }
+ 
+-static int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd)
+-{
+-	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
+-	u32 value;
+-
+-	if (pm_runtime_status_suspended(hcd->self.controller))
+-		return 0;
+-
+-	/* set usbcmd.EU3S */
+-	value = readl(&xhci->op_regs->command);
+-	value |= CMD_PM_INDEX;
+-	writel(value, &xhci->op_regs->command);
+-
+-	if (hcd->regs) {
+-		value = readl(hcd->regs + XECP_AUX_CTRL_REG1);
+-		value |= CFG_RXDET_P3_EN;
+-		writel(value, hcd->regs + XECP_AUX_CTRL_REG1);
+-
+-		value = readl(hcd->regs + XECP_PORT_CAP_REG);
+-		value |= LPM_2_STB_SWITCH_EN;
+-		writel(value, hcd->regs + XECP_PORT_CAP_REG);
+-	}
+-
+-	return 0;
+-}
+-
+ static void cdns_host_exit(struct cdns *cdns)
+ {
+ 	kfree(cdns->xhci_plat_data);
+diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c
+index 61b157b9c6626..a78584624288a 100644
+--- a/drivers/usb/chipidea/otg_fsm.c
++++ b/drivers/usb/chipidea/otg_fsm.c
+@@ -256,8 +256,10 @@ static void ci_otg_del_timer(struct ci_hdrc *ci, enum otg_fsm_timer t)
+ 	ci->enabled_otg_timer_bits &= ~(1 << t);
+ 	if (ci->next_otg_timer == t) {
+ 		if (ci->enabled_otg_timer_bits == 0) {
++			spin_unlock_irqrestore(&ci->lock, flags);
+ 			/* No enabled timers after delete it */
+ 			hrtimer_cancel(&ci->otg_fsm_hrtimer);
++			spin_lock_irqsave(&ci->lock, flags);
+ 			ci->next_otg_timer = NUM_OTG_FSM_TIMERS;
+ 		} else {
+ 			/* Find the next timer */
+diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
+index 0722d21313055..079e183cf3bff 100644
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -362,6 +362,9 @@ static const struct usb_device_id usb_quirk_list[] = {
+ 	{ USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM },
+ 	{ USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },
+ 
++	/* Realforce 87U Keyboard */
++	{ USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM },
++
+ 	/* M-Systems Flash Disk Pioneers */
+ 	{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index d03e1a9c144c1..038140b1de37b 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -1710,6 +1710,16 @@ static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
+ 	if (device_property_read_string(dev, "linux,extcon-name", &name) == 0)
+ 		return extcon_get_extcon_dev(name);
+ 
++	/*
++	 * Check explicitly if "usb-role-switch" is used since
++	 * extcon_find_edev_by_node() can not be used to check the absence of
++	 * an extcon device. In the absence of an device it will always return
++	 * EPROBE_DEFER.
++	 */
++	if (IS_ENABLED(CONFIG_USB_ROLE_SWITCH) &&
++	    device_property_read_bool(dev, "usb-role-switch"))
++		return NULL;
++
+ 	/*
+ 	 * Try to get an extcon device from the USB PHY controller's "port"
+ 	 * node. Check if it has the "port" node first, to avoid printing the
+diff --git a/drivers/usb/dwc3/host.c b/drivers/usb/dwc3/host.c
+index a7154fe8206d1..f6f13e7f1ba14 100644
+--- a/drivers/usb/dwc3/host.c
++++ b/drivers/usb/dwc3/host.c
+@@ -11,13 +11,8 @@
+ #include <linux/of.h>
+ #include <linux/platform_device.h>
+ 
+-#include "../host/xhci-plat.h"
+ #include "core.h"
+ 
+-static const struct xhci_plat_priv dwc3_xhci_plat_priv = {
+-	.quirks = XHCI_SKIP_PHY_INIT,
+-};
+-
+ static void dwc3_host_fill_xhci_irq_res(struct dwc3 *dwc,
+ 					int irq, char *name)
+ {
+@@ -97,11 +92,6 @@ int dwc3_host_init(struct dwc3 *dwc)
+ 		goto err;
+ 	}
+ 
+-	ret = platform_device_add_data(xhci, &dwc3_xhci_plat_priv,
+-					sizeof(dwc3_xhci_plat_priv));
+-	if (ret)
+-		goto err;
+-
+ 	memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props));
+ 
+ 	if (dwc->usb3_lpm_capable)
+diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c
+index 2df52f75f6b3c..7558cc4d90cc6 100644
+--- a/drivers/usb/host/bcma-hcd.c
++++ b/drivers/usb/host/bcma-hcd.c
+@@ -285,7 +285,7 @@ static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val)
+ {
+ 	struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev);
+ 
+-	if (IS_ERR_OR_NULL(usb_dev->gpio_desc))
++	if (!usb_dev->gpio_desc)
+ 		return;
+ 
+ 	gpiod_set_value(usb_dev->gpio_desc, val);
+@@ -406,9 +406,11 @@ static int bcma_hcd_probe(struct bcma_device *core)
+ 		return -ENOMEM;
+ 	usb_dev->core = core;
+ 
+-	if (core->dev.of_node)
+-		usb_dev->gpio_desc = devm_gpiod_get(&core->dev, "vcc",
+-						    GPIOD_OUT_HIGH);
++	usb_dev->gpio_desc = devm_gpiod_get_optional(&core->dev, "vcc",
++						     GPIOD_OUT_HIGH);
++	if (IS_ERR(usb_dev->gpio_desc))
++		return dev_err_probe(&core->dev, PTR_ERR(usb_dev->gpio_desc),
++				     "error obtaining VCC GPIO");
+ 
+ 	switch (core->id.id) {
+ 	case BCMA_CORE_USB20_HOST:
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 697683e3fbffa..c3b7f1d98e781 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -162,6 +162,8 @@ static void option_instat_callback(struct urb *urb);
+ #define NOVATELWIRELESS_PRODUCT_G2		0xA010
+ #define NOVATELWIRELESS_PRODUCT_MC551		0xB001
+ 
++#define UBLOX_VENDOR_ID				0x1546
++
+ /* AMOI PRODUCTS */
+ #define AMOI_VENDOR_ID				0x1614
+ #define AMOI_PRODUCT_H01			0x0800
+@@ -240,7 +242,6 @@ static void option_instat_callback(struct urb *urb);
+ #define QUECTEL_PRODUCT_UC15			0x9090
+ /* These u-blox products use Qualcomm's vendor ID */
+ #define UBLOX_PRODUCT_R410M			0x90b2
+-#define UBLOX_PRODUCT_R6XX			0x90fa
+ /* These Yuga products use Qualcomm's vendor ID */
+ #define YUGA_PRODUCT_CLM920_NC5			0x9625
+ 
+@@ -581,6 +582,9 @@ static void option_instat_callback(struct urb *urb);
+ #define OPPO_VENDOR_ID				0x22d9
+ #define OPPO_PRODUCT_R11			0x276c
+ 
++/* Sierra Wireless products */
++#define SIERRA_VENDOR_ID			0x1199
++#define SIERRA_PRODUCT_EM9191			0x90d3
+ 
+ /* Device flags */
+ 
+@@ -1124,8 +1128,16 @@ static const struct usb_device_id option_ids[] = {
+ 	/* u-blox products using Qualcomm vendor ID */
+ 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R410M),
+ 	  .driver_info = RSVD(1) | RSVD(3) },
+-	{ USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R6XX),
++	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x908b),	/* u-blox LARA-R6 00B */
++	  .driver_info = RSVD(4) },
++	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x90fa),
+ 	  .driver_info = RSVD(3) },
++	/* u-blox products */
++	{ USB_DEVICE(UBLOX_VENDOR_ID, 0x1341) },	/* u-blox LARA-L6 */
++	{ USB_DEVICE(UBLOX_VENDOR_ID, 0x1342),		/* u-blox LARA-L6 (RMNET) */
++	  .driver_info = RSVD(4) },
++	{ USB_DEVICE(UBLOX_VENDOR_ID, 0x1343),		/* u-blox LARA-L6 (ECM) */
++	  .driver_info = RSVD(4) },
+ 	/* Quectel products using Quectel vendor ID */
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21, 0xff, 0xff, 0xff),
+ 	  .driver_info = NUMEP2 },
+@@ -2167,6 +2179,7 @@ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x010a, 0xff) },			/* Fibocom MA510 (ECM mode) */
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) },	/* Fibocom FG150 Diag */
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) },		/* Fibocom FG150 AT */
++	{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0111, 0xff) },			/* Fibocom FM160 (MBIM mode) */
+ 	{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) },			/* Fibocom NL668-AM/NL652-EU (laptop MBIM) */
+ 	{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a2, 0xff) },			/* Fibocom FM101-GL (laptop MBIM) */
+ 	{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a4, 0xff),			/* Fibocom FM101-GL (laptop MBIM) */
+@@ -2176,6 +2189,8 @@ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) },			/* GosunCn GM500 MBIM */
+ 	{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) },			/* GosunCn GM500 ECM/NCM */
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
+ 	{ } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, option_ids);
+diff --git a/drivers/usb/typec/mux/intel_pmc_mux.c b/drivers/usb/typec/mux/intel_pmc_mux.c
+index a8e273fe204ab..795829ffe7768 100644
+--- a/drivers/usb/typec/mux/intel_pmc_mux.c
++++ b/drivers/usb/typec/mux/intel_pmc_mux.c
+@@ -369,13 +369,24 @@ pmc_usb_mux_usb4(struct pmc_usb_port *port, struct typec_mux_state *state)
+ 	return pmc_usb_command(port, (void *)&req, sizeof(req));
+ }
+ 
+-static int pmc_usb_mux_safe_state(struct pmc_usb_port *port)
++static int pmc_usb_mux_safe_state(struct pmc_usb_port *port,
++				  struct typec_mux_state *state)
+ {
+ 	u8 msg;
+ 
+ 	if (IOM_PORT_ACTIVITY_IS(port->iom_status, SAFE_MODE))
+ 		return 0;
+ 
++	if ((IOM_PORT_ACTIVITY_IS(port->iom_status, DP) ||
++	     IOM_PORT_ACTIVITY_IS(port->iom_status, DP_MFD)) &&
++	     state->alt && state->alt->svid == USB_TYPEC_DP_SID)
++		return 0;
++
++	if ((IOM_PORT_ACTIVITY_IS(port->iom_status, TBT) ||
++	     IOM_PORT_ACTIVITY_IS(port->iom_status, ALT_MODE_TBT_USB)) &&
++	     state->alt && state->alt->svid == USB_TYPEC_TBT_SID)
++		return 0;
++
+ 	msg = PMC_USB_SAFE_MODE;
+ 	msg |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
+ 
+@@ -443,7 +454,7 @@ pmc_usb_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state)
+ 		return 0;
+ 
+ 	if (state->mode == TYPEC_STATE_SAFE)
+-		return pmc_usb_mux_safe_state(port);
++		return pmc_usb_mux_safe_state(port, state);
+ 	if (state->mode == TYPEC_STATE_USB)
+ 		return pmc_usb_connect(port, port->role);
+ 
+diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
+index dfbba5ae9487b..92e35e62e78c2 100644
+--- a/drivers/usb/typec/tipd/core.c
++++ b/drivers/usb/typec/tipd/core.c
+@@ -474,7 +474,7 @@ static void tps6598x_handle_plug_event(struct tps6598x *tps, u32 status)
+ static irqreturn_t cd321x_interrupt(int irq, void *data)
+ {
+ 	struct tps6598x *tps = data;
+-	u64 event;
++	u64 event = 0;
+ 	u32 status;
+ 	int ret;
+ 
+@@ -519,8 +519,8 @@ err_unlock:
+ static irqreturn_t tps6598x_interrupt(int irq, void *data)
+ {
+ 	struct tps6598x *tps = data;
+-	u64 event1;
+-	u64 event2;
++	u64 event1 = 0;
++	u64 event2 = 0;
+ 	u32 status;
+ 	int ret;
+ 
+diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
+index 7cb56c382c97a..48ceca04d9b8a 100644
+--- a/drivers/vfio/vfio_main.c
++++ b/drivers/vfio/vfio_main.c
+@@ -710,8 +710,9 @@ EXPORT_SYMBOL_GPL(vfio_unregister_group_dev);
+ /*
+  * VFIO base fd, /dev/vfio/vfio
+  */
+-static long vfio_ioctl_check_extension(struct vfio_container *container,
+-				       unsigned long arg)
++static long
++vfio_container_ioctl_check_extension(struct vfio_container *container,
++				     unsigned long arg)
+ {
+ 	struct vfio_iommu_driver *driver;
+ 	long ret = 0;
+@@ -868,7 +869,7 @@ static long vfio_fops_unl_ioctl(struct file *filep,
+ 		ret = VFIO_API_VERSION;
+ 		break;
+ 	case VFIO_CHECK_EXTENSION:
+-		ret = vfio_ioctl_check_extension(container, arg);
++		ret = vfio_container_ioctl_check_extension(container, arg);
+ 		break;
+ 	case VFIO_SET_IOMMU:
+ 		ret = vfio_ioctl_set_iommu(container, arg);
+@@ -1085,9 +1086,28 @@ static void vfio_device_unassign_container(struct vfio_device *device)
+ 	up_write(&device->group->group_rwsem);
+ }
+ 
++static void vfio_device_container_register(struct vfio_device *device)
++{
++	struct vfio_iommu_driver *iommu_driver =
++		device->group->container->iommu_driver;
++
++	if (iommu_driver && iommu_driver->ops->register_device)
++		iommu_driver->ops->register_device(
++			device->group->container->iommu_data, device);
++}
++
++static void vfio_device_container_unregister(struct vfio_device *device)
++{
++	struct vfio_iommu_driver *iommu_driver =
++		device->group->container->iommu_driver;
++
++	if (iommu_driver && iommu_driver->ops->unregister_device)
++		iommu_driver->ops->unregister_device(
++			device->group->container->iommu_data, device);
++}
++
+ static struct file *vfio_device_open(struct vfio_device *device)
+ {
+-	struct vfio_iommu_driver *iommu_driver;
+ 	struct file *filep;
+ 	int ret;
+ 
+@@ -1118,12 +1138,7 @@ static struct file *vfio_device_open(struct vfio_device *device)
+ 			if (ret)
+ 				goto err_undo_count;
+ 		}
+-
+-		iommu_driver = device->group->container->iommu_driver;
+-		if (iommu_driver && iommu_driver->ops->register_device)
+-			iommu_driver->ops->register_device(
+-				device->group->container->iommu_data, device);
+-
++		vfio_device_container_register(device);
+ 		up_read(&device->group->group_rwsem);
+ 	}
+ 	mutex_unlock(&device->dev_set->lock);
+@@ -1161,10 +1176,7 @@ err_close_device:
+ 	if (device->open_count == 1 && device->ops->close_device) {
+ 		device->ops->close_device(device);
+ 
+-		iommu_driver = device->group->container->iommu_driver;
+-		if (iommu_driver && iommu_driver->ops->unregister_device)
+-			iommu_driver->ops->unregister_device(
+-				device->group->container->iommu_data, device);
++		vfio_device_container_unregister(device);
+ 	}
+ err_undo_count:
+ 	up_read(&device->group->group_rwsem);
+@@ -1360,7 +1372,6 @@ static const struct file_operations vfio_group_fops = {
+ static int vfio_device_fops_release(struct inode *inode, struct file *filep)
+ {
+ 	struct vfio_device *device = filep->private_data;
+-	struct vfio_iommu_driver *iommu_driver;
+ 
+ 	mutex_lock(&device->dev_set->lock);
+ 	vfio_assert_device_open(device);
+@@ -1368,10 +1379,7 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep)
+ 	if (device->open_count == 1 && device->ops->close_device)
+ 		device->ops->close_device(device);
+ 
+-	iommu_driver = device->group->container->iommu_driver;
+-	if (iommu_driver && iommu_driver->ops->unregister_device)
+-		iommu_driver->ops->unregister_device(
+-			device->group->container->iommu_data, device);
++	vfio_device_container_unregister(device);
+ 	up_read(&device->group->group_rwsem);
+ 	device->open_count--;
+ 	if (device->open_count == 0)
+@@ -1763,8 +1771,8 @@ bool vfio_file_enforced_coherent(struct file *file)
+ 
+ 	down_read(&group->group_rwsem);
+ 	if (group->container) {
+-		ret = vfio_ioctl_check_extension(group->container,
+-						 VFIO_DMA_CC_IOMMU);
++		ret = vfio_container_ioctl_check_extension(group->container,
++							   VFIO_DMA_CC_IOMMU);
+ 	} else {
+ 		/*
+ 		 * Since the coherency state is determined only once a container
+diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c
+index 47aa3a1ccaf57..fd3a644b08559 100644
+--- a/drivers/xen/pcpu.c
++++ b/drivers/xen/pcpu.c
+@@ -228,7 +228,7 @@ static int register_pcpu(struct pcpu *pcpu)
+ 
+ 	err = device_register(dev);
+ 	if (err) {
+-		pcpu_release(dev);
++		put_device(dev);
+ 		return err;
+ 	}
+ 
+diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
+index 2feb5c20641ae..a21b9e085d1b5 100644
+--- a/fs/btrfs/raid56.c
++++ b/fs/btrfs/raid56.c
+@@ -2767,8 +2767,10 @@ raid56_alloc_missing_rbio(struct bio *bio, struct btrfs_io_context *bioc)
+ 
+ 	rbio->faila = find_logical_bio_stripe(rbio, bio);
+ 	if (rbio->faila == -1) {
+-		BUG();
+-		kfree(rbio);
++		btrfs_warn_rl(fs_info,
++	"can not determine the failed stripe number for full stripe %llu",
++			      bioc->raid_map[0]);
++		__free_raid_bio(rbio);
+ 		return NULL;
+ 	}
+ 
+diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c
+index 843dd3d3adbe7..63676ea19f29e 100644
+--- a/fs/btrfs/tests/qgroup-tests.c
++++ b/fs/btrfs/tests/qgroup-tests.c
+@@ -225,7 +225,6 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+ 	 */
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false);
+ 	if (ret) {
+-		ulist_free(old_roots);
+ 		test_err("couldn't find old roots: %d", ret);
+ 		return ret;
+ 	}
+@@ -240,7 +239,6 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ 	if (ret) {
+ 		ulist_free(old_roots);
+-		ulist_free(new_roots);
+ 		test_err("couldn't find old roots: %d", ret);
+ 		return ret;
+ 	}
+@@ -252,17 +250,18 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+ 		return ret;
+ 	}
+ 
++	/* btrfs_qgroup_account_extent() always frees the ulists passed to it. */
++	old_roots = NULL;
++	new_roots = NULL;
++
+ 	if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID,
+ 				nodesize, nodesize)) {
+ 		test_err("qgroup counts didn't match expected values");
+ 		return -EINVAL;
+ 	}
+-	old_roots = NULL;
+-	new_roots = NULL;
+ 
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false);
+ 	if (ret) {
+-		ulist_free(old_roots);
+ 		test_err("couldn't find old roots: %d", ret);
+ 		return ret;
+ 	}
+@@ -276,7 +275,6 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ 	if (ret) {
+ 		ulist_free(old_roots);
+-		ulist_free(new_roots);
+ 		test_err("couldn't find old roots: %d", ret);
+ 		return ret;
+ 	}
+@@ -326,7 +324,6 @@ static int test_multiple_refs(struct btrfs_root *root,
+ 
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false);
+ 	if (ret) {
+-		ulist_free(old_roots);
+ 		test_err("couldn't find old roots: %d", ret);
+ 		return ret;
+ 	}
+@@ -341,7 +338,6 @@ static int test_multiple_refs(struct btrfs_root *root,
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ 	if (ret) {
+ 		ulist_free(old_roots);
+-		ulist_free(new_roots);
+ 		test_err("couldn't find old roots: %d", ret);
+ 		return ret;
+ 	}
+@@ -361,7 +357,6 @@ static int test_multiple_refs(struct btrfs_root *root,
+ 
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false);
+ 	if (ret) {
+-		ulist_free(old_roots);
+ 		test_err("couldn't find old roots: %d", ret);
+ 		return ret;
+ 	}
+@@ -376,7 +371,6 @@ static int test_multiple_refs(struct btrfs_root *root,
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ 	if (ret) {
+ 		ulist_free(old_roots);
+-		ulist_free(new_roots);
+ 		test_err("couldn't find old roots: %d", ret);
+ 		return ret;
+ 	}
+@@ -402,7 +396,6 @@ static int test_multiple_refs(struct btrfs_root *root,
+ 
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots, false);
+ 	if (ret) {
+-		ulist_free(old_roots);
+ 		test_err("couldn't find old roots: %d", ret);
+ 		return ret;
+ 	}
+@@ -417,7 +410,6 @@ static int test_multiple_refs(struct btrfs_root *root,
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ 	if (ret) {
+ 		ulist_free(old_roots);
+-		ulist_free(new_roots);
+ 		test_err("couldn't find old roots: %d", ret);
+ 		return ret;
+ 	}
+diff --git a/fs/buffer.c b/fs/buffer.c
+index 55e762a58eb65..e1198f4b28c8f 100644
+--- a/fs/buffer.c
++++ b/fs/buffer.c
+@@ -2352,7 +2352,7 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size)
+ 	struct address_space *mapping = inode->i_mapping;
+ 	const struct address_space_operations *aops = mapping->a_ops;
+ 	struct page *page;
+-	void *fsdata;
++	void *fsdata = NULL;
+ 	int err;
+ 
+ 	err = inode_newsize_ok(inode, size);
+@@ -2378,7 +2378,7 @@ static int cont_expand_zero(struct file *file, struct address_space *mapping,
+ 	const struct address_space_operations *aops = mapping->a_ops;
+ 	unsigned int blocksize = i_blocksize(inode);
+ 	struct page *page;
+-	void *fsdata;
++	void *fsdata = NULL;
+ 	pgoff_t index, curidx;
+ 	loff_t curpos;
+ 	unsigned zerofrom, offset, len;
+diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
+index 864cdaa0d2bd6..e4151852184e0 100644
+--- a/fs/ceph/snap.c
++++ b/fs/ceph/snap.c
+@@ -763,7 +763,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+ 	struct ceph_mds_snap_realm *ri;    /* encoded */
+ 	__le64 *snaps;                     /* encoded */
+ 	__le64 *prior_parent_snaps;        /* encoded */
+-	struct ceph_snap_realm *realm = NULL;
++	struct ceph_snap_realm *realm;
+ 	struct ceph_snap_realm *first_realm = NULL;
+ 	struct ceph_snap_realm *realm_to_rebuild = NULL;
+ 	int rebuild_snapcs;
+@@ -774,6 +774,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc,
+ 
+ 	dout("%s deletion=%d\n", __func__, deletion);
+ more:
++	realm = NULL;
+ 	rebuild_snapcs = 0;
+ 	ceph_decode_need(&p, e, sizeof(*ri), bad);
+ 	ri = p;
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index c2c36451a8837..317ca1be9c4c0 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -3846,9 +3846,13 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
+ 	uuid_copy(&cifs_sb->dfs_mount_id, &mnt_ctx.mount_id);
+ 
+ out:
+-	free_xid(mnt_ctx.xid);
+ 	cifs_try_adding_channels(cifs_sb, mnt_ctx.ses);
+-	return mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon);
++	rc = mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon);
++	if (rc)
++		goto error;
++
++	free_xid(mnt_ctx.xid);
++	return rc;
+ 
+ error:
+ 	dfs_cache_put_refsrv_sessions(&mnt_ctx.mount_id);
+@@ -3875,8 +3879,12 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
+ 			goto error;
+ 	}
+ 
++	rc = mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon);
++	if (rc)
++		goto error;
++
+ 	free_xid(mnt_ctx.xid);
+-	return mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon);
++	return rc;
+ 
+ error:
+ 	mount_put_conns(&mnt_ctx);
+diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
+index b6e6e5d6c8dd6..baccda02deabc 100644
+--- a/fs/cifs/ioctl.c
++++ b/fs/cifs/ioctl.c
+@@ -343,7 +343,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
+ 					rc = put_user(ExtAttrBits &
+ 						FS_FL_USER_VISIBLE,
+ 						(int __user *)arg);
+-				if (rc != EOPNOTSUPP)
++				if (rc != -EOPNOTSUPP)
+ 					break;
+ 			}
+ #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
+@@ -373,7 +373,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
+ 			 *		       pSMBFile->fid.netfid,
+ 			 *		       extAttrBits,
+ 			 *		       &ExtAttrMask);
+-			 * if (rc != EOPNOTSUPP)
++			 * if (rc != -EOPNOTSUPP)
+ 			 *	break;
+ 			 */
+ 
+diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
+index 87f60f7367315..35085fa866367 100644
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -400,6 +400,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
+ {
+ 	struct smb_hdr *buf = (struct smb_hdr *)buffer;
+ 	struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
++	struct TCP_Server_Info *pserver;
+ 	struct cifs_ses *ses;
+ 	struct cifs_tcon *tcon;
+ 	struct cifsInodeInfo *pCifsInode;
+@@ -464,9 +465,12 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
+ 	if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
+ 		return false;
+ 
++	/* If server is a channel, select the primary channel */
++	pserver = CIFS_SERVER_IS_CHAN(srv) ? srv->primary_server : srv;
++
+ 	/* look up tcon based on tid & uid */
+ 	spin_lock(&cifs_tcp_ses_lock);
+-	list_for_each_entry(ses, &srv->smb_ses_list, smb_ses_list) {
++	list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
+ 		list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+ 			if (tcon->tid != buf->Tid)
+ 				continue;
+diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
+index d73e5672aac49..3bcd3ac65dc17 100644
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -135,6 +135,7 @@ static __u32 get_neg_ctxt_len(struct smb2_hdr *hdr, __u32 len,
+ int
+ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
+ {
++	struct TCP_Server_Info *pserver;
+ 	struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
+ 	struct smb2_pdu *pdu = (struct smb2_pdu *)shdr;
+ 	int hdr_size = sizeof(struct smb2_hdr);
+@@ -143,6 +144,9 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
+ 	__u32 calc_len; /* calculated length */
+ 	__u64 mid;
+ 
++	/* If server is a channel, select the primary channel */
++	pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
++
+ 	/*
+ 	 * Add function to do table lookup of StructureSize by command
+ 	 * ie Validate the wct via smb2_struct_sizes table above
+@@ -155,7 +159,7 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
+ 
+ 		/* decrypt frame now that it is completely read in */
+ 		spin_lock(&cifs_tcp_ses_lock);
+-		list_for_each_entry(iter, &server->smb_ses_list, smb_ses_list) {
++		list_for_each_entry(iter, &pserver->smb_ses_list, smb_ses_list) {
+ 			if (iter->Suid == le64_to_cpu(thdr->SessionId)) {
+ 				ses = iter;
+ 				break;
+@@ -671,6 +675,7 @@ bool
+ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
+ {
+ 	struct smb2_oplock_break *rsp = (struct smb2_oplock_break *)buffer;
++	struct TCP_Server_Info *pserver;
+ 	struct cifs_ses *ses;
+ 	struct cifs_tcon *tcon;
+ 	struct cifsInodeInfo *cinode;
+@@ -691,9 +696,12 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
+ 
+ 	cifs_dbg(FYI, "oplock level 0x%x\n", rsp->OplockLevel);
+ 
++	/* If server is a channel, select the primary channel */
++	pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
++
+ 	/* look up tcon based on tid & uid */
+ 	spin_lock(&cifs_tcp_ses_lock);
+-	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
++	list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
+ 		list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+ 
+ 			spin_lock(&tcon->open_file_lock);
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 14376437187ae..b724bf42b5401 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -1123,6 +1123,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
+ 				COMPOUND_FID, current->tgid,
+ 				FILE_FULL_EA_INFORMATION,
+ 				SMB2_O_INFO_FILE, 0, data, size);
++	if (rc)
++		goto sea_exit;
+ 	smb2_set_next_command(tcon, &rqst[1]);
+ 	smb2_set_related(&rqst[1]);
+ 
+@@ -1133,6 +1135,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
+ 	rqst[2].rq_nvec = 1;
+ 	rc = SMB2_close_init(tcon, server,
+ 			     &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
++	if (rc)
++		goto sea_exit;
+ 	smb2_set_related(&rqst[2]);
+ 
+ 	rc = compound_send_recv(xid, ses, server,
+@@ -2288,14 +2292,18 @@ static void
+ smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server)
+ {
+ 	struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
++	struct TCP_Server_Info *pserver;
+ 	struct cifs_ses *ses;
+ 	struct cifs_tcon *tcon;
+ 
+ 	if (shdr->Status != STATUS_NETWORK_NAME_DELETED)
+ 		return;
+ 
++	/* If server is a channel, select the primary channel */
++	pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
++
+ 	spin_lock(&cifs_tcp_ses_lock);
+-	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
++	list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
+ 		list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+ 			if (tcon->tid == le32_to_cpu(shdr->Id.SyncId.TreeId)) {
+ 				spin_lock(&tcon->tc_lock);
+diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
+index 4640fc4a8b133..da85cfd7803b3 100644
+--- a/fs/cifs/smb2transport.c
++++ b/fs/cifs/smb2transport.c
+@@ -140,9 +140,13 @@ out:
+ static struct cifs_ses *
+ smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id)
+ {
++	struct TCP_Server_Info *pserver;
+ 	struct cifs_ses *ses;
+ 
+-	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
++	/* If server is a channel, select the primary channel */
++	pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
++
++	list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
+ 		if (ses->Suid != ses_id)
+ 			continue;
+ 		++ses->ses_count;
+diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c
+index b5fd9d71e67f1..46ab2b3f9a3c9 100644
+--- a/fs/erofs/fscache.c
++++ b/fs/erofs/fscache.c
+@@ -69,11 +69,15 @@ static void erofs_fscache_rreq_unlock_folios(struct netfs_io_request *rreq)
+ 
+ 	rcu_read_lock();
+ 	xas_for_each(&xas, folio, last_page) {
+-		unsigned int pgpos =
+-			(folio_index(folio) - start_page) * PAGE_SIZE;
+-		unsigned int pgend = pgpos + folio_size(folio);
++		unsigned int pgpos, pgend;
+ 		bool pg_failed = false;
+ 
++		if (xas_retry(&xas, folio))
++			continue;
++
++		pgpos = (folio_index(folio) - start_page) * PAGE_SIZE;
++		pgend = pgpos + folio_size(folio);
++
+ 		for (;;) {
+ 			if (!subreq) {
+ 				pg_failed = true;
+@@ -234,113 +238,114 @@ out:
+ 	return ret;
+ }
+ 
+-static int erofs_fscache_read_folio_inline(struct folio *folio,
+-					 struct erofs_map_blocks *map)
+-{
+-	struct super_block *sb = folio_mapping(folio)->host->i_sb;
+-	struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
+-	erofs_blk_t blknr;
+-	size_t offset, len;
+-	void *src, *dst;
+-
+-	/* For tail packing layout, the offset may be non-zero. */
+-	offset = erofs_blkoff(map->m_pa);
+-	blknr = erofs_blknr(map->m_pa);
+-	len = map->m_llen;
+-
+-	src = erofs_read_metabuf(&buf, sb, blknr, EROFS_KMAP);
+-	if (IS_ERR(src))
+-		return PTR_ERR(src);
+-
+-	dst = kmap_local_folio(folio, 0);
+-	memcpy(dst, src + offset, len);
+-	memset(dst + len, 0, PAGE_SIZE - len);
+-	kunmap_local(dst);
+-
+-	erofs_put_metabuf(&buf);
+-	return 0;
+-}
+-
+-static int erofs_fscache_read_folio(struct file *file, struct folio *folio)
++/*
++ * Read into page cache in the range described by (@pos, @len).
++ *
++ * On return, the caller is responsible for page unlocking if the output @unlock
++ * is true, or the callee will take this responsibility through netfs_io_request
++ * interface.
++ *
++ * The return value is the number of bytes successfully handled, or negative
++ * error code on failure. The only exception is that, the length of the range
++ * instead of the error code is returned on failure after netfs_io_request is
++ * allocated, so that .readahead() could advance rac accordingly.
++ */
++static int erofs_fscache_data_read(struct address_space *mapping,
++				   loff_t pos, size_t len, bool *unlock)
+ {
+-	struct inode *inode = folio_mapping(folio)->host;
++	struct inode *inode = mapping->host;
+ 	struct super_block *sb = inode->i_sb;
++	struct netfs_io_request *rreq;
+ 	struct erofs_map_blocks map;
+ 	struct erofs_map_dev mdev;
+-	struct netfs_io_request *rreq;
+-	erofs_off_t pos;
+-	loff_t pstart;
++	struct iov_iter iter;
++	size_t count;
+ 	int ret;
+ 
+-	DBG_BUGON(folio_size(folio) != EROFS_BLKSIZ);
++	*unlock = true;
+ 
+-	pos = folio_pos(folio);
+ 	map.m_la = pos;
+-
+ 	ret = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW);
+ 	if (ret)
+-		goto out_unlock;
++		return ret;
+ 
+-	if (!(map.m_flags & EROFS_MAP_MAPPED)) {
+-		folio_zero_range(folio, 0, folio_size(folio));
+-		goto out_uptodate;
++	if (map.m_flags & EROFS_MAP_META) {
++		struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
++		erofs_blk_t blknr;
++		size_t offset, size;
++		void *src;
++
++		/* For tail packing layout, the offset may be non-zero. */
++		offset = erofs_blkoff(map.m_pa);
++		blknr = erofs_blknr(map.m_pa);
++		size = map.m_llen;
++
++		src = erofs_read_metabuf(&buf, sb, blknr, EROFS_KMAP);
++		if (IS_ERR(src))
++			return PTR_ERR(src);
++
++		iov_iter_xarray(&iter, READ, &mapping->i_pages, pos, PAGE_SIZE);
++		if (copy_to_iter(src + offset, size, &iter) != size) {
++			erofs_put_metabuf(&buf);
++			return -EFAULT;
++		}
++		iov_iter_zero(PAGE_SIZE - size, &iter);
++		erofs_put_metabuf(&buf);
++		return PAGE_SIZE;
+ 	}
+ 
+-	if (map.m_flags & EROFS_MAP_META) {
+-		ret = erofs_fscache_read_folio_inline(folio, &map);
+-		goto out_uptodate;
++	if (!(map.m_flags & EROFS_MAP_MAPPED)) {
++		count = len;
++		iov_iter_xarray(&iter, READ, &mapping->i_pages, pos, count);
++		iov_iter_zero(count, &iter);
++		return count;
+ 	}
+ 
++	count = min_t(size_t, map.m_llen - (pos - map.m_la), len);
++	DBG_BUGON(!count || count % PAGE_SIZE);
++
+ 	mdev = (struct erofs_map_dev) {
+ 		.m_deviceid = map.m_deviceid,
+ 		.m_pa = map.m_pa,
+ 	};
+-
+ 	ret = erofs_map_dev(sb, &mdev);
+ 	if (ret)
+-		goto out_unlock;
+-
+-
+-	rreq = erofs_fscache_alloc_request(folio_mapping(folio),
+-				folio_pos(folio), folio_size(folio));
+-	if (IS_ERR(rreq)) {
+-		ret = PTR_ERR(rreq);
+-		goto out_unlock;
+-	}
++		return ret;
+ 
+-	pstart = mdev.m_pa + (pos - map.m_la);
+-	return erofs_fscache_read_folios_async(mdev.m_fscache->cookie,
+-				rreq, pstart);
++	rreq = erofs_fscache_alloc_request(mapping, pos, count);
++	if (IS_ERR(rreq))
++		return PTR_ERR(rreq);
+ 
+-out_uptodate:
+-	if (!ret)
+-		folio_mark_uptodate(folio);
+-out_unlock:
+-	folio_unlock(folio);
+-	return ret;
++	*unlock = false;
++	erofs_fscache_read_folios_async(mdev.m_fscache->cookie,
++			rreq, mdev.m_pa + (pos - map.m_la));
++	return count;
+ }
+ 
+-static void erofs_fscache_advance_folios(struct readahead_control *rac,
+-					 size_t len, bool unlock)
++static int erofs_fscache_read_folio(struct file *file, struct folio *folio)
+ {
+-	while (len) {
+-		struct folio *folio = readahead_folio(rac);
+-		len -= folio_size(folio);
+-		if (unlock) {
++	bool unlock;
++	int ret;
++
++	DBG_BUGON(folio_size(folio) != EROFS_BLKSIZ);
++
++	ret = erofs_fscache_data_read(folio_mapping(folio), folio_pos(folio),
++				      folio_size(folio), &unlock);
++	if (unlock) {
++		if (ret > 0)
+ 			folio_mark_uptodate(folio);
+-			folio_unlock(folio);
+-		}
++		folio_unlock(folio);
+ 	}
++	return ret < 0 ? ret : 0;
+ }
+ 
+ static void erofs_fscache_readahead(struct readahead_control *rac)
+ {
+-	struct inode *inode = rac->mapping->host;
+-	struct super_block *sb = inode->i_sb;
+-	size_t len, count, done = 0;
+-	erofs_off_t pos;
+-	loff_t start, offset;
+-	int ret;
++	struct folio *folio;
++	size_t len, done = 0;
++	loff_t start, pos;
++	bool unlock;
++	int ret, size;
+ 
+ 	if (!readahead_count(rac))
+ 		return;
+@@ -349,67 +354,22 @@ static void erofs_fscache_readahead(struct readahead_control *rac)
+ 	len = readahead_length(rac);
+ 
+ 	do {
+-		struct erofs_map_blocks map;
+-		struct erofs_map_dev mdev;
+-		struct netfs_io_request *rreq;
+-
+ 		pos = start + done;
+-		map.m_la = pos;
+-
+-		ret = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW);
+-		if (ret)
++		ret = erofs_fscache_data_read(rac->mapping, pos,
++					      len - done, &unlock);
++		if (ret <= 0)
+ 			return;
+ 
+-		offset = start + done;
+-		count = min_t(size_t, map.m_llen - (pos - map.m_la),
+-			      len - done);
+-
+-		if (!(map.m_flags & EROFS_MAP_MAPPED)) {
+-			struct iov_iter iter;
+-
+-			iov_iter_xarray(&iter, READ, &rac->mapping->i_pages,
+-					offset, count);
+-			iov_iter_zero(count, &iter);
+-
+-			erofs_fscache_advance_folios(rac, count, true);
+-			ret = count;
+-			continue;
+-		}
+-
+-		if (map.m_flags & EROFS_MAP_META) {
+-			struct folio *folio = readahead_folio(rac);
+-
+-			ret = erofs_fscache_read_folio_inline(folio, &map);
+-			if (!ret) {
++		size = ret;
++		while (size) {
++			folio = readahead_folio(rac);
++			size -= folio_size(folio);
++			if (unlock) {
+ 				folio_mark_uptodate(folio);
+-				ret = folio_size(folio);
++				folio_unlock(folio);
+ 			}
+-
+-			folio_unlock(folio);
+-			continue;
+ 		}
+-
+-		mdev = (struct erofs_map_dev) {
+-			.m_deviceid = map.m_deviceid,
+-			.m_pa = map.m_pa,
+-		};
+-		ret = erofs_map_dev(sb, &mdev);
+-		if (ret)
+-			return;
+-
+-		rreq = erofs_fscache_alloc_request(rac->mapping, offset, count);
+-		if (IS_ERR(rreq))
+-			return;
+-		/*
+-		 * Drop the ref of folios here. Unlock them in
+-		 * rreq_unlock_folios() when rreq complete.
+-		 */
+-		erofs_fscache_advance_folios(rac, count, false);
+-		ret = erofs_fscache_read_folios_async(mdev.m_fscache->cookie,
+-					rreq, mdev.m_pa + (pos - map.m_la));
+-		if (!ret)
+-			ret = count;
+-	} while (ret > 0 && ((done += ret) < len));
++	} while ((done += ret) < len);
+ }
+ 
+ static const struct address_space_operations erofs_fscache_meta_aops = {
+diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
+index 549879929c847..c7e2e62383668 100644
+--- a/fs/gfs2/ops_fstype.c
++++ b/fs/gfs2/ops_fstype.c
+@@ -178,7 +178,10 @@ static int gfs2_check_sb(struct gfs2_sbd *sdp, int silent)
+ 		pr_warn("Invalid block size\n");
+ 		return -EINVAL;
+ 	}
+-
++	if (sb->sb_bsize_shift != ffs(sb->sb_bsize) - 1) {
++		pr_warn("Invalid block size shift\n");
++		return -EINVAL;
++	}
+ 	return 0;
+ }
+ 
+@@ -381,8 +384,10 @@ static int init_names(struct gfs2_sbd *sdp, int silent)
+ 	if (!table[0])
+ 		table = sdp->sd_vfs->s_id;
+ 
+-	strlcpy(sdp->sd_proto_name, proto, GFS2_FSNAME_LEN);
+-	strlcpy(sdp->sd_table_name, table, GFS2_FSNAME_LEN);
++	BUILD_BUG_ON(GFS2_LOCKNAME_LEN > GFS2_FSNAME_LEN);
++
++	strscpy(sdp->sd_proto_name, proto, GFS2_LOCKNAME_LEN);
++	strscpy(sdp->sd_table_name, table, GFS2_LOCKNAME_LEN);
+ 
+ 	table = sdp->sd_table_name;
+ 	while ((table = strchr(table, '/')))
+@@ -1439,13 +1444,13 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
+ 
+ 	switch (o) {
+ 	case Opt_lockproto:
+-		strlcpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN);
++		strscpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN);
+ 		break;
+ 	case Opt_locktable:
+-		strlcpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN);
++		strscpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN);
+ 		break;
+ 	case Opt_hostdata:
+-		strlcpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN);
++		strscpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN);
+ 		break;
+ 	case Opt_spectator:
+ 		args->ar_spectator = 1;
+diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
+index f7a5b5124d8a9..fbcfa6bfee805 100644
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -328,6 +328,12 @@ static ssize_t hugetlbfs_read_iter(struct kiocb *iocb, struct iov_iter *to)
+ 		} else {
+ 			unlock_page(page);
+ 
++			if (PageHWPoison(page)) {
++				put_page(page);
++				retval = -EIO;
++				break;
++			}
++
+ 			/*
+ 			 * We have the page, copy it to user space buffer.
+ 			 */
+@@ -364,7 +370,7 @@ static int hugetlbfs_write_end(struct file *file, struct address_space *mapping,
+ 	return -EINVAL;
+ }
+ 
+-static void remove_huge_page(struct page *page)
++static void hugetlb_delete_from_page_cache(struct page *page)
+ {
+ 	ClearPageDirty(page);
+ 	ClearPageUptodate(page);
+@@ -487,15 +493,14 @@ static void remove_inode_hugepages(struct inode *inode, loff_t lstart,
+ 			folio_lock(folio);
+ 			/*
+ 			 * We must free the huge page and remove from page
+-			 * cache (remove_huge_page) BEFORE removing the
+-			 * region/reserve map (hugetlb_unreserve_pages).  In
+-			 * rare out of memory conditions, removal of the
+-			 * region/reserve map could fail. Correspondingly,
+-			 * the subpool and global reserve usage count can need
+-			 * to be adjusted.
++			 * cache BEFORE removing the region/reserve map
++			 * (hugetlb_unreserve_pages).  In rare out of memory
++			 * conditions, removal of the region/reserve map could
++			 * fail. Correspondingly, the subpool and global
++			 * reserve usage count can need to be adjusted.
+ 			 */
+ 			VM_BUG_ON(HPageRestoreReserve(&folio->page));
+-			remove_huge_page(&folio->page);
++			hugetlb_delete_from_page_cache(&folio->page);
+ 			freed++;
+ 			if (!truncate_op) {
+ 				if (unlikely(hugetlb_unreserve_pages(inode,
+@@ -737,7 +742,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,
+ 		}
+ 		clear_huge_page(page, addr, pages_per_huge_page(h));
+ 		__SetPageUptodate(page);
+-		error = huge_add_to_page_cache(page, mapping, index);
++		error = hugetlb_add_to_page_cache(page, mapping, index);
+ 		if (unlikely(error)) {
+ 			restore_reserve_on_error(h, &pseudo_vma, addr, page);
+ 			put_page(page);
+@@ -749,7 +754,7 @@ static long hugetlbfs_fallocate(struct file *file, int mode, loff_t offset,
+ 
+ 		SetHPageMigratable(page);
+ 		/*
+-		 * unlock_page because locked by huge_add_to_page_cache()
++		 * unlock_page because locked by hugetlb_add_to_page_cache()
+ 		 * put_page() due to reference from alloc_huge_page()
+ 		 */
+ 		unlock_page(page);
+@@ -991,13 +996,6 @@ static int hugetlbfs_migrate_folio(struct address_space *mapping,
+ static int hugetlbfs_error_remove_page(struct address_space *mapping,
+ 				struct page *page)
+ {
+-	struct inode *inode = mapping->host;
+-	pgoff_t index = page->index;
+-
+-	remove_huge_page(page);
+-	if (unlikely(hugetlb_unreserve_pages(inode, index, index + 1, 1)))
+-		hugetlb_fix_reserve_counts(inode);
+-
+ 	return 0;
+ }
+ 
+diff --git a/fs/namei.c b/fs/namei.c
+index 53b4bc094db23..076ae96ca0b14 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -5088,7 +5088,7 @@ int page_symlink(struct inode *inode, const char *symname, int len)
+ 	const struct address_space_operations *aops = mapping->a_ops;
+ 	bool nofs = !mapping_gfp_constraint(mapping, __GFP_FS);
+ 	struct page *page;
+-	void *fsdata;
++	void *fsdata = NULL;
+ 	int err;
+ 	unsigned int flags;
+ 
+diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
+index 0ce5358521510..7679a68e81930 100644
+--- a/fs/netfs/buffered_read.c
++++ b/fs/netfs/buffered_read.c
+@@ -17,9 +17,9 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
+ {
+ 	struct netfs_io_subrequest *subreq;
+ 	struct folio *folio;
+-	unsigned int iopos, account = 0;
+ 	pgoff_t start_page = rreq->start / PAGE_SIZE;
+ 	pgoff_t last_page = ((rreq->start + rreq->len) / PAGE_SIZE) - 1;
++	size_t account = 0;
+ 	bool subreq_failed = false;
+ 
+ 	XA_STATE(xas, &rreq->mapping->i_pages, start_page);
+@@ -39,18 +39,23 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
+ 	 */
+ 	subreq = list_first_entry(&rreq->subrequests,
+ 				  struct netfs_io_subrequest, rreq_link);
+-	iopos = 0;
+ 	subreq_failed = (subreq->error < 0);
+ 
+ 	trace_netfs_rreq(rreq, netfs_rreq_trace_unlock);
+ 
+ 	rcu_read_lock();
+ 	xas_for_each(&xas, folio, last_page) {
+-		unsigned int pgpos = (folio_index(folio) - start_page) * PAGE_SIZE;
+-		unsigned int pgend = pgpos + folio_size(folio);
++		loff_t pg_end;
+ 		bool pg_failed = false;
+ 
++		if (xas_retry(&xas, folio))
++			continue;
++
++		pg_end = folio_pos(folio) + folio_size(folio) - 1;
++
+ 		for (;;) {
++			loff_t sreq_end;
++
+ 			if (!subreq) {
+ 				pg_failed = true;
+ 				break;
+@@ -58,11 +63,11 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
+ 			if (test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags))
+ 				folio_start_fscache(folio);
+ 			pg_failed |= subreq_failed;
+-			if (pgend < iopos + subreq->len)
++			sreq_end = subreq->start + subreq->len - 1;
++			if (pg_end < sreq_end)
+ 				break;
+ 
+ 			account += subreq->transferred;
+-			iopos += subreq->len;
+ 			if (!list_is_last(&subreq->rreq_link, &rreq->subrequests)) {
+ 				subreq = list_next_entry(subreq, rreq_link);
+ 				subreq_failed = (subreq->error < 0);
+@@ -70,7 +75,8 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
+ 				subreq = NULL;
+ 				subreq_failed = false;
+ 			}
+-			if (pgend == iopos)
++
++			if (pg_end == sreq_end)
+ 				break;
+ 		}
+ 
+diff --git a/fs/netfs/io.c b/fs/netfs/io.c
+index 4289258992826..e374767d1b683 100644
+--- a/fs/netfs/io.c
++++ b/fs/netfs/io.c
+@@ -121,6 +121,9 @@ static void netfs_rreq_unmark_after_write(struct netfs_io_request *rreq,
+ 		XA_STATE(xas, &rreq->mapping->i_pages, subreq->start / PAGE_SIZE);
+ 
+ 		xas_for_each(&xas, folio, (subreq->start + subreq->len - 1) / PAGE_SIZE) {
++			if (xas_retry(&xas, folio))
++				continue;
++
+ 			/* We might have multiple writes from the same huge
+ 			 * folio, but we mustn't unlock a folio more than once.
+ 			 */
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 3ed14a2a84a44..313e9145b6c9f 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -7137,6 +7137,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
+ {
+ 	struct nfs4_lockdata *data = calldata;
+ 	struct nfs4_lock_state *lsp = data->lsp;
++	struct nfs_server *server = NFS_SERVER(d_inode(data->ctx->dentry));
+ 
+ 	if (!nfs4_sequence_done(task, &data->res.seq_res))
+ 		return;
+@@ -7144,8 +7145,7 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
+ 	data->rpc_status = task->tk_status;
+ 	switch (task->tk_status) {
+ 	case 0:
+-		renew_lease(NFS_SERVER(d_inode(data->ctx->dentry)),
+-				data->timestamp);
++		renew_lease(server, data->timestamp);
+ 		if (data->arg.new_lock && !data->cancelled) {
+ 			data->fl.fl_flags &= ~(FL_SLEEP | FL_ACCESS);
+ 			if (locks_lock_inode_wait(lsp->ls_state->inode, &data->fl) < 0)
+@@ -7166,6 +7166,8 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
+ 			if (!nfs4_stateid_match(&data->arg.open_stateid,
+ 						&lsp->ls_state->open_stateid))
+ 				goto out_restart;
++			else if (nfs4_async_handle_error(task, server, lsp->ls_state, NULL) == -EAGAIN)
++				goto out_restart;
+ 		} else if (!nfs4_stateid_match(&data->arg.lock_stateid,
+ 						&lsp->ls_stateid))
+ 				goto out_restart;
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index 0bc36472f8b7b..ddb2bf078fdaf 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -5313,6 +5313,7 @@ nfsd4_verify_deleg_dentry(struct nfsd4_open *open, struct nfs4_file *fp,
+ 	if (err)
+ 		return -EAGAIN;
+ 
++	exp_put(exp);
+ 	dput(child);
+ 	if (child != file_dentry(fp->fi_deleg_file->nf_file))
+ 		return -EAGAIN;
+diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
+index 52615e6090e1c..a3865bc4a0c65 100644
+--- a/fs/ntfs/attrib.c
++++ b/fs/ntfs/attrib.c
+@@ -594,17 +594,37 @@ static int ntfs_attr_find(const ATTR_TYPE type, const ntfschar *name,
+ 	for (;;	a = (ATTR_RECORD*)((u8*)a + le32_to_cpu(a->length))) {
+ 		u8 *mrec_end = (u8 *)ctx->mrec +
+ 		               le32_to_cpu(ctx->mrec->bytes_allocated);
+-		u8 *name_end = (u8 *)a + le16_to_cpu(a->name_offset) +
+-			       a->name_length * sizeof(ntfschar);
+-		if ((u8*)a < (u8*)ctx->mrec || (u8*)a > mrec_end ||
+-		    name_end > mrec_end)
++		u8 *name_end;
++
++		/* check whether ATTR_RECORD wrap */
++		if ((u8 *)a < (u8 *)ctx->mrec)
++			break;
++
++		/* check whether Attribute Record Header is within bounds */
++		if ((u8 *)a > mrec_end ||
++		    (u8 *)a + sizeof(ATTR_RECORD) > mrec_end)
++			break;
++
++		/* check whether ATTR_RECORD's name is within bounds */
++		name_end = (u8 *)a + le16_to_cpu(a->name_offset) +
++			   a->name_length * sizeof(ntfschar);
++		if (name_end > mrec_end)
+ 			break;
++
+ 		ctx->attr = a;
+ 		if (unlikely(le32_to_cpu(a->type) > le32_to_cpu(type) ||
+ 				a->type == AT_END))
+ 			return -ENOENT;
+ 		if (unlikely(!a->length))
+ 			break;
++
++		/* check whether ATTR_RECORD's length wrap */
++		if ((u8 *)a + le32_to_cpu(a->length) < (u8 *)a)
++			break;
++		/* check whether ATTR_RECORD's length is within bounds */
++		if ((u8 *)a + le32_to_cpu(a->length) > mrec_end)
++			break;
++
+ 		if (a->type != type)
+ 			continue;
+ 		/*
+diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
+index db0f1995aedd1..08c659332e26b 100644
+--- a/fs/ntfs/inode.c
++++ b/fs/ntfs/inode.c
+@@ -1829,6 +1829,13 @@ int ntfs_read_inode_mount(struct inode *vi)
+ 		goto err_out;
+ 	}
+ 
++	/* Sanity check offset to the first attribute */
++	if (le16_to_cpu(m->attrs_offset) >= le32_to_cpu(m->bytes_allocated)) {
++		ntfs_error(sb, "Incorrect mft offset to the first attribute %u in superblock.",
++			       le16_to_cpu(m->attrs_offset));
++		goto err_out;
++	}
++
+ 	/* Need this to sanity check attribute list references to $MFT. */
+ 	vi->i_generation = ni->seq_no = le16_to_cpu(m->sequence_number);
+ 
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 84b13fdd34a71..79624711fda7c 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -311,6 +311,13 @@ struct queue_limits {
+ 	unsigned char		discard_misaligned;
+ 	unsigned char		raid_partial_stripes_expensive;
+ 	enum blk_zoned_model	zoned;
++
++	/*
++	 * Drivers that set dma_alignment to less than 511 must be prepared to
++	 * handle individual bvec's that are not a multiple of a SECTOR_SIZE
++	 * due to possible offsets.
++	 */
++	unsigned int		dma_alignment;
+ };
+ 
+ typedef int (*report_zones_cb)(struct blk_zone *zone, unsigned int idx,
+@@ -456,12 +463,6 @@ struct request_queue {
+ 	unsigned long		nr_requests;	/* Max # of requests */
+ 
+ 	unsigned int		dma_pad_mask;
+-	/*
+-	 * Drivers that set dma_alignment to less than 511 must be prepared to
+-	 * handle individual bvec's that are not a multiple of a SECTOR_SIZE
+-	 * due to possible offsets.
+-	 */
+-	unsigned int		dma_alignment;
+ 
+ #ifdef CONFIG_BLK_INLINE_ENCRYPTION
+ 	struct blk_crypto_profile *crypto_profile;
+@@ -1311,7 +1312,7 @@ static inline sector_t bdev_zone_sectors(struct block_device *bdev)
+ 
+ static inline int queue_dma_alignment(const struct request_queue *q)
+ {
+-	return q ? q->dma_alignment : 511;
++	return q ? q->limits.dma_alignment : 511;
+ }
+ 
+ static inline unsigned int bdev_dma_alignment(struct block_device *bdev)
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 80fc8a88c610d..73662fbabd78f 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -1967,6 +1967,7 @@ static inline bool unprivileged_ebpf_enabled(void)
+ 	return !sysctl_unprivileged_bpf_disabled;
+ }
+ 
++void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog);
+ #else /* !CONFIG_BPF_SYSCALL */
+ static inline struct bpf_prog *bpf_prog_get(u32 ufd)
+ {
+@@ -2176,6 +2177,9 @@ static inline bool unprivileged_ebpf_enabled(void)
+ 	return false;
+ }
+ 
++static inline void bpf_prog_inc_misses_counter(struct bpf_prog *prog)
++{
++}
+ #endif /* CONFIG_BPF_SYSCALL */
+ 
+ void __bpf_free_used_btfs(struct bpf_prog_aux *aux,
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+index 67c88b82fc32d..53db3648207ae 100644
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -665,7 +665,7 @@ struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid,
+ 				nodemask_t *nmask, gfp_t gfp_mask);
+ struct page *alloc_huge_page_vma(struct hstate *h, struct vm_area_struct *vma,
+ 				unsigned long address);
+-int huge_add_to_page_cache(struct page *page, struct address_space *mapping,
++int hugetlb_add_to_page_cache(struct page *page, struct address_space *mapping,
+ 			pgoff_t idx);
+ void restore_reserve_on_error(struct hstate *h, struct vm_area_struct *vma,
+ 				unsigned long address, struct page *page);
+diff --git a/include/linux/io_uring.h b/include/linux/io_uring.h
+index 4a2f6cc5a4927..ad88c4fa11132 100644
+--- a/include/linux/io_uring.h
++++ b/include/linux/io_uring.h
+@@ -15,6 +15,9 @@ enum io_uring_cmd_flags {
+ 	IO_URING_F_SQE128		= 4,
+ 	IO_URING_F_CQE32		= 8,
+ 	IO_URING_F_IOPOLL		= 16,
++
++	/* the request is executed from poll, it should not be freed */
++	IO_URING_F_MULTISHOT		= 32,
+ };
+ 
+ struct io_uring_cmd {
+diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
+index 2504df9a0453e..3c7d295746f67 100644
+--- a/include/linux/ring_buffer.h
++++ b/include/linux/ring_buffer.h
+@@ -100,7 +100,7 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k
+ 
+ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full);
+ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+-			  struct file *filp, poll_table *poll_table);
++			  struct file *filp, poll_table *poll_table, int full);
+ void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu);
+ 
+ #define RING_BUFFER_ALL_CPUS -1
+diff --git a/include/linux/trace.h b/include/linux/trace.h
+index b5e16e438448f..80ffda8717491 100644
+--- a/include/linux/trace.h
++++ b/include/linux/trace.h
+@@ -26,13 +26,13 @@ struct trace_export {
+ 	int flags;
+ };
+ 
++struct trace_array;
++
+ #ifdef CONFIG_TRACING
+ 
+ int register_ftrace_export(struct trace_export *export);
+ int unregister_ftrace_export(struct trace_export *export);
+ 
+-struct trace_array;
+-
+ void trace_printk_init_buffers(void);
+ __printf(3, 4)
+ int trace_array_printk(struct trace_array *tr, unsigned long ip,
+diff --git a/include/linux/wireless.h b/include/linux/wireless.h
+index 2d1b54556eff4..e6e34d74dda04 100644
+--- a/include/linux/wireless.h
++++ b/include/linux/wireless.h
+@@ -26,7 +26,15 @@ struct compat_iw_point {
+ struct __compat_iw_event {
+ 	__u16		len;			/* Real length of this stuff */
+ 	__u16		cmd;			/* Wireless IOCTL */
+-	compat_caddr_t	pointer;
++
++	union {
++		compat_caddr_t	pointer;
++
++		/* we need ptr_bytes to make memcpy() run-time destination
++		 * buffer bounds checking happy, nothing special
++		 */
++		DECLARE_FLEX_ARRAY(__u8, ptr_bytes);
++	};
+ };
+ #define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer)
+ #define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length)
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 1c979fd1904ce..1eca38ac6c67e 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -563,7 +563,7 @@ static inline void iph_to_flow_copy_v4addrs(struct flow_keys *flow,
+ 	BUILD_BUG_ON(offsetof(typeof(flow->addrs), v4addrs.dst) !=
+ 		     offsetof(typeof(flow->addrs), v4addrs.src) +
+ 			      sizeof(flow->addrs.v4addrs.src));
+-	memcpy(&flow->addrs.v4addrs, &iph->saddr, sizeof(flow->addrs.v4addrs));
++	memcpy(&flow->addrs.v4addrs, &iph->addrs, sizeof(flow->addrs.v4addrs));
+ 	flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+ }
+ 
+diff --git a/include/net/ipv6.h b/include/net/ipv6.h
+index de9dcc5652c48..59125562c1a42 100644
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -897,7 +897,7 @@ static inline void iph_to_flow_copy_v6addrs(struct flow_keys *flow,
+ 	BUILD_BUG_ON(offsetof(typeof(flow->addrs), v6addrs.dst) !=
+ 		     offsetof(typeof(flow->addrs), v6addrs.src) +
+ 		     sizeof(flow->addrs.v6addrs.src));
+-	memcpy(&flow->addrs.v6addrs, &iph->saddr, sizeof(flow->addrs.v6addrs));
++	memcpy(&flow->addrs.v6addrs, &iph->addrs, sizeof(flow->addrs.v6addrs));
+ 	flow->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+ }
+ 
+diff --git a/include/soc/at91/sama7-ddr.h b/include/soc/at91/sama7-ddr.h
+index 6ce3bd22f6c69..5ad7ac2e3a7ce 100644
+--- a/include/soc/at91/sama7-ddr.h
++++ b/include/soc/at91/sama7-ddr.h
+@@ -26,7 +26,10 @@
+ #define	DDR3PHY_PGSR				(0x0C)		/* DDR3PHY PHY General Status Register */
+ #define		DDR3PHY_PGSR_IDONE		(1 << 0)	/* Initialization Done */
+ 
+-#define DDR3PHY_ACIOCR				(0x24)		/*  DDR3PHY AC I/O Configuration Register */
++#define	DDR3PHY_ACDLLCR				(0x14)		/* DDR3PHY AC DLL Control Register */
++#define		DDR3PHY_ACDLLCR_DLLSRST		(1 << 30)	/* DLL Soft Reset */
++
++#define DDR3PHY_ACIOCR				(0x24)		/* DDR3PHY AC I/O Configuration Register */
+ #define		DDR3PHY_ACIOCR_CSPDD_CS0	(1 << 18)	/* CS#[0] Power Down Driver */
+ #define		DDR3PHY_ACIOCR_CKPDD_CK0	(1 << 8)	/* CK[0] Power Down Driver */
+ #define		DDR3PHY_ACIORC_ACPDD		(1 << 3)	/* AC Power Down Driver */
+diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h
+index 961ec16a26b8b..874a92349bf5b 100644
+--- a/include/uapi/linux/ip.h
++++ b/include/uapi/linux/ip.h
+@@ -100,8 +100,10 @@ struct iphdr {
+ 	__u8	ttl;
+ 	__u8	protocol;
+ 	__sum16	check;
+-	__be32	saddr;
+-	__be32	daddr;
++	__struct_group(/* no tag */, addrs, /* no attrs */,
++		__be32	saddr;
++		__be32	daddr;
++	);
+ 	/*The options start here. */
+ };
+ 
+diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
+index 03cdbe798fe3c..81f4243bebb1c 100644
+--- a/include/uapi/linux/ipv6.h
++++ b/include/uapi/linux/ipv6.h
+@@ -130,8 +130,10 @@ struct ipv6hdr {
+ 	__u8			nexthdr;
+ 	__u8			hop_limit;
+ 
+-	struct	in6_addr	saddr;
+-	struct	in6_addr	daddr;
++	__struct_group(/* no tag */, addrs, /* no attrs */,
++		struct	in6_addr	saddr;
++		struct	in6_addr	daddr;
++	);
+ };
+ 
+ 
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index d29f397f095ee..adf73d1625218 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -171,6 +171,11 @@ static inline unsigned int __io_cqring_events(struct io_ring_ctx *ctx)
+ 	return ctx->cached_cq_tail - READ_ONCE(ctx->rings->cq.head);
+ }
+ 
++static inline unsigned int __io_cqring_events_user(struct io_ring_ctx *ctx)
++{
++	return READ_ONCE(ctx->rings->cq.tail) - READ_ONCE(ctx->rings->cq.head);
++}
++
+ static bool io_match_linked(struct io_kiocb *head)
+ {
+ 	struct io_kiocb *req;
+@@ -1613,7 +1618,7 @@ int io_poll_issue(struct io_kiocb *req, bool *locked)
+ 	io_tw_lock(req->ctx, locked);
+ 	if (unlikely(req->task->flags & PF_EXITING))
+ 		return -EFAULT;
+-	return io_issue_sqe(req, IO_URING_F_NONBLOCK);
++	return io_issue_sqe(req, IO_URING_F_NONBLOCK|IO_URING_F_MULTISHOT);
+ }
+ 
+ struct io_wq_work *io_wq_free_work(struct io_wq_work *work)
+@@ -2163,7 +2168,7 @@ struct io_wait_queue {
+ static inline bool io_should_wake(struct io_wait_queue *iowq)
+ {
+ 	struct io_ring_ctx *ctx = iowq->ctx;
+-	int dist = ctx->cached_cq_tail - (int) iowq->cq_tail;
++	int dist = READ_ONCE(ctx->rings->cq.tail) - (int) iowq->cq_tail;
+ 
+ 	/*
+ 	 * Wake up if we have enough events, or if a timeout occurred since we
+@@ -2240,7 +2245,8 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
+ 	do {
+ 		io_cqring_overflow_flush(ctx);
+ 
+-		if (io_cqring_events(ctx) >= min_events)
++		/* if user messes with these they will just get an early return */
++		if (__io_cqring_events_user(ctx) >= min_events)
+ 			return 0;
+ 		if (!io_run_task_work())
+ 			break;
+diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
+index 5121b20a91936..1b552d2137635 100644
+--- a/io_uring/io_uring.h
++++ b/io_uring/io_uring.h
+@@ -17,8 +17,8 @@ enum {
+ 	IOU_ISSUE_SKIP_COMPLETE	= -EIOCBQUEUED,
+ 
+ 	/*
+-	 * Intended only when both REQ_F_POLLED and REQ_F_APOLL_MULTISHOT
+-	 * are set to indicate to the poll runner that multishot should be
++	 * Intended only when both IO_URING_F_MULTISHOT is passed
++	 * to indicate to the poll runner that multishot should be
+ 	 * removed and the result is set on req->cqe.res.
+ 	 */
+ 	IOU_STOP_MULTISHOT	= -ECANCELED,
+diff --git a/io_uring/net.c b/io_uring/net.c
+index 7804ac77745b1..8205cfecd647c 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -66,8 +66,6 @@ struct io_sr_msg {
+ 	struct io_kiocb 		*notif;
+ };
+ 
+-#define IO_APOLL_MULTI_POLLED (REQ_F_APOLL_MULTISHOT | REQ_F_POLLED)
+-
+ int io_shutdown_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+ {
+ 	struct io_shutdown *shutdown = io_kiocb_to_cmd(req, struct io_shutdown);
+@@ -558,7 +556,8 @@ static inline void io_recv_prep_retry(struct io_kiocb *req)
+  * again (for multishot).
+  */
+ static inline bool io_recv_finish(struct io_kiocb *req, int *ret,
+-				  unsigned int cflags, bool mshot_finished)
++				  unsigned int cflags, bool mshot_finished,
++				  unsigned issue_flags)
+ {
+ 	if (!(req->flags & REQ_F_APOLL_MULTISHOT)) {
+ 		io_req_set_res(req, *ret, cflags);
+@@ -581,7 +580,7 @@ static inline bool io_recv_finish(struct io_kiocb *req, int *ret,
+ 
+ 	io_req_set_res(req, *ret, cflags);
+ 
+-	if (req->flags & REQ_F_POLLED)
++	if (issue_flags & IO_URING_F_MULTISHOT)
+ 		*ret = IOU_STOP_MULTISHOT;
+ 	else
+ 		*ret = IOU_OK;
+@@ -740,8 +739,7 @@ retry_multishot:
+ 	if (ret < min_ret) {
+ 		if (ret == -EAGAIN && force_nonblock) {
+ 			ret = io_setup_async_msg(req, kmsg, issue_flags);
+-			if (ret == -EAGAIN && (req->flags & IO_APOLL_MULTI_POLLED) ==
+-					       IO_APOLL_MULTI_POLLED) {
++			if (ret == -EAGAIN && (issue_flags & IO_URING_F_MULTISHOT)) {
+ 				io_kbuf_recycle(req, issue_flags);
+ 				return IOU_ISSUE_SKIP_COMPLETE;
+ 			}
+@@ -770,7 +768,7 @@ retry_multishot:
+ 	if (kmsg->msg.msg_inq)
+ 		cflags |= IORING_CQE_F_SOCK_NONEMPTY;
+ 
+-	if (!io_recv_finish(req, &ret, cflags, mshot_finished))
++	if (!io_recv_finish(req, &ret, cflags, mshot_finished, issue_flags))
+ 		goto retry_multishot;
+ 
+ 	if (mshot_finished) {
+@@ -836,7 +834,7 @@ retry_multishot:
+ 	ret = sock_recvmsg(sock, &msg, flags);
+ 	if (ret < min_ret) {
+ 		if (ret == -EAGAIN && force_nonblock) {
+-			if ((req->flags & IO_APOLL_MULTI_POLLED) == IO_APOLL_MULTI_POLLED) {
++			if (issue_flags & IO_URING_F_MULTISHOT) {
+ 				io_kbuf_recycle(req, issue_flags);
+ 				return IOU_ISSUE_SKIP_COMPLETE;
+ 			}
+@@ -869,7 +867,7 @@ out_free:
+ 	if (msg.msg_inq)
+ 		cflags |= IORING_CQE_F_SOCK_NONEMPTY;
+ 
+-	if (!io_recv_finish(req, &ret, cflags, ret <= 0))
++	if (!io_recv_finish(req, &ret, cflags, ret <= 0, issue_flags))
+ 		goto retry_multishot;
+ 
+ 	return ret;
+@@ -1168,8 +1166,7 @@ retry:
+ 			 * return EAGAIN to arm the poll infra since it
+ 			 * has already been done
+ 			 */
+-			if ((req->flags & IO_APOLL_MULTI_POLLED) ==
+-			    IO_APOLL_MULTI_POLLED)
++			if (issue_flags & IO_URING_F_MULTISHOT)
+ 				ret = IOU_ISSUE_SKIP_COMPLETE;
+ 			return ret;
+ 		}
+@@ -1194,9 +1191,7 @@ retry:
+ 		goto retry;
+ 
+ 	io_req_set_res(req, ret, 0);
+-	if (req->flags & REQ_F_POLLED)
+-		return IOU_STOP_MULTISHOT;
+-	return IOU_OK;
++	return (issue_flags & IO_URING_F_MULTISHOT) ? IOU_STOP_MULTISHOT : IOU_OK;
+ }
+ 
+ int io_socket_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+diff --git a/io_uring/poll.c b/io_uring/poll.c
+index 0d9f49c575e0f..ba0f684669306 100644
+--- a/io_uring/poll.c
++++ b/io_uring/poll.c
+@@ -226,6 +226,13 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+ 			return IOU_POLL_DONE;
+ 		if (v & IO_POLL_CANCEL_FLAG)
+ 			return -ECANCELED;
++		/*
++		 * cqe.res contains only events of the first wake up
++		 * and all others are be lost. Redo vfs_poll() to get
++		 * up to date state.
++		 */
++		if ((v & IO_POLL_REF_MASK) != 1)
++			req->cqe.res = 0;
+ 
+ 		/* the mask was stashed in __io_poll_execute */
+ 		if (!req->cqe.res) {
+@@ -237,6 +244,8 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+ 			continue;
+ 		if (req->apoll_events & EPOLLONESHOT)
+ 			return IOU_POLL_DONE;
++		if (io_is_uring_fops(req->file))
++			return IOU_POLL_DONE;
+ 
+ 		/* multishot, just fill a CQE and proceed */
+ 		if (!(req->flags & REQ_F_APOLL_MULTISHOT)) {
+@@ -256,6 +265,9 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+ 				return ret;
+ 		}
+ 
++		/* force the next iteration to vfs_poll() */
++		req->cqe.res = 0;
++
+ 		/*
+ 		 * Release all references, retry if someone tried to restart
+ 		 * task_work while we were executing it.
+@@ -394,7 +406,8 @@ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
+ 	return 1;
+ }
+ 
+-static void io_poll_double_prepare(struct io_kiocb *req)
++/* fails only when polling is already completing by the first entry */
++static bool io_poll_double_prepare(struct io_kiocb *req)
+ {
+ 	struct wait_queue_head *head;
+ 	struct io_poll *poll = io_poll_get_single(req);
+@@ -403,20 +416,20 @@ static void io_poll_double_prepare(struct io_kiocb *req)
+ 	rcu_read_lock();
+ 	head = smp_load_acquire(&poll->head);
+ 	/*
+-	 * poll arm may not hold ownership and so race with
+-	 * io_poll_wake() by modifying req->flags. There is only one
+-	 * poll entry queued, serialise with it by taking its head lock.
++	 * poll arm might not hold ownership and so race for req->flags with
++	 * io_poll_wake(). There is only one poll entry queued, serialise with
++	 * it by taking its head lock. As we're still arming the tw hanlder
++	 * is not going to be run, so there are no races with it.
+ 	 */
+-	if (head)
++	if (head) {
+ 		spin_lock_irq(&head->lock);
+-
+-	req->flags |= REQ_F_DOUBLE_POLL;
+-	if (req->opcode == IORING_OP_POLL_ADD)
+-		req->flags |= REQ_F_ASYNC_DATA;
+-
+-	if (head)
++		req->flags |= REQ_F_DOUBLE_POLL;
++		if (req->opcode == IORING_OP_POLL_ADD)
++			req->flags |= REQ_F_ASYNC_DATA;
+ 		spin_unlock_irq(&head->lock);
++	}
+ 	rcu_read_unlock();
++	return !!head;
+ }
+ 
+ static void __io_queue_proc(struct io_poll *poll, struct io_poll_table *pt,
+@@ -454,7 +467,11 @@ static void __io_queue_proc(struct io_poll *poll, struct io_poll_table *pt,
+ 		/* mark as double wq entry */
+ 		wqe_private |= IO_WQE_F_DOUBLE;
+ 		io_init_poll_iocb(poll, first->events, first->wait.func);
+-		io_poll_double_prepare(req);
++		if (!io_poll_double_prepare(req)) {
++			/* the request is completing, just back off */
++			kfree(poll);
++			return;
++		}
+ 		*poll_ptr = poll;
+ 	} else {
+ 		/* fine to modify, there is no poll queued to race with us */
+diff --git a/kernel/bpf/percpu_freelist.c b/kernel/bpf/percpu_freelist.c
+index 00b874c8e889f..2ffb741eee8d0 100644
+--- a/kernel/bpf/percpu_freelist.c
++++ b/kernel/bpf/percpu_freelist.c
+@@ -102,22 +102,21 @@ void pcpu_freelist_populate(struct pcpu_freelist *s, void *buf, u32 elem_size,
+ 			    u32 nr_elems)
+ {
+ 	struct pcpu_freelist_head *head;
+-	int i, cpu, pcpu_entries;
++	unsigned int cpu, cpu_idx, i, j, n, m;
+ 
+-	pcpu_entries = nr_elems / num_possible_cpus() + 1;
+-	i = 0;
++	n = nr_elems / num_possible_cpus();
++	m = nr_elems % num_possible_cpus();
+ 
++	cpu_idx = 0;
+ 	for_each_possible_cpu(cpu) {
+-again:
+ 		head = per_cpu_ptr(s->freelist, cpu);
+-		/* No locking required as this is not visible yet. */
+-		pcpu_freelist_push_node(head, buf);
+-		i++;
+-		buf += elem_size;
+-		if (i == nr_elems)
+-			break;
+-		if (i % pcpu_entries)
+-			goto again;
++		j = n + (cpu_idx < m ? 1 : 0);
++		for (i = 0; i < j; i++) {
++			/* No locking required as this is not visible yet. */
++			pcpu_freelist_push_node(head, buf);
++			buf += elem_size;
++		}
++		cpu_idx++;
+ 	}
+ }
+ 
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index 22e7a805c6723..0e758911d963f 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -2094,6 +2094,17 @@ struct bpf_prog_kstats {
+ 	u64 misses;
+ };
+ 
++void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog)
++{
++	struct bpf_prog_stats *stats;
++	unsigned int flags;
++
++	stats = this_cpu_ptr(prog->stats);
++	flags = u64_stats_update_begin_irqsave(&stats->syncp);
++	u64_stats_inc(&stats->misses);
++	u64_stats_update_end_irqrestore(&stats->syncp, flags);
++}
++
+ static void bpf_prog_get_stats(const struct bpf_prog *prog,
+ 			       struct bpf_prog_kstats *stats)
+ {
+diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
+index ad76940b02ccf..41b67eb83ab3f 100644
+--- a/kernel/bpf/trampoline.c
++++ b/kernel/bpf/trampoline.c
+@@ -863,17 +863,6 @@ static __always_inline u64 notrace bpf_prog_start_time(void)
+ 	return start;
+ }
+ 
+-static void notrace inc_misses_counter(struct bpf_prog *prog)
+-{
+-	struct bpf_prog_stats *stats;
+-	unsigned int flags;
+-
+-	stats = this_cpu_ptr(prog->stats);
+-	flags = u64_stats_update_begin_irqsave(&stats->syncp);
+-	u64_stats_inc(&stats->misses);
+-	u64_stats_update_end_irqrestore(&stats->syncp, flags);
+-}
+-
+ /* The logic is similar to bpf_prog_run(), but with an explicit
+  * rcu_read_lock() and migrate_disable() which are required
+  * for the trampoline. The macro is split into
+@@ -896,7 +885,7 @@ u64 notrace __bpf_prog_enter(struct bpf_prog *prog, struct bpf_tramp_run_ctx *ru
+ 	run_ctx->saved_run_ctx = bpf_set_run_ctx(&run_ctx->run_ctx);
+ 
+ 	if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) {
+-		inc_misses_counter(prog);
++		bpf_prog_inc_misses_counter(prog);
+ 		return 0;
+ 	}
+ 	return bpf_prog_start_time();
+@@ -967,7 +956,7 @@ u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, struct bpf_tramp_r
+ 	might_fault();
+ 
+ 	if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) {
+-		inc_misses_counter(prog);
++		bpf_prog_inc_misses_counter(prog);
+ 		return 0;
+ 	}
+ 
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 69fb46fdf7635..b781075dd5109 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -6674,11 +6674,11 @@ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ 	/* Transfer references to the callee */
+ 	err = copy_reference_state(callee, caller);
+ 	if (err)
+-		return err;
++		goto err_out;
+ 
+ 	err = set_callee_state_cb(env, caller, callee, *insn_idx);
+ 	if (err)
+-		return err;
++		goto err_out;
+ 
+ 	clear_caller_saved_regs(env, caller->regs);
+ 
+@@ -6695,6 +6695,11 @@ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ 		print_verifier_state(env, callee, true);
+ 	}
+ 	return 0;
++
++err_out:
++	free_func_state(callee);
++	state->frame[state->curframe + 1] = NULL;
++	return err;
+ }
+ 
+ int map_set_for_each_callback_args(struct bpf_verifier_env *env,
+@@ -6880,8 +6885,7 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
+ 		return -EINVAL;
+ 	}
+ 
+-	state->curframe--;
+-	caller = state->frame[state->curframe];
++	caller = state->frame[state->curframe - 1];
+ 	if (callee->in_callback_fn) {
+ 		/* enforce R0 return value range [0, 1]. */
+ 		struct tnum range = tnum_range(0, 1);
+@@ -6920,7 +6924,7 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
+ 	}
+ 	/* clear everything in the callee */
+ 	free_func_state(callee);
+-	state->frame[state->curframe + 1] = NULL;
++	state->frame[state->curframe--] = NULL;
+ 	return 0;
+ }
+ 
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 072ab26269c0b..bec18d81b1161 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -9282,14 +9282,27 @@ static int __perf_event_overflow(struct perf_event *event,
+ 	}
+ 
+ 	if (event->attr.sigtrap) {
+-		/*
+-		 * Should not be able to return to user space without processing
+-		 * pending_sigtrap (kernel events can overflow multiple times).
+-		 */
+-		WARN_ON_ONCE(event->pending_sigtrap && event->attr.exclude_kernel);
++		unsigned int pending_id = 1;
++
++		if (regs)
++			pending_id = hash32_ptr((void *)instruction_pointer(regs)) ?: 1;
+ 		if (!event->pending_sigtrap) {
+-			event->pending_sigtrap = 1;
++			event->pending_sigtrap = pending_id;
+ 			local_inc(&event->ctx->nr_pending);
++		} else if (event->attr.exclude_kernel) {
++			/*
++			 * Should not be able to return to user space without
++			 * consuming pending_sigtrap; with exceptions:
++			 *
++			 *  1. Where !exclude_kernel, events can overflow again
++			 *     in the kernel without returning to user space.
++			 *
++			 *  2. Events that can overflow again before the IRQ-
++			 *     work without user space progress (e.g. hrtimer).
++			 *     To approximate progress (with false negatives),
++			 *     check 32-bit hash of the current IP.
++			 */
++			WARN_ON_ONCE(event->pending_sigtrap != pending_id);
+ 		}
+ 		event->pending_addr = data->addr;
+ 		irq_work_queue(&event->pending_irq);
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index 917b92ae23821..6d2a8623ec7b5 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -1762,7 +1762,13 @@ static int __unregister_kprobe_top(struct kprobe *p)
+ 				if ((list_p != p) && (list_p->post_handler))
+ 					goto noclean;
+ 			}
+-			ap->post_handler = NULL;
++			/*
++			 * For the kprobe-on-ftrace case, we keep the
++			 * post_handler setting to identify this aggrprobe
++			 * armed with kprobe_ipmodify_ops.
++			 */
++			if (!kprobe_ftrace(ap))
++				ap->post_handler = NULL;
+ 		}
+ noclean:
+ 		/*
+diff --git a/kernel/rseq.c b/kernel/rseq.c
+index bda8175f8f993..d38ab944105d7 100644
+--- a/kernel/rseq.c
++++ b/kernel/rseq.c
+@@ -171,12 +171,27 @@ static int rseq_get_rseq_cs(struct task_struct *t, struct rseq_cs *rseq_cs)
+ 	return 0;
+ }
+ 
++static bool rseq_warn_flags(const char *str, u32 flags)
++{
++	u32 test_flags;
++
++	if (!flags)
++		return false;
++	test_flags = flags & RSEQ_CS_NO_RESTART_FLAGS;
++	if (test_flags)
++		pr_warn_once("Deprecated flags (%u) in %s ABI structure", test_flags, str);
++	test_flags = flags & ~RSEQ_CS_NO_RESTART_FLAGS;
++	if (test_flags)
++		pr_warn_once("Unknown flags (%u) in %s ABI structure", test_flags, str);
++	return true;
++}
++
+ static int rseq_need_restart(struct task_struct *t, u32 cs_flags)
+ {
+ 	u32 flags, event_mask;
+ 	int ret;
+ 
+-	if (WARN_ON_ONCE(cs_flags & RSEQ_CS_NO_RESTART_FLAGS) || cs_flags)
++	if (rseq_warn_flags("rseq_cs", cs_flags))
+ 		return -EINVAL;
+ 
+ 	/* Get thread flags. */
+@@ -184,7 +199,7 @@ static int rseq_need_restart(struct task_struct *t, u32 cs_flags)
+ 	if (ret)
+ 		return ret;
+ 
+-	if (WARN_ON_ONCE(flags & RSEQ_CS_NO_RESTART_FLAGS) || flags)
++	if (rseq_warn_flags("rseq", flags))
+ 		return -EINVAL;
+ 
+ 	/*
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index b1daf7c9b895a..ec4b81007796c 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -2058,9 +2058,15 @@ static __always_inline
+ void __bpf_trace_run(struct bpf_prog *prog, u64 *args)
+ {
+ 	cant_sleep();
++	if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) {
++		bpf_prog_inc_misses_counter(prog);
++		goto out;
++	}
+ 	rcu_read_lock();
+ 	(void) bpf_prog_run(prog, args);
+ 	rcu_read_unlock();
++out:
++	this_cpu_dec(*(prog->active));
+ }
+ 
+ #define UNPACK(...)			__VA_ARGS__
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 8cc9eb60c3c2a..9e6231f4a04f7 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -1289,6 +1289,7 @@ static int ftrace_add_mod(struct trace_array *tr,
+ 	if (!ftrace_mod)
+ 		return -ENOMEM;
+ 
++	INIT_LIST_HEAD(&ftrace_mod->list);
+ 	ftrace_mod->func = kstrdup(func, GFP_KERNEL);
+ 	ftrace_mod->module = kstrdup(module, GFP_KERNEL);
+ 	ftrace_mod->enable = enable;
+@@ -3193,7 +3194,7 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count)
+ 		/* if we can't allocate this size, try something smaller */
+ 		if (!order)
+ 			return -ENOMEM;
+-		order >>= 1;
++		order--;
+ 		goto again;
+ 	}
+ 
+@@ -7394,7 +7395,7 @@ void __init ftrace_init(void)
+ 	}
+ 
+ 	pr_info("ftrace: allocating %ld entries in %ld pages\n",
+-		count, count / ENTRIES_PER_PAGE + 1);
++		count, DIV_ROUND_UP(count, ENTRIES_PER_PAGE));
+ 
+ 	ret = ftrace_process_locs(NULL,
+ 				  __start_mcount_loc,
+diff --git a/kernel/trace/kprobe_event_gen_test.c b/kernel/trace/kprobe_event_gen_test.c
+index d81f7c51025c7..c736487fc0e48 100644
+--- a/kernel/trace/kprobe_event_gen_test.c
++++ b/kernel/trace/kprobe_event_gen_test.c
+@@ -73,6 +73,10 @@ static struct trace_event_file *gen_kretprobe_test;
+ #define KPROBE_GEN_TEST_ARG3	NULL
+ #endif
+ 
++static bool trace_event_file_is_valid(struct trace_event_file *input)
++{
++	return input && !IS_ERR(input);
++}
+ 
+ /*
+  * Test to make sure we can create a kprobe event, then add more
+@@ -139,6 +143,8 @@ static int __init test_gen_kprobe_cmd(void)
+ 	kfree(buf);
+ 	return ret;
+  delete:
++	if (trace_event_file_is_valid(gen_kprobe_test))
++		gen_kprobe_test = NULL;
+ 	/* We got an error after creating the event, delete it */
+ 	ret = kprobe_event_delete("gen_kprobe_test");
+ 	goto out;
+@@ -202,6 +208,8 @@ static int __init test_gen_kretprobe_cmd(void)
+ 	kfree(buf);
+ 	return ret;
+  delete:
++	if (trace_event_file_is_valid(gen_kretprobe_test))
++		gen_kretprobe_test = NULL;
+ 	/* We got an error after creating the event, delete it */
+ 	ret = kprobe_event_delete("gen_kretprobe_test");
+ 	goto out;
+@@ -217,10 +225,12 @@ static int __init kprobe_event_gen_test_init(void)
+ 
+ 	ret = test_gen_kretprobe_cmd();
+ 	if (ret) {
+-		WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
+-						  "kprobes",
+-						  "gen_kretprobe_test", false));
+-		trace_put_event_file(gen_kretprobe_test);
++		if (trace_event_file_is_valid(gen_kretprobe_test)) {
++			WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
++							  "kprobes",
++							  "gen_kretprobe_test", false));
++			trace_put_event_file(gen_kretprobe_test);
++		}
+ 		WARN_ON(kprobe_event_delete("gen_kretprobe_test"));
+ 	}
+ 
+@@ -229,24 +239,30 @@ static int __init kprobe_event_gen_test_init(void)
+ 
+ static void __exit kprobe_event_gen_test_exit(void)
+ {
+-	/* Disable the event or you can't remove it */
+-	WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr,
+-					  "kprobes",
+-					  "gen_kprobe_test", false));
++	if (trace_event_file_is_valid(gen_kprobe_test)) {
++		/* Disable the event or you can't remove it */
++		WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr,
++						  "kprobes",
++						  "gen_kprobe_test", false));
++
++		/* Now give the file and instance back */
++		trace_put_event_file(gen_kprobe_test);
++	}
+ 
+-	/* Now give the file and instance back */
+-	trace_put_event_file(gen_kprobe_test);
+ 
+ 	/* Now unregister and free the event */
+ 	WARN_ON(kprobe_event_delete("gen_kprobe_test"));
+ 
+-	/* Disable the event or you can't remove it */
+-	WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
+-					  "kprobes",
+-					  "gen_kretprobe_test", false));
++	if (trace_event_file_is_valid(gen_kretprobe_test)) {
++		/* Disable the event or you can't remove it */
++		WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
++						  "kprobes",
++						  "gen_kretprobe_test", false));
++
++		/* Now give the file and instance back */
++		trace_put_event_file(gen_kretprobe_test);
++	}
+ 
+-	/* Now give the file and instance back */
+-	trace_put_event_file(gen_kretprobe_test);
+ 
+ 	/* Now unregister and free the event */
+ 	WARN_ON(kprobe_event_delete("gen_kretprobe_test"));
+diff --git a/kernel/trace/rethook.c b/kernel/trace/rethook.c
+index c69d82273ce78..32c3dfdb4d6a7 100644
+--- a/kernel/trace/rethook.c
++++ b/kernel/trace/rethook.c
+@@ -83,8 +83,10 @@ struct rethook *rethook_alloc(void *data, rethook_handler_t handler)
+ {
+ 	struct rethook *rh = kzalloc(sizeof(struct rethook), GFP_KERNEL);
+ 
+-	if (!rh || !handler)
++	if (!rh || !handler) {
++		kfree(rh);
+ 		return NULL;
++	}
+ 
+ 	rh->data = data;
+ 	rh->handler = handler;
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index 9c72571ffb0bf..0b93dc17457de 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -519,6 +519,7 @@ struct ring_buffer_per_cpu {
+ 	local_t				committing;
+ 	local_t				commits;
+ 	local_t				pages_touched;
++	local_t				pages_lost;
+ 	local_t				pages_read;
+ 	long				last_pages_touch;
+ 	size_t				shortest_full;
+@@ -894,10 +895,18 @@ size_t ring_buffer_nr_pages(struct trace_buffer *buffer, int cpu)
+ size_t ring_buffer_nr_dirty_pages(struct trace_buffer *buffer, int cpu)
+ {
+ 	size_t read;
++	size_t lost;
+ 	size_t cnt;
+ 
+ 	read = local_read(&buffer->buffers[cpu]->pages_read);
++	lost = local_read(&buffer->buffers[cpu]->pages_lost);
+ 	cnt = local_read(&buffer->buffers[cpu]->pages_touched);
++
++	if (WARN_ON_ONCE(cnt < lost))
++		return 0;
++
++	cnt -= lost;
++
+ 	/* The reader can read an empty page, but not more than that */
+ 	if (cnt < read) {
+ 		WARN_ON_ONCE(read > cnt + 1);
+@@ -907,6 +916,21 @@ size_t ring_buffer_nr_dirty_pages(struct trace_buffer *buffer, int cpu)
+ 	return cnt - read;
+ }
+ 
++static __always_inline bool full_hit(struct trace_buffer *buffer, int cpu, int full)
++{
++	struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
++	size_t nr_pages;
++	size_t dirty;
++
++	nr_pages = cpu_buffer->nr_pages;
++	if (!nr_pages || !full)
++		return true;
++
++	dirty = ring_buffer_nr_dirty_pages(buffer, cpu);
++
++	return (dirty * 100) > (full * nr_pages);
++}
++
+ /*
+  * rb_wake_up_waiters - wake up tasks waiting for ring buffer input
+  *
+@@ -1046,22 +1070,20 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ 		    !ring_buffer_empty_cpu(buffer, cpu)) {
+ 			unsigned long flags;
+ 			bool pagebusy;
+-			size_t nr_pages;
+-			size_t dirty;
++			bool done;
+ 
+ 			if (!full)
+ 				break;
+ 
+ 			raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
+ 			pagebusy = cpu_buffer->reader_page == cpu_buffer->commit_page;
+-			nr_pages = cpu_buffer->nr_pages;
+-			dirty = ring_buffer_nr_dirty_pages(buffer, cpu);
++			done = !pagebusy && full_hit(buffer, cpu, full);
++
+ 			if (!cpu_buffer->shortest_full ||
+ 			    cpu_buffer->shortest_full > full)
+ 				cpu_buffer->shortest_full = full;
+ 			raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+-			if (!pagebusy &&
+-			    (!nr_pages || (dirty * 100) > full * nr_pages))
++			if (done)
+ 				break;
+ 		}
+ 
+@@ -1087,6 +1109,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+  * @cpu: the cpu buffer to wait on
+  * @filp: the file descriptor
+  * @poll_table: The poll descriptor
++ * @full: wait until the percentage of pages are available, if @cpu != RING_BUFFER_ALL_CPUS
+  *
+  * If @cpu == RING_BUFFER_ALL_CPUS then the task will wake up as soon
+  * as data is added to any of the @buffer's cpu buffers. Otherwise
+@@ -1096,14 +1119,15 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+  * zero otherwise.
+  */
+ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+-			  struct file *filp, poll_table *poll_table)
++			  struct file *filp, poll_table *poll_table, int full)
+ {
+ 	struct ring_buffer_per_cpu *cpu_buffer;
+ 	struct rb_irq_work *work;
+ 
+-	if (cpu == RING_BUFFER_ALL_CPUS)
++	if (cpu == RING_BUFFER_ALL_CPUS) {
+ 		work = &buffer->irq_work;
+-	else {
++		full = 0;
++	} else {
+ 		if (!cpumask_test_cpu(cpu, buffer->cpumask))
+ 			return -EINVAL;
+ 
+@@ -1111,8 +1135,14 @@ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+ 		work = &cpu_buffer->irq_work;
+ 	}
+ 
+-	poll_wait(filp, &work->waiters, poll_table);
+-	work->waiters_pending = true;
++	if (full) {
++		poll_wait(filp, &work->full_waiters, poll_table);
++		work->full_waiters_pending = true;
++	} else {
++		poll_wait(filp, &work->waiters, poll_table);
++		work->waiters_pending = true;
++	}
++
+ 	/*
+ 	 * There's a tight race between setting the waiters_pending and
+ 	 * checking if the ring buffer is empty.  Once the waiters_pending bit
+@@ -1128,6 +1158,9 @@ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+ 	 */
+ 	smp_mb();
+ 
++	if (full)
++		return full_hit(buffer, cpu, full) ? EPOLLIN | EPOLLRDNORM : 0;
++
+ 	if ((cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) ||
+ 	    (cpu != RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu(buffer, cpu)))
+ 		return EPOLLIN | EPOLLRDNORM;
+@@ -1769,9 +1802,9 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
+ 
+ 	free_buffer_page(cpu_buffer->reader_page);
+ 
+-	rb_head_page_deactivate(cpu_buffer);
+-
+ 	if (head) {
++		rb_head_page_deactivate(cpu_buffer);
++
+ 		list_for_each_entry_safe(bpage, tmp, head, list) {
+ 			list_del_init(&bpage->list);
+ 			free_buffer_page(bpage);
+@@ -2007,6 +2040,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages)
+ 			 */
+ 			local_add(page_entries, &cpu_buffer->overrun);
+ 			local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
++			local_inc(&cpu_buffer->pages_lost);
+ 		}
+ 
+ 		/*
+@@ -2491,6 +2525,7 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer,
+ 		 */
+ 		local_add(entries, &cpu_buffer->overrun);
+ 		local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
++		local_inc(&cpu_buffer->pages_lost);
+ 
+ 		/*
+ 		 * The entries will be zeroed out when we move the
+@@ -3155,10 +3190,6 @@ static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer,
+ static __always_inline void
+ rb_wakeups(struct trace_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer)
+ {
+-	size_t nr_pages;
+-	size_t dirty;
+-	size_t full;
+-
+ 	if (buffer->irq_work.waiters_pending) {
+ 		buffer->irq_work.waiters_pending = false;
+ 		/* irq_work_queue() supplies it's own memory barriers */
+@@ -3182,10 +3213,7 @@ rb_wakeups(struct trace_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer)
+ 
+ 	cpu_buffer->last_pages_touch = local_read(&cpu_buffer->pages_touched);
+ 
+-	full = cpu_buffer->shortest_full;
+-	nr_pages = cpu_buffer->nr_pages;
+-	dirty = ring_buffer_nr_dirty_pages(buffer, cpu_buffer->cpu);
+-	if (full && nr_pages && (dirty * 100) <= full * nr_pages)
++	if (!full_hit(buffer, cpu_buffer->cpu, cpu_buffer->shortest_full))
+ 		return;
+ 
+ 	cpu_buffer->irq_work.wakeup_full = true;
+@@ -5248,6 +5276,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
+ 	local_set(&cpu_buffer->committing, 0);
+ 	local_set(&cpu_buffer->commits, 0);
+ 	local_set(&cpu_buffer->pages_touched, 0);
++	local_set(&cpu_buffer->pages_lost, 0);
+ 	local_set(&cpu_buffer->pages_read, 0);
+ 	cpu_buffer->last_pages_touch = 0;
+ 	cpu_buffer->shortest_full = 0;
+diff --git a/kernel/trace/synth_event_gen_test.c b/kernel/trace/synth_event_gen_test.c
+index 0b15e975d2c2c..8d77526892f45 100644
+--- a/kernel/trace/synth_event_gen_test.c
++++ b/kernel/trace/synth_event_gen_test.c
+@@ -120,15 +120,13 @@ static int __init test_gen_synth_cmd(void)
+ 
+ 	/* Now generate a gen_synth_test event */
+ 	ret = synth_event_trace_array(gen_synth_test, vals, ARRAY_SIZE(vals));
+- out:
++ free:
++	kfree(buf);
+ 	return ret;
+  delete:
+ 	/* We got an error after creating the event, delete it */
+ 	synth_event_delete("gen_synth_test");
+- free:
+-	kfree(buf);
+-
+-	goto out;
++	goto free;
+ }
+ 
+ /*
+@@ -227,15 +225,13 @@ static int __init test_empty_synth_event(void)
+ 
+ 	/* Now trace an empty_synth_test event */
+ 	ret = synth_event_trace_array(empty_synth_test, vals, ARRAY_SIZE(vals));
+- out:
++ free:
++	kfree(buf);
+ 	return ret;
+  delete:
+ 	/* We got an error after creating the event, delete it */
+ 	synth_event_delete("empty_synth_test");
+- free:
+-	kfree(buf);
+-
+-	goto out;
++	goto free;
+ }
+ 
+ static struct synth_field_desc create_synth_test_fields[] = {
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index cc65887b31bd9..7132e21e90d6d 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -6657,6 +6657,7 @@ static int tracing_release_pipe(struct inode *inode, struct file *file)
+ 	mutex_unlock(&trace_types_lock);
+ 
+ 	free_cpumask_var(iter->started);
++	kfree(iter->fmt);
+ 	mutex_destroy(&iter->mutex);
+ 	kfree(iter);
+ 
+@@ -6681,7 +6682,7 @@ trace_poll(struct trace_iterator *iter, struct file *filp, poll_table *poll_tabl
+ 		return EPOLLIN | EPOLLRDNORM;
+ 	else
+ 		return ring_buffer_poll_wait(iter->array_buffer->buffer, iter->cpu_file,
+-					     filp, poll_table);
++					     filp, poll_table, iter->tr->buffer_percent);
+ }
+ 
+ static __poll_t
+@@ -7802,6 +7803,7 @@ static struct tracing_log_err *get_tracing_log_err(struct trace_array *tr,
+ 						   int len)
+ {
+ 	struct tracing_log_err *err;
++	char *cmd;
+ 
+ 	if (tr->n_err_log_entries < TRACING_LOG_ERRS_MAX) {
+ 		err = alloc_tracing_log_err(len);
+@@ -7810,12 +7812,12 @@ static struct tracing_log_err *get_tracing_log_err(struct trace_array *tr,
+ 
+ 		return err;
+ 	}
+-
++	cmd = kzalloc(len, GFP_KERNEL);
++	if (!cmd)
++		return ERR_PTR(-ENOMEM);
+ 	err = list_first_entry(&tr->err_log, struct tracing_log_err, list);
+ 	kfree(err->cmd);
+-	err->cmd = kzalloc(len, GFP_KERNEL);
+-	if (!err->cmd)
+-		return ERR_PTR(-ENOMEM);
++	err->cmd = cmd;
+ 	list_del(&err->list);
+ 
+ 	return err;
+diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
+index 860f5fb9514d7..3b055aaee89a9 100644
+--- a/kernel/trace/trace_eprobe.c
++++ b/kernel/trace/trace_eprobe.c
+@@ -560,6 +560,9 @@ static void eprobe_trigger_func(struct event_trigger_data *data,
+ {
+ 	struct eprobe_data *edata = data->private_data;
+ 
++	if (unlikely(!rec))
++		return;
++
+ 	__eprobe_trace_func(edata, rec);
+ }
+ 
+diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
+index e310052dc83ce..29fbfb27c2b2c 100644
+--- a/kernel/trace/trace_events_synth.c
++++ b/kernel/trace/trace_events_synth.c
+@@ -828,10 +828,9 @@ static int register_synth_event(struct synth_event *event)
+ 	}
+ 
+ 	ret = set_synth_event_print_fmt(call);
+-	if (ret < 0) {
++	/* unregister_trace_event() will be called inside */
++	if (ret < 0)
+ 		trace_remove_event_call(call);
+-		goto err;
+-	}
+  out:
+ 	return ret;
+  err:
+diff --git a/mm/filemap.c b/mm/filemap.c
+index 15800334147b3..ada25b9f45ad1 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -3712,7 +3712,7 @@ ssize_t generic_perform_write(struct kiocb *iocb, struct iov_iter *i)
+ 		unsigned long offset;	/* Offset into pagecache page */
+ 		unsigned long bytes;	/* Bytes to write to page */
+ 		size_t copied;		/* Bytes copied from user */
+-		void *fsdata;
++		void *fsdata = NULL;
+ 
+ 		offset = (pos & (PAGE_SIZE - 1));
+ 		bytes = min_t(unsigned long, PAGE_SIZE - offset,
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index ecc197d24efb7..dbb558e71e9e1 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -5445,7 +5445,7 @@ static bool hugetlbfs_pagecache_present(struct hstate *h,
+ 	return page != NULL;
+ }
+ 
+-int huge_add_to_page_cache(struct page *page, struct address_space *mapping,
++int hugetlb_add_to_page_cache(struct page *page, struct address_space *mapping,
+ 			   pgoff_t idx)
+ {
+ 	struct folio *folio = page_folio(page);
+@@ -5583,7 +5583,7 @@ retry:
+ 		new_page = true;
+ 
+ 		if (vma->vm_flags & VM_MAYSHARE) {
+-			int err = huge_add_to_page_cache(page, mapping, idx);
++			int err = hugetlb_add_to_page_cache(page, mapping, idx);
+ 			if (err) {
+ 				put_page(page);
+ 				if (err == -EEXIST)
+@@ -6008,11 +6008,11 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
+ 
+ 		/*
+ 		 * Serialization between remove_inode_hugepages() and
+-		 * huge_add_to_page_cache() below happens through the
++		 * hugetlb_add_to_page_cache() below happens through the
+ 		 * hugetlb_fault_mutex_table that here must be hold by
+ 		 * the caller.
+ 		 */
+-		ret = huge_add_to_page_cache(page, mapping, idx);
++		ret = hugetlb_add_to_page_cache(page, mapping, idx);
+ 		if (ret)
+ 			goto out_release_nounlock;
+ 		page_in_pagecache = true;
+@@ -6021,6 +6021,10 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
+ 	ptl = huge_pte_lockptr(h, dst_mm, dst_pte);
+ 	spin_lock(ptl);
+ 
++	ret = -EIO;
++	if (PageHWPoison(page))
++		goto out_release_unlock;
++
+ 	/*
+ 	 * Recheck the i_size after holding PT lock to make sure not
+ 	 * to leave any page mapped (as page_mapped()) beyond the end
+diff --git a/mm/maccess.c b/mm/maccess.c
+index 5f4d240f67ecc..074f6b086671e 100644
+--- a/mm/maccess.c
++++ b/mm/maccess.c
+@@ -97,7 +97,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
+ 	return src - unsafe_addr;
+ Efault:
+ 	pagefault_enable();
+-	dst[-1] = '\0';
++	dst[0] = '\0';
+ 	return -EFAULT;
+ }
+ 
+diff --git a/mm/memory-failure.c b/mm/memory-failure.c
+index e7ac570dda75d..4d302f6b02fc7 100644
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -1079,6 +1079,7 @@ static int me_huge_page(struct page_state *ps, struct page *p)
+ 	int res;
+ 	struct page *hpage = compound_head(p);
+ 	struct address_space *mapping;
++	bool extra_pins = false;
+ 
+ 	if (!PageHuge(hpage))
+ 		return MF_DELAYED;
+@@ -1086,6 +1087,8 @@ static int me_huge_page(struct page_state *ps, struct page *p)
+ 	mapping = page_mapping(hpage);
+ 	if (mapping) {
+ 		res = truncate_error_page(hpage, page_to_pfn(p), mapping);
++		/* The page is kept in page cache. */
++		extra_pins = true;
+ 		unlock_page(hpage);
+ 	} else {
+ 		unlock_page(hpage);
+@@ -1103,7 +1106,7 @@ static int me_huge_page(struct page_state *ps, struct page *p)
+ 		}
+ 	}
+ 
+-	if (has_extra_refcount(ps, p, false))
++	if (has_extra_refcount(ps, p, extra_pins))
+ 		res = MF_FAILED;
+ 
+ 	return res;
+diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
+index e758978b44bee..0191f22d1ec35 100644
+--- a/net/9p/trans_fd.c
++++ b/net/9p/trans_fd.c
+@@ -91,6 +91,7 @@ struct p9_poll_wait {
+  * @mux_list: list link for mux to manage multiple connections (?)
+  * @client: reference to client instance for this connection
+  * @err: error state
++ * @req_lock: lock protecting req_list and requests statuses
+  * @req_list: accounting for requests which have been sent
+  * @unsent_req_list: accounting for requests that haven't been sent
+  * @rreq: read request
+@@ -114,6 +115,7 @@ struct p9_conn {
+ 	struct list_head mux_list;
+ 	struct p9_client *client;
+ 	int err;
++	spinlock_t req_lock;
+ 	struct list_head req_list;
+ 	struct list_head unsent_req_list;
+ 	struct p9_req_t *rreq;
+@@ -189,10 +191,10 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
+ 
+ 	p9_debug(P9_DEBUG_ERROR, "mux %p err %d\n", m, err);
+ 
+-	spin_lock(&m->client->lock);
++	spin_lock(&m->req_lock);
+ 
+ 	if (m->err) {
+-		spin_unlock(&m->client->lock);
++		spin_unlock(&m->req_lock);
+ 		return;
+ 	}
+ 
+@@ -205,6 +207,8 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
+ 		list_move(&req->req_list, &cancel_list);
+ 	}
+ 
++	spin_unlock(&m->req_lock);
++
+ 	list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
+ 		p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req);
+ 		list_del(&req->req_list);
+@@ -212,7 +216,6 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
+ 			req->t_err = err;
+ 		p9_client_cb(m->client, req, REQ_STATUS_ERROR);
+ 	}
+-	spin_unlock(&m->client->lock);
+ }
+ 
+ static __poll_t
+@@ -359,7 +362,7 @@ static void p9_read_work(struct work_struct *work)
+ 	if ((m->rreq) && (m->rc.offset == m->rc.capacity)) {
+ 		p9_debug(P9_DEBUG_TRANS, "got new packet\n");
+ 		m->rreq->rc.size = m->rc.offset;
+-		spin_lock(&m->client->lock);
++		spin_lock(&m->req_lock);
+ 		if (m->rreq->status == REQ_STATUS_SENT) {
+ 			list_del(&m->rreq->req_list);
+ 			p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD);
+@@ -368,14 +371,14 @@ static void p9_read_work(struct work_struct *work)
+ 			p9_debug(P9_DEBUG_TRANS,
+ 				 "Ignore replies associated with a cancelled request\n");
+ 		} else {
+-			spin_unlock(&m->client->lock);
++			spin_unlock(&m->req_lock);
+ 			p9_debug(P9_DEBUG_ERROR,
+ 				 "Request tag %d errored out while we were reading the reply\n",
+ 				 m->rc.tag);
+ 			err = -EIO;
+ 			goto error;
+ 		}
+-		spin_unlock(&m->client->lock);
++		spin_unlock(&m->req_lock);
+ 		m->rc.sdata = NULL;
+ 		m->rc.offset = 0;
+ 		m->rc.capacity = 0;
+@@ -453,10 +456,10 @@ static void p9_write_work(struct work_struct *work)
+ 	}
+ 
+ 	if (!m->wsize) {
+-		spin_lock(&m->client->lock);
++		spin_lock(&m->req_lock);
+ 		if (list_empty(&m->unsent_req_list)) {
+ 			clear_bit(Wworksched, &m->wsched);
+-			spin_unlock(&m->client->lock);
++			spin_unlock(&m->req_lock);
+ 			return;
+ 		}
+ 
+@@ -471,7 +474,7 @@ static void p9_write_work(struct work_struct *work)
+ 		m->wpos = 0;
+ 		p9_req_get(req);
+ 		m->wreq = req;
+-		spin_unlock(&m->client->lock);
++		spin_unlock(&m->req_lock);
+ 	}
+ 
+ 	p9_debug(P9_DEBUG_TRANS, "mux %p pos %d size %d\n",
+@@ -588,6 +591,7 @@ static void p9_conn_create(struct p9_client *client)
+ 	INIT_LIST_HEAD(&m->mux_list);
+ 	m->client = client;
+ 
++	spin_lock_init(&m->req_lock);
+ 	INIT_LIST_HEAD(&m->req_list);
+ 	INIT_LIST_HEAD(&m->unsent_req_list);
+ 	INIT_WORK(&m->rq, p9_read_work);
+@@ -669,10 +673,10 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
+ 	if (m->err < 0)
+ 		return m->err;
+ 
+-	spin_lock(&client->lock);
++	spin_lock(&m->req_lock);
+ 	req->status = REQ_STATUS_UNSENT;
+ 	list_add_tail(&req->req_list, &m->unsent_req_list);
+-	spin_unlock(&client->lock);
++	spin_unlock(&m->req_lock);
+ 
+ 	if (test_and_clear_bit(Wpending, &m->wsched))
+ 		n = EPOLLOUT;
+@@ -687,11 +691,13 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
+ 
+ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
+ {
++	struct p9_trans_fd *ts = client->trans;
++	struct p9_conn *m = &ts->conn;
+ 	int ret = 1;
+ 
+ 	p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
+ 
+-	spin_lock(&client->lock);
++	spin_lock(&m->req_lock);
+ 
+ 	if (req->status == REQ_STATUS_UNSENT) {
+ 		list_del(&req->req_list);
+@@ -699,21 +705,24 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
+ 		p9_req_put(client, req);
+ 		ret = 0;
+ 	}
+-	spin_unlock(&client->lock);
++	spin_unlock(&m->req_lock);
+ 
+ 	return ret;
+ }
+ 
+ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
+ {
++	struct p9_trans_fd *ts = client->trans;
++	struct p9_conn *m = &ts->conn;
++
+ 	p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
+ 
+-	spin_lock(&client->lock);
++	spin_lock(&m->req_lock);
+ 	/* Ignore cancelled request if message has been received
+ 	 * before lock.
+ 	 */
+ 	if (req->status == REQ_STATUS_RCVD) {
+-		spin_unlock(&client->lock);
++		spin_unlock(&m->req_lock);
+ 		return 0;
+ 	}
+ 
+@@ -722,7 +731,8 @@ static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
+ 	 */
+ 	list_del(&req->req_list);
+ 	req->status = REQ_STATUS_FLSHD;
+-	spin_unlock(&client->lock);
++	spin_unlock(&m->req_lock);
++
+ 	p9_req_put(client, req);
+ 
+ 	return 0;
+@@ -821,11 +831,14 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
+ 		goto out_free_ts;
+ 	if (!(ts->rd->f_mode & FMODE_READ))
+ 		goto out_put_rd;
++	/* prevent workers from hanging on IO when fd is a pipe */
++	ts->rd->f_flags |= O_NONBLOCK;
+ 	ts->wr = fget(wfd);
+ 	if (!ts->wr)
+ 		goto out_put_rd;
+ 	if (!(ts->wr->f_mode & FMODE_WRITE))
+ 		goto out_put_wr;
++	ts->wr->f_flags |= O_NONBLOCK;
+ 
+ 	client->trans = ts;
+ 	client->status = Connected;
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 4df3d0ed6c80d..9c24947aa41ef 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -1990,7 +1990,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
+ 		if (link_type == LE_LINK && c->src_type == BDADDR_BREDR)
+ 			continue;
+ 
+-		if (c->psm == psm) {
++		if (c->chan_type != L2CAP_CHAN_FIXED && c->psm == psm) {
+ 			int src_match, dst_match;
+ 			int src_any, dst_any;
+ 
+diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
+index d11209367dd00..b422238f9f86c 100644
+--- a/net/bpf/test_run.c
++++ b/net/bpf/test_run.c
+@@ -733,6 +733,7 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size,
+ 	if (user_size > size)
+ 		return ERR_PTR(-EMSGSIZE);
+ 
++	size = SKB_DATA_ALIGN(size);
+ 	data = kzalloc(size + headroom + tailroom, GFP_USER);
+ 	if (!data)
+ 		return ERR_PTR(-ENOMEM);
+diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
+index 6e53dc9914094..9ffd40b8270c1 100644
+--- a/net/bridge/br_vlan.c
++++ b/net/bridge/br_vlan.c
+@@ -959,6 +959,8 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto,
+ 	list_for_each_entry(p, &br->port_list, list) {
+ 		vg = nbp_vlan_group(p);
+ 		list_for_each_entry(vlan, &vg->vlan_list, vlist) {
++			if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
++				continue;
+ 			err = vlan_vid_add(p->dev, proto, vlan->vid);
+ 			if (err)
+ 				goto err_filt;
+@@ -973,8 +975,11 @@ int __br_vlan_set_proto(struct net_bridge *br, __be16 proto,
+ 	/* Delete VLANs for the old proto from the device filter. */
+ 	list_for_each_entry(p, &br->port_list, list) {
+ 		vg = nbp_vlan_group(p);
+-		list_for_each_entry(vlan, &vg->vlan_list, vlist)
++		list_for_each_entry(vlan, &vg->vlan_list, vlist) {
++			if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
++				continue;
+ 			vlan_vid_del(p->dev, oldproto, vlan->vid);
++		}
+ 	}
+ 
+ 	return 0;
+@@ -983,13 +988,19 @@ err_filt:
+ 	attr.u.vlan_protocol = ntohs(oldproto);
+ 	switchdev_port_attr_set(br->dev, &attr, NULL);
+ 
+-	list_for_each_entry_continue_reverse(vlan, &vg->vlan_list, vlist)
++	list_for_each_entry_continue_reverse(vlan, &vg->vlan_list, vlist) {
++		if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
++			continue;
+ 		vlan_vid_del(p->dev, proto, vlan->vid);
++	}
+ 
+ 	list_for_each_entry_continue_reverse(p, &br->port_list, list) {
+ 		vg = nbp_vlan_group(p);
+-		list_for_each_entry(vlan, &vg->vlan_list, vlist)
++		list_for_each_entry(vlan, &vg->vlan_list, vlist) {
++			if (vlan->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
++				continue;
+ 			vlan_vid_del(p->dev, proto, vlan->vid);
++		}
+ 	}
+ 
+ 	return err;
+diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
+index 4d63ef13a1fd7..f35fc87c453a2 100644
+--- a/net/caif/chnl_net.c
++++ b/net/caif/chnl_net.c
+@@ -310,9 +310,6 @@ static int chnl_net_open(struct net_device *dev)
+ 
+ 	if (result == 0) {
+ 		pr_debug("connect timeout\n");
+-		caif_disconnect_client(dev_net(dev), &priv->chnl);
+-		priv->state = CAIF_DISCONNECTED;
+-		pr_debug("state disconnected\n");
+ 		result = -ETIMEDOUT;
+ 		goto error;
+ 	}
+diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
+index e537655e442b8..befa954b0a472 100644
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -850,6 +850,14 @@ disconnect:
+ 	return err;
+ }
+ 
++static void dsa_switch_teardown_tag_protocol(struct dsa_switch *ds)
++{
++	const struct dsa_device_ops *tag_ops = ds->dst->tag_ops;
++
++	if (tag_ops->disconnect)
++		tag_ops->disconnect(ds);
++}
++
+ static int dsa_switch_setup(struct dsa_switch *ds)
+ {
+ 	struct dsa_devlink_priv *dl_priv;
+@@ -953,6 +961,8 @@ static void dsa_switch_teardown(struct dsa_switch *ds)
+ 		ds->slave_mii_bus = NULL;
+ 	}
+ 
++	dsa_switch_teardown_tag_protocol(ds);
++
+ 	if (ds->ops->teardown)
+ 		ds->ops->teardown(ds);
+ 
+diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
+index d9722e49864b0..acea875c05e5c 100644
+--- a/net/dsa/dsa_priv.h
++++ b/net/dsa/dsa_priv.h
+@@ -201,6 +201,7 @@ static inline struct net_device *dsa_master_find_slave(struct net_device *dev,
+ }
+ 
+ /* port.c */
++bool dsa_port_supports_hwtstamp(struct dsa_port *dp, struct ifreq *ifr);
+ void dsa_port_set_tag_protocol(struct dsa_port *cpu_dp,
+ 			       const struct dsa_device_ops *tag_ops);
+ int dsa_port_set_state(struct dsa_port *dp, u8 state, bool do_fast_age);
+diff --git a/net/dsa/master.c b/net/dsa/master.c
+index 2851e44c4cf0d..46b1f0455a7bd 100644
+--- a/net/dsa/master.c
++++ b/net/dsa/master.c
+@@ -204,8 +204,7 @@ static int dsa_master_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ 		 * switch in the tree that is PTP capable.
+ 		 */
+ 		list_for_each_entry(dp, &dst->ports, list)
+-			if (dp->ds->ops->port_hwtstamp_get ||
+-			    dp->ds->ops->port_hwtstamp_set)
++			if (dsa_port_supports_hwtstamp(dp, ifr))
+ 				return -EBUSY;
+ 		break;
+ 	}
+diff --git a/net/dsa/port.c b/net/dsa/port.c
+index a8895ee3cd600..9ac87063cca8a 100644
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -109,6 +109,22 @@ static bool dsa_port_can_configure_learning(struct dsa_port *dp)
+ 	return !err;
+ }
+ 
++bool dsa_port_supports_hwtstamp(struct dsa_port *dp, struct ifreq *ifr)
++{
++	struct dsa_switch *ds = dp->ds;
++	int err;
++
++	if (!ds->ops->port_hwtstamp_get || !ds->ops->port_hwtstamp_set)
++		return false;
++
++	/* "See through" shim implementations of the "get" method.
++	 * This will clobber the ifreq structure, but we will either return an
++	 * error, or the master will overwrite it with proper values.
++	 */
++	err = ds->ops->port_hwtstamp_get(ds, dp->index, ifr);
++	return err != -EOPNOTSUPP;
++}
++
+ int dsa_port_set_state(struct dsa_port *dp, u8 state, bool do_fast_age)
+ {
+ 	struct dsa_switch *ds = dp->ds;
+diff --git a/net/ipv4/tcp_cdg.c b/net/ipv4/tcp_cdg.c
+index ddc7ba0554bdd..112f28f936934 100644
+--- a/net/ipv4/tcp_cdg.c
++++ b/net/ipv4/tcp_cdg.c
+@@ -375,6 +375,7 @@ static void tcp_cdg_init(struct sock *sk)
+ 	struct cdg *ca = inet_csk_ca(sk);
+ 	struct tcp_sock *tp = tcp_sk(sk);
+ 
++	ca->gradients = NULL;
+ 	/* We silently fall back to window = 1 if allocation fails. */
+ 	if (window > 1)
+ 		ca->gradients = kcalloc(window, sizeof(ca->gradients[0]),
+@@ -388,6 +389,7 @@ static void tcp_cdg_release(struct sock *sk)
+ 	struct cdg *ca = inet_csk_ca(sk);
+ 
+ 	kfree(ca->gradients);
++	ca->gradients = NULL;
+ }
+ 
+ static struct tcp_congestion_ops tcp_cdg __read_mostly = {
+diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
+index befc62606cdf0..890a2423f559e 100644
+--- a/net/kcm/kcmsock.c
++++ b/net/kcm/kcmsock.c
+@@ -222,7 +222,7 @@ static void requeue_rx_msgs(struct kcm_mux *mux, struct sk_buff_head *head)
+ 	struct sk_buff *skb;
+ 	struct kcm_sock *kcm;
+ 
+-	while ((skb = __skb_dequeue(head))) {
++	while ((skb = skb_dequeue(head))) {
+ 		/* Reset destructor to avoid calling kcm_rcv_ready */
+ 		skb->destructor = sock_rfree;
+ 		skb_orphan(skb);
+@@ -1085,53 +1085,17 @@ out_error:
+ 	return err;
+ }
+ 
+-static struct sk_buff *kcm_wait_data(struct sock *sk, int flags,
+-				     long timeo, int *err)
+-{
+-	struct sk_buff *skb;
+-
+-	while (!(skb = skb_peek(&sk->sk_receive_queue))) {
+-		if (sk->sk_err) {
+-			*err = sock_error(sk);
+-			return NULL;
+-		}
+-
+-		if (sock_flag(sk, SOCK_DONE))
+-			return NULL;
+-
+-		if ((flags & MSG_DONTWAIT) || !timeo) {
+-			*err = -EAGAIN;
+-			return NULL;
+-		}
+-
+-		sk_wait_data(sk, &timeo, NULL);
+-
+-		/* Handle signals */
+-		if (signal_pending(current)) {
+-			*err = sock_intr_errno(timeo);
+-			return NULL;
+-		}
+-	}
+-
+-	return skb;
+-}
+-
+ static int kcm_recvmsg(struct socket *sock, struct msghdr *msg,
+ 		       size_t len, int flags)
+ {
+ 	struct sock *sk = sock->sk;
+ 	struct kcm_sock *kcm = kcm_sk(sk);
+ 	int err = 0;
+-	long timeo;
+ 	struct strp_msg *stm;
+ 	int copied = 0;
+ 	struct sk_buff *skb;
+ 
+-	timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+-
+-	lock_sock(sk);
+-
+-	skb = kcm_wait_data(sk, flags, timeo, &err);
++	skb = skb_recv_datagram(sk, flags, &err);
+ 	if (!skb)
+ 		goto out;
+ 
+@@ -1162,14 +1126,11 @@ msg_finished:
+ 			/* Finished with message */
+ 			msg->msg_flags |= MSG_EOR;
+ 			KCM_STATS_INCR(kcm->stats.rx_msgs);
+-			skb_unlink(skb, &sk->sk_receive_queue);
+-			kfree_skb(skb);
+ 		}
+ 	}
+ 
+ out:
+-	release_sock(sk);
+-
++	skb_free_datagram(sk, skb);
+ 	return copied ? : err;
+ }
+ 
+@@ -1179,7 +1140,6 @@ static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos,
+ {
+ 	struct sock *sk = sock->sk;
+ 	struct kcm_sock *kcm = kcm_sk(sk);
+-	long timeo;
+ 	struct strp_msg *stm;
+ 	int err = 0;
+ 	ssize_t copied;
+@@ -1187,11 +1147,7 @@ static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos,
+ 
+ 	/* Only support splice for SOCKSEQPACKET */
+ 
+-	timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+-
+-	lock_sock(sk);
+-
+-	skb = kcm_wait_data(sk, flags, timeo, &err);
++	skb = skb_recv_datagram(sk, flags, &err);
+ 	if (!skb)
+ 		goto err_out;
+ 
+@@ -1219,13 +1175,11 @@ static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos,
+ 	 * finish reading the message.
+ 	 */
+ 
+-	release_sock(sk);
+-
++	skb_free_datagram(sk, skb);
+ 	return copied;
+ 
+ err_out:
+-	release_sock(sk);
+-
++	skb_free_datagram(sk, skb);
+ 	return err;
+ }
+ 
+@@ -1845,10 +1799,10 @@ static int kcm_release(struct socket *sock)
+ 	kcm = kcm_sk(sk);
+ 	mux = kcm->mux;
+ 
++	lock_sock(sk);
+ 	sock_orphan(sk);
+ 	kfree_skb(kcm->seq_skb);
+ 
+-	lock_sock(sk);
+ 	/* Purge queue under lock to avoid race condition with tx_work trying
+ 	 * to act when queue is nonempty. If tx_work runs after this point
+ 	 * it will just return.
+diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
+index 16ae92054baa8..6b31746f9be3b 100644
+--- a/net/netfilter/ipset/ip_set_core.c
++++ b/net/netfilter/ipset/ip_set_core.c
+@@ -1719,11 +1719,13 @@ call_ad(struct net *net, struct sock *ctnl, struct sk_buff *skb,
+ 		skb2 = nlmsg_new(payload, GFP_KERNEL);
+ 		if (!skb2)
+ 			return -ENOMEM;
+-		rep = __nlmsg_put(skb2, NETLINK_CB(skb).portid,
+-				  nlh->nlmsg_seq, NLMSG_ERROR, payload, 0);
++		rep = nlmsg_put(skb2, NETLINK_CB(skb).portid,
++				nlh->nlmsg_seq, NLMSG_ERROR, payload, 0);
+ 		errmsg = nlmsg_data(rep);
+ 		errmsg->error = ret;
+-		memcpy(&errmsg->msg, nlh, nlh->nlmsg_len);
++		unsafe_memcpy(&errmsg->msg, nlh, nlh->nlmsg_len,
++			      /* Bounds checked by the skb layer. */);
++
+ 		cmdattr = (void *)&errmsg->msg + min_len;
+ 
+ 		ret = nla_parse(cda, IPSET_ATTR_CMD_MAX, cmdattr,
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 0cd91f813a3bd..d8d3ed2096a31 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -2440,11 +2440,13 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err,
+ 		return;
+ 	}
+ 
+-	rep = __nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
+-			  NLMSG_ERROR, payload, flags);
++	rep = nlmsg_put(skb, NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
++			NLMSG_ERROR, payload, flags);
+ 	errmsg = nlmsg_data(rep);
+ 	errmsg->error = err;
+-	memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh));
++	unsafe_memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg)
++					 ? nlh->nlmsg_len : sizeof(*nlh),
++		      /* Bounds checked by the skb layer. */);
+ 
+ 	if (nlk_has_extack && extack) {
+ 		if (extack->_msg) {
+diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
+index e213aaf45d67c..20831079fb09e 100644
+--- a/net/sctp/outqueue.c
++++ b/net/sctp/outqueue.c
+@@ -384,6 +384,7 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
+ {
+ 	struct sctp_outq *q = &asoc->outqueue;
+ 	struct sctp_chunk *chk, *temp;
++	struct sctp_stream_out *sout;
+ 
+ 	q->sched->unsched_all(&asoc->stream);
+ 
+@@ -398,12 +399,14 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
+ 		sctp_sched_dequeue_common(q, chk);
+ 		asoc->sent_cnt_removable--;
+ 		asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
+-		if (chk->sinfo.sinfo_stream < asoc->stream.outcnt) {
+-			struct sctp_stream_out *streamout =
+-				SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);
+ 
+-			streamout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
+-		}
++		sout = SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream);
++		sout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
++
++		/* clear out_curr if all frag chunks are pruned */
++		if (asoc->stream.out_curr == sout &&
++		    list_is_last(&chk->frag_list, &chk->msg->chunks))
++			asoc->stream.out_curr = NULL;
+ 
+ 		msg_len -= chk->skb->truesize + sizeof(struct sctp_chunk);
+ 		sctp_chunk_free(chk);
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index a31a27816cc0f..7bb247c51e2f6 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -1989,7 +1989,7 @@ gss_unwrap_resp_integ(struct rpc_task *task, struct rpc_cred *cred,
+ 		goto unwrap_failed;
+ 	mic.len = len;
+ 	mic.data = kmalloc(len, GFP_KERNEL);
+-	if (!mic.data)
++	if (ZERO_OR_NULL_PTR(mic.data))
+ 		goto unwrap_failed;
+ 	if (read_bytes_from_xdr_buf(rcv_buf, offset, mic.data, mic.len))
+ 		goto unwrap_failed;
+diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
+index 76a80a41615be..fe8765c4075d3 100644
+--- a/net/wireless/wext-core.c
++++ b/net/wireless/wext-core.c
+@@ -468,6 +468,7 @@ void wireless_send_event(struct net_device *	dev,
+ 	struct __compat_iw_event *compat_event;
+ 	struct compat_iw_point compat_wrqu;
+ 	struct sk_buff *compskb;
++	int ptr_len;
+ #endif
+ 
+ 	/*
+@@ -582,6 +583,9 @@ void wireless_send_event(struct net_device *	dev,
+ 	nlmsg_end(skb, nlh);
+ #ifdef CONFIG_COMPAT
+ 	hdr_len = compat_event_type_size[descr->header_type];
++
++	/* ptr_len is remaining size in event header apart from LCP */
++	ptr_len = hdr_len - IW_EV_COMPAT_LCP_LEN;
+ 	event_len = hdr_len + extra_len;
+ 
+ 	compskb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+@@ -612,16 +616,15 @@ void wireless_send_event(struct net_device *	dev,
+ 	if (descr->header_type == IW_HEADER_TYPE_POINT) {
+ 		compat_wrqu.length = wrqu->data.length;
+ 		compat_wrqu.flags = wrqu->data.flags;
+-		memcpy(&compat_event->pointer,
+-			((char *) &compat_wrqu) + IW_EV_COMPAT_POINT_OFF,
+-			hdr_len - IW_EV_COMPAT_LCP_LEN);
++		memcpy(compat_event->ptr_bytes,
++		       ((char *)&compat_wrqu) + IW_EV_COMPAT_POINT_OFF,
++			ptr_len);
+ 		if (extra_len)
+-			memcpy(((char *) compat_event) + hdr_len,
+-				extra, extra_len);
++			memcpy(&compat_event->ptr_bytes[ptr_len],
++			       extra, extra_len);
+ 	} else {
+ 		/* extra_len must be zero, so no if (extra) needed */
+-		memcpy(&compat_event->pointer, wrqu,
+-			hdr_len - IW_EV_COMPAT_LCP_LEN);
++		memcpy(compat_event->ptr_bytes, wrqu, ptr_len);
+ 	}
+ 
+ 	nlmsg_end(compskb, nlh);
+diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c
+index 5259ef8f5242f..748d8630ab58b 100644
+--- a/net/x25/x25_dev.c
++++ b/net/x25/x25_dev.c
+@@ -117,7 +117,7 @@ int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev,
+ 
+ 	if (!pskb_may_pull(skb, 1)) {
+ 		x25_neigh_put(nb);
+-		return 0;
++		goto drop;
+ 	}
+ 
+ 	switch (skb->data[0]) {
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index b7cccbef401ce..bf58e98c7a699 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9446,6 +9446,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_AMP),
+ 	SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_AMP),
+ 	SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_AMP),
++	SND_PCI_QUIRK(0x144d, 0xc1a3, "Samsung Galaxy Book Pro (NP935XDB-KC1SE)", ALC298_FIXUP_SAMSUNG_AMP),
++	SND_PCI_QUIRK(0x144d, 0xc1a6, "Samsung Galaxy Book Pro 360 (NP930QBD)", ALC298_FIXUP_SAMSUNG_AMP),
+ 	SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
+ 	SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_AMP),
+ 	SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_AMP),
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index 2cb50d5cf1a9a..6c0f1de10429a 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -45,6 +45,27 @@ static struct snd_soc_card acp6x_card = {
+ };
+ 
+ static const struct dmi_system_id yc_acp_quirk_table[] = {
++	{
++		.driver_data = &acp6x_card,
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
++		}
++	},
++	{
++		.driver_data = &acp6x_card,
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
++		}
++	},
++	{
++		.driver_data = &acp6x_card,
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "21D1"),
++		}
++	},
+ 	{
+ 		.driver_data = &acp6x_card,
+ 		.matches = {
+diff --git a/sound/soc/codecs/jz4725b.c b/sound/soc/codecs/jz4725b.c
+index 5201a8f6d7b63..71ea576f7e67a 100644
+--- a/sound/soc/codecs/jz4725b.c
++++ b/sound/soc/codecs/jz4725b.c
+@@ -136,14 +136,17 @@ enum {
+ #define REG_CGR3_GO1L_OFFSET		0
+ #define REG_CGR3_GO1L_MASK		(0x1f << REG_CGR3_GO1L_OFFSET)
+ 
++#define REG_CGR10_GIL_OFFSET		0
++#define REG_CGR10_GIR_OFFSET		4
++
+ struct jz_icdc {
+ 	struct regmap *regmap;
+ 	void __iomem *base;
+ 	struct clk *clk;
+ };
+ 
+-static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_dac_tlv, -2250, 0);
+-static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_line_tlv, -1500, 600);
++static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_adc_tlv,     0, 150, 0);
++static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_dac_tlv, -2250, 150, 0);
+ 
+ static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
+ 	SOC_DOUBLE_TLV("Master Playback Volume",
+@@ -151,11 +154,11 @@ static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
+ 		       REG_CGR1_GODL_OFFSET,
+ 		       REG_CGR1_GODR_OFFSET,
+ 		       0xf, 1, jz4725b_dac_tlv),
+-	SOC_DOUBLE_R_TLV("Master Capture Volume",
+-			 JZ4725B_CODEC_REG_CGR3,
+-			 JZ4725B_CODEC_REG_CGR2,
+-			 REG_CGR2_GO1R_OFFSET,
+-			 0x1f, 1, jz4725b_line_tlv),
++	SOC_DOUBLE_TLV("Master Capture Volume",
++		       JZ4725B_CODEC_REG_CGR10,
++		       REG_CGR10_GIL_OFFSET,
++		       REG_CGR10_GIR_OFFSET,
++		       0xf, 0, jz4725b_adc_tlv),
+ 
+ 	SOC_SINGLE("Master Playback Switch", JZ4725B_CODEC_REG_CR1,
+ 		   REG_CR1_DAC_MUTE_OFFSET, 1, 1),
+@@ -180,7 +183,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(jz4725b_codec_adc_src_enum,
+ 				  jz4725b_codec_adc_src_texts,
+ 				  jz4725b_codec_adc_src_values);
+ static const struct snd_kcontrol_new jz4725b_codec_adc_src_ctrl =
+-			SOC_DAPM_ENUM("Route", jz4725b_codec_adc_src_enum);
++	SOC_DAPM_ENUM("ADC Source Capture Route", jz4725b_codec_adc_src_enum);
+ 
+ static const struct snd_kcontrol_new jz4725b_codec_mixer_controls[] = {
+ 	SOC_DAPM_SINGLE("Line In Bypass", JZ4725B_CODEC_REG_CR1,
+@@ -225,7 +228,7 @@ static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
+ 	SND_SOC_DAPM_ADC("ADC", "Capture",
+ 			 JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_ADC_OFFSET, 1),
+ 
+-	SND_SOC_DAPM_MUX("ADC Source", SND_SOC_NOPM, 0, 0,
++	SND_SOC_DAPM_MUX("ADC Source Capture Route", SND_SOC_NOPM, 0, 0,
+ 			 &jz4725b_codec_adc_src_ctrl),
+ 
+ 	/* Mixer */
+@@ -236,7 +239,8 @@ static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
+ 	SND_SOC_DAPM_MIXER("DAC to Mixer", JZ4725B_CODEC_REG_CR1,
+ 			   REG_CR1_DACSEL_OFFSET, 0, NULL, 0),
+ 
+-	SND_SOC_DAPM_MIXER("Line In", SND_SOC_NOPM, 0, 0, NULL, 0),
++	SND_SOC_DAPM_MIXER("Line In", JZ4725B_CODEC_REG_PMR1,
++			   REG_PMR1_SB_LIN_OFFSET, 1, NULL, 0),
+ 	SND_SOC_DAPM_MIXER("HP Out", JZ4725B_CODEC_REG_CR1,
+ 			   REG_CR1_HP_DIS_OFFSET, 1, NULL, 0),
+ 
+@@ -283,11 +287,11 @@ static const struct snd_soc_dapm_route jz4725b_codec_dapm_routes[] = {
+ 	{"Mixer", NULL, "DAC to Mixer"},
+ 
+ 	{"Mixer to ADC", NULL, "Mixer"},
+-	{"ADC Source", "Mixer", "Mixer to ADC"},
+-	{"ADC Source", "Line In", "Line In"},
+-	{"ADC Source", "Mic 1", "Mic 1"},
+-	{"ADC Source", "Mic 2", "Mic 2"},
+-	{"ADC", NULL, "ADC Source"},
++	{"ADC Source Capture Route", "Mixer", "Mixer to ADC"},
++	{"ADC Source Capture Route", "Line In", "Line In"},
++	{"ADC Source Capture Route", "Mic 1", "Mic 1"},
++	{"ADC Source Capture Route", "Mic 2", "Mic 2"},
++	{"ADC", NULL, "ADC Source Capture Route"},
+ 
+ 	{"Out Stage", NULL, "Mixer"},
+ 	{"HP Out", NULL, "Out Stage"},
+diff --git a/sound/soc/codecs/mt6660.c b/sound/soc/codecs/mt6660.c
+index 45e0df13afb9f..b8369eeccc302 100644
+--- a/sound/soc/codecs/mt6660.c
++++ b/sound/soc/codecs/mt6660.c
+@@ -503,14 +503,14 @@ static int mt6660_i2c_probe(struct i2c_client *client)
+ 		dev_err(chip->dev, "read chip revision fail\n");
+ 		goto probe_fail;
+ 	}
++	pm_runtime_set_active(chip->dev);
++	pm_runtime_enable(chip->dev);
+ 
+ 	ret = devm_snd_soc_register_component(chip->dev,
+ 					       &mt6660_component_driver,
+ 					       &mt6660_codec_dai, 1);
+-	if (!ret) {
+-		pm_runtime_set_active(chip->dev);
+-		pm_runtime_enable(chip->dev);
+-	}
++	if (ret)
++		pm_runtime_disable(chip->dev);
+ 
+ 	return ret;
+ 
+diff --git a/sound/soc/codecs/rt1019.c b/sound/soc/codecs/rt1019.c
+index b66bfecbb879b..49f527c61a7ad 100644
+--- a/sound/soc/codecs/rt1019.c
++++ b/sound/soc/codecs/rt1019.c
+@@ -391,18 +391,18 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ 			unsigned int rx_mask, int slots, int slot_width)
+ {
+ 	struct snd_soc_component *component = dai->component;
+-	unsigned int val = 0, rx_slotnum;
++	unsigned int cn = 0, cl = 0, rx_slotnum;
+ 	int ret = 0, first_bit;
+ 
+ 	switch (slots) {
+ 	case 4:
+-		val |= RT1019_I2S_TX_4CH;
++		cn = RT1019_I2S_TX_4CH;
+ 		break;
+ 	case 6:
+-		val |= RT1019_I2S_TX_6CH;
++		cn = RT1019_I2S_TX_6CH;
+ 		break;
+ 	case 8:
+-		val |= RT1019_I2S_TX_8CH;
++		cn = RT1019_I2S_TX_8CH;
+ 		break;
+ 	case 2:
+ 		break;
+@@ -412,16 +412,16 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ 
+ 	switch (slot_width) {
+ 	case 20:
+-		val |= RT1019_I2S_DL_20;
++		cl = RT1019_TDM_CL_20;
+ 		break;
+ 	case 24:
+-		val |= RT1019_I2S_DL_24;
++		cl = RT1019_TDM_CL_24;
+ 		break;
+ 	case 32:
+-		val |= RT1019_I2S_DL_32;
++		cl = RT1019_TDM_CL_32;
+ 		break;
+ 	case 8:
+-		val |= RT1019_I2S_DL_8;
++		cl = RT1019_TDM_CL_8;
+ 		break;
+ 	case 16:
+ 		break;
+@@ -470,8 +470,10 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ 		goto _set_tdm_err_;
+ 	}
+ 
++	snd_soc_component_update_bits(component, RT1019_TDM_1,
++		RT1019_TDM_CL_MASK, cl);
+ 	snd_soc_component_update_bits(component, RT1019_TDM_2,
+-		RT1019_I2S_CH_TX_MASK | RT1019_I2S_DF_MASK, val);
++		RT1019_I2S_CH_TX_MASK, cn);
+ 
+ _set_tdm_err_:
+ 	return ret;
+diff --git a/sound/soc/codecs/rt1019.h b/sound/soc/codecs/rt1019.h
+index 64df831eeb720..48ba15efb48dd 100644
+--- a/sound/soc/codecs/rt1019.h
++++ b/sound/soc/codecs/rt1019.h
+@@ -95,6 +95,12 @@
+ #define RT1019_TDM_BCLK_MASK		(0x1 << 6)
+ #define RT1019_TDM_BCLK_NORM		(0x0 << 6)
+ #define RT1019_TDM_BCLK_INV			(0x1 << 6)
++#define RT1019_TDM_CL_MASK			(0x7)
++#define RT1019_TDM_CL_8				(0x4)
++#define RT1019_TDM_CL_32			(0x3)
++#define RT1019_TDM_CL_24			(0x2)
++#define RT1019_TDM_CL_20			(0x1)
++#define RT1019_TDM_CL_16			(0x0)
+ 
+ /* 0x0401 TDM Control-2 */
+ #define RT1019_I2S_CH_TX_MASK		(0x3 << 6)
+diff --git a/sound/soc/codecs/rt1308-sdw.h b/sound/soc/codecs/rt1308-sdw.h
+index 6668e19d85d46..b5f231f708cba 100644
+--- a/sound/soc/codecs/rt1308-sdw.h
++++ b/sound/soc/codecs/rt1308-sdw.h
+@@ -139,10 +139,12 @@ static const struct reg_default rt1308_reg_defaults[] = {
+ 	{ 0x3005, 0x23 },
+ 	{ 0x3008, 0x02 },
+ 	{ 0x300a, 0x00 },
++	{ 0xc000 | (RT1308_DATA_PATH << 4), 0x00 },
+ 	{ 0xc003 | (RT1308_DAC_SET << 4), 0x00 },
+ 	{ 0xc000 | (RT1308_POWER << 4), 0x00 },
+ 	{ 0xc001 | (RT1308_POWER << 4), 0x00 },
+ 	{ 0xc002 | (RT1308_POWER << 4), 0x00 },
++	{ 0xc000 | (RT1308_POWER_STATUS << 4), 0x00 },
+ };
+ 
+ #define RT1308_SDW_OFFSET 0xc000
+diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c
+index 1a25a37879356..362663abcb89e 100644
+--- a/sound/soc/codecs/rt5514-spi.c
++++ b/sound/soc/codecs/rt5514-spi.c
+@@ -298,13 +298,14 @@ static int rt5514_spi_pcm_new(struct snd_soc_component *component,
+ }
+ 
+ static const struct snd_soc_component_driver rt5514_spi_component = {
+-	.name		= DRV_NAME,
+-	.probe		= rt5514_spi_pcm_probe,
+-	.open		= rt5514_spi_pcm_open,
+-	.hw_params	= rt5514_spi_hw_params,
+-	.hw_free	= rt5514_spi_hw_free,
+-	.pointer	= rt5514_spi_pcm_pointer,
+-	.pcm_construct	= rt5514_spi_pcm_new,
++	.name			= DRV_NAME,
++	.probe			= rt5514_spi_pcm_probe,
++	.open			= rt5514_spi_pcm_open,
++	.hw_params		= rt5514_spi_hw_params,
++	.hw_free		= rt5514_spi_hw_free,
++	.pointer		= rt5514_spi_pcm_pointer,
++	.pcm_construct		= rt5514_spi_pcm_new,
++	.legacy_dai_naming	= 1,
+ };
+ 
+ /**
+diff --git a/sound/soc/codecs/rt5677-spi.c b/sound/soc/codecs/rt5677-spi.c
+index 8f3993a4c1cc7..d25703dd74996 100644
+--- a/sound/soc/codecs/rt5677-spi.c
++++ b/sound/soc/codecs/rt5677-spi.c
+@@ -396,15 +396,16 @@ static int rt5677_spi_pcm_probe(struct snd_soc_component *component)
+ }
+ 
+ static const struct snd_soc_component_driver rt5677_spi_dai_component = {
+-	.name		= DRV_NAME,
+-	.probe		= rt5677_spi_pcm_probe,
+-	.open		= rt5677_spi_pcm_open,
+-	.close		= rt5677_spi_pcm_close,
+-	.hw_params	= rt5677_spi_hw_params,
+-	.hw_free	= rt5677_spi_hw_free,
+-	.prepare	= rt5677_spi_prepare,
+-	.pointer	= rt5677_spi_pcm_pointer,
+-	.pcm_construct	= rt5677_spi_pcm_new,
++	.name			= DRV_NAME,
++	.probe			= rt5677_spi_pcm_probe,
++	.open			= rt5677_spi_pcm_open,
++	.close			= rt5677_spi_pcm_close,
++	.hw_params		= rt5677_spi_hw_params,
++	.hw_free		= rt5677_spi_hw_free,
++	.prepare		= rt5677_spi_prepare,
++	.pointer		= rt5677_spi_pcm_pointer,
++	.pcm_construct		= rt5677_spi_pcm_new,
++	.legacy_dai_naming	= 1,
+ };
+ 
+ /* Select a suitable transfer command for the next transfer to ensure
+diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c
+index eb47e7cd485aa..95fe993d59cb1 100644
+--- a/sound/soc/codecs/rt5682s.c
++++ b/sound/soc/codecs/rt5682s.c
+@@ -1932,7 +1932,7 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ 		unsigned int rx_mask, int slots, int slot_width)
+ {
+ 	struct snd_soc_component *component = dai->component;
+-	unsigned int cl, val = 0;
++	unsigned int cl, val = 0, tx_slotnum;
+ 
+ 	if (tx_mask || rx_mask)
+ 		snd_soc_component_update_bits(component,
+@@ -1941,6 +1941,16 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ 		snd_soc_component_update_bits(component,
+ 			RT5682S_TDM_ADDA_CTRL_2, RT5682S_TDM_EN, 0);
+ 
++	/* Tx slot configuration */
++	tx_slotnum = hweight_long(tx_mask);
++	if (tx_slotnum) {
++		if (tx_slotnum > slots) {
++			dev_err(component->dev, "Invalid or oversized Tx slots.\n");
++			return -EINVAL;
++		}
++		val |= (tx_slotnum - 1) << RT5682S_TDM_ADC_DL_SFT;
++	}
++
+ 	switch (slots) {
+ 	case 4:
+ 		val |= RT5682S_TDM_TX_CH_4;
+@@ -1961,7 +1971,8 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ 	}
+ 
+ 	snd_soc_component_update_bits(component, RT5682S_TDM_CTRL,
+-		RT5682S_TDM_TX_CH_MASK | RT5682S_TDM_RX_CH_MASK, val);
++		RT5682S_TDM_TX_CH_MASK | RT5682S_TDM_RX_CH_MASK |
++		RT5682S_TDM_ADC_DL_MASK, val);
+ 
+ 	switch (slot_width) {
+ 	case 8:
+diff --git a/sound/soc/codecs/rt5682s.h b/sound/soc/codecs/rt5682s.h
+index 7353831c73dd5..b660a311b6c21 100644
+--- a/sound/soc/codecs/rt5682s.h
++++ b/sound/soc/codecs/rt5682s.h
+@@ -899,6 +899,7 @@
+ #define RT5682S_TDM_RX_CH_8			(0x3 << 8)
+ #define RT5682S_TDM_ADC_LCA_MASK		(0x7 << 4)
+ #define RT5682S_TDM_ADC_LCA_SFT			4
++#define RT5682S_TDM_ADC_DL_MASK			(0x3 << 0)
+ #define RT5682S_TDM_ADC_DL_SFT			0
+ 
+ /* TDM control 2 (0x007a) */
+diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c
+index 39902f77a2e0f..6c87c3cf5ef74 100644
+--- a/sound/soc/codecs/tas2764.c
++++ b/sound/soc/codecs/tas2764.c
+@@ -386,20 +386,13 @@ static int tas2764_set_dai_tdm_slot(struct snd_soc_dai *dai,
+ 	if (tx_mask == 0 || rx_mask != 0)
+ 		return -EINVAL;
+ 
+-	if (slots == 1) {
+-		if (tx_mask != 1)
+-			return -EINVAL;
+-		left_slot = 0;
+-		right_slot = 0;
++	left_slot = __ffs(tx_mask);
++	tx_mask &= ~(1 << left_slot);
++	if (tx_mask == 0) {
++		right_slot = left_slot;
+ 	} else {
+-		left_slot = __ffs(tx_mask);
+-		tx_mask &= ~(1 << left_slot);
+-		if (tx_mask == 0) {
+-			right_slot = left_slot;
+-		} else {
+-			right_slot = __ffs(tx_mask);
+-			tx_mask &= ~(1 << right_slot);
+-		}
++		right_slot = __ffs(tx_mask);
++		tx_mask &= ~(1 << right_slot);
+ 	}
+ 
+ 	if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
+diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c
+index b6765235a4b3d..8557759acb1f2 100644
+--- a/sound/soc/codecs/tas2770.c
++++ b/sound/soc/codecs/tas2770.c
+@@ -395,21 +395,13 @@ static int tas2770_set_dai_tdm_slot(struct snd_soc_dai *dai,
+ 	if (tx_mask == 0 || rx_mask != 0)
+ 		return -EINVAL;
+ 
+-	if (slots == 1) {
+-		if (tx_mask != 1)
+-			return -EINVAL;
+-
+-		left_slot = 0;
+-		right_slot = 0;
++	left_slot = __ffs(tx_mask);
++	tx_mask &= ~(1 << left_slot);
++	if (tx_mask == 0) {
++		right_slot = left_slot;
+ 	} else {
+-		left_slot = __ffs(tx_mask);
+-		tx_mask &= ~(1 << left_slot);
+-		if (tx_mask == 0) {
+-			right_slot = left_slot;
+-		} else {
+-			right_slot = __ffs(tx_mask);
+-			tx_mask &= ~(1 << right_slot);
+-		}
++		right_slot = __ffs(tx_mask);
++		tx_mask &= ~(1 << right_slot);
+ 	}
+ 
+ 	if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
+diff --git a/sound/soc/codecs/tas2780.c b/sound/soc/codecs/tas2780.c
+index a6db6f0e5431f..afdf0c863aa10 100644
+--- a/sound/soc/codecs/tas2780.c
++++ b/sound/soc/codecs/tas2780.c
+@@ -380,20 +380,13 @@ static int tas2780_set_dai_tdm_slot(struct snd_soc_dai *dai,
+ 	if (tx_mask == 0 || rx_mask != 0)
+ 		return -EINVAL;
+ 
+-	if (slots == 1) {
+-		if (tx_mask != 1)
+-			return -EINVAL;
+-		left_slot = 0;
+-		right_slot = 0;
++	left_slot = __ffs(tx_mask);
++	tx_mask &= ~(1 << left_slot);
++	if (tx_mask == 0) {
++		right_slot = left_slot;
+ 	} else {
+-		left_slot = __ffs(tx_mask);
+-		tx_mask &= ~(1 << left_slot);
+-		if (tx_mask == 0) {
+-			right_slot = left_slot;
+-		} else {
+-			right_slot = __ffs(tx_mask);
+-			tx_mask &= ~(1 << right_slot);
+-		}
++		right_slot = __ffs(tx_mask);
++		tx_mask &= ~(1 << right_slot);
+ 	}
+ 
+ 	if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
+diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
+index c09c9ac51b3e7..af7d324e33525 100644
+--- a/sound/soc/codecs/wm5102.c
++++ b/sound/soc/codecs/wm5102.c
+@@ -2099,6 +2099,9 @@ static int wm5102_probe(struct platform_device *pdev)
+ 		regmap_update_bits(arizona->regmap, wm5102_digital_vu[i],
+ 				   WM5102_DIG_VU, WM5102_DIG_VU);
+ 
++	pm_runtime_enable(&pdev->dev);
++	pm_runtime_idle(&pdev->dev);
++
+ 	ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
+ 				  "ADSP2 Compressed IRQ", wm5102_adsp2_irq,
+ 				  wm5102);
+@@ -2131,9 +2134,6 @@ static int wm5102_probe(struct platform_device *pdev)
+ 		goto err_spk_irqs;
+ 	}
+ 
+-	pm_runtime_enable(&pdev->dev);
+-	pm_runtime_idle(&pdev->dev);
+-
+ 	return ret;
+ 
+ err_spk_irqs:
+diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
+index fc634c995834d..f3f4a10bf0f7c 100644
+--- a/sound/soc/codecs/wm5110.c
++++ b/sound/soc/codecs/wm5110.c
+@@ -2457,6 +2457,9 @@ static int wm5110_probe(struct platform_device *pdev)
+ 		regmap_update_bits(arizona->regmap, wm5110_digital_vu[i],
+ 				   WM5110_DIG_VU, WM5110_DIG_VU);
+ 
++	pm_runtime_enable(&pdev->dev);
++	pm_runtime_idle(&pdev->dev);
++
+ 	ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
+ 				  "ADSP2 Compressed IRQ", wm5110_adsp2_irq,
+ 				  wm5110);
+@@ -2489,9 +2492,6 @@ static int wm5110_probe(struct platform_device *pdev)
+ 		goto err_spk_irqs;
+ 	}
+ 
+-	pm_runtime_enable(&pdev->dev);
+-	pm_runtime_idle(&pdev->dev);
+-
+ 	return ret;
+ 
+ err_spk_irqs:
+diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
+index 398c448ea8540..6df06fba43778 100644
+--- a/sound/soc/codecs/wm8962.c
++++ b/sound/soc/codecs/wm8962.c
+@@ -1840,6 +1840,49 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
+ 	       4, 1, 0, inmix_tlv),
+ };
+ 
++static int tp_event(struct snd_soc_dapm_widget *w,
++		    struct snd_kcontrol *kcontrol, int event)
++{
++	int ret, reg, val, mask;
++	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
++
++	ret = pm_runtime_resume_and_get(component->dev);
++	if (ret < 0) {
++		dev_err(component->dev, "Failed to resume device: %d\n", ret);
++		return ret;
++	}
++
++	reg = WM8962_ADDITIONAL_CONTROL_4;
++
++	if (!strcmp(w->name, "TEMP_HP")) {
++		mask = WM8962_TEMP_ENA_HP_MASK;
++		val = WM8962_TEMP_ENA_HP;
++	} else if (!strcmp(w->name, "TEMP_SPK")) {
++		mask = WM8962_TEMP_ENA_SPK_MASK;
++		val = WM8962_TEMP_ENA_SPK;
++	} else {
++		pm_runtime_put(component->dev);
++		return -EINVAL;
++	}
++
++	switch (event) {
++	case SND_SOC_DAPM_POST_PMD:
++		val = 0;
++		fallthrough;
++	case SND_SOC_DAPM_POST_PMU:
++		ret = snd_soc_component_update_bits(component, reg, mask, val);
++		break;
++	default:
++		WARN(1, "Invalid event %d\n", event);
++		pm_runtime_put(component->dev);
++		return -EINVAL;
++	}
++
++	pm_runtime_put(component->dev);
++
++	return 0;
++}
++
+ static int cp_event(struct snd_soc_dapm_widget *w,
+ 		    struct snd_kcontrol *kcontrol, int event)
+ {
+@@ -2140,8 +2183,10 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
+ 		      WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
+ 		      SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+-SND_SOC_DAPM_SUPPLY("TEMP_HP", WM8962_ADDITIONAL_CONTROL_4, 2, 0, NULL, 0),
+-SND_SOC_DAPM_SUPPLY("TEMP_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0),
++SND_SOC_DAPM_SUPPLY("TEMP_HP", SND_SOC_NOPM, 0, 0, tp_event,
++		SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
++SND_SOC_DAPM_SUPPLY("TEMP_SPK", SND_SOC_NOPM, 0, 0, tp_event,
++		SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+ 
+ SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
+ 		   inpgal, ARRAY_SIZE(inpgal)),
+@@ -3763,6 +3808,11 @@ static int wm8962_i2c_probe(struct i2c_client *i2c)
+ 	if (ret < 0)
+ 		goto err_pm_runtime;
+ 
++	regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4,
++			    WM8962_TEMP_ENA_HP_MASK, 0);
++	regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4,
++			    WM8962_TEMP_ENA_SPK_MASK, 0);
++
+ 	regcache_cache_only(wm8962->regmap, true);
+ 
+ 	/* The drivers should power up as needed */
+diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
+index 77136a5216059..210ad662fc26d 100644
+--- a/sound/soc/codecs/wm8997.c
++++ b/sound/soc/codecs/wm8997.c
+@@ -1161,6 +1161,9 @@ static int wm8997_probe(struct platform_device *pdev)
+ 		regmap_update_bits(arizona->regmap, wm8997_digital_vu[i],
+ 				   WM8997_DIG_VU, WM8997_DIG_VU);
+ 
++	pm_runtime_enable(&pdev->dev);
++	pm_runtime_idle(&pdev->dev);
++
+ 	arizona_init_common(arizona);
+ 
+ 	ret = arizona_init_vol_limit(arizona);
+@@ -1179,9 +1182,6 @@ static int wm8997_probe(struct platform_device *pdev)
+ 		goto err_spk_irqs;
+ 	}
+ 
+-	pm_runtime_enable(&pdev->dev);
+-	pm_runtime_idle(&pdev->dev);
+-
+ 	return ret;
+ 
+ err_spk_irqs:
+diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
+index aa5edf32d9889..d90adb6ee43d9 100644
+--- a/sound/soc/fsl/fsl_asrc.c
++++ b/sound/soc/fsl/fsl_asrc.c
+@@ -1224,7 +1224,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	ret = pm_runtime_put_sync(&pdev->dev);
+-	if (ret < 0)
++	if (ret < 0 && ret != -ENOSYS)
+ 		goto err_pm_get_sync;
+ 
+ 	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component,
+diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
+index 5c21fc490fce1..17fefd27ec90a 100644
+--- a/sound/soc/fsl/fsl_esai.c
++++ b/sound/soc/fsl/fsl_esai.c
+@@ -1069,7 +1069,7 @@ static int fsl_esai_probe(struct platform_device *pdev)
+ 	regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0);
+ 
+ 	ret = pm_runtime_put_sync(&pdev->dev);
+-	if (ret < 0)
++	if (ret < 0 && ret != -ENOSYS)
+ 		goto err_pm_get_sync;
+ 
+ 	/*
+diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
+index d430eece1d6b1..887063f9cbeae 100644
+--- a/sound/soc/fsl/fsl_sai.c
++++ b/sound/soc/fsl/fsl_sai.c
+@@ -1415,7 +1415,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	ret = pm_runtime_put_sync(dev);
+-	if (ret < 0)
++	if (ret < 0 && ret != -ENOSYS)
+ 		goto err_pm_get_sync;
+ 
+ 	/*
+diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
+index 045965312245b..30c53dca342e8 100644
+--- a/sound/soc/intel/boards/sof_rt5682.c
++++ b/sound/soc/intel/boards/sof_rt5682.c
+@@ -225,6 +225,18 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
+ 					SOF_RT5682_SSP_AMP(2) |
+ 					SOF_RT5682_NUM_HDMIDEV(4)),
+ 	},
++	{
++		.callback = sof_rt5682_quirk_cb,
++		.matches = {
++			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"),
++		},
++		.driver_data = (void *)(SOF_RT5682_MCLK_EN |
++					SOF_RT5682_SSP_CODEC(2) |
++					SOF_SPEAKER_AMP_PRESENT |
++					SOF_RT5682_SSP_AMP(0) |
++					SOF_RT5682_NUM_HDMIDEV(4)
++					),
++	},
+ 	{}
+ };
+ 
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
+index 2ff30b40a1e4c..ee9857dc3135d 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -202,6 +202,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
+ 					SOF_SDW_PCH_DMIC |
+ 					RT711_JD1),
+ 	},
++	{
++		/* NUC15 LAPBC710 skews */
++		.callback = sof_sdw_quirk_cb,
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
++			DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"),
++		},
++		.driver_data = (void *)(SOF_SDW_TGL_HDMI |
++					SOF_SDW_PCH_DMIC |
++					RT711_JD1),
++	},
+ 	/* TigerLake-SDCA devices */
+ 	{
+ 		.callback = sof_sdw_quirk_cb,
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index e824ff1a9fc09..3d057784cbd53 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -3472,10 +3472,23 @@ EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_cpus);
+ 
+ static int __init snd_soc_init(void)
+ {
++	int ret;
++
+ 	snd_soc_debugfs_init();
+-	snd_soc_util_init();
++	ret = snd_soc_util_init();
++	if (ret)
++		goto err_util_init;
+ 
+-	return platform_driver_register(&soc_driver);
++	ret = platform_driver_register(&soc_driver);
++	if (ret)
++		goto err_register;
++	return 0;
++
++err_register:
++	snd_soc_util_exit();
++err_util_init:
++	snd_soc_debugfs_exit();
++	return ret;
+ }
+ module_init(snd_soc_init);
+ 
+diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
+index 70c380c0ac7b6..d1308904e6e0f 100644
+--- a/sound/soc/soc-utils.c
++++ b/sound/soc/soc-utils.c
+@@ -263,7 +263,7 @@ int __init snd_soc_util_init(void)
+ 	return ret;
+ }
+ 
+-void __exit snd_soc_util_exit(void)
++void snd_soc_util_exit(void)
+ {
+ 	platform_driver_unregister(&soc_dummy_driver);
+ 	platform_device_unregister(soc_dummy_dev);
+diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
+index 9273a70fec25c..e1b7f07de7fcd 100644
+--- a/sound/soc/sof/topology.c
++++ b/sound/soc/sof/topology.c
+@@ -1346,16 +1346,6 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
+ 		break;
+ 	}
+ 
+-	if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) {
+-		swidget->core = SOF_DSP_PRIMARY_CORE;
+-	} else {
+-		int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples,
+-					       swidget->num_tuples);
+-
+-		if (core >= 0)
+-			swidget->core = core;
+-	}
+-
+ 	/* check token parsing reply */
+ 	if (ret < 0) {
+ 		dev_err(scomp->dev,
+@@ -1367,6 +1357,16 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
+ 		return ret;
+ 	}
+ 
++	if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) {
++		swidget->core = SOF_DSP_PRIMARY_CORE;
++	} else {
++		int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples,
++					       swidget->num_tuples);
++
++		if (core >= 0)
++			swidget->core = core;
++	}
++
+ 	/* bind widget to external event */
+ 	if (tw->event_type) {
+ 		if (widget_ops[w->id].bind_event) {
+diff --git a/sound/usb/midi.c b/sound/usb/midi.c
+index bbff0923d2646..2839f6b6f09b4 100644
+--- a/sound/usb/midi.c
++++ b/sound/usb/midi.c
+@@ -1133,10 +1133,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
+ 					port = &umidi->endpoints[i].out->ports[j];
+ 					break;
+ 				}
+-	if (!port) {
+-		snd_BUG();
++	if (!port)
+ 		return -ENXIO;
+-	}
+ 
+ 	substream->runtime->private_data = port;
+ 	port->state = STATE_UNKNOWN;
+diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
+index a072b2d3e726a..133e4c73d3702 100644
+--- a/tools/testing/cxl/test/cxl.c
++++ b/tools/testing/cxl/test/cxl.c
+@@ -695,7 +695,7 @@ static __init int cxl_test_init(void)
+ 
+ 		pdev = platform_device_alloc("cxl_switch_uport", i);
+ 		if (!pdev)
+-			goto err_port;
++			goto err_uport;
+ 		pdev->dev.parent = &root_port->dev;
+ 
+ 		rc = platform_device_add(pdev);
+@@ -713,7 +713,7 @@ static __init int cxl_test_init(void)
+ 
+ 		pdev = platform_device_alloc("cxl_switch_dport", i);
+ 		if (!pdev)
+-			goto err_port;
++			goto err_dport;
+ 		pdev->dev.parent = &uport->dev;
+ 
+ 		rc = platform_device_add(pdev);
+diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
+index 3561c97701f24..a07b8ae64bf83 100644
+--- a/tools/testing/selftests/bpf/test_progs.c
++++ b/tools/testing/selftests/bpf/test_progs.c
+@@ -993,7 +993,7 @@ static inline const char *str_msg(const struct msg *msg, char *buf)
+ 			msg->subtest_done.have_log);
+ 		break;
+ 	case MSG_TEST_LOG:
+-		sprintf(buf, "MSG_TEST_LOG (cnt: %ld, last: %d)",
++		sprintf(buf, "MSG_TEST_LOG (cnt: %zu, last: %d)",
+ 			strlen(msg->test_log.log_buf),
+ 			msg->test_log.is_last);
+ 		break;
+diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
+index f9d553fbf68a3..ce97a92626989 100644
+--- a/tools/testing/selftests/bpf/test_verifier.c
++++ b/tools/testing/selftests/bpf/test_verifier.c
+@@ -1260,7 +1260,7 @@ static int get_xlated_program(int fd_prog, struct bpf_insn **buf, int *cnt)
+ 
+ 	bzero(&info, sizeof(info));
+ 	info.xlated_prog_len = xlated_prog_len;
+-	info.xlated_prog_insns = (__u64)*buf;
++	info.xlated_prog_insns = (__u64)(unsigned long)*buf;
+ 	if (bpf_obj_get_info_by_fd(fd_prog, &info, &info_len)) {
+ 		perror("second bpf_obj_get_info_by_fd failed");
+ 		goto out_free_buf;
+diff --git a/tools/testing/selftests/futex/functional/Makefile b/tools/testing/selftests/futex/functional/Makefile
+index 7321490116925..5a0e0df8de9b3 100644
+--- a/tools/testing/selftests/futex/functional/Makefile
++++ b/tools/testing/selftests/futex/functional/Makefile
+@@ -3,11 +3,11 @@ INCLUDES := -I../include -I../../ -I../../../../../usr/include/
+ CFLAGS := $(CFLAGS) -g -O2 -Wall -D_GNU_SOURCE -pthread $(INCLUDES) $(KHDR_INCLUDES)
+ LDLIBS := -lpthread -lrt
+ 
+-HEADERS := \
++LOCAL_HDRS := \
+ 	../include/futextest.h \
+ 	../include/atomic.h \
+ 	../include/logging.h
+-TEST_GEN_FILES := \
++TEST_GEN_PROGS := \
+ 	futex_wait_timeout \
+ 	futex_wait_wouldblock \
+ 	futex_requeue_pi \
+@@ -24,5 +24,3 @@ TEST_PROGS := run.sh
+ top_srcdir = ../../../../..
+ DEFAULT_INSTALL_HDR_PATH := 1
+ include ../../lib.mk
+-
+-$(TEST_GEN_FILES): $(HEADERS)
+diff --git a/tools/testing/selftests/intel_pstate/Makefile b/tools/testing/selftests/intel_pstate/Makefile
+index 39f0fa2a8fd63..05d66ef50c977 100644
+--- a/tools/testing/selftests/intel_pstate/Makefile
++++ b/tools/testing/selftests/intel_pstate/Makefile
+@@ -2,10 +2,10 @@
+ CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE
+ LDLIBS += -lm
+ 
+-uname_M := $(shell uname -m 2>/dev/null || echo not)
+-ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
++ARCH ?= $(shell uname -m 2>/dev/null || echo not)
++ARCH_PROCESSED := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+ 
+-ifeq (x86,$(ARCH))
++ifeq (x86,$(ARCH_PROCESSED))
+ TEST_GEN_FILES := msr aperf
+ endif
+ 
+diff --git a/tools/testing/selftests/kexec/Makefile b/tools/testing/selftests/kexec/Makefile
+index 806a150648c36..67fe7a46cb624 100644
+--- a/tools/testing/selftests/kexec/Makefile
++++ b/tools/testing/selftests/kexec/Makefile
+@@ -1,10 +1,10 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ # Makefile for kexec tests
+ 
+-uname_M := $(shell uname -m 2>/dev/null || echo not)
+-ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
++ARCH ?= $(shell uname -m 2>/dev/null || echo not)
++ARCH_PROCESSED := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
+ 
+-ifeq ($(ARCH),$(filter $(ARCH),x86 ppc64le))
++ifeq ($(ARCH_PROCESSED),$(filter $(ARCH_PROCESSED),x86 ppc64le))
+ TEST_PROGS := test_kexec_load.sh test_kexec_file_load.sh
+ TEST_FILES := kexec_common_lib.sh
+ 
+diff --git a/tools/testing/selftests/pidfd/pidfd_wait.c b/tools/testing/selftests/pidfd/pidfd_wait.c
+index 070c1c876df15..c3e2a3041f55f 100644
+--- a/tools/testing/selftests/pidfd/pidfd_wait.c
++++ b/tools/testing/selftests/pidfd/pidfd_wait.c
+@@ -95,20 +95,28 @@ TEST(wait_states)
+ 		.flags = CLONE_PIDFD | CLONE_PARENT_SETTID,
+ 		.exit_signal = SIGCHLD,
+ 	};
++	int pfd[2];
+ 	pid_t pid;
+ 	siginfo_t info = {
+ 		.si_signo = 0,
+ 	};
+ 
++	ASSERT_EQ(pipe(pfd), 0);
+ 	pid = sys_clone3(&args);
+ 	ASSERT_GE(pid, 0);
+ 
+ 	if (pid == 0) {
++		char buf[2];
++
++		close(pfd[1]);
+ 		kill(getpid(), SIGSTOP);
++		ASSERT_EQ(read(pfd[0], buf, 1), 1);
++		close(pfd[0]);
+ 		kill(getpid(), SIGSTOP);
+ 		exit(EXIT_SUCCESS);
+ 	}
+ 
++	close(pfd[0]);
+ 	ASSERT_EQ(sys_waitid(P_PIDFD, pidfd, &info, WSTOPPED, NULL), 0);
+ 	ASSERT_EQ(info.si_signo, SIGCHLD);
+ 	ASSERT_EQ(info.si_code, CLD_STOPPED);
+@@ -117,6 +125,8 @@ TEST(wait_states)
+ 	ASSERT_EQ(sys_pidfd_send_signal(pidfd, SIGCONT, NULL, 0), 0);
+ 
+ 	ASSERT_EQ(sys_waitid(P_PIDFD, pidfd, &info, WCONTINUED, NULL), 0);
++	ASSERT_EQ(write(pfd[1], "C", 1), 1);
++	close(pfd[1]);
+ 	ASSERT_EQ(info.si_signo, SIGCHLD);
+ 	ASSERT_EQ(info.si_code, CLD_CONTINUED);
+ 	ASSERT_EQ(info.si_pid, parent_tid);


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-16 11:16 Alice Ferrazzi
  0 siblings, 0 replies; 27+ messages in thread
From: Alice Ferrazzi @ 2022-11-16 11:16 UTC (permalink / raw
  To: gentoo-commits

commit:     167e638e734a78f986f9cb92a872a2e5ed7b2a1f
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Wed Nov 16 11:11:17 2022 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Wed Nov 16 11:11:17 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=167e638e

Linux patch 6.0.9

Signed-off-by: Alice Ferrazzi <alicef <AT> gentoo.org>

 0000_README            |    4 +
 1008_linux-6.0.9.patch | 6943 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 6947 insertions(+)

diff --git a/0000_README b/0000_README
index 04880a09..bda6a465 100644
--- a/0000_README
+++ b/0000_README
@@ -75,6 +75,10 @@ Patch:  1007_linux-6.0.8.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.8
 
+Patch:  1008_linux-6.0.9.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.9
+
 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/1008_linux-6.0.9.patch b/1008_linux-6.0.9.patch
new file mode 100644
index 00000000..efa04169
--- /dev/null
+++ b/1008_linux-6.0.9.patch
@@ -0,0 +1,6943 @@
+diff --git a/Documentation/devicetree/bindings/net/engleder,tsnep.yaml b/Documentation/devicetree/bindings/net/engleder,tsnep.yaml
+index d0e1476e15b50..ccc42cb470dac 100644
+--- a/Documentation/devicetree/bindings/net/engleder,tsnep.yaml
++++ b/Documentation/devicetree/bindings/net/engleder,tsnep.yaml
+@@ -28,7 +28,7 @@ properties:
+ 
+   nvmem-cells: true
+ 
+-  nvmem-cells-names: true
++  nvmem-cell-names: true
+ 
+   phy-connection-type:
+     enum:
+diff --git a/Documentation/virt/kvm/devices/vm.rst b/Documentation/virt/kvm/devices/vm.rst
+index 0aa5b1cfd700c..60acc39e0e937 100644
+--- a/Documentation/virt/kvm/devices/vm.rst
++++ b/Documentation/virt/kvm/devices/vm.rst
+@@ -215,6 +215,7 @@ KVM_S390_VM_TOD_EXT).
+ :Parameters: address of a buffer in user space to store the data (u8) to
+ :Returns:   -EFAULT if the given address is not accessible from kernel space;
+ 	    -EINVAL if setting the TOD clock extension to != 0 is not supported
++	    -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor)
+ 
+ 3.2. ATTRIBUTE: KVM_S390_VM_TOD_LOW
+ -----------------------------------
+@@ -224,6 +225,7 @@ the POP (u64).
+ 
+ :Parameters: address of a buffer in user space to store the data (u64) to
+ :Returns:    -EFAULT if the given address is not accessible from kernel space
++	     -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor)
+ 
+ 3.3. ATTRIBUTE: KVM_S390_VM_TOD_EXT
+ -----------------------------------
+@@ -237,6 +239,7 @@ it, it is stored as 0 and not allowed to be set to a value != 0.
+ 	     (kvm_s390_vm_tod_clock) to
+ :Returns:   -EFAULT if the given address is not accessible from kernel space;
+ 	    -EINVAL if setting the TOD clock extension to != 0 is not supported
++	    -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor)
+ 
+ 4. GROUP: KVM_S390_VM_CRYPTO
+ ============================
+diff --git a/Makefile b/Makefile
+index bcb76d4fdbc11..a234f16783ede 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 8
++SUBLEVEL = 9
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
+index e1be6c429810d..a908a37f03678 100644
+--- a/arch/arm64/kernel/efi.c
++++ b/arch/arm64/kernel/efi.c
+@@ -12,6 +12,14 @@
+ 
+ #include <asm/efi.h>
+ 
++static bool region_is_misaligned(const efi_memory_desc_t *md)
++{
++	if (PAGE_SIZE == EFI_PAGE_SIZE)
++		return false;
++	return !PAGE_ALIGNED(md->phys_addr) ||
++	       !PAGE_ALIGNED(md->num_pages << EFI_PAGE_SHIFT);
++}
++
+ /*
+  * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be
+  * executable, everything else can be mapped with the XN bits
+@@ -25,14 +33,22 @@ static __init pteval_t create_mapping_protection(efi_memory_desc_t *md)
+ 	if (type == EFI_MEMORY_MAPPED_IO)
+ 		return PROT_DEVICE_nGnRE;
+ 
+-	if (WARN_ONCE(!PAGE_ALIGNED(md->phys_addr),
+-		      "UEFI Runtime regions are not aligned to 64 KB -- buggy firmware?"))
++	if (region_is_misaligned(md)) {
++		static bool __initdata code_is_misaligned;
++
+ 		/*
+-		 * If the region is not aligned to the page size of the OS, we
+-		 * can not use strict permissions, since that would also affect
+-		 * the mapping attributes of the adjacent regions.
++		 * Regions that are not aligned to the OS page size cannot be
++		 * mapped with strict permissions, as those might interfere
++		 * with the permissions that are needed by the adjacent
++		 * region's mapping. However, if we haven't encountered any
++		 * misaligned runtime code regions so far, we can safely use
++		 * non-executable permissions for non-code regions.
+ 		 */
+-		return pgprot_val(PAGE_KERNEL_EXEC);
++		code_is_misaligned |= (type == EFI_RUNTIME_SERVICES_CODE);
++
++		return code_is_misaligned ? pgprot_val(PAGE_KERNEL_EXEC)
++					  : pgprot_val(PAGE_KERNEL);
++	}
+ 
+ 	/* R-- */
+ 	if ((attr & (EFI_MEMORY_XP | EFI_MEMORY_RO)) ==
+@@ -63,19 +79,16 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
+ 	bool page_mappings_only = (md->type == EFI_RUNTIME_SERVICES_CODE ||
+ 				   md->type == EFI_RUNTIME_SERVICES_DATA);
+ 
+-	if (!PAGE_ALIGNED(md->phys_addr) ||
+-	    !PAGE_ALIGNED(md->num_pages << EFI_PAGE_SHIFT)) {
+-		/*
+-		 * If the end address of this region is not aligned to page
+-		 * size, the mapping is rounded up, and may end up sharing a
+-		 * page frame with the next UEFI memory region. If we create
+-		 * a block entry now, we may need to split it again when mapping
+-		 * the next region, and support for that is going to be removed
+-		 * from the MMU routines. So avoid block mappings altogether in
+-		 * that case.
+-		 */
++	/*
++	 * If this region is not aligned to the page size used by the OS, the
++	 * mapping will be rounded outwards, and may end up sharing a page
++	 * frame with an adjacent runtime memory region. Given that the page
++	 * table descriptor covering the shared page will be rewritten when the
++	 * adjacent region gets mapped, we must avoid block mappings here so we
++	 * don't have to worry about splitting them when that happens.
++	 */
++	if (region_is_misaligned(md))
+ 		page_mappings_only = true;
+-	}
+ 
+ 	create_pgd_mapping(mm, md->phys_addr, md->virt_addr,
+ 			   md->num_pages << EFI_PAGE_SHIFT,
+@@ -102,6 +115,9 @@ int __init efi_set_mapping_permissions(struct mm_struct *mm,
+ 	BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE &&
+ 	       md->type != EFI_RUNTIME_SERVICES_DATA);
+ 
++	if (region_is_misaligned(md))
++		return 0;
++
+ 	/*
+ 	 * Calling apply_to_page_range() is only safe on regions that are
+ 	 * guaranteed to be mapped down to pages. Since we are only called
+diff --git a/arch/m68k/include/uapi/asm/bootinfo-virt.h b/arch/m68k/include/uapi/asm/bootinfo-virt.h
+index b091ee9b06e05..7dbcd7bec1034 100644
+--- a/arch/m68k/include/uapi/asm/bootinfo-virt.h
++++ b/arch/m68k/include/uapi/asm/bootinfo-virt.h
+@@ -13,13 +13,8 @@
+ #define BI_VIRT_VIRTIO_BASE	0x8004
+ #define BI_VIRT_CTRL_BASE	0x8005
+ 
+-/*
+- * A random seed used to initialize the RNG. Record format:
+- *
+- *   - length       [ 2 bytes, 16-bit big endian ]
+- *   - seed data    [ `length` bytes, padded to preserve 2-byte alignment ]
+- */
+-#define BI_VIRT_RNG_SEED	0x8006
++/* No longer used -- replaced with BI_RNG_SEED -- but don't reuse this index:
++ * #define BI_VIRT_RNG_SEED	0x8006 */
+ 
+ #define VIRT_BOOTI_VERSION	MK_BI_VERSION(2, 0)
+ 
+diff --git a/arch/m68k/include/uapi/asm/bootinfo.h b/arch/m68k/include/uapi/asm/bootinfo.h
+index 95ecf3ae4c49f..024e87d7095f8 100644
+--- a/arch/m68k/include/uapi/asm/bootinfo.h
++++ b/arch/m68k/include/uapi/asm/bootinfo.h
+@@ -64,6 +64,13 @@ struct mem_info {
+ 					/* (struct mem_info) */
+ #define BI_COMMAND_LINE		0x0007	/* kernel command line parameters */
+ 					/* (string) */
++/*
++ * A random seed used to initialize the RNG. Record format:
++ *
++ *   - length       [ 2 bytes, 16-bit big endian ]
++ *   - seed data    [ `length` bytes, padded to preserve 4-byte struct alignment ]
++ */
++#define BI_RNG_SEED		0x0008
+ 
+ 
+     /*
+diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
+index 7e7ef67cff8b2..e45cc99237030 100644
+--- a/arch/m68k/kernel/setup_mm.c
++++ b/arch/m68k/kernel/setup_mm.c
+@@ -25,6 +25,7 @@
+ #include <linux/module.h>
+ #include <linux/nvram.h>
+ #include <linux/initrd.h>
++#include <linux/random.h>
+ 
+ #include <asm/bootinfo.h>
+ #include <asm/byteorder.h>
+@@ -151,6 +152,17 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
+ 				sizeof(m68k_command_line));
+ 			break;
+ 
++		case BI_RNG_SEED: {
++			u16 len = be16_to_cpup(data);
++			add_bootloader_randomness(data + 2, len);
++			/*
++			 * Zero the data to preserve forward secrecy, and zero the
++			 * length to prevent kexec from using it.
++			 */
++			memzero_explicit((void *)data, len + 2);
++			break;
++		}
++
+ 		default:
+ 			if (MACH_IS_AMIGA)
+ 				unknown = amiga_parse_bootinfo(record);
+diff --git a/arch/m68k/virt/config.c b/arch/m68k/virt/config.c
+index 4ab22946ff68f..632ba200ad425 100644
+--- a/arch/m68k/virt/config.c
++++ b/arch/m68k/virt/config.c
+@@ -2,7 +2,6 @@
+ 
+ #include <linux/reboot.h>
+ #include <linux/serial_core.h>
+-#include <linux/random.h>
+ #include <clocksource/timer-goldfish.h>
+ 
+ #include <asm/bootinfo.h>
+@@ -93,16 +92,6 @@ int __init virt_parse_bootinfo(const struct bi_record *record)
+ 		data += 4;
+ 		virt_bi_data.virtio.irq = be32_to_cpup(data);
+ 		break;
+-	case BI_VIRT_RNG_SEED: {
+-		u16 len = be16_to_cpup(data);
+-		add_bootloader_randomness(data + 2, len);
+-		/*
+-		 * Zero the data to preserve forward secrecy, and zero the
+-		 * length to prevent kexec from using it.
+-		 */
+-		memzero_explicit((void *)data, len + 2);
+-		break;
+-	}
+ 	default:
+ 		unknown = 1;
+ 		break;
+diff --git a/arch/mips/kernel/jump_label.c b/arch/mips/kernel/jump_label.c
+index 71a882c8c6eb1..f7978d50a2ba5 100644
+--- a/arch/mips/kernel/jump_label.c
++++ b/arch/mips/kernel/jump_label.c
+@@ -56,7 +56,7 @@ void arch_jump_label_transform(struct jump_entry *e,
+ 			 * The branch offset must fit in the instruction's 26
+ 			 * bit field.
+ 			 */
+-			WARN_ON((offset >= BIT(25)) ||
++			WARN_ON((offset >= (long)BIT(25)) ||
+ 				(offset < -(long)BIT(25)));
+ 
+ 			insn.j_format.opcode = bc6_op;
+diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
+index ceb9ebab6558c..52002d54b1637 100644
+--- a/arch/riscv/kernel/process.c
++++ b/arch/riscv/kernel/process.c
+@@ -164,6 +164,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
+ 	unsigned long tls = args->tls;
+ 	struct pt_regs *childregs = task_pt_regs(p);
+ 
++	memset(&p->thread.s, 0, sizeof(p->thread.s));
++
+ 	/* p->thread holds context to be restored by __switch_to() */
+ 	if (unlikely(args->fn)) {
+ 		/* Kernel thread */
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
+index ad76bb59b0590..67ec1fadcfe24 100644
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -283,6 +283,7 @@ void __init setup_arch(char **cmdline_p)
+ 	else
+ 		pr_err("No DTB found in kernel mappings\n");
+ #endif
++	early_init_fdt_scan_reserved_mem();
+ 	misc_mem_init();
+ 
+ 	init_resources();
+diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
+index f2e065671e4d5..84ac0fe612e79 100644
+--- a/arch/riscv/kernel/vdso/Makefile
++++ b/arch/riscv/kernel/vdso/Makefile
+@@ -30,7 +30,7 @@ obj-y += vdso.o
+ CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
+ 
+ # Disable -pg to prevent insert call site
+-CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os
++CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE)
+ 
+ # Disable profiling and instrumentation for VDSO code
+ GCOV_PROFILE := n
+diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
+index b56a0a75533fe..50a1b6edd4918 100644
+--- a/arch/riscv/mm/init.c
++++ b/arch/riscv/mm/init.c
+@@ -262,7 +262,6 @@ static void __init setup_bootmem(void)
+ 			memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
+ 	}
+ 
+-	early_init_fdt_scan_reserved_mem();
+ 	dma_contiguous_reserve(dma32_phys_limit);
+ 	if (IS_ENABLED(CONFIG_64BIT))
+ 		hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT);
+diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
+index b7ef0b71014df..2486281027c02 100644
+--- a/arch/s390/kvm/kvm-s390.c
++++ b/arch/s390/kvm/kvm-s390.c
+@@ -1207,6 +1207,8 @@ static int kvm_s390_vm_get_migration(struct kvm *kvm,
+ 	return 0;
+ }
+ 
++static void __kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod);
++
+ static int kvm_s390_set_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr)
+ {
+ 	struct kvm_s390_vm_tod_clock gtod;
+@@ -1216,7 +1218,7 @@ static int kvm_s390_set_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr)
+ 
+ 	if (!test_kvm_facility(kvm, 139) && gtod.epoch_idx)
+ 		return -EINVAL;
+-	kvm_s390_set_tod_clock(kvm, &gtod);
++	__kvm_s390_set_tod_clock(kvm, &gtod);
+ 
+ 	VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x, TOD base: 0x%llx",
+ 		gtod.epoch_idx, gtod.tod);
+@@ -1247,7 +1249,7 @@ static int kvm_s390_set_tod_low(struct kvm *kvm, struct kvm_device_attr *attr)
+ 			   sizeof(gtod.tod)))
+ 		return -EFAULT;
+ 
+-	kvm_s390_set_tod_clock(kvm, &gtod);
++	__kvm_s390_set_tod_clock(kvm, &gtod);
+ 	VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx", gtod.tod);
+ 	return 0;
+ }
+@@ -1259,6 +1261,16 @@ static int kvm_s390_set_tod(struct kvm *kvm, struct kvm_device_attr *attr)
+ 	if (attr->flags)
+ 		return -EINVAL;
+ 
++	mutex_lock(&kvm->lock);
++	/*
++	 * For protected guests, the TOD is managed by the ultravisor, so trying
++	 * to change it will never bring the expected results.
++	 */
++	if (kvm_s390_pv_is_protected(kvm)) {
++		ret = -EOPNOTSUPP;
++		goto out_unlock;
++	}
++
+ 	switch (attr->attr) {
+ 	case KVM_S390_VM_TOD_EXT:
+ 		ret = kvm_s390_set_tod_ext(kvm, attr);
+@@ -1273,6 +1285,9 @@ static int kvm_s390_set_tod(struct kvm *kvm, struct kvm_device_attr *attr)
+ 		ret = -ENXIO;
+ 		break;
+ 	}
++
++out_unlock:
++	mutex_unlock(&kvm->lock);
+ 	return ret;
+ }
+ 
+@@ -4379,13 +4394,6 @@ static void __kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_t
+ 	preempt_enable();
+ }
+ 
+-void kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod)
+-{
+-	mutex_lock(&kvm->lock);
+-	__kvm_s390_set_tod_clock(kvm, gtod);
+-	mutex_unlock(&kvm->lock);
+-}
+-
+ int kvm_s390_try_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod)
+ {
+ 	if (!mutex_trylock(&kvm->lock))
+diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
+index f6fd668f887e8..4755492dfabc6 100644
+--- a/arch/s390/kvm/kvm-s390.h
++++ b/arch/s390/kvm/kvm-s390.h
+@@ -363,7 +363,6 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
+ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu);
+ 
+ /* implemented in kvm-s390.c */
+-void kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod);
+ int kvm_s390_try_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod);
+ long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable);
+ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr);
+diff --git a/arch/s390/kvm/pci.c b/arch/s390/kvm/pci.c
+index c50c1645c0aec..ded1af2ddae99 100644
+--- a/arch/s390/kvm/pci.c
++++ b/arch/s390/kvm/pci.c
+@@ -126,7 +126,7 @@ int kvm_s390_pci_aen_init(u8 nisc)
+ 		return -EPERM;
+ 
+ 	mutex_lock(&aift->aift_lock);
+-	aift->kzdev = kcalloc(ZPCI_NR_DEVICES, sizeof(struct kvm_zdev),
++	aift->kzdev = kcalloc(ZPCI_NR_DEVICES, sizeof(struct kvm_zdev *),
+ 			      GFP_KERNEL);
+ 	if (!aift->kzdev) {
+ 		rc = -ENOMEM;
+diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
+index 1e086b37a3071..28e8e678c8357 100644
+--- a/arch/x86/include/asm/msr-index.h
++++ b/arch/x86/include/asm/msr-index.h
+@@ -535,6 +535,11 @@
+ #define MSR_AMD64_CPUID_FN_1		0xc0011004
+ #define MSR_AMD64_LS_CFG		0xc0011020
+ #define MSR_AMD64_DC_CFG		0xc0011022
++
++#define MSR_AMD64_DE_CFG		0xc0011029
++#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT	 1
++#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE	BIT_ULL(MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT)
++
+ #define MSR_AMD64_BU_CFG2		0xc001102a
+ #define MSR_AMD64_IBSFETCHCTL		0xc0011030
+ #define MSR_AMD64_IBSFETCHLINAD		0xc0011031
+@@ -637,9 +642,6 @@
+ #define FAM10H_MMIO_CONF_BASE_MASK	0xfffffffULL
+ #define FAM10H_MMIO_CONF_BASE_SHIFT	20
+ #define MSR_FAM10H_NODE_ID		0xc001100c
+-#define MSR_F10H_DECFG			0xc0011029
+-#define MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT	1
+-#define MSR_F10H_DECFG_LFENCE_SERIALIZE		BIT_ULL(MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT)
+ 
+ /* K8 MSRs */
+ #define MSR_K8_TOP_MEM1			0xc001001a
+diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
+index cb50589a7102f..437308004ef2e 100644
+--- a/arch/x86/kernel/asm-offsets.c
++++ b/arch/x86/kernel/asm-offsets.c
+@@ -19,7 +19,6 @@
+ #include <asm/suspend.h>
+ #include <asm/tlbflush.h>
+ #include <asm/tdx.h>
+-#include "../kvm/vmx/vmx.h"
+ 
+ #ifdef CONFIG_XEN
+ #include <xen/interface/xen.h>
+@@ -108,9 +107,4 @@ static void __used common(void)
+ 	OFFSET(TSS_sp0, tss_struct, x86_tss.sp0);
+ 	OFFSET(TSS_sp1, tss_struct, x86_tss.sp1);
+ 	OFFSET(TSS_sp2, tss_struct, x86_tss.sp2);
+-
+-	if (IS_ENABLED(CONFIG_KVM_INTEL)) {
+-		BLANK();
+-		OFFSET(VMX_spec_ctrl, vcpu_vmx, spec_ctrl);
+-	}
+ }
+diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
+index 48276c0e479d8..500b1f9862b13 100644
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -770,8 +770,6 @@ static void init_amd_gh(struct cpuinfo_x86 *c)
+ 		set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH);
+ }
+ 
+-#define MSR_AMD64_DE_CFG	0xC0011029
+-
+ static void init_amd_ln(struct cpuinfo_x86 *c)
+ {
+ 	/*
+@@ -965,8 +963,8 @@ static void init_amd(struct cpuinfo_x86 *c)
+ 		 * msr_set_bit() uses the safe accessors, too, even if the MSR
+ 		 * is not present.
+ 		 */
+-		msr_set_bit(MSR_F10H_DECFG,
+-			    MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT);
++		msr_set_bit(MSR_AMD64_DE_CFG,
++			    MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT);
+ 
+ 		/* A serializing LFENCE stops RDTSC speculation */
+ 		set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
+diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c
+index 21fd425088fe5..c393b8773ace6 100644
+--- a/arch/x86/kernel/cpu/hygon.c
++++ b/arch/x86/kernel/cpu/hygon.c
+@@ -326,8 +326,8 @@ static void init_hygon(struct cpuinfo_x86 *c)
+ 		 * msr_set_bit() uses the safe accessors, too, even if the MSR
+ 		 * is not present.
+ 		 */
+-		msr_set_bit(MSR_F10H_DECFG,
+-			    MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT);
++		msr_set_bit(MSR_AMD64_DE_CFG,
++			    MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT);
+ 
+ 		/* A serializing LFENCE stops RDTSC speculation */
+ 		set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
+diff --git a/arch/x86/kvm/.gitignore b/arch/x86/kvm/.gitignore
+new file mode 100644
+index 0000000000000..615d6ff35c009
+--- /dev/null
++++ b/arch/x86/kvm/.gitignore
+@@ -0,0 +1,2 @@
++/kvm-asm-offsets.s
++/kvm-asm-offsets.h
+diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
+index 30f244b645234..f453a0f96e243 100644
+--- a/arch/x86/kvm/Makefile
++++ b/arch/x86/kvm/Makefile
+@@ -34,3 +34,15 @@ endif
+ obj-$(CONFIG_KVM)	+= kvm.o
+ obj-$(CONFIG_KVM_INTEL)	+= kvm-intel.o
+ obj-$(CONFIG_KVM_AMD)	+= kvm-amd.o
++
++AFLAGS_svm/vmenter.o    := -iquote $(obj)
++$(obj)/svm/vmenter.o: $(obj)/kvm-asm-offsets.h
++
++AFLAGS_vmx/vmenter.o    := -iquote $(obj)
++$(obj)/vmx/vmenter.o: $(obj)/kvm-asm-offsets.h
++
++$(obj)/kvm-asm-offsets.h: $(obj)/kvm-asm-offsets.s FORCE
++	$(call filechk,offsets,__KVM_ASM_OFFSETS_H__)
++
++targets += kvm-asm-offsets.s
++clean-files += kvm-asm-offsets.h
+diff --git a/arch/x86/kvm/kvm-asm-offsets.c b/arch/x86/kvm/kvm-asm-offsets.c
+new file mode 100644
+index 0000000000000..f83e88b85bf21
+--- /dev/null
++++ b/arch/x86/kvm/kvm-asm-offsets.c
+@@ -0,0 +1,27 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Generate definitions needed by assembly language modules.
++ * This code generates raw asm output which is post-processed to extract
++ * and format the required data.
++ */
++#define COMPILE_OFFSETS
++
++#include <linux/kbuild.h>
++#include "vmx/vmx.h"
++#include "svm/svm.h"
++
++static void __used common(void)
++{
++	if (IS_ENABLED(CONFIG_KVM_AMD)) {
++		BLANK();
++		OFFSET(SVM_vcpu_arch_regs, vcpu_svm, vcpu.arch.regs);
++		OFFSET(SVM_current_vmcb, vcpu_svm, current_vmcb);
++		OFFSET(SVM_vmcb01, vcpu_svm, vmcb01);
++		OFFSET(KVM_VMCB_pa, kvm_vmcb_info, pa);
++	}
++
++	if (IS_ENABLED(CONFIG_KVM_INTEL)) {
++		BLANK();
++		OFFSET(VMX_spec_ctrl, vcpu_vmx, spec_ctrl);
++	}
++}
+diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
+index 3552e6af36844..83e30e4db2ae0 100644
+--- a/arch/x86/kvm/mmu/mmu.c
++++ b/arch/x86/kvm/mmu/mmu.c
+@@ -6044,7 +6044,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end)
+ 
+ 	write_lock(&kvm->mmu_lock);
+ 
+-	kvm_mmu_invalidate_begin(kvm, gfn_start, gfn_end);
++	kvm_mmu_invalidate_begin(kvm, 0, -1ul);
+ 
+ 	flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end);
+ 
+@@ -6058,7 +6058,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end)
+ 		kvm_flush_remote_tlbs_with_address(kvm, gfn_start,
+ 						   gfn_end - gfn_start);
+ 
+-	kvm_mmu_invalidate_end(kvm, gfn_start, gfn_end);
++	kvm_mmu_invalidate_end(kvm, 0, -1ul);
+ 
+ 	write_unlock(&kvm->mmu_lock);
+ }
+diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
+index 28064060413ac..c9c9bd453a97d 100644
+--- a/arch/x86/kvm/svm/sev.c
++++ b/arch/x86/kvm/svm/sev.c
+@@ -605,7 +605,7 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm)
+ 	save->dr6  = svm->vcpu.arch.dr6;
+ 
+ 	pr_debug("Virtual Machine Save Area (VMSA):\n");
+-	print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, save, sizeof(*save), false);
++	print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, save, sizeof(*save), false);
+ 
+ 	return 0;
+ }
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index f3813dbacb9f1..454746641a483 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -2711,9 +2711,9 @@ static int svm_get_msr_feature(struct kvm_msr_entry *msr)
+ 	msr->data = 0;
+ 
+ 	switch (msr->index) {
+-	case MSR_F10H_DECFG:
+-		if (boot_cpu_has(X86_FEATURE_LFENCE_RDTSC))
+-			msr->data |= MSR_F10H_DECFG_LFENCE_SERIALIZE;
++	case MSR_AMD64_DE_CFG:
++		if (cpu_feature_enabled(X86_FEATURE_LFENCE_RDTSC))
++			msr->data |= MSR_AMD64_DE_CFG_LFENCE_SERIALIZE;
+ 		break;
+ 	case MSR_IA32_PERF_CAPABILITIES:
+ 		return 0;
+@@ -2814,7 +2814,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ 			msr_info->data = 0x1E;
+ 		}
+ 		break;
+-	case MSR_F10H_DECFG:
++	case MSR_AMD64_DE_CFG:
+ 		msr_info->data = svm->msr_decfg;
+ 		break;
+ 	default:
+@@ -3043,7 +3043,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
+ 	case MSR_VM_IGNNE:
+ 		vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data);
+ 		break;
+-	case MSR_F10H_DECFG: {
++	case MSR_AMD64_DE_CFG: {
+ 		struct kvm_msr_entry msr_entry;
+ 
+ 		msr_entry.index = msr->index;
+@@ -3915,25 +3915,15 @@ static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
+ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu)
+ {
+ 	struct vcpu_svm *svm = to_svm(vcpu);
+-	unsigned long vmcb_pa = svm->current_vmcb->pa;
+ 
+ 	guest_state_enter_irqoff();
+ 
+ 	if (sev_es_guest(vcpu->kvm)) {
+-		__svm_sev_es_vcpu_run(vmcb_pa);
++		__svm_sev_es_vcpu_run(svm);
+ 	} else {
+ 		struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu);
+ 
+-		/*
+-		 * Use a single vmcb (vmcb01 because it's always valid) for
+-		 * context switching guest state via VMLOAD/VMSAVE, that way
+-		 * the state doesn't need to be copied between vmcb01 and
+-		 * vmcb02 when switching vmcbs for nested virtualization.
+-		 */
+-		vmload(svm->vmcb01.pa);
+-		__svm_vcpu_run(vmcb_pa, (unsigned long *)&vcpu->arch.regs);
+-		vmsave(svm->vmcb01.pa);
+-
++		__svm_vcpu_run(svm);
+ 		vmload(__sme_page_pa(sd->save_area));
+ 	}
+ 
+diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
+index 6a7686bf69000..7ff1879e73c56 100644
+--- a/arch/x86/kvm/svm/svm.h
++++ b/arch/x86/kvm/svm/svm.h
+@@ -683,7 +683,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm);
+ 
+ /* vmenter.S */
+ 
+-void __svm_sev_es_vcpu_run(unsigned long vmcb_pa);
+-void __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs);
++void __svm_sev_es_vcpu_run(struct vcpu_svm *svm);
++void __svm_vcpu_run(struct vcpu_svm *svm);
+ 
+ #endif
+diff --git a/arch/x86/kvm/svm/vmenter.S b/arch/x86/kvm/svm/vmenter.S
+index 723f8534986c3..5bc2ed7d79c07 100644
+--- a/arch/x86/kvm/svm/vmenter.S
++++ b/arch/x86/kvm/svm/vmenter.S
+@@ -4,35 +4,37 @@
+ #include <asm/bitsperlong.h>
+ #include <asm/kvm_vcpu_regs.h>
+ #include <asm/nospec-branch.h>
++#include "kvm-asm-offsets.h"
+ 
+ #define WORD_SIZE (BITS_PER_LONG / 8)
+ 
+ /* Intentionally omit RAX as it's context switched by hardware */
+-#define VCPU_RCX	__VCPU_REGS_RCX * WORD_SIZE
+-#define VCPU_RDX	__VCPU_REGS_RDX * WORD_SIZE
+-#define VCPU_RBX	__VCPU_REGS_RBX * WORD_SIZE
++#define VCPU_RCX	(SVM_vcpu_arch_regs + __VCPU_REGS_RCX * WORD_SIZE)
++#define VCPU_RDX	(SVM_vcpu_arch_regs + __VCPU_REGS_RDX * WORD_SIZE)
++#define VCPU_RBX	(SVM_vcpu_arch_regs + __VCPU_REGS_RBX * WORD_SIZE)
+ /* Intentionally omit RSP as it's context switched by hardware */
+-#define VCPU_RBP	__VCPU_REGS_RBP * WORD_SIZE
+-#define VCPU_RSI	__VCPU_REGS_RSI * WORD_SIZE
+-#define VCPU_RDI	__VCPU_REGS_RDI * WORD_SIZE
++#define VCPU_RBP	(SVM_vcpu_arch_regs + __VCPU_REGS_RBP * WORD_SIZE)
++#define VCPU_RSI	(SVM_vcpu_arch_regs + __VCPU_REGS_RSI * WORD_SIZE)
++#define VCPU_RDI	(SVM_vcpu_arch_regs + __VCPU_REGS_RDI * WORD_SIZE)
+ 
+ #ifdef CONFIG_X86_64
+-#define VCPU_R8		__VCPU_REGS_R8  * WORD_SIZE
+-#define VCPU_R9		__VCPU_REGS_R9  * WORD_SIZE
+-#define VCPU_R10	__VCPU_REGS_R10 * WORD_SIZE
+-#define VCPU_R11	__VCPU_REGS_R11 * WORD_SIZE
+-#define VCPU_R12	__VCPU_REGS_R12 * WORD_SIZE
+-#define VCPU_R13	__VCPU_REGS_R13 * WORD_SIZE
+-#define VCPU_R14	__VCPU_REGS_R14 * WORD_SIZE
+-#define VCPU_R15	__VCPU_REGS_R15 * WORD_SIZE
++#define VCPU_R8		(SVM_vcpu_arch_regs + __VCPU_REGS_R8  * WORD_SIZE)
++#define VCPU_R9		(SVM_vcpu_arch_regs + __VCPU_REGS_R9  * WORD_SIZE)
++#define VCPU_R10	(SVM_vcpu_arch_regs + __VCPU_REGS_R10 * WORD_SIZE)
++#define VCPU_R11	(SVM_vcpu_arch_regs + __VCPU_REGS_R11 * WORD_SIZE)
++#define VCPU_R12	(SVM_vcpu_arch_regs + __VCPU_REGS_R12 * WORD_SIZE)
++#define VCPU_R13	(SVM_vcpu_arch_regs + __VCPU_REGS_R13 * WORD_SIZE)
++#define VCPU_R14	(SVM_vcpu_arch_regs + __VCPU_REGS_R14 * WORD_SIZE)
++#define VCPU_R15	(SVM_vcpu_arch_regs + __VCPU_REGS_R15 * WORD_SIZE)
+ #endif
+ 
++#define SVM_vmcb01_pa	(SVM_vmcb01 + KVM_VMCB_pa)
++
+ .section .noinstr.text, "ax"
+ 
+ /**
+  * __svm_vcpu_run - Run a vCPU via a transition to SVM guest mode
+- * @vmcb_pa:	unsigned long
+- * @regs:	unsigned long * (to guest registers)
++ * @svm:	struct vcpu_svm *
+  */
+ SYM_FUNC_START(__svm_vcpu_run)
+ 	push %_ASM_BP
+@@ -47,49 +49,54 @@ SYM_FUNC_START(__svm_vcpu_run)
+ #endif
+ 	push %_ASM_BX
+ 
+-	/* Save @regs. */
+-	push %_ASM_ARG2
+-
+-	/* Save @vmcb. */
++	/* Save @svm. */
+ 	push %_ASM_ARG1
+ 
+-	/* Move @regs to RAX. */
+-	mov %_ASM_ARG2, %_ASM_AX
++.ifnc _ASM_ARG1, _ASM_DI
++	/* Move @svm to RDI. */
++	mov %_ASM_ARG1, %_ASM_DI
++.endif
++
++	/*
++	 * Use a single vmcb (vmcb01 because it's always valid) for
++	 * context switching guest state via VMLOAD/VMSAVE, that way
++	 * the state doesn't need to be copied between vmcb01 and
++	 * vmcb02 when switching vmcbs for nested virtualization.
++	 */
++	mov SVM_vmcb01_pa(%_ASM_DI), %_ASM_AX
++1:	vmload %_ASM_AX
++2:
++
++	/* Get svm->current_vmcb->pa into RAX. */
++	mov SVM_current_vmcb(%_ASM_DI), %_ASM_AX
++	mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX
+ 
+ 	/* Load guest registers. */
+-	mov VCPU_RCX(%_ASM_AX), %_ASM_CX
+-	mov VCPU_RDX(%_ASM_AX), %_ASM_DX
+-	mov VCPU_RBX(%_ASM_AX), %_ASM_BX
+-	mov VCPU_RBP(%_ASM_AX), %_ASM_BP
+-	mov VCPU_RSI(%_ASM_AX), %_ASM_SI
+-	mov VCPU_RDI(%_ASM_AX), %_ASM_DI
++	mov VCPU_RCX(%_ASM_DI), %_ASM_CX
++	mov VCPU_RDX(%_ASM_DI), %_ASM_DX
++	mov VCPU_RBX(%_ASM_DI), %_ASM_BX
++	mov VCPU_RBP(%_ASM_DI), %_ASM_BP
++	mov VCPU_RSI(%_ASM_DI), %_ASM_SI
+ #ifdef CONFIG_X86_64
+-	mov VCPU_R8 (%_ASM_AX),  %r8
+-	mov VCPU_R9 (%_ASM_AX),  %r9
+-	mov VCPU_R10(%_ASM_AX), %r10
+-	mov VCPU_R11(%_ASM_AX), %r11
+-	mov VCPU_R12(%_ASM_AX), %r12
+-	mov VCPU_R13(%_ASM_AX), %r13
+-	mov VCPU_R14(%_ASM_AX), %r14
+-	mov VCPU_R15(%_ASM_AX), %r15
++	mov VCPU_R8 (%_ASM_DI),  %r8
++	mov VCPU_R9 (%_ASM_DI),  %r9
++	mov VCPU_R10(%_ASM_DI), %r10
++	mov VCPU_R11(%_ASM_DI), %r11
++	mov VCPU_R12(%_ASM_DI), %r12
++	mov VCPU_R13(%_ASM_DI), %r13
++	mov VCPU_R14(%_ASM_DI), %r14
++	mov VCPU_R15(%_ASM_DI), %r15
+ #endif
+-
+-	/* "POP" @vmcb to RAX. */
+-	pop %_ASM_AX
++	mov VCPU_RDI(%_ASM_DI), %_ASM_DI
+ 
+ 	/* Enter guest mode */
+ 	sti
+ 
+-1:	vmrun %_ASM_AX
+-
+-2:	cli
++3:	vmrun %_ASM_AX
++4:
++	cli
+ 
+-#ifdef CONFIG_RETPOLINE
+-	/* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
+-	FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
+-#endif
+-
+-	/* "POP" @regs to RAX. */
++	/* Pop @svm to RAX while it's the only available register. */
+ 	pop %_ASM_AX
+ 
+ 	/* Save all guest registers.  */
+@@ -110,6 +117,18 @@ SYM_FUNC_START(__svm_vcpu_run)
+ 	mov %r15, VCPU_R15(%_ASM_AX)
+ #endif
+ 
++	/* @svm can stay in RDI from now on.  */
++	mov %_ASM_AX, %_ASM_DI
++
++	mov SVM_vmcb01_pa(%_ASM_DI), %_ASM_AX
++5:	vmsave %_ASM_AX
++6:
++
++#ifdef CONFIG_RETPOLINE
++	/* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
++	FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
++#endif
++
+ 	/*
+ 	 * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be
+ 	 * untrained as soon as we exit the VM and are back to the
+@@ -159,17 +178,25 @@ SYM_FUNC_START(__svm_vcpu_run)
+ 	pop %_ASM_BP
+ 	RET
+ 
+-3:	cmpb $0, kvm_rebooting
++10:	cmpb $0, kvm_rebooting
+ 	jne 2b
+ 	ud2
++30:	cmpb $0, kvm_rebooting
++	jne 4b
++	ud2
++50:	cmpb $0, kvm_rebooting
++	jne 6b
++	ud2
+ 
+-	_ASM_EXTABLE(1b, 3b)
++	_ASM_EXTABLE(1b, 10b)
++	_ASM_EXTABLE(3b, 30b)
++	_ASM_EXTABLE(5b, 50b)
+ 
+ SYM_FUNC_END(__svm_vcpu_run)
+ 
+ /**
+  * __svm_sev_es_vcpu_run - Run a SEV-ES vCPU via a transition to SVM guest mode
+- * @vmcb_pa:	unsigned long
++ * @svm:	struct vcpu_svm *
+  */
+ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ 	push %_ASM_BP
+@@ -184,8 +211,9 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run)
+ #endif
+ 	push %_ASM_BX
+ 
+-	/* Move @vmcb to RAX. */
+-	mov %_ASM_ARG1, %_ASM_AX
++	/* Get svm->current_vmcb->pa into RAX. */
++	mov SVM_current_vmcb(%_ASM_ARG1), %_ASM_AX
++	mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX
+ 
+ 	/* Enter guest mode */
+ 	sti
+diff --git a/arch/x86/kvm/vmx/vmenter.S b/arch/x86/kvm/vmx/vmenter.S
+index 6de96b9438044..660165065dfe8 100644
+--- a/arch/x86/kvm/vmx/vmenter.S
++++ b/arch/x86/kvm/vmx/vmenter.S
+@@ -1,12 +1,12 @@
+ /* SPDX-License-Identifier: GPL-2.0 */
+ #include <linux/linkage.h>
+ #include <asm/asm.h>
+-#include <asm/asm-offsets.h>
+ #include <asm/bitsperlong.h>
+ #include <asm/kvm_vcpu_regs.h>
+ #include <asm/nospec-branch.h>
+ #include <asm/percpu.h>
+ #include <asm/segment.h>
++#include "kvm-asm-offsets.h"
+ #include "run_flags.h"
+ 
+ #define WORD_SIZE (BITS_PER_LONG / 8)
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 05f4424eb0c52..71cbafd67319b 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -1431,20 +1431,10 @@ static const u32 msrs_to_save_all[] = {
+ 	MSR_ARCH_PERFMON_PERFCTR0 + 2, MSR_ARCH_PERFMON_PERFCTR0 + 3,
+ 	MSR_ARCH_PERFMON_PERFCTR0 + 4, MSR_ARCH_PERFMON_PERFCTR0 + 5,
+ 	MSR_ARCH_PERFMON_PERFCTR0 + 6, MSR_ARCH_PERFMON_PERFCTR0 + 7,
+-	MSR_ARCH_PERFMON_PERFCTR0 + 8, MSR_ARCH_PERFMON_PERFCTR0 + 9,
+-	MSR_ARCH_PERFMON_PERFCTR0 + 10, MSR_ARCH_PERFMON_PERFCTR0 + 11,
+-	MSR_ARCH_PERFMON_PERFCTR0 + 12, MSR_ARCH_PERFMON_PERFCTR0 + 13,
+-	MSR_ARCH_PERFMON_PERFCTR0 + 14, MSR_ARCH_PERFMON_PERFCTR0 + 15,
+-	MSR_ARCH_PERFMON_PERFCTR0 + 16, MSR_ARCH_PERFMON_PERFCTR0 + 17,
+ 	MSR_ARCH_PERFMON_EVENTSEL0, MSR_ARCH_PERFMON_EVENTSEL1,
+ 	MSR_ARCH_PERFMON_EVENTSEL0 + 2, MSR_ARCH_PERFMON_EVENTSEL0 + 3,
+ 	MSR_ARCH_PERFMON_EVENTSEL0 + 4, MSR_ARCH_PERFMON_EVENTSEL0 + 5,
+ 	MSR_ARCH_PERFMON_EVENTSEL0 + 6, MSR_ARCH_PERFMON_EVENTSEL0 + 7,
+-	MSR_ARCH_PERFMON_EVENTSEL0 + 8, MSR_ARCH_PERFMON_EVENTSEL0 + 9,
+-	MSR_ARCH_PERFMON_EVENTSEL0 + 10, MSR_ARCH_PERFMON_EVENTSEL0 + 11,
+-	MSR_ARCH_PERFMON_EVENTSEL0 + 12, MSR_ARCH_PERFMON_EVENTSEL0 + 13,
+-	MSR_ARCH_PERFMON_EVENTSEL0 + 14, MSR_ARCH_PERFMON_EVENTSEL0 + 15,
+-	MSR_ARCH_PERFMON_EVENTSEL0 + 16, MSR_ARCH_PERFMON_EVENTSEL0 + 17,
+ 	MSR_IA32_PEBS_ENABLE, MSR_IA32_DS_AREA, MSR_PEBS_DATA_CFG,
+ 
+ 	MSR_K7_EVNTSEL0, MSR_K7_EVNTSEL1, MSR_K7_EVNTSEL2, MSR_K7_EVNTSEL3,
+@@ -1551,7 +1541,7 @@ static const u32 msr_based_features_all[] = {
+ 	MSR_IA32_VMX_EPT_VPID_CAP,
+ 	MSR_IA32_VMX_VMFUNC,
+ 
+-	MSR_F10H_DECFG,
++	MSR_AMD64_DE_CFG,
+ 	MSR_IA32_UCODE_REV,
+ 	MSR_IA32_ARCH_CAPABILITIES,
+ 	MSR_IA32_PERF_CAPABILITIES,
+@@ -7005,12 +6995,12 @@ static void kvm_init_msr_list(void)
+ 				intel_pt_validate_hw_cap(PT_CAP_num_address_ranges) * 2)
+ 				continue;
+ 			break;
+-		case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR0 + 17:
++		case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR0 + 7:
+ 			if (msrs_to_save_all[i] - MSR_ARCH_PERFMON_PERFCTR0 >=
+ 			    min(INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp))
+ 				continue;
+ 			break;
+-		case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL0 + 17:
++		case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL0 + 7:
+ 			if (msrs_to_save_all[i] - MSR_ARCH_PERFMON_EVENTSEL0 >=
+ 			    min(INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp))
+ 				continue;
+diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
+index 6b3033845c6d3..5804bbae4f012 100644
+--- a/arch/x86/mm/hugetlbpage.c
++++ b/arch/x86/mm/hugetlbpage.c
+@@ -37,8 +37,12 @@ int pmd_huge(pmd_t pmd)
+  */
+ int pud_huge(pud_t pud)
+ {
++#if CONFIG_PGTABLE_LEVELS > 2
+ 	return !pud_none(pud) &&
+ 		(pud_val(pud) & (_PAGE_PRESENT|_PAGE_PSE)) != _PAGE_PRESENT;
++#else
++	return 0;
++#endif
+ }
+ 
+ #ifdef CONFIG_HUGETLB_PAGE
+diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
+index bb176c72891c9..4cd39f304e206 100644
+--- a/arch/x86/power/cpu.c
++++ b/arch/x86/power/cpu.c
+@@ -519,6 +519,7 @@ static void pm_save_spec_msr(void)
+ 		MSR_TSX_FORCE_ABORT,
+ 		MSR_IA32_MCU_OPT_CTRL,
+ 		MSR_AMD64_LS_CFG,
++		MSR_AMD64_DE_CFG,
+ 	};
+ 
+ 	msr_build_context(spec_msr_id, ARRAY_SIZE(spec_msr_id));
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index ff9602a0e54ef..b0e442a75690a 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -3266,6 +3266,7 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf)
+ 	case REPORT_LUNS:
+ 	case REQUEST_SENSE:
+ 	case SYNCHRONIZE_CACHE:
++	case SYNCHRONIZE_CACHE_16:
+ 	case REZERO_UNIT:
+ 	case SEEK_6:
+ 	case SEEK_10:
+@@ -3924,6 +3925,7 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
+ 		return ata_scsi_write_same_xlat;
+ 
+ 	case SYNCHRONIZE_CACHE:
++	case SYNCHRONIZE_CACHE_16:
+ 		if (ata_try_flush_cache(dev))
+ 			return ata_scsi_flush_xlat;
+ 		break;
+@@ -4147,6 +4149,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
+ 	 * turning this into a no-op.
+ 	 */
+ 	case SYNCHRONIZE_CACHE:
++	case SYNCHRONIZE_CACHE_16:
+ 		fallthrough;
+ 
+ 	/* no-op's, complete with success */
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index 6b7fb955a05ac..78344e4d4215b 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -1533,9 +1533,24 @@ static const struct attribute_group *region_groups[] = {
+ 
+ static void cxl_region_release(struct device *dev)
+ {
++	struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev->parent);
+ 	struct cxl_region *cxlr = to_cxl_region(dev);
++	int id = atomic_read(&cxlrd->region_id);
++
++	/*
++	 * Try to reuse the recently idled id rather than the cached
++	 * next id to prevent the region id space from increasing
++	 * unnecessarily.
++	 */
++	if (cxlr->id < id)
++		if (atomic_try_cmpxchg(&cxlrd->region_id, &id, cxlr->id)) {
++			memregion_free(id);
++			goto out;
++		}
+ 
+ 	memregion_free(cxlr->id);
++out:
++	put_device(dev->parent);
+ 	kfree(cxlr);
+ }
+ 
+@@ -1597,6 +1612,11 @@ static struct cxl_region *cxl_region_alloc(struct cxl_root_decoder *cxlrd, int i
+ 	device_initialize(dev);
+ 	lockdep_set_class(&dev->mutex, &cxl_region_key);
+ 	dev->parent = &cxlrd->cxlsd.cxld.dev;
++	/*
++	 * Keep root decoder pinned through cxl_region_release to fixup
++	 * region id allocations
++	 */
++	get_device(dev->parent);
+ 	device_set_pm_not_required(dev);
+ 	dev->bus = &cxl_bus_type;
+ 	dev->type = &cxl_region_type;
+diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c
+index d1f74a3aa999d..6780761a16403 100644
+--- a/drivers/dma/apple-admac.c
++++ b/drivers/dma/apple-admac.c
+@@ -490,7 +490,7 @@ static struct dma_chan *admac_dma_of_xlate(struct of_phandle_args *dma_spec,
+ 		return NULL;
+ 	}
+ 
+-	return &ad->channels[index].chan;
++	return dma_get_slave_channel(&ad->channels[index].chan);
+ }
+ 
+ static int admac_drain_reports(struct admac_data *ad, int channo)
+diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
+index 5a50423b7378e..858bd64f13135 100644
+--- a/drivers/dma/at_hdmac.c
++++ b/drivers/dma/at_hdmac.c
+@@ -256,6 +256,8 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first)
+ 		       ATC_SPIP_BOUNDARY(first->boundary));
+ 	channel_writel(atchan, DPIP, ATC_DPIP_HOLE(first->dst_hole) |
+ 		       ATC_DPIP_BOUNDARY(first->boundary));
++	/* Don't allow CPU to reorder channel enable. */
++	wmb();
+ 	dma_writel(atdma, CHER, atchan->mask);
+ 
+ 	vdbg_dump_regs(atchan);
+@@ -316,7 +318,8 @@ static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
+ 	struct at_desc *desc_first = atc_first_active(atchan);
+ 	struct at_desc *desc;
+ 	int ret;
+-	u32 ctrla, dscr, trials;
++	u32 ctrla, dscr;
++	unsigned int i;
+ 
+ 	/*
+ 	 * If the cookie doesn't match to the currently running transfer then
+@@ -386,7 +389,7 @@ static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
+ 		dscr = channel_readl(atchan, DSCR);
+ 		rmb(); /* ensure DSCR is read before CTRLA */
+ 		ctrla = channel_readl(atchan, CTRLA);
+-		for (trials = 0; trials < ATC_MAX_DSCR_TRIALS; ++trials) {
++		for (i = 0; i < ATC_MAX_DSCR_TRIALS; ++i) {
+ 			u32 new_dscr;
+ 
+ 			rmb(); /* ensure DSCR is read after CTRLA */
+@@ -412,7 +415,7 @@ static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
+ 			rmb(); /* ensure DSCR is read before CTRLA */
+ 			ctrla = channel_readl(atchan, CTRLA);
+ 		}
+-		if (unlikely(trials >= ATC_MAX_DSCR_TRIALS))
++		if (unlikely(i == ATC_MAX_DSCR_TRIALS))
+ 			return -ETIMEDOUT;
+ 
+ 		/* for the first descriptor we can be more accurate */
+@@ -462,18 +465,6 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
+ 	if (!atc_chan_is_cyclic(atchan))
+ 		dma_cookie_complete(txd);
+ 
+-	/* If the transfer was a memset, free our temporary buffer */
+-	if (desc->memset_buffer) {
+-		dma_pool_free(atdma->memset_pool, desc->memset_vaddr,
+-			      desc->memset_paddr);
+-		desc->memset_buffer = false;
+-	}
+-
+-	/* move children to free_list */
+-	list_splice_init(&desc->tx_list, &atchan->free_list);
+-	/* move myself to free_list */
+-	list_move(&desc->desc_node, &atchan->free_list);
+-
+ 	spin_unlock_irqrestore(&atchan->lock, flags);
+ 
+ 	dma_descriptor_unmap(txd);
+@@ -483,42 +474,20 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
+ 		dmaengine_desc_get_callback_invoke(txd, NULL);
+ 
+ 	dma_run_dependencies(txd);
+-}
+-
+-/**
+- * atc_complete_all - finish work for all transactions
+- * @atchan: channel to complete transactions for
+- *
+- * Eventually submit queued descriptors if any
+- *
+- * Assume channel is idle while calling this function
+- * Called with atchan->lock held and bh disabled
+- */
+-static void atc_complete_all(struct at_dma_chan *atchan)
+-{
+-	struct at_desc *desc, *_desc;
+-	LIST_HEAD(list);
+-	unsigned long flags;
+-
+-	dev_vdbg(chan2dev(&atchan->chan_common), "complete all\n");
+ 
+ 	spin_lock_irqsave(&atchan->lock, flags);
+-
+-	/*
+-	 * Submit queued descriptors ASAP, i.e. before we go through
+-	 * the completed ones.
+-	 */
+-	if (!list_empty(&atchan->queue))
+-		atc_dostart(atchan, atc_first_queued(atchan));
+-	/* empty active_list now it is completed */
+-	list_splice_init(&atchan->active_list, &list);
+-	/* empty queue list by moving descriptors (if any) to active_list */
+-	list_splice_init(&atchan->queue, &atchan->active_list);
+-
++	/* move children to free_list */
++	list_splice_init(&desc->tx_list, &atchan->free_list);
++	/* add myself to free_list */
++	list_add(&desc->desc_node, &atchan->free_list);
+ 	spin_unlock_irqrestore(&atchan->lock, flags);
+ 
+-	list_for_each_entry_safe(desc, _desc, &list, desc_node)
+-		atc_chain_complete(atchan, desc);
++	/* If the transfer was a memset, free our temporary buffer */
++	if (desc->memset_buffer) {
++		dma_pool_free(atdma->memset_pool, desc->memset_vaddr,
++			      desc->memset_paddr);
++		desc->memset_buffer = false;
++	}
+ }
+ 
+ /**
+@@ -527,26 +496,28 @@ static void atc_complete_all(struct at_dma_chan *atchan)
+  */
+ static void atc_advance_work(struct at_dma_chan *atchan)
+ {
++	struct at_desc *desc;
+ 	unsigned long flags;
+-	int ret;
+ 
+ 	dev_vdbg(chan2dev(&atchan->chan_common), "advance_work\n");
+ 
+ 	spin_lock_irqsave(&atchan->lock, flags);
+-	ret = atc_chan_is_enabled(atchan);
+-	spin_unlock_irqrestore(&atchan->lock, flags);
+-	if (ret)
+-		return;
+-
+-	if (list_empty(&atchan->active_list) ||
+-	    list_is_singular(&atchan->active_list))
+-		return atc_complete_all(atchan);
++	if (atc_chan_is_enabled(atchan) || list_empty(&atchan->active_list))
++		return spin_unlock_irqrestore(&atchan->lock, flags);
+ 
+-	atc_chain_complete(atchan, atc_first_active(atchan));
++	desc = atc_first_active(atchan);
++	/* Remove the transfer node from the active list. */
++	list_del_init(&desc->desc_node);
++	spin_unlock_irqrestore(&atchan->lock, flags);
++	atc_chain_complete(atchan, desc);
+ 
+ 	/* advance work */
+ 	spin_lock_irqsave(&atchan->lock, flags);
+-	atc_dostart(atchan, atc_first_active(atchan));
++	if (!list_empty(&atchan->active_list)) {
++		desc = atc_first_queued(atchan);
++		list_move_tail(&desc->desc_node, &atchan->active_list);
++		atc_dostart(atchan, desc);
++	}
+ 	spin_unlock_irqrestore(&atchan->lock, flags);
+ }
+ 
+@@ -558,6 +529,7 @@ static void atc_advance_work(struct at_dma_chan *atchan)
+ static void atc_handle_error(struct at_dma_chan *atchan)
+ {
+ 	struct at_desc *bad_desc;
++	struct at_desc *desc;
+ 	struct at_desc *child;
+ 	unsigned long flags;
+ 
+@@ -570,13 +542,12 @@ static void atc_handle_error(struct at_dma_chan *atchan)
+ 	bad_desc = atc_first_active(atchan);
+ 	list_del_init(&bad_desc->desc_node);
+ 
+-	/* As we are stopped, take advantage to push queued descriptors
+-	 * in active_list */
+-	list_splice_init(&atchan->queue, atchan->active_list.prev);
+-
+ 	/* Try to restart the controller */
+-	if (!list_empty(&atchan->active_list))
+-		atc_dostart(atchan, atc_first_active(atchan));
++	if (!list_empty(&atchan->active_list)) {
++		desc = atc_first_queued(atchan);
++		list_move_tail(&desc->desc_node, &atchan->active_list);
++		atc_dostart(atchan, desc);
++	}
+ 
+ 	/*
+ 	 * KERN_CRITICAL may seem harsh, but since this only happens
+@@ -691,19 +662,11 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx)
+ 	spin_lock_irqsave(&atchan->lock, flags);
+ 	cookie = dma_cookie_assign(tx);
+ 
+-	if (list_empty(&atchan->active_list)) {
+-		dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n",
+-				desc->txd.cookie);
+-		atc_dostart(atchan, desc);
+-		list_add_tail(&desc->desc_node, &atchan->active_list);
+-	} else {
+-		dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n",
+-				desc->txd.cookie);
+-		list_add_tail(&desc->desc_node, &atchan->queue);
+-	}
+-
++	list_add_tail(&desc->desc_node, &atchan->queue);
+ 	spin_unlock_irqrestore(&atchan->lock, flags);
+ 
++	dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n",
++		 desc->txd.cookie);
+ 	return cookie;
+ }
+ 
+@@ -1445,11 +1408,8 @@ static int atc_terminate_all(struct dma_chan *chan)
+ 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
+ 	struct at_dma		*atdma = to_at_dma(chan->device);
+ 	int			chan_id = atchan->chan_common.chan_id;
+-	struct at_desc		*desc, *_desc;
+ 	unsigned long		flags;
+ 
+-	LIST_HEAD(list);
+-
+ 	dev_vdbg(chan2dev(chan), "%s\n", __func__);
+ 
+ 	/*
+@@ -1468,19 +1428,15 @@ static int atc_terminate_all(struct dma_chan *chan)
+ 		cpu_relax();
+ 
+ 	/* active_list entries will end up before queued entries */
+-	list_splice_init(&atchan->queue, &list);
+-	list_splice_init(&atchan->active_list, &list);
+-
+-	spin_unlock_irqrestore(&atchan->lock, flags);
+-
+-	/* Flush all pending and queued descriptors */
+-	list_for_each_entry_safe(desc, _desc, &list, desc_node)
+-		atc_chain_complete(atchan, desc);
++	list_splice_tail_init(&atchan->queue, &atchan->free_list);
++	list_splice_tail_init(&atchan->active_list, &atchan->free_list);
+ 
+ 	clear_bit(ATC_IS_PAUSED, &atchan->status);
+ 	/* if channel dedicated to cyclic operations, free it */
+ 	clear_bit(ATC_IS_CYCLIC, &atchan->status);
+ 
++	spin_unlock_irqrestore(&atchan->lock, flags);
++
+ 	return 0;
+ }
+ 
+@@ -1535,20 +1491,26 @@ atc_tx_status(struct dma_chan *chan,
+ }
+ 
+ /**
+- * atc_issue_pending - try to finish work
++ * atc_issue_pending - takes the first transaction descriptor in the pending
++ * queue and starts the transfer.
+  * @chan: target DMA channel
+  */
+ static void atc_issue_pending(struct dma_chan *chan)
+ {
+-	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
++	struct at_dma_chan *atchan = to_at_dma_chan(chan);
++	struct at_desc *desc;
++	unsigned long flags;
+ 
+ 	dev_vdbg(chan2dev(chan), "issue_pending\n");
+ 
+-	/* Not needed for cyclic transfers */
+-	if (atc_chan_is_cyclic(atchan))
+-		return;
++	spin_lock_irqsave(&atchan->lock, flags);
++	if (atc_chan_is_enabled(atchan) || list_empty(&atchan->queue))
++		return spin_unlock_irqrestore(&atchan->lock, flags);
+ 
+-	atc_advance_work(atchan);
++	desc = atc_first_queued(atchan);
++	list_move_tail(&desc->desc_node, &atchan->active_list);
++	atc_dostart(atchan, desc);
++	spin_unlock_irqrestore(&atchan->lock, flags);
+ }
+ 
+ /**
+@@ -1966,7 +1928,11 @@ static int __init at_dma_probe(struct platform_device *pdev)
+ 	  dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)  ? "slave " : "",
+ 	  plat_dat->nr_channels);
+ 
+-	dma_async_device_register(&atdma->dma_common);
++	err = dma_async_device_register(&atdma->dma_common);
++	if (err) {
++		dev_err(&pdev->dev, "Unable to register: %d.\n", err);
++		goto err_dma_async_device_register;
++	}
+ 
+ 	/*
+ 	 * Do not return an error if the dmac node is not present in order to
+@@ -1986,6 +1952,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
+ 
+ err_of_dma_controller_register:
+ 	dma_async_device_unregister(&atdma->dma_common);
++err_dma_async_device_register:
+ 	dma_pool_destroy(atdma->memset_pool);
+ err_memset_pool_create:
+ 	dma_pool_destroy(atdma->dma_desc_pool);
+diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
+index 4d1ebc040031c..d4d382d746078 100644
+--- a/drivers/dma/at_hdmac_regs.h
++++ b/drivers/dma/at_hdmac_regs.h
+@@ -186,13 +186,13 @@
+ /* LLI == Linked List Item; aka DMA buffer descriptor */
+ struct at_lli {
+ 	/* values that are not changed by hardware */
+-	dma_addr_t	saddr;
+-	dma_addr_t	daddr;
++	u32 saddr;
++	u32 daddr;
+ 	/* value that may get written back: */
+-	u32		ctrla;
++	u32 ctrla;
+ 	/* more values that are not changed by hardware */
+-	u32		ctrlb;
+-	dma_addr_t	dscr;	/* chain to next lli */
++	u32 ctrlb;
++	u32 dscr;	/* chain to next lli */
+ };
+ 
+ /**
+diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c
+index c2808fd081d65..a9b96b18772f3 100644
+--- a/drivers/dma/idxd/cdev.c
++++ b/drivers/dma/idxd/cdev.c
+@@ -312,6 +312,24 @@ static int idxd_user_drv_probe(struct idxd_dev *idxd_dev)
+ 	if (idxd->state != IDXD_DEV_ENABLED)
+ 		return -ENXIO;
+ 
++	/*
++	 * User type WQ is enabled only when SVA is enabled for two reasons:
++	 *   - If no IOMMU or IOMMU Passthrough without SVA, userspace
++	 *     can directly access physical address through the WQ.
++	 *   - The IDXD cdev driver does not provide any ways to pin
++	 *     user pages and translate the address from user VA to IOVA or
++	 *     PA without IOMMU SVA. Therefore the application has no way
++	 *     to instruct the device to perform DMA function. This makes
++	 *     the cdev not usable for normal application usage.
++	 */
++	if (!device_user_pasid_enabled(idxd)) {
++		idxd->cmd_status = IDXD_SCMD_WQ_USER_NO_IOMMU;
++		dev_dbg(&idxd->pdev->dev,
++			"User type WQ cannot be enabled without SVA.\n");
++
++		return -EOPNOTSUPP;
++	}
++
+ 	mutex_lock(&wq->wq_lock);
+ 	wq->type = IDXD_WQT_USER;
+ 	rc = drv_enable_wq(wq);
+diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
+index 5a8cc52c1abfd..bd6e50f795beb 100644
+--- a/drivers/dma/idxd/device.c
++++ b/drivers/dma/idxd/device.c
+@@ -388,7 +388,7 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq)
+ 	clear_bit(WQ_FLAG_BLOCK_ON_FAULT, &wq->flags);
+ 	memset(wq->name, 0, WQ_NAME_SIZE);
+ 	wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER;
+-	wq->max_batch_size = WQ_DEFAULT_MAX_BATCH;
++	idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH);
+ }
+ 
+ static void idxd_wq_device_reset_cleanup(struct idxd_wq *wq)
+@@ -724,13 +724,21 @@ static void idxd_device_wqs_clear_state(struct idxd_device *idxd)
+ 
+ void idxd_device_clear_state(struct idxd_device *idxd)
+ {
+-	if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
+-		return;
++	/* IDXD is always disabled. Other states are cleared only when IDXD is configurable. */
++	if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) {
++		/*
++		 * Clearing wq state is protected by wq lock.
++		 * So no need to be protected by device lock.
++		 */
++		idxd_device_wqs_clear_state(idxd);
++
++		spin_lock(&idxd->dev_lock);
++		idxd_groups_clear_state(idxd);
++		idxd_engines_clear_state(idxd);
++	} else {
++		spin_lock(&idxd->dev_lock);
++	}
+ 
+-	idxd_device_wqs_clear_state(idxd);
+-	spin_lock(&idxd->dev_lock);
+-	idxd_groups_clear_state(idxd);
+-	idxd_engines_clear_state(idxd);
+ 	idxd->state = IDXD_DEV_DISABLED;
+ 	spin_unlock(&idxd->dev_lock);
+ }
+@@ -863,7 +871,7 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
+ 
+ 	/* bytes 12-15 */
+ 	wq->wqcfg->max_xfer_shift = ilog2(wq->max_xfer_bytes);
+-	wq->wqcfg->max_batch_shift = ilog2(wq->max_batch_size);
++	idxd_wqcfg_set_max_batch_shift(idxd->data->type, wq->wqcfg, ilog2(wq->max_batch_size));
+ 
+ 	dev_dbg(dev, "WQ %d CFGs\n", wq->id);
+ 	for (i = 0; i < WQCFG_STRIDES(idxd); i++) {
+@@ -1031,7 +1039,7 @@ static int idxd_wq_load_config(struct idxd_wq *wq)
+ 	wq->priority = wq->wqcfg->priority;
+ 
+ 	wq->max_xfer_bytes = 1ULL << wq->wqcfg->max_xfer_shift;
+-	wq->max_batch_size = 1ULL << wq->wqcfg->max_batch_shift;
++	idxd_wq_set_max_batch_size(idxd->data->type, wq, 1U << wq->wqcfg->max_batch_shift);
+ 
+ 	for (i = 0; i < WQCFG_STRIDES(idxd); i++) {
+ 		wqcfg_offset = WQCFG_OFFSET(idxd, wq->id, i);
+diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h
+index fed0dfc1eaa83..05c3f86944783 100644
+--- a/drivers/dma/idxd/idxd.h
++++ b/drivers/dma/idxd/idxd.h
+@@ -308,6 +308,8 @@ struct idxd_device {
+ 	struct work_struct work;
+ 
+ 	struct idxd_pmu *idxd_pmu;
++
++	unsigned long *opcap_bmap;
+ };
+ 
+ /* IDXD software descriptor */
+@@ -540,6 +542,38 @@ static inline int idxd_wq_refcount(struct idxd_wq *wq)
+ 	return wq->client_count;
+ };
+ 
++/*
++ * Intel IAA does not support batch processing.
++ * The max batch size of device, max batch size of wq and
++ * max batch shift of wqcfg should be always 0 on IAA.
++ */
++static inline void idxd_set_max_batch_size(int idxd_type, struct idxd_device *idxd,
++					   u32 max_batch_size)
++{
++	if (idxd_type == IDXD_TYPE_IAX)
++		idxd->max_batch_size = 0;
++	else
++		idxd->max_batch_size = max_batch_size;
++}
++
++static inline void idxd_wq_set_max_batch_size(int idxd_type, struct idxd_wq *wq,
++					      u32 max_batch_size)
++{
++	if (idxd_type == IDXD_TYPE_IAX)
++		wq->max_batch_size = 0;
++	else
++		wq->max_batch_size = max_batch_size;
++}
++
++static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wqcfg,
++						  u32 max_batch_shift)
++{
++	if (idxd_type == IDXD_TYPE_IAX)
++		wqcfg->max_batch_shift = 0;
++	else
++		wqcfg->max_batch_shift = max_batch_shift;
++}
++
+ int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv,
+ 					struct module *module, const char *mod_name);
+ #define idxd_driver_register(driver) \
+diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c
+index aa3478257ddb5..cf94795ca1afa 100644
+--- a/drivers/dma/idxd/init.c
++++ b/drivers/dma/idxd/init.c
+@@ -177,7 +177,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd)
+ 		init_completion(&wq->wq_dead);
+ 		init_completion(&wq->wq_resurrect);
+ 		wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER;
+-		wq->max_batch_size = WQ_DEFAULT_MAX_BATCH;
++		idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH);
+ 		wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES;
+ 		wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev));
+ 		if (!wq->wqcfg) {
+@@ -369,6 +369,19 @@ static void idxd_read_table_offsets(struct idxd_device *idxd)
+ 	dev_dbg(dev, "IDXD Perfmon Offset: %#x\n", idxd->perfmon_offset);
+ }
+ 
++static void multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count)
++{
++	int i, j, nr;
++
++	for (i = 0, nr = 0; i < count; i++) {
++		for (j = 0; j < BITS_PER_LONG_LONG; j++) {
++			if (val[i] & BIT(j))
++				set_bit(nr, bmap);
++			nr++;
++		}
++	}
++}
++
+ static void idxd_read_caps(struct idxd_device *idxd)
+ {
+ 	struct device *dev = &idxd->pdev->dev;
+@@ -389,7 +402,7 @@ static void idxd_read_caps(struct idxd_device *idxd)
+ 
+ 	idxd->max_xfer_bytes = 1ULL << idxd->hw.gen_cap.max_xfer_shift;
+ 	dev_dbg(dev, "max xfer size: %llu bytes\n", idxd->max_xfer_bytes);
+-	idxd->max_batch_size = 1U << idxd->hw.gen_cap.max_batch_shift;
++	idxd_set_max_batch_size(idxd->data->type, idxd, 1U << idxd->hw.gen_cap.max_batch_shift);
+ 	dev_dbg(dev, "max batch size: %u\n", idxd->max_batch_size);
+ 	if (idxd->hw.gen_cap.config_en)
+ 		set_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags);
+@@ -427,6 +440,7 @@ static void idxd_read_caps(struct idxd_device *idxd)
+ 				IDXD_OPCAP_OFFSET + i * sizeof(u64));
+ 		dev_dbg(dev, "opcap[%d]: %#llx\n", i, idxd->hw.opcap.bits[i]);
+ 	}
++	multi_u64_to_bmap(idxd->opcap_bmap, &idxd->hw.opcap.bits[0], 4);
+ }
+ 
+ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data)
+@@ -448,6 +462,12 @@ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_d
+ 	if (idxd->id < 0)
+ 		return NULL;
+ 
++	idxd->opcap_bmap = bitmap_zalloc_node(IDXD_MAX_OPCAP_BITS, GFP_KERNEL, dev_to_node(dev));
++	if (!idxd->opcap_bmap) {
++		ida_free(&idxd_ida, idxd->id);
++		return NULL;
++	}
++
+ 	device_initialize(conf_dev);
+ 	conf_dev->parent = dev;
+ 	conf_dev->bus = &dsa_bus_type;
+diff --git a/drivers/dma/idxd/registers.h b/drivers/dma/idxd/registers.h
+index 02449aa9c454f..4c96ea85f8435 100644
+--- a/drivers/dma/idxd/registers.h
++++ b/drivers/dma/idxd/registers.h
+@@ -90,6 +90,8 @@ struct opcap {
+ 	u64 bits[4];
+ };
+ 
++#define IDXD_MAX_OPCAP_BITS		256U
++
+ #define IDXD_OPCAP_OFFSET		0x40
+ 
+ #define IDXD_TABLE_OFFSET		0x60
+diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c
+index 3f262a57441b4..82538622320a8 100644
+--- a/drivers/dma/idxd/sysfs.c
++++ b/drivers/dma/idxd/sysfs.c
+@@ -961,7 +961,7 @@ static ssize_t wq_max_batch_size_store(struct device *dev, struct device_attribu
+ 	if (batch_size > idxd->max_batch_size)
+ 		return -EINVAL;
+ 
+-	wq->max_batch_size = (u32)batch_size;
++	idxd_wq_set_max_batch_size(idxd->data->type, wq, (u32)batch_size);
+ 
+ 	return count;
+ }
+@@ -1177,14 +1177,8 @@ static ssize_t op_cap_show(struct device *dev,
+ 			   struct device_attribute *attr, char *buf)
+ {
+ 	struct idxd_device *idxd = confdev_to_idxd(dev);
+-	int i, rc = 0;
+-
+-	for (i = 0; i < 4; i++)
+-		rc += sysfs_emit_at(buf, rc, "%#llx ", idxd->hw.opcap.bits[i]);
+ 
+-	rc--;
+-	rc += sysfs_emit_at(buf, rc, "\n");
+-	return rc;
++	return sysfs_emit(buf, "%*pb\n", IDXD_MAX_OPCAP_BITS, idxd->opcap_bmap);
+ }
+ static DEVICE_ATTR_RO(op_cap);
+ 
+@@ -1408,6 +1402,7 @@ static void idxd_conf_device_release(struct device *dev)
+ 	kfree(idxd->wqs);
+ 	kfree(idxd->engines);
+ 	ida_free(&idxd_ida, idxd->id);
++	bitmap_free(idxd->opcap_bmap);
+ 	kfree(idxd);
+ }
+ 
+diff --git a/drivers/dma/mv_xor_v2.c b/drivers/dma/mv_xor_v2.c
+index f629ef6fd3c2a..113834e1167b6 100644
+--- a/drivers/dma/mv_xor_v2.c
++++ b/drivers/dma/mv_xor_v2.c
+@@ -893,6 +893,7 @@ static int mv_xor_v2_remove(struct platform_device *pdev)
+ 	tasklet_kill(&xor_dev->irq_tasklet);
+ 
+ 	clk_disable_unprepare(xor_dev->clk);
++	clk_disable_unprepare(xor_dev->reg_clk);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
+index e7034f6f3994a..22a392fe6d32b 100644
+--- a/drivers/dma/pxa_dma.c
++++ b/drivers/dma/pxa_dma.c
+@@ -1247,14 +1247,14 @@ static int pxad_init_phys(struct platform_device *op,
+ 		return -ENOMEM;
+ 
+ 	for (i = 0; i < nb_phy_chans; i++)
+-		if (platform_get_irq(op, i) > 0)
++		if (platform_get_irq_optional(op, i) > 0)
+ 			nr_irq++;
+ 
+ 	for (i = 0; i < nb_phy_chans; i++) {
+ 		phy = &pdev->phys[i];
+ 		phy->base = pdev->base;
+ 		phy->idx = i;
+-		irq = platform_get_irq(op, i);
++		irq = platform_get_irq_optional(op, i);
+ 		if ((nr_irq > 1) && (irq > 0))
+ 			ret = devm_request_irq(&op->dev, irq,
+ 					       pxad_chan_handler,
+diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
+index adb25a11c70fe..5aeaaac846dfd 100644
+--- a/drivers/dma/stm32-dma.c
++++ b/drivers/dma/stm32-dma.c
+@@ -663,6 +663,8 @@ static void stm32_dma_handle_chan_paused(struct stm32_dma_chan *chan)
+ 
+ 	chan->chan_reg.dma_sndtr = stm32_dma_read(dmadev, STM32_DMA_SNDTR(chan->id));
+ 
++	chan->status = DMA_PAUSED;
++
+ 	dev_dbg(chan2dev(chan), "vchan %pK: paused\n", &chan->vchan);
+ }
+ 
+@@ -775,9 +777,7 @@ static irqreturn_t stm32_dma_chan_irq(int irq, void *devid)
+ 	if (status & STM32_DMA_TCI) {
+ 		stm32_dma_irq_clear(chan, STM32_DMA_TCI);
+ 		if (scr & STM32_DMA_SCR_TCIE) {
+-			if (chan->status == DMA_PAUSED && !(scr & STM32_DMA_SCR_EN))
+-				stm32_dma_handle_chan_paused(chan);
+-			else
++			if (chan->status != DMA_PAUSED)
+ 				stm32_dma_handle_chan_done(chan, scr);
+ 		}
+ 		status &= ~STM32_DMA_TCI;
+@@ -824,13 +824,11 @@ static int stm32_dma_pause(struct dma_chan *c)
+ 		return -EPERM;
+ 
+ 	spin_lock_irqsave(&chan->vchan.lock, flags);
++
+ 	ret = stm32_dma_disable_chan(chan);
+-	/*
+-	 * A transfer complete flag is set to indicate the end of transfer due to the stream
+-	 * interruption, so wait for interrupt
+-	 */
+ 	if (!ret)
+-		chan->status = DMA_PAUSED;
++		stm32_dma_handle_chan_paused(chan);
++
+ 	spin_unlock_irqrestore(&chan->vchan.lock, flags);
+ 
+ 	return ret;
+diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c
+index 4fdd9f06b7235..4f1aeb81e9c7f 100644
+--- a/drivers/dma/ti/k3-udma-glue.c
++++ b/drivers/dma/ti/k3-udma-glue.c
+@@ -299,6 +299,7 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev,
+ 	ret = device_register(&tx_chn->common.chan_dev);
+ 	if (ret) {
+ 		dev_err(dev, "Channel Device registration failed %d\n", ret);
++		put_device(&tx_chn->common.chan_dev);
+ 		tx_chn->common.chan_dev.parent = NULL;
+ 		goto err;
+ 	}
+@@ -917,6 +918,7 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name,
+ 	ret = device_register(&rx_chn->common.chan_dev);
+ 	if (ret) {
+ 		dev_err(dev, "Channel Device registration failed %d\n", ret);
++		put_device(&rx_chn->common.chan_dev);
+ 		rx_chn->common.chan_dev.parent = NULL;
+ 		goto err;
+ 	}
+@@ -1048,6 +1050,7 @@ k3_udma_glue_request_remote_rx_chn(struct device *dev, const char *name,
+ 	ret = device_register(&rx_chn->common.chan_dev);
+ 	if (ret) {
+ 		dev_err(dev, "Channel Device registration failed %d\n", ret);
++		put_device(&rx_chn->common.chan_dev);
+ 		rx_chn->common.chan_dev.parent = NULL;
+ 		goto err;
+ 	}
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+index 9ecb7f663e196..278512535b518 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
+@@ -485,6 +485,21 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m);
+  */
+ static inline uint64_t amdgpu_vm_tlb_seq(struct amdgpu_vm *vm)
+ {
++	unsigned long flags;
++	spinlock_t *lock;
++
++	/*
++	 * Workaround to stop racing between the fence signaling and handling
++	 * the cb. The lock is static after initially setting it up, just make
++	 * sure that the dma_fence structure isn't freed up.
++	 */
++	rcu_read_lock();
++	lock = vm->last_tlb_flush->lock;
++	rcu_read_unlock();
++
++	spin_lock_irqsave(lock, flags);
++	spin_unlock_irqrestore(lock, flags);
++
+ 	return atomic64_read(&vm->tlb_seq);
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+index 28ec5f8ac1c11..27159f1d112ec 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+@@ -435,7 +435,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
+ 	if (place->flags & TTM_PL_FLAG_TOPDOWN)
+ 		vres->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION;
+ 
+-	if (fpfn || lpfn != man->size)
++	if (fpfn || lpfn != mgr->mm.size)
+ 		/* Allocate blocks in desired range */
+ 		vres->flags |= DRM_BUDDY_RANGE_ALLOCATION;
+ 
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+index dc774ddf34456..033fcd594edcb 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+@@ -1928,7 +1928,7 @@ static int criu_checkpoint(struct file *filep,
+ {
+ 	int ret;
+ 	uint32_t num_devices, num_bos, num_objects;
+-	uint64_t priv_size, priv_offset = 0;
++	uint64_t priv_size, priv_offset = 0, bo_priv_offset;
+ 
+ 	if (!args->devices || !args->bos || !args->priv_data)
+ 		return -EINVAL;
+@@ -1972,38 +1972,34 @@ static int criu_checkpoint(struct file *filep,
+ 	if (ret)
+ 		goto exit_unlock;
+ 
+-	ret = criu_checkpoint_bos(p, num_bos, (uint8_t __user *)args->bos,
+-			    (uint8_t __user *)args->priv_data, &priv_offset);
+-	if (ret)
+-		goto exit_unlock;
++	/* Leave room for BOs in the private data. They need to be restored
++	 * before events, but we checkpoint them last to simplify the error
++	 * handling.
++	 */
++	bo_priv_offset = priv_offset;
++	priv_offset += num_bos * sizeof(struct kfd_criu_bo_priv_data);
+ 
+ 	if (num_objects) {
+ 		ret = kfd_criu_checkpoint_queues(p, (uint8_t __user *)args->priv_data,
+ 						 &priv_offset);
+ 		if (ret)
+-			goto close_bo_fds;
++			goto exit_unlock;
+ 
+ 		ret = kfd_criu_checkpoint_events(p, (uint8_t __user *)args->priv_data,
+ 						 &priv_offset);
+ 		if (ret)
+-			goto close_bo_fds;
++			goto exit_unlock;
+ 
+ 		ret = kfd_criu_checkpoint_svm(p, (uint8_t __user *)args->priv_data, &priv_offset);
+ 		if (ret)
+-			goto close_bo_fds;
++			goto exit_unlock;
+ 	}
+ 
+-close_bo_fds:
+-	if (ret) {
+-		/* If IOCTL returns err, user assumes all FDs opened in criu_dump_bos are closed */
+-		uint32_t i;
+-		struct kfd_criu_bo_bucket *bo_buckets = (struct kfd_criu_bo_bucket *) args->bos;
+-
+-		for (i = 0; i < num_bos; i++) {
+-			if (bo_buckets[i].alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM)
+-				close_fd(bo_buckets[i].dmabuf_fd);
+-		}
+-	}
++	/* This must be the last thing in this function that can fail.
++	 * Otherwise we leak dmabuf file descriptors.
++	 */
++	ret = criu_checkpoint_bos(p, num_bos, (uint8_t __user *)args->bos,
++			   (uint8_t __user *)args->priv_data, &bo_priv_offset);
+ 
+ exit_unlock:
+ 	mutex_unlock(&p->mutex);
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+index 83e3ce9f60491..729d26d648af3 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+@@ -506,6 +506,7 @@ int kfd_criu_restore_event(struct file *devkfd,
+ 		ret = create_other_event(p, ev, &ev_priv->event_id);
+ 		break;
+ 	}
++	mutex_unlock(&p->event_mutex);
+ 
+ exit:
+ 	if (ret)
+@@ -513,8 +514,6 @@ exit:
+ 
+ 	kfree(ev_priv);
+ 
+-	mutex_unlock(&p->event_mutex);
+-
+ 	return ret;
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+index b059a77b6081d..058dbb6782df6 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+@@ -886,7 +886,7 @@ svm_migrate_to_vram(struct svm_range *prange, uint32_t best_loc,
+ static vm_fault_t svm_migrate_to_ram(struct vm_fault *vmf)
+ {
+ 	unsigned long addr = vmf->address;
+-	struct vm_area_struct *vma;
++	struct svm_range_bo *svm_bo;
+ 	enum svm_work_list_ops op;
+ 	struct svm_range *parent;
+ 	struct svm_range *prange;
+@@ -894,29 +894,42 @@ static vm_fault_t svm_migrate_to_ram(struct vm_fault *vmf)
+ 	struct mm_struct *mm;
+ 	int r = 0;
+ 
+-	vma = vmf->vma;
+-	mm = vma->vm_mm;
++	svm_bo = vmf->page->zone_device_data;
++	if (!svm_bo) {
++		pr_debug("failed get device page at addr 0x%lx\n", addr);
++		return VM_FAULT_SIGBUS;
++	}
++	if (!mmget_not_zero(svm_bo->eviction_fence->mm)) {
++		pr_debug("addr 0x%lx of process mm is detroyed\n", addr);
++		return VM_FAULT_SIGBUS;
++	}
+ 
+-	p = kfd_lookup_process_by_mm(vma->vm_mm);
++	mm = svm_bo->eviction_fence->mm;
++	if (mm != vmf->vma->vm_mm)
++		pr_debug("addr 0x%lx is COW mapping in child process\n", addr);
++
++	p = kfd_lookup_process_by_mm(mm);
+ 	if (!p) {
+ 		pr_debug("failed find process at fault address 0x%lx\n", addr);
+-		return VM_FAULT_SIGBUS;
++		r = VM_FAULT_SIGBUS;
++		goto out_mmput;
+ 	}
+ 	if (READ_ONCE(p->svms.faulting_task) == current) {
+ 		pr_debug("skipping ram migration\n");
+-		kfd_unref_process(p);
+-		return 0;
++		r = 0;
++		goto out_unref_process;
+ 	}
+-	addr >>= PAGE_SHIFT;
++
+ 	pr_debug("CPU page fault svms 0x%p address 0x%lx\n", &p->svms, addr);
++	addr >>= PAGE_SHIFT;
+ 
+ 	mutex_lock(&p->svms.lock);
+ 
+ 	prange = svm_range_from_addr(&p->svms, addr, &parent);
+ 	if (!prange) {
+-		pr_debug("cannot find svm range at 0x%lx\n", addr);
++		pr_debug("failed get range svms 0x%p addr 0x%lx\n", &p->svms, addr);
+ 		r = -EFAULT;
+-		goto out;
++		goto out_unlock_svms;
+ 	}
+ 
+ 	mutex_lock(&parent->migrate_mutex);
+@@ -938,10 +951,11 @@ static vm_fault_t svm_migrate_to_ram(struct vm_fault *vmf)
+ 		goto out_unlock_prange;
+ 	}
+ 
+-	r = svm_migrate_vram_to_ram(prange, mm, KFD_MIGRATE_TRIGGER_PAGEFAULT_CPU);
++	r = svm_migrate_vram_to_ram(prange, vmf->vma->vm_mm,
++				    KFD_MIGRATE_TRIGGER_PAGEFAULT_CPU);
+ 	if (r)
+-		pr_debug("failed %d migrate 0x%p [0x%lx 0x%lx] to ram\n", r,
+-			 prange, prange->start, prange->last);
++		pr_debug("failed %d migrate svms 0x%p range 0x%p [0x%lx 0x%lx]\n",
++			 r, prange->svms, prange, prange->start, prange->last);
+ 
+ 	/* xnack on, update mapping on GPUs with ACCESS_IN_PLACE */
+ 	if (p->xnack_enabled && parent == prange)
+@@ -955,12 +969,13 @@ out_unlock_prange:
+ 	if (prange != parent)
+ 		mutex_unlock(&prange->migrate_mutex);
+ 	mutex_unlock(&parent->migrate_mutex);
+-out:
++out_unlock_svms:
+ 	mutex_unlock(&p->svms.lock);
+-	kfd_unref_process(p);
+-
++out_unref_process:
+ 	pr_debug("CPU fault svms 0x%p address 0x%lx done\n", &p->svms, addr);
+-
++	kfd_unref_process(p);
++out_mmput:
++	mmput(mm);
+ 	return r ? VM_FAULT_SIGBUS : 0;
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
+index 4a15aa7a375fe..2680eecb3369d 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c
+@@ -356,32 +356,32 @@ static struct wm_table ddr5_wm_table = {
+ 			.wm_inst = WM_A,
+ 			.wm_type = WM_TYPE_PSTATE_CHG,
+ 			.pstate_latency_us = 11.72,
+-			.sr_exit_time_us = 9,
+-			.sr_enter_plus_exit_time_us = 11,
++			.sr_exit_time_us = 12.5,
++			.sr_enter_plus_exit_time_us = 14.5,
+ 			.valid = true,
+ 		},
+ 		{
+ 			.wm_inst = WM_B,
+ 			.wm_type = WM_TYPE_PSTATE_CHG,
+ 			.pstate_latency_us = 11.72,
+-			.sr_exit_time_us = 9,
+-			.sr_enter_plus_exit_time_us = 11,
++			.sr_exit_time_us = 12.5,
++			.sr_enter_plus_exit_time_us = 14.5,
+ 			.valid = true,
+ 		},
+ 		{
+ 			.wm_inst = WM_C,
+ 			.wm_type = WM_TYPE_PSTATE_CHG,
+ 			.pstate_latency_us = 11.72,
+-			.sr_exit_time_us = 9,
+-			.sr_enter_plus_exit_time_us = 11,
++			.sr_exit_time_us = 12.5,
++			.sr_enter_plus_exit_time_us = 14.5,
+ 			.valid = true,
+ 		},
+ 		{
+ 			.wm_inst = WM_D,
+ 			.wm_type = WM_TYPE_PSTATE_CHG,
+ 			.pstate_latency_us = 11.72,
+-			.sr_exit_time_us = 9,
+-			.sr_enter_plus_exit_time_us = 11,
++			.sr_exit_time_us = 12.5,
++			.sr_enter_plus_exit_time_us = 14.5,
+ 			.valid = true,
+ 		},
+ 	}
+@@ -393,32 +393,32 @@ static struct wm_table lpddr5_wm_table = {
+ 			.wm_inst = WM_A,
+ 			.wm_type = WM_TYPE_PSTATE_CHG,
+ 			.pstate_latency_us = 11.65333,
+-			.sr_exit_time_us = 11.5,
+-			.sr_enter_plus_exit_time_us = 14.5,
++			.sr_exit_time_us = 16.5,
++			.sr_enter_plus_exit_time_us = 18.5,
+ 			.valid = true,
+ 		},
+ 		{
+ 			.wm_inst = WM_B,
+ 			.wm_type = WM_TYPE_PSTATE_CHG,
+ 			.pstate_latency_us = 11.65333,
+-			.sr_exit_time_us = 11.5,
+-			.sr_enter_plus_exit_time_us = 14.5,
++			.sr_exit_time_us = 16.5,
++			.sr_enter_plus_exit_time_us = 18.5,
+ 			.valid = true,
+ 		},
+ 		{
+ 			.wm_inst = WM_C,
+ 			.wm_type = WM_TYPE_PSTATE_CHG,
+ 			.pstate_latency_us = 11.65333,
+-			.sr_exit_time_us = 11.5,
+-			.sr_enter_plus_exit_time_us = 14.5,
++			.sr_exit_time_us = 16.5,
++			.sr_enter_plus_exit_time_us = 18.5,
+ 			.valid = true,
+ 		},
+ 		{
+ 			.wm_inst = WM_D,
+ 			.wm_type = WM_TYPE_PSTATE_CHG,
+ 			.pstate_latency_us = 11.65333,
+-			.sr_exit_time_us = 11.5,
+-			.sr_enter_plus_exit_time_us = 14.5,
++			.sr_exit_time_us = 16.5,
++			.sr_enter_plus_exit_time_us = 18.5,
+ 			.valid = true,
+ 		},
+ 	}
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
+index f0f3f66629cc0..e7f1d5f8166f9 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
+@@ -156,7 +156,8 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
+ {
+ 	struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+ 	unsigned int num_levels;
+-	unsigned int num_dcfclk_levels, num_dtbclk_levels, num_dispclk_levels;
++	struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk;
++	unsigned int i;
+ 
+ 	memset(&(clk_mgr_base->clks), 0, sizeof(struct dc_clocks));
+ 	clk_mgr_base->clks.p_state_change_support = true;
+@@ -180,42 +181,42 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base)
+ 	/* DCFCLK */
+ 	dcn32_init_single_clock(clk_mgr, PPCLK_DCFCLK,
+ 			&clk_mgr_base->bw_params->clk_table.entries[0].dcfclk_mhz,
+-			&num_levels);
+-	num_dcfclk_levels = num_levels;
++			&num_entries_per_clk->num_dcfclk_levels);
+ 
+ 	/* SOCCLK */
+ 	dcn32_init_single_clock(clk_mgr, PPCLK_SOCCLK,
+ 					&clk_mgr_base->bw_params->clk_table.entries[0].socclk_mhz,
+-					&num_levels);
++					&num_entries_per_clk->num_socclk_levels);
++
+ 	/* DTBCLK */
+ 	if (!clk_mgr->base.ctx->dc->debug.disable_dtb_ref_clk_switch)
+ 		dcn32_init_single_clock(clk_mgr, PPCLK_DTBCLK,
+ 				&clk_mgr_base->bw_params->clk_table.entries[0].dtbclk_mhz,
+-				&num_levels);
+-	num_dtbclk_levels = num_levels;
++				&num_entries_per_clk->num_dtbclk_levels);
+ 
+ 	/* DISPCLK */
+ 	dcn32_init_single_clock(clk_mgr, PPCLK_DISPCLK,
+ 			&clk_mgr_base->bw_params->clk_table.entries[0].dispclk_mhz,
+-			&num_levels);
+-	num_dispclk_levels = num_levels;
++			&num_entries_per_clk->num_dispclk_levels);
++	num_levels = num_entries_per_clk->num_dispclk_levels;
+ 
+-	if (num_dcfclk_levels && num_dtbclk_levels && num_dispclk_levels)
++	if (num_entries_per_clk->num_dcfclk_levels &&
++			num_entries_per_clk->num_dtbclk_levels &&
++			num_entries_per_clk->num_dispclk_levels)
+ 		clk_mgr->dpm_present = true;
+ 
+ 	if (clk_mgr_base->ctx->dc->debug.min_disp_clk_khz) {
+-		unsigned int i;
+-
+ 		for (i = 0; i < num_levels; i++)
+ 			if (clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz
+ 					< khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_disp_clk_khz))
+ 				clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz
+ 					= khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_disp_clk_khz);
+ 	}
++	for (i = 0; i < num_levels; i++)
++		if (clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz > 1950)
++			clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz = 1950;
+ 
+ 	if (clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz) {
+-		unsigned int i;
+-
+ 		for (i = 0; i < num_levels; i++)
+ 			if (clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz
+ 					< khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz))
+@@ -370,7 +371,7 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
+ 			/* to disable P-State switching, set UCLK min = max */
+ 			if (!clk_mgr_base->clks.p_state_change_support)
+ 				dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
+-						clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz);
++						clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz);
+ 		}
+ 
+ 		if (should_update_pstate_support(safe_to_lower, fclk_p_state_change_support, clk_mgr_base->clks.fclk_p_state_change_support) &&
+@@ -632,7 +633,7 @@ static void dcn32_set_hard_min_memclk(struct clk_mgr *clk_mgr_base, bool current
+ 					khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz));
+ 		else
+ 			dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
+-					clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz);
++					clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz);
+ 	} else {
+ 		dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
+ 				clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz);
+@@ -648,22 +649,37 @@ static void dcn32_set_hard_max_memclk(struct clk_mgr *clk_mgr_base)
+ 		return;
+ 
+ 	dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK,
+-			clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries - 1].memclk_mhz);
++			clk_mgr_base->bw_params->clk_table.entries[clk_mgr_base->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1].memclk_mhz);
+ }
+ 
+ /* Get current memclk states, update bounding box */
+ static void dcn32_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base)
+ {
+ 	struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
++	struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk;
+ 	unsigned int num_levels;
+ 
+ 	if (!clk_mgr->smu_present)
+ 		return;
+ 
+-	/* Refresh memclk states */
++	/* Refresh memclk and fclk states */
+ 	dcn32_init_single_clock(clk_mgr, PPCLK_UCLK,
+ 			&clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz,
+-			&num_levels);
++			&num_entries_per_clk->num_memclk_levels);
++
++	/* memclk must have at least one level */
++	num_entries_per_clk->num_memclk_levels = num_entries_per_clk->num_memclk_levels ? num_entries_per_clk->num_memclk_levels : 1;
++
++	dcn32_init_single_clock(clk_mgr, PPCLK_FCLK,
++			&clk_mgr_base->bw_params->clk_table.entries[0].fclk_mhz,
++			&num_entries_per_clk->num_fclk_levels);
++
++	if (num_entries_per_clk->num_memclk_levels >= num_entries_per_clk->num_fclk_levels) {
++		num_levels = num_entries_per_clk->num_memclk_levels;
++	} else {
++		num_levels = num_entries_per_clk->num_fclk_levels;
++	}
++
+ 	clk_mgr_base->bw_params->clk_table.num_entries = num_levels ? num_levels : 1;
+ 
+ 	if (clk_mgr->dpm_present && !num_levels)
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c
+index 8c0ab013764e3..e7f1bf0b04c57 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dio_stream_encoder.c
+@@ -49,18 +49,30 @@
+ #define CTX \
+ 	enc1->base.ctx
+ 
++static void enc314_reset_fifo(struct stream_encoder *enc, bool reset)
++{
++	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
++	uint32_t reset_val = reset ? 1 : 0;
++	uint32_t is_symclk_on;
++
++	REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, reset_val);
++	REG_GET(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, &is_symclk_on);
++
++	if (is_symclk_on)
++		REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, reset_val, 10, 5000);
++	else
++		udelay(10);
++}
+ 
+ static void enc314_enable_fifo(struct stream_encoder *enc)
+ {
+ 	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);
+ 
+-	/* TODO: Confirm if we need to wait for DIG_SYMCLK_FE_ON */
+-	REG_WAIT(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, 1, 10, 5000);
+ 	REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, 0x7);
+-	REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1);
+-	REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 10, 5000);
+-	REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0);
+-	REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 10, 5000);
++
++	enc314_reset_fifo(enc, true);
++	enc314_reset_fifo(enc, false);
++
+ 	REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1);
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
+index 4bb3b31ea7e0c..60f43473d6d88 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
+@@ -146,8 +146,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_14_soc = {
+ 		},
+ 	},
+ 	.num_states = 5,
+-	.sr_exit_time_us = 9.0,
+-	.sr_enter_plus_exit_time_us = 11.0,
++	.sr_exit_time_us = 16.5,
++	.sr_enter_plus_exit_time_us = 18.5,
+ 	.sr_exit_z8_time_us = 442.0,
+ 	.sr_enter_plus_exit_z8_time_us = 560.0,
+ 	.writeback_latency_us = 12.0,
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
+index d9f1b0a4fbd4a..591ab1389e3b3 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr.h
+@@ -95,10 +95,23 @@ struct clk_limit_table_entry {
+ 	unsigned int wck_ratio;
+ };
+ 
++struct clk_limit_num_entries {
++	unsigned int num_dcfclk_levels;
++	unsigned int num_fclk_levels;
++	unsigned int num_memclk_levels;
++	unsigned int num_socclk_levels;
++	unsigned int num_dtbclk_levels;
++	unsigned int num_dispclk_levels;
++	unsigned int num_dppclk_levels;
++	unsigned int num_phyclk_levels;
++	unsigned int num_phyclk_d18_levels;
++};
++
+ /* This table is contiguous */
+ struct clk_limit_table {
+ 	struct clk_limit_table_entry entries[MAX_NUM_DPM_LVL];
+-	unsigned int num_entries;
++	struct clk_limit_num_entries num_entries_per_clk;
++	unsigned int num_entries; /* highest populated dpm level for back compatibility */
+ };
+ 
+ struct wm_range_table_entry {
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_4_ppsmc.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_4_ppsmc.h
+index d9b0cd7522006..f4d6c07b56ea7 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_4_ppsmc.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu_v13_0_4_ppsmc.h
+@@ -54,14 +54,14 @@
+ #define PPSMC_MSG_TestMessage                   0x01 ///< To check if PMFW is alive and responding. Requirement specified by PMFW team
+ #define PPSMC_MSG_GetPmfwVersion                0x02 ///< Get PMFW version
+ #define PPSMC_MSG_GetDriverIfVersion            0x03 ///< Get PMFW_DRIVER_IF version
+-#define PPSMC_MSG_EnableGfxOff                  0x04 ///< Enable GFXOFF
+-#define PPSMC_MSG_DisableGfxOff                 0x05 ///< Disable GFXOFF
++#define PPSMC_MSG_SPARE0                        0x04 ///< SPARE
++#define PPSMC_MSG_SPARE1                        0x05 ///< SPARE
+ #define PPSMC_MSG_PowerDownVcn                  0x06 ///< Power down VCN
+ #define PPSMC_MSG_PowerUpVcn                    0x07 ///< Power up VCN; VCN is power gated by default
+ #define PPSMC_MSG_SetHardMinVcn                 0x08 ///< For wireless display
+ #define PPSMC_MSG_SetSoftMinGfxclk              0x09 ///< Set SoftMin for GFXCLK, argument is frequency in MHz
+-#define PPSMC_MSG_ActiveProcessNotify           0x0A ///< Needs update
+-#define PPSMC_MSG_ForcePowerDownGfx             0x0B ///< Force power down GFX, i.e. enter GFXOFF
++#define PPSMC_MSG_SPARE2                        0x0A ///< SPARE
++#define PPSMC_MSG_SPARE3                        0x0B ///< SPARE
+ #define PPSMC_MSG_PrepareMp1ForUnload           0x0C ///< Prepare PMFW for GFX driver unload
+ #define PPSMC_MSG_SetDriverDramAddrHigh         0x0D ///< Set high 32 bits of DRAM address for Driver table transfer
+ #define PPSMC_MSG_SetDriverDramAddrLow          0x0E ///< Set low 32 bits of DRAM address for Driver table transfer
+@@ -73,8 +73,7 @@
+ #define PPSMC_MSG_SetSoftMinFclk                0x14 ///< Set hard min for FCLK
+ #define PPSMC_MSG_SetSoftMinVcn                 0x15 ///< Set soft min for VCN clocks (VCLK and DCLK)
+ 
+-
+-#define PPSMC_MSG_EnableGfxImu                  0x16 ///< Needs update
++#define PPSMC_MSG_EnableGfxImu                  0x16 ///< Enable GFX IMU
+ 
+ #define PPSMC_MSG_GetGfxclkFrequency            0x17 ///< Get GFX clock frequency
+ #define PPSMC_MSG_GetFclkFrequency              0x18 ///< Get FCLK frequency
+@@ -102,8 +101,8 @@
+ #define PPSMC_MSG_SetHardMinIspxclkByFreq       0x2C ///< Set HardMin by frequency for ISPXCLK
+ #define PPSMC_MSG_PowerDownUmsch                0x2D ///< Power down VCN.UMSCH (aka VSCH) scheduler
+ #define PPSMC_MSG_PowerUpUmsch                  0x2E ///< Power up VCN.UMSCH (aka VSCH) scheduler
+-#define PPSMC_Message_IspStutterOn_MmhubPgDis   0x2F ///< ISP StutterOn mmHub PgDis
+-#define PPSMC_Message_IspStutterOff_MmhubPgEn   0x30 ///< ISP StufferOff mmHub PgEn
++#define PPSMC_MSG_IspStutterOn_MmhubPgDis       0x2F ///< ISP StutterOn mmHub PgDis
++#define PPSMC_MSG_IspStutterOff_MmhubPgEn       0x30 ///< ISP StufferOff mmHub PgEn
+ 
+ #define PPSMC_Message_Count                     0x31 ///< Total number of PPSMC messages
+ /** @}*/
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+index 644ea150e0751..8292839bc42a9 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+@@ -376,7 +376,9 @@ static void sienna_cichlid_check_bxco_support(struct smu_context *smu)
+ 		if (((adev->pdev->device == 0x73A1) &&
+ 		    (adev->pdev->revision == 0x00)) ||
+ 		    ((adev->pdev->device == 0x73BF) &&
+-		    (adev->pdev->revision == 0xCF)))
++		    (adev->pdev->revision == 0xCF)) ||
++		    ((adev->pdev->device == 0x7422) &&
++		    (adev->pdev->revision == 0x00)))
+ 			smu_baco->platform_support = false;
+ 
+ 	}
+diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
+index d4492b6d23d25..21ba510716b6c 100644
+--- a/drivers/gpu/drm/i915/display/intel_dp.c
++++ b/drivers/gpu/drm/i915/display/intel_dp.c
+@@ -5233,7 +5233,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
+ 			      encoder->devdata, IS_ERR(edid) ? NULL : edid);
+ 
+ 	intel_panel_add_edid_fixed_modes(intel_connector,
+-					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
++					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE ||
+ 					 intel_vrr_is_capable(intel_connector));
+ 
+ 	/* MSO requires information from the EDID */
+diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
+index 730480ac3300d..c0bec3e0f0ae9 100644
+--- a/drivers/gpu/drm/i915/display/intel_lvds.c
++++ b/drivers/gpu/drm/i915/display/intel_lvds.c
+@@ -972,8 +972,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
+ 
+ 	/* Try EDID first */
+ 	intel_panel_add_edid_fixed_modes(intel_connector,
+-					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
+-					 false);
++					 intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE);
+ 
+ 	/* Failed to get EDID, what about VBT? */
+ 	if (!intel_panel_preferred_fixed_mode(intel_connector))
+diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
+index 237a40623dd7b..1e008922b95d3 100644
+--- a/drivers/gpu/drm/i915/display/intel_panel.c
++++ b/drivers/gpu/drm/i915/display/intel_panel.c
+@@ -81,15 +81,14 @@ static bool is_alt_drrs_mode(const struct drm_display_mode *mode,
+ 		mode->clock != preferred_mode->clock;
+ }
+ 
+-static bool is_alt_vrr_mode(const struct drm_display_mode *mode,
+-			    const struct drm_display_mode *preferred_mode)
++static bool is_alt_fixed_mode(const struct drm_display_mode *mode,
++			      const struct drm_display_mode *preferred_mode)
+ {
+ 	return drm_mode_match(mode, preferred_mode,
+ 			      DRM_MODE_MATCH_FLAGS |
+ 			      DRM_MODE_MATCH_3D_FLAGS) &&
+ 		mode->hdisplay == preferred_mode->hdisplay &&
+-		mode->vdisplay == preferred_mode->vdisplay &&
+-		mode->clock != preferred_mode->clock;
++		mode->vdisplay == preferred_mode->vdisplay;
+ }
+ 
+ const struct drm_display_mode *
+@@ -172,19 +171,7 @@ int intel_panel_compute_config(struct intel_connector *connector,
+ 	return 0;
+ }
+ 
+-static bool is_alt_fixed_mode(const struct drm_display_mode *mode,
+-			      const struct drm_display_mode *preferred_mode,
+-			      bool has_vrr)
+-{
+-	/* is_alt_drrs_mode() is a subset of is_alt_vrr_mode() */
+-	if (has_vrr)
+-		return is_alt_vrr_mode(mode, preferred_mode);
+-	else
+-		return is_alt_drrs_mode(mode, preferred_mode);
+-}
+-
+-static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connector,
+-						 bool has_vrr)
++static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connector)
+ {
+ 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ 	const struct drm_display_mode *preferred_mode =
+@@ -192,7 +179,7 @@ static void intel_panel_add_edid_alt_fixed_modes(struct intel_connector *connect
+ 	struct drm_display_mode *mode, *next;
+ 
+ 	list_for_each_entry_safe(mode, next, &connector->base.probed_modes, head) {
+-		if (!is_alt_fixed_mode(mode, preferred_mode, has_vrr))
++		if (!is_alt_fixed_mode(mode, preferred_mode))
+ 			continue;
+ 
+ 		drm_dbg_kms(&dev_priv->drm,
+@@ -251,11 +238,11 @@ static void intel_panel_destroy_probed_modes(struct intel_connector *connector)
+ }
+ 
+ void intel_panel_add_edid_fixed_modes(struct intel_connector *connector,
+-				      bool has_drrs, bool has_vrr)
++				      bool use_alt_fixed_modes)
+ {
+ 	intel_panel_add_edid_preferred_mode(connector);
+-	if (intel_panel_preferred_fixed_mode(connector) && (has_drrs || has_vrr))
+-		intel_panel_add_edid_alt_fixed_modes(connector, has_vrr);
++	if (intel_panel_preferred_fixed_mode(connector) && use_alt_fixed_modes)
++		intel_panel_add_edid_alt_fixed_modes(connector);
+ 	intel_panel_destroy_probed_modes(connector);
+ }
+ 
+diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_panel.h
+index b087c0c3cc6db..4a94bd0eae3bf 100644
+--- a/drivers/gpu/drm/i915/display/intel_panel.h
++++ b/drivers/gpu/drm/i915/display/intel_panel.h
+@@ -41,7 +41,7 @@ int intel_panel_fitting(struct intel_crtc_state *crtc_state,
+ int intel_panel_compute_config(struct intel_connector *connector,
+ 			       struct drm_display_mode *adjusted_mode);
+ void intel_panel_add_edid_fixed_modes(struct intel_connector *connector,
+-				      bool has_drrs, bool has_vrr);
++				      bool use_alt_fixed_modes);
+ void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector);
+ void intel_panel_add_vbt_sdvo_fixed_mode(struct intel_connector *connector);
+ void intel_panel_add_encoder_fixed_mode(struct intel_connector *connector,
+diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
+index e6a870641cd25..fbe777e02ea7f 100644
+--- a/drivers/gpu/drm/i915/display/intel_psr.c
++++ b/drivers/gpu/drm/i915/display/intel_psr.c
+@@ -2188,8 +2188,11 @@ static void _psr_invalidate_handle(struct intel_dp *intel_dp)
+ 	if (intel_dp->psr.psr2_sel_fetch_enabled) {
+ 		u32 val;
+ 
+-		if (intel_dp->psr.psr2_sel_fetch_cff_enabled)
++		if (intel_dp->psr.psr2_sel_fetch_cff_enabled) {
++			/* Send one update otherwise lag is observed in screen */
++			intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
+ 			return;
++		}
+ 
+ 		val = man_trk_ctl_enable_bit_get(dev_priv) |
+ 		      man_trk_ctl_partial_frame_bit_get(dev_priv) |
+diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
+index b5f65b093c106..6b471fc297bd6 100644
+--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
++++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
+@@ -2900,8 +2900,12 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
+ 	intel_panel_add_vbt_sdvo_fixed_mode(intel_connector);
+ 
+ 	if (!intel_panel_preferred_fixed_mode(intel_connector)) {
++		mutex_lock(&i915->drm.mode_config.mutex);
++
+ 		intel_ddc_get_modes(connector, &intel_sdvo->ddc);
+-		intel_panel_add_edid_fixed_modes(intel_connector, false, false);
++		intel_panel_add_edid_fixed_modes(intel_connector, false);
++
++		mutex_unlock(&i915->drm.mode_config.mutex);
+ 	}
+ 
+ 	intel_panel_init(intel_connector);
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+index f5062d0c63336..824971a1ceece 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+@@ -40,13 +40,13 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
+ 		goto err;
+ 	}
+ 
+-	ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL);
++	ret = sg_alloc_table(st, obj->mm.pages->orig_nents, GFP_KERNEL);
+ 	if (ret)
+ 		goto err_free;
+ 
+ 	src = obj->mm.pages->sgl;
+ 	dst = st->sgl;
+-	for (i = 0; i < obj->mm.pages->nents; i++) {
++	for (i = 0; i < obj->mm.pages->orig_nents; i++) {
+ 		sg_set_page(dst, sg_page(src), src->length, 0);
+ 		dst = sg_next(dst);
+ 		src = sg_next(src);
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+index 34b9c76cd8e66..b5eb279a5c2c7 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+@@ -369,14 +369,14 @@ __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,
+ 
+ 	__start_cpu_write(obj);
+ 	/*
+-	 * On non-LLC platforms, force the flush-on-acquire if this is ever
++	 * On non-LLC igfx platforms, force the flush-on-acquire if this is ever
+ 	 * swapped-in. Our async flush path is not trust worthy enough yet(and
+ 	 * happens in the wrong order), and with some tricks it's conceivable
+ 	 * for userspace to change the cache-level to I915_CACHE_NONE after the
+ 	 * pages are swapped-in, and since execbuf binds the object before doing
+ 	 * the async flush, we have a race window.
+ 	 */
+-	if (!HAS_LLC(i915))
++	if (!HAS_LLC(i915) && !IS_DGFX(i915))
+ 		obj->cache_dirty = true;
+ }
+ 
+diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
+index e3cd589464777..de89946c4817f 100644
+--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
++++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
+@@ -1595,6 +1595,9 @@ static void intel_vgpu_remove(struct mdev_device *mdev)
+ 
+ 	if (WARN_ON_ONCE(vgpu->attached))
+ 		return;
++
++	vfio_unregister_group_dev(&vgpu->vfio_device);
++	vfio_uninit_group_dev(&vgpu->vfio_device);
+ 	intel_gvt_destroy_vgpu(vgpu);
+ }
+ 
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
+index c186ace7f83b9..2064863a0fd32 100644
+--- a/drivers/gpu/drm/vc4/vc4_drv.c
++++ b/drivers/gpu/drm/vc4/vc4_drv.c
+@@ -476,7 +476,12 @@ static int __init vc4_drm_register(void)
+ 	if (ret)
+ 		return ret;
+ 
+-	return platform_driver_register(&vc4_platform_driver);
++	ret = platform_driver_register(&vc4_platform_driver);
++	if (ret)
++		platform_unregister_drivers(component_drivers,
++					    ARRAY_SIZE(component_drivers));
++
++	return ret;
+ }
+ 
+ static void __exit vc4_drm_unregister(void)
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 874c6bd787c56..4e5bba0822a5d 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -2712,9 +2712,16 @@ static int vc4_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
+ 		DRM_ERROR("Failed to get HDMI state machine clock\n");
+ 		return PTR_ERR(vc4_hdmi->hsm_clock);
+ 	}
++
+ 	vc4_hdmi->audio_clock = vc4_hdmi->hsm_clock;
+ 	vc4_hdmi->cec_clock = vc4_hdmi->hsm_clock;
+ 
++	vc4_hdmi->hsm_rpm_clock = devm_clk_get(dev, "hdmi");
++	if (IS_ERR(vc4_hdmi->hsm_rpm_clock)) {
++		DRM_ERROR("Failed to get HDMI state machine clock\n");
++		return PTR_ERR(vc4_hdmi->hsm_rpm_clock);
++	}
++
+ 	return 0;
+ }
+ 
+@@ -2796,6 +2803,12 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi)
+ 		return PTR_ERR(vc4_hdmi->hsm_clock);
+ 	}
+ 
++	vc4_hdmi->hsm_rpm_clock = devm_clk_get(dev, "hdmi");
++	if (IS_ERR(vc4_hdmi->hsm_rpm_clock)) {
++		DRM_ERROR("Failed to get HDMI state machine clock\n");
++		return PTR_ERR(vc4_hdmi->hsm_rpm_clock);
++	}
++
+ 	vc4_hdmi->pixel_bvb_clock = devm_clk_get(dev, "bvb");
+ 	if (IS_ERR(vc4_hdmi->pixel_bvb_clock)) {
+ 		DRM_ERROR("Failed to get pixel bvb clock\n");
+@@ -2859,7 +2872,7 @@ static int vc4_hdmi_runtime_suspend(struct device *dev)
+ {
+ 	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+ 
+-	clk_disable_unprepare(vc4_hdmi->hsm_clock);
++	clk_disable_unprepare(vc4_hdmi->hsm_rpm_clock);
+ 
+ 	return 0;
+ }
+@@ -2877,11 +2890,11 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
+ 	 * its frequency while the power domain is active so that it
+ 	 * keeps its rate.
+ 	 */
+-	ret = clk_set_min_rate(vc4_hdmi->hsm_clock, HSM_MIN_CLOCK_FREQ);
++	ret = clk_set_min_rate(vc4_hdmi->hsm_rpm_clock, HSM_MIN_CLOCK_FREQ);
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
++	ret = clk_prepare_enable(vc4_hdmi->hsm_rpm_clock);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -2894,7 +2907,7 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
+ 	 * case, it will lead to a silent CPU stall. Let's make sure we
+ 	 * prevent such a case.
+ 	 */
+-	rate = clk_get_rate(vc4_hdmi->hsm_clock);
++	rate = clk_get_rate(vc4_hdmi->hsm_rpm_clock);
+ 	if (!rate) {
+ 		ret = -EINVAL;
+ 		goto err_disable_clk;
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.h b/drivers/gpu/drm/vc4/vc4_hdmi.h
+index c3ed2b07df235..47f141ec8c40c 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
+@@ -171,6 +171,7 @@ struct vc4_hdmi {
+ 	struct clk *cec_clock;
+ 	struct clk *pixel_clock;
+ 	struct clk *hsm_clock;
++	struct clk *hsm_rpm_clock;
+ 	struct clk *audio_clock;
+ 	struct clk *pixel_bvb_clock;
+ 
+diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c
+index e0bc731241960..ab57b49a44ed9 100644
+--- a/drivers/hid/hid-hyperv.c
++++ b/drivers/hid/hid-hyperv.c
+@@ -499,7 +499,7 @@ static int mousevsc_probe(struct hv_device *device,
+ 
+ 	ret = hid_add_device(hid_dev);
+ 	if (ret)
+-		goto probe_err1;
++		goto probe_err2;
+ 
+ 
+ 	ret = hid_parse(hid_dev);
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
+index d049239256a26..2bd1a43021c92 100644
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -2522,11 +2522,12 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
+ 
+ 	if (!delay_pen_events(wacom_wac) && wacom_wac->tool[0]) {
+ 		int id = wacom_wac->id[0];
+-		if (wacom_wac->features.quirks & WACOM_QUIRK_PEN_BUTTON3 &&
+-		    wacom_wac->hid_data.barrelswitch & wacom_wac->hid_data.barrelswitch2) {
+-			wacom_wac->hid_data.barrelswitch = 0;
+-			wacom_wac->hid_data.barrelswitch2 = 0;
+-			wacom_wac->hid_data.barrelswitch3 = 1;
++		if (wacom_wac->features.quirks & WACOM_QUIRK_PEN_BUTTON3) {
++			int sw_state = wacom_wac->hid_data.barrelswitch |
++				       (wacom_wac->hid_data.barrelswitch2 << 1);
++			wacom_wac->hid_data.barrelswitch = sw_state == 1;
++			wacom_wac->hid_data.barrelswitch2 = sw_state == 2;
++			wacom_wac->hid_data.barrelswitch3 = sw_state == 3;
+ 		}
+ 		input_report_key(input, BTN_STYLUS, wacom_wac->hid_data.barrelswitch);
+ 		input_report_key(input, BTN_STYLUS2, wacom_wac->hid_data.barrelswitch2);
+diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom_hwspinlock.c
+index 80ea45b3a815f..9734e149d981b 100644
+--- a/drivers/hwspinlock/qcom_hwspinlock.c
++++ b/drivers/hwspinlock/qcom_hwspinlock.c
+@@ -121,7 +121,7 @@ static const struct regmap_config tcsr_mutex_config = {
+ 	.reg_bits		= 32,
+ 	.reg_stride		= 4,
+ 	.val_bits		= 32,
+-	.max_register		= 0x40000,
++	.max_register		= 0x20000,
+ 	.fast_io		= true,
+ };
+ 
+diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c
+index aff36a933ebec..55d8bd232695c 100644
+--- a/drivers/mmc/host/sdhci-brcmstb.c
++++ b/drivers/mmc/host/sdhci-brcmstb.c
+@@ -12,6 +12,7 @@
+ #include <linux/bitops.h>
+ #include <linux/delay.h>
+ 
++#include "sdhci-cqhci.h"
+ #include "sdhci-pltfm.h"
+ #include "cqhci.h"
+ 
+@@ -55,7 +56,7 @@ static void brcmstb_reset(struct sdhci_host *host, u8 mask)
+ 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ 	struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host);
+ 
+-	sdhci_reset(host, mask);
++	sdhci_and_cqhci_reset(host, mask);
+ 
+ 	/* Reset will clear this, so re-enable it */
+ 	if (priv->flags & BRCMSTB_PRIV_FLAGS_GATE_CLOCK)
+diff --git a/drivers/mmc/host/sdhci-cqhci.h b/drivers/mmc/host/sdhci-cqhci.h
+new file mode 100644
+index 0000000000000..cf8e7ba71bbd7
+--- /dev/null
++++ b/drivers/mmc/host/sdhci-cqhci.h
+@@ -0,0 +1,24 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright 2022 The Chromium OS Authors
++ *
++ * Support that applies to the combination of SDHCI and CQHCI, while not
++ * expressing a dependency between the two modules.
++ */
++
++#ifndef __MMC_HOST_SDHCI_CQHCI_H__
++#define __MMC_HOST_SDHCI_CQHCI_H__
++
++#include "cqhci.h"
++#include "sdhci.h"
++
++static inline void sdhci_and_cqhci_reset(struct sdhci_host *host, u8 mask)
++{
++	if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL) &&
++	    host->mmc->cqe_private)
++		cqhci_deactivate(host->mmc);
++
++	sdhci_reset(host, mask);
++}
++
++#endif /* __MMC_HOST_SDHCI_CQHCI_H__ */
+diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
+index 747df79d90eef..31ea0a2fce358 100644
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -25,6 +25,7 @@
+ #include <linux/of_device.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/pm_runtime.h>
++#include "sdhci-cqhci.h"
+ #include "sdhci-pltfm.h"
+ #include "sdhci-esdhc.h"
+ #include "cqhci.h"
+@@ -1288,7 +1289,7 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
+ 
+ static void esdhc_reset(struct sdhci_host *host, u8 mask)
+ {
+-	sdhci_reset(host, mask);
++	sdhci_and_cqhci_reset(host, mask);
+ 
+ 	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
+@@ -1671,14 +1672,14 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
+ 	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
+ 		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
+ 
+-	if (host->caps & MMC_CAP_8_BIT_DATA &&
++	if (host->mmc->caps & MMC_CAP_8_BIT_DATA &&
+ 	    imx_data->socdata->flags & ESDHC_FLAG_HS400)
+ 		host->mmc->caps2 |= MMC_CAP2_HS400;
+ 
+ 	if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23)
+ 		host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN;
+ 
+-	if (host->caps & MMC_CAP_8_BIT_DATA &&
++	if (host->mmc->caps & MMC_CAP_8_BIT_DATA &&
+ 	    imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
+ 		host->mmc->caps2 |= MMC_CAP2_HS400_ES;
+ 		host->mmc_host_ops.hs400_enhanced_strobe =
+diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
+index 3997cad1f793d..cfb891430174a 100644
+--- a/drivers/mmc/host/sdhci-of-arasan.c
++++ b/drivers/mmc/host/sdhci-of-arasan.c
+@@ -25,6 +25,7 @@
+ #include <linux/firmware/xlnx-zynqmp.h>
+ 
+ #include "cqhci.h"
++#include "sdhci-cqhci.h"
+ #include "sdhci-pltfm.h"
+ 
+ #define SDHCI_ARASAN_VENDOR_REGISTER	0x78
+@@ -366,7 +367,7 @@ static void sdhci_arasan_reset(struct sdhci_host *host, u8 mask)
+ 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ 	struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host);
+ 
+-	sdhci_reset(host, mask);
++	sdhci_and_cqhci_reset(host, mask);
+ 
+ 	if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_FORCE_CDTEST) {
+ 		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
+index 413925bce0ca8..c71000a07656e 100644
+--- a/drivers/mmc/host/sdhci-tegra.c
++++ b/drivers/mmc/host/sdhci-tegra.c
+@@ -28,6 +28,7 @@
+ 
+ #include <soc/tegra/common.h>
+ 
++#include "sdhci-cqhci.h"
+ #include "sdhci-pltfm.h"
+ #include "cqhci.h"
+ 
+@@ -367,7 +368,7 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
+ 	const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
+ 	u32 misc_ctrl, clk_ctrl, pad_ctrl;
+ 
+-	sdhci_reset(host, mask);
++	sdhci_and_cqhci_reset(host, mask);
+ 
+ 	if (!(mask & SDHCI_RESET_ALL))
+ 		return;
+diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c
+index e7ced1496a073..b82ab5f1fcf31 100644
+--- a/drivers/mmc/host/sdhci_am654.c
++++ b/drivers/mmc/host/sdhci_am654.c
+@@ -15,6 +15,7 @@
+ #include <linux/sys_soc.h>
+ 
+ #include "cqhci.h"
++#include "sdhci-cqhci.h"
+ #include "sdhci-pltfm.h"
+ 
+ /* CTL_CFG Registers */
+@@ -378,7 +379,7 @@ static void sdhci_am654_reset(struct sdhci_host *host, u8 mask)
+ 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ 	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
+ 
+-	sdhci_reset(host, mask);
++	sdhci_and_cqhci_reset(host, mask);
+ 
+ 	if (sdhci_am654->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST) {
+ 		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+@@ -464,7 +465,7 @@ static struct sdhci_ops sdhci_am654_ops = {
+ 	.set_clock = sdhci_am654_set_clock,
+ 	.write_b = sdhci_am654_write_b,
+ 	.irq = sdhci_am654_cqhci_irq,
+-	.reset = sdhci_reset,
++	.reset = sdhci_and_cqhci_reset,
+ };
+ 
+ static const struct sdhci_pltfm_data sdhci_am654_pdata = {
+@@ -494,7 +495,7 @@ static struct sdhci_ops sdhci_j721e_8bit_ops = {
+ 	.set_clock = sdhci_am654_set_clock,
+ 	.write_b = sdhci_am654_write_b,
+ 	.irq = sdhci_am654_cqhci_irq,
+-	.reset = sdhci_reset,
++	.reset = sdhci_and_cqhci_reset,
+ };
+ 
+ static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = {
+diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
+index 3a2d109a3792f..199cb200f2bdd 100644
+--- a/drivers/net/can/at91_can.c
++++ b/drivers/net/can/at91_can.c
+@@ -452,7 +452,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	unsigned int mb, prio;
+ 	u32 reg_mid, reg_mcr;
+ 
+-	if (can_dropped_invalid_skb(dev, skb))
++	if (can_dev_dropped_skb(dev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	mb = get_tx_next_mb(priv);
+diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c
+index d6605dbb7737b..c63f7fc1e6917 100644
+--- a/drivers/net/can/c_can/c_can_main.c
++++ b/drivers/net/can/c_can/c_can_main.c
+@@ -457,7 +457,7 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
+ 	struct c_can_tx_ring *tx_ring = &priv->tx;
+ 	u32 idx, obj, cmd = IF_COMM_TX;
+ 
+-	if (can_dropped_invalid_skb(dev, skb))
++	if (can_dev_dropped_skb(dev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	if (c_can_tx_busy(priv, tx_ring))
+diff --git a/drivers/net/can/can327.c b/drivers/net/can/can327.c
+index 0aa1af31d0fe4..0941977807761 100644
+--- a/drivers/net/can/can327.c
++++ b/drivers/net/can/can327.c
+@@ -813,7 +813,7 @@ static netdev_tx_t can327_netdev_start_xmit(struct sk_buff *skb,
+ 	struct can327 *elm = netdev_priv(dev);
+ 	struct can_frame *frame = (struct can_frame *)skb->data;
+ 
+-	if (can_dropped_invalid_skb(dev, skb))
++	if (can_dev_dropped_skb(dev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	/* We shouldn't get here after a hardware fault:
+diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
+index 0b9dfc76e769c..30909f3aab576 100644
+--- a/drivers/net/can/cc770/cc770.c
++++ b/drivers/net/can/cc770/cc770.c
+@@ -429,7 +429,7 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	struct cc770_priv *priv = netdev_priv(dev);
+ 	unsigned int mo = obj2msgobj(CC770_OBJ_TX);
+ 
+-	if (can_dropped_invalid_skb(dev, skb))
++	if (can_dev_dropped_skb(dev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	netif_stop_queue(dev);
+diff --git a/drivers/net/can/ctucanfd/ctucanfd_base.c b/drivers/net/can/ctucanfd/ctucanfd_base.c
+index 3c18d028bd8ce..c2c51d7af1bd4 100644
+--- a/drivers/net/can/ctucanfd/ctucanfd_base.c
++++ b/drivers/net/can/ctucanfd/ctucanfd_base.c
+@@ -600,7 +600,7 @@ static netdev_tx_t ctucan_start_xmit(struct sk_buff *skb, struct net_device *nde
+ 	bool ok;
+ 	unsigned long flags;
+ 
+-	if (can_dropped_invalid_skb(ndev, skb))
++	if (can_dev_dropped_skb(ndev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	if (unlikely(!CTU_CAN_FD_TXTNF(priv))) {
+diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
+index 07e0feac86292..3f37149d2c7aa 100644
+--- a/drivers/net/can/dev/skb.c
++++ b/drivers/net/can/dev/skb.c
+@@ -5,7 +5,6 @@
+  */
+ 
+ #include <linux/can/dev.h>
+-#include <linux/can/netlink.h>
+ #include <linux/module.h>
+ 
+ #define MOD_DESC "CAN device driver interface"
+@@ -300,7 +299,6 @@ static bool can_skb_headroom_valid(struct net_device *dev, struct sk_buff *skb)
+ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb)
+ {
+ 	const struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
+-	struct can_priv *priv = netdev_priv(dev);
+ 
+ 	if (skb->protocol == htons(ETH_P_CAN)) {
+ 		if (unlikely(skb->len != CAN_MTU ||
+@@ -314,13 +312,8 @@ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb)
+ 		goto inval_skb;
+ 	}
+ 
+-	if (!can_skb_headroom_valid(dev, skb)) {
+-		goto inval_skb;
+-	} else if (priv->ctrlmode & CAN_CTRLMODE_LISTENONLY) {
+-		netdev_info_once(dev,
+-				 "interface in listen only mode, dropping skb\n");
++	if (!can_skb_headroom_valid(dev, skb))
+ 		goto inval_skb;
+-	}
+ 
+ 	return false;
+ 
+diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c
+index ccb438eca517d..1fcc65350f102 100644
+--- a/drivers/net/can/flexcan/flexcan-core.c
++++ b/drivers/net/can/flexcan/flexcan-core.c
+@@ -742,7 +742,7 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de
+ 	u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | ((can_fd_len2dlc(cfd->len)) << 16);
+ 	int i;
+ 
+-	if (can_dropped_invalid_skb(dev, skb))
++	if (can_dev_dropped_skb(dev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	netif_stop_queue(dev);
+diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c
+index 6c37aab93eb3a..4bedcc3eea0d6 100644
+--- a/drivers/net/can/grcan.c
++++ b/drivers/net/can/grcan.c
+@@ -1345,7 +1345,7 @@ static netdev_tx_t grcan_start_xmit(struct sk_buff *skb,
+ 	unsigned long flags;
+ 	u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT;
+ 
+-	if (can_dropped_invalid_skb(dev, skb))
++	if (can_dev_dropped_skb(dev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	/* Trying to transmit in silent mode will generate error interrupts, but
+diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
+index ad7a89b95da71..78b6e31487cff 100644
+--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
++++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
+@@ -860,7 +860,7 @@ static netdev_tx_t ifi_canfd_start_xmit(struct sk_buff *skb,
+ 	u32 txst, txid, txdlc;
+ 	int i;
+ 
+-	if (can_dropped_invalid_skb(ndev, skb))
++	if (can_dev_dropped_skb(ndev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	/* Check if the TX buffer is full */
+diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
+index 71a2caae07579..0732a50921418 100644
+--- a/drivers/net/can/janz-ican3.c
++++ b/drivers/net/can/janz-ican3.c
+@@ -1693,7 +1693,7 @@ static netdev_tx_t ican3_xmit(struct sk_buff *skb, struct net_device *ndev)
+ 	void __iomem *desc_addr;
+ 	unsigned long flags;
+ 
+-	if (can_dropped_invalid_skb(ndev, skb))
++	if (can_dev_dropped_skb(ndev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	spin_lock_irqsave(&mod->lock, flags);
+diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
+index ed54c0b3c7d46..e7cc499c17733 100644
+--- a/drivers/net/can/kvaser_pciefd.c
++++ b/drivers/net/can/kvaser_pciefd.c
+@@ -775,7 +775,7 @@ static netdev_tx_t kvaser_pciefd_start_xmit(struct sk_buff *skb,
+ 	int nwords;
+ 	u8 count;
+ 
+-	if (can_dropped_invalid_skb(netdev, skb))
++	if (can_dev_dropped_skb(netdev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	nwords = kvaser_pciefd_prepare_tx_packet(&packet, can, skb);
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index 4709c012b1dc9..4dc67fdfcdb9d 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -1722,7 +1722,7 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb,
+ {
+ 	struct m_can_classdev *cdev = netdev_priv(dev);
+ 
+-	if (can_dropped_invalid_skb(dev, skb))
++	if (can_dev_dropped_skb(dev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	if (cdev->is_peripheral) {
+diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
+index 2119fbb287efc..a6829cdc0e81f 100644
+--- a/drivers/net/can/mscan/mscan.c
++++ b/drivers/net/can/mscan/mscan.c
+@@ -191,7 +191,7 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	int i, rtr, buf_id;
+ 	u32 can_id;
+ 
+-	if (can_dropped_invalid_skb(dev, skb))
++	if (can_dev_dropped_skb(dev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	out_8(&regs->cantier, 0);
+diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
+index 0558ff67ec6ab..2a44b2803e555 100644
+--- a/drivers/net/can/pch_can.c
++++ b/drivers/net/can/pch_can.c
+@@ -882,7 +882,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev)
+ 	int i;
+ 	u32 id2;
+ 
+-	if (can_dropped_invalid_skb(ndev, skb))
++	if (can_dev_dropped_skb(ndev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	tx_obj_no = priv->tx_obj;
+diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c
+index f8420cc1d9075..31c9c127e24bb 100644
+--- a/drivers/net/can/peak_canfd/peak_canfd.c
++++ b/drivers/net/can/peak_canfd/peak_canfd.c
+@@ -651,7 +651,7 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb,
+ 	int room_left;
+ 	u8 len;
+ 
+-	if (can_dropped_invalid_skb(ndev, skb))
++	if (can_dev_dropped_skb(ndev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	msg_size = ALIGN(sizeof(*msg) + cf->len, 4);
+diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
+index 6ee968c59ac90..cc43c9c5e38c5 100644
+--- a/drivers/net/can/rcar/rcar_can.c
++++ b/drivers/net/can/rcar/rcar_can.c
+@@ -590,7 +590,7 @@ static netdev_tx_t rcar_can_start_xmit(struct sk_buff *skb,
+ 	struct can_frame *cf = (struct can_frame *)skb->data;
+ 	u32 data, i;
+ 
+-	if (can_dropped_invalid_skb(ndev, skb))
++	if (can_dev_dropped_skb(ndev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	if (cf->can_id & CAN_EFF_FLAG)	/* Extended frame format */
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
+index d77c8d6d191a6..26ba650a8cbc2 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -81,8 +81,7 @@ enum rcanfd_chip_id {
+ 
+ /* RSCFDnCFDGERFL / RSCFDnGERFL */
+ #define RCANFD_GERFL_EEF0_7		GENMASK(23, 16)
+-#define RCANFD_GERFL_EEF1		BIT(17)
+-#define RCANFD_GERFL_EEF0		BIT(16)
++#define RCANFD_GERFL_EEF(ch)		BIT(16 + (ch))
+ #define RCANFD_GERFL_CMPOF		BIT(3)	/* CAN FD only */
+ #define RCANFD_GERFL_THLES		BIT(2)
+ #define RCANFD_GERFL_MES		BIT(1)
+@@ -90,7 +89,7 @@ enum rcanfd_chip_id {
+ 
+ #define RCANFD_GERFL_ERR(gpriv, x) \
+ 	((x) & (reg_v3u(gpriv, RCANFD_GERFL_EEF0_7, \
+-			RCANFD_GERFL_EEF0 | RCANFD_GERFL_EEF1) | \
++			RCANFD_GERFL_EEF(0) | RCANFD_GERFL_EEF(1)) | \
+ 		RCANFD_GERFL_MES | \
+ 		((gpriv)->fdmode ? RCANFD_GERFL_CMPOF : 0)))
+ 
+@@ -936,12 +935,8 @@ static void rcar_canfd_global_error(struct net_device *ndev)
+ 	u32 ridx = ch + RCANFD_RFFIFO_IDX;
+ 
+ 	gerfl = rcar_canfd_read(priv->base, RCANFD_GERFL);
+-	if ((gerfl & RCANFD_GERFL_EEF0) && (ch == 0)) {
+-		netdev_dbg(ndev, "Ch0: ECC Error flag\n");
+-		stats->tx_dropped++;
+-	}
+-	if ((gerfl & RCANFD_GERFL_EEF1) && (ch == 1)) {
+-		netdev_dbg(ndev, "Ch1: ECC Error flag\n");
++	if (gerfl & RCANFD_GERFL_EEF(ch)) {
++		netdev_dbg(ndev, "Ch%u: ECC Error flag\n", ch);
+ 		stats->tx_dropped++;
+ 	}
+ 	if (gerfl & RCANFD_GERFL_MES) {
+@@ -1481,7 +1476,7 @@ static netdev_tx_t rcar_canfd_start_xmit(struct sk_buff *skb,
+ 	unsigned long flags;
+ 	u32 ch = priv->channel;
+ 
+-	if (can_dropped_invalid_skb(ndev, skb))
++	if (can_dev_dropped_skb(ndev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	if (cf->can_id & CAN_EFF_FLAG) {
+diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
+index 98dfd5f295a71..a0a820174a00f 100644
+--- a/drivers/net/can/sja1000/sja1000.c
++++ b/drivers/net/can/sja1000/sja1000.c
+@@ -291,7 +291,7 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
+ 	u8 cmd_reg_val = 0x00;
+ 	int i;
+ 
+-	if (can_dropped_invalid_skb(dev, skb))
++	if (can_dev_dropped_skb(dev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	netif_stop_queue(dev);
+diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
+index 8d13fdf8c28a4..fbb34139daa1a 100644
+--- a/drivers/net/can/slcan/slcan-core.c
++++ b/drivers/net/can/slcan/slcan-core.c
+@@ -594,7 +594,7 @@ static netdev_tx_t slcan_netdev_xmit(struct sk_buff *skb,
+ {
+ 	struct slcan *sl = netdev_priv(dev);
+ 
+-	if (can_dropped_invalid_skb(dev, skb))
++	if (can_dev_dropped_skb(dev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	spin_lock(&sl->lock);
+diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
+index a5ef57f415f73..c72f505d29fee 100644
+--- a/drivers/net/can/softing/softing_main.c
++++ b/drivers/net/can/softing/softing_main.c
+@@ -60,7 +60,7 @@ static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb,
+ 	struct can_frame *cf = (struct can_frame *)skb->data;
+ 	uint8_t buf[DPRAM_TX_SIZE];
+ 
+-	if (can_dropped_invalid_skb(dev, skb))
++	if (can_dev_dropped_skb(dev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	spin_lock(&card->spin);
+diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c
+index b87dc420428d9..e1b8533a602e2 100644
+--- a/drivers/net/can/spi/hi311x.c
++++ b/drivers/net/can/spi/hi311x.c
+@@ -373,7 +373,7 @@ static netdev_tx_t hi3110_hard_start_xmit(struct sk_buff *skb,
+ 		return NETDEV_TX_BUSY;
+ 	}
+ 
+-	if (can_dropped_invalid_skb(net, skb))
++	if (can_dev_dropped_skb(net, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	netif_stop_queue(net);
+diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
+index 24883a65ca66a..79c4bab5f7246 100644
+--- a/drivers/net/can/spi/mcp251x.c
++++ b/drivers/net/can/spi/mcp251x.c
+@@ -789,7 +789,7 @@ static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb,
+ 		return NETDEV_TX_BUSY;
+ 	}
+ 
+-	if (can_dropped_invalid_skb(net, skb))
++	if (can_dev_dropped_skb(net, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	netif_stop_queue(net);
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c
+index ffb6c36b7d9bd..160528d3cc26b 100644
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c
+@@ -172,7 +172,7 @@ netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
+ 	u8 tx_head;
+ 	int err;
+ 
+-	if (can_dropped_invalid_skb(ndev, skb))
++	if (can_dev_dropped_skb(ndev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	if (mcp251xfd_tx_busy(priv, tx_ring))
+diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
+index 525309da1320a..2b78f9197681b 100644
+--- a/drivers/net/can/sun4i_can.c
++++ b/drivers/net/can/sun4i_can.c
+@@ -429,7 +429,7 @@ static netdev_tx_t sun4ican_start_xmit(struct sk_buff *skb, struct net_device *d
+ 	canid_t id;
+ 	int i;
+ 
+-	if (can_dropped_invalid_skb(dev, skb))
++	if (can_dev_dropped_skb(dev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	netif_stop_queue(dev);
+diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
+index b218fb3c6b760..27700f72eac25 100644
+--- a/drivers/net/can/ti_hecc.c
++++ b/drivers/net/can/ti_hecc.c
+@@ -470,7 +470,7 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)
+ 	u32 mbxno, mbx_mask, data;
+ 	unsigned long flags;
+ 
+-	if (can_dropped_invalid_skb(ndev, skb))
++	if (can_dev_dropped_skb(ndev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	mbxno = get_tx_head_mb(priv);
+diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
+index d31191686a549..050c0b49938a4 100644
+--- a/drivers/net/can/usb/ems_usb.c
++++ b/drivers/net/can/usb/ems_usb.c
+@@ -747,7 +747,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne
+ 	size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN
+ 			+ sizeof(struct cpc_can_msg);
+ 
+-	if (can_dropped_invalid_skb(netdev, skb))
++	if (can_dev_dropped_skb(netdev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	/* create a URB, and a buffer for it, and copy the data to the URB */
+diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c
+index 1bcfad11b1e44..81b88e9e5bdc0 100644
+--- a/drivers/net/can/usb/esd_usb.c
++++ b/drivers/net/can/usb/esd_usb.c
+@@ -725,7 +725,7 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb,
+ 	int ret = NETDEV_TX_OK;
+ 	size_t size = sizeof(struct esd_usb_msg);
+ 
+-	if (can_dropped_invalid_skb(netdev, skb))
++	if (can_dev_dropped_skb(netdev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	/* create a URB, and a buffer for it, and copy the data to the URB */
+diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
+index 51294b7170405..25f863b4f5f06 100644
+--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
++++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
+@@ -1913,7 +1913,7 @@ static netdev_tx_t es58x_start_xmit(struct sk_buff *skb,
+ 	unsigned int frame_len;
+ 	int ret;
+ 
+-	if (can_dropped_invalid_skb(netdev, skb)) {
++	if (can_dev_dropped_skb(netdev, skb)) {
+ 		if (priv->tx_urb)
+ 			goto xmit_commit;
+ 		return NETDEV_TX_OK;
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index c1ff3c046d62c..cd4115a1b81c6 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -605,7 +605,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+ 	unsigned int idx;
+ 	struct gs_tx_context *txc;
+ 
+-	if (can_dropped_invalid_skb(netdev, skb))
++	if (can_dev_dropped_skb(netdev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	/* find an empty context to keep track of transmission */
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+index e91648ed73862..802e27c0ecedb 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+@@ -570,7 +570,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
+ 	unsigned int i;
+ 	unsigned long flags;
+ 
+-	if (can_dropped_invalid_skb(netdev, skb))
++	if (can_dev_dropped_skb(netdev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	urb = usb_alloc_urb(0, GFP_ATOMIC);
+diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c
+index 69346c63021fe..218b098b261df 100644
+--- a/drivers/net/can/usb/mcba_usb.c
++++ b/drivers/net/can/usb/mcba_usb.c
+@@ -311,7 +311,7 @@ static netdev_tx_t mcba_usb_start_xmit(struct sk_buff *skb,
+ 		.cmd_id = MBCA_CMD_TRANSMIT_MESSAGE_EV
+ 	};
+ 
+-	if (can_dropped_invalid_skb(netdev, skb))
++	if (can_dev_dropped_skb(netdev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	ctx = mcba_usb_get_free_ctx(priv, cf);
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+index 8c9d53f6e24c3..ca92d027ba3ef 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+@@ -351,7 +351,7 @@ static netdev_tx_t peak_usb_ndo_start_xmit(struct sk_buff *skb,
+ 	int i, err;
+ 	size_t size = dev->adapter->tx_buffer_size;
+ 
+-	if (can_dropped_invalid_skb(netdev, skb))
++	if (can_dev_dropped_skb(netdev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++)
+diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
+index 7c35f50fda4ee..67c2ff407d066 100644
+--- a/drivers/net/can/usb/ucan.c
++++ b/drivers/net/can/usb/ucan.c
+@@ -1120,7 +1120,7 @@ static netdev_tx_t ucan_start_xmit(struct sk_buff *skb,
+ 	struct can_frame *cf = (struct can_frame *)skb->data;
+ 
+ 	/* check skb */
+-	if (can_dropped_invalid_skb(netdev, skb))
++	if (can_dev_dropped_skb(netdev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	/* allocate a context and slow down tx path, if fifo state is low */
+diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
+index 64c00abe91cf0..8a5596ce4e463 100644
+--- a/drivers/net/can/usb/usb_8dev.c
++++ b/drivers/net/can/usb/usb_8dev.c
+@@ -602,7 +602,7 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,
+ 	int i, err;
+ 	size_t size = sizeof(struct usb_8dev_tx_msg);
+ 
+-	if (can_dropped_invalid_skb(netdev, skb))
++	if (can_dev_dropped_skb(netdev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	/* create a URB, and a buffer for it, and copy the data to the URB */
+diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
+index 5d3172795ad01..43c812ea1de02 100644
+--- a/drivers/net/can/xilinx_can.c
++++ b/drivers/net/can/xilinx_can.c
+@@ -743,7 +743,7 @@ static netdev_tx_t xcan_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+ 	struct xcan_priv *priv = netdev_priv(ndev);
+ 	int ret;
+ 
+-	if (can_dropped_invalid_skb(ndev, skb))
++	if (can_dev_dropped_skb(ndev, skb))
+ 		return NETDEV_TX_OK;
+ 
+ 	if (priv->devtype.flags & XCAN_FLAG_TX_MAILBOXES)
+diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+index 53dc8d5fede86..c51d9edb3828a 100644
+--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+@@ -1004,8 +1004,10 @@ static int xgene_enet_open(struct net_device *ndev)
+ 
+ 	xgene_enet_napi_enable(pdata);
+ 	ret = xgene_enet_register_irq(ndev);
+-	if (ret)
++	if (ret) {
++		xgene_enet_napi_disable(pdata);
+ 		return ret;
++	}
+ 
+ 	if (ndev->phydev) {
+ 		phy_start(ndev->phydev);
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
+index 8b53d6688a4bd..958b7f8c77d91 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
+@@ -585,6 +585,7 @@ static int aq_update_txsa(struct aq_nic_s *nic, const unsigned int sc_idx,
+ 
+ 	ret = aq_mss_set_egress_sakey_record(hw, &key_rec, sa_idx);
+ 
++	memzero_explicit(&key_rec, sizeof(key_rec));
+ 	return ret;
+ }
+ 
+@@ -932,6 +933,7 @@ static int aq_update_rxsa(struct aq_nic_s *nic, const unsigned int sc_idx,
+ 
+ 	ret = aq_mss_set_ingress_sakey_record(hw, &sa_key_record, sa_idx);
+ 
++	memzero_explicit(&sa_key_record, sizeof(sa_key_record));
+ 	return ret;
+ }
+ 
+diff --git a/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c b/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c
+index 36c7cf05630a1..4319249595207 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c
++++ b/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c
+@@ -757,6 +757,7 @@ set_ingress_sakey_record(struct aq_hw_s *hw,
+ 			 u16 table_index)
+ {
+ 	u16 packed_record[18];
++	int ret;
+ 
+ 	if (table_index >= NUMROWS_INGRESSSAKEYRECORD)
+ 		return -EINVAL;
+@@ -789,9 +790,12 @@ set_ingress_sakey_record(struct aq_hw_s *hw,
+ 
+ 	packed_record[16] = rec->key_len & 0x3;
+ 
+-	return set_raw_ingress_record(hw, packed_record, 18, 2,
+-				      ROWOFFSET_INGRESSSAKEYRECORD +
+-					      table_index);
++	ret = set_raw_ingress_record(hw, packed_record, 18, 2,
++				     ROWOFFSET_INGRESSSAKEYRECORD +
++				     table_index);
++
++	memzero_explicit(packed_record, sizeof(packed_record));
++	return ret;
+ }
+ 
+ int aq_mss_set_ingress_sakey_record(struct aq_hw_s *hw,
+@@ -1739,14 +1743,14 @@ static int set_egress_sakey_record(struct aq_hw_s *hw,
+ 	ret = set_raw_egress_record(hw, packed_record, 8, 2,
+ 				    ROWOFFSET_EGRESSSAKEYRECORD + table_index);
+ 	if (unlikely(ret))
+-		return ret;
++		goto clear_key;
+ 	ret = set_raw_egress_record(hw, packed_record + 8, 8, 2,
+ 				    ROWOFFSET_EGRESSSAKEYRECORD + table_index -
+ 					    32);
+-	if (unlikely(ret))
+-		return ret;
+ 
+-	return 0;
++clear_key:
++	memzero_explicit(packed_record, sizeof(packed_record));
++	return ret;
+ }
+ 
+ int aq_mss_set_egress_sakey_record(struct aq_hw_s *hw,
+diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
+index 56e0fb07aec7f..1cd3c289f49be 100644
+--- a/drivers/net/ethernet/broadcom/Kconfig
++++ b/drivers/net/ethernet/broadcom/Kconfig
+@@ -77,7 +77,7 @@ config BCMGENET
+ 	select BCM7XXX_PHY
+ 	select MDIO_BCM_UNIMAC
+ 	select DIMLIB
+-	select BROADCOM_PHY if ARCH_BCM2835
++	select BROADCOM_PHY if (ARCH_BCM2835 && PTP_1588_CLOCK_OPTIONAL)
+ 	help
+ 	  This driver supports the built-in Ethernet MACs found in the
+ 	  Broadcom BCM7xxx Set Top Box family chipset.
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+index 96da0ba3d5078..be5df8fca264e 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+@@ -12894,8 +12894,8 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
+ 	rcu_read_lock();
+ 	hlist_for_each_entry_rcu(fltr, head, hash) {
+ 		if (bnxt_fltr_match(fltr, new_fltr)) {
++			rc = fltr->sw_id;
+ 			rcu_read_unlock();
+-			rc = 0;
+ 			goto err_free;
+ 		}
+ 	}
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+index 87eb5362ad70a..a182254569661 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+@@ -162,7 +162,7 @@ static int bnxt_set_coalesce(struct net_device *dev,
+ 	}
+ 
+ reset_coalesce:
+-	if (netif_running(dev)) {
++	if (test_bit(BNXT_STATE_OPEN, &bp->state)) {
+ 		if (update_stats) {
+ 			rc = bnxt_close_nic(bp, true, false);
+ 			if (!rc)
+diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+index 174b1e156669e..481d85bfa483f 100644
+--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+@@ -1302,6 +1302,7 @@ static int cxgb_up(struct adapter *adap)
+ 		if (ret < 0) {
+ 			CH_ERR(adap, "failed to bind qsets, err %d\n", ret);
+ 			t3_intr_disable(adap);
++			quiesce_rx(adap);
+ 			free_irq_resources(adap);
+ 			err = ret;
+ 			goto out;
+diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+index c2822e635f896..40bb473ec3c89 100644
+--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+@@ -858,7 +858,7 @@ static int cxgb4vf_open(struct net_device *dev)
+ 	 */
+ 	err = t4vf_update_port_info(pi);
+ 	if (err < 0)
+-		return err;
++		goto err_unwind;
+ 
+ 	/*
+ 	 * Note that this interface is up and start everything up ...
+diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c
+index 39ae965cd4f64..b0c756b65cc2e 100644
+--- a/drivers/net/ethernet/freescale/fman/mac.c
++++ b/drivers/net/ethernet/freescale/fman/mac.c
+@@ -882,12 +882,21 @@ _return:
+ 	return err;
+ }
+ 
++static int mac_remove(struct platform_device *pdev)
++{
++	struct mac_device *mac_dev = platform_get_drvdata(pdev);
++
++	platform_device_unregister(mac_dev->priv->eth_dev);
++	return 0;
++}
++
+ static struct platform_driver mac_driver = {
+ 	.driver = {
+ 		.name		= KBUILD_MODNAME,
+ 		.of_match_table	= mac_match,
+ 	},
+ 	.probe		= mac_probe,
++	.remove		= mac_remove,
+ };
+ 
+ builtin_platform_driver(mac_driver);
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+index 5a9e6563923eb..24a701fd140e9 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+@@ -2438,6 +2438,8 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
+ 		list_for_each_entry(f, &adapter->vlan_filter_list, list) {
+ 			if (f->is_new_vlan) {
+ 				f->is_new_vlan = false;
++				if (!f->vlan.vid)
++					continue;
+ 				if (f->vlan.tpid == ETH_P_8021Q)
+ 					set_bit(f->vlan.vid,
+ 						adapter->vsi.active_cvlans);
+diff --git a/drivers/net/ethernet/intel/ice/ice_base.c b/drivers/net/ethernet/intel/ice/ice_base.c
+index 1e32438081780..9ee022bb8ec21 100644
+--- a/drivers/net/ethernet/intel/ice/ice_base.c
++++ b/drivers/net/ethernet/intel/ice/ice_base.c
+@@ -959,7 +959,7 @@ ice_vsi_stop_tx_ring(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,
+ 	 * associated to the queue to schedule NAPI handler
+ 	 */
+ 	q_vector = ring->q_vector;
+-	if (q_vector)
++	if (q_vector && !(vsi->vf && ice_is_vf_disabled(vsi->vf)))
+ 		ice_trigger_sw_intr(hw, q_vector);
+ 
+ 	status = ice_dis_vsi_txq(vsi->port_info, txq_meta->vsi_idx,
+diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
+index 58d483e2f539e..11399f55e6476 100644
+--- a/drivers/net/ethernet/intel/ice/ice_lib.c
++++ b/drivers/net/ethernet/intel/ice/ice_lib.c
+@@ -2222,6 +2222,31 @@ int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi)
+ 	return ice_vsi_stop_tx_rings(vsi, ICE_NO_RESET, 0, vsi->xdp_rings, vsi->num_xdp_txq);
+ }
+ 
++/**
++ * ice_vsi_is_rx_queue_active
++ * @vsi: the VSI being configured
++ *
++ * Return true if at least one queue is active.
++ */
++bool ice_vsi_is_rx_queue_active(struct ice_vsi *vsi)
++{
++	struct ice_pf *pf = vsi->back;
++	struct ice_hw *hw = &pf->hw;
++	int i;
++
++	ice_for_each_rxq(vsi, i) {
++		u32 rx_reg;
++		int pf_q;
++
++		pf_q = vsi->rxq_map[i];
++		rx_reg = rd32(hw, QRX_CTRL(pf_q));
++		if (rx_reg & QRX_CTRL_QENA_STAT_M)
++			return true;
++	}
++
++	return false;
++}
++
+ /**
+  * ice_vsi_is_vlan_pruning_ena - check if VLAN pruning is enabled or not
+  * @vsi: VSI to check whether or not VLAN pruning is enabled.
+diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h
+index 8712b1d2ceec9..441fb132f1941 100644
+--- a/drivers/net/ethernet/intel/ice/ice_lib.h
++++ b/drivers/net/ethernet/intel/ice/ice_lib.h
+@@ -127,4 +127,5 @@ u16 ice_vsi_num_non_zero_vlans(struct ice_vsi *vsi);
+ bool ice_is_feature_supported(struct ice_pf *pf, enum ice_feature f);
+ void ice_clear_feature_support(struct ice_pf *pf, enum ice_feature f);
+ void ice_init_feature_support(struct ice_pf *pf);
++bool ice_vsi_is_rx_queue_active(struct ice_vsi *vsi);
+ #endif /* !_ICE_LIB_H_ */
+diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
+index 0abeed092de1d..1c51778db951b 100644
+--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
++++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
+@@ -576,7 +576,10 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
+ 			return -EINVAL;
+ 		}
+ 		ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id);
+-		ice_vsi_stop_all_rx_rings(vsi);
++
++		if (ice_vsi_is_rx_queue_active(vsi))
++			ice_vsi_stop_all_rx_rings(vsi);
++
+ 		dev_dbg(dev, "VF is already disabled, there is no need for resetting it, telling VM, all is fine %d\n",
+ 			vf->vf_id);
+ 		return 0;
+diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
+index b6be0552a6c1d..40a5957b14493 100644
+--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
++++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
+@@ -2481,6 +2481,7 @@ out_free:
+ 	for (i = 0; i < mp->rxq_count; i++)
+ 		rxq_deinit(mp->rxq + i);
+ out:
++	napi_disable(&mp->napi);
+ 	free_irq(dev->irq, dev);
+ 
+ 	return err;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+index d686c7b6252f4..9c2baa437c231 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -863,6 +863,7 @@ static int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura)
+ 	}
+ 
+ 	sq->head = 0;
++	sq->cons_head = 0;
+ 	sq->sqe_per_sqb = (pfvf->hw.sqb_size / sq->sqe_size) - 1;
+ 	sq->num_sqbs = (qset->sqe_cnt + sq->sqe_per_sqb) / sq->sqe_per_sqb;
+ 	/* Set SQE threshold to 10% of total SQEs */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+index 9376d0e62914b..80fde101df96d 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+@@ -15,6 +15,7 @@
+ #include <net/ip.h>
+ #include <linux/bpf.h>
+ #include <linux/bpf_trace.h>
++#include <linux/bitfield.h>
+ 
+ #include "otx2_reg.h"
+ #include "otx2_common.h"
+@@ -1161,6 +1162,59 @@ int otx2_set_real_num_queues(struct net_device *netdev,
+ }
+ EXPORT_SYMBOL(otx2_set_real_num_queues);
+ 
++static char *nix_sqoperr_e_str[NIX_SQOPERR_MAX] = {
++	"NIX_SQOPERR_OOR",
++	"NIX_SQOPERR_CTX_FAULT",
++	"NIX_SQOPERR_CTX_POISON",
++	"NIX_SQOPERR_DISABLED",
++	"NIX_SQOPERR_SIZE_ERR",
++	"NIX_SQOPERR_OFLOW",
++	"NIX_SQOPERR_SQB_NULL",
++	"NIX_SQOPERR_SQB_FAULT",
++	"NIX_SQOPERR_SQE_SZ_ZERO",
++};
++
++static char *nix_mnqerr_e_str[NIX_MNQERR_MAX] = {
++	"NIX_MNQERR_SQ_CTX_FAULT",
++	"NIX_MNQERR_SQ_CTX_POISON",
++	"NIX_MNQERR_SQB_FAULT",
++	"NIX_MNQERR_SQB_POISON",
++	"NIX_MNQERR_TOTAL_ERR",
++	"NIX_MNQERR_LSO_ERR",
++	"NIX_MNQERR_CQ_QUERY_ERR",
++	"NIX_MNQERR_MAX_SQE_SIZE_ERR",
++	"NIX_MNQERR_MAXLEN_ERR",
++	"NIX_MNQERR_SQE_SIZEM1_ZERO",
++};
++
++static char *nix_snd_status_e_str[NIX_SND_STATUS_MAX] =  {
++	"NIX_SND_STATUS_GOOD",
++	"NIX_SND_STATUS_SQ_CTX_FAULT",
++	"NIX_SND_STATUS_SQ_CTX_POISON",
++	"NIX_SND_STATUS_SQB_FAULT",
++	"NIX_SND_STATUS_SQB_POISON",
++	"NIX_SND_STATUS_HDR_ERR",
++	"NIX_SND_STATUS_EXT_ERR",
++	"NIX_SND_STATUS_JUMP_FAULT",
++	"NIX_SND_STATUS_JUMP_POISON",
++	"NIX_SND_STATUS_CRC_ERR",
++	"NIX_SND_STATUS_IMM_ERR",
++	"NIX_SND_STATUS_SG_ERR",
++	"NIX_SND_STATUS_MEM_ERR",
++	"NIX_SND_STATUS_INVALID_SUBDC",
++	"NIX_SND_STATUS_SUBDC_ORDER_ERR",
++	"NIX_SND_STATUS_DATA_FAULT",
++	"NIX_SND_STATUS_DATA_POISON",
++	"NIX_SND_STATUS_NPC_DROP_ACTION",
++	"NIX_SND_STATUS_LOCK_VIOL",
++	"NIX_SND_STATUS_NPC_UCAST_CHAN_ERR",
++	"NIX_SND_STATUS_NPC_MCAST_CHAN_ERR",
++	"NIX_SND_STATUS_NPC_MCAST_ABORT",
++	"NIX_SND_STATUS_NPC_VTAG_PTR_ERR",
++	"NIX_SND_STATUS_NPC_VTAG_SIZE_ERR",
++	"NIX_SND_STATUS_SEND_STATS_ERR",
++};
++
+ static irqreturn_t otx2_q_intr_handler(int irq, void *data)
+ {
+ 	struct otx2_nic *pf = data;
+@@ -1194,46 +1248,67 @@ static irqreturn_t otx2_q_intr_handler(int irq, void *data)
+ 
+ 	/* SQ */
+ 	for (qidx = 0; qidx < pf->hw.tot_tx_queues; qidx++) {
++		u64 sq_op_err_dbg, mnq_err_dbg, snd_err_dbg;
++		u8 sq_op_err_code, mnq_err_code, snd_err_code;
++
++		/* Below debug registers captures first errors corresponding to
++		 * those registers. We don't have to check against SQ qid as
++		 * these are fatal errors.
++		 */
++
+ 		ptr = otx2_get_regaddr(pf, NIX_LF_SQ_OP_INT);
+ 		val = otx2_atomic64_add((qidx << 44), ptr);
+ 		otx2_write64(pf, NIX_LF_SQ_OP_INT, (qidx << 44) |
+ 			     (val & NIX_SQINT_BITS));
+ 
+-		if (!(val & (NIX_SQINT_BITS | BIT_ULL(42))))
+-			continue;
+-
+ 		if (val & BIT_ULL(42)) {
+ 			netdev_err(pf->netdev, "SQ%lld: error reading NIX_LF_SQ_OP_INT, NIX_LF_ERR_INT 0x%llx\n",
+ 				   qidx, otx2_read64(pf, NIX_LF_ERR_INT));
+-		} else {
+-			if (val & BIT_ULL(NIX_SQINT_LMT_ERR)) {
+-				netdev_err(pf->netdev, "SQ%lld: LMT store error NIX_LF_SQ_OP_ERR_DBG:0x%llx",
+-					   qidx,
+-					   otx2_read64(pf,
+-						       NIX_LF_SQ_OP_ERR_DBG));
+-				otx2_write64(pf, NIX_LF_SQ_OP_ERR_DBG,
+-					     BIT_ULL(44));
+-			}
+-			if (val & BIT_ULL(NIX_SQINT_MNQ_ERR)) {
+-				netdev_err(pf->netdev, "SQ%lld: Meta-descriptor enqueue error NIX_LF_MNQ_ERR_DGB:0x%llx\n",
+-					   qidx,
+-					   otx2_read64(pf, NIX_LF_MNQ_ERR_DBG));
+-				otx2_write64(pf, NIX_LF_MNQ_ERR_DBG,
+-					     BIT_ULL(44));
+-			}
+-			if (val & BIT_ULL(NIX_SQINT_SEND_ERR)) {
+-				netdev_err(pf->netdev, "SQ%lld: Send error, NIX_LF_SEND_ERR_DBG 0x%llx",
+-					   qidx,
+-					   otx2_read64(pf,
+-						       NIX_LF_SEND_ERR_DBG));
+-				otx2_write64(pf, NIX_LF_SEND_ERR_DBG,
+-					     BIT_ULL(44));
+-			}
+-			if (val & BIT_ULL(NIX_SQINT_SQB_ALLOC_FAIL))
+-				netdev_err(pf->netdev, "SQ%lld: SQB allocation failed",
+-					   qidx);
++			goto done;
+ 		}
+ 
++		sq_op_err_dbg = otx2_read64(pf, NIX_LF_SQ_OP_ERR_DBG);
++		if (!(sq_op_err_dbg & BIT(44)))
++			goto chk_mnq_err_dbg;
++
++		sq_op_err_code = FIELD_GET(GENMASK(7, 0), sq_op_err_dbg);
++		netdev_err(pf->netdev, "SQ%lld: NIX_LF_SQ_OP_ERR_DBG(%llx)  err=%s\n",
++			   qidx, sq_op_err_dbg, nix_sqoperr_e_str[sq_op_err_code]);
++
++		otx2_write64(pf, NIX_LF_SQ_OP_ERR_DBG, BIT_ULL(44));
++
++		if (sq_op_err_code == NIX_SQOPERR_SQB_NULL)
++			goto chk_mnq_err_dbg;
++
++		/* Err is not NIX_SQOPERR_SQB_NULL, call aq function to read SQ structure.
++		 * TODO: But we are in irq context. How to call mbox functions which does sleep
++		 */
++
++chk_mnq_err_dbg:
++		mnq_err_dbg = otx2_read64(pf, NIX_LF_MNQ_ERR_DBG);
++		if (!(mnq_err_dbg & BIT(44)))
++			goto chk_snd_err_dbg;
++
++		mnq_err_code = FIELD_GET(GENMASK(7, 0), mnq_err_dbg);
++		netdev_err(pf->netdev, "SQ%lld: NIX_LF_MNQ_ERR_DBG(%llx)  err=%s\n",
++			   qidx, mnq_err_dbg,  nix_mnqerr_e_str[mnq_err_code]);
++		otx2_write64(pf, NIX_LF_MNQ_ERR_DBG, BIT_ULL(44));
++
++chk_snd_err_dbg:
++		snd_err_dbg = otx2_read64(pf, NIX_LF_SEND_ERR_DBG);
++		if (snd_err_dbg & BIT(44)) {
++			snd_err_code = FIELD_GET(GENMASK(7, 0), snd_err_dbg);
++			netdev_err(pf->netdev, "SQ%lld: NIX_LF_SND_ERR_DBG:0x%llx err=%s\n",
++				   qidx, snd_err_dbg, nix_snd_status_e_str[snd_err_code]);
++			otx2_write64(pf, NIX_LF_SEND_ERR_DBG, BIT_ULL(44));
++		}
++
++done:
++		/* Print values and reset */
++		if (val & BIT_ULL(NIX_SQINT_SQB_ALLOC_FAIL))
++			netdev_err(pf->netdev, "SQ%lld: SQB allocation failed",
++				   qidx);
++
+ 		schedule_work(&pf->reset_task);
+ 	}
+ 
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h
+index 4bbd12ff26e64..e5f30fd778fc1 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_struct.h
+@@ -274,4 +274,61 @@ enum nix_sqint_e {
+ 			BIT_ULL(NIX_SQINT_SEND_ERR) | \
+ 			BIT_ULL(NIX_SQINT_SQB_ALLOC_FAIL))
+ 
++enum nix_sqoperr_e {
++	NIX_SQOPERR_OOR = 0,
++	NIX_SQOPERR_CTX_FAULT = 1,
++	NIX_SQOPERR_CTX_POISON = 2,
++	NIX_SQOPERR_DISABLED = 3,
++	NIX_SQOPERR_SIZE_ERR = 4,
++	NIX_SQOPERR_OFLOW = 5,
++	NIX_SQOPERR_SQB_NULL = 6,
++	NIX_SQOPERR_SQB_FAULT = 7,
++	NIX_SQOPERR_SQE_SZ_ZERO = 8,
++	NIX_SQOPERR_MAX,
++};
++
++enum nix_mnqerr_e {
++	NIX_MNQERR_SQ_CTX_FAULT = 0,
++	NIX_MNQERR_SQ_CTX_POISON = 1,
++	NIX_MNQERR_SQB_FAULT = 2,
++	NIX_MNQERR_SQB_POISON = 3,
++	NIX_MNQERR_TOTAL_ERR = 4,
++	NIX_MNQERR_LSO_ERR = 5,
++	NIX_MNQERR_CQ_QUERY_ERR = 6,
++	NIX_MNQERR_MAX_SQE_SIZE_ERR = 7,
++	NIX_MNQERR_MAXLEN_ERR = 8,
++	NIX_MNQERR_SQE_SIZEM1_ZERO = 9,
++	NIX_MNQERR_MAX,
++};
++
++enum nix_snd_status_e {
++	NIX_SND_STATUS_GOOD = 0x0,
++	NIX_SND_STATUS_SQ_CTX_FAULT = 0x1,
++	NIX_SND_STATUS_SQ_CTX_POISON = 0x2,
++	NIX_SND_STATUS_SQB_FAULT = 0x3,
++	NIX_SND_STATUS_SQB_POISON = 0x4,
++	NIX_SND_STATUS_HDR_ERR = 0x5,
++	NIX_SND_STATUS_EXT_ERR = 0x6,
++	NIX_SND_STATUS_JUMP_FAULT = 0x7,
++	NIX_SND_STATUS_JUMP_POISON = 0x8,
++	NIX_SND_STATUS_CRC_ERR = 0x9,
++	NIX_SND_STATUS_IMM_ERR = 0x10,
++	NIX_SND_STATUS_SG_ERR = 0x11,
++	NIX_SND_STATUS_MEM_ERR = 0x12,
++	NIX_SND_STATUS_INVALID_SUBDC = 0x13,
++	NIX_SND_STATUS_SUBDC_ORDER_ERR = 0x14,
++	NIX_SND_STATUS_DATA_FAULT = 0x15,
++	NIX_SND_STATUS_DATA_POISON = 0x16,
++	NIX_SND_STATUS_NPC_DROP_ACTION = 0x17,
++	NIX_SND_STATUS_LOCK_VIOL = 0x18,
++	NIX_SND_STATUS_NPC_UCAST_CHAN_ERR = 0x19,
++	NIX_SND_STATUS_NPC_MCAST_CHAN_ERR = 0x20,
++	NIX_SND_STATUS_NPC_MCAST_ABORT = 0x21,
++	NIX_SND_STATUS_NPC_VTAG_PTR_ERR = 0x22,
++	NIX_SND_STATUS_NPC_VTAG_SIZE_ERR = 0x23,
++	NIX_SND_STATUS_SEND_MEM_FAULT = 0x24,
++	NIX_SND_STATUS_SEND_STATS_ERR = 0x25,
++	NIX_SND_STATUS_MAX,
++};
++
+ #endif /* OTX2_STRUCT_H */
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+index a18e8efd0f1ee..664f977433f4a 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+@@ -435,6 +435,7 @@ static int otx2_tx_napi_handler(struct otx2_nic *pfvf,
+ 				struct otx2_cq_queue *cq, int budget)
+ {
+ 	int tx_pkts = 0, tx_bytes = 0, qidx;
++	struct otx2_snd_queue *sq;
+ 	struct nix_cqe_tx_s *cqe;
+ 	int processed_cqe = 0;
+ 
+@@ -445,6 +446,9 @@ static int otx2_tx_napi_handler(struct otx2_nic *pfvf,
+ 		return 0;
+ 
+ process_cqe:
++	qidx = cq->cq_idx - pfvf->hw.rx_queues;
++	sq = &pfvf->qset.sq[qidx];
++
+ 	while (likely(processed_cqe < budget) && cq->pend_cqe) {
+ 		cqe = (struct nix_cqe_tx_s *)otx2_get_next_cqe(cq);
+ 		if (unlikely(!cqe)) {
+@@ -452,18 +456,20 @@ process_cqe:
+ 				return 0;
+ 			break;
+ 		}
++
+ 		if (cq->cq_type == CQ_XDP) {
+-			qidx = cq->cq_idx - pfvf->hw.rx_queues;
+-			otx2_xdp_snd_pkt_handler(pfvf, &pfvf->qset.sq[qidx],
+-						 cqe);
++			otx2_xdp_snd_pkt_handler(pfvf, sq, cqe);
+ 		} else {
+-			otx2_snd_pkt_handler(pfvf, cq,
+-					     &pfvf->qset.sq[cq->cint_idx],
+-					     cqe, budget, &tx_pkts, &tx_bytes);
++			otx2_snd_pkt_handler(pfvf, cq, sq, cqe, budget,
++					     &tx_pkts, &tx_bytes);
+ 		}
++
+ 		cqe->hdr.cqe_type = NIX_XQE_TYPE_INVALID;
+ 		processed_cqe++;
+ 		cq->pend_cqe--;
++
++		sq->cons_head++;
++		sq->cons_head &= (sq->sqe_cnt - 1);
+ 	}
+ 
+ 	/* Free CQEs to HW */
+@@ -972,17 +978,17 @@ bool otx2_sq_append_skb(struct net_device *netdev, struct otx2_snd_queue *sq,
+ {
+ 	struct netdev_queue *txq = netdev_get_tx_queue(netdev, qidx);
+ 	struct otx2_nic *pfvf = netdev_priv(netdev);
+-	int offset, num_segs, free_sqe;
++	int offset, num_segs, free_desc;
+ 	struct nix_sqe_hdr_s *sqe_hdr;
+ 
+-	/* Check if there is room for new SQE.
+-	 * 'Num of SQBs freed to SQ's pool - SQ's Aura count'
+-	 * will give free SQE count.
++	/* Check if there is enough room between producer
++	 * and consumer index.
+ 	 */
+-	free_sqe = (sq->num_sqbs - *sq->aura_fc_addr) * sq->sqe_per_sqb;
++	free_desc = (sq->cons_head - sq->head - 1 + sq->sqe_cnt) & (sq->sqe_cnt - 1);
++	if (free_desc < sq->sqe_thresh)
++		return false;
+ 
+-	if (free_sqe < sq->sqe_thresh ||
+-	    free_sqe < otx2_get_sqe_count(pfvf, skb))
++	if (free_desc < otx2_get_sqe_count(pfvf, skb))
+ 		return false;
+ 
+ 	num_segs = skb_shinfo(skb)->nr_frags + 1;
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
+index fbe62bbfb789a..93cac2c2664c2 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
+@@ -79,6 +79,7 @@ struct sg_list {
+ struct otx2_snd_queue {
+ 	u8			aura_id;
+ 	u16			head;
++	u16			cons_head;
+ 	u16			sqe_size;
+ 	u32			sqe_cnt;
+ 	u16			num_sqbs;
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c b/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c
+index dc3e3ddc60bf5..faa5109a09d7a 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c
+@@ -776,6 +776,7 @@ tx_done:
+ int prestera_rxtx_switch_init(struct prestera_switch *sw)
+ {
+ 	struct prestera_rxtx *rxtx;
++	int err;
+ 
+ 	rxtx = kzalloc(sizeof(*rxtx), GFP_KERNEL);
+ 	if (!rxtx)
+@@ -783,7 +784,11 @@ int prestera_rxtx_switch_init(struct prestera_switch *sw)
+ 
+ 	sw->rxtx = rxtx;
+ 
+-	return prestera_sdma_switch_init(sw);
++	err = prestera_sdma_switch_init(sw);
++	if (err)
++		kfree(rxtx);
++
++	return err;
+ }
+ 
+ void prestera_rxtx_switch_fini(struct prestera_switch *sw)
+diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
+index 3f0e5e64de505..57f4373b30ba1 100644
+--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
++++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
+@@ -1026,6 +1026,8 @@ static int mtk_star_enable(struct net_device *ndev)
+ 	return 0;
+ 
+ err_free_irq:
++	napi_disable(&priv->rx_napi);
++	napi_disable(&priv->tx_napi);
+ 	free_irq(ndev->irq, ndev);
+ err_free_skbs:
+ 	mtk_star_free_rx_skbs(priv);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 46ba4c2faad21..2e0d59ca62b50 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -1770,12 +1770,17 @@ void mlx5_cmd_flush(struct mlx5_core_dev *dev)
+ 	struct mlx5_cmd *cmd = &dev->cmd;
+ 	int i;
+ 
+-	for (i = 0; i < cmd->max_reg_cmds; i++)
+-		while (down_trylock(&cmd->sem))
++	for (i = 0; i < cmd->max_reg_cmds; i++) {
++		while (down_trylock(&cmd->sem)) {
+ 			mlx5_cmd_trigger_completions(dev);
++			cond_resched();
++		}
++	}
+ 
+-	while (down_trylock(&cmd->pages_sem))
++	while (down_trylock(&cmd->pages_sem)) {
+ 		mlx5_cmd_trigger_completions(dev);
++		cond_resched();
++	}
+ 
+ 	/* Unlock cmdif */
+ 	up(&cmd->pages_sem);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
+index 39ef2a2561a30..8099a21e674c9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
+@@ -164,6 +164,36 @@ static int mlx5_esw_bridge_port_changeupper(struct notifier_block *nb, void *ptr
+ 	return err;
+ }
+ 
++static int
++mlx5_esw_bridge_changeupper_validate_netdev(void *ptr)
++{
++	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
++	struct netdev_notifier_changeupper_info *info = ptr;
++	struct net_device *upper = info->upper_dev;
++	struct net_device *lower;
++	struct list_head *iter;
++
++	if (!netif_is_bridge_master(upper) || !netif_is_lag_master(dev))
++		return 0;
++
++	netdev_for_each_lower_dev(dev, lower, iter) {
++		struct mlx5_core_dev *mdev;
++		struct mlx5e_priv *priv;
++
++		if (!mlx5e_eswitch_rep(lower))
++			continue;
++
++		priv = netdev_priv(lower);
++		mdev = priv->mdev;
++		if (!mlx5_lag_is_active(mdev))
++			return -EAGAIN;
++		if (!mlx5_lag_is_shared_fdb(mdev))
++			return -EOPNOTSUPP;
++	}
++
++	return 0;
++}
++
+ static int mlx5_esw_bridge_switchdev_port_event(struct notifier_block *nb,
+ 						unsigned long event, void *ptr)
+ {
+@@ -171,6 +201,7 @@ static int mlx5_esw_bridge_switchdev_port_event(struct notifier_block *nb,
+ 
+ 	switch (event) {
+ 	case NETDEV_PRECHANGEUPPER:
++		err = mlx5_esw_bridge_changeupper_validate_netdev(ptr);
+ 		break;
+ 
+ 	case NETDEV_CHANGEUPPER:
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c
+index 305fde62a78de..3337241cfd84c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c
+@@ -6,70 +6,42 @@
+ #include "en/tc_priv.h"
+ #include "mlx5_core.h"
+ 
+-/* Must be aligned with enum flow_action_id. */
+ static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS] = {
+-	&mlx5e_tc_act_accept,
+-	&mlx5e_tc_act_drop,
+-	&mlx5e_tc_act_trap,
+-	&mlx5e_tc_act_goto,
+-	&mlx5e_tc_act_mirred,
+-	&mlx5e_tc_act_mirred,
+-	&mlx5e_tc_act_redirect_ingress,
+-	NULL, /* FLOW_ACTION_MIRRED_INGRESS, */
+-	&mlx5e_tc_act_vlan,
+-	&mlx5e_tc_act_vlan,
+-	&mlx5e_tc_act_vlan_mangle,
+-	&mlx5e_tc_act_tun_encap,
+-	&mlx5e_tc_act_tun_decap,
+-	&mlx5e_tc_act_pedit,
+-	&mlx5e_tc_act_pedit,
+-	&mlx5e_tc_act_csum,
+-	NULL, /* FLOW_ACTION_MARK, */
+-	&mlx5e_tc_act_ptype,
+-	NULL, /* FLOW_ACTION_PRIORITY, */
+-	NULL, /* FLOW_ACTION_WAKE, */
+-	NULL, /* FLOW_ACTION_QUEUE, */
+-	&mlx5e_tc_act_sample,
+-	&mlx5e_tc_act_police,
+-	&mlx5e_tc_act_ct,
+-	NULL, /* FLOW_ACTION_CT_METADATA, */
+-	&mlx5e_tc_act_mpls_push,
+-	&mlx5e_tc_act_mpls_pop,
+-	NULL, /* FLOW_ACTION_MPLS_MANGLE, */
+-	NULL, /* FLOW_ACTION_GATE, */
+-	NULL, /* FLOW_ACTION_PPPOE_PUSH, */
+-	NULL, /* FLOW_ACTION_JUMP, */
+-	NULL, /* FLOW_ACTION_PIPE, */
+-	&mlx5e_tc_act_vlan,
+-	&mlx5e_tc_act_vlan,
++	[FLOW_ACTION_ACCEPT] = &mlx5e_tc_act_accept,
++	[FLOW_ACTION_DROP] = &mlx5e_tc_act_drop,
++	[FLOW_ACTION_TRAP] = &mlx5e_tc_act_trap,
++	[FLOW_ACTION_GOTO] = &mlx5e_tc_act_goto,
++	[FLOW_ACTION_REDIRECT] = &mlx5e_tc_act_mirred,
++	[FLOW_ACTION_MIRRED] = &mlx5e_tc_act_mirred,
++	[FLOW_ACTION_REDIRECT_INGRESS] = &mlx5e_tc_act_redirect_ingress,
++	[FLOW_ACTION_VLAN_PUSH] = &mlx5e_tc_act_vlan,
++	[FLOW_ACTION_VLAN_POP] = &mlx5e_tc_act_vlan,
++	[FLOW_ACTION_VLAN_MANGLE] = &mlx5e_tc_act_vlan_mangle,
++	[FLOW_ACTION_TUNNEL_ENCAP] = &mlx5e_tc_act_tun_encap,
++	[FLOW_ACTION_TUNNEL_DECAP] = &mlx5e_tc_act_tun_decap,
++	[FLOW_ACTION_MANGLE] = &mlx5e_tc_act_pedit,
++	[FLOW_ACTION_ADD] = &mlx5e_tc_act_pedit,
++	[FLOW_ACTION_CSUM] = &mlx5e_tc_act_csum,
++	[FLOW_ACTION_PTYPE] = &mlx5e_tc_act_ptype,
++	[FLOW_ACTION_SAMPLE] = &mlx5e_tc_act_sample,
++	[FLOW_ACTION_POLICE] = &mlx5e_tc_act_police,
++	[FLOW_ACTION_CT] = &mlx5e_tc_act_ct,
++	[FLOW_ACTION_MPLS_PUSH] = &mlx5e_tc_act_mpls_push,
++	[FLOW_ACTION_MPLS_POP] = &mlx5e_tc_act_mpls_pop,
++	[FLOW_ACTION_VLAN_PUSH_ETH] = &mlx5e_tc_act_vlan,
++	[FLOW_ACTION_VLAN_POP_ETH] = &mlx5e_tc_act_vlan,
+ };
+ 
+-/* Must be aligned with enum flow_action_id. */
+ static struct mlx5e_tc_act *tc_acts_nic[NUM_FLOW_ACTIONS] = {
+-	&mlx5e_tc_act_accept,
+-	&mlx5e_tc_act_drop,
+-	NULL, /* FLOW_ACTION_TRAP, */
+-	&mlx5e_tc_act_goto,
+-	&mlx5e_tc_act_mirred_nic,
+-	NULL, /* FLOW_ACTION_MIRRED, */
+-	NULL, /* FLOW_ACTION_REDIRECT_INGRESS, */
+-	NULL, /* FLOW_ACTION_MIRRED_INGRESS, */
+-	NULL, /* FLOW_ACTION_VLAN_PUSH, */
+-	NULL, /* FLOW_ACTION_VLAN_POP, */
+-	NULL, /* FLOW_ACTION_VLAN_MANGLE, */
+-	NULL, /* FLOW_ACTION_TUNNEL_ENCAP, */
+-	NULL, /* FLOW_ACTION_TUNNEL_DECAP, */
+-	&mlx5e_tc_act_pedit,
+-	&mlx5e_tc_act_pedit,
+-	&mlx5e_tc_act_csum,
+-	&mlx5e_tc_act_mark,
+-	NULL, /* FLOW_ACTION_PTYPE, */
+-	NULL, /* FLOW_ACTION_PRIORITY, */
+-	NULL, /* FLOW_ACTION_WAKE, */
+-	NULL, /* FLOW_ACTION_QUEUE, */
+-	NULL, /* FLOW_ACTION_SAMPLE, */
+-	NULL, /* FLOW_ACTION_POLICE, */
+-	&mlx5e_tc_act_ct,
++	[FLOW_ACTION_ACCEPT] = &mlx5e_tc_act_accept,
++	[FLOW_ACTION_DROP] = &mlx5e_tc_act_drop,
++	[FLOW_ACTION_GOTO] = &mlx5e_tc_act_goto,
++	[FLOW_ACTION_REDIRECT] = &mlx5e_tc_act_mirred_nic,
++	[FLOW_ACTION_MANGLE] = &mlx5e_tc_act_pedit,
++	[FLOW_ACTION_ADD] = &mlx5e_tc_act_pedit,
++	[FLOW_ACTION_CSUM] = &mlx5e_tc_act_csum,
++	[FLOW_ACTION_MARK] = &mlx5e_tc_act_mark,
++	[FLOW_ACTION_CT] = &mlx5e_tc_act_ct,
+ };
+ 
+ /**
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+index ff8ca7a7e1036..aeed165a2dec2 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+@@ -11,6 +11,27 @@
+ 
+ #define INL_HDR_START_SZ (sizeof(((struct mlx5_wqe_eth_seg *)NULL)->inline_hdr.start))
+ 
++/* IPSEC inline data includes:
++ * 1. ESP trailer: up to 255 bytes of padding, 1 byte for pad length, 1 byte for
++ *    next header.
++ * 2. ESP authentication data: 16 bytes for ICV.
++ */
++#define MLX5E_MAX_TX_IPSEC_DS DIV_ROUND_UP(sizeof(struct mlx5_wqe_inline_seg) + \
++					   255 + 1 + 1 + 16, MLX5_SEND_WQE_DS)
++
++/* 366 should be big enough to cover all L2, L3 and L4 headers with possible
++ * encapsulations.
++ */
++#define MLX5E_MAX_TX_INLINE_DS DIV_ROUND_UP(366 - INL_HDR_START_SZ + VLAN_HLEN, \
++					    MLX5_SEND_WQE_DS)
++
++/* Sync the calculation with mlx5e_sq_calc_wqe_attr. */
++#define MLX5E_MAX_TX_WQEBBS DIV_ROUND_UP(MLX5E_TX_WQE_EMPTY_DS_COUNT + \
++					 MLX5E_MAX_TX_INLINE_DS + \
++					 MLX5E_MAX_TX_IPSEC_DS + \
++					 MAX_SKB_FRAGS + 1, \
++					 MLX5_SEND_WQEBB_NUM_DS)
++
+ #define MLX5E_RX_ERR_CQE(cqe) (get_cqe_opcode(cqe) != MLX5_CQE_RESP_SEND)
+ 
+ static inline
+@@ -424,6 +445,8 @@ mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg,
+ 
+ static inline u16 mlx5e_stop_room_for_wqe(struct mlx5_core_dev *mdev, u16 wqe_size)
+ {
++	WARN_ON_ONCE(PAGE_SIZE / MLX5_SEND_WQE_BB < mlx5e_get_max_sq_wqebbs(mdev));
++
+ 	/* A WQE must not cross the page boundary, hence two conditions:
+ 	 * 1. Its size must not exceed the page size.
+ 	 * 2. If the WQE size is X, and the space remaining in a page is less
+@@ -436,7 +459,6 @@ static inline u16 mlx5e_stop_room_for_wqe(struct mlx5_core_dev *mdev, u16 wqe_si
+ 		  "wqe_size %u is greater than max SQ WQEBBs %u",
+ 		  wqe_size, mlx5e_get_max_sq_wqebbs(mdev));
+ 
+-
+ 	return MLX5E_STOP_ROOM(wqe_size);
+ }
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+index 02eb2f0fa2ae7..6cf6a81775a85 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -5514,6 +5514,13 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)
+ 	if (priv->fs)
+ 		priv->fs->state_destroy = !test_bit(MLX5E_STATE_DESTROYING, &priv->state);
+ 
++	/* Validate the max_wqe_size_sq capability. */
++	if (WARN_ON_ONCE(mlx5e_get_max_sq_wqebbs(priv->mdev) < MLX5E_MAX_TX_WQEBBS)) {
++		mlx5_core_warn(priv->mdev, "MLX5E: Max SQ WQEBBs firmware capability: %u, needed %lu\n",
++			       mlx5e_get_max_sq_wqebbs(priv->mdev), MLX5E_MAX_TX_WQEBBS);
++		return -EIO;
++	}
++
+ 	/* max number of channels may have changed */
+ 	max_nch = mlx5e_calc_max_nch(priv->mdev, priv->netdev, profile);
+ 	if (priv->channels.params.num_channels > max_nch) {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+index a687f047e3aeb..229c14b1af004 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+@@ -4739,12 +4739,6 @@ int mlx5e_policer_validate(const struct flow_action *action,
+ 		return -EOPNOTSUPP;
+ 	}
+ 
+-	if (act->police.rate_pkt_ps) {
+-		NL_SET_ERR_MSG_MOD(extack,
+-				   "QoS offload not support packets per second");
+-		return -EOPNOTSUPP;
+-	}
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+index 4d45150a3f8ef..a30e50d9969f7 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+@@ -304,6 +304,8 @@ static void mlx5e_sq_calc_wqe_attr(struct sk_buff *skb, const struct mlx5e_tx_at
+ 	u16 ds_cnt_inl = 0;
+ 	u16 ds_cnt_ids = 0;
+ 
++	/* Sync the calculation with MLX5E_MAX_TX_WQEBBS. */
++
+ 	if (attr->insz)
+ 		ds_cnt_ids = DIV_ROUND_UP(sizeof(struct mlx5_wqe_inline_seg) + attr->insz,
+ 					  MLX5_SEND_WQE_DS);
+@@ -316,6 +318,9 @@ static void mlx5e_sq_calc_wqe_attr(struct sk_buff *skb, const struct mlx5e_tx_at
+ 			inl += VLAN_HLEN;
+ 
+ 		ds_cnt_inl = DIV_ROUND_UP(inl, MLX5_SEND_WQE_DS);
++		if (WARN_ON_ONCE(ds_cnt_inl > MLX5E_MAX_TX_INLINE_DS))
++			netdev_warn(skb->dev, "ds_cnt_inl = %u > max %u\n", ds_cnt_inl,
++				    (u16)MLX5E_MAX_TX_INLINE_DS);
+ 		ds_cnt += ds_cnt_inl;
+ 	}
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+index 6aa58044b949b..4d8b8f6143cc9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+@@ -1388,12 +1388,14 @@ void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw)
+ 		 esw->mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS",
+ 		 esw->esw_funcs.num_vfs, esw->enabled_vports);
+ 
+-	esw->fdb_table.flags &= ~MLX5_ESW_FDB_CREATED;
+-	if (esw->mode == MLX5_ESWITCH_OFFLOADS)
+-		esw_offloads_disable(esw);
+-	else if (esw->mode == MLX5_ESWITCH_LEGACY)
+-		esw_legacy_disable(esw);
+-	mlx5_esw_acls_ns_cleanup(esw);
++	if (esw->fdb_table.flags & MLX5_ESW_FDB_CREATED) {
++		esw->fdb_table.flags &= ~MLX5_ESW_FDB_CREATED;
++		if (esw->mode == MLX5_ESWITCH_OFFLOADS)
++			esw_offloads_disable(esw);
++		else if (esw->mode == MLX5_ESWITCH_LEGACY)
++			esw_legacy_disable(esw);
++		mlx5_esw_acls_ns_cleanup(esw);
++	}
+ 
+ 	if (esw->mode == MLX5_ESWITCH_OFFLOADS)
+ 		devl_rate_nodes_destroy(devlink);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+index a9f4c652f859c..3c68cac4a9c2c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+@@ -2207,7 +2207,7 @@ out_free:
+ static int esw_offloads_start(struct mlx5_eswitch *esw,
+ 			      struct netlink_ext_ack *extack)
+ {
+-	int err, err1;
++	int err;
+ 
+ 	esw->mode = MLX5_ESWITCH_OFFLOADS;
+ 	err = mlx5_eswitch_enable_locked(esw, esw->dev->priv.sriov.num_vfs);
+@@ -2215,11 +2215,6 @@ static int esw_offloads_start(struct mlx5_eswitch *esw,
+ 		NL_SET_ERR_MSG_MOD(extack,
+ 				   "Failed setting eswitch to offloads");
+ 		esw->mode = MLX5_ESWITCH_LEGACY;
+-		err1 = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_IGNORE_NUM_VFS);
+-		if (err1) {
+-			NL_SET_ERR_MSG_MOD(extack,
+-					   "Failed setting eswitch back to legacy");
+-		}
+ 		mlx5_rescan_drivers(esw->dev);
+ 	}
+ 	if (esw->offloads.inline_mode == MLX5_INLINE_MODE_NONE) {
+@@ -3272,19 +3267,12 @@ err_metadata:
+ static int esw_offloads_stop(struct mlx5_eswitch *esw,
+ 			     struct netlink_ext_ack *extack)
+ {
+-	int err, err1;
++	int err;
+ 
+ 	esw->mode = MLX5_ESWITCH_LEGACY;
+ 	err = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_IGNORE_NUM_VFS);
+-	if (err) {
++	if (err)
+ 		NL_SET_ERR_MSG_MOD(extack, "Failed setting eswitch to legacy");
+-		esw->mode = MLX5_ESWITCH_OFFLOADS;
+-		err1 = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_IGNORE_NUM_VFS);
+-		if (err1) {
+-			NL_SET_ERR_MSG_MOD(extack,
+-					   "Failed setting eswitch back to offloads");
+-		}
+-	}
+ 
+ 	return err;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
+index ee568bf34ae25..108a3503f413c 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
+@@ -30,9 +30,9 @@ mlx5_eswitch_termtbl_hash(struct mlx5_flow_act *flow_act,
+ 		     sizeof(dest->vport.num), hash);
+ 	hash = jhash((const void *)&dest->vport.vhca_id,
+ 		     sizeof(dest->vport.num), hash);
+-	if (dest->vport.pkt_reformat)
+-		hash = jhash(dest->vport.pkt_reformat,
+-			     sizeof(*dest->vport.pkt_reformat),
++	if (flow_act->pkt_reformat)
++		hash = jhash(flow_act->pkt_reformat,
++			     sizeof(*flow_act->pkt_reformat),
+ 			     hash);
+ 	return hash;
+ }
+@@ -53,9 +53,11 @@ mlx5_eswitch_termtbl_cmp(struct mlx5_flow_act *flow_act1,
+ 	if (ret)
+ 		return ret;
+ 
+-	return dest1->vport.pkt_reformat && dest2->vport.pkt_reformat ?
+-	       memcmp(dest1->vport.pkt_reformat, dest2->vport.pkt_reformat,
+-		      sizeof(*dest1->vport.pkt_reformat)) : 0;
++	if (flow_act1->pkt_reformat && flow_act2->pkt_reformat)
++		return memcmp(flow_act1->pkt_reformat, flow_act2->pkt_reformat,
++			      sizeof(*flow_act1->pkt_reformat));
++
++	return !(flow_act1->pkt_reformat == flow_act2->pkt_reformat);
+ }
+ 
+ static int
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index 07c583996c297..9d908a0ccfef1 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -152,7 +152,8 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
+ 		mlx5_unload_one(dev);
+ 		if (mlx5_health_wait_pci_up(dev))
+ 			mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
+-		mlx5_load_one(dev, false);
++		else
++			mlx5_load_one(dev, false);
+ 		devlink_remote_reload_actions_performed(priv_to_devlink(dev), 0,
+ 							BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
+ 							BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE));
+diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
+index 30f955efa8308..8f74c039b3be2 100644
+--- a/drivers/net/ethernet/neterion/s2io.c
++++ b/drivers/net/ethernet/neterion/s2io.c
+@@ -7128,9 +7128,8 @@ static int s2io_card_up(struct s2io_nic *sp)
+ 		if (ret) {
+ 			DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
+ 				  dev->name);
+-			s2io_reset(sp);
+-			free_rx_buffers(sp);
+-			return -ENOMEM;
++			ret = -ENOMEM;
++			goto err_fill_buff;
+ 		}
+ 		DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i,
+ 			  ring->rx_bufs_left);
+@@ -7168,18 +7167,16 @@ static int s2io_card_up(struct s2io_nic *sp)
+ 	/* Enable Rx Traffic and interrupts on the NIC */
+ 	if (start_nic(sp)) {
+ 		DBG_PRINT(ERR_DBG, "%s: Starting NIC failed\n", dev->name);
+-		s2io_reset(sp);
+-		free_rx_buffers(sp);
+-		return -ENODEV;
++		ret = -ENODEV;
++		goto err_out;
+ 	}
+ 
+ 	/* Add interrupt service routine */
+ 	if (s2io_add_isr(sp) != 0) {
+ 		if (sp->config.intr_type == MSI_X)
+ 			s2io_rem_isr(sp);
+-		s2io_reset(sp);
+-		free_rx_buffers(sp);
+-		return -ENODEV;
++		ret = -ENODEV;
++		goto err_out;
+ 	}
+ 
+ 	timer_setup(&sp->alarm_timer, s2io_alarm_handle, 0);
+@@ -7199,6 +7196,20 @@ static int s2io_card_up(struct s2io_nic *sp)
+ 	}
+ 
+ 	return 0;
++
++err_out:
++	if (config->napi) {
++		if (config->intr_type == MSI_X) {
++			for (i = 0; i < sp->config.rx_ring_num; i++)
++				napi_disable(&sp->mac_control.rings[i].napi);
++		} else {
++			napi_disable(&sp->napi);
++		}
++	}
++err_fill_buff:
++	s2io_reset(sp);
++	free_rx_buffers(sp);
++	return ret;
+ }
+ 
+ /**
+diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c
+index 4b3482ce90a1c..4fc279a175629 100644
+--- a/drivers/net/ethernet/ni/nixge.c
++++ b/drivers/net/ethernet/ni/nixge.c
+@@ -900,6 +900,7 @@ static int nixge_open(struct net_device *ndev)
+ err_rx_irq:
+ 	free_irq(priv->tx_irq, ndev);
+ err_tx_irq:
++	napi_disable(&priv->napi);
+ 	phy_stop(phy);
+ 	phy_disconnect(phy);
+ 	tasklet_kill(&priv->dma_err_tasklet);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+index 9af25be424014..66c30a40a6a21 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+@@ -630,7 +630,6 @@ static int ehl_common_data(struct pci_dev *pdev,
+ {
+ 	plat->rx_queues_to_use = 8;
+ 	plat->tx_queues_to_use = 8;
+-	plat->clk_ptp_rate = 200000000;
+ 	plat->use_phy_wol = 1;
+ 
+ 	plat->safety_feat_cfg->tsoee = 1;
+@@ -655,6 +654,8 @@ static int ehl_sgmii_data(struct pci_dev *pdev,
+ 	plat->serdes_powerup = intel_serdes_powerup;
+ 	plat->serdes_powerdown = intel_serdes_powerdown;
+ 
++	plat->clk_ptp_rate = 204800000;
++
+ 	return ehl_common_data(pdev, plat);
+ }
+ 
+@@ -668,6 +669,8 @@ static int ehl_rgmii_data(struct pci_dev *pdev,
+ 	plat->bus_id = 1;
+ 	plat->phy_interface = PHY_INTERFACE_MODE_RGMII;
+ 
++	plat->clk_ptp_rate = 204800000;
++
+ 	return ehl_common_data(pdev, plat);
+ }
+ 
+@@ -684,6 +687,8 @@ static int ehl_pse0_common_data(struct pci_dev *pdev,
+ 	plat->bus_id = 2;
+ 	plat->addr64 = 32;
+ 
++	plat->clk_ptp_rate = 200000000;
++
+ 	intel_mgbe_pse_crossts_adj(intel_priv, EHL_PSE_ART_MHZ);
+ 
+ 	return ehl_common_data(pdev, plat);
+@@ -723,6 +728,8 @@ static int ehl_pse1_common_data(struct pci_dev *pdev,
+ 	plat->bus_id = 3;
+ 	plat->addr64 = 32;
+ 
++	plat->clk_ptp_rate = 200000000;
++
+ 	intel_mgbe_pse_crossts_adj(intel_priv, EHL_PSE_ART_MHZ);
+ 
+ 	return ehl_common_data(pdev, plat);
+@@ -758,7 +765,7 @@ static int tgl_common_data(struct pci_dev *pdev,
+ {
+ 	plat->rx_queues_to_use = 6;
+ 	plat->tx_queues_to_use = 4;
+-	plat->clk_ptp_rate = 200000000;
++	plat->clk_ptp_rate = 204800000;
+ 	plat->speed_mode_2500 = intel_speed_mode_2500;
+ 
+ 	plat->safety_feat_cfg->tsoee = 1;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+index 79fa7870563b8..a25c187d31853 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+@@ -75,20 +75,24 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ 		plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
+ 						   sizeof(*plat->mdio_bus_data),
+ 						   GFP_KERNEL);
+-		if (!plat->mdio_bus_data)
+-			return -ENOMEM;
++		if (!plat->mdio_bus_data) {
++			ret = -ENOMEM;
++			goto err_put_node;
++		}
+ 		plat->mdio_bus_data->needs_reset = true;
+ 	}
+ 
+ 	plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg), GFP_KERNEL);
+-	if (!plat->dma_cfg)
+-		return -ENOMEM;
++	if (!plat->dma_cfg) {
++		ret = -ENOMEM;
++		goto err_put_node;
++	}
+ 
+ 	/* Enable pci device */
+ 	ret = pci_enable_device(pdev);
+ 	if (ret) {
+ 		dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n", __func__);
+-		return ret;
++		goto err_put_node;
+ 	}
+ 
+ 	/* Get the base address of device */
+@@ -97,7 +101,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ 			continue;
+ 		ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
+ 		if (ret)
+-			return ret;
++			goto err_disable_device;
+ 		break;
+ 	}
+ 
+@@ -108,7 +112,8 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ 	phy_mode = device_get_phy_mode(&pdev->dev);
+ 	if (phy_mode < 0) {
+ 		dev_err(&pdev->dev, "phy_mode not found\n");
+-		return phy_mode;
++		ret = phy_mode;
++		goto err_disable_device;
+ 	}
+ 
+ 	plat->phy_interface = phy_mode;
+@@ -125,6 +130,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ 	if (res.irq < 0) {
+ 		dev_err(&pdev->dev, "IRQ macirq not found\n");
+ 		ret = -ENODEV;
++		goto err_disable_msi;
+ 	}
+ 
+ 	res.wol_irq = of_irq_get_byname(np, "eth_wake_irq");
+@@ -137,15 +143,31 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ 	if (res.lpi_irq < 0) {
+ 		dev_err(&pdev->dev, "IRQ eth_lpi not found\n");
+ 		ret = -ENODEV;
++		goto err_disable_msi;
+ 	}
+ 
+-	return stmmac_dvr_probe(&pdev->dev, plat, &res);
++	ret = stmmac_dvr_probe(&pdev->dev, plat, &res);
++	if (ret)
++		goto err_disable_msi;
++
++	return ret;
++
++err_disable_msi:
++	pci_disable_msi(pdev);
++err_disable_device:
++	pci_disable_device(pdev);
++err_put_node:
++	of_node_put(plat->mdio_node);
++	return ret;
+ }
+ 
+ static void loongson_dwmac_remove(struct pci_dev *pdev)
+ {
++	struct net_device *ndev = dev_get_drvdata(&pdev->dev);
++	struct stmmac_priv *priv = netdev_priv(ndev);
+ 	int i;
+ 
++	of_node_put(priv->plat->mdio_node);
+ 	stmmac_dvr_remove(&pdev->dev);
+ 
+ 	for (i = 0; i < PCI_STD_NUM_BARS; i++) {
+@@ -155,6 +177,7 @@ static void loongson_dwmac_remove(struct pci_dev *pdev)
+ 		break;
+ 	}
+ 
++	pci_disable_msi(pdev);
+ 	pci_disable_device(pdev);
+ }
+ 
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+index c7a6588d9398b..e8b507f88fbce 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
+@@ -272,11 +272,9 @@ static int meson8b_devm_clk_prepare_enable(struct meson8b_dwmac *dwmac,
+ 	if (ret)
+ 		return ret;
+ 
+-	devm_add_action_or_reset(dwmac->dev,
+-				 (void(*)(void *))clk_disable_unprepare,
+-				 dwmac->rgmii_tx_clk);
+-
+-	return 0;
++	return devm_add_action_or_reset(dwmac->dev,
++					(void(*)(void *))clk_disable_unprepare,
++					clk);
+ }
+ 
+ static int meson8b_init_rgmii_delays(struct meson8b_dwmac *dwmac)
+diff --git a/drivers/net/ethernet/sunplus/spl2sw_driver.c b/drivers/net/ethernet/sunplus/spl2sw_driver.c
+index 61d1d07dc0704..d6f1fef4ff3af 100644
+--- a/drivers/net/ethernet/sunplus/spl2sw_driver.c
++++ b/drivers/net/ethernet/sunplus/spl2sw_driver.c
+@@ -286,7 +286,6 @@ static u32 spl2sw_init_netdev(struct platform_device *pdev, u8 *mac_addr,
+ 	if (ret) {
+ 		dev_err(&pdev->dev, "Failed to register net device \"%s\"!\n",
+ 			ndev->name);
+-		free_netdev(ndev);
+ 		*r_ndev = NULL;
+ 		return ret;
+ 	}
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index f4a6b590a1e39..348201e10d497 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -2791,7 +2791,6 @@ static int am65_cpsw_nuss_remove(struct platform_device *pdev)
+ 	if (ret < 0)
+ 		return ret;
+ 
+-	am65_cpsw_nuss_phylink_cleanup(common);
+ 	am65_cpsw_unregister_devlink(common);
+ 	am65_cpsw_unregister_notifiers(common);
+ 
+@@ -2799,6 +2798,7 @@ static int am65_cpsw_nuss_remove(struct platform_device *pdev)
+ 	 * dma_deconfigure(dev) before devres_release_all(dev)
+ 	 */
+ 	am65_cpsw_nuss_cleanup_ndev(common);
++	am65_cpsw_nuss_phylink_cleanup(common);
+ 
+ 	of_platform_device_destroy(common->mdio_dev, NULL);
+ 
+diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
+index ed66c4d4d8301..613e2c7c950ca 100644
+--- a/drivers/net/ethernet/ti/cpsw.c
++++ b/drivers/net/ethernet/ti/cpsw.c
+@@ -854,6 +854,8 @@ static int cpsw_ndo_open(struct net_device *ndev)
+ 
+ err_cleanup:
+ 	if (!cpsw->usage_count) {
++		napi_disable(&cpsw->napi_rx);
++		napi_disable(&cpsw->napi_tx);
+ 		cpdma_ctlr_stop(cpsw->dma);
+ 		cpsw_destroy_xdp_rxqs(cpsw);
+ 	}
+diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c
+index 5251fc3242219..a2fe0534c769b 100644
+--- a/drivers/net/ethernet/tundra/tsi108_eth.c
++++ b/drivers/net/ethernet/tundra/tsi108_eth.c
+@@ -1303,12 +1303,15 @@ static int tsi108_open(struct net_device *dev)
+ 
+ 	data->rxring = dma_alloc_coherent(&data->pdev->dev, rxring_size,
+ 					  &data->rxdma, GFP_KERNEL);
+-	if (!data->rxring)
++	if (!data->rxring) {
++		free_irq(data->irq_num, dev);
+ 		return -ENOMEM;
++	}
+ 
+ 	data->txring = dma_alloc_coherent(&data->pdev->dev, txring_size,
+ 					  &data->txdma, GFP_KERNEL);
+ 	if (!data->txring) {
++		free_irq(data->irq_num, dev);
+ 		dma_free_coherent(&data->pdev->dev, rxring_size, data->rxring,
+ 				    data->rxdma);
+ 		return -ENOMEM;
+diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
+index 30af0081e2bef..83a16d10eedbc 100644
+--- a/drivers/net/hamradio/bpqether.c
++++ b/drivers/net/hamradio/bpqether.c
+@@ -533,7 +533,7 @@ static int bpq_device_event(struct notifier_block *this,
+ 	if (!net_eq(dev_net(dev), &init_net))
+ 		return NOTIFY_DONE;
+ 
+-	if (!dev_is_ethdev(dev))
++	if (!dev_is_ethdev(dev) && !bpq_get_ax25_dev(dev))
+ 		return NOTIFY_DONE;
+ 
+ 	switch (event) {
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index c6d271e5687e9..ddfa853ec9b53 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -1427,7 +1427,8 @@ static struct macsec_rx_sc *del_rx_sc(struct macsec_secy *secy, sci_t sci)
+ 	return NULL;
+ }
+ 
+-static struct macsec_rx_sc *create_rx_sc(struct net_device *dev, sci_t sci)
++static struct macsec_rx_sc *create_rx_sc(struct net_device *dev, sci_t sci,
++					 bool active)
+ {
+ 	struct macsec_rx_sc *rx_sc;
+ 	struct macsec_dev *macsec;
+@@ -1451,7 +1452,7 @@ static struct macsec_rx_sc *create_rx_sc(struct net_device *dev, sci_t sci)
+ 	}
+ 
+ 	rx_sc->sci = sci;
+-	rx_sc->active = true;
++	rx_sc->active = active;
+ 	refcount_set(&rx_sc->refcnt, 1);
+ 
+ 	secy = &macsec_priv(dev)->secy;
+@@ -1860,6 +1861,7 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info)
+ 		       secy->key_len);
+ 
+ 		err = macsec_offload(ops->mdo_add_rxsa, &ctx);
++		memzero_explicit(ctx.sa.key, secy->key_len);
+ 		if (err)
+ 			goto cleanup;
+ 	}
+@@ -1904,7 +1906,7 @@ static int macsec_add_rxsc(struct sk_buff *skb, struct genl_info *info)
+ 	struct macsec_rx_sc *rx_sc;
+ 	struct nlattr *tb_rxsc[MACSEC_RXSC_ATTR_MAX + 1];
+ 	struct macsec_secy *secy;
+-	bool was_active;
++	bool active = true;
+ 	int ret;
+ 
+ 	if (!attrs[MACSEC_ATTR_IFINDEX])
+@@ -1926,16 +1928,15 @@ static int macsec_add_rxsc(struct sk_buff *skb, struct genl_info *info)
+ 	secy = &macsec_priv(dev)->secy;
+ 	sci = nla_get_sci(tb_rxsc[MACSEC_RXSC_ATTR_SCI]);
+ 
+-	rx_sc = create_rx_sc(dev, sci);
++	if (tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE])
++		active = nla_get_u8(tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE]);
++
++	rx_sc = create_rx_sc(dev, sci, active);
+ 	if (IS_ERR(rx_sc)) {
+ 		rtnl_unlock();
+ 		return PTR_ERR(rx_sc);
+ 	}
+ 
+-	was_active = rx_sc->active;
+-	if (tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE])
+-		rx_sc->active = !!nla_get_u8(tb_rxsc[MACSEC_RXSC_ATTR_ACTIVE]);
+-
+ 	if (macsec_is_offloaded(netdev_priv(dev))) {
+ 		const struct macsec_ops *ops;
+ 		struct macsec_context ctx;
+@@ -1959,7 +1960,8 @@ static int macsec_add_rxsc(struct sk_buff *skb, struct genl_info *info)
+ 	return 0;
+ 
+ cleanup:
+-	rx_sc->active = was_active;
++	del_rx_sc(secy, sci);
++	free_rx_sc(rx_sc);
+ 	rtnl_unlock();
+ 	return ret;
+ }
+@@ -2102,6 +2104,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info)
+ 		       secy->key_len);
+ 
+ 		err = macsec_offload(ops->mdo_add_txsa, &ctx);
++		memzero_explicit(ctx.sa.key, secy->key_len);
+ 		if (err)
+ 			goto cleanup;
+ 	}
+@@ -2598,7 +2601,7 @@ static bool macsec_is_configured(struct macsec_dev *macsec)
+ 	struct macsec_tx_sc *tx_sc = &secy->tx_sc;
+ 	int i;
+ 
+-	if (secy->n_rx_sc > 0)
++	if (secy->rx_sc)
+ 		return true;
+ 
+ 	for (i = 0; i < MACSEC_NUM_AN; i++)
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index 1080d6ebff63b..9983d37ee87d9 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -1533,8 +1533,10 @@ destroy_macvlan_port:
+ 	/* the macvlan port may be freed by macvlan_uninit when fail to register.
+ 	 * so we destroy the macvlan port only when it's valid.
+ 	 */
+-	if (create && macvlan_port_get_rtnl(lowerdev))
++	if (create && macvlan_port_get_rtnl(lowerdev)) {
++		macvlan_flush_sources(port, vlan);
+ 		macvlan_port_destroy(port->dev);
++	}
+ 	return err;
+ }
+ EXPORT_SYMBOL_GPL(macvlan_common_newlink);
+diff --git a/drivers/net/phy/mscc/mscc_macsec.c b/drivers/net/phy/mscc/mscc_macsec.c
+index b7b2521c73fb6..c00eef457b850 100644
+--- a/drivers/net/phy/mscc/mscc_macsec.c
++++ b/drivers/net/phy/mscc/mscc_macsec.c
+@@ -632,6 +632,7 @@ static void vsc8584_macsec_free_flow(struct vsc8531_private *priv,
+ 
+ 	list_del(&flow->list);
+ 	clear_bit(flow->index, bitmap);
++	memzero_explicit(flow->key, sizeof(flow->key));
+ 	kfree(flow);
+ }
+ 
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index b02bd0a6c0a93..3387074a2bdb8 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1967,17 +1967,25 @@ drop:
+ 					  skb_headlen(skb));
+ 
+ 		if (unlikely(headlen > skb_headlen(skb))) {
++			WARN_ON_ONCE(1);
++			err = -ENOMEM;
+ 			dev_core_stats_rx_dropped_inc(tun->dev);
++napi_busy:
+ 			napi_free_frags(&tfile->napi);
+ 			rcu_read_unlock();
+ 			mutex_unlock(&tfile->napi_mutex);
+-			WARN_ON(1);
+-			return -ENOMEM;
++			return err;
+ 		}
+ 
+-		local_bh_disable();
+-		napi_gro_frags(&tfile->napi);
+-		local_bh_enable();
++		if (likely(napi_schedule_prep(&tfile->napi))) {
++			local_bh_disable();
++			napi_gro_frags(&tfile->napi);
++			napi_complete(&tfile->napi);
++			local_bh_enable();
++		} else {
++			err = -EBUSY;
++			goto napi_busy;
++		}
+ 		mutex_unlock(&tfile->napi_mutex);
+ 	} else if (tfile->napi_enabled) {
+ 		struct sk_buff_head *queue = &tfile->sk.sk_write_queue;
+diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
+index 960f1393595cc..d62a904d2e422 100644
+--- a/drivers/net/wan/lapbether.c
++++ b/drivers/net/wan/lapbether.c
+@@ -325,6 +325,7 @@ static int lapbeth_open(struct net_device *dev)
+ 
+ 	err = lapb_register(dev, &lapbeth_callbacks);
+ 	if (err != LAPB_OK) {
++		napi_disable(&lapbeth->napi);
+ 		pr_err("lapb_register error: %d\n", err);
+ 		return -ENODEV;
+ 	}
+@@ -446,7 +447,7 @@ static int lapbeth_device_event(struct notifier_block *this,
+ 	if (dev_net(dev) != &init_net)
+ 		return NOTIFY_DONE;
+ 
+-	if (!dev_is_ethdev(dev))
++	if (!dev_is_ethdev(dev) && !lapbeth_get_x25_dev(dev))
+ 		return NOTIFY_DONE;
+ 
+ 	switch (event) {
+diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c
+index 7ee3ff69dfc85..6fae4e61ede7f 100644
+--- a/drivers/net/wireless/ath/ath11k/reg.c
++++ b/drivers/net/wireless/ath/ath11k/reg.c
+@@ -287,11 +287,7 @@ int ath11k_regd_update(struct ath11k *ar)
+ 		goto err;
+ 	}
+ 
+-	rtnl_lock();
+-	wiphy_lock(ar->hw->wiphy);
+-	ret = regulatory_set_wiphy_regd_sync(ar->hw->wiphy, regd_copy);
+-	wiphy_unlock(ar->hw->wiphy);
+-	rtnl_unlock();
++	ret = regulatory_set_wiphy_regd(ar->hw->wiphy, regd_copy);
+ 
+ 	kfree(regd_copy);
+ 
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c b/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c
+index 57304a5adf68e..6e32eb91bba95 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_imem_ops.c
+@@ -91,6 +91,14 @@ void ipc_imem_wwan_channel_init(struct iosm_imem *ipc_imem,
+ 	}
+ 
+ 	ipc_chnl_cfg_get(&chnl_cfg, ipc_imem->nr_of_channels);
++
++	if (ipc_imem->mmio->mux_protocol == MUX_AGGREGATION &&
++	    ipc_imem->nr_of_channels == IPC_MEM_IP_CHL_ID_0) {
++		chnl_cfg.ul_nr_of_entries = IPC_MEM_MAX_TDS_MUX_AGGR_UL;
++		chnl_cfg.dl_nr_of_entries = IPC_MEM_MAX_TDS_MUX_AGGR_DL;
++		chnl_cfg.dl_buf_size = IPC_MEM_MAX_ADB_BUF_SIZE;
++	}
++
+ 	ipc_imem_channel_init(ipc_imem, IPC_CTYPE_WWAN, chnl_cfg,
+ 			      IRQ_MOD_OFF);
+ 
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_mux.h b/drivers/net/wwan/iosm/iosm_ipc_mux.h
+index cd9d74cc097f1..9968bb885c1f3 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_mux.h
++++ b/drivers/net/wwan/iosm/iosm_ipc_mux.h
+@@ -10,6 +10,7 @@
+ 
+ #define IPC_MEM_MAX_UL_DG_ENTRIES	100
+ #define IPC_MEM_MAX_TDS_MUX_AGGR_UL	60
++#define IPC_MEM_MAX_TDS_MUX_AGGR_DL	60
+ 
+ #define IPC_MEM_MAX_ADB_BUF_SIZE (16 * 1024)
+ #define IPC_MEM_MAX_UL_ADB_BUF_SIZE IPC_MEM_MAX_ADB_BUF_SIZE
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_pcie.c b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+index 31f57b986df28..97cb6846c6ae2 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_pcie.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_pcie.c
+@@ -232,6 +232,7 @@ static void ipc_pcie_config_init(struct iosm_pcie *ipc_pcie)
+  */
+ static enum ipc_pcie_sleep_state ipc_pcie_read_bios_cfg(struct device *dev)
+ {
++	enum ipc_pcie_sleep_state sleep_state = IPC_PCIE_D0L12;
+ 	union acpi_object *object;
+ 	acpi_handle handle_acpi;
+ 
+@@ -242,12 +243,16 @@ static enum ipc_pcie_sleep_state ipc_pcie_read_bios_cfg(struct device *dev)
+ 	}
+ 
+ 	object = acpi_evaluate_dsm(handle_acpi, &wwan_acpi_guid, 0, 3, NULL);
++	if (!object)
++		goto default_ret;
++
++	if (object->integer.value == 3)
++		sleep_state = IPC_PCIE_D3L2;
+ 
+-	if (object && object->integer.value == 3)
+-		return IPC_PCIE_D3L2;
++	kfree(object);
+ 
+ default_ret:
+-	return IPC_PCIE_D0L12;
++	return sleep_state;
+ }
+ 
+ static int ipc_pcie_probe(struct pci_dev *pci,
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_wwan.c b/drivers/net/wwan/iosm/iosm_ipc_wwan.c
+index 4712f01a7e33e..3d70b34f96e31 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_wwan.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_wwan.c
+@@ -168,6 +168,7 @@ static void ipc_wwan_setup(struct net_device *iosm_dev)
+ 	iosm_dev->max_mtu = ETH_MAX_MTU;
+ 
+ 	iosm_dev->flags = IFF_POINTOPOINT | IFF_NOARP;
++	iosm_dev->needs_free_netdev = true;
+ 
+ 	iosm_dev->netdev_ops = &ipc_inm_ops;
+ }
+diff --git a/drivers/net/wwan/mhi_wwan_mbim.c b/drivers/net/wwan/mhi_wwan_mbim.c
+index 6872782e8dd89..ef70bb7c88ad6 100644
+--- a/drivers/net/wwan/mhi_wwan_mbim.c
++++ b/drivers/net/wwan/mhi_wwan_mbim.c
+@@ -582,6 +582,7 @@ static void mhi_mbim_setup(struct net_device *ndev)
+ 	ndev->min_mtu = ETH_MIN_MTU;
+ 	ndev->max_mtu = MHI_MAX_BUF_SZ - ndev->needed_headroom;
+ 	ndev->tx_queue_len = 1000;
++	ndev->needs_free_netdev = true;
+ }
+ 
+ static const struct wwan_ops mhi_mbim_wwan_ops = {
+diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c
+index e7c6f6629e7c5..ba64284eaf9fa 100644
+--- a/drivers/pci/controller/pci-hyperv.c
++++ b/drivers/pci/controller/pci-hyperv.c
+@@ -1614,7 +1614,7 @@ out:
+ 
+ static u32 hv_compose_msi_req_v1(
+ 	struct pci_create_interrupt *int_pkt, const struct cpumask *affinity,
+-	u32 slot, u8 vector, u8 vector_count)
++	u32 slot, u8 vector, u16 vector_count)
+ {
+ 	int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE;
+ 	int_pkt->wslot.slot = slot;
+@@ -1642,7 +1642,7 @@ static int hv_compose_msi_req_get_cpu(const struct cpumask *affinity)
+ 
+ static u32 hv_compose_msi_req_v2(
+ 	struct pci_create_interrupt2 *int_pkt, const struct cpumask *affinity,
+-	u32 slot, u8 vector, u8 vector_count)
++	u32 slot, u8 vector, u16 vector_count)
+ {
+ 	int cpu;
+ 
+@@ -1661,7 +1661,7 @@ static u32 hv_compose_msi_req_v2(
+ 
+ static u32 hv_compose_msi_req_v3(
+ 	struct pci_create_interrupt3 *int_pkt, const struct cpumask *affinity,
+-	u32 slot, u32 vector, u8 vector_count)
++	u32 slot, u32 vector, u16 vector_count)
+ {
+ 	int cpu;
+ 
+@@ -1701,7 +1701,12 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 	struct compose_comp_ctxt comp;
+ 	struct tran_int_desc *int_desc;
+ 	struct msi_desc *msi_desc;
+-	u8 vector, vector_count;
++	/*
++	 * vector_count should be u16: see hv_msi_desc, hv_msi_desc2
++	 * and hv_msi_desc3. vector must be u32: see hv_msi_desc3.
++	 */
++	u16 vector_count;
++	u32 vector;
+ 	struct {
+ 		struct pci_packet pci_pkt;
+ 		union {
+@@ -1767,6 +1772,11 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 		vector_count = 1;
+ 	}
+ 
++	/*
++	 * hv_compose_msi_req_v1 and v2 are for x86 only, meaning 'vector'
++	 * can't exceed u8. Cast 'vector' down to u8 for v1/v2 explicitly
++	 * for better readability.
++	 */
+ 	memset(&ctxt, 0, sizeof(ctxt));
+ 	init_completion(&comp.comp_pkt.host_event);
+ 	ctxt.pci_pkt.completion_func = hv_pci_compose_compl;
+@@ -1777,7 +1787,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 		size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1,
+ 					dest,
+ 					hpdev->desc.win_slot.slot,
+-					vector,
++					(u8)vector,
+ 					vector_count);
+ 		break;
+ 
+@@ -1786,7 +1796,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+ 		size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2,
+ 					dest,
+ 					hpdev->desc.win_slot.slot,
+-					vector,
++					(u8)vector,
+ 					vector_count);
+ 		break;
+ 
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+index 4b18289761044..3e730c05ac3fb 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c
+@@ -1914,7 +1914,7 @@ static void qcom_qmp_phy_combo_enable_autonomous_mode(struct qmp_phy *qphy)
+ static void qcom_qmp_phy_combo_disable_autonomous_mode(struct qmp_phy *qphy)
+ {
+ 	const struct qmp_phy_cfg *cfg = qphy->cfg;
+-	void __iomem *pcs_usb = qphy->pcs_usb ?: qphy->pcs_usb;
++	void __iomem *pcs_usb = qphy->pcs_usb ?: qphy->pcs;
+ 	void __iomem *pcs_misc = qphy->pcs_misc;
+ 
+ 	/* Disable i/o clamp_n on resume for normal mode */
+diff --git a/drivers/phy/ralink/phy-mt7621-pci.c b/drivers/phy/ralink/phy-mt7621-pci.c
+index 5e6530f545b5c..85888ab2d307a 100644
+--- a/drivers/phy/ralink/phy-mt7621-pci.c
++++ b/drivers/phy/ralink/phy-mt7621-pci.c
+@@ -280,7 +280,8 @@ static struct phy *mt7621_pcie_phy_of_xlate(struct device *dev,
+ }
+ 
+ static const struct soc_device_attribute mt7621_pci_quirks_match[] = {
+-	{ .soc_id = "mt7621", .revision = "E2" }
++	{ .soc_id = "mt7621", .revision = "E2" },
++	{ /* sentinel */ }
+ };
+ 
+ static const struct regmap_config mt7621_pci_phy_regmap_config = {
+diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c
+index a98c911cc37ae..5bb9647b078f1 100644
+--- a/drivers/phy/st/phy-stm32-usbphyc.c
++++ b/drivers/phy/st/phy-stm32-usbphyc.c
+@@ -710,6 +710,8 @@ static int stm32_usbphyc_probe(struct platform_device *pdev)
+ 		ret = of_property_read_u32(child, "reg", &index);
+ 		if (ret || index > usbphyc->nphys) {
+ 			dev_err(&phy->dev, "invalid reg property: %d\n", ret);
++			if (!ret)
++				ret = -EINVAL;
+ 			goto put_child;
+ 		}
+ 
+diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
+index fc8dbbd6fc7c2..4fbe91769c915 100644
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -1298,8 +1298,16 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
+ 	wwan_rfkill = NULL;
+ 	rfkill2_count = 0;
+ 
+-	if (hp_wmi_rfkill_setup(device))
+-		hp_wmi_rfkill2_setup(device);
++	/*
++	 * In pre-2009 BIOS, command 1Bh return 0x4 to indicate that
++	 * BIOS no longer controls the power for the wireless
++	 * devices. All features supported by this command will no
++	 * longer be supported.
++	 */
++	if (!hp_wmi_bios_2009_later()) {
++		if (hp_wmi_rfkill_setup(device))
++			hp_wmi_rfkill2_setup(device);
++	}
+ 
+ 	err = hp_wmi_hwmon_init();
+ 
+diff --git a/drivers/platform/x86/p2sb.c b/drivers/platform/x86/p2sb.c
+index 384d0962ae93a..1cf2471d54dde 100644
+--- a/drivers/platform/x86/p2sb.c
++++ b/drivers/platform/x86/p2sb.c
+@@ -19,26 +19,23 @@
+ #define P2SBC			0xe0
+ #define P2SBC_HIDE		BIT(8)
+ 
++#define P2SB_DEVFN_DEFAULT	PCI_DEVFN(31, 1)
++
+ static const struct x86_cpu_id p2sb_cpu_ids[] = {
+ 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT,	PCI_DEVFN(13, 0)),
+-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D,	PCI_DEVFN(31, 1)),
+-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_D,	PCI_DEVFN(31, 1)),
+-	X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE,		PCI_DEVFN(31, 1)),
+-	X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L,		PCI_DEVFN(31, 1)),
+-	X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE,		PCI_DEVFN(31, 1)),
+-	X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L,		PCI_DEVFN(31, 1)),
+ 	{}
+ };
+ 
+ static int p2sb_get_devfn(unsigned int *devfn)
+ {
++	unsigned int fn = P2SB_DEVFN_DEFAULT;
+ 	const struct x86_cpu_id *id;
+ 
+ 	id = x86_match_cpu(p2sb_cpu_ids);
+-	if (!id)
+-		return -ENODEV;
++	if (id)
++		fn = (unsigned int)id->driver_data;
+ 
+-	*devfn = (unsigned int)id->driver_data;
++	*devfn = fn;
+ 	return 0;
+ }
+ 
+diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
+index 3a992a6478c30..6e5990611d834 100644
+--- a/drivers/soundwire/qcom.c
++++ b/drivers/soundwire/qcom.c
+@@ -344,6 +344,9 @@ static int qcom_swrm_cmd_fifo_wr_cmd(struct qcom_swrm_ctrl *swrm, u8 cmd_data,
+ 	if (swrm_wait_for_wr_fifo_avail(swrm))
+ 		return SDW_CMD_FAIL_OTHER;
+ 
++	if (cmd_id == SWR_BROADCAST_CMD_ID)
++		reinit_completion(&swrm->broadcast);
++
+ 	/* Its assumed that write is okay as we do not get any status back */
+ 	swrm->reg_write(swrm, SWRM_CMD_FIFO_WR_CMD, val);
+ 
+@@ -377,6 +380,12 @@ static int qcom_swrm_cmd_fifo_rd_cmd(struct qcom_swrm_ctrl *swrm,
+ 
+ 	val = swrm_get_packed_reg_val(&swrm->rcmd_id, len, dev_addr, reg_addr);
+ 
++	/*
++	 * Check for outstanding cmd wrt. write fifo depth to avoid
++	 * overflow as read will also increase write fifo cnt.
++	 */
++	swrm_wait_for_wr_fifo_avail(swrm);
++
+ 	/* wait for FIFO RD to complete to avoid overflow */
+ 	usleep_range(100, 105);
+ 	swrm->reg_write(swrm, SWRM_CMD_FIFO_RD_CMD, val);
+diff --git a/drivers/spi/spi-intel.c b/drivers/spi/spi-intel.c
+index 66063687ae271..3f6db482b6c71 100644
+--- a/drivers/spi/spi-intel.c
++++ b/drivers/spi/spi-intel.c
+@@ -52,17 +52,17 @@
+ #define FRACC				0x50
+ 
+ #define FREG(n)				(0x54 + ((n) * 4))
+-#define FREG_BASE_MASK			0x3fff
++#define FREG_BASE_MASK			GENMASK(14, 0)
+ #define FREG_LIMIT_SHIFT		16
+-#define FREG_LIMIT_MASK			(0x03fff << FREG_LIMIT_SHIFT)
++#define FREG_LIMIT_MASK			GENMASK(30, 16)
+ 
+ /* Offset is from @ispi->pregs */
+ #define PR(n)				((n) * 4)
+ #define PR_WPE				BIT(31)
+ #define PR_LIMIT_SHIFT			16
+-#define PR_LIMIT_MASK			(0x3fff << PR_LIMIT_SHIFT)
++#define PR_LIMIT_MASK			GENMASK(30, 16)
+ #define PR_RPE				BIT(15)
+-#define PR_BASE_MASK			0x3fff
++#define PR_BASE_MASK			GENMASK(14, 0)
+ 
+ /* Offsets are from @ispi->sregs */
+ #define SSFSTS_CTL			0x00
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index 0a3b9f7eed30f..cd9dc358d3967 100644
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -551,14 +551,17 @@ static void mtk_spi_enable_transfer(struct spi_master *master)
+ 	writel(cmd, mdata->base + SPI_CMD_REG);
+ }
+ 
+-static int mtk_spi_get_mult_delta(u32 xfer_len)
++static int mtk_spi_get_mult_delta(struct mtk_spi *mdata, u32 xfer_len)
+ {
+-	u32 mult_delta;
++	u32 mult_delta = 0;
+ 
+-	if (xfer_len > MTK_SPI_PACKET_SIZE)
+-		mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
+-	else
+-		mult_delta = 0;
++	if (mdata->dev_comp->ipm_design) {
++		if (xfer_len > MTK_SPI_IPM_PACKET_SIZE)
++			mult_delta = xfer_len % MTK_SPI_IPM_PACKET_SIZE;
++	} else {
++		if (xfer_len > MTK_SPI_PACKET_SIZE)
++			mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
++	}
+ 
+ 	return mult_delta;
+ }
+@@ -570,22 +573,22 @@ static void mtk_spi_update_mdata_len(struct spi_master *master)
+ 
+ 	if (mdata->tx_sgl_len && mdata->rx_sgl_len) {
+ 		if (mdata->tx_sgl_len > mdata->rx_sgl_len) {
+-			mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len);
++			mult_delta = mtk_spi_get_mult_delta(mdata, mdata->rx_sgl_len);
+ 			mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
+ 			mdata->rx_sgl_len = mult_delta;
+ 			mdata->tx_sgl_len -= mdata->xfer_len;
+ 		} else {
+-			mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len);
++			mult_delta = mtk_spi_get_mult_delta(mdata, mdata->tx_sgl_len);
+ 			mdata->xfer_len = mdata->tx_sgl_len - mult_delta;
+ 			mdata->tx_sgl_len = mult_delta;
+ 			mdata->rx_sgl_len -= mdata->xfer_len;
+ 		}
+ 	} else if (mdata->tx_sgl_len) {
+-		mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len);
++		mult_delta = mtk_spi_get_mult_delta(mdata, mdata->tx_sgl_len);
+ 		mdata->xfer_len = mdata->tx_sgl_len - mult_delta;
+ 		mdata->tx_sgl_len = mult_delta;
+ 	} else if (mdata->rx_sgl_len) {
+-		mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len);
++		mult_delta = mtk_spi_get_mult_delta(mdata, mdata->rx_sgl_len);
+ 		mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
+ 		mdata->rx_sgl_len = mult_delta;
+ 	}
+diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
+index 9853f6c7e81d7..583c22df40403 100644
+--- a/drivers/thunderbolt/tb.c
++++ b/drivers/thunderbolt/tb.c
+@@ -105,6 +105,32 @@ static void tb_remove_dp_resources(struct tb_switch *sw)
+ 	}
+ }
+ 
++static void tb_discover_dp_resource(struct tb *tb, struct tb_port *port)
++{
++	struct tb_cm *tcm = tb_priv(tb);
++	struct tb_port *p;
++
++	list_for_each_entry(p, &tcm->dp_resources, list) {
++		if (p == port)
++			return;
++	}
++
++	tb_port_dbg(port, "DP %s resource available discovered\n",
++		    tb_port_is_dpin(port) ? "IN" : "OUT");
++	list_add_tail(&port->list, &tcm->dp_resources);
++}
++
++static void tb_discover_dp_resources(struct tb *tb)
++{
++	struct tb_cm *tcm = tb_priv(tb);
++	struct tb_tunnel *tunnel;
++
++	list_for_each_entry(tunnel, &tcm->tunnel_list, list) {
++		if (tb_tunnel_is_dp(tunnel))
++			tb_discover_dp_resource(tb, tunnel->dst_port);
++	}
++}
++
+ static void tb_switch_discover_tunnels(struct tb_switch *sw,
+ 				       struct list_head *list,
+ 				       bool alloc_hopids)
+@@ -1446,6 +1472,8 @@ static int tb_start(struct tb *tb)
+ 	tb_scan_switch(tb->root_switch);
+ 	/* Find out tunnels created by the boot firmware */
+ 	tb_discover_tunnels(tb);
++	/* Add DP resources from the DP tunnels created by the boot firmware */
++	tb_discover_dp_resources(tb);
+ 	/*
+ 	 * If the boot firmware did not create USB 3.x tunnels create them
+ 	 * now for the whole topology.
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 2633137c3e9f1..aa4bc213d301b 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -2544,7 +2544,9 @@ static int btrfs_read_roots(struct btrfs_fs_info *fs_info)
+ 		fs_info->dev_root = root;
+ 	}
+ 	/* Initialize fs_info for all devices in any case */
+-	btrfs_init_devices_late(fs_info);
++	ret = btrfs_init_devices_late(fs_info);
++	if (ret)
++		goto out;
+ 
+ 	/*
+ 	 * This tree can share blocks with some other fs tree during relocation
+diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c
+index cc9377cf56a33..8c8e28dff2f12 100644
+--- a/fs/btrfs/tests/btrfs-tests.c
++++ b/fs/btrfs/tests/btrfs-tests.c
+@@ -200,7 +200,7 @@ void btrfs_free_dummy_fs_info(struct btrfs_fs_info *fs_info)
+ 
+ void btrfs_free_dummy_root(struct btrfs_root *root)
+ {
+-	if (!root)
++	if (IS_ERR_OR_NULL(root))
+ 		return;
+ 	/* Will be freed by btrfs_free_fs_roots */
+ 	if (WARN_ON(test_bit(BTRFS_ROOT_IN_RADIX, &root->state)))
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 5d004772ab493..7aa220742c61d 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -1009,6 +1009,18 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
+ 			rcu_assign_pointer(device->name, name);
+ 		}
+ 
++		if (orig_dev->zone_info) {
++			struct btrfs_zoned_device_info *zone_info;
++
++			zone_info = btrfs_clone_dev_zone_info(orig_dev);
++			if (!zone_info) {
++				btrfs_free_device(device);
++				ret = -ENOMEM;
++				goto error;
++			}
++			device->zone_info = zone_info;
++		}
++
+ 		list_add(&device->dev_list, &fs_devices->devices);
+ 		device->fs_devices = fs_devices;
+ 		fs_devices->num_devices++;
+@@ -6805,18 +6817,18 @@ static bool dev_args_match_fs_devices(const struct btrfs_dev_lookup_args *args,
+ static bool dev_args_match_device(const struct btrfs_dev_lookup_args *args,
+ 				  const struct btrfs_device *device)
+ {
+-	ASSERT((args->devid != (u64)-1) || args->missing);
++	if (args->missing) {
++		if (test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state) &&
++		    !device->bdev)
++			return true;
++		return false;
++	}
+ 
+-	if ((args->devid != (u64)-1) && device->devid != args->devid)
++	if (device->devid != args->devid)
+ 		return false;
+ 	if (args->uuid && memcmp(device->uuid, args->uuid, BTRFS_UUID_SIZE) != 0)
+ 		return false;
+-	if (!args->missing)
+-		return true;
+-	if (test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state) &&
+-	    !device->bdev)
+-		return true;
+-	return false;
++	return true;
+ }
+ 
+ /*
+@@ -7631,10 +7643,11 @@ error:
+ 	return ret;
+ }
+ 
+-void btrfs_init_devices_late(struct btrfs_fs_info *fs_info)
++int btrfs_init_devices_late(struct btrfs_fs_info *fs_info)
+ {
+ 	struct btrfs_fs_devices *fs_devices = fs_info->fs_devices, *seed_devs;
+ 	struct btrfs_device *device;
++	int ret = 0;
+ 
+ 	fs_devices->fs_info = fs_info;
+ 
+@@ -7643,12 +7656,18 @@ void btrfs_init_devices_late(struct btrfs_fs_info *fs_info)
+ 		device->fs_info = fs_info;
+ 
+ 	list_for_each_entry(seed_devs, &fs_devices->seed_list, seed_list) {
+-		list_for_each_entry(device, &seed_devs->devices, dev_list)
++		list_for_each_entry(device, &seed_devs->devices, dev_list) {
+ 			device->fs_info = fs_info;
++			ret = btrfs_get_dev_zone_info(device, false);
++			if (ret)
++				break;
++		}
+ 
+ 		seed_devs->fs_info = fs_info;
+ 	}
+ 	mutex_unlock(&fs_devices->device_list_mutex);
++
++	return ret;
+ }
+ 
+ static u64 btrfs_dev_stats_value(const struct extent_buffer *eb,
+diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
+index 5639961b3626f..6d6cf77cd1b57 100644
+--- a/fs/btrfs/volumes.h
++++ b/fs/btrfs/volumes.h
+@@ -629,7 +629,7 @@ int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes,
+ void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index);
+ int btrfs_get_dev_stats(struct btrfs_fs_info *fs_info,
+ 			struct btrfs_ioctl_get_dev_stats *stats);
+-void btrfs_init_devices_late(struct btrfs_fs_info *fs_info);
++int btrfs_init_devices_late(struct btrfs_fs_info *fs_info);
+ int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info);
+ int btrfs_run_dev_stats(struct btrfs_trans_handle *trans);
+ void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_device *srcdev);
+diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
+index 73c6929f7be66..a227d27a63bfd 100644
+--- a/fs/btrfs/zoned.c
++++ b/fs/btrfs/zoned.c
+@@ -639,6 +639,46 @@ void btrfs_destroy_dev_zone_info(struct btrfs_device *device)
+ 	device->zone_info = NULL;
+ }
+ 
++struct btrfs_zoned_device_info *btrfs_clone_dev_zone_info(struct btrfs_device *orig_dev)
++{
++	struct btrfs_zoned_device_info *zone_info;
++
++	zone_info = kmemdup(orig_dev->zone_info, sizeof(*zone_info), GFP_KERNEL);
++	if (!zone_info)
++		return NULL;
++
++	zone_info->seq_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL);
++	if (!zone_info->seq_zones)
++		goto out;
++
++	bitmap_copy(zone_info->seq_zones, orig_dev->zone_info->seq_zones,
++		    zone_info->nr_zones);
++
++	zone_info->empty_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL);
++	if (!zone_info->empty_zones)
++		goto out;
++
++	bitmap_copy(zone_info->empty_zones, orig_dev->zone_info->empty_zones,
++		    zone_info->nr_zones);
++
++	zone_info->active_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL);
++	if (!zone_info->active_zones)
++		goto out;
++
++	bitmap_copy(zone_info->active_zones, orig_dev->zone_info->active_zones,
++		    zone_info->nr_zones);
++	zone_info->zone_cache = NULL;
++
++	return zone_info;
++
++out:
++	bitmap_free(zone_info->seq_zones);
++	bitmap_free(zone_info->empty_zones);
++	bitmap_free(zone_info->active_zones);
++	kfree(zone_info);
++	return NULL;
++}
++
+ int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
+ 		       struct blk_zone *zone)
+ {
+diff --git a/fs/btrfs/zoned.h b/fs/btrfs/zoned.h
+index e17462db3a842..8bd16d40b7c65 100644
+--- a/fs/btrfs/zoned.h
++++ b/fs/btrfs/zoned.h
+@@ -36,6 +36,7 @@ int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
+ int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info);
+ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache);
+ void btrfs_destroy_dev_zone_info(struct btrfs_device *device);
++struct btrfs_zoned_device_info *btrfs_clone_dev_zone_info(struct btrfs_device *orig_dev);
+ int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info);
+ int btrfs_check_mountopts_zoned(struct btrfs_fs_info *info);
+ int btrfs_sb_log_location_bdev(struct block_device *bdev, int mirror, int rw,
+@@ -103,6 +104,16 @@ static inline int btrfs_get_dev_zone_info(struct btrfs_device *device,
+ 
+ static inline void btrfs_destroy_dev_zone_info(struct btrfs_device *device) { }
+ 
++/*
++ * In case the kernel is compiled without CONFIG_BLK_DEV_ZONED we'll never call
++ * into btrfs_clone_dev_zone_info() so it's safe to return NULL here.
++ */
++static inline struct btrfs_zoned_device_info *btrfs_clone_dev_zone_info(
++						 struct btrfs_device *orig_dev)
++{
++	return NULL;
++}
++
+ static inline int btrfs_check_zoned_mode(const struct btrfs_fs_info *fs_info)
+ {
+ 	if (!btrfs_is_zoned(fs_info))
+diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
+index 56d2c6fc61753..8568c33d4a76f 100644
+--- a/fs/nilfs2/segment.c
++++ b/fs/nilfs2/segment.c
+@@ -317,7 +317,7 @@ void nilfs_relax_pressure_in_lock(struct super_block *sb)
+ 	struct the_nilfs *nilfs = sb->s_fs_info;
+ 	struct nilfs_sc_info *sci = nilfs->ns_writer;
+ 
+-	if (!sci || !sci->sc_flush_request)
++	if (sb_rdonly(sb) || unlikely(!sci) || !sci->sc_flush_request)
+ 		return;
+ 
+ 	set_bit(NILFS_SC_PRIOR_FLUSH, &sci->sc_flags);
+@@ -2243,7 +2243,7 @@ int nilfs_construct_segment(struct super_block *sb)
+ 	struct nilfs_transaction_info *ti;
+ 	int err;
+ 
+-	if (!sci)
++	if (sb_rdonly(sb) || unlikely(!sci))
+ 		return -EROFS;
+ 
+ 	/* A call inside transactions causes a deadlock. */
+@@ -2282,7 +2282,7 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
+ 	struct nilfs_transaction_info ti;
+ 	int err = 0;
+ 
+-	if (!sci)
++	if (sb_rdonly(sb) || unlikely(!sci))
+ 		return -EROFS;
+ 
+ 	nilfs_transaction_lock(sb, &ti, 0);
+@@ -2778,11 +2778,12 @@ int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root)
+ 
+ 	if (nilfs->ns_writer) {
+ 		/*
+-		 * This happens if the filesystem was remounted
+-		 * read/write after nilfs_error degenerated it into a
+-		 * read-only mount.
++		 * This happens if the filesystem is made read-only by
++		 * __nilfs_error or nilfs_remount and then remounted
++		 * read/write.  In these cases, reuse the existing
++		 * writer.
+ 		 */
+-		nilfs_detach_log_writer(sb);
++		return 0;
+ 	}
+ 
+ 	nilfs->ns_writer = nilfs_segctor_new(sb, root);
+diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
+index ba108f915391e..6edb6e0dd61f7 100644
+--- a/fs/nilfs2/super.c
++++ b/fs/nilfs2/super.c
+@@ -1133,8 +1133,6 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
+ 	if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb))
+ 		goto out;
+ 	if (*flags & SB_RDONLY) {
+-		/* Shutting down log writer */
+-		nilfs_detach_log_writer(sb);
+ 		sb->s_flags |= SB_RDONLY;
+ 
+ 		/*
+diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
+index 3b4a079c9617c..c8b89b4f94e0e 100644
+--- a/fs/nilfs2/the_nilfs.c
++++ b/fs/nilfs2/the_nilfs.c
+@@ -690,9 +690,7 @@ int nilfs_count_free_blocks(struct the_nilfs *nilfs, sector_t *nblocks)
+ {
+ 	unsigned long ncleansegs;
+ 
+-	down_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
+ 	ncleansegs = nilfs_sufile_get_ncleansegs(nilfs->ns_sufile);
+-	up_read(&NILFS_MDT(nilfs->ns_dat)->mi_sem);
+ 	*nblocks = (sector_t)ncleansegs * nilfs->ns_blocks_per_segment;
+ 	return 0;
+ }
+diff --git a/fs/udf/namei.c b/fs/udf/namei.c
+index b3d5f97f16cdb..865e658535b11 100644
+--- a/fs/udf/namei.c
++++ b/fs/udf/namei.c
+@@ -240,7 +240,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
+ 						      poffset - lfi);
+ 			else {
+ 				if (!copy_name) {
+-					copy_name = kmalloc(UDF_NAME_LEN,
++					copy_name = kmalloc(UDF_NAME_LEN_CS0,
+ 							    GFP_NOFS);
+ 					if (!copy_name) {
+ 						fi = ERR_PTR(-ENOMEM);
+diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
+index 7c90b1ab3e00d..594422890f8d8 100644
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -333,6 +333,7 @@
+ #define DATA_DATA							\
+ 	*(.xiptext)							\
+ 	*(DATA_MAIN)							\
++	*(.data..decrypted)						\
+ 	*(.ref.data)							\
+ 	*(.data..shared_aligned) /* percpu related */			\
+ 	MEM_KEEP(init.data*)						\
+@@ -975,7 +976,6 @@
+ #ifdef CONFIG_AMD_MEM_ENCRYPT
+ #define PERCPU_DECRYPTED_SECTION					\
+ 	. = ALIGN(PAGE_SIZE);						\
+-	*(.data..decrypted)						\
+ 	*(.data..percpu..decrypted)					\
+ 	. = ALIGN(PAGE_SIZE);
+ #else
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
+index 1fdddbf3546b4..184b957e28ada 100644
+--- a/include/linux/bpf_verifier.h
++++ b/include/linux/bpf_verifier.h
+@@ -348,6 +348,27 @@ struct bpf_verifier_state {
+ 	     iter < frame->allocated_stack / BPF_REG_SIZE;		\
+ 	     iter++, reg = bpf_get_spilled_reg(iter, frame))
+ 
++/* Invoke __expr over regsiters in __vst, setting __state and __reg */
++#define bpf_for_each_reg_in_vstate(__vst, __state, __reg, __expr)   \
++	({                                                               \
++		struct bpf_verifier_state *___vstate = __vst;            \
++		int ___i, ___j;                                          \
++		for (___i = 0; ___i <= ___vstate->curframe; ___i++) {    \
++			struct bpf_reg_state *___regs;                   \
++			__state = ___vstate->frame[___i];                \
++			___regs = __state->regs;                         \
++			for (___j = 0; ___j < MAX_BPF_REG; ___j++) {     \
++				__reg = &___regs[___j];                  \
++				(void)(__expr);                          \
++			}                                                \
++			bpf_for_each_spilled_reg(___j, __state, __reg) { \
++				if (!__reg)                              \
++					continue;                        \
++				(void)(__expr);                          \
++			}                                                \
++		}                                                        \
++	})
++
+ /* linked list of verifier states used to prune search */
+ struct bpf_verifier_state_list {
+ 	struct bpf_verifier_state state;
+diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
+index c3e50e537e397..20631a2463769 100644
+--- a/include/linux/can/dev.h
++++ b/include/linux/can/dev.h
+@@ -147,6 +147,22 @@ static inline u32 can_get_static_ctrlmode(struct can_priv *priv)
+ 	return priv->ctrlmode & ~priv->ctrlmode_supported;
+ }
+ 
++/* drop skb if it does not contain a valid CAN frame for sending */
++static inline bool can_dev_dropped_skb(struct net_device *dev, struct sk_buff *skb)
++{
++	struct can_priv *priv = netdev_priv(dev);
++
++	if (priv->ctrlmode & CAN_CTRLMODE_LISTENONLY) {
++		netdev_info_once(dev,
++				 "interface in listen only mode, dropping skb\n");
++		kfree_skb(skb);
++		dev->stats.tx_dropped++;
++		return true;
++	}
++
++	return can_dropped_invalid_skb(dev, skb);
++}
++
+ void can_setup(struct net_device *dev);
+ 
+ struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,
+diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h
+index 48f4b645193b7..70d6cb94e5802 100644
+--- a/include/linux/skmsg.h
++++ b/include/linux/skmsg.h
+@@ -376,7 +376,7 @@ static inline void sk_psock_report_error(struct sk_psock *psock, int err)
+ }
+ 
+ struct sk_psock *sk_psock_init(struct sock *sk, int node);
+-void sk_psock_stop(struct sk_psock *psock, bool wait);
++void sk_psock_stop(struct sk_psock *psock);
+ 
+ #if IS_ENABLED(CONFIG_BPF_STREAM_PARSER)
+ int sk_psock_init_strp(struct sock *sk, struct sk_psock *psock);
+diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h
+index 463d1ba2232ac..3d61a0ae055d4 100644
+--- a/include/uapi/linux/capability.h
++++ b/include/uapi/linux/capability.h
+@@ -426,7 +426,7 @@ struct vfs_ns_cap_data {
+  */
+ 
+ #define CAP_TO_INDEX(x)     ((x) >> 5)        /* 1 << 5 == bits in __u32 */
+-#define CAP_TO_MASK(x)      (1 << ((x) & 31)) /* mask for indexed __u32 */
++#define CAP_TO_MASK(x)      (1U << ((x) & 31)) /* mask for indexed __u32 */
+ 
+ 
+ #endif /* _UAPI_LINUX_CAPABILITY_H */
+diff --git a/include/uapi/linux/idxd.h b/include/uapi/linux/idxd.h
+index 095299c75828c..2b9e7feba3f32 100644
+--- a/include/uapi/linux/idxd.h
++++ b/include/uapi/linux/idxd.h
+@@ -29,6 +29,7 @@ enum idxd_scmd_stat {
+ 	IDXD_SCMD_WQ_NO_SIZE = 0x800e0000,
+ 	IDXD_SCMD_WQ_NO_PRIV = 0x800f0000,
+ 	IDXD_SCMD_WQ_IRQ_ERR = 0x80100000,
++	IDXD_SCMD_WQ_USER_NO_IOMMU = 0x80110000,
+ };
+ 
+ #define IDXD_SCMD_SOFTERR_MASK	0x80000000
+diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c
+index 25cd724ade184..e2c46889d5fab 100644
+--- a/io_uring/kbuf.c
++++ b/io_uring/kbuf.c
+@@ -346,6 +346,8 @@ int io_provide_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
+ 	tmp = READ_ONCE(sqe->off);
+ 	if (tmp > USHRT_MAX)
+ 		return -E2BIG;
++	if (tmp + p->nbufs >= USHRT_MAX)
++		return -EINVAL;
+ 	p->bid = tmp;
+ 	return 0;
+ }
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 8b5ea7f6b5365..69fb46fdf7635 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -1011,12 +1011,17 @@ out:
+  */
+ static void *realloc_array(void *arr, size_t old_n, size_t new_n, size_t size)
+ {
++	void *new_arr;
++
+ 	if (!new_n || old_n == new_n)
+ 		goto out;
+ 
+-	arr = krealloc_array(arr, new_n, size, GFP_KERNEL);
+-	if (!arr)
++	new_arr = krealloc_array(arr, new_n, size, GFP_KERNEL);
++	if (!new_arr) {
++		kfree(arr);
+ 		return NULL;
++	}
++	arr = new_arr;
+ 
+ 	if (new_n > old_n)
+ 		memset(arr + old_n * size, 0, (new_n - old_n) * size);
+@@ -6495,31 +6500,15 @@ static int check_func_proto(const struct bpf_func_proto *fn, int func_id,
+ /* Packet data might have moved, any old PTR_TO_PACKET[_META,_END]
+  * are now invalid, so turn them into unknown SCALAR_VALUE.
+  */
+-static void __clear_all_pkt_pointers(struct bpf_verifier_env *env,
+-				     struct bpf_func_state *state)
++static void clear_all_pkt_pointers(struct bpf_verifier_env *env)
+ {
+-	struct bpf_reg_state *regs = state->regs, *reg;
+-	int i;
+-
+-	for (i = 0; i < MAX_BPF_REG; i++)
+-		if (reg_is_pkt_pointer_any(&regs[i]))
+-			mark_reg_unknown(env, regs, i);
++	struct bpf_func_state *state;
++	struct bpf_reg_state *reg;
+ 
+-	bpf_for_each_spilled_reg(i, state, reg) {
+-		if (!reg)
+-			continue;
++	bpf_for_each_reg_in_vstate(env->cur_state, state, reg, ({
+ 		if (reg_is_pkt_pointer_any(reg))
+ 			__mark_reg_unknown(env, reg);
+-	}
+-}
+-
+-static void clear_all_pkt_pointers(struct bpf_verifier_env *env)
+-{
+-	struct bpf_verifier_state *vstate = env->cur_state;
+-	int i;
+-
+-	for (i = 0; i <= vstate->curframe; i++)
+-		__clear_all_pkt_pointers(env, vstate->frame[i]);
++	}));
+ }
+ 
+ enum {
+@@ -6548,41 +6537,28 @@ static void mark_pkt_end(struct bpf_verifier_state *vstate, int regn, bool range
+ 		reg->range = AT_PKT_END;
+ }
+ 
+-static void release_reg_references(struct bpf_verifier_env *env,
+-				   struct bpf_func_state *state,
+-				   int ref_obj_id)
+-{
+-	struct bpf_reg_state *regs = state->regs, *reg;
+-	int i;
+-
+-	for (i = 0; i < MAX_BPF_REG; i++)
+-		if (regs[i].ref_obj_id == ref_obj_id)
+-			mark_reg_unknown(env, regs, i);
+-
+-	bpf_for_each_spilled_reg(i, state, reg) {
+-		if (!reg)
+-			continue;
+-		if (reg->ref_obj_id == ref_obj_id)
+-			__mark_reg_unknown(env, reg);
+-	}
+-}
+-
+ /* The pointer with the specified id has released its reference to kernel
+  * resources. Identify all copies of the same pointer and clear the reference.
+  */
+ static int release_reference(struct bpf_verifier_env *env,
+ 			     int ref_obj_id)
+ {
+-	struct bpf_verifier_state *vstate = env->cur_state;
++	struct bpf_func_state *state;
++	struct bpf_reg_state *reg;
+ 	int err;
+-	int i;
+ 
+ 	err = release_reference_state(cur_func(env), ref_obj_id);
+ 	if (err)
+ 		return err;
+ 
+-	for (i = 0; i <= vstate->curframe; i++)
+-		release_reg_references(env, vstate->frame[i], ref_obj_id);
++	bpf_for_each_reg_in_vstate(env->cur_state, state, reg, ({
++		if (reg->ref_obj_id == ref_obj_id) {
++			if (!env->allow_ptr_leaks)
++				__mark_reg_not_init(env, reg);
++			else
++				__mark_reg_unknown(env, reg);
++		}
++	}));
+ 
+ 	return 0;
+ }
+@@ -9278,34 +9254,14 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
+ 	return 0;
+ }
+ 
+-static void __find_good_pkt_pointers(struct bpf_func_state *state,
+-				     struct bpf_reg_state *dst_reg,
+-				     enum bpf_reg_type type, int new_range)
+-{
+-	struct bpf_reg_state *reg;
+-	int i;
+-
+-	for (i = 0; i < MAX_BPF_REG; i++) {
+-		reg = &state->regs[i];
+-		if (reg->type == type && reg->id == dst_reg->id)
+-			/* keep the maximum range already checked */
+-			reg->range = max(reg->range, new_range);
+-	}
+-
+-	bpf_for_each_spilled_reg(i, state, reg) {
+-		if (!reg)
+-			continue;
+-		if (reg->type == type && reg->id == dst_reg->id)
+-			reg->range = max(reg->range, new_range);
+-	}
+-}
+-
+ static void find_good_pkt_pointers(struct bpf_verifier_state *vstate,
+ 				   struct bpf_reg_state *dst_reg,
+ 				   enum bpf_reg_type type,
+ 				   bool range_right_open)
+ {
+-	int new_range, i;
++	struct bpf_func_state *state;
++	struct bpf_reg_state *reg;
++	int new_range;
+ 
+ 	if (dst_reg->off < 0 ||
+ 	    (dst_reg->off == 0 && range_right_open))
+@@ -9370,9 +9326,11 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *vstate,
+ 	 * the range won't allow anything.
+ 	 * dst_reg->off is known < MAX_PACKET_OFF, therefore it fits in a u16.
+ 	 */
+-	for (i = 0; i <= vstate->curframe; i++)
+-		__find_good_pkt_pointers(vstate->frame[i], dst_reg, type,
+-					 new_range);
++	bpf_for_each_reg_in_vstate(vstate, state, reg, ({
++		if (reg->type == type && reg->id == dst_reg->id)
++			/* keep the maximum range already checked */
++			reg->range = max(reg->range, new_range);
++	}));
+ }
+ 
+ static int is_branch32_taken(struct bpf_reg_state *reg, u32 val, u8 opcode)
+@@ -9861,7 +9819,7 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state,
+ 
+ 		if (!reg_may_point_to_spin_lock(reg)) {
+ 			/* For not-NULL ptr, reg->ref_obj_id will be reset
+-			 * in release_reg_references().
++			 * in release_reference().
+ 			 *
+ 			 * reg->id is still used by spin_lock ptr. Other
+ 			 * than spin_lock ptr type, reg->id can be reset.
+@@ -9871,22 +9829,6 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state,
+ 	}
+ }
+ 
+-static void __mark_ptr_or_null_regs(struct bpf_func_state *state, u32 id,
+-				    bool is_null)
+-{
+-	struct bpf_reg_state *reg;
+-	int i;
+-
+-	for (i = 0; i < MAX_BPF_REG; i++)
+-		mark_ptr_or_null_reg(state, &state->regs[i], id, is_null);
+-
+-	bpf_for_each_spilled_reg(i, state, reg) {
+-		if (!reg)
+-			continue;
+-		mark_ptr_or_null_reg(state, reg, id, is_null);
+-	}
+-}
+-
+ /* The logic is similar to find_good_pkt_pointers(), both could eventually
+  * be folded together at some point.
+  */
+@@ -9894,10 +9836,9 @@ static void mark_ptr_or_null_regs(struct bpf_verifier_state *vstate, u32 regno,
+ 				  bool is_null)
+ {
+ 	struct bpf_func_state *state = vstate->frame[vstate->curframe];
+-	struct bpf_reg_state *regs = state->regs;
++	struct bpf_reg_state *regs = state->regs, *reg;
+ 	u32 ref_obj_id = regs[regno].ref_obj_id;
+ 	u32 id = regs[regno].id;
+-	int i;
+ 
+ 	if (ref_obj_id && ref_obj_id == id && is_null)
+ 		/* regs[regno] is in the " == NULL" branch.
+@@ -9906,8 +9847,9 @@ static void mark_ptr_or_null_regs(struct bpf_verifier_state *vstate, u32 regno,
+ 		 */
+ 		WARN_ON_ONCE(release_reference_state(state, id));
+ 
+-	for (i = 0; i <= vstate->curframe; i++)
+-		__mark_ptr_or_null_regs(vstate->frame[i], id, is_null);
++	bpf_for_each_reg_in_vstate(vstate, state, reg, ({
++		mark_ptr_or_null_reg(state, reg, id, is_null);
++	}));
+ }
+ 
+ static bool try_match_pkt_pointers(const struct bpf_insn *insn,
+@@ -10020,23 +9962,11 @@ static void find_equal_scalars(struct bpf_verifier_state *vstate,
+ {
+ 	struct bpf_func_state *state;
+ 	struct bpf_reg_state *reg;
+-	int i, j;
+ 
+-	for (i = 0; i <= vstate->curframe; i++) {
+-		state = vstate->frame[i];
+-		for (j = 0; j < MAX_BPF_REG; j++) {
+-			reg = &state->regs[j];
+-			if (reg->type == SCALAR_VALUE && reg->id == known_reg->id)
+-				*reg = *known_reg;
+-		}
+-
+-		bpf_for_each_spilled_reg(j, state, reg) {
+-			if (!reg)
+-				continue;
+-			if (reg->type == SCALAR_VALUE && reg->id == known_reg->id)
+-				*reg = *known_reg;
+-		}
+-	}
++	bpf_for_each_reg_in_vstate(vstate, state, reg, ({
++		if (reg->type == SCALAR_VALUE && reg->id == known_reg->id)
++			*reg = *known_reg;
++	}));
+ }
+ 
+ static int check_cond_jmp_op(struct bpf_verifier_env *env,
+diff --git a/mm/damon/dbgfs.c b/mm/damon/dbgfs.c
+index 4e51466c4e74d..dafe7e71329b8 100644
+--- a/mm/damon/dbgfs.c
++++ b/mm/damon/dbgfs.c
+@@ -882,6 +882,7 @@ out:
+ static int dbgfs_rm_context(char *name)
+ {
+ 	struct dentry *root, *dir, **new_dirs;
++	struct inode *inode;
+ 	struct damon_ctx **new_ctxs;
+ 	int i, j;
+ 	int ret = 0;
+@@ -897,6 +898,12 @@ static int dbgfs_rm_context(char *name)
+ 	if (!dir)
+ 		return -ENOENT;
+ 
++	inode = d_inode(dir);
++	if (!S_ISDIR(inode->i_mode)) {
++		ret = -EINVAL;
++		goto out_dput;
++	}
++
+ 	new_dirs = kmalloc_array(dbgfs_nr_ctxs - 1, sizeof(*dbgfs_dirs),
+ 			GFP_KERNEL);
+ 	if (!new_dirs) {
+diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
+index 20f414c0379f9..fffb78378d6c0 100644
+--- a/mm/hugetlb_vmemmap.c
++++ b/mm/hugetlb_vmemmap.c
+@@ -11,6 +11,7 @@
+ #define pr_fmt(fmt)	"HugeTLB: " fmt
+ 
+ #include <linux/pgtable.h>
++#include <linux/moduleparam.h>
+ #include <linux/bootmem_info.h>
+ #include <asm/pgalloc.h>
+ #include <asm/tlbflush.h>
+diff --git a/mm/memremap.c b/mm/memremap.c
+index 58b20c3c300b8..b893e37c95c1e 100644
+--- a/mm/memremap.c
++++ b/mm/memremap.c
+@@ -330,6 +330,7 @@ void *memremap_pages(struct dev_pagemap *pgmap, int nid)
+ 			WARN(1, "File system DAX not supported\n");
+ 			return ERR_PTR(-EINVAL);
+ 		}
++		params.pgprot = pgprot_decrypted(params.pgprot);
+ 		break;
+ 	case MEMORY_DEVICE_GENERIC:
+ 		break;
+diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
+index 7327b2573f7c2..9fb3a8bd21102 100644
+--- a/mm/userfaultfd.c
++++ b/mm/userfaultfd.c
+@@ -64,7 +64,7 @@ int mfill_atomic_install_pte(struct mm_struct *dst_mm, pmd_t *dst_pmd,
+ 	pte_t _dst_pte, *dst_pte;
+ 	bool writable = dst_vma->vm_flags & VM_WRITE;
+ 	bool vm_shared = dst_vma->vm_flags & VM_SHARED;
+-	bool page_in_cache = page->mapping;
++	bool page_in_cache = page_mapping(page);
+ 	spinlock_t *ptl;
+ 	struct inode *inode;
+ 	pgoff_t offset, max_off;
+diff --git a/net/can/af_can.c b/net/can/af_can.c
+index 1fb49d51b25d6..e48ccf7cf2007 100644
+--- a/net/can/af_can.c
++++ b/net/can/af_can.c
+@@ -451,7 +451,7 @@ int can_rx_register(struct net *net, struct net_device *dev, canid_t can_id,
+ 
+ 	/* insert new receiver  (dev,canid,mask) -> (func,data) */
+ 
+-	if (dev && dev->type != ARPHRD_CAN)
++	if (dev && (dev->type != ARPHRD_CAN || !can_get_ml_priv(dev)))
+ 		return -ENODEV;
+ 
+ 	if (dev && !net_eq(net, dev_net(dev)))
+diff --git a/net/can/isotp.c b/net/can/isotp.c
+index 43a27d19cdacf..58e7d79ccd292 100644
+--- a/net/can/isotp.c
++++ b/net/can/isotp.c
+@@ -111,6 +111,9 @@ MODULE_ALIAS("can-proto-6");
+ #define ISOTP_FC_WT 1		/* wait */
+ #define ISOTP_FC_OVFLW 2	/* overflow */
+ 
++#define ISOTP_FC_TIMEOUT 1	/* 1 sec */
++#define ISOTP_ECHO_TIMEOUT 2	/* 2 secs */
++
+ enum {
+ 	ISOTP_IDLE = 0,
+ 	ISOTP_WAIT_FIRST_FC,
+@@ -258,7 +261,8 @@ static int isotp_send_fc(struct sock *sk, int ae, u8 flowstatus)
+ 	so->lastrxcf_tstamp = ktime_set(0, 0);
+ 
+ 	/* start rx timeout watchdog */
+-	hrtimer_start(&so->rxtimer, ktime_set(1, 0), HRTIMER_MODE_REL_SOFT);
++	hrtimer_start(&so->rxtimer, ktime_set(ISOTP_FC_TIMEOUT, 0),
++		      HRTIMER_MODE_REL_SOFT);
+ 	return 0;
+ }
+ 
+@@ -344,6 +348,8 @@ static int check_pad(struct isotp_sock *so, struct canfd_frame *cf,
+ 	return 0;
+ }
+ 
++static void isotp_send_cframe(struct isotp_sock *so);
++
+ static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae)
+ {
+ 	struct sock *sk = &so->sk;
+@@ -398,14 +404,15 @@ static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae)
+ 	case ISOTP_FC_CTS:
+ 		so->tx.bs = 0;
+ 		so->tx.state = ISOTP_SENDING;
+-		/* start cyclic timer for sending CF frame */
+-		hrtimer_start(&so->txtimer, so->tx_gap,
++		/* send CF frame and enable echo timeout handling */
++		hrtimer_start(&so->txtimer, ktime_set(ISOTP_ECHO_TIMEOUT, 0),
+ 			      HRTIMER_MODE_REL_SOFT);
++		isotp_send_cframe(so);
+ 		break;
+ 
+ 	case ISOTP_FC_WT:
+ 		/* start timer to wait for next FC frame */
+-		hrtimer_start(&so->txtimer, ktime_set(1, 0),
++		hrtimer_start(&so->txtimer, ktime_set(ISOTP_FC_TIMEOUT, 0),
+ 			      HRTIMER_MODE_REL_SOFT);
+ 		break;
+ 
+@@ -600,7 +607,7 @@ static int isotp_rcv_cf(struct sock *sk, struct canfd_frame *cf, int ae,
+ 	/* perform blocksize handling, if enabled */
+ 	if (!so->rxfc.bs || ++so->rx.bs < so->rxfc.bs) {
+ 		/* start rx timeout watchdog */
+-		hrtimer_start(&so->rxtimer, ktime_set(1, 0),
++		hrtimer_start(&so->rxtimer, ktime_set(ISOTP_FC_TIMEOUT, 0),
+ 			      HRTIMER_MODE_REL_SOFT);
+ 		return 0;
+ 	}
+@@ -829,7 +836,7 @@ static void isotp_rcv_echo(struct sk_buff *skb, void *data)
+ 	struct isotp_sock *so = isotp_sk(sk);
+ 	struct canfd_frame *cf = (struct canfd_frame *)skb->data;
+ 
+-	/* only handle my own local echo skb's */
++	/* only handle my own local echo CF/SF skb's (no FF!) */
+ 	if (skb->sk != sk || so->cfecho != *(u32 *)cf->data)
+ 		return;
+ 
+@@ -849,13 +856,16 @@ static void isotp_rcv_echo(struct sk_buff *skb, void *data)
+ 	if (so->txfc.bs && so->tx.bs >= so->txfc.bs) {
+ 		/* stop and wait for FC with timeout */
+ 		so->tx.state = ISOTP_WAIT_FC;
+-		hrtimer_start(&so->txtimer, ktime_set(1, 0),
++		hrtimer_start(&so->txtimer, ktime_set(ISOTP_FC_TIMEOUT, 0),
+ 			      HRTIMER_MODE_REL_SOFT);
+ 		return;
+ 	}
+ 
+ 	/* no gap between data frames needed => use burst mode */
+ 	if (!so->tx_gap) {
++		/* enable echo timeout handling */
++		hrtimer_start(&so->txtimer, ktime_set(ISOTP_ECHO_TIMEOUT, 0),
++			      HRTIMER_MODE_REL_SOFT);
+ 		isotp_send_cframe(so);
+ 		return;
+ 	}
+@@ -879,7 +889,7 @@ static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer)
+ 			/* start timeout for unlikely lost echo skb */
+ 			hrtimer_set_expires(&so->txtimer,
+ 					    ktime_add(ktime_get(),
+-						      ktime_set(2, 0)));
++						      ktime_set(ISOTP_ECHO_TIMEOUT, 0)));
+ 			restart = HRTIMER_RESTART;
+ 
+ 			/* push out the next consecutive frame */
+@@ -907,7 +917,8 @@ static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer)
+ 		break;
+ 
+ 	default:
+-		WARN_ON_ONCE(1);
++		WARN_ONCE(1, "can-isotp: tx timer state %08X cfecho %08X\n",
++			  so->tx.state, so->cfecho);
+ 	}
+ 
+ 	return restart;
+@@ -923,7 +934,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ 	struct canfd_frame *cf;
+ 	int ae = (so->opt.flags & CAN_ISOTP_EXTEND_ADDR) ? 1 : 0;
+ 	int wait_tx_done = (so->opt.flags & CAN_ISOTP_WAIT_TX_DONE) ? 1 : 0;
+-	s64 hrtimer_sec = 0;
++	s64 hrtimer_sec = ISOTP_ECHO_TIMEOUT;
+ 	int off;
+ 	int err;
+ 
+@@ -942,6 +953,8 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ 		err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+ 		if (err)
+ 			goto err_out;
++
++		so->tx.state = ISOTP_SENDING;
+ 	}
+ 
+ 	if (!size || size > MAX_MSG_LENGTH) {
+@@ -986,6 +999,10 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ 	cf = (struct canfd_frame *)skb->data;
+ 	skb_put_zero(skb, so->ll.mtu);
+ 
++	/* cfecho should have been zero'ed by init / former isotp_rcv_echo() */
++	if (so->cfecho)
++		pr_notice_once("can-isotp: uninit cfecho %08X\n", so->cfecho);
++
+ 	/* check for single frame transmission depending on TX_DL */
+ 	if (size <= so->tx.ll_dl - SF_PCI_SZ4 - ae - off) {
+ 		/* The message size generally fits into a SingleFrame - good.
+@@ -1011,11 +1028,8 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ 		else
+ 			cf->data[ae] |= size;
+ 
+-		so->tx.state = ISOTP_IDLE;
+-		wake_up_interruptible(&so->wait);
+-
+-		/* don't enable wait queue for a single frame transmission */
+-		wait_tx_done = 0;
++		/* set CF echo tag for isotp_rcv_echo() (SF-mode) */
++		so->cfecho = *(u32 *)cf->data;
+ 	} else {
+ 		/* send first frame */
+ 
+@@ -1031,31 +1045,23 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ 			/* disable wait for FCs due to activated block size */
+ 			so->txfc.bs = 0;
+ 
+-			/* cfecho should have been zero'ed by init */
+-			if (so->cfecho)
+-				pr_notice_once("can-isotp: no fc cfecho %08X\n",
+-					       so->cfecho);
+-
+-			/* set consecutive frame echo tag */
++			/* set CF echo tag for isotp_rcv_echo() (CF-mode) */
+ 			so->cfecho = *(u32 *)cf->data;
+-
+-			/* switch directly to ISOTP_SENDING state */
+-			so->tx.state = ISOTP_SENDING;
+-
+-			/* start timeout for unlikely lost echo skb */
+-			hrtimer_sec = 2;
+ 		} else {
+ 			/* standard flow control check */
+ 			so->tx.state = ISOTP_WAIT_FIRST_FC;
+ 
+ 			/* start timeout for FC */
+-			hrtimer_sec = 1;
+-		}
++			hrtimer_sec = ISOTP_FC_TIMEOUT;
+ 
+-		hrtimer_start(&so->txtimer, ktime_set(hrtimer_sec, 0),
+-			      HRTIMER_MODE_REL_SOFT);
++			/* no CF echo tag for isotp_rcv_echo() (FF-mode) */
++			so->cfecho = 0;
++		}
+ 	}
+ 
++	hrtimer_start(&so->txtimer, ktime_set(hrtimer_sec, 0),
++		      HRTIMER_MODE_REL_SOFT);
++
+ 	/* send the first or only CAN frame */
+ 	cf->flags = so->ll.tx_flags;
+ 
+@@ -1068,8 +1074,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
+ 			       __func__, ERR_PTR(err));
+ 
+ 		/* no transmission -> no timeout monitoring */
+-		if (hrtimer_sec)
+-			hrtimer_cancel(&so->txtimer);
++		hrtimer_cancel(&so->txtimer);
+ 
+ 		/* reset consecutive frame echo tag */
+ 		so->cfecho = 0;
+diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c
+index 8452b0fbb78c9..82671a882716f 100644
+--- a/net/can/j1939/main.c
++++ b/net/can/j1939/main.c
+@@ -332,6 +332,9 @@ int j1939_send_one(struct j1939_priv *priv, struct sk_buff *skb)
+ 	/* re-claim the CAN_HDR from the SKB */
+ 	cf = skb_push(skb, J1939_CAN_HDR);
+ 
++	/* initialize header structure */
++	memset(cf, 0, J1939_CAN_HDR);
++
+ 	/* make it a full can frame again */
+ 	skb_put(skb, J1939_CAN_FTR + (8 - dlc));
+ 
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 5e1a8eeb5e322..d9c19ae05fe67 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -4031,23 +4031,25 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
+ 	int i = 0;
+ 	int pos;
+ 
+-	if (list_skb && !list_skb->head_frag && skb_headlen(list_skb) &&
+-	    (skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY)) {
+-		/* gso_size is untrusted, and we have a frag_list with a linear
+-		 * non head_frag head.
+-		 *
+-		 * (we assume checking the first list_skb member suffices;
+-		 * i.e if either of the list_skb members have non head_frag
+-		 * head, then the first one has too).
+-		 *
+-		 * If head_skb's headlen does not fit requested gso_size, it
+-		 * means that the frag_list members do NOT terminate on exact
+-		 * gso_size boundaries. Hence we cannot perform skb_frag_t page
+-		 * sharing. Therefore we must fallback to copying the frag_list
+-		 * skbs; we do so by disabling SG.
+-		 */
+-		if (mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb))
+-			features &= ~NETIF_F_SG;
++	if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) &&
++	    mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) {
++		struct sk_buff *check_skb;
++
++		for (check_skb = list_skb; check_skb; check_skb = check_skb->next) {
++			if (skb_headlen(check_skb) && !check_skb->head_frag) {
++				/* gso_size is untrusted, and we have a frag_list with
++				 * a linear non head_frag item.
++				 *
++				 * If head_skb's headlen does not fit requested gso_size,
++				 * it means that the frag_list members do NOT terminate
++				 * on exact gso_size boundaries. Hence we cannot perform
++				 * skb_frag_t page sharing. Therefore we must fallback to
++				 * copying the frag_list skbs; we do so by disabling SG.
++				 */
++				features &= ~NETIF_F_SG;
++				break;
++			}
++		}
+ 	}
+ 
+ 	__skb_push(head_skb, doffset);
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index 1efdc47a999b4..e6b9ced3eda82 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -803,16 +803,13 @@ static void sk_psock_link_destroy(struct sk_psock *psock)
+ 	}
+ }
+ 
+-void sk_psock_stop(struct sk_psock *psock, bool wait)
++void sk_psock_stop(struct sk_psock *psock)
+ {
+ 	spin_lock_bh(&psock->ingress_lock);
+ 	sk_psock_clear_state(psock, SK_PSOCK_TX_ENABLED);
+ 	sk_psock_cork_free(psock);
+ 	__sk_psock_zap_ingress(psock);
+ 	spin_unlock_bh(&psock->ingress_lock);
+-
+-	if (wait)
+-		cancel_work_sync(&psock->work);
+ }
+ 
+ static void sk_psock_done_strp(struct sk_psock *psock);
+@@ -850,7 +847,7 @@ void sk_psock_drop(struct sock *sk, struct sk_psock *psock)
+ 		sk_psock_stop_verdict(sk, psock);
+ 	write_unlock_bh(&sk->sk_callback_lock);
+ 
+-	sk_psock_stop(psock, false);
++	sk_psock_stop(psock);
+ 
+ 	INIT_RCU_WORK(&psock->rwork, sk_psock_destroy);
+ 	queue_rcu_work(system_wq, &psock->rwork);
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c
+index 9a9fb9487d636..632df0c525625 100644
+--- a/net/core/sock_map.c
++++ b/net/core/sock_map.c
+@@ -1596,7 +1596,7 @@ void sock_map_destroy(struct sock *sk)
+ 	saved_destroy = psock->saved_destroy;
+ 	sock_map_remove_links(sk, psock);
+ 	rcu_read_unlock();
+-	sk_psock_stop(psock, false);
++	sk_psock_stop(psock);
+ 	sk_psock_put(sk, psock);
+ 	saved_destroy(sk);
+ }
+@@ -1619,9 +1619,10 @@ void sock_map_close(struct sock *sk, long timeout)
+ 	saved_close = psock->saved_close;
+ 	sock_map_remove_links(sk, psock);
+ 	rcu_read_unlock();
+-	sk_psock_stop(psock, true);
+-	sk_psock_put(sk, psock);
++	sk_psock_stop(psock);
+ 	release_sock(sk);
++	cancel_work_sync(&psock->work);
++	sk_psock_put(sk, psock);
+ 	saved_close(sk, timeout);
+ }
+ EXPORT_SYMBOL_GPL(sock_map_close);
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 5fbd0a5b48f7e..cdd4f2f60f0c6 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3648,7 +3648,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, int optname,
+ 	case TCP_REPAIR_OPTIONS:
+ 		if (!tp->repair)
+ 			err = -EINVAL;
+-		else if (sk->sk_state == TCP_ESTABLISHED)
++		else if (sk->sk_state == TCP_ESTABLISHED && !tp->bytes_sent)
+ 			err = tcp_repair_options_est(sk, optval, optlen);
+ 		else
+ 			err = -EPERM;
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index c501c329b1dbe..cf9c3e8f7ccbf 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -278,7 +278,7 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
+ {
+ 	bool cork = false, enospc = sk_msg_full(msg);
+ 	struct sock *sk_redir;
+-	u32 tosend, delta = 0;
++	u32 tosend, origsize, sent, delta = 0;
+ 	u32 eval = __SK_NONE;
+ 	int ret;
+ 
+@@ -333,10 +333,12 @@ more_data:
+ 			cork = true;
+ 			psock->cork = NULL;
+ 		}
+-		sk_msg_return(sk, msg, msg->sg.size);
++		sk_msg_return(sk, msg, tosend);
+ 		release_sock(sk);
+ 
++		origsize = msg->sg.size;
+ 		ret = tcp_bpf_sendmsg_redir(sk_redir, msg, tosend, flags);
++		sent = origsize - msg->sg.size;
+ 
+ 		if (eval == __SK_REDIRECT)
+ 			sock_put(sk_redir);
+@@ -375,7 +377,7 @@ more_data:
+ 		    msg->sg.data[msg->sg.start].page_link &&
+ 		    msg->sg.data[msg->sg.start].length) {
+ 			if (eval == __SK_REDIRECT)
+-				sk_mem_charge(sk, msg->sg.size);
++				sk_mem_charge(sk, tosend - sent);
+ 			goto more_data;
+ 		}
+ 	}
+diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
+index 8a22486cf2702..17ac45aa7194c 100644
+--- a/net/ipv6/addrlabel.c
++++ b/net/ipv6/addrlabel.c
+@@ -437,6 +437,7 @@ static void ip6addrlbl_putmsg(struct nlmsghdr *nlh,
+ {
+ 	struct ifaddrlblmsg *ifal = nlmsg_data(nlh);
+ 	ifal->ifal_family = AF_INET6;
++	ifal->__ifal_reserved = 0;
+ 	ifal->ifal_prefixlen = prefixlen;
+ 	ifal->ifal_flags = 0;
+ 	ifal->ifal_index = ifindex;
+diff --git a/net/mac80211/s1g.c b/net/mac80211/s1g.c
+index 8ca7d45d6daae..c1f964e9991cd 100644
+--- a/net/mac80211/s1g.c
++++ b/net/mac80211/s1g.c
+@@ -112,6 +112,9 @@ ieee80211_s1g_rx_twt_setup(struct ieee80211_sub_if_data *sdata,
+ 		goto out;
+ 	}
+ 
++	/* TWT Information not supported yet */
++	twt->control |= IEEE80211_TWT_CONTROL_RX_DISABLED;
++
+ 	drv_add_twt_setup(sdata->local, sdata, &sta->sta, twt);
+ out:
+ 	ieee80211_s1g_send_twt_setup(sdata, mgmt->sa, sdata->vif.addr, twt);
+diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
+index 13249e97a0692..d2c4f9226f947 100644
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -4379,6 +4379,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
+ 	if (likely(!is_multicast_ether_addr(eth->h_dest)))
+ 		goto normal;
+ 
++	if (unlikely(!ieee80211_sdata_running(sdata))) {
++		kfree_skb(skb);
++		return NETDEV_TX_OK;
++	}
++
+ 	if (unlikely(ieee80211_multicast_to_unicast(skb, dev))) {
+ 		struct sk_buff_head queue;
+ 
+diff --git a/net/mctp/af_mctp.c b/net/mctp/af_mctp.c
+index b6b5e496fa403..fc9e728b6333a 100644
+--- a/net/mctp/af_mctp.c
++++ b/net/mctp/af_mctp.c
+@@ -665,12 +665,14 @@ static __init int mctp_init(void)
+ 
+ 	rc = mctp_neigh_init();
+ 	if (rc)
+-		goto err_unreg_proto;
++		goto err_unreg_routes;
+ 
+ 	mctp_device_init();
+ 
+ 	return 0;
+ 
++err_unreg_routes:
++	mctp_routes_exit();
+ err_unreg_proto:
+ 	proto_unregister(&mctp_proto);
+ err_unreg_sock:
+diff --git a/net/mctp/route.c b/net/mctp/route.c
+index 2155f15a074cd..f9a80b82dc511 100644
+--- a/net/mctp/route.c
++++ b/net/mctp/route.c
+@@ -1400,7 +1400,7 @@ int __init mctp_routes_init(void)
+ 	return register_pernet_subsys(&mctp_net_ops);
+ }
+ 
+-void __exit mctp_routes_exit(void)
++void mctp_routes_exit(void)
+ {
+ 	unregister_pernet_subsys(&mctp_net_ops);
+ 	rtnl_unregister(PF_MCTP, RTM_DELROUTE);
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 879f4a1a27d54..42e370575c304 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -10090,7 +10090,8 @@ static void __net_exit nf_tables_exit_net(struct net *net)
+ 	struct nftables_pernet *nft_net = nft_pernet(net);
+ 
+ 	mutex_lock(&nft_net->commit_mutex);
+-	if (!list_empty(&nft_net->commit_list))
++	if (!list_empty(&nft_net->commit_list) ||
++	    !list_empty(&nft_net->module_list))
+ 		__nf_tables_abort(net, NFNL_ABORT_NONE);
+ 	__nft_release_tables(net);
+ 	mutex_unlock(&nft_net->commit_mutex);
+diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
+index 9c44518cb70ff..6d18fb3468683 100644
+--- a/net/netfilter/nfnetlink.c
++++ b/net/netfilter/nfnetlink.c
+@@ -294,6 +294,7 @@ replay:
+ 			nfnl_lock(subsys_id);
+ 			if (nfnl_dereference_protected(subsys_id) != ss ||
+ 			    nfnetlink_find_client(type, ss) != nc) {
++				nfnl_unlock(subsys_id);
+ 				err = -EAGAIN;
+ 				break;
+ 			}
+diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
+index 0749df80454d4..ce00f271ca6b2 100644
+--- a/net/tipc/netlink_compat.c
++++ b/net/tipc/netlink_compat.c
+@@ -880,7 +880,7 @@ static int tipc_nl_compat_name_table_dump_header(struct tipc_nl_compat_msg *msg)
+ 	};
+ 
+ 	ntq = (struct tipc_name_table_query *)TLV_DATA(msg->req);
+-	if (TLV_GET_DATA_LEN(msg->req) < sizeof(struct tipc_name_table_query))
++	if (TLV_GET_DATA_LEN(msg->req) < (int)sizeof(struct tipc_name_table_query))
+ 		return -EINVAL;
+ 
+ 	depth = ntohl(ntq->depth);
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index d5c7a5aa68532..c3d950d294329 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -1084,6 +1084,8 @@ MODULE_FIRMWARE("regulatory.db");
+ 
+ static int query_regdb_file(const char *alpha2)
+ {
++	int err;
++
+ 	ASSERT_RTNL();
+ 
+ 	if (regdb)
+@@ -1093,9 +1095,13 @@ static int query_regdb_file(const char *alpha2)
+ 	if (!alpha2)
+ 		return -ENOMEM;
+ 
+-	return request_firmware_nowait(THIS_MODULE, true, "regulatory.db",
+-				       &reg_pdev->dev, GFP_KERNEL,
+-				       (void *)alpha2, regdb_fw_cb);
++	err = request_firmware_nowait(THIS_MODULE, true, "regulatory.db",
++				      &reg_pdev->dev, GFP_KERNEL,
++				      (void *)alpha2, regdb_fw_cb);
++	if (err)
++		kfree(alpha2);
++
++	return err;
+ }
+ 
+ int reg_reload_regdb(void)
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 39fb9cc25cdca..9067e4b70855a 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -1674,7 +1674,9 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
+ 		if (old == rcu_access_pointer(known->pub.ies))
+ 			rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
+ 
+-		cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old);
++		cfg80211_update_hidden_bsses(known,
++					     rcu_access_pointer(new->pub.beacon_ies),
++					     old);
+ 
+ 		if (old)
+ 			kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
+diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
+index e55c0421718b3..2ca33fd5a5757 100644
+--- a/sound/arm/pxa2xx-ac97-lib.c
++++ b/sound/arm/pxa2xx-ac97-lib.c
+@@ -402,8 +402,10 @@ int pxa2xx_ac97_hw_probe(struct platform_device *dev)
+ 		goto err_clk2;
+ 
+ 	irq = platform_get_irq(dev, 0);
+-	if (!irq)
++	if (irq < 0) {
++		ret = irq;
+ 		goto err_irq;
++	}
+ 
+ 	ret = request_irq(irq, pxa2xx_ac97_irq, 0, "AC97", NULL);
+ 	if (ret < 0)
+diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
+index cfcd8eff41398..d311cff8d5bef 100644
+--- a/sound/core/memalloc.c
++++ b/sound/core/memalloc.c
+@@ -9,6 +9,7 @@
+ #include <linux/slab.h>
+ #include <linux/mm.h>
+ #include <linux/dma-mapping.h>
++#include <linux/dma-map-ops.h>
+ #include <linux/genalloc.h>
+ #include <linux/highmem.h>
+ #include <linux/vmalloc.h>
+@@ -528,17 +529,17 @@ static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size)
+ 
+ 	sgt = dma_alloc_noncontiguous(dmab->dev.dev, size, dmab->dev.dir,
+ 				      DEFAULT_GFP, 0);
+-	if (!sgt) {
+ #ifdef CONFIG_SND_DMA_SGBUF
++	if (!sgt && !get_dma_ops(dmab->dev.dev)) {
+ 		if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG)
+ 			dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK;
+ 		else
+ 			dmab->dev.type = SNDRV_DMA_TYPE_DEV_SG_FALLBACK;
+ 		return snd_dma_sg_fallback_alloc(dmab, size);
+-#else
+-		return NULL;
+-#endif
+ 	}
++#endif
++	if (!sgt)
++		return NULL;
+ 
+ 	dmab->dev.need_sync = dma_need_sync(dmab->dev.dev,
+ 					    sg_dma_address(sgt->sgl));
+@@ -874,7 +875,7 @@ static const struct snd_malloc_ops snd_dma_noncoherent_ops = {
+ /*
+  * Entry points
+  */
+-static const struct snd_malloc_ops *dma_ops[] = {
++static const struct snd_malloc_ops *snd_dma_ops[] = {
+ 	[SNDRV_DMA_TYPE_CONTINUOUS] = &snd_dma_continuous_ops,
+ 	[SNDRV_DMA_TYPE_VMALLOC] = &snd_dma_vmalloc_ops,
+ #ifdef CONFIG_HAS_DMA
+@@ -900,7 +901,7 @@ static const struct snd_malloc_ops *snd_dma_get_ops(struct snd_dma_buffer *dmab)
+ 	if (WARN_ON_ONCE(!dmab))
+ 		return NULL;
+ 	if (WARN_ON_ONCE(dmab->dev.type <= SNDRV_DMA_TYPE_UNKNOWN ||
+-			 dmab->dev.type >= ARRAY_SIZE(dma_ops)))
++			 dmab->dev.type >= ARRAY_SIZE(snd_dma_ops)))
+ 		return NULL;
+-	return dma_ops[dmab->dev.type];
++	return snd_dma_ops[dmab->dev.type];
+ }
+diff --git a/sound/hda/hdac_sysfs.c b/sound/hda/hdac_sysfs.c
+index e47de49a32e3e..62a9615dcf529 100644
+--- a/sound/hda/hdac_sysfs.c
++++ b/sound/hda/hdac_sysfs.c
+@@ -346,8 +346,10 @@ static int add_widget_node(struct kobject *parent, hda_nid_t nid,
+ 		return -ENOMEM;
+ 	kobject_init(kobj, &widget_ktype);
+ 	err = kobject_add(kobj, parent, "%02x", nid);
+-	if (err < 0)
++	if (err < 0) {
++		kobject_put(kobj);
+ 		return err;
++	}
+ 	err = sysfs_create_group(kobj, group);
+ 	if (err < 0) {
+ 		kobject_put(kobj);
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 1631e1de84046..8f8b9ebe5c5ff 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2718,6 +2718,9 @@ static const struct pci_device_id azx_ids[] = {
+ 	{ PCI_DEVICE(0x1002, 0xab28),
+ 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+ 	  AZX_DCAPS_PM_RUNTIME },
++	{ PCI_DEVICE(0x1002, 0xab30),
++	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
++	  AZX_DCAPS_PM_RUNTIME },
+ 	{ PCI_DEVICE(0x1002, 0xab38),
+ 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
+ 	  AZX_DCAPS_PM_RUNTIME },
+diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
+index 208933792787d..801dd8d44953b 100644
+--- a/sound/pci/hda/patch_ca0132.c
++++ b/sound/pci/hda/patch_ca0132.c
+@@ -1306,6 +1306,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
+ 	SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI),
+ 	SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI),
+ 	SND_PCI_QUIRK(0x3842, 0x1038, "EVGA X99 Classified", QUIRK_R3DI),
++	SND_PCI_QUIRK(0x3842, 0x1055, "EVGA Z390 DARK", QUIRK_R3DI),
+ 	SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D),
+ 	SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D),
+ 	SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5),
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 6e25a0f89f6b4..b7cccbef401ce 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -9414,6 +9414,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
+ 	SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
+ 	SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
++	SND_PCI_QUIRK(0x1043, 0x1f12, "ASUS UM5302", ALC287_FIXUP_CS35L41_I2C_2),
+ 	SND_PCI_QUIRK(0x1043, 0x1f92, "ASUS ROG Flow X16", ALC289_FIXUP_ASUS_GA401),
+ 	SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
+ 	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
+@@ -9618,6 +9619,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+ 	SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
+ 	SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK),
++	SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC),
+ 	SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
+ 	SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),
+diff --git a/sound/usb/card.c b/sound/usb/card.c
+index a5ed11ea11456..26268ffb82742 100644
+--- a/sound/usb/card.c
++++ b/sound/usb/card.c
+@@ -742,6 +742,18 @@ get_alias_quirk(struct usb_device *dev, unsigned int id)
+ 	return NULL;
+ }
+ 
++/* register card if we reach to the last interface or to the specified
++ * one given via option
++ */
++static int try_to_register_card(struct snd_usb_audio *chip, int ifnum)
++{
++	if (check_delayed_register_option(chip) == ifnum ||
++	    chip->last_iface == ifnum ||
++	    usb_interface_claimed(usb_ifnum_to_if(chip->dev, chip->last_iface)))
++		return snd_card_register(chip->card);
++	return 0;
++}
++
+ /*
+  * probe the active usb device
+  *
+@@ -880,15 +892,9 @@ static int usb_audio_probe(struct usb_interface *intf,
+ 		chip->need_delayed_register = false; /* clear again */
+ 	}
+ 
+-	/* register card if we reach to the last interface or to the specified
+-	 * one given via option
+-	 */
+-	if (check_delayed_register_option(chip) == ifnum ||
+-	    usb_interface_claimed(usb_ifnum_to_if(dev, chip->last_iface))) {
+-		err = snd_card_register(chip->card);
+-		if (err < 0)
+-			goto __error;
+-	}
++	err = try_to_register_card(chip, ifnum);
++	if (err < 0)
++		goto __error_no_register;
+ 
+ 	if (chip->quirk_flags & QUIRK_FLAG_SHARE_MEDIA_DEVICE) {
+ 		/* don't want to fail when snd_media_device_create() fails */
+@@ -907,6 +913,11 @@ static int usb_audio_probe(struct usb_interface *intf,
+ 	return 0;
+ 
+  __error:
++	/* in the case of error in secondary interface, still try to register */
++	if (chip)
++		try_to_register_card(chip, ifnum);
++
++ __error_no_register:
+ 	if (chip) {
+ 		/* chip->active is inside the chip->card object,
+ 		 * decrement before memory is possibly returned.
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index 06dfdd45cff8c..874fcf245747f 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -2049,6 +2049,10 @@ YAMAHA_DEVICE(0x7010, "UB99"),
+ 		}
+ 	}
+ },
++{
++	/* M-Audio Micro */
++	USB_DEVICE_VENDOR_SPEC(0x0763, 0x201a),
++},
+ {
+ 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x2030),
+ 	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index eadac586bcc83..250bda7cda075 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1913,6 +1913,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
+ 	/* XMOS based USB DACs */
+ 	switch (chip->usb_id) {
+ 	case USB_ID(0x1511, 0x0037): /* AURALiC VEGA */
++	case USB_ID(0x21ed, 0xd75a): /* Accuphase DAC-60 option card */
+ 	case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */
+ 	case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */
+ 		if (fp->altsetting == 2)
+diff --git a/tools/arch/x86/include/asm/msr-index.h b/tools/arch/x86/include/asm/msr-index.h
+index 6674bdb096f34..ee71f15eed7f2 100644
+--- a/tools/arch/x86/include/asm/msr-index.h
++++ b/tools/arch/x86/include/asm/msr-index.h
+@@ -530,6 +530,11 @@
+ #define MSR_AMD64_CPUID_FN_1		0xc0011004
+ #define MSR_AMD64_LS_CFG		0xc0011020
+ #define MSR_AMD64_DC_CFG		0xc0011022
++
++#define MSR_AMD64_DE_CFG		0xc0011029
++#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT	1
++#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE	BIT_ULL(MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT)
++
+ #define MSR_AMD64_BU_CFG2		0xc001102a
+ #define MSR_AMD64_IBSFETCHCTL		0xc0011030
+ #define MSR_AMD64_IBSFETCHLINAD		0xc0011031
+@@ -632,9 +637,6 @@
+ #define FAM10H_MMIO_CONF_BASE_MASK	0xfffffffULL
+ #define FAM10H_MMIO_CONF_BASE_SHIFT	20
+ #define MSR_FAM10H_NODE_ID		0xc001100c
+-#define MSR_F10H_DECFG			0xc0011029
+-#define MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT	1
+-#define MSR_F10H_DECFG_LFENCE_SERIALIZE		BIT_ULL(MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT)
+ 
+ /* K8 MSRs */
+ #define MSR_K8_TOP_MEM1			0xc001001a
+diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
+index 067e9ea59e3b0..3bdbc0ce75b15 100644
+--- a/tools/bpf/bpftool/common.c
++++ b/tools/bpf/bpftool/common.c
+@@ -300,6 +300,9 @@ int do_pin_any(int argc, char **argv, int (*get_fd)(int *, char ***))
+ 	int err;
+ 	int fd;
+ 
++	if (!REQ_ARGS(3))
++		return -EINVAL;
++
+ 	fd = get_fd(&argc, &argv);
+ 	if (fd < 0)
+ 		return fd;
+diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
+index 4b9c71faa01ad..f136309044dab 100644
+--- a/tools/perf/.gitignore
++++ b/tools/perf/.gitignore
+@@ -4,6 +4,7 @@ PERF-GUI-VARS
+ PERF-VERSION-FILE
+ FEATURE-DUMP
+ perf
++!include/perf/
+ perf-read-vdso32
+ perf-read-vdsox32
+ perf-help
+diff --git a/tools/perf/tests/shell/test_brstack.sh b/tools/perf/tests/shell/test_brstack.sh
+index ec801cffae6bc..d7ff5c4b4da4c 100755
+--- a/tools/perf/tests/shell/test_brstack.sh
++++ b/tools/perf/tests/shell/test_brstack.sh
+@@ -13,7 +13,10 @@ fi
+ 
+ # skip the test if the hardware doesn't support branch stack sampling
+ # and if the architecture doesn't support filter types: any,save_type,u
+-perf record -b -o- -B --branch-filter any,save_type,u true > /dev/null 2>&1 || exit 2
++if ! perf record -o- --no-buildid --branch-filter any,save_type,u -- true > /dev/null 2>&1 ; then
++	echo "skip: system doesn't support filter types: any,save_type,u"
++	exit 2
++fi
+ 
+ TMPDIR=$(mktemp -d /tmp/__perf_test.program.XXXXX)
+ 
+diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c
+index bb4aa88c50a82..35264b5684d09 100644
+--- a/tools/perf/util/parse-branch-options.c
++++ b/tools/perf/util/parse-branch-options.c
+@@ -101,8 +101,10 @@ parse_branch_stack(const struct option *opt, const char *str, int unset)
+ 	/*
+ 	 * cannot set it twice, -b + --branch-filter for instance
+ 	 */
+-	if (*mode)
++	if (*mode) {
++		pr_err("Error: Can't use --branch-any (-b) with --branch-filter (-j).\n");
+ 		return -1;
++	}
+ 
+ 	return parse_branch_str(str, mode);
+ }
+diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
+index b82844cb0ce77..7c5f5219dbff2 100644
+--- a/tools/perf/util/stat-display.c
++++ b/tools/perf/util/stat-display.c
+@@ -273,7 +273,7 @@ static void new_line_csv(struct perf_stat_config *config, void *ctx)
+ 
+ 	fputc('\n', os->fh);
+ 	if (os->prefix)
+-		fprintf(os->fh, "%s%s", os->prefix, config->csv_sep);
++		fprintf(os->fh, "%s", os->prefix);
+ 	aggr_printout(config, os->evsel, os->id, os->nr);
+ 	for (i = 0; i < os->nfields; i++)
+ 		fputs(config->csv_sep, os->fh);
+@@ -556,7 +556,7 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int
+ 			[AGGR_CORE] = 2,
+ 			[AGGR_THREAD] = 1,
+ 			[AGGR_UNSET] = 0,
+-			[AGGR_NODE] = 0,
++			[AGGR_NODE] = 1,
+ 		};
+ 
+ 		pm = config->metric_only ? print_metric_only_csv : print_metric_csv;
+@@ -1126,6 +1126,7 @@ static int aggr_header_lens[] = {
+ 	[AGGR_SOCKET] = 12,
+ 	[AGGR_NONE] = 6,
+ 	[AGGR_THREAD] = 24,
++	[AGGR_NODE] = 6,
+ 	[AGGR_GLOBAL] = 0,
+ };
+ 
+@@ -1135,6 +1136,7 @@ static const char *aggr_header_csv[] = {
+ 	[AGGR_SOCKET] 	= 	"socket,cpus",
+ 	[AGGR_NONE] 	= 	"cpu,",
+ 	[AGGR_THREAD] 	= 	"comm-pid,",
++	[AGGR_NODE] 	= 	"node,",
+ 	[AGGR_GLOBAL] 	=	""
+ };
+ 
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 4c5259828efdc..b76c775f61f99 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -5404,6 +5404,7 @@ static int kvm_debugfs_open(struct inode *inode, struct file *file,
+ 			   int (*get)(void *, u64 *), int (*set)(void *, u64),
+ 			   const char *fmt)
+ {
++	int ret;
+ 	struct kvm_stat_data *stat_data = (struct kvm_stat_data *)
+ 					  inode->i_private;
+ 
+@@ -5415,15 +5416,13 @@ static int kvm_debugfs_open(struct inode *inode, struct file *file,
+ 	if (!kvm_get_kvm_safe(stat_data->kvm))
+ 		return -ENOENT;
+ 
+-	if (simple_attr_open(inode, file, get,
+-		    kvm_stats_debugfs_mode(stat_data->desc) & 0222
+-		    ? set : NULL,
+-		    fmt)) {
++	ret = simple_attr_open(inode, file, get,
++			       kvm_stats_debugfs_mode(stat_data->desc) & 0222
++			       ? set : NULL, fmt);
++	if (ret)
+ 		kvm_put_kvm(stat_data->kvm);
+-		return -ENOMEM;
+-	}
+ 
+-	return 0;
++	return ret;
+ }
+ 
+ static int kvm_debugfs_release(struct inode *inode, struct file *file)


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-10 18:18 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-11-10 18:18 UTC (permalink / raw
  To: gentoo-commits

commit:     e9f10a9f82f0947e4dbab972345827bf6ddcd393
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Nov 10 18:18:04 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Nov 10 18:18:04 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=e9f10a9f

Remove redundant patch

Removed:
btrfs: Don't use btrfs_chunk::sub_stripes from disk

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

 0000_README                            |  4 --
 1900_btrfs-chunk-sub_stripes-fix.patch | 92 ----------------------------------
 2 files changed, 96 deletions(-)

diff --git a/0000_README b/0000_README
index 52ac8549..04880a09 100644
--- a/0000_README
+++ b/0000_README
@@ -87,10 +87,6 @@ Patch:  1700_sparc-address-warray-bound-warnings.patch
 From:		https://github.com/KSPP/linux/issues/109
 Desc:		Address -Warray-bounds warnings 
 
-Patch:  1900_btrfs-chunk-sub_stripes-fix.patch
-From:		https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
-Desc:		btrfs: Don't use btrfs_chunk::sub_stripes from disk
-
 Patch:  2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
 From:   https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw
 Desc:   Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758

diff --git a/1900_btrfs-chunk-sub_stripes-fix.patch b/1900_btrfs-chunk-sub_stripes-fix.patch
deleted file mode 100644
index 2ffe02fe..00000000
--- a/1900_btrfs-chunk-sub_stripes-fix.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 76a66ba101329316a5d7f4275070be22eb85fdf2 Mon Sep 17 00:00:00 2001
-From: Qu Wenruo <wqu@suse.com>
-Date: Fri, 21 Oct 2022 08:43:45 +0800
-Subject: btrfs: don't use btrfs_chunk::sub_stripes from disk
-
-[BUG]
-There are two reports (the earliest one from LKP, a more recent one from
-kernel bugzilla) that we can have some chunks with 0 as sub_stripes.
-
-This will cause divide-by-zero errors at btrfs_rmap_block, which is
-introduced by a recent kernel patch ac0677348f3c ("btrfs: merge
-calculations for simple striped profiles in btrfs_rmap_block"):
-
-		if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
-				 BTRFS_BLOCK_GROUP_RAID10)) {
-			stripe_nr = stripe_nr * map->num_stripes + i;
-			stripe_nr = div_u64(stripe_nr, map->sub_stripes); <<<
-		}
-
-[CAUSE]
-From the more recent report, it has been proven that we have some chunks
-with 0 as sub_stripes, mostly caused by older mkfs.
-
-It turns out that the mkfs.btrfs fix is only introduced in 6718ab4d33aa
-("btrfs-progs: Initialize sub_stripes to 1 in btrfs_alloc_data_chunk")
-which is included in v5.4 btrfs-progs release.
-
-So there would be quite some old filesystems with such 0 sub_stripes.
-
-[FIX]
-Just don't trust the sub_stripes values from disk.
-
-We have a trusted btrfs_raid_array[] to fetch the correct sub_stripes
-numbers for each profile and that are fixed.
-
-By this, we can keep the compatibility with older filesystems while
-still avoid divide-by-zero bugs.
-
-Reported-by: kernel test robot <oliver.sang@intel.com>
-Reported-by: Viktor Kuzmin <kvaster@gmail.com>
-Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216559
-Fixes: ac0677348f3c ("btrfs: merge calculations for simple striped profiles in btrfs_rmap_block")
-CC: stable@vger.kernel.org # 6.0
-Reviewed-by: Su Yue <glass@fydeos.io>
-Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
-Signed-off-by: Qu Wenruo <wqu@suse.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
----
- fs/btrfs/volumes.c | 12 +++++++++++-
- 1 file changed, 11 insertions(+), 1 deletion(-)
-
-(limited to 'fs/btrfs/volumes.c')
-
-diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
-index 94ba46d579205..a8d4bc6a19379 100644
---- a/fs/btrfs/volumes.c
-+++ b/fs/btrfs/volumes.c
-@@ -7142,6 +7142,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
- 	u64 devid;
- 	u64 type;
- 	u8 uuid[BTRFS_UUID_SIZE];
-+	int index;
- 	int num_stripes;
- 	int ret;
- 	int i;
-@@ -7149,6 +7150,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
- 	logical = key->offset;
- 	length = btrfs_chunk_length(leaf, chunk);
- 	type = btrfs_chunk_type(leaf, chunk);
-+	index = btrfs_bg_flags_to_raid_index(type);
- 	num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
- 
- #if BITS_PER_LONG == 32
-@@ -7202,7 +7204,15 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
- 	map->io_align = btrfs_chunk_io_align(leaf, chunk);
- 	map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
- 	map->type = type;
--	map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
-+	/*
-+	 * We can't use the sub_stripes value, as for profiles other than
-+	 * RAID10, they may have 0 as sub_stripes for filesystems created by
-+	 * older mkfs (<v5.4).
-+	 * In that case, it can cause divide-by-zero errors later.
-+	 * Since currently sub_stripes is fixed for each profile, let's
-+	 * use the trusted value instead.
-+	 */
-+	map->sub_stripes = btrfs_raid_array[index].sub_stripes;
- 	map->verified_stripes = 0;
- 	em->orig_block_len = btrfs_calc_stripe_length(em);
- 	for (i = 0; i < num_stripes; i++) {
--- 
-cgit 


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-10 18:10 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-11-10 18:10 UTC (permalink / raw
  To: gentoo-commits

commit:     8b3e419be10860f5c8692b5fb9acaaee189b3279
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Nov 10 18:09:47 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Nov 10 18:09:47 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=8b3e419b

Linux patch 6.0.8

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

 0000_README            |    4 +
 1007_linux-6.0.8.patch | 7683 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 7687 insertions(+)

diff --git a/0000_README b/0000_README
index 004afc57..52ac8549 100644
--- a/0000_README
+++ b/0000_README
@@ -71,6 +71,10 @@ Patch:  1006_linux-6.0.7.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.7
 
+Patch:  1007_linux-6.0.8.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.8
+
 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/1007_linux-6.0.8.patch b/1007_linux-6.0.8.patch
new file mode 100644
index 00000000..c970b363
--- /dev/null
+++ b/1007_linux-6.0.8.patch
@@ -0,0 +1,7683 @@
+diff --git a/Documentation/process/howto.rst b/Documentation/process/howto.rst
+index cd6997a9d2032..8fc5398c732bc 100644
+--- a/Documentation/process/howto.rst
++++ b/Documentation/process/howto.rst
+@@ -36,7 +36,7 @@ experience, the following books are good for, if anything, reference:
+  - "C:  A Reference Manual" by Harbison and Steele [Prentice Hall]
+ 
+ The kernel is written using GNU C and the GNU toolchain.  While it
+-adheres to the ISO C89 standard, it uses a number of extensions that are
++adheres to the ISO C11 standard, it uses a number of extensions that are
+ not featured in the standard.  The kernel is a freestanding C
+ environment, with no reliance on the standard C library, so some
+ portions of the C standard are not supported.  Arbitrary long long
+diff --git a/Documentation/trace/histogram.rst b/Documentation/trace/histogram.rst
+index 859fd1b76c638..69354e1e7b255 100644
+--- a/Documentation/trace/histogram.rst
++++ b/Documentation/trace/histogram.rst
+@@ -39,7 +39,7 @@ Documentation written by Tom Zanussi
+   will use the event's kernel stacktrace as the key.  The keywords
+   'keys' or 'key' can be used to specify keys, and the keywords
+   'values', 'vals', or 'val' can be used to specify values.  Compound
+-  keys consisting of up to two fields can be specified by the 'keys'
++  keys consisting of up to three fields can be specified by the 'keys'
+   keyword.  Hashing a compound key produces a unique entry in the
+   table for each unique combination of component keys, and can be
+   useful for providing more fine-grained summaries of event data.
+diff --git a/Documentation/translations/it_IT/process/howto.rst b/Documentation/translations/it_IT/process/howto.rst
+index 16ad5622d5495..67b84f015da8a 100644
+--- a/Documentation/translations/it_IT/process/howto.rst
++++ b/Documentation/translations/it_IT/process/howto.rst
+@@ -44,7 +44,7 @@ altro, utili riferimenti:
+ - "C:  A Reference Manual" di Harbison and Steele [Prentice Hall]
+ 
+ Il kernel è stato scritto usando GNU C e la toolchain GNU.
+-Sebbene si attenga allo standard ISO C89, esso utilizza una serie di
++Sebbene si attenga allo standard ISO C11, esso utilizza una serie di
+ estensioni che non sono previste in questo standard. Il kernel è un
+ ambiente C indipendente, che non ha alcuna dipendenza dalle librerie
+ C standard, così alcune parti del C standard non sono supportate.
+diff --git a/Documentation/translations/ja_JP/howto.rst b/Documentation/translations/ja_JP/howto.rst
+index 649e2ff2a407e..e2e946a4298ad 100644
+--- a/Documentation/translations/ja_JP/howto.rst
++++ b/Documentation/translations/ja_JP/howto.rst
+@@ -65,7 +65,7 @@ Linux カーネル開発のやり方
+  - 『新・詳説 C 言語 H&S リファレンス』 (サミュエル P ハービソン/ガイ L スティール共著 斉藤 信男監訳)[ソフトバンク]
+ 
+ カーネルは GNU C と GNU ツールチェインを使って書かれています。カーネル
+-は ISO C89 仕様に準拠して書く一方で、標準には無い言語拡張を多く使って
++は ISO C11 仕様に準拠して書く一方で、標準には無い言語拡張を多く使って
+ います。カーネルは標準 C ライブラリに依存しない、C 言語非依存環境です。
+ そのため、C の標準の中で使えないものもあります。特に任意の long long
+ の除算や浮動小数点は使えません。カーネルがツールチェインや C 言語拡張
+diff --git a/Documentation/translations/ko_KR/howto.rst b/Documentation/translations/ko_KR/howto.rst
+index e43970584ca4d..2a7ab4257e44c 100644
+--- a/Documentation/translations/ko_KR/howto.rst
++++ b/Documentation/translations/ko_KR/howto.rst
+@@ -62,7 +62,7 @@ Documentation/process/howto.rst
+  - "Practical C Programming" by Steve Oualline [O'Reilly]
+  - "C:  A Reference Manual" by Harbison and Steele [Prentice Hall]
+ 
+-커널은 GNU C와 GNU 툴체인을 사용하여 작성되었다. 이 툴들은 ISO C89 표준을
++커널은 GNU C와 GNU 툴체인을 사용하여 작성되었다. 이 툴들은 ISO C11 표준을
+ 따르는 반면 표준에 있지 않은 많은 확장기능도 가지고 있다. 커널은 표준 C
+ 라이브러리와는 관계없이 freestanding C 환경이어서 C 표준의 일부는
+ 지원되지 않는다. 임의의 long long 나누기나 floating point는 지원되지 않는다.
+diff --git a/Documentation/translations/zh_CN/process/howto.rst b/Documentation/translations/zh_CN/process/howto.rst
+index 1455190dc087a..e7e4bb000b8a5 100644
+--- a/Documentation/translations/zh_CN/process/howto.rst
++++ b/Documentation/translations/zh_CN/process/howto.rst
+@@ -45,7 +45,7 @@ Linux内核大部分是由C语言写成的,一些体系结构相关的代码
+  - "C:  A Reference Manual" by Harbison and Steele [Prentice Hall]
+    《C语言参考手册(原书第5版)》(邱仲潘 等译)[机械工业出版社]
+ 
+-Linux内核使用GNU C和GNU工具链开发。虽然它遵循ISO C89标准,但也用到了一些
++Linux内核使用GNU C和GNU工具链开发。虽然它遵循ISO C11标准,但也用到了一些
+ 标准中没有定义的扩展。内核是自给自足的C环境,不依赖于标准C库的支持,所以
+ 并不支持C标准中的部分定义。比如long long类型的大数除法和浮点运算就不允许
+ 使用。有时候确实很难弄清楚内核对工具链的要求和它所使用的扩展,不幸的是目
+diff --git a/Documentation/translations/zh_TW/process/howto.rst b/Documentation/translations/zh_TW/process/howto.rst
+index 68ae4411285b8..e335789d7e26c 100644
+--- a/Documentation/translations/zh_TW/process/howto.rst
++++ b/Documentation/translations/zh_TW/process/howto.rst
+@@ -48,7 +48,7 @@ Linux內核大部分是由C語言寫成的,一些體系結構相關的代碼
+  - "C:  A Reference Manual" by Harbison and Steele [Prentice Hall]
+    《C語言參考手冊(原書第5版)》(邱仲潘 等譯)[機械工業出版社]
+ 
+-Linux內核使用GNU C和GNU工具鏈開發。雖然它遵循ISO C89標準,但也用到了一些
++Linux內核使用GNU C和GNU工具鏈開發。雖然它遵循ISO C11標準,但也用到了一些
+ 標準中沒有定義的擴展。內核是自給自足的C環境,不依賴於標準C庫的支持,所以
+ 並不支持C標準中的部分定義。比如long long類型的大數除法和浮點運算就不允許
+ 使用。有時候確實很難弄清楚內核對工具鏈的要求和它所使用的擴展,不幸的是目
+diff --git a/Makefile b/Makefile
+index c2144a4bb2efe..bcb76d4fdbc11 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 7
++SUBLEVEL = 8
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/arm/boot/dts/imx6q-yapp4-crux.dts b/arch/arm/boot/dts/imx6q-yapp4-crux.dts
+index 15f4824a5142a..bddf3822ebf73 100644
+--- a/arch/arm/boot/dts/imx6q-yapp4-crux.dts
++++ b/arch/arm/boot/dts/imx6q-yapp4-crux.dts
+@@ -33,6 +33,10 @@
+ 	status = "okay";
+ };
+ 
++&reg_pu {
++	regulator-always-on;
++};
++
+ &reg_usb_h1_vbus {
+ 	status = "okay";
+ };
+diff --git a/arch/arm/boot/dts/imx6qdl-gw5910.dtsi b/arch/arm/boot/dts/imx6qdl-gw5910.dtsi
+index 68e5ab2e27e22..6bb4855d13ce5 100644
+--- a/arch/arm/boot/dts/imx6qdl-gw5910.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-gw5910.dtsi
+@@ -29,7 +29,7 @@
+ 
+ 		user-pb {
+ 			label = "user_pb";
+-			gpios = <&gsc_gpio 0 GPIO_ACTIVE_LOW>;
++			gpios = <&gsc_gpio 2 GPIO_ACTIVE_LOW>;
+ 			linux,code = <BTN_0>;
+ 		};
+ 
+diff --git a/arch/arm/boot/dts/imx6qdl-gw5913.dtsi b/arch/arm/boot/dts/imx6qdl-gw5913.dtsi
+index 8e23cec7149e5..696427b487f01 100644
+--- a/arch/arm/boot/dts/imx6qdl-gw5913.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-gw5913.dtsi
+@@ -26,7 +26,7 @@
+ 
+ 		user-pb {
+ 			label = "user_pb";
+-			gpios = <&gsc_gpio 0 GPIO_ACTIVE_LOW>;
++			gpios = <&gsc_gpio 2 GPIO_ACTIVE_LOW>;
+ 			linux,code = <BTN_0>;
+ 		};
+ 
+diff --git a/arch/arm/boot/dts/imx6qp-yapp4-crux-plus.dts b/arch/arm/boot/dts/imx6qp-yapp4-crux-plus.dts
+index cea165f2161a3..afaf4a6759d4b 100644
+--- a/arch/arm/boot/dts/imx6qp-yapp4-crux-plus.dts
++++ b/arch/arm/boot/dts/imx6qp-yapp4-crux-plus.dts
+@@ -33,6 +33,10 @@
+ 	status = "okay";
+ };
+ 
++&reg_pu {
++	regulator-always-on;
++};
++
+ &reg_usb_h1_vbus {
+ 	status = "okay";
+ };
+diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi
+index fbaa0ce464271..8f1bb78fc1e48 100644
+--- a/arch/arm/boot/dts/ste-href.dtsi
++++ b/arch/arm/boot/dts/ste-href.dtsi
+@@ -24,6 +24,14 @@
+ 			polling-delay = <0>;
+ 			polling-delay-passive = <0>;
+ 			thermal-sensors = <&bat_therm>;
++
++			trips {
++				battery-crit-hi {
++					temperature = <70000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
+ 		};
+ 	};
+ 
+diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
+index 1c9094f248939..e2f0cdacba7d1 100644
+--- a/arch/arm/boot/dts/ste-snowball.dts
++++ b/arch/arm/boot/dts/ste-snowball.dts
+@@ -28,6 +28,14 @@
+ 			polling-delay = <0>;
+ 			polling-delay-passive = <0>;
+ 			thermal-sensors = <&bat_therm>;
++
++			trips {
++				battery-crit-hi {
++					temperature = <70000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
+ 		};
+ 	};
+ 
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-codina-tmo.dts b/arch/arm/boot/dts/ste-ux500-samsung-codina-tmo.dts
+index d6940e0afa863..27a3ab7e25e13 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-codina-tmo.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-codina-tmo.dts
+@@ -44,6 +44,14 @@
+ 			polling-delay = <0>;
+ 			polling-delay-passive = <0>;
+ 			thermal-sensors = <&bat_therm>;
++
++			trips {
++				battery-crit-hi {
++					temperature = <70000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
+ 		};
+ 	};
+ 
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
+index 5f41256d7f4b4..b88f0c07873dd 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-codina.dts
+@@ -57,6 +57,14 @@
+ 			polling-delay = <0>;
+ 			polling-delay-passive = <0>;
+ 			thermal-sensors = <&bat_therm>;
++
++			trips {
++				battery-crit-hi {
++					temperature = <70000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
+ 		};
+ 	};
+ 
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts b/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
+index 806da3fc33cd7..7231bc7452000 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-gavini.dts
+@@ -30,6 +30,14 @@
+ 			polling-delay = <0>;
+ 			polling-delay-passive = <0>;
+ 			thermal-sensors = <&bat_therm>;
++
++			trips {
++				battery-crit-hi {
++					temperature = <70000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
+ 		};
+ 	};
+ 
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-golden.dts b/arch/arm/boot/dts/ste-ux500-samsung-golden.dts
+index b0dce91aff4be..9604695edf530 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-golden.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-golden.dts
+@@ -35,6 +35,14 @@
+ 			polling-delay = <0>;
+ 			polling-delay-passive = <0>;
+ 			thermal-sensors = <&bat_therm>;
++
++			trips {
++				battery-crit-hi {
++					temperature = <70000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
+ 		};
+ 	};
+ 
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
+index ed5c79c3d04b0..69387e8754a95 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-janice.dts
+@@ -30,6 +30,14 @@
+ 			polling-delay = <0>;
+ 			polling-delay-passive = <0>;
+ 			thermal-sensors = <&bat_therm>;
++
++			trips {
++				battery-crit-hi {
++					temperature = <70000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
+ 		};
+ 	};
+ 
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts b/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts
+index c57676faf181b..167846df31045 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-kyle.dts
+@@ -34,6 +34,14 @@
+ 			polling-delay = <0>;
+ 			polling-delay-passive = <0>;
+ 			thermal-sensors = <&bat_therm>;
++
++			trips {
++				battery-crit-hi {
++					temperature = <70000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
+ 		};
+ 	};
+ 
+diff --git a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts
+index 81b341a5ae451..93e5f5ed888d1 100644
+--- a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts
++++ b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts
+@@ -30,6 +30,14 @@
+ 			polling-delay = <0>;
+ 			polling-delay-passive = <0>;
+ 			thermal-sensors = <&bat_therm>;
++
++			trips {
++				battery-crit-hi {
++					temperature = <70000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
+ 		};
+ 	};
+ 
+diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
+index 2f27619d8abd5..8b4d280b1e7e7 100644
+--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
++++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
+@@ -751,12 +751,26 @@
+ 			polling-delay = <1000>;
+ 			polling-delay-passive = <100>;
+ 			thermal-sensors = <&scpi_sensors0 0>;
++			trips {
++				pmic_crit0: trip0 {
++					temperature = <90000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
+ 		};
+ 
+ 		soc {
+ 			polling-delay = <1000>;
+ 			polling-delay-passive = <100>;
+ 			thermal-sensors = <&scpi_sensors0 3>;
++			trips {
++				soc_crit0: trip0 {
++					temperature = <80000>;
++					hysteresis = <2000>;
++					type = "critical";
++				};
++			};
+ 		};
+ 
+ 		big_cluster_thermal_zone: big-cluster {
+diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+index 421d879013d7f..260d045dbd9a8 100644
+--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+@@ -779,6 +779,9 @@
+ 			little-endian;
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
++			clock-frequency = <2500000>;
++			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
++					    QORIQ_CLK_PLL_DIV(1)>;
+ 			status = "disabled";
+ 		};
+ 
+@@ -788,6 +791,9 @@
+ 			little-endian;
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
++			clock-frequency = <2500000>;
++			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
++					    QORIQ_CLK_PLL_DIV(1)>;
+ 			status = "disabled";
+ 		};
+ 
+diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
+index d76f1c42f3fa5..7bb33933c2cb2 100644
+--- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
+@@ -533,6 +533,9 @@
+ 			little-endian;
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
++			clock-frequency = <2500000>;
++			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
++					    QORIQ_CLK_PLL_DIV(2)>;
+ 			status = "disabled";
+ 		};
+ 
+@@ -542,6 +545,9 @@
+ 			little-endian;
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
++			clock-frequency = <2500000>;
++			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
++					    QORIQ_CLK_PLL_DIV(2)>;
+ 			status = "disabled";
+ 		};
+ 
+diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+index 6680fb2a6dc92..8c76d86cb7566 100644
+--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+@@ -1385,6 +1385,9 @@
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+ 			little-endian;
++			clock-frequency = <2500000>;
++			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
++					    QORIQ_CLK_PLL_DIV(2)>;
+ 			status = "disabled";
+ 		};
+ 
+@@ -1395,6 +1398,9 @@
+ 			little-endian;
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
++			clock-frequency = <2500000>;
++			clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
++					    QORIQ_CLK_PLL_DIV(2)>;
+ 			status = "disabled";
+ 		};
+ 
+diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
+index 82a1c44883786..10370d1a6c6de 100644
+--- a/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
+@@ -38,9 +38,9 @@ conn_subsys: bus@5b000000 {
+ 		interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
+ 		reg = <0x5b010000 0x10000>;
+ 		clocks = <&sdhc0_lpcg IMX_LPCG_CLK_4>,
+-			 <&sdhc0_lpcg IMX_LPCG_CLK_5>,
+-			 <&sdhc0_lpcg IMX_LPCG_CLK_0>;
+-		clock-names = "ipg", "per", "ahb";
++			 <&sdhc0_lpcg IMX_LPCG_CLK_0>,
++			 <&sdhc0_lpcg IMX_LPCG_CLK_5>;
++		clock-names = "ipg", "ahb", "per";
+ 		power-domains = <&pd IMX_SC_R_SDHC_0>;
+ 		status = "disabled";
+ 	};
+@@ -49,9 +49,9 @@ conn_subsys: bus@5b000000 {
+ 		interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
+ 		reg = <0x5b020000 0x10000>;
+ 		clocks = <&sdhc1_lpcg IMX_LPCG_CLK_4>,
+-			 <&sdhc1_lpcg IMX_LPCG_CLK_5>,
+-			 <&sdhc1_lpcg IMX_LPCG_CLK_0>;
+-		clock-names = "ipg", "per", "ahb";
++			 <&sdhc1_lpcg IMX_LPCG_CLK_0>,
++			 <&sdhc1_lpcg IMX_LPCG_CLK_5>;
++		clock-names = "ipg", "ahb", "per";
+ 		power-domains = <&pd IMX_SC_R_SDHC_1>;
+ 		fsl,tuning-start-tap = <20>;
+ 		fsl,tuning-step = <2>;
+@@ -62,9 +62,9 @@ conn_subsys: bus@5b000000 {
+ 		interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
+ 		reg = <0x5b030000 0x10000>;
+ 		clocks = <&sdhc2_lpcg IMX_LPCG_CLK_4>,
+-			 <&sdhc2_lpcg IMX_LPCG_CLK_5>,
+-			 <&sdhc2_lpcg IMX_LPCG_CLK_0>;
+-		clock-names = "ipg", "per", "ahb";
++			 <&sdhc2_lpcg IMX_LPCG_CLK_0>,
++			 <&sdhc2_lpcg IMX_LPCG_CLK_5>;
++		clock-names = "ipg", "ahb", "per";
+ 		power-domains = <&pd IMX_SC_R_SDHC_2>;
+ 		status = "disabled";
+ 	};
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts b/arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts
+index 32f6f2f50c10c..43e89859c0445 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-mx8menlo.dts
+@@ -250,21 +250,21 @@
+ 		/* SODIMM 96 */
+ 		MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4			0x1c4
+ 		/* CPLD_D[7] */
+-		MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5			0x1c4
++		MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5			0x184
+ 		/* CPLD_D[6] */
+-		MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0			0x1c4
++		MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0			0x184
+ 		/* CPLD_D[5] */
+-		MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11			0x1c4
++		MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11			0x184
+ 		/* CPLD_D[4] */
+-		MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12			0x1c4
++		MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12			0x184
+ 		/* CPLD_D[3] */
+-		MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13			0x1c4
++		MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13			0x184
+ 		/* CPLD_D[2] */
+-		MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14			0x1c4
++		MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14			0x184
+ 		/* CPLD_D[1] */
+-		MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15			0x1c4
++		MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15			0x184
+ 		/* CPLD_D[0] */
+-		MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16			0x1c4
++		MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16			0x184
+ 		/* KBD_intK */
+ 		MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27			0x1c4
+ 		/* DISP_reset */
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+index afb90f59c83c5..dabd94dc30c4b 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+@@ -276,6 +276,7 @@
+ 		assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>;
+ 		assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>;
+ 		clock-names = "main_clk";
++		power-domains = <&pgc_otg1>;
+ 	};
+ 
+ 	usbphynop2: usbphynop2 {
+@@ -285,6 +286,7 @@
+ 		assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>;
+ 		assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>;
+ 		clock-names = "main_clk";
++		power-domains = <&pgc_otg2>;
+ 	};
+ 
+ 	soc: soc@0 {
+@@ -674,13 +676,11 @@
+ 					pgc_otg1: power-domain@2 {
+ 						#power-domain-cells = <0>;
+ 						reg = <IMX8MM_POWER_DOMAIN_OTG1>;
+-						power-domains = <&pgc_hsiomix>;
+ 					};
+ 
+ 					pgc_otg2: power-domain@3 {
+ 						#power-domain-cells = <0>;
+ 						reg = <IMX8MM_POWER_DOMAIN_OTG2>;
+-						power-domains = <&pgc_hsiomix>;
+ 					};
+ 
+ 					pgc_gpumix: power-domain@4 {
+@@ -1186,7 +1186,7 @@
+ 				assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>;
+ 				phys = <&usbphynop1>;
+ 				fsl,usbmisc = <&usbmisc1 0>;
+-				power-domains = <&pgc_otg1>;
++				power-domains = <&pgc_hsiomix>;
+ 				status = "disabled";
+ 			};
+ 
+@@ -1206,7 +1206,7 @@
+ 				assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>;
+ 				phys = <&usbphynop2>;
+ 				fsl,usbmisc = <&usbmisc2 0>;
+-				power-domains = <&pgc_otg2>;
++				power-domains = <&pgc_hsiomix>;
+ 				status = "disabled";
+ 			};
+ 
+diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+index cb2836bfbd95c..ad0b99adf6911 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
+@@ -662,7 +662,6 @@
+ 					pgc_otg1: power-domain@1 {
+ 						#power-domain-cells = <0>;
+ 						reg = <IMX8MN_POWER_DOMAIN_OTG1>;
+-						power-domains = <&pgc_hsiomix>;
+ 					};
+ 
+ 					pgc_gpumix: power-domain@2 {
+@@ -1076,7 +1075,7 @@
+ 				assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>;
+ 				phys = <&usbphynop1>;
+ 				fsl,usbmisc = <&usbmisc1 0>;
+-				power-domains = <&pgc_otg1>;
++				power-domains = <&pgc_hsiomix>;
+ 				status = "disabled";
+ 			};
+ 
+@@ -1175,5 +1174,6 @@
+ 		assigned-clocks = <&clk IMX8MN_CLK_USB_PHY_REF>;
+ 		assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_100M>;
+ 		clock-names = "main_clk";
++		power-domains = <&pgc_otg1>;
+ 	};
+ };
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
+index 1c74c6a194491..360be51a35274 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
+@@ -339,16 +339,6 @@
+ 			  "SODIMM_82",
+ 			  "SODIMM_70",
+ 			  "SODIMM_72";
+-
+-	ctrl-sleep-moci-hog {
+-		gpio-hog;
+-		/* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+-		gpios = <29 GPIO_ACTIVE_HIGH>;
+-		line-name = "CTRL_SLEEP_MOCI#";
+-		output-high;
+-		pinctrl-names = "default";
+-		pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+-	};
+ };
+ 
+ &gpio3 {
+@@ -417,6 +407,16 @@
+ 			  "SODIMM_256",
+ 			  "SODIMM_48",
+ 			  "SODIMM_44";
++
++	ctrl-sleep-moci-hog {
++		gpio-hog;
++		/* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
++		gpios = <29 GPIO_ACTIVE_HIGH>;
++		line-name = "CTRL_SLEEP_MOCI#";
++		output-high;
++		pinctrl-names = "default";
++		pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
++	};
+ };
+ 
+ /* On-module I2C */
+diff --git a/arch/arm64/boot/dts/freescale/imx93.dtsi b/arch/arm64/boot/dts/freescale/imx93.dtsi
+index f83a07c7c9b1e..6981d3b0e2740 100644
+--- a/arch/arm64/boot/dts/freescale/imx93.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx93.dtsi
+@@ -295,7 +295,10 @@
+ 			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+ 			interrupt-controller;
+ 			#interrupt-cells = <2>;
+-			gpio-ranges = <&iomuxc 0 32 32>;
++			clocks = <&clk IMX93_CLK_GPIO2_GATE>,
++				 <&clk IMX93_CLK_GPIO2_GATE>;
++			clock-names = "gpio", "port";
++			gpio-ranges = <&iomuxc 0 4 30>;
+ 		};
+ 
+ 		gpio3: gpio@43820080 {
+@@ -306,7 +309,11 @@
+ 			interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+ 			interrupt-controller;
+ 			#interrupt-cells = <2>;
+-			gpio-ranges = <&iomuxc 0 64 32>;
++			clocks = <&clk IMX93_CLK_GPIO3_GATE>,
++				 <&clk IMX93_CLK_GPIO3_GATE>;
++			clock-names = "gpio", "port";
++			gpio-ranges = <&iomuxc 0 84 8>, <&iomuxc 8 66 18>,
++				      <&iomuxc 26 34 2>, <&iomuxc 28 0 4>;
+ 		};
+ 
+ 		gpio4: gpio@43830080 {
+@@ -317,7 +324,10 @@
+ 			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+ 			interrupt-controller;
+ 			#interrupt-cells = <2>;
+-			gpio-ranges = <&iomuxc 0 96 32>;
++			clocks = <&clk IMX93_CLK_GPIO4_GATE>,
++				 <&clk IMX93_CLK_GPIO4_GATE>;
++			clock-names = "gpio", "port";
++			gpio-ranges = <&iomuxc 0 38 28>, <&iomuxc 28 36 2>;
+ 		};
+ 
+ 		gpio1: gpio@47400080 {
+@@ -328,7 +338,10 @@
+ 			interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ 			interrupt-controller;
+ 			#interrupt-cells = <2>;
+-			gpio-ranges = <&iomuxc 0 0 32>;
++			clocks = <&clk IMX93_CLK_GPIO1_GATE>,
++				 <&clk IMX93_CLK_GPIO1_GATE>;
++			clock-names = "gpio", "port";
++			gpio-ranges = <&iomuxc 0 92 16>;
+ 		};
+ 	};
+ };
+diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
+index c75ca36b4a491..deb2897f39d63 100644
+--- a/arch/arm64/kernel/entry-common.c
++++ b/arch/arm64/kernel/entry-common.c
+@@ -329,7 +329,8 @@ static void cortex_a76_erratum_1463225_svc_handler(void)
+ 	__this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 0);
+ }
+ 
+-static bool cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
++static __always_inline bool
++cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
+ {
+ 	if (!__this_cpu_read(__in_cortex_a76_erratum_1463225_wa))
+ 		return false;
+diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c
+index b7557b25ed568..791d3de767713 100644
+--- a/arch/arm64/kvm/hyp/exception.c
++++ b/arch/arm64/kvm/hyp/exception.c
+@@ -13,6 +13,7 @@
+ #include <hyp/adjust_pc.h>
+ #include <linux/kvm_host.h>
+ #include <asm/kvm_emulate.h>
++#include <asm/kvm_mmu.h>
+ 
+ #if !defined (__KVM_NVHE_HYPERVISOR__) && !defined (__KVM_VHE_HYPERVISOR__)
+ #error Hypervisor code only!
+@@ -115,7 +116,7 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
+ 	new |= (old & PSR_C_BIT);
+ 	new |= (old & PSR_V_BIT);
+ 
+-	if (kvm_has_mte(vcpu->kvm))
++	if (kvm_has_mte(kern_hyp_va(vcpu->kvm)))
+ 		new |= PSR_TCO_BIT;
+ 
+ 	new |= (old & PSR_DIT_BIT);
+diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
+index 6cbbb6c02f663..3330d1b76bdd2 100644
+--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
++++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
+@@ -87,6 +87,17 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
+ 
+ 	vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2);
+ 	write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
++
++	if (cpus_have_final_cap(ARM64_SME)) {
++		sysreg_clear_set_s(SYS_HFGRTR_EL2,
++				   HFGxTR_EL2_nSMPRI_EL1_MASK |
++				   HFGxTR_EL2_nTPIDR2_EL0_MASK,
++				   0);
++		sysreg_clear_set_s(SYS_HFGWTR_EL2,
++				   HFGxTR_EL2_nSMPRI_EL1_MASK |
++				   HFGxTR_EL2_nTPIDR2_EL0_MASK,
++				   0);
++	}
+ }
+ 
+ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
+@@ -96,6 +107,15 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
+ 	write_sysreg(0, hstr_el2);
+ 	if (kvm_arm_support_pmu_v3())
+ 		write_sysreg(0, pmuserenr_el0);
++
++	if (cpus_have_final_cap(ARM64_SME)) {
++		sysreg_clear_set_s(SYS_HFGRTR_EL2, 0,
++				   HFGxTR_EL2_nSMPRI_EL1_MASK |
++				   HFGxTR_EL2_nTPIDR2_EL0_MASK);
++		sysreg_clear_set_s(SYS_HFGWTR_EL2, 0,
++				   HFGxTR_EL2_nSMPRI_EL1_MASK |
++				   HFGxTR_EL2_nTPIDR2_EL0_MASK);
++	}
+ }
+ 
+ static inline void ___activate_traps(struct kvm_vcpu *vcpu)
+diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
+index 9f63857020618..c5f6fd8a94405 100644
+--- a/arch/arm64/kvm/hyp/nvhe/switch.c
++++ b/arch/arm64/kvm/hyp/nvhe/switch.c
+@@ -55,18 +55,6 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
+ 	write_sysreg(val, cptr_el2);
+ 	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2);
+ 
+-	if (cpus_have_final_cap(ARM64_SME)) {
+-		val = read_sysreg_s(SYS_HFGRTR_EL2);
+-		val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK |
+-			 HFGxTR_EL2_nSMPRI_EL1_MASK);
+-		write_sysreg_s(val, SYS_HFGRTR_EL2);
+-
+-		val = read_sysreg_s(SYS_HFGWTR_EL2);
+-		val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK |
+-			 HFGxTR_EL2_nSMPRI_EL1_MASK);
+-		write_sysreg_s(val, SYS_HFGWTR_EL2);
+-	}
+-
+ 	if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
+ 		struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
+ 
+@@ -110,20 +98,6 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
+ 
+ 	write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2);
+ 
+-	if (cpus_have_final_cap(ARM64_SME)) {
+-		u64 val;
+-
+-		val = read_sysreg_s(SYS_HFGRTR_EL2);
+-		val |= HFGxTR_EL2_nTPIDR2_EL0_MASK |
+-			HFGxTR_EL2_nSMPRI_EL1_MASK;
+-		write_sysreg_s(val, SYS_HFGRTR_EL2);
+-
+-		val = read_sysreg_s(SYS_HFGWTR_EL2);
+-		val |= HFGxTR_EL2_nTPIDR2_EL0_MASK |
+-			HFGxTR_EL2_nSMPRI_EL1_MASK;
+-		write_sysreg_s(val, SYS_HFGWTR_EL2);
+-	}
+-
+ 	cptr = CPTR_EL2_DEFAULT;
+ 	if (vcpu_has_sve(vcpu) && (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED))
+ 		cptr |= CPTR_EL2_TZ;
+diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
+index 7acb87eaa0925..1a97391fedd29 100644
+--- a/arch/arm64/kvm/hyp/vhe/switch.c
++++ b/arch/arm64/kvm/hyp/vhe/switch.c
+@@ -63,10 +63,6 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
+ 		__activate_traps_fpsimd32(vcpu);
+ 	}
+ 
+-	if (cpus_have_final_cap(ARM64_SME))
+-		write_sysreg(read_sysreg(sctlr_el2) & ~SCTLR_ELx_ENTP2,
+-			     sctlr_el2);
+-
+ 	write_sysreg(val, cpacr_el1);
+ 
+ 	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1);
+@@ -88,10 +84,6 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
+ 	 */
+ 	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
+ 
+-	if (cpus_have_final_cap(ARM64_SME))
+-		write_sysreg(read_sysreg(sctlr_el2) | SCTLR_ELx_ENTP2,
+-			     sctlr_el2);
+-
+ 	write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1);
+ 
+ 	if (!arm64_kernel_unmapped_at_el0())
+diff --git a/arch/parisc/include/asm/hardware.h b/arch/parisc/include/asm/hardware.h
+index 9d3d7737c58b1..a005ebc547793 100644
+--- a/arch/parisc/include/asm/hardware.h
++++ b/arch/parisc/include/asm/hardware.h
+@@ -10,12 +10,12 @@
+ #define SVERSION_ANY_ID		PA_SVERSION_ANY_ID
+ 
+ struct hp_hardware {
+-	unsigned short	hw_type:5;	/* HPHW_xxx */
+-	unsigned short	hversion;
+-	unsigned long	sversion:28;
+-	unsigned short	opt;
+-	const char	name[80];	/* The hardware description */
+-};
++	unsigned int	hw_type:8;	/* HPHW_xxx */
++	unsigned int	hversion:12;
++	unsigned int	sversion:12;
++	unsigned char	opt;
++	unsigned char	name[59];	/* The hardware description */
++} __packed;
+ 
+ struct parisc_device;
+ 
+diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
+index d126e78e101ae..e7ee0c0c91d35 100644
+--- a/arch/parisc/kernel/drivers.c
++++ b/arch/parisc/kernel/drivers.c
+@@ -882,15 +882,13 @@ void __init walk_central_bus(void)
+ 			&root);
+ }
+ 
+-static void print_parisc_device(struct parisc_device *dev)
++static __init void print_parisc_device(struct parisc_device *dev)
+ {
+-	char hw_path[64];
+-	static int count;
++	static int count __initdata;
+ 
+-	print_pa_hwpath(dev, hw_path);
+-	pr_info("%d. %s at %pap [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
+-		++count, dev->name, &(dev->hpa.start), hw_path, dev->id.hw_type,
+-		dev->id.hversion_rev, dev->id.hversion, dev->id.sversion);
++	pr_info("%d. %s at %pap { type:%d, hv:%#x, sv:%#x, rev:%#x }",
++		++count, dev->name, &(dev->hpa.start), dev->id.hw_type,
++		dev->id.hversion, dev->id.sversion, dev->id.hversion_rev);
+ 
+ 	if (dev->num_addrs) {
+ 		int k;
+@@ -1079,7 +1077,7 @@ static __init int qemu_print_iodc_data(struct device *lin_dev, void *data)
+ 
+ 
+ 
+-static int print_one_device(struct device * dev, void * data)
++static __init int print_one_device(struct device * dev, void * data)
+ {
+ 	struct parisc_device * pdev = to_parisc_device(dev);
+ 
+diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c
+index 928dcf7a20d98..b8998cf0508a6 100644
+--- a/arch/x86/coco/tdx/tdx.c
++++ b/arch/x86/coco/tdx/tdx.c
+@@ -34,6 +34,8 @@
+ #define VE_GET_PORT_NUM(e)	((e) >> 16)
+ #define VE_IS_IO_STRING(e)	((e) & BIT(4))
+ 
++#define ATTR_SEPT_VE_DISABLE	BIT(28)
++
+ /*
+  * Wrapper for standard use of __tdx_hypercall with no output aside from
+  * return code.
+@@ -98,10 +100,11 @@ static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9,
+ 		panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);
+ }
+ 
+-static u64 get_cc_mask(void)
++static void tdx_parse_tdinfo(u64 *cc_mask)
+ {
+ 	struct tdx_module_output out;
+ 	unsigned int gpa_width;
++	u64 td_attr;
+ 
+ 	/*
+ 	 * TDINFO TDX module call is used to get the TD execution environment
+@@ -109,19 +112,27 @@ static u64 get_cc_mask(void)
+ 	 * information, etc. More details about the ABI can be found in TDX
+ 	 * Guest-Host-Communication Interface (GHCI), section 2.4.2 TDCALL
+ 	 * [TDG.VP.INFO].
++	 */
++	tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out);
++
++	/*
++	 * The highest bit of a guest physical address is the "sharing" bit.
++	 * Set it for shared pages and clear it for private pages.
+ 	 *
+ 	 * The GPA width that comes out of this call is critical. TDX guests
+ 	 * can not meaningfully run without it.
+ 	 */
+-	tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out);
+-
+ 	gpa_width = out.rcx & GENMASK(5, 0);
++	*cc_mask = BIT_ULL(gpa_width - 1);
+ 
+ 	/*
+-	 * The highest bit of a guest physical address is the "sharing" bit.
+-	 * Set it for shared pages and clear it for private pages.
++	 * The kernel can not handle #VE's when accessing normal kernel
++	 * memory.  Ensure that no #VE will be delivered for accesses to
++	 * TD-private memory.  Only VMM-shared memory (MMIO) will #VE.
+ 	 */
+-	return BIT_ULL(gpa_width - 1);
++	td_attr = out.rdx;
++	if (!(td_attr & ATTR_SEPT_VE_DISABLE))
++		panic("TD misconfiguration: SEPT_VE_DISABLE attibute must be set.\n");
+ }
+ 
+ /*
+@@ -758,7 +769,7 @@ void __init tdx_early_init(void)
+ 	setup_force_cpu_cap(X86_FEATURE_TDX_GUEST);
+ 
+ 	cc_set_vendor(CC_VENDOR_INTEL);
+-	cc_mask = get_cc_mask();
++	tdx_parse_tdinfo(&cc_mask);
+ 	cc_set_mask(cc_mask);
+ 
+ 	/*
+diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
+index c20d8cd47c484..3bfd0c5e01593 100644
+--- a/arch/x86/events/intel/core.c
++++ b/arch/x86/events/intel/core.c
+@@ -4891,6 +4891,7 @@ static const struct x86_cpu_desc isolation_ucodes[] = {
+ 	INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X,		 5, 0x00000000),
+ 	INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X,		 6, 0x00000000),
+ 	INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X,		 7, 0x00000000),
++	INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X,		11, 0x00000000),
+ 	INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_L,		 3, 0x0000007c),
+ 	INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE,		 3, 0x0000007c),
+ 	INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE,		 9, 0x0000004e),
+diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
+index ac973c6f82ad6..d1b9d2ad03476 100644
+--- a/arch/x86/events/intel/ds.c
++++ b/arch/x86/events/intel/ds.c
+@@ -982,8 +982,13 @@ struct event_constraint intel_icl_pebs_event_constraints[] = {
+ 	INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL),	/* SLOTS */
+ 
+ 	INTEL_PLD_CONSTRAINT(0x1cd, 0xff),			/* MEM_TRANS_RETIRED.LOAD_LATENCY */
+-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x1d0, 0xf),	/* MEM_INST_RETIRED.LOAD */
+-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x2d0, 0xf),	/* MEM_INST_RETIRED.STORE */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf),	/* MEM_INST_RETIRED.STLB_MISS_LOADS */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf),	/* MEM_INST_RETIRED.STLB_MISS_STORES */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf),	/* MEM_INST_RETIRED.LOCK_LOADS */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf),	/* MEM_INST_RETIRED.SPLIT_LOADS */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf),	/* MEM_INST_RETIRED.SPLIT_STORES */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf),	/* MEM_INST_RETIRED.ALL_LOADS */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf),	/* MEM_INST_RETIRED.ALL_STORES */
+ 
+ 	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf), /* MEM_LOAD_*_RETIRED.* */
+ 
+@@ -1004,8 +1009,13 @@ struct event_constraint intel_spr_pebs_event_constraints[] = {
+ 	INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xfe),
+ 	INTEL_PLD_CONSTRAINT(0x1cd, 0xfe),
+ 	INTEL_PSD_CONSTRAINT(0x2cd, 0x1),
+-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x1d0, 0xf),
+-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x2d0, 0xf),
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf),	/* MEM_INST_RETIRED.STLB_MISS_LOADS */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf),	/* MEM_INST_RETIRED.STLB_MISS_STORES */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf),	/* MEM_INST_RETIRED.LOCK_LOADS */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf),	/* MEM_INST_RETIRED.SPLIT_LOADS */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf),	/* MEM_INST_RETIRED.SPLIT_STORES */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf),	/* MEM_INST_RETIRED.ALL_LOADS */
++	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf),	/* MEM_INST_RETIRED.ALL_STORES */
+ 
+ 	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf),
+ 
+diff --git a/arch/x86/include/asm/syscall_wrapper.h b/arch/x86/include/asm/syscall_wrapper.h
+index 59358d1bf8800..fd2669b1cb2d9 100644
+--- a/arch/x86/include/asm/syscall_wrapper.h
++++ b/arch/x86/include/asm/syscall_wrapper.h
+@@ -6,7 +6,7 @@
+ #ifndef _ASM_X86_SYSCALL_WRAPPER_H
+ #define _ASM_X86_SYSCALL_WRAPPER_H
+ 
+-struct pt_regs;
++#include <asm/ptrace.h>
+ 
+ extern long __x64_sys_ni_syscall(const struct pt_regs *regs);
+ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs);
+diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
+index 2796dde06302a..28ab0b9484d33 100644
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -1117,11 +1117,13 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
+ 			entry->eax = max(entry->eax, 0x80000021);
+ 		break;
+ 	case 0x80000001:
++		entry->ebx &= ~GENMASK(27, 16);
+ 		cpuid_entry_override(entry, CPUID_8000_0001_EDX);
+ 		cpuid_entry_override(entry, CPUID_8000_0001_ECX);
+ 		break;
+ 	case 0x80000006:
+-		/* L2 cache and TLB: pass through host info. */
++		/* Drop reserved bits, pass host L2 cache and TLB info. */
++		entry->edx &= ~GENMASK(17, 16);
+ 		break;
+ 	case 0x80000007: /* Advanced power management */
+ 		/* invariant TSC is CPUID.80000007H:EDX[8] */
+@@ -1151,6 +1153,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
+ 			g_phys_as = phys_as;
+ 
+ 		entry->eax = g_phys_as | (virt_as << 8);
++		entry->ecx &= ~(GENMASK(31, 16) | GENMASK(11, 8));
+ 		entry->edx = 0;
+ 		cpuid_entry_override(entry, CPUID_8000_0008_EBX);
+ 		break;
+@@ -1170,6 +1173,9 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
+ 		entry->ecx = entry->edx = 0;
+ 		break;
+ 	case 0x8000001a:
++		entry->eax &= GENMASK(2, 0);
++		entry->ebx = entry->ecx = entry->edx = 0;
++		break;
+ 	case 0x8000001e:
+ 		break;
+ 	case 0x8000001F:
+@@ -1177,7 +1183,8 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
+ 			entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
+ 		} else {
+ 			cpuid_entry_override(entry, CPUID_8000_001F_EAX);
+-
++			/* Clear NumVMPL since KVM does not support VMPL.  */
++			entry->ebx &= ~GENMASK(31, 12);
+ 			/*
+ 			 * Enumerate '0' for "PA bits reduction", the adjusted
+ 			 * MAXPHYADDR is enumerated directly (see 0x80000008).
+diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
+index 883e380e5801d..fdb20b3c38f5f 100644
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -791,8 +791,7 @@ static int linearize(struct x86_emulate_ctxt *ctxt,
+ 			   ctxt->mode, linear);
+ }
+ 
+-static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst,
+-			     enum x86emul_mode mode)
++static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst)
+ {
+ 	ulong linear;
+ 	int rc;
+@@ -802,41 +801,71 @@ static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst,
+ 
+ 	if (ctxt->op_bytes != sizeof(unsigned long))
+ 		addr.ea = dst & ((1UL << (ctxt->op_bytes << 3)) - 1);
+-	rc = __linearize(ctxt, addr, &max_size, 1, false, true, mode, &linear);
++	rc = __linearize(ctxt, addr, &max_size, 1, false, true, ctxt->mode, &linear);
+ 	if (rc == X86EMUL_CONTINUE)
+ 		ctxt->_eip = addr.ea;
+ 	return rc;
+ }
+ 
++static inline int emulator_recalc_and_set_mode(struct x86_emulate_ctxt *ctxt)
++{
++	u64 efer;
++	struct desc_struct cs;
++	u16 selector;
++	u32 base3;
++
++	ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
++
++	if (!(ctxt->ops->get_cr(ctxt, 0) & X86_CR0_PE)) {
++		/* Real mode. cpu must not have long mode active */
++		if (efer & EFER_LMA)
++			return X86EMUL_UNHANDLEABLE;
++		ctxt->mode = X86EMUL_MODE_REAL;
++		return X86EMUL_CONTINUE;
++	}
++
++	if (ctxt->eflags & X86_EFLAGS_VM) {
++		/* Protected/VM86 mode. cpu must not have long mode active */
++		if (efer & EFER_LMA)
++			return X86EMUL_UNHANDLEABLE;
++		ctxt->mode = X86EMUL_MODE_VM86;
++		return X86EMUL_CONTINUE;
++	}
++
++	if (!ctxt->ops->get_segment(ctxt, &selector, &cs, &base3, VCPU_SREG_CS))
++		return X86EMUL_UNHANDLEABLE;
++
++	if (efer & EFER_LMA) {
++		if (cs.l) {
++			/* Proper long mode */
++			ctxt->mode = X86EMUL_MODE_PROT64;
++		} else if (cs.d) {
++			/* 32 bit compatibility mode*/
++			ctxt->mode = X86EMUL_MODE_PROT32;
++		} else {
++			ctxt->mode = X86EMUL_MODE_PROT16;
++		}
++	} else {
++		/* Legacy 32 bit / 16 bit mode */
++		ctxt->mode = cs.d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
++	}
++
++	return X86EMUL_CONTINUE;
++}
++
+ static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst)
+ {
+-	return assign_eip(ctxt, dst, ctxt->mode);
++	return assign_eip(ctxt, dst);
+ }
+ 
+-static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst,
+-			  const struct desc_struct *cs_desc)
++static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst)
+ {
+-	enum x86emul_mode mode = ctxt->mode;
+-	int rc;
++	int rc = emulator_recalc_and_set_mode(ctxt);
+ 
+-#ifdef CONFIG_X86_64
+-	if (ctxt->mode >= X86EMUL_MODE_PROT16) {
+-		if (cs_desc->l) {
+-			u64 efer = 0;
++	if (rc != X86EMUL_CONTINUE)
++		return rc;
+ 
+-			ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
+-			if (efer & EFER_LMA)
+-				mode = X86EMUL_MODE_PROT64;
+-		} else
+-			mode = X86EMUL_MODE_PROT32; /* temporary value */
+-	}
+-#endif
+-	if (mode == X86EMUL_MODE_PROT16 || mode == X86EMUL_MODE_PROT32)
+-		mode = cs_desc->d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
+-	rc = assign_eip(ctxt, dst, mode);
+-	if (rc == X86EMUL_CONTINUE)
+-		ctxt->mode = mode;
+-	return rc;
++	return assign_eip(ctxt, dst);
+ }
+ 
+ static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
+@@ -2170,7 +2199,7 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
+ 	if (rc != X86EMUL_CONTINUE)
+ 		return rc;
+ 
+-	rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc);
++	rc = assign_eip_far(ctxt, ctxt->src.val);
+ 	/* Error handling is not implemented. */
+ 	if (rc != X86EMUL_CONTINUE)
+ 		return X86EMUL_UNHANDLEABLE;
+@@ -2248,7 +2277,7 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
+ 				       &new_desc);
+ 	if (rc != X86EMUL_CONTINUE)
+ 		return rc;
+-	rc = assign_eip_far(ctxt, eip, &new_desc);
++	rc = assign_eip_far(ctxt, eip);
+ 	/* Error handling is not implemented. */
+ 	if (rc != X86EMUL_CONTINUE)
+ 		return X86EMUL_UNHANDLEABLE;
+@@ -2430,7 +2459,7 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt,
+ 	ctxt->eflags =             GET_SMSTATE(u32, smstate, 0x7ff4) | X86_EFLAGS_FIXED;
+ 	ctxt->_eip =               GET_SMSTATE(u32, smstate, 0x7ff0);
+ 
+-	for (i = 0; i < NR_EMULATOR_GPRS; i++)
++	for (i = 0; i < 8; i++)
+ 		*reg_write(ctxt, i) = GET_SMSTATE(u32, smstate, 0x7fd0 + i * 4);
+ 
+ 	val = GET_SMSTATE(u32, smstate, 0x7fcc);
+@@ -2487,7 +2516,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt,
+ 	u16 selector;
+ 	int i, r;
+ 
+-	for (i = 0; i < NR_EMULATOR_GPRS; i++)
++	for (i = 0; i < 16; i++)
+ 		*reg_write(ctxt, i) = GET_SMSTATE(u64, smstate, 0x7ff8 - i * 8);
+ 
+ 	ctxt->_eip   = GET_SMSTATE(u64, smstate, 0x7f78);
+@@ -2631,7 +2660,7 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)
+ 	 * those side effects need to be explicitly handled for both success
+ 	 * and shutdown.
+ 	 */
+-	return X86EMUL_CONTINUE;
++	return emulator_recalc_and_set_mode(ctxt);
+ 
+ emulate_shutdown:
+ 	ctxt->ops->triple_fault(ctxt);
+@@ -2874,6 +2903,7 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt)
+ 	ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS);
+ 
+ 	ctxt->_eip = rdx;
++	ctxt->mode = usermode;
+ 	*reg_write(ctxt, VCPU_REGS_RSP) = rcx;
+ 
+ 	return X86EMUL_CONTINUE;
+@@ -3467,7 +3497,7 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt)
+ 	if (rc != X86EMUL_CONTINUE)
+ 		return rc;
+ 
+-	rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc);
++	rc = assign_eip_far(ctxt, ctxt->src.val);
+ 	if (rc != X86EMUL_CONTINUE)
+ 		goto fail;
+ 
+@@ -3609,11 +3639,25 @@ static int em_movbe(struct x86_emulate_ctxt *ctxt)
+ 
+ static int em_cr_write(struct x86_emulate_ctxt *ctxt)
+ {
+-	if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val))
++	int cr_num = ctxt->modrm_reg;
++	int r;
++
++	if (ctxt->ops->set_cr(ctxt, cr_num, ctxt->src.val))
+ 		return emulate_gp(ctxt, 0);
+ 
+ 	/* Disable writeback. */
+ 	ctxt->dst.type = OP_NONE;
++
++	if (cr_num == 0) {
++		/*
++		 * CR0 write might have updated CR0.PE and/or CR0.PG
++		 * which can affect the cpu's execution mode.
++		 */
++		r = emulator_recalc_and_set_mode(ctxt);
++		if (r != X86EMUL_CONTINUE)
++			return r;
++	}
++
+ 	return X86EMUL_CONTINUE;
+ }
+ 
+diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h
+index c5e5dfef69c7f..2bd599d61b9bf 100644
+--- a/arch/x86/kvm/vmx/capabilities.h
++++ b/arch/x86/kvm/vmx/capabilities.h
+@@ -24,8 +24,6 @@ extern int __read_mostly pt_mode;
+ #define PMU_CAP_FW_WRITES	(1ULL << 13)
+ #define PMU_CAP_LBR_FMT		0x3f
+ 
+-#define DEBUGCTLMSR_LBR_MASK		(DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI)
+-
+ struct nested_vmx_msrs {
+ 	/*
+ 	 * We only store the "true" versions of the VMX capability MSRs. We
+@@ -404,6 +402,7 @@ static inline bool vmx_pebs_supported(void)
+ static inline u64 vmx_get_perf_capabilities(void)
+ {
+ 	u64 perf_cap = PMU_CAP_FW_WRITES;
++	struct x86_pmu_lbr lbr;
+ 	u64 host_perf_cap = 0;
+ 
+ 	if (!enable_pmu)
+@@ -412,7 +411,8 @@ static inline u64 vmx_get_perf_capabilities(void)
+ 	if (boot_cpu_has(X86_FEATURE_PDCM))
+ 		rdmsrl(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);
+ 
+-	perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
++	if (x86_perf_get_lbr(&lbr) >= 0 && lbr.nr)
++		perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT;
+ 
+ 	if (vmx_pebs_supported()) {
+ 		perf_cap |= host_perf_cap & PERF_CAP_PEBS_MASK;
+@@ -423,19 +423,6 @@ static inline u64 vmx_get_perf_capabilities(void)
+ 	return perf_cap;
+ }
+ 
+-static inline u64 vmx_supported_debugctl(void)
+-{
+-	u64 debugctl = 0;
+-
+-	if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT))
+-		debugctl |= DEBUGCTLMSR_BUS_LOCK_DETECT;
+-
+-	if (vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT)
+-		debugctl |= DEBUGCTLMSR_LBR_MASK;
+-
+-	return debugctl;
+-}
+-
+ static inline bool cpu_has_notify_vmexit(void)
+ {
+ 	return vmcs_config.cpu_based_2nd_exec_ctrl &
+diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
+index 7f3581960eb5d..74de8c9e401b1 100644
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -2016,15 +2016,17 @@ static u64 nested_vmx_truncate_sysenter_addr(struct kvm_vcpu *vcpu,
+ 	return (unsigned long)data;
+ }
+ 
+-static u64 vcpu_supported_debugctl(struct kvm_vcpu *vcpu)
++static u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_initiated)
+ {
+-	u64 debugctl = vmx_supported_debugctl();
++	u64 debugctl = 0;
+ 
+-	if (!intel_pmu_lbr_is_enabled(vcpu))
+-		debugctl &= ~DEBUGCTLMSR_LBR_MASK;
++	if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT) &&
++	    (host_initiated || guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT)))
++		debugctl |= DEBUGCTLMSR_BUS_LOCK_DETECT;
+ 
+-	if (!guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT))
+-		debugctl &= ~DEBUGCTLMSR_BUS_LOCK_DETECT;
++	if ((vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT) &&
++	    (host_initiated || intel_pmu_lbr_is_enabled(vcpu)))
++		debugctl |= DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI;
+ 
+ 	return debugctl;
+ }
+@@ -2098,7 +2100,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ 		vmcs_writel(GUEST_SYSENTER_ESP, data);
+ 		break;
+ 	case MSR_IA32_DEBUGCTLMSR: {
+-		u64 invalid = data & ~vcpu_supported_debugctl(vcpu);
++		u64 invalid;
++
++		invalid = data & ~vmx_get_supported_debugctl(vcpu, msr_info->host_initiated);
+ 		if (invalid & (DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR)) {
+ 			if (report_ignored_msrs)
+ 				vcpu_unimpl(vcpu, "%s: BTF|LBR in IA32_DEBUGCTLMSR 0x%llx, nop\n",
+@@ -8277,6 +8281,11 @@ static __init int hardware_setup(void)
+ 	if (!cpu_has_virtual_nmis())
+ 		enable_vnmi = 0;
+ 
++#ifdef CONFIG_X86_SGX_KVM
++	if (!cpu_has_vmx_encls_vmexit())
++		enable_sgx = false;
++#endif
++
+ 	/*
+ 	 * set_apic_access_page_addr() is used to reload apic access
+ 	 * page upon invalidation.  No need to do anything if not
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 86c3b29f1abc0..05f4424eb0c52 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -2304,11 +2304,11 @@ static void kvm_write_system_time(struct kvm_vcpu *vcpu, gpa_t system_time,
+ 
+ 	/* we verify if the enable bit is set... */
+ 	if (system_time & 1) {
+-		kvm_gfn_to_pfn_cache_init(vcpu->kvm, &vcpu->arch.pv_time, vcpu,
+-					  KVM_HOST_USES_PFN, system_time & ~1ULL,
+-					  sizeof(struct pvclock_vcpu_time_info));
++		kvm_gpc_activate(vcpu->kvm, &vcpu->arch.pv_time, vcpu,
++				 KVM_HOST_USES_PFN, system_time & ~1ULL,
++				 sizeof(struct pvclock_vcpu_time_info));
+ 	} else {
+-		kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, &vcpu->arch.pv_time);
++		kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.pv_time);
+ 	}
+ 
+ 	return;
+@@ -3377,7 +3377,7 @@ static int kvm_pv_enable_async_pf_int(struct kvm_vcpu *vcpu, u64 data)
+ 
+ static void kvmclock_reset(struct kvm_vcpu *vcpu)
+ {
+-	kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, &vcpu->arch.pv_time);
++	kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.pv_time);
+ 	vcpu->arch.time = 0;
+ }
+ 
+@@ -11629,6 +11629,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
+ 	vcpu->arch.regs_avail = ~0;
+ 	vcpu->arch.regs_dirty = ~0;
+ 
++	kvm_gpc_init(&vcpu->arch.pv_time);
++
+ 	if (!irqchip_in_kernel(vcpu->kvm) || kvm_vcpu_is_reset_bsp(vcpu))
+ 		vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+ 	else
+diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
+index 280cb5dc7341a..cecf8299b187b 100644
+--- a/arch/x86/kvm/xen.c
++++ b/arch/x86/kvm/xen.c
+@@ -42,13 +42,13 @@ static int kvm_xen_shared_info_init(struct kvm *kvm, gfn_t gfn)
+ 	int idx = srcu_read_lock(&kvm->srcu);
+ 
+ 	if (gfn == GPA_INVALID) {
+-		kvm_gfn_to_pfn_cache_destroy(kvm, gpc);
++		kvm_gpc_deactivate(kvm, gpc);
+ 		goto out;
+ 	}
+ 
+ 	do {
+-		ret = kvm_gfn_to_pfn_cache_init(kvm, gpc, NULL, KVM_HOST_USES_PFN,
+-						gpa, PAGE_SIZE);
++		ret = kvm_gpc_activate(kvm, gpc, NULL, KVM_HOST_USES_PFN, gpa,
++				       PAGE_SIZE);
+ 		if (ret)
+ 			goto out;
+ 
+@@ -554,15 +554,15 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
+ 			     offsetof(struct compat_vcpu_info, time));
+ 
+ 		if (data->u.gpa == GPA_INVALID) {
+-			kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, &vcpu->arch.xen.vcpu_info_cache);
++			kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.vcpu_info_cache);
+ 			r = 0;
+ 			break;
+ 		}
+ 
+-		r = kvm_gfn_to_pfn_cache_init(vcpu->kvm,
+-					      &vcpu->arch.xen.vcpu_info_cache,
+-					      NULL, KVM_HOST_USES_PFN, data->u.gpa,
+-					      sizeof(struct vcpu_info));
++		r = kvm_gpc_activate(vcpu->kvm,
++				     &vcpu->arch.xen.vcpu_info_cache, NULL,
++				     KVM_HOST_USES_PFN, data->u.gpa,
++				     sizeof(struct vcpu_info));
+ 		if (!r)
+ 			kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
+ 
+@@ -570,16 +570,16 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
+ 
+ 	case KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO:
+ 		if (data->u.gpa == GPA_INVALID) {
+-			kvm_gfn_to_pfn_cache_destroy(vcpu->kvm,
+-						     &vcpu->arch.xen.vcpu_time_info_cache);
++			kvm_gpc_deactivate(vcpu->kvm,
++					   &vcpu->arch.xen.vcpu_time_info_cache);
+ 			r = 0;
+ 			break;
+ 		}
+ 
+-		r = kvm_gfn_to_pfn_cache_init(vcpu->kvm,
+-					      &vcpu->arch.xen.vcpu_time_info_cache,
+-					      NULL, KVM_HOST_USES_PFN, data->u.gpa,
+-					      sizeof(struct pvclock_vcpu_time_info));
++		r = kvm_gpc_activate(vcpu->kvm,
++				     &vcpu->arch.xen.vcpu_time_info_cache,
++				     NULL, KVM_HOST_USES_PFN, data->u.gpa,
++				     sizeof(struct pvclock_vcpu_time_info));
+ 		if (!r)
+ 			kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
+ 		break;
+@@ -590,16 +590,15 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
+ 			break;
+ 		}
+ 		if (data->u.gpa == GPA_INVALID) {
+-			kvm_gfn_to_pfn_cache_destroy(vcpu->kvm,
+-						     &vcpu->arch.xen.runstate_cache);
++			kvm_gpc_deactivate(vcpu->kvm,
++					   &vcpu->arch.xen.runstate_cache);
+ 			r = 0;
+ 			break;
+ 		}
+ 
+-		r = kvm_gfn_to_pfn_cache_init(vcpu->kvm,
+-					      &vcpu->arch.xen.runstate_cache,
+-					      NULL, KVM_HOST_USES_PFN, data->u.gpa,
+-					      sizeof(struct vcpu_runstate_info));
++		r = kvm_gpc_activate(vcpu->kvm, &vcpu->arch.xen.runstate_cache,
++				     NULL, KVM_HOST_USES_PFN, data->u.gpa,
++				     sizeof(struct vcpu_runstate_info));
+ 		break;
+ 
+ 	case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT:
+@@ -1817,7 +1816,12 @@ void kvm_xen_init_vcpu(struct kvm_vcpu *vcpu)
+ {
+ 	vcpu->arch.xen.vcpu_id = vcpu->vcpu_idx;
+ 	vcpu->arch.xen.poll_evtchn = 0;
++
+ 	timer_setup(&vcpu->arch.xen.poll_timer, cancel_evtchn_poll, 0);
++
++	kvm_gpc_init(&vcpu->arch.xen.runstate_cache);
++	kvm_gpc_init(&vcpu->arch.xen.vcpu_info_cache);
++	kvm_gpc_init(&vcpu->arch.xen.vcpu_time_info_cache);
+ }
+ 
+ void kvm_xen_destroy_vcpu(struct kvm_vcpu *vcpu)
+@@ -1825,18 +1829,17 @@ void kvm_xen_destroy_vcpu(struct kvm_vcpu *vcpu)
+ 	if (kvm_xen_timer_enabled(vcpu))
+ 		kvm_xen_stop_timer(vcpu);
+ 
+-	kvm_gfn_to_pfn_cache_destroy(vcpu->kvm,
+-				     &vcpu->arch.xen.runstate_cache);
+-	kvm_gfn_to_pfn_cache_destroy(vcpu->kvm,
+-				     &vcpu->arch.xen.vcpu_info_cache);
+-	kvm_gfn_to_pfn_cache_destroy(vcpu->kvm,
+-				     &vcpu->arch.xen.vcpu_time_info_cache);
++	kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.runstate_cache);
++	kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.vcpu_info_cache);
++	kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.vcpu_time_info_cache);
++
+ 	del_timer_sync(&vcpu->arch.xen.poll_timer);
+ }
+ 
+ void kvm_xen_init_vm(struct kvm *kvm)
+ {
+ 	idr_init(&kvm->arch.xen.evtchn_ports);
++	kvm_gpc_init(&kvm->arch.xen.shinfo_cache);
+ }
+ 
+ void kvm_xen_destroy_vm(struct kvm *kvm)
+@@ -1844,7 +1847,7 @@ void kvm_xen_destroy_vm(struct kvm *kvm)
+ 	struct evtchnfd *evtchnfd;
+ 	int i;
+ 
+-	kvm_gfn_to_pfn_cache_destroy(kvm, &kvm->arch.xen.shinfo_cache);
++	kvm_gpc_deactivate(kvm, &kvm->arch.xen.shinfo_cache);
+ 
+ 	idr_for_each_entry(&kvm->arch.xen.evtchn_ports, evtchnfd, i) {
+ 		if (!evtchnfd->deliver.port.port)
+diff --git a/block/bio.c b/block/bio.c
+index 77e3b764a0784..fc2364cf17750 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -741,7 +741,7 @@ void bio_put(struct bio *bio)
+ 			return;
+ 	}
+ 
+-	if (bio->bi_opf & REQ_ALLOC_CACHE) {
++	if ((bio->bi_opf & REQ_ALLOC_CACHE) && !WARN_ON_ONCE(in_interrupt())) {
+ 		struct bio_alloc_cache *cache;
+ 
+ 		bio_uninit(bio);
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index fe840536e6ac4..edf41959a705f 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -4104,9 +4104,7 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
+ 	return 0;
+ 
+ err_hctxs:
+-	xa_destroy(&q->hctx_table);
+-	q->nr_hw_queues = 0;
+-	blk_mq_sysfs_deinit(q);
++	blk_mq_release(q);
+ err_poll:
+ 	blk_stat_free_callback(q->poll_cb);
+ 	q->poll_cb = NULL;
+diff --git a/block/genhd.c b/block/genhd.c
+index 988ba52fd3316..044ff97381e33 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -519,6 +519,7 @@ out_unregister_bdi:
+ 		bdi_unregister(disk->bdi);
+ out_unregister_queue:
+ 	blk_unregister_queue(disk);
++	rq_qos_exit(disk->queue);
+ out_put_slave_dir:
+ 	kobject_put(disk->slave_dir);
+ out_put_holder_dir:
+diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
+index 80ad530583c9c..9952f3a792bad 100644
+--- a/drivers/acpi/apei/ghes.c
++++ b/drivers/acpi/apei/ghes.c
+@@ -163,7 +163,7 @@ static void ghes_unmap(void __iomem *vaddr, enum fixed_addresses fixmap_idx)
+ 	clear_fixmap(fixmap_idx);
+ }
+ 
+-int ghes_estatus_pool_init(int num_ghes)
++int ghes_estatus_pool_init(unsigned int num_ghes)
+ {
+ 	unsigned long addr, len;
+ 	int rc;
+diff --git a/drivers/acpi/numa/srat.c b/drivers/acpi/numa/srat.c
+index 3b818ab186be8..1f4fc5f8a819d 100644
+--- a/drivers/acpi/numa/srat.c
++++ b/drivers/acpi/numa/srat.c
+@@ -327,6 +327,7 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
+ 		pr_warn("ACPI NUMA: Failed to add memblk for CFMWS node %d [mem %#llx-%#llx]\n",
+ 			node, start, end);
+ 	}
++	node_set(node, numa_nodes_parsed);
+ 
+ 	/* Set the next available fake_pxm value */
+ 	(*fake_pxm)++;
+diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
+index 0a8bf09a5c19e..03c580625c2cc 100644
+--- a/drivers/ata/pata_legacy.c
++++ b/drivers/ata/pata_legacy.c
+@@ -315,9 +315,10 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev)
+ 	outb(inb(0x1F4) & 0x07, 0x1F4);
+ 
+ 	rt = inb(0x1F3);
+-	rt &= 0x07 << (3 * adev->devno);
++	rt &= ~(0x07 << (3 * !adev->devno));
+ 	if (pio)
+-		rt |= (1 + 3 * pio) << (3 * adev->devno);
++		rt |= (1 + 3 * pio) << (3 * !adev->devno);
++	outb(rt, 0x1F3);
+ 
+ 	udelay(100);
+ 	outb(inb(0x1F2) | 0x01, 0x1F2);
+diff --git a/drivers/ata/pata_palmld.c b/drivers/ata/pata_palmld.c
+index 400e65190904f..51caa2a427dd8 100644
+--- a/drivers/ata/pata_palmld.c
++++ b/drivers/ata/pata_palmld.c
+@@ -63,8 +63,8 @@ static int palmld_pata_probe(struct platform_device *pdev)
+ 
+ 	/* remap drive's physical memory address */
+ 	mem = devm_platform_ioremap_resource(pdev, 0);
+-	if (!mem)
+-		return -ENOMEM;
++	if (IS_ERR(mem))
++		return PTR_ERR(mem);
+ 
+ 	/* request and activate power and reset GPIOs */
+ 	lda->power = devm_gpiod_get(dev, "power", GPIOD_OUT_HIGH);
+diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
+index 6a4a94b4cdf42..31a8715d3a4d3 100644
+--- a/drivers/block/ublk_drv.c
++++ b/drivers/block/ublk_drv.c
+@@ -1507,6 +1507,9 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd)
+ 	 */
+ 	ub->dev_info.flags &= UBLK_F_ALL;
+ 
++	if (!IS_BUILTIN(CONFIG_BLK_DEV_UBLK))
++		ub->dev_info.flags |= UBLK_F_URING_CMD_COMP_IN_TASK;
++
+ 	/* We are not ready to support zero copy */
+ 	ub->dev_info.flags &= ~UBLK_F_SUPPORT_ZERO_COPY;
+ 
+diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c
+index 67c21263f9e0f..fd281d4395055 100644
+--- a/drivers/bluetooth/virtio_bt.c
++++ b/drivers/bluetooth/virtio_bt.c
+@@ -219,7 +219,7 @@ static void virtbt_rx_work(struct work_struct *work)
+ 	if (!skb)
+ 		return;
+ 
+-	skb->len = len;
++	skb_put(skb, len);
+ 	virtbt_rx_handle(vbt, skb);
+ 
+ 	if (virtbt_add_inbuf(vbt) < 0)
+diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c
+index e7dd457e9b22b..e98fcac578d66 100644
+--- a/drivers/char/hw_random/bcm2835-rng.c
++++ b/drivers/char/hw_random/bcm2835-rng.c
+@@ -71,7 +71,7 @@ static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max,
+ 	while ((rng_readl(priv, RNG_STATUS) >> 24) == 0) {
+ 		if (!wait)
+ 			return 0;
+-		cpu_relax();
++		hwrng_msleep(rng, 1000);
+ 	}
+ 
+ 	num_words = rng_readl(priv, RNG_STATUS) >> 24;
+diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c
+index 4f5df1fc74b46..e6247141d0c05 100644
+--- a/drivers/clk/clk-renesas-pcie.c
++++ b/drivers/clk/clk-renesas-pcie.c
+@@ -90,13 +90,66 @@ static const struct regmap_access_table rs9_writeable_table = {
+ 	.n_yes_ranges = ARRAY_SIZE(rs9_writeable_ranges),
+ };
+ 
++static int rs9_regmap_i2c_write(void *context,
++				unsigned int reg, unsigned int val)
++{
++	struct i2c_client *i2c = context;
++	const u8 data[3] = { reg, 1, val };
++	const int count = ARRAY_SIZE(data);
++	int ret;
++
++	ret = i2c_master_send(i2c, data, count);
++	if (ret == count)
++		return 0;
++	else if (ret < 0)
++		return ret;
++	else
++		return -EIO;
++}
++
++static int rs9_regmap_i2c_read(void *context,
++			       unsigned int reg, unsigned int *val)
++{
++	struct i2c_client *i2c = context;
++	struct i2c_msg xfer[2];
++	u8 txdata = reg;
++	u8 rxdata[2];
++	int ret;
++
++	xfer[0].addr = i2c->addr;
++	xfer[0].flags = 0;
++	xfer[0].len = 1;
++	xfer[0].buf = (void *)&txdata;
++
++	xfer[1].addr = i2c->addr;
++	xfer[1].flags = I2C_M_RD;
++	xfer[1].len = 2;
++	xfer[1].buf = (void *)rxdata;
++
++	ret = i2c_transfer(i2c->adapter, xfer, 2);
++	if (ret < 0)
++		return ret;
++	if (ret != 2)
++		return -EIO;
++
++	/*
++	 * Byte 0 is transfer length, which is always 1 due
++	 * to BCP register programming to 1 in rs9_probe(),
++	 * ignore it and use data from Byte 1.
++	 */
++	*val = rxdata[1];
++	return 0;
++}
++
+ static const struct regmap_config rs9_regmap_config = {
+ 	.reg_bits = 8,
+ 	.val_bits = 8,
+-	.cache_type = REGCACHE_FLAT,
+-	.max_register = 0x8,
++	.cache_type = REGCACHE_NONE,
++	.max_register = RS9_REG_BCP,
+ 	.rd_table = &rs9_readable_table,
+ 	.wr_table = &rs9_writeable_table,
++	.reg_write = rs9_regmap_i2c_write,
++	.reg_read = rs9_regmap_i2c_read,
+ };
+ 
+ static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
+@@ -242,11 +295,17 @@ static int rs9_probe(struct i2c_client *client)
+ 			return ret;
+ 	}
+ 
+-	rs9->regmap = devm_regmap_init_i2c(client, &rs9_regmap_config);
++	rs9->regmap = devm_regmap_init(&client->dev, NULL,
++				       client, &rs9_regmap_config);
+ 	if (IS_ERR(rs9->regmap))
+ 		return dev_err_probe(&client->dev, PTR_ERR(rs9->regmap),
+ 				     "Failed to allocate register map\n");
+ 
++	/* Always read back 1 Byte via I2C */
++	ret = regmap_write(rs9->regmap, RS9_REG_BCP, 1);
++	if (ret < 0)
++		return ret;
++
+ 	/* Register clock */
+ 	for (i = 0; i < rs9->chip_info->num_clks; i++) {
+ 		snprintf(name, 5, "DIF%d", i);
+diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c
+index 7ff64d4d5920d..2360f3f956184 100644
+--- a/drivers/clk/qcom/gcc-sc7280.c
++++ b/drivers/clk/qcom/gcc-sc7280.c
+@@ -3467,6 +3467,7 @@ static int gcc_sc7280_probe(struct platform_device *pdev)
+ 	regmap_update_bits(regmap, 0x28004, BIT(0), BIT(0));
+ 	regmap_update_bits(regmap, 0x28014, BIT(0), BIT(0));
+ 	regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0));
++	regmap_update_bits(regmap, 0x7100C, BIT(13), BIT(13));
+ 
+ 	ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
+ 			ARRAY_SIZE(gcc_dfs_clocks));
+diff --git a/drivers/clk/qcom/gpucc-sc7280.c b/drivers/clk/qcom/gpucc-sc7280.c
+index 9a832f2bcf491..1490cd45a654a 100644
+--- a/drivers/clk/qcom/gpucc-sc7280.c
++++ b/drivers/clk/qcom/gpucc-sc7280.c
+@@ -463,6 +463,7 @@ static int gpu_cc_sc7280_probe(struct platform_device *pdev)
+ 	 */
+ 	regmap_update_bits(regmap, 0x1170, BIT(0), BIT(0));
+ 	regmap_update_bits(regmap, 0x1098, BIT(0), BIT(0));
++	regmap_update_bits(regmap, 0x1098, BIT(13), BIT(13));
+ 
+ 	return qcom_cc_really_probe(pdev, &gpu_cc_sc7280_desc, regmap);
+ }
+diff --git a/drivers/clk/renesas/r8a779g0-cpg-mssr.c b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+index 3fc4233b1ead8..7beb0e3b18724 100644
+--- a/drivers/clk/renesas/r8a779g0-cpg-mssr.c
++++ b/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+@@ -47,6 +47,7 @@ enum clk_ids {
+ 	CLK_S0_VIO,
+ 	CLK_S0_VC,
+ 	CLK_S0_HSC,
++	CLK_SASYNCPER,
+ 	CLK_SV_VIP,
+ 	CLK_SV_IR,
+ 	CLK_SDSRC,
+@@ -84,6 +85,7 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = {
+ 	DEF_FIXED(".s0_vio",	CLK_S0_VIO,	CLK_PLL1_DIV2,	2, 1),
+ 	DEF_FIXED(".s0_vc",	CLK_S0_VC,	CLK_PLL1_DIV2,	2, 1),
+ 	DEF_FIXED(".s0_hsc",	CLK_S0_HSC,	CLK_PLL1_DIV2,	2, 1),
++	DEF_FIXED(".sasyncper",	CLK_SASYNCPER,	CLK_PLL5_DIV4,	3, 1),
+ 	DEF_FIXED(".sv_vip",	CLK_SV_VIP,	CLK_PLL1,	5, 1),
+ 	DEF_FIXED(".sv_ir",	CLK_SV_IR,	CLK_PLL1,	5, 1),
+ 	DEF_BASE(".sdsrc",	CLK_SDSRC,	CLK_TYPE_GEN4_SDSRC, CLK_PLL5),
+@@ -128,6 +130,9 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = {
+ 	DEF_FIXED("s0d4_hsc",	R8A779G0_CLK_S0D4_HSC,	CLK_S0_HSC,	4, 1),
+ 	DEF_FIXED("cl16m_hsc",	R8A779G0_CLK_CL16M_HSC,	CLK_S0_HSC,	48, 1),
+ 	DEF_FIXED("s0d2_cc",	R8A779G0_CLK_S0D2_CC,	CLK_S0,		2, 1),
++	DEF_FIXED("sasyncperd1",R8A779G0_CLK_SASYNCPERD1, CLK_SASYNCPER,1, 1),
++	DEF_FIXED("sasyncperd2",R8A779G0_CLK_SASYNCPERD2, CLK_SASYNCPER,2, 1),
++	DEF_FIXED("sasyncperd4",R8A779G0_CLK_SASYNCPERD4, CLK_SASYNCPER,4, 1),
+ 	DEF_FIXED("svd1_ir",	R8A779G0_CLK_SVD1_IR,	CLK_SV_IR,	1, 1),
+ 	DEF_FIXED("svd2_ir",	R8A779G0_CLK_SVD2_IR,	CLK_SV_IR,	2, 1),
+ 	DEF_FIXED("svd1_vip",	R8A779G0_CLK_SVD1_VIP,	CLK_SV_VIP,	1, 1),
+@@ -150,10 +155,10 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = {
+ };
+ 
+ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
+-	DEF_MOD("hscif0",	514,	R8A779G0_CLK_S0D3_PER),
+-	DEF_MOD("hscif1",	515,	R8A779G0_CLK_S0D3_PER),
+-	DEF_MOD("hscif2",	516,	R8A779G0_CLK_S0D3_PER),
+-	DEF_MOD("hscif3",	517,	R8A779G0_CLK_S0D3_PER),
++	DEF_MOD("hscif0",	514,	R8A779G0_CLK_SASYNCPERD1),
++	DEF_MOD("hscif1",	515,	R8A779G0_CLK_SASYNCPERD1),
++	DEF_MOD("hscif2",	516,	R8A779G0_CLK_SASYNCPERD1),
++	DEF_MOD("hscif3",	517,	R8A779G0_CLK_SASYNCPERD1),
+ };
+ 
+ /*
+diff --git a/drivers/cxl/core/pmem.c b/drivers/cxl/core/pmem.c
+index 1d12a8206444e..36aa5070d9024 100644
+--- a/drivers/cxl/core/pmem.c
++++ b/drivers/cxl/core/pmem.c
+@@ -188,6 +188,7 @@ static void cxl_nvdimm_release(struct device *dev)
+ {
+ 	struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev);
+ 
++	xa_destroy(&cxl_nvd->pmem_regions);
+ 	kfree(cxl_nvd);
+ }
+ 
+@@ -230,6 +231,7 @@ static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_memdev *cxlmd)
+ 
+ 	dev = &cxl_nvd->dev;
+ 	cxl_nvd->cxlmd = cxlmd;
++	xa_init(&cxl_nvd->pmem_regions);
+ 	device_initialize(dev);
+ 	lockdep_set_class(&dev->mutex, &cxl_nvdimm_key);
+ 	device_set_pm_not_required(dev);
+diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
+index bffde862de0bf..e7556864ea808 100644
+--- a/drivers/cxl/core/port.c
++++ b/drivers/cxl/core/port.c
+@@ -811,6 +811,7 @@ static struct cxl_dport *find_dport(struct cxl_port *port, int id)
+ static int add_dport(struct cxl_port *port, struct cxl_dport *new)
+ {
+ 	struct cxl_dport *dup;
++	int rc;
+ 
+ 	device_lock_assert(&port->dev);
+ 	dup = find_dport(port, new->port_id);
+@@ -821,8 +822,14 @@ static int add_dport(struct cxl_port *port, struct cxl_dport *new)
+ 			dev_name(dup->dport));
+ 		return -EBUSY;
+ 	}
+-	return xa_insert(&port->dports, (unsigned long)new->dport, new,
+-			 GFP_KERNEL);
++
++	rc = xa_insert(&port->dports, (unsigned long)new->dport, new,
++		       GFP_KERNEL);
++	if (rc)
++		return rc;
++
++	port->nr_dports++;
++	return 0;
+ }
+ 
+ /*
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index 4011480169784..6b7fb955a05ac 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -657,6 +657,9 @@ static struct cxl_region_ref *alloc_region_ref(struct cxl_port *port,
+ 	xa_for_each(&port->regions, index, iter) {
+ 		struct cxl_region_params *ip = &iter->region->params;
+ 
++		if (!ip->res)
++			continue;
++
+ 		if (ip->res->start > p->res->start) {
+ 			dev_dbg(&cxlr->dev,
+ 				"%s: HPA order violation %s:%pr vs %pr\n",
+@@ -686,18 +689,27 @@ static struct cxl_region_ref *alloc_region_ref(struct cxl_port *port,
+ 	return cxl_rr;
+ }
+ 
+-static void free_region_ref(struct cxl_region_ref *cxl_rr)
++static void cxl_rr_free_decoder(struct cxl_region_ref *cxl_rr)
+ {
+-	struct cxl_port *port = cxl_rr->port;
+ 	struct cxl_region *cxlr = cxl_rr->region;
+ 	struct cxl_decoder *cxld = cxl_rr->decoder;
+ 
++	if (!cxld)
++		return;
++
+ 	dev_WARN_ONCE(&cxlr->dev, cxld->region != cxlr, "region mismatch\n");
+ 	if (cxld->region == cxlr) {
+ 		cxld->region = NULL;
+ 		put_device(&cxlr->dev);
+ 	}
++}
++
++static void free_region_ref(struct cxl_region_ref *cxl_rr)
++{
++	struct cxl_port *port = cxl_rr->port;
++	struct cxl_region *cxlr = cxl_rr->region;
+ 
++	cxl_rr_free_decoder(cxl_rr);
+ 	xa_erase(&port->regions, (unsigned long)cxlr);
+ 	xa_destroy(&cxl_rr->endpoints);
+ 	kfree(cxl_rr);
+@@ -728,6 +740,33 @@ static int cxl_rr_ep_add(struct cxl_region_ref *cxl_rr,
+ 	return 0;
+ }
+ 
++static int cxl_rr_alloc_decoder(struct cxl_port *port, struct cxl_region *cxlr,
++				struct cxl_endpoint_decoder *cxled,
++				struct cxl_region_ref *cxl_rr)
++{
++	struct cxl_decoder *cxld;
++
++	if (port == cxled_to_port(cxled))
++		cxld = &cxled->cxld;
++	else
++		cxld = cxl_region_find_decoder(port, cxlr);
++	if (!cxld) {
++		dev_dbg(&cxlr->dev, "%s: no decoder available\n",
++			dev_name(&port->dev));
++		return -EBUSY;
++	}
++
++	if (cxld->region) {
++		dev_dbg(&cxlr->dev, "%s: %s already attached to %s\n",
++			dev_name(&port->dev), dev_name(&cxld->dev),
++			dev_name(&cxld->region->dev));
++		return -EBUSY;
++	}
++
++	cxl_rr->decoder = cxld;
++	return 0;
++}
++
+ /**
+  * cxl_port_attach_region() - track a region's interest in a port by endpoint
+  * @port: port to add a new region reference 'struct cxl_region_ref'
+@@ -794,12 +833,6 @@ static int cxl_port_attach_region(struct cxl_port *port,
+ 			cxl_rr->nr_targets++;
+ 			nr_targets_inc = true;
+ 		}
+-
+-		/*
+-		 * The decoder for @cxlr was allocated when the region was first
+-		 * attached to @port.
+-		 */
+-		cxld = cxl_rr->decoder;
+ 	} else {
+ 		cxl_rr = alloc_region_ref(port, cxlr);
+ 		if (IS_ERR(cxl_rr)) {
+@@ -810,26 +843,11 @@ static int cxl_port_attach_region(struct cxl_port *port,
+ 		}
+ 		nr_targets_inc = true;
+ 
+-		if (port == cxled_to_port(cxled))
+-			cxld = &cxled->cxld;
+-		else
+-			cxld = cxl_region_find_decoder(port, cxlr);
+-		if (!cxld) {
+-			dev_dbg(&cxlr->dev, "%s: no decoder available\n",
+-				dev_name(&port->dev));
+-			goto out_erase;
+-		}
+-
+-		if (cxld->region) {
+-			dev_dbg(&cxlr->dev, "%s: %s already attached to %s\n",
+-				dev_name(&port->dev), dev_name(&cxld->dev),
+-				dev_name(&cxld->region->dev));
+-			rc = -EBUSY;
++		rc = cxl_rr_alloc_decoder(port, cxlr, cxled, cxl_rr);
++		if (rc)
+ 			goto out_erase;
+-		}
+-
+-		cxl_rr->decoder = cxld;
+ 	}
++	cxld = cxl_rr->decoder;
+ 
+ 	rc = cxl_rr_ep_add(cxl_rr, cxled);
+ 	if (rc) {
+@@ -971,7 +989,14 @@ static int cxl_port_setup_targets(struct cxl_port *port,
+ 	if (cxl_rr->nr_targets_set) {
+ 		int i, distance;
+ 
+-		distance = p->nr_targets / cxl_rr->nr_targets;
++		/*
++		 * Passthrough ports impose no distance requirements between
++		 * peers
++		 */
++		if (port->nr_dports == 1)
++			distance = 0;
++		else
++			distance = p->nr_targets / cxl_rr->nr_targets;
+ 		for (i = 0; i < cxl_rr->nr_targets_set; i++)
+ 			if (ep->dport == cxlsd->target[i]) {
+ 				rc = check_last_peer(cxled, ep, cxl_rr,
+@@ -1538,8 +1563,19 @@ static struct cxl_region *to_cxl_region(struct device *dev)
+ static void unregister_region(void *dev)
+ {
+ 	struct cxl_region *cxlr = to_cxl_region(dev);
++	struct cxl_region_params *p = &cxlr->params;
++	int i;
+ 
+ 	device_del(dev);
++
++	/*
++	 * Now that region sysfs is shutdown, the parameter block is now
++	 * read-only, so no need to hold the region rwsem to access the
++	 * region parameters.
++	 */
++	for (i = 0; i < p->interleave_ways; i++)
++		detach_target(cxlr, i);
++
+ 	cxl_region_iomem_release(cxlr);
+ 	put_device(dev);
+ }
+diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
+index f680450f0b16c..ac75554b5d763 100644
+--- a/drivers/cxl/cxl.h
++++ b/drivers/cxl/cxl.h
+@@ -423,7 +423,7 @@ struct cxl_nvdimm {
+ 	struct device dev;
+ 	struct cxl_memdev *cxlmd;
+ 	struct cxl_nvdimm_bridge *bridge;
+-	struct cxl_pmem_region *region;
++	struct xarray pmem_regions;
+ };
+ 
+ struct cxl_pmem_region_mapping {
+@@ -457,6 +457,7 @@ struct cxl_pmem_region {
+  * @regions: cxl_region_ref instances, regions mapped by this port
+  * @parent_dport: dport that points to this port in the parent
+  * @decoder_ida: allocator for decoder ids
++ * @nr_dports: number of entries in @dports
+  * @hdm_end: track last allocated HDM decoder instance for allocation ordering
+  * @commit_end: cursor to track highest committed decoder for commit ordering
+  * @component_reg_phys: component register capability base address (optional)
+@@ -475,6 +476,7 @@ struct cxl_port {
+ 	struct xarray regions;
+ 	struct cxl_dport *parent_dport;
+ 	struct ida decoder_ida;
++	int nr_dports;
+ 	int hdm_end;
+ 	int commit_end;
+ 	resource_size_t component_reg_phys;
+diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c
+index 7dc0a2fa1a6b6..faade12279f02 100644
+--- a/drivers/cxl/pmem.c
++++ b/drivers/cxl/pmem.c
+@@ -30,17 +30,20 @@ static void unregister_nvdimm(void *nvdimm)
+ 	struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm);
+ 	struct cxl_nvdimm_bridge *cxl_nvb = cxl_nvd->bridge;
+ 	struct cxl_pmem_region *cxlr_pmem;
++	unsigned long index;
+ 
+ 	device_lock(&cxl_nvb->dev);
+-	cxlr_pmem = cxl_nvd->region;
+ 	dev_set_drvdata(&cxl_nvd->dev, NULL);
+-	cxl_nvd->region = NULL;
+-	device_unlock(&cxl_nvb->dev);
++	xa_for_each(&cxl_nvd->pmem_regions, index, cxlr_pmem) {
++		get_device(&cxlr_pmem->dev);
++		device_unlock(&cxl_nvb->dev);
+ 
+-	if (cxlr_pmem) {
+ 		device_release_driver(&cxlr_pmem->dev);
+ 		put_device(&cxlr_pmem->dev);
++
++		device_lock(&cxl_nvb->dev);
+ 	}
++	device_unlock(&cxl_nvb->dev);
+ 
+ 	nvdimm_delete(nvdimm);
+ 	cxl_nvd->bridge = NULL;
+@@ -366,25 +369,49 @@ static int match_cxl_nvdimm(struct device *dev, void *data)
+ 
+ static void unregister_nvdimm_region(void *nd_region)
+ {
+-	struct cxl_nvdimm_bridge *cxl_nvb;
+-	struct cxl_pmem_region *cxlr_pmem;
++	nvdimm_region_delete(nd_region);
++}
++
++static int cxl_nvdimm_add_region(struct cxl_nvdimm *cxl_nvd,
++				 struct cxl_pmem_region *cxlr_pmem)
++{
++	int rc;
++
++	rc = xa_insert(&cxl_nvd->pmem_regions, (unsigned long)cxlr_pmem,
++		       cxlr_pmem, GFP_KERNEL);
++	if (rc)
++		return rc;
++
++	get_device(&cxlr_pmem->dev);
++	return 0;
++}
++
++static void cxl_nvdimm_del_region(struct cxl_nvdimm *cxl_nvd,
++				  struct cxl_pmem_region *cxlr_pmem)
++{
++	/*
++	 * It is possible this is called without a corresponding
++	 * cxl_nvdimm_add_region for @cxlr_pmem
++	 */
++	cxlr_pmem = xa_erase(&cxl_nvd->pmem_regions, (unsigned long)cxlr_pmem);
++	if (cxlr_pmem)
++		put_device(&cxlr_pmem->dev);
++}
++
++static void release_mappings(void *data)
++{
+ 	int i;
++	struct cxl_pmem_region *cxlr_pmem = data;
++	struct cxl_nvdimm_bridge *cxl_nvb = cxlr_pmem->bridge;
+ 
+-	cxlr_pmem = nd_region_provider_data(nd_region);
+-	cxl_nvb = cxlr_pmem->bridge;
+ 	device_lock(&cxl_nvb->dev);
+ 	for (i = 0; i < cxlr_pmem->nr_mappings; i++) {
+ 		struct cxl_pmem_region_mapping *m = &cxlr_pmem->mapping[i];
+ 		struct cxl_nvdimm *cxl_nvd = m->cxl_nvd;
+ 
+-		if (cxl_nvd->region) {
+-			put_device(&cxlr_pmem->dev);
+-			cxl_nvd->region = NULL;
+-		}
++		cxl_nvdimm_del_region(cxl_nvd, cxlr_pmem);
+ 	}
+ 	device_unlock(&cxl_nvb->dev);
+-
+-	nvdimm_region_delete(nd_region);
+ }
+ 
+ static void cxlr_pmem_remove_resource(void *res)
+@@ -422,7 +449,7 @@ static int cxl_pmem_region_probe(struct device *dev)
+ 	if (!cxl_nvb->nvdimm_bus) {
+ 		dev_dbg(dev, "nvdimm bus not found\n");
+ 		rc = -ENXIO;
+-		goto err;
++		goto out_nvb;
+ 	}
+ 
+ 	memset(&mappings, 0, sizeof(mappings));
+@@ -431,7 +458,7 @@ static int cxl_pmem_region_probe(struct device *dev)
+ 	res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
+ 	if (!res) {
+ 		rc = -ENOMEM;
+-		goto err;
++		goto out_nvb;
+ 	}
+ 
+ 	res->name = "Persistent Memory";
+@@ -442,11 +469,11 @@ static int cxl_pmem_region_probe(struct device *dev)
+ 
+ 	rc = insert_resource(&iomem_resource, res);
+ 	if (rc)
+-		goto err;
++		goto out_nvb;
+ 
+ 	rc = devm_add_action_or_reset(dev, cxlr_pmem_remove_resource, res);
+ 	if (rc)
+-		goto err;
++		goto out_nvb;
+ 
+ 	ndr_desc.res = res;
+ 	ndr_desc.provider_data = cxlr_pmem;
+@@ -462,7 +489,7 @@ static int cxl_pmem_region_probe(struct device *dev)
+ 	nd_set = devm_kzalloc(dev, sizeof(*nd_set), GFP_KERNEL);
+ 	if (!nd_set) {
+ 		rc = -ENOMEM;
+-		goto err;
++		goto out_nvb;
+ 	}
+ 
+ 	ndr_desc.memregion = cxlr->id;
+@@ -472,9 +499,13 @@ static int cxl_pmem_region_probe(struct device *dev)
+ 	info = kmalloc_array(cxlr_pmem->nr_mappings, sizeof(*info), GFP_KERNEL);
+ 	if (!info) {
+ 		rc = -ENOMEM;
+-		goto err;
++		goto out_nvb;
+ 	}
+ 
++	rc = devm_add_action_or_reset(dev, release_mappings, cxlr_pmem);
++	if (rc)
++		goto out_nvd;
++
+ 	for (i = 0; i < cxlr_pmem->nr_mappings; i++) {
+ 		struct cxl_pmem_region_mapping *m = &cxlr_pmem->mapping[i];
+ 		struct cxl_memdev *cxlmd = m->cxlmd;
+@@ -486,7 +517,7 @@ static int cxl_pmem_region_probe(struct device *dev)
+ 			dev_dbg(dev, "[%d]: %s: no cxl_nvdimm found\n", i,
+ 				dev_name(&cxlmd->dev));
+ 			rc = -ENODEV;
+-			goto err;
++			goto out_nvd;
+ 		}
+ 
+ 		/* safe to drop ref now with bridge lock held */
+@@ -498,10 +529,17 @@ static int cxl_pmem_region_probe(struct device *dev)
+ 			dev_dbg(dev, "[%d]: %s: no nvdimm found\n", i,
+ 				dev_name(&cxlmd->dev));
+ 			rc = -ENODEV;
+-			goto err;
++			goto out_nvd;
+ 		}
+-		cxl_nvd->region = cxlr_pmem;
+-		get_device(&cxlr_pmem->dev);
++
++		/*
++		 * Pin the region per nvdimm device as those may be released
++		 * out-of-order with respect to the region, and a single nvdimm
++		 * maybe associated with multiple regions
++		 */
++		rc = cxl_nvdimm_add_region(cxl_nvd, cxlr_pmem);
++		if (rc)
++			goto out_nvd;
+ 		m->cxl_nvd = cxl_nvd;
+ 		mappings[i] = (struct nd_mapping_desc) {
+ 			.nvdimm = nvdimm,
+@@ -527,27 +565,18 @@ static int cxl_pmem_region_probe(struct device *dev)
+ 		nvdimm_pmem_region_create(cxl_nvb->nvdimm_bus, &ndr_desc);
+ 	if (!cxlr_pmem->nd_region) {
+ 		rc = -ENOMEM;
+-		goto err;
++		goto out_nvd;
+ 	}
+ 
+ 	rc = devm_add_action_or_reset(dev, unregister_nvdimm_region,
+ 				      cxlr_pmem->nd_region);
+-out:
++out_nvd:
+ 	kfree(info);
++out_nvb:
+ 	device_unlock(&cxl_nvb->dev);
+ 	put_device(&cxl_nvb->dev);
+ 
+ 	return rc;
+-
+-err:
+-	dev_dbg(dev, "failed to create nvdimm region\n");
+-	for (i--; i >= 0; i--) {
+-		nvdimm = mappings[i].nvdimm;
+-		cxl_nvd = nvdimm_provider_data(nvdimm);
+-		put_device(&cxl_nvd->region->dev);
+-		cxl_nvd->region = NULL;
+-	}
+-	goto out;
+ }
+ 
+ static struct cxl_driver cxl_pmem_region_driver = {
+diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
+index 609ebedee9cb6..9022f5ee29aa8 100644
+--- a/drivers/firmware/arm_scmi/driver.c
++++ b/drivers/firmware/arm_scmi/driver.c
+@@ -2044,8 +2044,12 @@ scmi_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
+ {
+ 	int ret = scmi_chan_setup(info, dev, prot_id, true);
+ 
+-	if (!ret) /* Rx is optional, hence no error check */
+-		scmi_chan_setup(info, dev, prot_id, false);
++	if (!ret) {
++		/* Rx is optional, report only memory errors */
++		ret = scmi_chan_setup(info, dev, prot_id, false);
++		if (ret && ret != -ENOMEM)
++			ret = 0;
++	}
+ 
+ 	return ret;
+ }
+@@ -2571,6 +2575,7 @@ MODULE_DEVICE_TABLE(of, scmi_of_match);
+ static struct platform_driver scmi_driver = {
+ 	.driver = {
+ 		   .name = "arm-scmi",
++		   .suppress_bind_attrs = true,
+ 		   .of_match_table = scmi_of_match,
+ 		   .dev_groups = versions_groups,
+ 		   },
+diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c
+index 14709dbc96a1a..33c9b81a55cd1 100644
+--- a/drivers/firmware/arm_scmi/virtio.c
++++ b/drivers/firmware/arm_scmi/virtio.c
+@@ -148,7 +148,6 @@ static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch)
+ {
+ 	unsigned long flags;
+ 	DECLARE_COMPLETION_ONSTACK(vioch_shutdown_done);
+-	void *deferred_wq = NULL;
+ 
+ 	/*
+ 	 * Prepare to wait for the last release if not already released
+@@ -162,16 +161,11 @@ static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch)
+ 
+ 	vioch->shutdown_done = &vioch_shutdown_done;
+ 	virtio_break_device(vioch->vqueue->vdev);
+-	if (!vioch->is_rx && vioch->deferred_tx_wq) {
+-		deferred_wq = vioch->deferred_tx_wq;
++	if (!vioch->is_rx && vioch->deferred_tx_wq)
+ 		/* Cannot be kicked anymore after this...*/
+ 		vioch->deferred_tx_wq = NULL;
+-	}
+ 	spin_unlock_irqrestore(&vioch->lock, flags);
+ 
+-	if (deferred_wq)
+-		destroy_workqueue(deferred_wq);
+-
+ 	scmi_vio_channel_release(vioch);
+ 
+ 	/* Let any possibly concurrent RX path release the channel */
+@@ -416,6 +410,11 @@ static bool virtio_chan_available(struct device *dev, int idx)
+ 	return vioch && !vioch->cinfo;
+ }
+ 
++static void scmi_destroy_tx_workqueue(void *deferred_tx_wq)
++{
++	destroy_workqueue(deferred_tx_wq);
++}
++
+ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
+ 			     bool tx)
+ {
+@@ -430,6 +429,8 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
+ 
+ 	/* Setup a deferred worker for polling. */
+ 	if (tx && !vioch->deferred_tx_wq) {
++		int ret;
++
+ 		vioch->deferred_tx_wq =
+ 			alloc_workqueue(dev_name(&scmi_vdev->dev),
+ 					WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
+@@ -437,6 +438,11 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
+ 		if (!vioch->deferred_tx_wq)
+ 			return -ENOMEM;
+ 
++		ret = devm_add_action_or_reset(dev, scmi_destroy_tx_workqueue,
++					       vioch->deferred_tx_wq);
++		if (ret)
++			return ret;
++
+ 		INIT_WORK(&vioch->deferred_tx_work,
+ 			  scmi_vio_deferred_tx_worker);
+ 	}
+@@ -444,12 +450,12 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
+ 	for (i = 0; i < vioch->max_msg; i++) {
+ 		struct scmi_vio_msg *msg;
+ 
+-		msg = devm_kzalloc(cinfo->dev, sizeof(*msg), GFP_KERNEL);
++		msg = devm_kzalloc(dev, sizeof(*msg), GFP_KERNEL);
+ 		if (!msg)
+ 			return -ENOMEM;
+ 
+ 		if (tx) {
+-			msg->request = devm_kzalloc(cinfo->dev,
++			msg->request = devm_kzalloc(dev,
+ 						    VIRTIO_SCMI_MAX_PDU_SIZE,
+ 						    GFP_KERNEL);
+ 			if (!msg->request)
+@@ -458,7 +464,7 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
+ 			refcount_set(&msg->users, 1);
+ 		}
+ 
+-		msg->input = devm_kzalloc(cinfo->dev, VIRTIO_SCMI_MAX_PDU_SIZE,
++		msg->input = devm_kzalloc(dev, VIRTIO_SCMI_MAX_PDU_SIZE,
+ 					  GFP_KERNEL);
+ 		if (!msg->input)
+ 			return -ENOMEM;
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index aa6d109fac08b..a06decee51e06 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -608,7 +608,7 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
+ 
+ 		seed = early_memremap(efi_rng_seed, sizeof(*seed));
+ 		if (seed != NULL) {
+-			size = READ_ONCE(seed->size);
++			size = min(seed->size, EFI_RANDOM_SEED_SIZE);
+ 			early_memunmap(seed, sizeof(*seed));
+ 		} else {
+ 			pr_err("Could not map UEFI random seed!\n");
+diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c
+index 24aa375353724..33ab567695951 100644
+--- a/drivers/firmware/efi/libstub/random.c
++++ b/drivers/firmware/efi/libstub/random.c
+@@ -75,7 +75,12 @@ efi_status_t efi_random_get_seed(void)
+ 	if (status != EFI_SUCCESS)
+ 		return status;
+ 
+-	status = efi_bs_call(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
++	/*
++	 * Use EFI_ACPI_RECLAIM_MEMORY here so that it is guaranteed that the
++	 * allocation will survive a kexec reboot (although we refresh the seed
++	 * beforehand)
++	 */
++	status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
+ 			     sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
+ 			     (void **)&seed);
+ 	if (status != EFI_SUCCESS)
+diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c
+index 8f665678e9e39..e8d69bd548f3f 100644
+--- a/drivers/firmware/efi/tpm.c
++++ b/drivers/firmware/efi/tpm.c
+@@ -97,7 +97,7 @@ int __init efi_tpm_eventlog_init(void)
+ 		goto out_calc;
+ 	}
+ 
+-	memblock_reserve((unsigned long)final_tbl,
++	memblock_reserve(efi.tpm_final_log,
+ 			 tbl_size + sizeof(*final_tbl));
+ 	efi_tpm_final_log_size = tbl_size;
+ 
+diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
+index 433b615871395..0ba9f18312f5b 100644
+--- a/drivers/firmware/efi/vars.c
++++ b/drivers/firmware/efi/vars.c
+@@ -21,29 +21,22 @@ static struct efivars *__efivars;
+ 
+ static DEFINE_SEMAPHORE(efivars_lock);
+ 
+-static efi_status_t check_var_size(u32 attributes, unsigned long size)
+-{
+-	const struct efivar_operations *fops;
+-
+-	fops = __efivars->ops;
+-
+-	if (!fops->query_variable_store)
+-		return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
+-
+-	return fops->query_variable_store(attributes, size, false);
+-}
+-
+-static
+-efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size)
++static efi_status_t check_var_size(bool nonblocking, u32 attributes,
++				   unsigned long size)
+ {
+ 	const struct efivar_operations *fops;
++	efi_status_t status;
+ 
+ 	fops = __efivars->ops;
+ 
+ 	if (!fops->query_variable_store)
++		status = EFI_UNSUPPORTED;
++	else
++		status = fops->query_variable_store(attributes, size,
++						    nonblocking);
++	if (status == EFI_UNSUPPORTED)
+ 		return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
+-
+-	return fops->query_variable_store(attributes, size, true);
++	return status;
+ }
+ 
+ /**
+@@ -195,26 +188,6 @@ efi_status_t efivar_get_next_variable(unsigned long *name_size,
+ }
+ EXPORT_SYMBOL_NS_GPL(efivar_get_next_variable, EFIVAR);
+ 
+-/*
+- * efivar_set_variable_blocking() - local helper function for set_variable
+- *
+- * Must be called with efivars_lock held.
+- */
+-static efi_status_t
+-efivar_set_variable_blocking(efi_char16_t *name, efi_guid_t *vendor,
+-			     u32 attr, unsigned long data_size, void *data)
+-{
+-	efi_status_t status;
+-
+-	if (data_size > 0) {
+-		status = check_var_size(attr, data_size +
+-					      ucs2_strsize(name, 1024));
+-		if (status != EFI_SUCCESS)
+-			return status;
+-	}
+-	return __efivars->ops->set_variable(name, vendor, attr, data_size, data);
+-}
+-
+ /*
+  * efivar_set_variable_locked() - set a variable identified by name/vendor
+  *
+@@ -228,23 +201,21 @@ efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor,
+ 	efi_set_variable_t *setvar;
+ 	efi_status_t status;
+ 
+-	if (!nonblocking)
+-		return efivar_set_variable_blocking(name, vendor, attr,
+-						    data_size, data);
++	if (data_size > 0) {
++		status = check_var_size(nonblocking, attr,
++					data_size + ucs2_strsize(name, 1024));
++		if (status != EFI_SUCCESS)
++			return status;
++	}
+ 
+ 	/*
+ 	 * If no _nonblocking variant exists, the ordinary one
+ 	 * is assumed to be non-blocking.
+ 	 */
+-	setvar = __efivars->ops->set_variable_nonblocking ?:
+-		 __efivars->ops->set_variable;
++	setvar = __efivars->ops->set_variable_nonblocking;
++	if (!setvar || !nonblocking)
++		 setvar = __efivars->ops->set_variable;
+ 
+-	if (data_size > 0) {
+-		status = check_var_size_nonblocking(attr, data_size +
+-							  ucs2_strsize(name, 1024));
+-		if (status != EFI_SUCCESS)
+-			return status;
+-	}
+ 	return setvar(name, vendor, attr, data_size, data);
+ }
+ EXPORT_SYMBOL_NS_GPL(efivar_set_variable_locked, EFIVAR);
+@@ -264,7 +235,8 @@ efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+ 	if (efivar_lock())
+ 		return EFI_ABORTED;
+ 
+-	status = efivar_set_variable_blocking(name, vendor, attr, data_size, data);
++	status = efivar_set_variable_locked(name, vendor, attr, data_size,
++					    data, false);
+ 	efivar_unlock();
+ 	return status;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+index 5e53a52939356..0d939f07d5061 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+@@ -703,6 +703,13 @@ err:
+ 
+ void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle)
+ {
++	/* Temporary workaround to fix issues observed in some
++	 * compute applications when GFXOFF is enabled on GFX11.
++	 */
++	if (IP_VERSION_MAJ(adev->ip_versions[GC_HWIP][0]) == 11) {
++		pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled");
++		amdgpu_gfx_off_ctrl(adev, idle);
++	}
+ 	amdgpu_dpm_switch_power_profile(adev,
+ 					PP_SMC_POWER_PROFILE_COMPUTE,
+ 					!idle);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c
+index 0b0a72ca56956..7e80caa05060b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c
+@@ -111,7 +111,7 @@ static int init_interrupts_v11(struct amdgpu_device *adev, uint32_t pipe_id)
+ 
+ 	lock_srbm(adev, mec, pipe, 0, 0);
+ 
+-	WREG32(SOC15_REG_OFFSET(GC, 0, regCPC_INT_CNTL),
++	WREG32_SOC15(GC, 0, regCPC_INT_CNTL,
+ 		CP_INT_CNTL_RING0__TIME_STAMP_INT_ENABLE_MASK |
+ 		CP_INT_CNTL_RING0__OPCODE_ERROR_INT_ENABLE_MASK);
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+index 9be57389301b4..af5aeb0ec2e92 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+@@ -726,6 +726,12 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev)
+ 			adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE;
+ 	}
+ 
++	if (amdgpu_sriov_vf(adev) && adev->asic_type == CHIP_SIENNA_CICHLID)
++		/* VF MMIO access (except mailbox range) from CPU
++		 * will be blocked during sriov runtime
++		 */
++		adev->virt.caps |= AMDGPU_VF_MMIO_ACCESS_PROTECT;
++
+ 	/* we have the ability to check now */
+ 	if (amdgpu_sriov_vf(adev)) {
+ 		switch (adev->asic_type) {
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+index 239f232f9c026..617d072275ebe 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+@@ -31,6 +31,7 @@
+ #define AMDGPU_SRIOV_CAPS_IS_VF        (1 << 2) /* this GPU is a virtual function */
+ #define AMDGPU_PASSTHROUGH_MODE        (1 << 3) /* thw whole GPU is pass through for VM */
+ #define AMDGPU_SRIOV_CAPS_RUNTIME      (1 << 4) /* is out of full access mode */
++#define AMDGPU_VF_MMIO_ACCESS_PROTECT  (1 << 5) /* MMIO write access is not allowed in sriov runtime */
+ 
+ /* flags for indirect register access path supported by rlcg for sriov */
+ #define AMDGPU_RLCG_GC_WRITE_LEGACY    (0x8 << 28)
+@@ -294,6 +295,9 @@ struct amdgpu_video_codec_info;
+ #define amdgpu_passthrough(adev) \
+ ((adev)->virt.caps & AMDGPU_PASSTHROUGH_MODE)
+ 
++#define amdgpu_sriov_vf_mmio_access_protection(adev) \
++((adev)->virt.caps & AMDGPU_VF_MMIO_ACCESS_PROTECT)
++
+ static inline bool is_virtual_machine(void)
+ {
+ #if defined(CONFIG_X86)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index 690fd4f639f19..04130f8813ef1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -2301,7 +2301,11 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
+ 	 */
+ #ifdef CONFIG_X86_64
+ 	if (amdgpu_vm_update_mode == -1) {
+-		if (amdgpu_gmc_vram_full_visible(&adev->gmc))
++		/* For asic with VF MMIO access protection
++		 * avoid using CPU for VM table updates
++		 */
++		if (amdgpu_gmc_vram_full_visible(&adev->gmc) &&
++		    !amdgpu_sriov_vf_mmio_access_protection(adev))
+ 			adev->vm_manager.vm_update_mode =
+ 				AMDGPU_VM_USE_CPU_FOR_COMPUTE;
+ 		else
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+index daf8ba8235cd0..03775e0a81004 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+@@ -1729,7 +1729,7 @@ static void gfx_v11_0_init_compute_vmid(struct amdgpu_device *adev)
+ 		WREG32_SOC15(GC, 0, regSH_MEM_BASES, sh_mem_bases);
+ 
+ 		/* Enable trap for each kfd vmid. */
+-		data = RREG32(SOC15_REG_OFFSET(GC, 0, regSPI_GDBG_PER_VMID_CNTL));
++		data = RREG32_SOC15(GC, 0, regSPI_GDBG_PER_VMID_CNTL);
+ 		data = REG_SET_FIELD(data, SPI_GDBG_PER_VMID_CNTL, TRAP_EN, 1);
+ 	}
+ 	soc21_grbm_select(adev, 0, 0, 0, 0);
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
+index 1471bfb9ae38e..2475fdbe80104 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
+@@ -185,6 +185,10 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
+ 	/* Use register 17 for GART */
+ 	const unsigned eng = 17;
+ 	unsigned int i;
++	unsigned char hub_ip = 0;
++
++	hub_ip = (vmhub == AMDGPU_GFXHUB_0) ?
++		   GC_HWIP : MMHUB_HWIP;
+ 
+ 	spin_lock(&adev->gmc.invalidate_lock);
+ 	/*
+@@ -198,8 +202,8 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
+ 	if (use_semaphore) {
+ 		for (i = 0; i < adev->usec_timeout; i++) {
+ 			/* a read return value of 1 means semaphore acuqire */
+-			tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem +
+-					    hub->eng_distance * eng);
++			tmp = RREG32_RLC_NO_KIQ(hub->vm_inv_eng0_sem +
++					    hub->eng_distance * eng, hub_ip);
+ 			if (tmp & 0x1)
+ 				break;
+ 			udelay(1);
+@@ -209,12 +213,12 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
+ 			DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n");
+ 	}
+ 
+-	WREG32_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng, inv_req);
++	WREG32_RLC_NO_KIQ(hub->vm_inv_eng0_req + hub->eng_distance * eng, inv_req, hub_ip);
+ 
+ 	/* Wait for ACK with a delay.*/
+ 	for (i = 0; i < adev->usec_timeout; i++) {
+-		tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_ack +
+-				    hub->eng_distance * eng);
++		tmp = RREG32_RLC_NO_KIQ(hub->vm_inv_eng0_ack +
++				    hub->eng_distance * eng, hub_ip);
+ 		tmp &= 1 << vmid;
+ 		if (tmp)
+ 			break;
+@@ -228,8 +232,8 @@ static void gmc_v11_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
+ 		 * add semaphore release after invalidation,
+ 		 * write with 0 means semaphore release
+ 		 */
+-		WREG32_NO_KIQ(hub->vm_inv_eng0_sem +
+-			      hub->eng_distance * eng, 0);
++		WREG32_RLC_NO_KIQ(hub->vm_inv_eng0_sem +
++			      hub->eng_distance * eng, 0, hub_ip);
+ 
+ 	/* Issue additional private vm invalidation to MMHUB */
+ 	if ((vmhub != AMDGPU_GFXHUB_0) &&
+diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+index f92744b8d79df..2dd827472d6e4 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+@@ -1145,6 +1145,42 @@ static int mes_v11_0_sw_fini(void *handle)
+ 	return 0;
+ }
+ 
++static void mes_v11_0_kiq_dequeue_sched(struct amdgpu_device *adev)
++{
++	uint32_t data;
++	int i;
++
++	mutex_lock(&adev->srbm_mutex);
++	soc21_grbm_select(adev, 3, AMDGPU_MES_SCHED_PIPE, 0, 0);
++
++	/* disable the queue if it's active */
++	if (RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1) {
++		WREG32_SOC15(GC, 0, regCP_HQD_DEQUEUE_REQUEST, 1);
++		for (i = 0; i < adev->usec_timeout; i++) {
++			if (!(RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1))
++				break;
++			udelay(1);
++		}
++	}
++	data = RREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL);
++	data = REG_SET_FIELD(data, CP_HQD_PQ_DOORBELL_CONTROL,
++				DOORBELL_EN, 0);
++	data = REG_SET_FIELD(data, CP_HQD_PQ_DOORBELL_CONTROL,
++				DOORBELL_HIT, 1);
++	WREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL, data);
++
++	WREG32_SOC15(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL, 0);
++
++	WREG32_SOC15(GC, 0, regCP_HQD_PQ_WPTR_LO, 0);
++	WREG32_SOC15(GC, 0, regCP_HQD_PQ_WPTR_HI, 0);
++	WREG32_SOC15(GC, 0, regCP_HQD_PQ_RPTR, 0);
++
++	soc21_grbm_select(adev, 0, 0, 0, 0);
++	mutex_unlock(&adev->srbm_mutex);
++
++	adev->mes.ring.sched.ready = false;
++}
++
+ static void mes_v11_0_kiq_setting(struct amdgpu_ring *ring)
+ {
+ 	uint32_t tmp;
+@@ -1196,6 +1232,9 @@ failure:
+ 
+ static int mes_v11_0_kiq_hw_fini(struct amdgpu_device *adev)
+ {
++	if (adev->mes.ring.sched.ready)
++		mes_v11_0_kiq_dequeue_sched(adev);
++
+ 	mes_v11_0_enable(adev, false);
+ 	return 0;
+ }
+@@ -1251,9 +1290,6 @@ failure:
+ 
+ static int mes_v11_0_hw_fini(void *handle)
+ {
+-	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+-
+-	adev->mes.ring.sched.ready = false;
+ 	return 0;
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+index 6d721fadcbee6..7f5e039893e89 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+@@ -847,7 +847,7 @@ static const struct resource_caps res_cap_dcn314 = {
+ 	.num_ddc = 5,
+ 	.num_vmid = 16,
+ 	.num_mpc_3dlut = 2,
+-	.num_dsc = 3,
++	.num_dsc = 4,
+ };
+ 
+ static const struct dc_plane_cap plane_cap = {
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+index b6369758b4912..aa976fe4d426d 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+@@ -119,15 +119,15 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = {
+ 		},
+ 	},
+ 	.num_states = 1,
+-	.sr_exit_time_us = 12.36,
+-	.sr_enter_plus_exit_time_us = 16.72,
++	.sr_exit_time_us = 19.95,
++	.sr_enter_plus_exit_time_us = 24.36,
+ 	.sr_exit_z8_time_us = 285.0,
+ 	.sr_enter_plus_exit_z8_time_us = 320,
+ 	.writeback_latency_us = 12.0,
+ 	.round_trip_ping_latency_dcfclk_cycles = 263,
+-	.urgent_latency_pixel_data_only_us = 4.0,
+-	.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
+-	.urgent_latency_vm_data_only_us = 4.0,
++	.urgent_latency_pixel_data_only_us = 9.35,
++	.urgent_latency_pixel_mixed_with_vm_data_us = 9.35,
++	.urgent_latency_vm_data_only_us = 9.35,
+ 	.fclk_change_latency_us = 20,
+ 	.usr_retraining_latency_us = 2,
+ 	.smn_latency_us = 2,
+diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
+index e85364dff4e04..5cb3e8634739d 100644
+--- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
++++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h
+@@ -262,8 +262,9 @@ struct kfd2kgd_calls {
+ 				uint32_t queue_id);
+ 
+ 	int (*hqd_destroy)(struct amdgpu_device *adev, void *mqd,
+-				uint32_t reset_type, unsigned int timeout,
+-				uint32_t pipe_id, uint32_t queue_id);
++				enum kfd_preempt_type reset_type,
++				unsigned int timeout, uint32_t pipe_id,
++				uint32_t queue_id);
+ 
+ 	bool (*hqd_sdma_is_occupied)(struct amdgpu_device *adev, void *mqd);
+ 
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+index 93f9b8377539a..750d8da84fac4 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+@@ -210,7 +210,8 @@ int smu_v13_0_init_pptable_microcode(struct smu_context *smu)
+ 		return 0;
+ 
+ 	if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 7)) ||
+-	    (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 0)))
++	    (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 0)) ||
++	    (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 10)))
+ 		return 0;
+ 
+ 	/* override pptable_id from driver parameter */
+diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
+index 19122bc6d2aba..b5f65b093c106 100644
+--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
++++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
+@@ -2747,13 +2747,10 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
+ 	if (!intel_sdvo_connector)
+ 		return false;
+ 
+-	if (device == 0) {
+-		intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0;
++	if (device == 0)
+ 		intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0;
+-	} else if (device == 1) {
+-		intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1;
++	else if (device == 1)
+ 		intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1;
+-	}
+ 
+ 	intel_connector = &intel_sdvo_connector->base;
+ 	connector = &intel_connector->base;
+@@ -2808,7 +2805,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
+ 	encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
+ 	connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
+ 
+-	intel_sdvo->controlled_output |= type;
+ 	intel_sdvo_connector->output_flag = type;
+ 
+ 	if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+@@ -2849,13 +2845,10 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
+ 	encoder->encoder_type = DRM_MODE_ENCODER_DAC;
+ 	connector->connector_type = DRM_MODE_CONNECTOR_VGA;
+ 
+-	if (device == 0) {
+-		intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0;
++	if (device == 0)
+ 		intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0;
+-	} else if (device == 1) {
+-		intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1;
++	else if (device == 1)
+ 		intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
+-	}
+ 
+ 	if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+ 		kfree(intel_sdvo_connector);
+@@ -2885,13 +2878,10 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
+ 	encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
+ 	connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
+ 
+-	if (device == 0) {
+-		intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0;
++	if (device == 0)
+ 		intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0;
+-	} else if (device == 1) {
+-		intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1;
++	else if (device == 1)
+ 		intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
+-	}
+ 
+ 	if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
+ 		kfree(intel_sdvo_connector);
+@@ -2926,16 +2916,39 @@ err:
+ 	return false;
+ }
+ 
++static u16 intel_sdvo_filter_output_flags(u16 flags)
++{
++	flags &= SDVO_OUTPUT_MASK;
++
++	/* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
++	if (!(flags & SDVO_OUTPUT_TMDS0))
++		flags &= ~SDVO_OUTPUT_TMDS1;
++
++	if (!(flags & SDVO_OUTPUT_RGB0))
++		flags &= ~SDVO_OUTPUT_RGB1;
++
++	if (!(flags & SDVO_OUTPUT_LVDS0))
++		flags &= ~SDVO_OUTPUT_LVDS1;
++
++	return flags;
++}
++
+ static bool
+ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags)
+ {
+-	/* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
++	struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev);
++
++	flags = intel_sdvo_filter_output_flags(flags);
++
++	intel_sdvo->controlled_output = flags;
++
++	intel_sdvo_select_ddc_bus(i915, intel_sdvo);
+ 
+ 	if (flags & SDVO_OUTPUT_TMDS0)
+ 		if (!intel_sdvo_dvi_init(intel_sdvo, 0))
+ 			return false;
+ 
+-	if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK)
++	if (flags & SDVO_OUTPUT_TMDS1)
+ 		if (!intel_sdvo_dvi_init(intel_sdvo, 1))
+ 			return false;
+ 
+@@ -2956,7 +2969,7 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags)
+ 		if (!intel_sdvo_analog_init(intel_sdvo, 0))
+ 			return false;
+ 
+-	if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK)
++	if (flags & SDVO_OUTPUT_RGB1)
+ 		if (!intel_sdvo_analog_init(intel_sdvo, 1))
+ 			return false;
+ 
+@@ -2964,14 +2977,13 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags)
+ 		if (!intel_sdvo_lvds_init(intel_sdvo, 0))
+ 			return false;
+ 
+-	if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK)
++	if (flags & SDVO_OUTPUT_LVDS1)
+ 		if (!intel_sdvo_lvds_init(intel_sdvo, 1))
+ 			return false;
+ 
+-	if ((flags & SDVO_OUTPUT_MASK) == 0) {
++	if (flags == 0) {
+ 		unsigned char bytes[2];
+ 
+-		intel_sdvo->controlled_output = 0;
+ 		memcpy(bytes, &intel_sdvo->caps.output_flags, 2);
+ 		DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
+ 			      SDVO_NAME(intel_sdvo),
+@@ -3383,8 +3395,6 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
+ 	 */
+ 	intel_sdvo->base.cloneable = 0;
+ 
+-	intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo);
+-
+ 	/* Set the input timing to the screen. Assume always input 0. */
+ 	if (!intel_sdvo_set_target_input(intel_sdvo))
+ 		goto err_output;
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+index c698f95af15fe..629acb403a2c9 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+@@ -6,7 +6,6 @@
+ 
+ #include <linux/scatterlist.h>
+ #include <linux/slab.h>
+-#include <linux/swiotlb.h>
+ 
+ #include "i915_drv.h"
+ #include "i915_gem.h"
+@@ -38,22 +37,12 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
+ 	struct scatterlist *sg;
+ 	unsigned int sg_page_sizes;
+ 	unsigned int npages;
+-	int max_order;
++	int max_order = MAX_ORDER;
++	unsigned int max_segment;
+ 	gfp_t gfp;
+ 
+-	max_order = MAX_ORDER;
+-#ifdef CONFIG_SWIOTLB
+-	if (is_swiotlb_active(obj->base.dev->dev)) {
+-		unsigned int max_segment;
+-
+-		max_segment = swiotlb_max_segment();
+-		if (max_segment) {
+-			max_segment = max_t(unsigned int, max_segment,
+-					    PAGE_SIZE) >> PAGE_SHIFT;
+-			max_order = min(max_order, ilog2(max_segment));
+-		}
+-	}
+-#endif
++	max_segment = i915_sg_segment_size(i915->drm.dev) >> PAGE_SHIFT;
++	max_order = min(max_order, get_order(max_segment));
+ 
+ 	gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_RECLAIMABLE;
+ 	if (IS_I965GM(i915) || IS_I965G(i915)) {
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+index 4eed3dd90ba8b..34b9c76cd8e66 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+@@ -194,7 +194,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
+ 	struct intel_memory_region *mem = obj->mm.region;
+ 	struct address_space *mapping = obj->base.filp->f_mapping;
+ 	const unsigned long page_count = obj->base.size / PAGE_SIZE;
+-	unsigned int max_segment = i915_sg_segment_size();
++	unsigned int max_segment = i915_sg_segment_size(i915->drm.dev);
+ 	struct sg_table *st;
+ 	struct sgt_iter sgt_iter;
+ 	struct page *page;
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+index 6f3ab7ade41ad..e85cfc36359a4 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+@@ -189,7 +189,7 @@ static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev,
+ 	struct drm_i915_private *i915 = container_of(bdev, typeof(*i915), bdev);
+ 	struct intel_memory_region *mr = i915->mm.regions[INTEL_MEMORY_SYSTEM];
+ 	struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
+-	const unsigned int max_segment = i915_sg_segment_size();
++	const unsigned int max_segment = i915_sg_segment_size(i915->drm.dev);
+ 	const size_t size = (size_t)ttm->num_pages << PAGE_SHIFT;
+ 	struct file *filp = i915_tt->filp;
+ 	struct sgt_iter sgt_iter;
+@@ -568,7 +568,7 @@ static struct i915_refct_sgt *i915_ttm_tt_get_st(struct ttm_tt *ttm)
+ 	ret = sg_alloc_table_from_pages_segment(st,
+ 			ttm->pages, ttm->num_pages,
+ 			0, (unsigned long)ttm->num_pages << PAGE_SHIFT,
+-			i915_sg_segment_size(), GFP_KERNEL);
++			i915_sg_segment_size(i915_tt->dev), GFP_KERNEL);
+ 	if (ret) {
+ 		st->sgl = NULL;
+ 		return ERR_PTR(ret);
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
+index 8423df021b713..e4515d6acd43c 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
+@@ -129,7 +129,7 @@ static void i915_gem_object_userptr_drop_ref(struct drm_i915_gem_object *obj)
+ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj)
+ {
+ 	const unsigned long num_pages = obj->base.size >> PAGE_SHIFT;
+-	unsigned int max_segment = i915_sg_segment_size();
++	unsigned int max_segment = i915_sg_segment_size(obj->base.dev->dev);
+ 	struct sg_table *st;
+ 	unsigned int sg_page_sizes;
+ 	struct page **pvec;
+diff --git a/drivers/gpu/drm/i915/i915_scatterlist.h b/drivers/gpu/drm/i915/i915_scatterlist.h
+index 9ddb3e743a3e5..b0a1db44f8950 100644
+--- a/drivers/gpu/drm/i915/i915_scatterlist.h
++++ b/drivers/gpu/drm/i915/i915_scatterlist.h
+@@ -9,7 +9,8 @@
+ 
+ #include <linux/pfn.h>
+ #include <linux/scatterlist.h>
+-#include <linux/swiotlb.h>
++#include <linux/dma-mapping.h>
++#include <xen/xen.h>
+ 
+ #include "i915_gem.h"
+ 
+@@ -127,19 +128,26 @@ static inline unsigned int i915_sg_dma_sizes(struct scatterlist *sg)
+ 	return page_sizes;
+ }
+ 
+-static inline unsigned int i915_sg_segment_size(void)
++static inline unsigned int i915_sg_segment_size(struct device *dev)
+ {
+-	unsigned int size = swiotlb_max_segment();
+-
+-	if (size == 0)
+-		size = UINT_MAX;
+-
+-	size = rounddown(size, PAGE_SIZE);
+-	/* swiotlb_max_segment_size can return 1 byte when it means one page. */
+-	if (size < PAGE_SIZE)
+-		size = PAGE_SIZE;
+-
+-	return size;
++	size_t max = min_t(size_t, UINT_MAX, dma_max_mapping_size(dev));
++
++	/*
++	 * For Xen PV guests pages aren't contiguous in DMA (machine) address
++	 * space.  The DMA API takes care of that both in dma_alloc_* (by
++	 * calling into the hypervisor to make the pages contiguous) and in
++	 * dma_map_* (by bounce buffering).  But i915 abuses ignores the
++	 * coherency aspects of the DMA API and thus can't cope with bounce
++	 * buffering actually happening, so add a hack here to force small
++	 * allocations and mappings when running in PV mode on Xen.
++	 *
++	 * Note this will still break if bounce buffering is required for other
++	 * reasons, like confidential computing hypervisors or PCIe root ports
++	 * with addressing limitations.
++	 */
++	if (xen_pv_domain())
++		max = PAGE_SIZE;
++	return round_down(max, PAGE_SIZE);
+ }
+ 
+ bool i915_sg_trim(struct sg_table *orig_st);
+diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+index 110e83aad9bb4..1aa3700551f4d 100644
+--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+@@ -1031,23 +1031,31 @@ static int dw_mipi_dsi_rockchip_host_attach(void *priv_data,
+ 	if (ret) {
+ 		DRM_DEV_ERROR(dsi->dev, "Failed to register component: %d\n",
+ 					ret);
+-		return ret;
++		goto out;
+ 	}
+ 
+ 	second = dw_mipi_dsi_rockchip_find_second(dsi);
+-	if (IS_ERR(second))
+-		return PTR_ERR(second);
++	if (IS_ERR(second)) {
++		ret = PTR_ERR(second);
++		goto out;
++	}
+ 	if (second) {
+ 		ret = component_add(second, &dw_mipi_dsi_rockchip_ops);
+ 		if (ret) {
+ 			DRM_DEV_ERROR(second,
+ 				      "Failed to register component: %d\n",
+ 				      ret);
+-			return ret;
++			goto out;
+ 		}
+ 	}
+ 
+ 	return 0;
++
++out:
++	mutex_lock(&dsi->usage_mutex);
++	dsi->usage_mode = DW_DSI_USAGE_IDLE;
++	mutex_unlock(&dsi->usage_mutex);
++	return ret;
+ }
+ 
+ static int dw_mipi_dsi_rockchip_host_detach(void *priv_data,
+@@ -1634,5 +1642,11 @@ struct platform_driver dw_mipi_dsi_rockchip_driver = {
+ 		.of_match_table = dw_mipi_dsi_rockchip_dt_ids,
+ 		.pm	= &dw_mipi_dsi_rockchip_pm_ops,
+ 		.name	= "dw-mipi-dsi-rockchip",
++		/*
++		 * For dual-DSI display, one DSI pokes at the other DSI's
++		 * drvdata in dw_mipi_dsi_rockchip_find_second(). This is not
++		 * safe for asynchronous probe.
++		 */
++		.probe_type = PROBE_FORCE_SYNCHRONOUS,
+ 	},
+ };
+diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+index c14f888938688..2f4b8f64cbad3 100644
+--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
++++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+@@ -565,7 +565,8 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
+ 
+ 	ret = rockchip_hdmi_parse_dt(hdmi);
+ 	if (ret) {
+-		DRM_DEV_ERROR(hdmi->dev, "Unable to parse OF data\n");
++		if (ret != -EPROBE_DEFER)
++			DRM_DEV_ERROR(hdmi->dev, "Unable to parse OF data\n");
+ 		return ret;
+ 	}
+ 
+diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+index 985584147da10..cf8322c300bd5 100644
+--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
++++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+@@ -364,9 +364,12 @@ rockchip_gem_create_with_handle(struct drm_file *file_priv,
+ {
+ 	struct rockchip_gem_object *rk_obj;
+ 	struct drm_gem_object *obj;
++	bool is_framebuffer;
+ 	int ret;
+ 
+-	rk_obj = rockchip_gem_create_object(drm, size, false);
++	is_framebuffer = drm->fb_helper && file_priv == drm->fb_helper->client.file;
++
++	rk_obj = rockchip_gem_create_object(drm, size, is_framebuffer);
+ 	if (IS_ERR(rk_obj))
+ 		return ERR_CAST(rk_obj);
+ 
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 780a19a75c3f5..874c6bd787c56 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -2869,6 +2869,7 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
+ 	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+ 	unsigned long __maybe_unused flags;
+ 	u32 __maybe_unused value;
++	unsigned long rate;
+ 	int ret;
+ 
+ 	/*
+@@ -2884,6 +2885,21 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
+ 	if (ret)
+ 		return ret;
+ 
++	/*
++	 * Whenever the RaspberryPi boots without an HDMI monitor
++	 * plugged in, the firmware won't have initialized the HSM clock
++	 * rate and it will be reported as 0.
++	 *
++	 * If we try to access a register of the controller in such a
++	 * case, it will lead to a silent CPU stall. Let's make sure we
++	 * prevent such a case.
++	 */
++	rate = clk_get_rate(vc4_hdmi->hsm_clock);
++	if (!rate) {
++		ret = -EINVAL;
++		goto err_disable_clk;
++	}
++
+ 	if (vc4_hdmi->variant->reset)
+ 		vc4_hdmi->variant->reset(vc4_hdmi);
+ 
+@@ -2905,6 +2921,10 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
+ #endif
+ 
+ 	return 0;
++
++err_disable_clk:
++	clk_disable_unprepare(vc4_hdmi->hsm_clock);
++	return ret;
+ }
+ 
+ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 043cf1cc87946..256795ed6247e 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -867,6 +867,7 @@
+ #define USB_DEVICE_ID_MADCATZ_BEATPAD	0x4540
+ #define USB_DEVICE_ID_MADCATZ_RAT5	0x1705
+ #define USB_DEVICE_ID_MADCATZ_RAT9	0x1709
++#define USB_DEVICE_ID_MADCATZ_MMO7  0x1713
+ 
+ #define USB_VENDOR_ID_MCC		0x09db
+ #define USB_DEVICE_ID_MCC_PMD1024LS	0x0076
+diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
+index 70f602c64fd13..50e1c717fc0a3 100644
+--- a/drivers/hid/hid-quirks.c
++++ b/drivers/hid/hid-quirks.c
+@@ -620,6 +620,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT5) },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) },
++	{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_MMO7) },
+ #endif
+ #if IS_ENABLED(CONFIG_HID_SAMSUNG)
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
+diff --git a/drivers/hid/hid-saitek.c b/drivers/hid/hid-saitek.c
+index c7bf14c019605..b84e975977c42 100644
+--- a/drivers/hid/hid-saitek.c
++++ b/drivers/hid/hid-saitek.c
+@@ -187,6 +187,8 @@ static const struct hid_device_id saitek_devices[] = {
+ 		.driver_data = SAITEK_RELEASE_MODE_RAT7 },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7),
+ 		.driver_data = SAITEK_RELEASE_MODE_MMO7 },
++	{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_MMO7),
++		.driver_data = SAITEK_RELEASE_MODE_MMO7 },
+ 	{ }
+ };
+ 
+diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
+index 39cb1b7bb8656..809fbd014cd68 100644
+--- a/drivers/i2c/busses/i2c-piix4.c
++++ b/drivers/i2c/busses/i2c-piix4.c
+@@ -1080,6 +1080,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
+ 					   "", &piix4_main_adapters[0]);
+ 		if (retval < 0)
+ 			return retval;
++		piix4_adapter_count = 1;
+ 	}
+ 
+ 	/* Check for auxiliary SMBus on some AMD chipsets */
+diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
+index b3fe6b2aa3ca9..277a02455cddd 100644
+--- a/drivers/i2c/busses/i2c-xiic.c
++++ b/drivers/i2c/busses/i2c-xiic.c
+@@ -920,6 +920,7 @@ static struct platform_driver xiic_i2c_driver = {
+ 
+ module_platform_driver(xiic_i2c_driver);
+ 
++MODULE_ALIAS("platform:" DRIVER_NAME);
+ MODULE_AUTHOR("info@mocean-labs.com");
+ MODULE_DESCRIPTION("Xilinx I2C bus driver");
+ MODULE_LICENSE("GPL v2");
+diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
+index 130e8dd6f0c89..7719f7f93c3f0 100644
+--- a/drivers/iio/adc/stm32-adc.c
++++ b/drivers/iio/adc/stm32-adc.c
+@@ -2064,18 +2064,19 @@ static int stm32_adc_generic_chan_init(struct iio_dev *indio_dev,
+ 		stm32_adc_chan_init_one(indio_dev, &channels[scan_index], val,
+ 					vin[1], scan_index, differential);
+ 
++		val = 0;
+ 		ret = of_property_read_u32(child, "st,min-sample-time-ns", &val);
+ 		/* st,min-sample-time-ns is optional */
+-		if (!ret) {
+-			stm32_adc_smpr_init(adc, channels[scan_index].channel, val);
+-			if (differential)
+-				stm32_adc_smpr_init(adc, vin[1], val);
+-		} else if (ret != -EINVAL) {
++		if (ret && ret != -EINVAL) {
+ 			dev_err(&indio_dev->dev, "Invalid st,min-sample-time-ns property %d\n",
+ 				ret);
+ 			goto err;
+ 		}
+ 
++		stm32_adc_smpr_init(adc, channels[scan_index].channel, val);
++		if (differential)
++			stm32_adc_smpr_init(adc, vin[1], val);
++
+ 		scan_index++;
+ 	}
+ 
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index be317f2665a9e..ff8821f79feca 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -1556,7 +1556,7 @@ static bool validate_ipv4_net_dev(struct net_device *net_dev,
+ 		return false;
+ 
+ 	memset(&fl4, 0, sizeof(fl4));
+-	fl4.flowi4_iif = net_dev->ifindex;
++	fl4.flowi4_oif = net_dev->ifindex;
+ 	fl4.daddr = daddr;
+ 	fl4.saddr = saddr;
+ 
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
+index d275db195f1a1..4053a09b8d33e 100644
+--- a/drivers/infiniband/core/device.c
++++ b/drivers/infiniband/core/device.c
+@@ -2815,10 +2815,18 @@ static int __init ib_core_init(void)
+ 
+ 	nldev_init();
+ 	rdma_nl_register(RDMA_NL_LS, ibnl_ls_cb_table);
+-	roce_gid_mgmt_init();
++	ret = roce_gid_mgmt_init();
++	if (ret) {
++		pr_warn("Couldn't init RoCE GID management\n");
++		goto err_parent;
++	}
+ 
+ 	return 0;
+ 
++err_parent:
++	rdma_nl_unregister(RDMA_NL_LS);
++	nldev_exit();
++	unregister_pernet_device(&rdma_dev_net_ops);
+ err_compat:
+ 	unregister_blocking_lsm_notifier(&ibdev_lsm_nb);
+ err_sa:
+diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
+index b92358f606d00..12dc97067ed2b 100644
+--- a/drivers/infiniband/core/nldev.c
++++ b/drivers/infiniband/core/nldev.c
+@@ -2537,7 +2537,7 @@ void __init nldev_init(void)
+ 	rdma_nl_register(RDMA_NL_NLDEV, nldev_cb_table);
+ }
+ 
+-void __exit nldev_exit(void)
++void nldev_exit(void)
+ {
+ 	rdma_nl_unregister(RDMA_NL_NLDEV);
+ }
+diff --git a/drivers/infiniband/hw/hfi1/pio.c b/drivers/infiniband/hw/hfi1/pio.c
+index 3d42bd2b36bd4..51ae58c02b15c 100644
+--- a/drivers/infiniband/hw/hfi1/pio.c
++++ b/drivers/infiniband/hw/hfi1/pio.c
+@@ -913,8 +913,7 @@ void sc_disable(struct send_context *sc)
+ 	spin_unlock(&sc->release_lock);
+ 
+ 	write_seqlock(&sc->waitlock);
+-	if (!list_empty(&sc->piowait))
+-		list_move(&sc->piowait, &wake_list);
++	list_splice_init(&sc->piowait, &wake_list);
+ 	write_sequnlock(&sc->waitlock);
+ 	while (!list_empty(&wake_list)) {
+ 		struct iowait *wait;
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+index c780646bd60ac..105888c6ccb77 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -118,7 +118,6 @@ static const u32 hns_roce_op_code[] = {
+ 	HR_OPC_MAP(ATOMIC_CMP_AND_SWP,		ATOM_CMP_AND_SWAP),
+ 	HR_OPC_MAP(ATOMIC_FETCH_AND_ADD,	ATOM_FETCH_AND_ADD),
+ 	HR_OPC_MAP(SEND_WITH_INV,		SEND_WITH_INV),
+-	HR_OPC_MAP(LOCAL_INV,			LOCAL_INV),
+ 	HR_OPC_MAP(MASKED_ATOMIC_CMP_AND_SWP,	ATOM_MSK_CMP_AND_SWAP),
+ 	HR_OPC_MAP(MASKED_ATOMIC_FETCH_AND_ADD,	ATOM_MSK_FETCH_AND_ADD),
+ 	HR_OPC_MAP(REG_MR,			FAST_REG_PMR),
+@@ -560,9 +559,6 @@ static int set_rc_opcode(struct hns_roce_dev *hr_dev,
+ 		else
+ 			ret = -EOPNOTSUPP;
+ 		break;
+-	case IB_WR_LOCAL_INV:
+-		hr_reg_enable(rc_sq_wqe, RC_SEND_WQE_SO);
+-		fallthrough;
+ 	case IB_WR_SEND_WITH_INV:
+ 		rc_sq_wqe->inv_key = cpu_to_le32(wr->ex.invalidate_rkey);
+ 		break;
+@@ -2809,8 +2805,12 @@ static int free_mr_modify_qp(struct hns_roce_dev *hr_dev)
+ 
+ static int free_mr_init(struct hns_roce_dev *hr_dev)
+ {
++	struct hns_roce_v2_priv *priv = hr_dev->priv;
++	struct hns_roce_v2_free_mr *free_mr = &priv->free_mr;
+ 	int ret;
+ 
++	mutex_init(&free_mr->mutex);
++
+ 	ret = free_mr_alloc_res(hr_dev);
+ 	if (ret)
+ 		return ret;
+@@ -3226,7 +3226,6 @@ static int hns_roce_v2_write_mtpt(struct hns_roce_dev *hr_dev,
+ 
+ 	hr_reg_write(mpt_entry, MPT_ST, V2_MPT_ST_VALID);
+ 	hr_reg_write(mpt_entry, MPT_PD, mr->pd);
+-	hr_reg_enable(mpt_entry, MPT_L_INV_EN);
+ 
+ 	hr_reg_write_bool(mpt_entry, MPT_BIND_EN,
+ 			  mr->access & IB_ACCESS_MW_BIND);
+@@ -3317,7 +3316,6 @@ static int hns_roce_v2_frmr_write_mtpt(struct hns_roce_dev *hr_dev,
+ 
+ 	hr_reg_enable(mpt_entry, MPT_RA_EN);
+ 	hr_reg_enable(mpt_entry, MPT_R_INV_EN);
+-	hr_reg_enable(mpt_entry, MPT_L_INV_EN);
+ 
+ 	hr_reg_enable(mpt_entry, MPT_FRE);
+ 	hr_reg_clear(mpt_entry, MPT_MR_MW);
+@@ -3349,7 +3347,6 @@ static int hns_roce_v2_mw_write_mtpt(void *mb_buf, struct hns_roce_mw *mw)
+ 	hr_reg_write(mpt_entry, MPT_PD, mw->pdn);
+ 
+ 	hr_reg_enable(mpt_entry, MPT_R_INV_EN);
+-	hr_reg_enable(mpt_entry, MPT_L_INV_EN);
+ 	hr_reg_enable(mpt_entry, MPT_LW_EN);
+ 
+ 	hr_reg_enable(mpt_entry, MPT_MR_MW);
+@@ -3798,7 +3795,6 @@ static const u32 wc_send_op_map[] = {
+ 	HR_WC_OP_MAP(RDMA_READ,			RDMA_READ),
+ 	HR_WC_OP_MAP(RDMA_WRITE,		RDMA_WRITE),
+ 	HR_WC_OP_MAP(RDMA_WRITE_WITH_IMM,	RDMA_WRITE),
+-	HR_WC_OP_MAP(LOCAL_INV,			LOCAL_INV),
+ 	HR_WC_OP_MAP(ATOM_CMP_AND_SWAP,		COMP_SWAP),
+ 	HR_WC_OP_MAP(ATOM_FETCH_AND_ADD,	FETCH_ADD),
+ 	HR_WC_OP_MAP(ATOM_MSK_CMP_AND_SWAP,	MASKED_COMP_SWAP),
+@@ -3848,9 +3844,6 @@ static void fill_send_wc(struct ib_wc *wc, struct hns_roce_v2_cqe *cqe)
+ 	case HNS_ROCE_V2_WQE_OP_RDMA_WRITE_WITH_IMM:
+ 		wc->wc_flags |= IB_WC_WITH_IMM;
+ 		break;
+-	case HNS_ROCE_V2_WQE_OP_LOCAL_INV:
+-		wc->wc_flags |= IB_WC_WITH_INVALIDATE;
+-		break;
+ 	case HNS_ROCE_V2_WQE_OP_ATOM_CMP_AND_SWAP:
+ 	case HNS_ROCE_V2_WQE_OP_ATOM_FETCH_AND_ADD:
+ 	case HNS_ROCE_V2_WQE_OP_ATOM_MSK_CMP_AND_SWAP:
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+index 64797109bab63..4544a8775ce5a 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+@@ -182,7 +182,6 @@ enum {
+ 	HNS_ROCE_V2_WQE_OP_ATOM_MSK_CMP_AND_SWAP	= 0x8,
+ 	HNS_ROCE_V2_WQE_OP_ATOM_MSK_FETCH_AND_ADD	= 0x9,
+ 	HNS_ROCE_V2_WQE_OP_FAST_REG_PMR			= 0xa,
+-	HNS_ROCE_V2_WQE_OP_LOCAL_INV			= 0xb,
+ 	HNS_ROCE_V2_WQE_OP_BIND_MW			= 0xc,
+ 	HNS_ROCE_V2_WQE_OP_MASK				= 0x1f,
+ };
+@@ -916,7 +915,6 @@ struct hns_roce_v2_rc_send_wqe {
+ #define RC_SEND_WQE_OWNER RC_SEND_WQE_FIELD_LOC(7, 7)
+ #define RC_SEND_WQE_CQE RC_SEND_WQE_FIELD_LOC(8, 8)
+ #define RC_SEND_WQE_FENCE RC_SEND_WQE_FIELD_LOC(9, 9)
+-#define RC_SEND_WQE_SO RC_SEND_WQE_FIELD_LOC(10, 10)
+ #define RC_SEND_WQE_SE RC_SEND_WQE_FIELD_LOC(11, 11)
+ #define RC_SEND_WQE_INLINE RC_SEND_WQE_FIELD_LOC(12, 12)
+ #define RC_SEND_WQE_WQE_INDEX RC_SEND_WQE_FIELD_LOC(30, 15)
+diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c
+index 5152f10d2e6de..ba0c3e4c07d85 100644
+--- a/drivers/infiniband/hw/qedr/main.c
++++ b/drivers/infiniband/hw/qedr/main.c
+@@ -344,6 +344,10 @@ static int qedr_alloc_resources(struct qedr_dev *dev)
+ 	if (IS_IWARP(dev)) {
+ 		xa_init(&dev->qps);
+ 		dev->iwarp_wq = create_singlethread_workqueue("qedr_iwarpq");
++		if (!dev->iwarp_wq) {
++			rc = -ENOMEM;
++			goto err1;
++		}
+ 	}
+ 
+ 	/* Allocate Status blocks for CNQ */
+@@ -351,7 +355,7 @@ static int qedr_alloc_resources(struct qedr_dev *dev)
+ 				GFP_KERNEL);
+ 	if (!dev->sb_array) {
+ 		rc = -ENOMEM;
+-		goto err1;
++		goto err_destroy_wq;
+ 	}
+ 
+ 	dev->cnq_array = kcalloc(dev->num_cnq,
+@@ -402,6 +406,9 @@ err3:
+ 	kfree(dev->cnq_array);
+ err2:
+ 	kfree(dev->sb_array);
++err_destroy_wq:
++	if (IS_IWARP(dev))
++		destroy_workqueue(dev->iwarp_wq);
+ err1:
+ 	kfree(dev->sgid_tbl);
+ 	return rc;
+diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
+index 7c336db5cb547..f8b1d9fa04941 100644
+--- a/drivers/infiniband/sw/rxe/rxe_resp.c
++++ b/drivers/infiniband/sw/rxe/rxe_resp.c
+@@ -806,8 +806,10 @@ static enum resp_states read_reply(struct rxe_qp *qp,
+ 
+ 	skb = prepare_ack_packet(qp, &ack_pkt, opcode, payload,
+ 				 res->cur_psn, AETH_ACK_UNLIMITED);
+-	if (!skb)
++	if (!skb) {
++		rxe_put(mr);
+ 		return RESPST_ERR_RNR;
++	}
+ 
+ 	rxe_mr_copy(mr, res->read.va, payload_addr(&ack_pkt),
+ 		    payload, RXE_FROM_MR_OBJ);
+diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
+index a52f275f82634..f8447135a9022 100644
+--- a/drivers/isdn/hardware/mISDN/netjet.c
++++ b/drivers/isdn/hardware/mISDN/netjet.c
+@@ -956,7 +956,7 @@ nj_release(struct tiger_hw *card)
+ 	}
+ 	if (card->irq > 0)
+ 		free_irq(card->irq, card);
+-	if (card->isac.dch.dev.dev.class)
++	if (device_is_registered(&card->isac.dch.dev.dev))
+ 		mISDN_unregister_device(&card->isac.dch.dev);
+ 
+ 	for (i = 0; i < 2; i++) {
+diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
+index a41b4b2645941..7ea0100f218a0 100644
+--- a/drivers/isdn/mISDN/core.c
++++ b/drivers/isdn/mISDN/core.c
+@@ -233,11 +233,12 @@ mISDN_register_device(struct mISDNdevice *dev,
+ 	if (debug & DEBUG_CORE)
+ 		printk(KERN_DEBUG "mISDN_register %s %d\n",
+ 		       dev_name(&dev->dev), dev->id);
++	dev->dev.class = &mISDN_class;
++
+ 	err = create_stack(dev);
+ 	if (err)
+ 		goto error1;
+ 
+-	dev->dev.class = &mISDN_class;
+ 	dev->dev.platform_data = dev;
+ 	dev->dev.parent = parent;
+ 	dev_set_drvdata(&dev->dev, dev);
+@@ -249,8 +250,8 @@ mISDN_register_device(struct mISDNdevice *dev,
+ 
+ error3:
+ 	delete_stack(dev);
+-	return err;
+ error1:
++	put_device(&dev->dev);
+ 	return err;
+ 
+ }
+diff --git a/drivers/media/cec/platform/cros-ec/cros-ec-cec.c b/drivers/media/cec/platform/cros-ec/cros-ec-cec.c
+index 3b583ed4da9df..6ebedc71d67d4 100644
+--- a/drivers/media/cec/platform/cros-ec/cros-ec-cec.c
++++ b/drivers/media/cec/platform/cros-ec/cros-ec-cec.c
+@@ -44,6 +44,8 @@ static void handle_cec_message(struct cros_ec_cec *cros_ec_cec)
+ 	uint8_t *cec_message = cros_ec->event_data.data.cec_message;
+ 	unsigned int len = cros_ec->event_size;
+ 
++	if (len > CEC_MAX_MSG_SIZE)
++		len = CEC_MAX_MSG_SIZE;
+ 	cros_ec_cec->rx_msg.len = len;
+ 	memcpy(cros_ec_cec->rx_msg.msg, cec_message, len);
+ 
+@@ -221,6 +223,8 @@ static const struct cec_dmi_match cec_dmi_match_table[] = {
+ 	{ "Google", "Moli", "0000:00:02.0", "Port B" },
+ 	/* Google Kinox */
+ 	{ "Google", "Kinox", "0000:00:02.0", "Port B" },
++	/* Google Kuldax */
++	{ "Google", "Kuldax", "0000:00:02.0", "Port B" },
+ };
+ 
+ static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev,
+diff --git a/drivers/media/cec/platform/s5p/s5p_cec.c b/drivers/media/cec/platform/s5p/s5p_cec.c
+index ce9a9d922f116..0a30e7acdc10e 100644
+--- a/drivers/media/cec/platform/s5p/s5p_cec.c
++++ b/drivers/media/cec/platform/s5p/s5p_cec.c
+@@ -115,6 +115,8 @@ static irqreturn_t s5p_cec_irq_handler(int irq, void *priv)
+ 				dev_dbg(cec->dev, "Buffer overrun (worker did not process previous message)\n");
+ 			cec->rx = STATE_BUSY;
+ 			cec->msg.len = status >> 24;
++			if (cec->msg.len > CEC_MAX_MSG_SIZE)
++				cec->msg.len = CEC_MAX_MSG_SIZE;
+ 			cec->msg.rx_status = CEC_RX_STATUS_OK;
+ 			s5p_cec_get_rx_buf(cec, cec->msg.len,
+ 					cec->msg.msg);
+diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
+index 9430295a8175c..ef0d063ec3526 100644
+--- a/drivers/media/dvb-frontends/drxk_hard.c
++++ b/drivers/media/dvb-frontends/drxk_hard.c
+@@ -6660,7 +6660,7 @@ static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
+ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+ {
+ 	struct drxk_state *state = fe->demodulator_priv;
+-	u16 err;
++	u16 err = 0;
+ 
+ 	dprintk(1, "\n");
+ 
+diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
+index d5904c96ff3fc..c66963a2ccd99 100644
+--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-capture.c
+@@ -1273,11 +1273,12 @@ static int rkisp1_capture_link_validate(struct media_link *link)
+ 	struct rkisp1_capture *cap = video_get_drvdata(vdev);
+ 	const struct rkisp1_capture_fmt_cfg *fmt =
+ 		rkisp1_find_fmt_cfg(cap, cap->pix.fmt.pixelformat);
+-	struct v4l2_subdev_format sd_fmt;
++	struct v4l2_subdev_format sd_fmt = {
++		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
++		.pad = link->source->index,
++	};
+ 	int ret;
+ 
+-	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+-	sd_fmt.pad = link->source->index;
+ 	ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sd_fmt);
+ 	if (ret)
+ 		return ret;
+diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
+index 383a3ec83ca9f..00032b849a076 100644
+--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
+@@ -472,23 +472,43 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
+ 				   struct v4l2_mbus_framefmt *format,
+ 				   unsigned int which)
+ {
+-	const struct rkisp1_mbus_info *mbus_info;
++	const struct rkisp1_mbus_info *sink_info;
++	const struct rkisp1_mbus_info *src_info;
++	struct v4l2_mbus_framefmt *sink_fmt;
+ 	struct v4l2_mbus_framefmt *src_fmt;
+ 	const struct v4l2_rect *src_crop;
+ 
++	sink_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state,
++					  RKISP1_ISP_PAD_SINK_VIDEO, which);
+ 	src_fmt = rkisp1_isp_get_pad_fmt(isp, sd_state,
+ 					 RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+ 	src_crop = rkisp1_isp_get_pad_crop(isp, sd_state,
+ 					   RKISP1_ISP_PAD_SOURCE_VIDEO, which);
+ 
++	/*
++	 * Media bus code. The ISP can operate in pass-through mode (Bayer in,
++	 * Bayer out or YUV in, YUV out) or process Bayer data to YUV, but
++	 * can't convert from YUV to Bayer.
++	 */
++	sink_info = rkisp1_mbus_info_get_by_code(sink_fmt->code);
++
+ 	src_fmt->code = format->code;
+-	mbus_info = rkisp1_mbus_info_get_by_code(src_fmt->code);
+-	if (!mbus_info || !(mbus_info->direction & RKISP1_ISP_SD_SRC)) {
++	src_info = rkisp1_mbus_info_get_by_code(src_fmt->code);
++	if (!src_info || !(src_info->direction & RKISP1_ISP_SD_SRC)) {
+ 		src_fmt->code = RKISP1_DEF_SRC_PAD_FMT;
+-		mbus_info = rkisp1_mbus_info_get_by_code(src_fmt->code);
++		src_info = rkisp1_mbus_info_get_by_code(src_fmt->code);
+ 	}
+-	if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
+-		isp->src_fmt = mbus_info;
++
++	if (sink_info->pixel_enc == V4L2_PIXEL_ENC_YUV &&
++	    src_info->pixel_enc == V4L2_PIXEL_ENC_BAYER) {
++		src_fmt->code = sink_fmt->code;
++		src_info = sink_info;
++	}
++
++	/*
++	 * The source width and height must be identical to the source crop
++	 * size.
++	 */
+ 	src_fmt->width  = src_crop->width;
+ 	src_fmt->height = src_crop->height;
+ 
+@@ -498,14 +518,18 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
+ 	 */
+ 	if (format->flags & V4L2_MBUS_FRAMEFMT_SET_CSC &&
+ 	    format->quantization == V4L2_QUANTIZATION_FULL_RANGE &&
+-	    mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
++	    src_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
+ 		src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+-	else if (mbus_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
++	else if (src_info->pixel_enc == V4L2_PIXEL_ENC_YUV)
+ 		src_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
+ 	else
+ 		src_fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+ 
+ 	*format = *src_fmt;
++
++	/* Store the source format info when setting the active format. */
++	if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
++		isp->src_fmt = src_info;
+ }
+ 
+ static void rkisp1_isp_set_src_crop(struct rkisp1_isp *isp,
+diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
+index 9da7dc1bc6909..02ac3043badd4 100644
+--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-params.c
+@@ -343,7 +343,7 @@ static void rkisp1_lsc_config(struct rkisp1_params *params,
+ 			     RKISP1_CIF_ISP_LSC_XSIZE_01 + i * 4, data);
+ 
+ 		/* program x grad tables */
+-		data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2],
++		data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->x_grad_tbl[i * 2],
+ 						    arg->x_grad_tbl[i * 2 + 1]);
+ 		rkisp1_write(params->rkisp1,
+ 			     RKISP1_CIF_ISP_LSC_XGRAD_01 + i * 4, data);
+@@ -355,7 +355,7 @@ static void rkisp1_lsc_config(struct rkisp1_params *params,
+ 			     RKISP1_CIF_ISP_LSC_YSIZE_01 + i * 4, data);
+ 
+ 		/* program y grad tables */
+-		data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2],
++		data = RKISP1_CIF_ISP_LSC_SECT_GRAD(arg->y_grad_tbl[i * 2],
+ 						    arg->y_grad_tbl[i * 2 + 1]);
+ 		rkisp1_write(params->rkisp1,
+ 			     RKISP1_CIF_ISP_LSC_YGRAD_01 + i * 4, data);
+@@ -1066,7 +1066,7 @@ static void rkisp1_ie_enable(struct rkisp1_params *params, bool en)
+ 	}
+ }
+ 
+-static void rkisp1_csm_config(struct rkisp1_params *params, bool full_range)
++static void rkisp1_csm_config(struct rkisp1_params *params)
+ {
+ 	static const u16 full_range_coeff[] = {
+ 		0x0026, 0x004b, 0x000f,
+@@ -1080,7 +1080,7 @@ static void rkisp1_csm_config(struct rkisp1_params *params, bool full_range)
+ 	};
+ 	unsigned int i;
+ 
+-	if (full_range) {
++	if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE) {
+ 		for (i = 0; i < ARRAY_SIZE(full_range_coeff); i++)
+ 			rkisp1_write(params->rkisp1,
+ 				     RKISP1_CIF_ISP_CC_COEFF_0 + i * 4,
+@@ -1552,11 +1552,7 @@ static void rkisp1_params_config_parameter(struct rkisp1_params *params)
+ 	rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP_V10,
+ 			      rkisp1_hst_params_default_config.mode);
+ 
+-	/* set the  range */
+-	if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE)
+-		rkisp1_csm_config(params, true);
+-	else
+-		rkisp1_csm_config(params, false);
++	rkisp1_csm_config(params);
+ 
+ 	spin_lock_irq(&params->config_lock);
+ 
+diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
+index dd3e6c38be677..025491f8793f6 100644
+--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-regs.h
+@@ -576,7 +576,7 @@
+ 	(((v0) & 0x1FFF) | (((v1) & 0x1FFF) << 13))
+ #define RKISP1_CIF_ISP_LSC_SECT_SIZE(v0, v1)      \
+ 	(((v0) & 0xFFF) | (((v1) & 0xFFF) << 16))
+-#define RKISP1_CIF_ISP_LSC_GRAD_SIZE(v0, v1)      \
++#define RKISP1_CIF_ISP_LSC_SECT_GRAD(v0, v1)      \
+ 	(((v0) & 0xFFF) | (((v1) & 0xFFF) << 16))
+ 
+ /* LSC: ISP_LSC_TABLE_SEL */
+diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
+index f4caa8f684aad..a2dc6f60d9cf6 100644
+--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c
+@@ -411,6 +411,10 @@ static int rkisp1_rsz_init_config(struct v4l2_subdev *sd,
+ 	sink_fmt->height = RKISP1_DEFAULT_HEIGHT;
+ 	sink_fmt->field = V4L2_FIELD_NONE;
+ 	sink_fmt->code = RKISP1_DEF_FMT;
++	sink_fmt->colorspace = V4L2_COLORSPACE_SRGB;
++	sink_fmt->xfer_func = V4L2_XFER_FUNC_SRGB;
++	sink_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
++	sink_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
+ 
+ 	sink_crop = v4l2_subdev_get_try_crop(sd, sd_state,
+ 					     RKISP1_RSZ_PAD_SINK);
+diff --git a/drivers/net/dsa/dsa_loop.c b/drivers/net/dsa/dsa_loop.c
+index 263e41191c292..0d20ebafbd03a 100644
+--- a/drivers/net/dsa/dsa_loop.c
++++ b/drivers/net/dsa/dsa_loop.c
+@@ -378,6 +378,17 @@ static struct mdio_driver dsa_loop_drv = {
+ 
+ #define NUM_FIXED_PHYS	(DSA_LOOP_NUM_PORTS - 2)
+ 
++static void dsa_loop_phydevs_unregister(void)
++{
++	unsigned int i;
++
++	for (i = 0; i < NUM_FIXED_PHYS; i++)
++		if (!IS_ERR(phydevs[i])) {
++			fixed_phy_unregister(phydevs[i]);
++			phy_device_free(phydevs[i]);
++		}
++}
++
+ static int __init dsa_loop_init(void)
+ {
+ 	struct fixed_phy_status status = {
+@@ -385,23 +396,23 @@ static int __init dsa_loop_init(void)
+ 		.speed = SPEED_100,
+ 		.duplex = DUPLEX_FULL,
+ 	};
+-	unsigned int i;
++	unsigned int i, ret;
+ 
+ 	for (i = 0; i < NUM_FIXED_PHYS; i++)
+ 		phydevs[i] = fixed_phy_register(PHY_POLL, &status, NULL);
+ 
+-	return mdio_driver_register(&dsa_loop_drv);
++	ret = mdio_driver_register(&dsa_loop_drv);
++	if (ret)
++		dsa_loop_phydevs_unregister();
++
++	return ret;
+ }
+ module_init(dsa_loop_init);
+ 
+ static void __exit dsa_loop_exit(void)
+ {
+-	unsigned int i;
+-
+ 	mdio_driver_unregister(&dsa_loop_drv);
+-	for (i = 0; i < NUM_FIXED_PHYS; i++)
+-		if (!IS_ERR(phydevs[i]))
+-			fixed_phy_unregister(phydevs[i]);
++	dsa_loop_phydevs_unregister();
+ }
+ module_exit(dsa_loop_exit);
+ 
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index a486435ceee2c..5aa254eaa8d02 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -657,7 +657,7 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
+ 		dev_kfree_skb_any(skb);
+ 		if (net_ratelimit())
+ 			netdev_err(ndev, "Tx DMA memory map failed\n");
+-		return NETDEV_TX_BUSY;
++		return NETDEV_TX_OK;
+ 	}
+ 
+ 	bdp->cbd_datlen = cpu_to_fec16(size);
+@@ -719,7 +719,7 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
+ 			dev_kfree_skb_any(skb);
+ 			if (net_ratelimit())
+ 				netdev_err(ndev, "Tx DMA memory map failed\n");
+-			return NETDEV_TX_BUSY;
++			return NETDEV_TX_OK;
+ 		}
+ 	}
+ 
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 5ab7c0f81e9af..e6b141536879f 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -3007,19 +3007,19 @@ static void __ibmvnic_reset(struct work_struct *work)
+ 		rwi = get_next_rwi(adapter);
+ 
+ 		/*
+-		 * If there is another reset queued, free the previous rwi
+-		 * and process the new reset even if previous reset failed
+-		 * (the previous reset could have failed because of a fail
+-		 * over for instance, so process the fail over).
+-		 *
+ 		 * If there are no resets queued and the previous reset failed,
+ 		 * the adapter would be in an undefined state. So retry the
+ 		 * previous reset as a hard reset.
++		 *
++		 * Else, free the previous rwi and, if there is another reset
++		 * queued, process the new reset even if previous reset failed
++		 * (the previous reset could have failed because of a fail
++		 * over for instance, so process the fail over).
+ 		 */
+-		if (rwi)
+-			kfree(tmprwi);
+-		else if (rc)
++		if (!rwi && rc)
+ 			rwi = tmprwi;
++		else
++			kfree(tmprwi);
+ 
+ 		if (rwi && (rwi->reset_reason == VNIC_RESET_FAILOVER ||
+ 			    rwi->reset_reason == VNIC_RESET_MOBILITY || rc))
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+index 69f741db25b1f..3a1a0f9178c01 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+@@ -414,13 +414,15 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx)
+ 	/* Get the received frame and unmap it */
+ 	db = &rx->dcbs[rx->dcb_index].db[rx->db_index];
+ 	page = rx->page[rx->dcb_index][rx->db_index];
++
++	dma_sync_single_for_cpu(lan966x->dev, (dma_addr_t)db->dataptr,
++				FDMA_DCB_STATUS_BLOCKL(db->status),
++				DMA_FROM_DEVICE);
++
+ 	skb = build_skb(page_address(page), PAGE_SIZE << rx->page_order);
+ 	if (unlikely(!skb))
+ 		goto unmap_page;
+ 
+-	dma_unmap_single(lan966x->dev, (dma_addr_t)db->dataptr,
+-			 FDMA_DCB_STATUS_BLOCKL(db->status),
+-			 DMA_FROM_DEVICE);
+ 	skb_put(skb, FDMA_DCB_STATUS_BLOCKL(db->status));
+ 
+ 	lan966x_ifh_get_src_port(skb->data, &src_port);
+@@ -429,6 +431,10 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx)
+ 	if (WARN_ON(src_port >= lan966x->num_phys_ports))
+ 		goto free_skb;
+ 
++	dma_unmap_single_attrs(lan966x->dev, (dma_addr_t)db->dataptr,
++			       PAGE_SIZE << rx->page_order, DMA_FROM_DEVICE,
++			       DMA_ATTR_SKIP_CPU_SYNC);
++
+ 	skb->dev = lan966x->ports[src_port]->dev;
+ 	skb_pull(skb, IFH_LEN * sizeof(u32));
+ 
+@@ -454,9 +460,9 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx)
+ free_skb:
+ 	kfree_skb(skb);
+ unmap_page:
+-	dma_unmap_page(lan966x->dev, (dma_addr_t)db->dataptr,
+-		       FDMA_DCB_STATUS_BLOCKL(db->status),
+-		       DMA_FROM_DEVICE);
++	dma_unmap_single_attrs(lan966x->dev, (dma_addr_t)db->dataptr,
++			       PAGE_SIZE << rx->page_order, DMA_FROM_DEVICE,
++			       DMA_ATTR_SKIP_CPU_SYNC);
+ 	__free_pages(page, rx->page_order);
+ 
+ 	return NULL;
+@@ -668,12 +674,14 @@ static int lan966x_fdma_get_max_mtu(struct lan966x *lan966x)
+ 	int i;
+ 
+ 	for (i = 0; i < lan966x->num_phys_ports; ++i) {
++		struct lan966x_port *port;
+ 		int mtu;
+ 
+-		if (!lan966x->ports[i])
++		port = lan966x->ports[i];
++		if (!port)
+ 			continue;
+ 
+-		mtu = lan966x->ports[i]->dev->mtu;
++		mtu = lan_rd(lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port));
+ 		if (mtu > max_mtu)
+ 			max_mtu = mtu;
+ 	}
+@@ -733,6 +741,8 @@ int lan966x_fdma_change_mtu(struct lan966x *lan966x)
+ 
+ 	max_mtu = lan966x_fdma_get_max_mtu(lan966x);
+ 	max_mtu += IFH_LEN * sizeof(u32);
++	max_mtu += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
++	max_mtu += VLAN_HLEN * 2;
+ 
+ 	if (round_up(max_mtu, PAGE_SIZE) / PAGE_SIZE - 1 ==
+ 	    lan966x->rx.page_order)
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+index d928b75f37803..4a3cb75794202 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+@@ -385,7 +385,7 @@ static int lan966x_port_change_mtu(struct net_device *dev, int new_mtu)
+ 	int old_mtu = dev->mtu;
+ 	int err;
+ 
+-	lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(new_mtu),
++	lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(LAN966X_HW_MTU(new_mtu)),
+ 	       lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port));
+ 	dev->mtu = new_mtu;
+ 
+@@ -394,7 +394,7 @@ static int lan966x_port_change_mtu(struct net_device *dev, int new_mtu)
+ 
+ 	err = lan966x_fdma_change_mtu(lan966x);
+ 	if (err) {
+-		lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(old_mtu),
++		lan_wr(DEV_MAC_MAXLEN_CFG_MAX_LEN_SET(LAN966X_HW_MTU(old_mtu)),
+ 		       lan966x, DEV_MAC_MAXLEN_CFG(port->chip_port));
+ 		dev->mtu = old_mtu;
+ 	}
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+index 2787055c18475..e316bfe186d74 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+@@ -24,6 +24,8 @@
+ #define LAN966X_BUFFER_MEMORY		(160 * 1024)
+ #define LAN966X_BUFFER_MIN_SZ		60
+ 
++#define LAN966X_HW_MTU(mtu)		((mtu) + ETH_HLEN + ETH_FCS_LEN)
++
+ #define PGID_AGGR			64
+ #define PGID_SRC			80
+ #define PGID_ENTRIES			89
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
+index 8265ad89f0bcb..357ecc2f1089d 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
+@@ -444,6 +444,21 @@ enum lan966x_target {
+ #define DEV_MAC_MAXLEN_CFG_MAX_LEN_GET(x)\
+ 	FIELD_GET(DEV_MAC_MAXLEN_CFG_MAX_LEN, x)
+ 
++/*      DEV:MAC_CFG_STATUS:MAC_TAGS_CFG */
++#define DEV_MAC_TAGS_CFG(t)       __REG(TARGET_DEV, t, 8, 28, 0, 1, 44, 12, 0, 1, 4)
++
++#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA        BIT(1)
++#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_SET(x)\
++	FIELD_PREP(DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA, x)
++#define DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_GET(x)\
++	FIELD_GET(DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA, x)
++
++#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA            BIT(0)
++#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(x)\
++	FIELD_PREP(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
++#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_GET(x)\
++	FIELD_GET(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
++
+ /*      DEV:MAC_CFG_STATUS:MAC_IFG_CFG */
+ #define DEV_MAC_IFG_CFG(t)        __REG(TARGET_DEV, t, 8, 28, 0, 1, 44, 20, 0, 1, 4)
+ 
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c b/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
+index 8d7260cd7da9c..3c44660128dae 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_vlan.c
+@@ -169,6 +169,12 @@ void lan966x_vlan_port_apply(struct lan966x_port *port)
+ 		ANA_VLAN_CFG_VLAN_POP_CNT,
+ 		lan966x, ANA_VLAN_CFG(port->chip_port));
+ 
++	lan_rmw(DEV_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(port->vlan_aware) |
++		DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA_SET(port->vlan_aware),
++		DEV_MAC_TAGS_CFG_VLAN_AWR_ENA |
++		DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA,
++		lan966x, DEV_MAC_TAGS_CFG(port->chip_port));
++
+ 	/* Drop frames with multicast source address */
+ 	val = ANA_DROP_CFG_DROP_MC_SMAC_ENA_SET(1);
+ 	if (port->vlan_aware && !pvid)
+diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
+index 153d68e29b8b3..68a68477ab7bc 100644
+--- a/drivers/net/ethernet/sfc/efx.c
++++ b/drivers/net/ethernet/sfc/efx.c
+@@ -1059,8 +1059,10 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
+ 
+ 	/* Allocate and initialise a struct net_device */
+ 	net_dev = alloc_etherdev_mq(sizeof(probe_data), EFX_MAX_CORE_TX_QUEUES);
+-	if (!net_dev)
+-		return -ENOMEM;
++	if (!net_dev) {
++		rc = -ENOMEM;
++		goto fail0;
++	}
+ 	probe_ptr = netdev_priv(net_dev);
+ 	*probe_ptr = probe_data;
+ 	efx->net_dev = net_dev;
+@@ -1132,6 +1134,8 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
+ 	WARN_ON(rc > 0);
+ 	netif_dbg(efx, drv, efx->net_dev, "initialisation failed. rc=%d\n", rc);
+ 	free_netdev(net_dev);
++ fail0:
++	kfree(probe_data);
+ 	return rc;
+ }
+ 
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+index 017dbbda0c1c4..79fa7870563b8 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+@@ -51,7 +51,6 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ 	struct stmmac_resources res;
+ 	struct device_node *np;
+ 	int ret, i, phy_mode;
+-	bool mdio = false;
+ 
+ 	np = dev_of_node(&pdev->dev);
+ 
+@@ -69,12 +68,10 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
+ 	if (!plat)
+ 		return -ENOMEM;
+ 
++	plat->mdio_node = of_get_child_by_name(np, "mdio");
+ 	if (plat->mdio_node) {
+-		dev_err(&pdev->dev, "Found MDIO subnode\n");
+-		mdio = true;
+-	}
++		dev_info(&pdev->dev, "Found MDIO subnode\n");
+ 
+-	if (mdio) {
+ 		plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
+ 						   sizeof(*plat->mdio_bus_data),
+ 						   GFP_KERNEL);
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index 8a2dbe849866d..1bc988d9f2e8a 100644
+--- a/drivers/net/phy/mdio_bus.c
++++ b/drivers/net/phy/mdio_bus.c
+@@ -583,7 +583,7 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
+ 	}
+ 
+ 	for (i = 0; i < PHY_MAX_ADDR; i++) {
+-		if ((bus->phy_mask & (1 << i)) == 0) {
++		if ((bus->phy_mask & BIT(i)) == 0) {
+ 			struct phy_device *phydev;
+ 
+ 			phydev = mdiobus_scan(bus, i);
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index db736b944016e..b02bd0a6c0a93 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1459,7 +1459,8 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile,
+ 	int err;
+ 	int i;
+ 
+-	if (it->nr_segs > MAX_SKB_FRAGS + 1)
++	if (it->nr_segs > MAX_SKB_FRAGS + 1 ||
++	    len > (ETH_MAX_MTU - NET_SKB_PAD - NET_IP_ALIGN))
+ 		return ERR_PTR(-EMSGSIZE);
+ 
+ 	local_bh_disable();
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
+index bc3f4e4edcdf9..dac7eb77799bd 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
+@@ -228,6 +228,10 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
+ 			  brcmf_fweh_event_name(event->code), event->code,
+ 			  event->emsg.ifidx, event->emsg.bsscfgidx,
+ 			  event->emsg.addr);
++		if (event->emsg.bsscfgidx >= BRCMF_MAX_IFS) {
++			bphy_err(drvr, "invalid bsscfg index: %u\n", event->emsg.bsscfgidx);
++			goto event_free;
++		}
+ 
+ 		/* convert event message */
+ 		emsg_be = &event->emsg;
+diff --git a/drivers/nfc/fdp/fdp.c b/drivers/nfc/fdp/fdp.c
+index c6b3334f24c9e..f12f903a9dd13 100644
+--- a/drivers/nfc/fdp/fdp.c
++++ b/drivers/nfc/fdp/fdp.c
+@@ -249,11 +249,19 @@ static int fdp_nci_close(struct nci_dev *ndev)
+ static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+ {
+ 	struct fdp_nci_info *info = nci_get_drvdata(ndev);
++	int ret;
+ 
+ 	if (atomic_dec_and_test(&info->data_pkt_counter))
+ 		info->data_pkt_counter_cb(ndev);
+ 
+-	return info->phy_ops->write(info->phy, skb);
++	ret = info->phy_ops->write(info->phy, skb);
++	if (ret < 0) {
++		kfree_skb(skb);
++		return ret;
++	}
++
++	consume_skb(skb);
++	return 0;
+ }
+ 
+ static int fdp_nci_request_firmware(struct nci_dev *ndev)
+diff --git a/drivers/nfc/nfcmrvl/i2c.c b/drivers/nfc/nfcmrvl/i2c.c
+index 01329b91d59d5..a902720cd8493 100644
+--- a/drivers/nfc/nfcmrvl/i2c.c
++++ b/drivers/nfc/nfcmrvl/i2c.c
+@@ -132,10 +132,15 @@ static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private *priv,
+ 			ret = -EREMOTEIO;
+ 		} else
+ 			ret = 0;
++	}
++
++	if (ret) {
+ 		kfree_skb(skb);
++		return ret;
+ 	}
+ 
+-	return ret;
++	consume_skb(skb);
++	return 0;
+ }
+ 
+ static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv,
+diff --git a/drivers/nfc/nxp-nci/core.c b/drivers/nfc/nxp-nci/core.c
+index 7c93d484dc1bc..580cb6ecffee4 100644
+--- a/drivers/nfc/nxp-nci/core.c
++++ b/drivers/nfc/nxp-nci/core.c
+@@ -80,10 +80,13 @@ static int nxp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+ 		return -EINVAL;
+ 
+ 	r = info->phy_ops->write(info->phy_id, skb);
+-	if (r < 0)
++	if (r < 0) {
+ 		kfree_skb(skb);
++		return r;
++	}
+ 
+-	return r;
++	consume_skb(skb);
++	return 0;
+ }
+ 
+ static int nxp_nci_rf_pll_unlocked_ntf(struct nci_dev *ndev,
+diff --git a/drivers/nfc/s3fwrn5/core.c b/drivers/nfc/s3fwrn5/core.c
+index 1c412007fabb6..0270e05b68dff 100644
+--- a/drivers/nfc/s3fwrn5/core.c
++++ b/drivers/nfc/s3fwrn5/core.c
+@@ -110,11 +110,15 @@ static int s3fwrn5_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+ 	}
+ 
+ 	ret = s3fwrn5_write(info, skb);
+-	if (ret < 0)
++	if (ret < 0) {
+ 		kfree_skb(skb);
++		mutex_unlock(&info->mutex);
++		return ret;
++	}
+ 
++	consume_skb(skb);
+ 	mutex_unlock(&info->mutex);
+-	return ret;
++	return 0;
+ }
+ 
+ static int s3fwrn5_nci_post_setup(struct nci_dev *ndev)
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 57cc2bb5b1a2b..554468ea5a2a9 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -3508,6 +3508,16 @@ static const struct pci_device_id nvme_id_table[] = {
+ 		.driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
+ 	{ PCI_DEVICE(0x2646, 0x2263),   /* KINGSTON A2000 NVMe SSD  */
+ 		.driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
++	{ PCI_DEVICE(0x2646, 0x5018),   /* KINGSTON OM8SFP4xxxxP OS21012 NVMe SSD */
++		.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
++	{ PCI_DEVICE(0x2646, 0x5016),   /* KINGSTON OM3PGP4xxxxP OS21011 NVMe SSD */
++		.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
++	{ PCI_DEVICE(0x2646, 0x501A),   /* KINGSTON OM8PGP4xxxxP OS21005 NVMe SSD */
++		.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
++	{ PCI_DEVICE(0x2646, 0x501B),   /* KINGSTON OM8PGP4xxxxQ OS21005 NVMe SSD */
++		.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
++	{ PCI_DEVICE(0x2646, 0x501E),   /* KINGSTON OM3PGP4xxxxQ OS21011 NVMe SSD */
++		.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
+ 	{ PCI_DEVICE(0x1e4B, 0x1001),   /* MAXIO MAP1001 */
+ 		.driver_data = NVME_QUIRK_BOGUS_NID, },
+ 	{ PCI_DEVICE(0x1e4B, 0x1002),   /* MAXIO MAP1002 */
+diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
+index bdef7a8d6ab8e..bcc1dae007803 100644
+--- a/drivers/parisc/iosapic.c
++++ b/drivers/parisc/iosapic.c
+@@ -866,6 +866,7 @@ int iosapic_serial_irq(struct parisc_device *dev)
+ 
+ 	return vi->txn_irq;
+ }
++EXPORT_SYMBOL(iosapic_serial_irq);
+ #endif
+ 
+ 
+diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
+index 5d61f58399dca..dc41d7c6b9b19 100644
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -828,6 +828,14 @@ store_state_field(struct device *dev, struct device_attribute *attr,
+ 	}
+ 
+ 	mutex_lock(&sdev->state_mutex);
++	switch (sdev->sdev_state) {
++	case SDEV_RUNNING:
++	case SDEV_OFFLINE:
++		break;
++	default:
++		mutex_unlock(&sdev->state_mutex);
++		return -EINVAL;
++	}
+ 	if (sdev->sdev_state == SDEV_RUNNING && state == SDEV_RUNNING) {
+ 		ret = 0;
+ 	} else {
+diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
+index 2036f72eeb4af..1dd8312d824ce 100644
+--- a/drivers/staging/media/hantro/hantro_drv.c
++++ b/drivers/staging/media/hantro/hantro_drv.c
+@@ -251,6 +251,11 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
+ 
+ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
+ {
++	struct hantro_ctx *ctx;
++
++	ctx = container_of(ctrl->handler,
++			   struct hantro_ctx, ctrl_handler);
++
+ 	if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) {
+ 		const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps;
+ 
+@@ -272,6 +277,8 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl)
+ 		if (sps->bit_depth_luma_minus8 != 0)
+ 			/* Only 8-bit is supported */
+ 			return -EINVAL;
++
++		ctx->bit_depth = sps->bit_depth_luma_minus8 + 8;
+ 	} else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) {
+ 		const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame;
+ 
+diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+index 233ecd863d5f1..a917079a6ed30 100644
+--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
++++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+@@ -12,7 +12,7 @@
+ 
+ static size_t hantro_hevc_chroma_offset(struct hantro_ctx *ctx)
+ {
+-	return ctx->dst_fmt.width * ctx->dst_fmt.height;
++	return ctx->dst_fmt.width * ctx->dst_fmt.height * ctx->bit_depth / 8;
+ }
+ 
+ static size_t hantro_hevc_motion_vectors_offset(struct hantro_ctx *ctx)
+diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c
+index b990bc98164c3..9383fb7081f6c 100644
+--- a/drivers/staging/media/hantro/hantro_hevc.c
++++ b/drivers/staging/media/hantro/hantro_hevc.c
+@@ -104,7 +104,7 @@ static int tile_buffer_reallocate(struct hantro_ctx *ctx)
+ 		hevc_dec->tile_bsd.cpu = NULL;
+ 	}
+ 
+-	size = VERT_FILTER_RAM_SIZE * height64 * (num_tile_cols - 1);
++	size = (VERT_FILTER_RAM_SIZE * height64 * (num_tile_cols - 1) * ctx->bit_depth) / 8;
+ 	hevc_dec->tile_filter.cpu = dma_alloc_coherent(vpu->dev, size,
+ 						       &hevc_dec->tile_filter.dma,
+ 						       GFP_KERNEL);
+@@ -112,7 +112,7 @@ static int tile_buffer_reallocate(struct hantro_ctx *ctx)
+ 		goto err_free_tile_buffers;
+ 	hevc_dec->tile_filter.size = size;
+ 
+-	size = VERT_SAO_RAM_SIZE * height64 * (num_tile_cols - 1);
++	size = (VERT_SAO_RAM_SIZE * height64 * (num_tile_cols - 1) * ctx->bit_depth) / 8;
+ 	hevc_dec->tile_sao.cpu = dma_alloc_coherent(vpu->dev, size,
+ 						    &hevc_dec->tile_sao.dma,
+ 						    GFP_KERNEL);
+diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c
+index 8549d95be0f25..52f224d8def10 100644
+--- a/drivers/staging/media/meson/vdec/vdec.c
++++ b/drivers/staging/media/meson/vdec/vdec.c
+@@ -1102,6 +1102,7 @@ static int vdec_probe(struct platform_device *pdev)
+ 
+ err_vdev_release:
+ 	video_device_release(vdev);
++	v4l2_device_unregister(&core->v4l2_dev);
+ 	return ret;
+ }
+ 
+@@ -1110,6 +1111,7 @@ static int vdec_remove(struct platform_device *pdev)
+ 	struct amvdec_core *core = platform_get_drvdata(pdev);
+ 
+ 	video_unregister_device(core->vdev_dec);
++	v4l2_device_unregister(&core->v4l2_dev);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
+index d0b49e15fbf5e..7b3ffb7f50aba 100644
+--- a/drivers/tty/serial/8250/Kconfig
++++ b/drivers/tty/serial/8250/Kconfig
+@@ -118,7 +118,7 @@ config SERIAL_8250_CONSOLE
+ 
+ config SERIAL_8250_GSC
+ 	tristate
+-	depends on SERIAL_8250 && GSC
++	depends on SERIAL_8250 && PARISC
+ 	default SERIAL_8250
+ 
+ config SERIAL_8250_DMA
+diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
+index ccc818b409774..21c478df6aef4 100644
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -289,8 +289,10 @@ static void prelim_release(struct preftree *preftree)
+ 	struct prelim_ref *ref, *next_ref;
+ 
+ 	rbtree_postorder_for_each_entry_safe(ref, next_ref,
+-					     &preftree->root.rb_root, rbnode)
++					     &preftree->root.rb_root, rbnode) {
++		free_inode_elem_list(ref->inode_list);
+ 		free_pref(ref);
++	}
+ 
+ 	preftree->root = RB_ROOT_CACHED;
+ 	preftree->count = 0;
+@@ -648,6 +650,18 @@ unode_aux_to_inode_list(struct ulist_node *node)
+ 	return (struct extent_inode_elem *)(uintptr_t)node->aux;
+ }
+ 
++static void free_leaf_list(struct ulist *ulist)
++{
++	struct ulist_node *node;
++	struct ulist_iterator uiter;
++
++	ULIST_ITER_INIT(&uiter);
++	while ((node = ulist_next(ulist, &uiter)))
++		free_inode_elem_list(unode_aux_to_inode_list(node));
++
++	ulist_free(ulist);
++}
++
+ /*
+  * We maintain three separate rbtrees: one for direct refs, one for
+  * indirect refs which have a key, and one for indirect refs which do not
+@@ -762,7 +776,11 @@ static int resolve_indirect_refs(struct btrfs_fs_info *fs_info,
+ 		cond_resched();
+ 	}
+ out:
+-	ulist_free(parents);
++	/*
++	 * We may have inode lists attached to refs in the parents ulist, so we
++	 * must free them before freeing the ulist and its refs.
++	 */
++	free_leaf_list(parents);
+ 	return ret;
+ }
+ 
+@@ -1368,6 +1386,12 @@ again:
+ 				if (ret < 0)
+ 					goto out;
+ 				ref->inode_list = eie;
++				/*
++				 * We transferred the list ownership to the ref,
++				 * so set to NULL to avoid a double free in case
++				 * an error happens after this.
++				 */
++				eie = NULL;
+ 			}
+ 			ret = ulist_add_merge_ptr(refs, ref->parent,
+ 						  ref->inode_list,
+@@ -1393,6 +1417,14 @@ again:
+ 				eie->next = ref->inode_list;
+ 			}
+ 			eie = NULL;
++			/*
++			 * We have transferred the inode list ownership from
++			 * this ref to the ref we added to the 'refs' ulist.
++			 * So set this ref's inode list to NULL to avoid
++			 * use-after-free when our caller uses it or double
++			 * frees in case an error happens before we return.
++			 */
++			ref->inode_list = NULL;
+ 		}
+ 		cond_resched();
+ 	}
+@@ -1409,24 +1441,6 @@ out:
+ 	return ret;
+ }
+ 
+-static void free_leaf_list(struct ulist *blocks)
+-{
+-	struct ulist_node *node = NULL;
+-	struct extent_inode_elem *eie;
+-	struct ulist_iterator uiter;
+-
+-	ULIST_ITER_INIT(&uiter);
+-	while ((node = ulist_next(blocks, &uiter))) {
+-		if (!node->aux)
+-			continue;
+-		eie = unode_aux_to_inode_list(node);
+-		free_inode_elem_list(eie);
+-		node->aux = 0;
+-	}
+-
+-	ulist_free(blocks);
+-}
+-
+ /*
+  * Finds all leafs with a reference to the specified combination of bytenr and
+  * offset. key_list_head will point to a list of corresponding keys (caller must
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index df8c99c99df92..bad06add93d7e 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -3407,7 +3407,10 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
+ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
+ 			     const struct btrfs_ioctl_encoded_io_args *encoded);
+ 
+-ssize_t btrfs_dio_rw(struct kiocb *iocb, struct iov_iter *iter, size_t done_before);
++ssize_t btrfs_dio_read(struct kiocb *iocb, struct iov_iter *iter,
++		       size_t done_before);
++struct iomap_dio *btrfs_dio_write(struct kiocb *iocb, struct iov_iter *iter,
++				  size_t done_before);
+ 
+ extern const struct dentry_operations btrfs_dentry_operations;
+ 
+diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
+index 1d4c2397d0d62..fab7eb76e53b2 100644
+--- a/fs/btrfs/export.c
++++ b/fs/btrfs/export.c
+@@ -58,7 +58,7 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
+ }
+ 
+ struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
+-				u64 root_objectid, u32 generation,
++				u64 root_objectid, u64 generation,
+ 				int check_generation)
+ {
+ 	struct btrfs_fs_info *fs_info = btrfs_sb(sb);
+diff --git a/fs/btrfs/export.h b/fs/btrfs/export.h
+index f32f4113c976a..5afb7ca428289 100644
+--- a/fs/btrfs/export.h
++++ b/fs/btrfs/export.h
+@@ -19,7 +19,7 @@ struct btrfs_fid {
+ } __attribute__ ((packed));
+ 
+ struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
+-				u64 root_objectid, u32 generation,
++				u64 root_objectid, u64 generation,
+ 				int check_generation);
+ struct dentry *btrfs_get_parent(struct dentry *child);
+ 
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index cfbbd7dc3c46b..32c3a5e5a3dd7 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -3294,21 +3294,22 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
+ 		}
+ 
+ 		/*
+-		 * If this is a leaf and there are tree mod log users, we may
+-		 * have recorded mod log operations that point to this leaf.
+-		 * So we must make sure no one reuses this leaf's extent before
+-		 * mod log operations are applied to a node, otherwise after
+-		 * rewinding a node using the mod log operations we get an
+-		 * inconsistent btree, as the leaf's extent may now be used as
+-		 * a node or leaf for another different btree.
++		 * If there are tree mod log users we may have recorded mod log
++		 * operations for this node.  If we re-allocate this node we
++		 * could replay operations on this node that happened when it
++		 * existed in a completely different root.  For example if it
++		 * was part of root A, then was reallocated to root B, and we
++		 * are doing a btrfs_old_search_slot(root b), we could replay
++		 * operations that happened when the block was part of root A,
++		 * giving us an inconsistent view of the btree.
++		 *
+ 		 * We are safe from races here because at this point no other
+ 		 * node or root points to this extent buffer, so if after this
+-		 * check a new tree mod log user joins, it will not be able to
+-		 * find a node pointing to this leaf and record operations that
+-		 * point to this leaf.
++		 * check a new tree mod log user joins we will not have an
++		 * existing log of operations on this node that we have to
++		 * contend with.
+ 		 */
+-		if (btrfs_header_level(buf) == 0 &&
+-		    test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags))
++		if (test_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags))
+ 			must_pin = true;
+ 
+ 		if (must_pin || btrfs_is_zoned(fs_info)) {
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 19e9df0c86496..db7c6d22190de 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -1889,6 +1889,7 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from)
+ 	loff_t endbyte;
+ 	ssize_t err;
+ 	unsigned int ilock_flags = 0;
++	struct iomap_dio *dio;
+ 
+ 	if (iocb->ki_flags & IOCB_NOWAIT)
+ 		ilock_flags |= BTRFS_ILOCK_TRY;
+@@ -1949,11 +1950,22 @@ relock:
+ 	 * So here we disable page faults in the iov_iter and then retry if we
+ 	 * got -EFAULT, faulting in the pages before the retry.
+ 	 */
+-again:
+ 	from->nofault = true;
+-	err = btrfs_dio_rw(iocb, from, written);
++	dio = btrfs_dio_write(iocb, from, written);
+ 	from->nofault = false;
+ 
++	/*
++	 * iomap_dio_complete() will call btrfs_sync_file() if we have a dsync
++	 * iocb, and that needs to lock the inode. So unlock it before calling
++	 * iomap_dio_complete() to avoid a deadlock.
++	 */
++	btrfs_inode_unlock(inode, ilock_flags);
++
++	if (IS_ERR_OR_NULL(dio))
++		err = PTR_ERR_OR_ZERO(dio);
++	else
++		err = iomap_dio_complete(dio);
++
+ 	/* No increment (+=) because iomap returns a cumulative value. */
+ 	if (err > 0)
+ 		written = err;
+@@ -1979,12 +1991,10 @@ again:
+ 		} else {
+ 			fault_in_iov_iter_readable(from, left);
+ 			prev_left = left;
+-			goto again;
++			goto relock;
+ 		}
+ 	}
+ 
+-	btrfs_inode_unlock(inode, ilock_flags);
+-
+ 	/*
+ 	 * If 'err' is -ENOTBLK or we have not written all data, then it means
+ 	 * we must fallback to buffered IO.
+@@ -3787,7 +3797,7 @@ again:
+ 	 */
+ 	pagefault_disable();
+ 	to->nofault = true;
+-	ret = btrfs_dio_rw(iocb, to, read);
++	ret = btrfs_dio_read(iocb, to, read);
+ 	to->nofault = false;
+ 	pagefault_enable();
+ 
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 1372210869b14..893693112fb80 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -8142,7 +8142,7 @@ static void btrfs_submit_direct(const struct iomap_iter *iter,
+ 		 */
+ 		status = BLK_STS_RESOURCE;
+ 		dip->csums = kcalloc(nr_sectors, fs_info->csum_size, GFP_NOFS);
+-		if (!dip)
++		if (!dip->csums)
+ 			goto out_err;
+ 
+ 		status = btrfs_lookup_bio_sums(inode, dio_bio, dip->csums);
+@@ -8241,13 +8241,21 @@ static const struct iomap_dio_ops btrfs_dio_ops = {
+ 	.bio_set		= &btrfs_dio_bioset,
+ };
+ 
+-ssize_t btrfs_dio_rw(struct kiocb *iocb, struct iov_iter *iter, size_t done_before)
++ssize_t btrfs_dio_read(struct kiocb *iocb, struct iov_iter *iter, size_t done_before)
+ {
+ 	struct btrfs_dio_data data;
+ 
+ 	return iomap_dio_rw(iocb, iter, &btrfs_dio_iomap_ops, &btrfs_dio_ops,
+-			    IOMAP_DIO_PARTIAL | IOMAP_DIO_NOSYNC,
+-			    &data, done_before);
++			    IOMAP_DIO_PARTIAL, &data, done_before);
++}
++
++struct iomap_dio *btrfs_dio_write(struct kiocb *iocb, struct iov_iter *iter,
++				  size_t done_before)
++{
++	struct btrfs_dio_data data;
++
++	return __iomap_dio_rw(iocb, iter, &btrfs_dio_iomap_ops, &btrfs_dio_ops,
++			    IOMAP_DIO_PARTIAL, &data, done_before);
+ }
+ 
+ static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c
+index eee1e44595410..843dd3d3adbe7 100644
+--- a/fs/btrfs/tests/qgroup-tests.c
++++ b/fs/btrfs/tests/qgroup-tests.c
+@@ -232,8 +232,10 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+ 
+ 	ret = insert_normal_tree_ref(root, nodesize, nodesize, 0,
+ 				BTRFS_FS_TREE_OBJECTID);
+-	if (ret)
++	if (ret) {
++		ulist_free(old_roots);
+ 		return ret;
++	}
+ 
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ 	if (ret) {
+@@ -266,8 +268,10 @@ static int test_no_shared_qgroup(struct btrfs_root *root,
+ 	}
+ 
+ 	ret = remove_extent_item(root, nodesize, nodesize);
+-	if (ret)
++	if (ret) {
++		ulist_free(old_roots);
+ 		return -EINVAL;
++	}
+ 
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ 	if (ret) {
+@@ -329,8 +333,10 @@ static int test_multiple_refs(struct btrfs_root *root,
+ 
+ 	ret = insert_normal_tree_ref(root, nodesize, nodesize, 0,
+ 				BTRFS_FS_TREE_OBJECTID);
+-	if (ret)
++	if (ret) {
++		ulist_free(old_roots);
+ 		return ret;
++	}
+ 
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ 	if (ret) {
+@@ -362,8 +368,10 @@ static int test_multiple_refs(struct btrfs_root *root,
+ 
+ 	ret = add_tree_ref(root, nodesize, nodesize, 0,
+ 			BTRFS_FIRST_FREE_OBJECTID);
+-	if (ret)
++	if (ret) {
++		ulist_free(old_roots);
+ 		return ret;
++	}
+ 
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ 	if (ret) {
+@@ -401,8 +409,10 @@ static int test_multiple_refs(struct btrfs_root *root,
+ 
+ 	ret = remove_extent_ref(root, nodesize, nodesize, 0,
+ 				BTRFS_FIRST_FREE_OBJECTID);
+-	if (ret)
++	if (ret) {
++		ulist_free(old_roots);
+ 		return ret;
++	}
+ 
+ 	ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots, false);
+ 	if (ret) {
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index f63ff91e28837..5d004772ab493 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -7029,6 +7029,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ 	u64 devid;
+ 	u64 type;
+ 	u8 uuid[BTRFS_UUID_SIZE];
++	int index;
+ 	int num_stripes;
+ 	int ret;
+ 	int i;
+@@ -7036,6 +7037,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ 	logical = key->offset;
+ 	length = btrfs_chunk_length(leaf, chunk);
+ 	type = btrfs_chunk_type(leaf, chunk);
++	index = btrfs_bg_flags_to_raid_index(type);
+ 	num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
+ 
+ #if BITS_PER_LONG == 32
+@@ -7089,7 +7091,15 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ 	map->io_align = btrfs_chunk_io_align(leaf, chunk);
+ 	map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
+ 	map->type = type;
+-	map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
++	/*
++	 * We can't use the sub_stripes value, as for profiles other than
++	 * RAID10, they may have 0 as sub_stripes for filesystems created by
++	 * older mkfs (<v5.4).
++	 * In that case, it can cause divide-by-zero errors later.
++	 * Since currently sub_stripes is fixed for each profile, let's
++	 * use the trusted value instead.
++	 */
++	map->sub_stripes = btrfs_raid_array[index].sub_stripes;
+ 	map->verified_stripes = 0;
+ 	em->orig_block_len = btrfs_calc_stripe_length(em);
+ 	for (i = 0; i < num_stripes; i++) {
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index e960dda893c63..c2c36451a8837 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -3921,12 +3921,11 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
+ 	pSMB->AndXCommand = 0xFF;
+ 	pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
+ 	bcc_ptr = &pSMB->Password[0];
+-	if (tcon->pipe || (ses->server->sec_mode & SECMODE_USER)) {
+-		pSMB->PasswordLength = cpu_to_le16(1);	/* minimum */
+-		*bcc_ptr = 0; /* password is null byte */
+-		bcc_ptr++;              /* skip password */
+-		/* already aligned so no need to do it below */
+-	}
++
++	pSMB->PasswordLength = cpu_to_le16(1);	/* minimum */
++	*bcc_ptr = 0; /* password is null byte */
++	bcc_ptr++;              /* skip password */
++	/* already aligned so no need to do it below */
+ 
+ 	if (ses->server->sign)
+ 		smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
+index 3afdaa0847736..577cae7facb01 100644
+--- a/fs/crypto/fscrypt_private.h
++++ b/fs/crypto/fscrypt_private.h
+@@ -225,7 +225,7 @@ struct fscrypt_info {
+ 	 * will be NULL if the master key was found in a process-subscribed
+ 	 * keyring rather than in the filesystem-level keyring.
+ 	 */
+-	struct key *ci_master_key;
++	struct fscrypt_master_key *ci_master_key;
+ 
+ 	/*
+ 	 * Link in list of inodes that were unlocked with the master key.
+@@ -436,6 +436,40 @@ struct fscrypt_master_key_secret {
+  */
+ struct fscrypt_master_key {
+ 
++	/*
++	 * Back-pointer to the super_block of the filesystem to which this
++	 * master key has been added.  Only valid if ->mk_active_refs > 0.
++	 */
++	struct super_block			*mk_sb;
++
++	/*
++	 * Link in ->mk_sb->s_master_keys->key_hashtable.
++	 * Only valid if ->mk_active_refs > 0.
++	 */
++	struct hlist_node			mk_node;
++
++	/* Semaphore that protects ->mk_secret and ->mk_users */
++	struct rw_semaphore			mk_sem;
++
++	/*
++	 * Active and structural reference counts.  An active ref guarantees
++	 * that the struct continues to exist, continues to be in the keyring
++	 * ->mk_sb->s_master_keys, and that any embedded subkeys (e.g.
++	 * ->mk_direct_keys) that have been prepared continue to exist.
++	 * A structural ref only guarantees that the struct continues to exist.
++	 *
++	 * There is one active ref associated with ->mk_secret being present,
++	 * and one active ref for each inode in ->mk_decrypted_inodes.
++	 *
++	 * There is one structural ref associated with the active refcount being
++	 * nonzero.  Finding a key in the keyring also takes a structural ref,
++	 * which is then held temporarily while the key is operated on.
++	 */
++	refcount_t				mk_active_refs;
++	refcount_t				mk_struct_refs;
++
++	struct rcu_head				mk_rcu_head;
++
+ 	/*
+ 	 * The secret key material.  After FS_IOC_REMOVE_ENCRYPTION_KEY is
+ 	 * executed, this is wiped and no new inodes can be unlocked with this
+@@ -444,7 +478,10 @@ struct fscrypt_master_key {
+ 	 * FS_IOC_REMOVE_ENCRYPTION_KEY can be retried, or
+ 	 * FS_IOC_ADD_ENCRYPTION_KEY can add the secret again.
+ 	 *
+-	 * Locking: protected by this master key's key->sem.
++	 * While ->mk_secret is present, one ref in ->mk_active_refs is held.
++	 *
++	 * Locking: protected by ->mk_sem.  The manipulation of ->mk_active_refs
++	 *	    associated with this field is protected by ->mk_sem as well.
+ 	 */
+ 	struct fscrypt_master_key_secret	mk_secret;
+ 
+@@ -465,22 +502,12 @@ struct fscrypt_master_key {
+ 	 *
+ 	 * This is NULL for v1 policy keys; those can only be added by root.
+ 	 *
+-	 * Locking: in addition to this keyring's own semaphore, this is
+-	 * protected by this master key's key->sem, so we can do atomic
+-	 * search+insert.  It can also be searched without taking any locks, but
+-	 * in that case the returned key may have already been removed.
++	 * Locking: protected by ->mk_sem.  (We don't just rely on the keyrings
++	 * subsystem semaphore ->mk_users->sem, as we need support for atomic
++	 * search+insert along with proper synchronization with ->mk_secret.)
+ 	 */
+ 	struct key		*mk_users;
+ 
+-	/*
+-	 * Length of ->mk_decrypted_inodes, plus one if mk_secret is present.
+-	 * Once this goes to 0, the master key is removed from ->s_master_keys.
+-	 * The 'struct fscrypt_master_key' will continue to live as long as the
+-	 * 'struct key' whose payload it is, but we won't let this reference
+-	 * count rise again.
+-	 */
+-	refcount_t		mk_refcount;
+-
+ 	/*
+ 	 * List of inodes that were unlocked using this key.  This allows the
+ 	 * inodes to be evicted efficiently if the key is removed.
+@@ -506,10 +533,10 @@ static inline bool
+ is_master_key_secret_present(const struct fscrypt_master_key_secret *secret)
+ {
+ 	/*
+-	 * The READ_ONCE() is only necessary for fscrypt_drop_inode() and
+-	 * fscrypt_key_describe().  These run in atomic context, so they can't
+-	 * take the key semaphore and thus 'secret' can change concurrently
+-	 * which would be a data race.  But they only need to know whether the
++	 * The READ_ONCE() is only necessary for fscrypt_drop_inode().
++	 * fscrypt_drop_inode() runs in atomic context, so it can't take the key
++	 * semaphore and thus 'secret' can change concurrently which would be a
++	 * data race.  But fscrypt_drop_inode() only need to know whether the
+ 	 * secret *was* present at the time of check, so READ_ONCE() suffices.
+ 	 */
+ 	return READ_ONCE(secret->size) != 0;
+@@ -538,7 +565,11 @@ static inline int master_key_spec_len(const struct fscrypt_key_specifier *spec)
+ 	return 0;
+ }
+ 
+-struct key *
++void fscrypt_put_master_key(struct fscrypt_master_key *mk);
++
++void fscrypt_put_master_key_activeref(struct fscrypt_master_key *mk);
++
++struct fscrypt_master_key *
+ fscrypt_find_master_key(struct super_block *sb,
+ 			const struct fscrypt_key_specifier *mk_spec);
+ 
+diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
+index 7c01025879b38..7b8c5a1104b58 100644
+--- a/fs/crypto/hooks.c
++++ b/fs/crypto/hooks.c
+@@ -5,8 +5,6 @@
+  * Encryption hooks for higher-level filesystem operations.
+  */
+ 
+-#include <linux/key.h>
+-
+ #include "fscrypt_private.h"
+ 
+ /**
+@@ -142,7 +140,6 @@ int fscrypt_prepare_setflags(struct inode *inode,
+ 			     unsigned int oldflags, unsigned int flags)
+ {
+ 	struct fscrypt_info *ci;
+-	struct key *key;
+ 	struct fscrypt_master_key *mk;
+ 	int err;
+ 
+@@ -158,14 +155,13 @@ int fscrypt_prepare_setflags(struct inode *inode,
+ 		ci = inode->i_crypt_info;
+ 		if (ci->ci_policy.version != FSCRYPT_POLICY_V2)
+ 			return -EINVAL;
+-		key = ci->ci_master_key;
+-		mk = key->payload.data[0];
+-		down_read(&key->sem);
++		mk = ci->ci_master_key;
++		down_read(&mk->mk_sem);
+ 		if (is_master_key_secret_present(&mk->mk_secret))
+ 			err = fscrypt_derive_dirhash_key(ci, mk);
+ 		else
+ 			err = -ENOKEY;
+-		up_read(&key->sem);
++		up_read(&mk->mk_sem);
+ 		return err;
+ 	}
+ 	return 0;
+diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c
+index caee9f8620dd9..f10ace12c05f8 100644
+--- a/fs/crypto/keyring.c
++++ b/fs/crypto/keyring.c
+@@ -18,6 +18,7 @@
+  * information about these ioctls.
+  */
+ 
++#include <asm/unaligned.h>
+ #include <crypto/skcipher.h>
+ #include <linux/key-type.h>
+ #include <linux/random.h>
+@@ -25,6 +26,18 @@
+ 
+ #include "fscrypt_private.h"
+ 
++/* The master encryption keys for a filesystem (->s_master_keys) */
++struct fscrypt_keyring {
++	/*
++	 * Lock that protects ->key_hashtable.  It does *not* protect the
++	 * fscrypt_master_key structs themselves.
++	 */
++	spinlock_t lock;
++
++	/* Hash table that maps fscrypt_key_specifier to fscrypt_master_key */
++	struct hlist_head key_hashtable[128];
++};
++
+ static void wipe_master_key_secret(struct fscrypt_master_key_secret *secret)
+ {
+ 	fscrypt_destroy_hkdf(&secret->hkdf);
+@@ -38,20 +51,70 @@ static void move_master_key_secret(struct fscrypt_master_key_secret *dst,
+ 	memzero_explicit(src, sizeof(*src));
+ }
+ 
+-static void free_master_key(struct fscrypt_master_key *mk)
++static void fscrypt_free_master_key(struct rcu_head *head)
++{
++	struct fscrypt_master_key *mk =
++		container_of(head, struct fscrypt_master_key, mk_rcu_head);
++	/*
++	 * The master key secret and any embedded subkeys should have already
++	 * been wiped when the last active reference to the fscrypt_master_key
++	 * struct was dropped; doing it here would be unnecessarily late.
++	 * Nevertheless, use kfree_sensitive() in case anything was missed.
++	 */
++	kfree_sensitive(mk);
++}
++
++void fscrypt_put_master_key(struct fscrypt_master_key *mk)
++{
++	if (!refcount_dec_and_test(&mk->mk_struct_refs))
++		return;
++	/*
++	 * No structural references left, so free ->mk_users, and also free the
++	 * fscrypt_master_key struct itself after an RCU grace period ensures
++	 * that concurrent keyring lookups can no longer find it.
++	 */
++	WARN_ON(refcount_read(&mk->mk_active_refs) != 0);
++	key_put(mk->mk_users);
++	mk->mk_users = NULL;
++	call_rcu(&mk->mk_rcu_head, fscrypt_free_master_key);
++}
++
++void fscrypt_put_master_key_activeref(struct fscrypt_master_key *mk)
+ {
++	struct super_block *sb = mk->mk_sb;
++	struct fscrypt_keyring *keyring = sb->s_master_keys;
+ 	size_t i;
+ 
+-	wipe_master_key_secret(&mk->mk_secret);
++	if (!refcount_dec_and_test(&mk->mk_active_refs))
++		return;
++	/*
++	 * No active references left, so complete the full removal of this
++	 * fscrypt_master_key struct by removing it from the keyring and
++	 * destroying any subkeys embedded in it.
++	 */
++
++	spin_lock(&keyring->lock);
++	hlist_del_rcu(&mk->mk_node);
++	spin_unlock(&keyring->lock);
++
++	/*
++	 * ->mk_active_refs == 0 implies that ->mk_secret is not present and
++	 * that ->mk_decrypted_inodes is empty.
++	 */
++	WARN_ON(is_master_key_secret_present(&mk->mk_secret));
++	WARN_ON(!list_empty(&mk->mk_decrypted_inodes));
+ 
+ 	for (i = 0; i <= FSCRYPT_MODE_MAX; i++) {
+ 		fscrypt_destroy_prepared_key(&mk->mk_direct_keys[i]);
+ 		fscrypt_destroy_prepared_key(&mk->mk_iv_ino_lblk_64_keys[i]);
+ 		fscrypt_destroy_prepared_key(&mk->mk_iv_ino_lblk_32_keys[i]);
+ 	}
++	memzero_explicit(&mk->mk_ino_hash_key,
++			 sizeof(mk->mk_ino_hash_key));
++	mk->mk_ino_hash_key_initialized = false;
+ 
+-	key_put(mk->mk_users);
+-	kfree_sensitive(mk);
++	/* Drop the structural ref associated with the active refs. */
++	fscrypt_put_master_key(mk);
+ }
+ 
+ static inline bool valid_key_spec(const struct fscrypt_key_specifier *spec)
+@@ -61,44 +124,6 @@ static inline bool valid_key_spec(const struct fscrypt_key_specifier *spec)
+ 	return master_key_spec_len(spec) != 0;
+ }
+ 
+-static int fscrypt_key_instantiate(struct key *key,
+-				   struct key_preparsed_payload *prep)
+-{
+-	key->payload.data[0] = (struct fscrypt_master_key *)prep->data;
+-	return 0;
+-}
+-
+-static void fscrypt_key_destroy(struct key *key)
+-{
+-	free_master_key(key->payload.data[0]);
+-}
+-
+-static void fscrypt_key_describe(const struct key *key, struct seq_file *m)
+-{
+-	seq_puts(m, key->description);
+-
+-	if (key_is_positive(key)) {
+-		const struct fscrypt_master_key *mk = key->payload.data[0];
+-
+-		if (!is_master_key_secret_present(&mk->mk_secret))
+-			seq_puts(m, ": secret removed");
+-	}
+-}
+-
+-/*
+- * Type of key in ->s_master_keys.  Each key of this type represents a master
+- * key which has been added to the filesystem.  Its payload is a
+- * 'struct fscrypt_master_key'.  The "." prefix in the key type name prevents
+- * users from adding keys of this type via the keyrings syscalls rather than via
+- * the intended method of FS_IOC_ADD_ENCRYPTION_KEY.
+- */
+-static struct key_type key_type_fscrypt = {
+-	.name			= "._fscrypt",
+-	.instantiate		= fscrypt_key_instantiate,
+-	.destroy		= fscrypt_key_destroy,
+-	.describe		= fscrypt_key_describe,
+-};
+-
+ static int fscrypt_user_key_instantiate(struct key *key,
+ 					struct key_preparsed_payload *prep)
+ {
+@@ -131,32 +156,6 @@ static struct key_type key_type_fscrypt_user = {
+ 	.describe		= fscrypt_user_key_describe,
+ };
+ 
+-/* Search ->s_master_keys or ->mk_users */
+-static struct key *search_fscrypt_keyring(struct key *keyring,
+-					  struct key_type *type,
+-					  const char *description)
+-{
+-	/*
+-	 * We need to mark the keyring reference as "possessed" so that we
+-	 * acquire permission to search it, via the KEY_POS_SEARCH permission.
+-	 */
+-	key_ref_t keyref = make_key_ref(keyring, true /* possessed */);
+-
+-	keyref = keyring_search(keyref, type, description, false);
+-	if (IS_ERR(keyref)) {
+-		if (PTR_ERR(keyref) == -EAGAIN || /* not found */
+-		    PTR_ERR(keyref) == -EKEYREVOKED) /* recently invalidated */
+-			keyref = ERR_PTR(-ENOKEY);
+-		return ERR_CAST(keyref);
+-	}
+-	return key_ref_to_ptr(keyref);
+-}
+-
+-#define FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE	\
+-	(CONST_STRLEN("fscrypt-") + sizeof_field(struct super_block, s_id))
+-
+-#define FSCRYPT_MK_DESCRIPTION_SIZE	(2 * FSCRYPT_KEY_IDENTIFIER_SIZE + 1)
+-
+ #define FSCRYPT_MK_USERS_DESCRIPTION_SIZE	\
+ 	(CONST_STRLEN("fscrypt-") + 2 * FSCRYPT_KEY_IDENTIFIER_SIZE + \
+ 	 CONST_STRLEN("-users") + 1)
+@@ -164,21 +163,6 @@ static struct key *search_fscrypt_keyring(struct key *keyring,
+ #define FSCRYPT_MK_USER_DESCRIPTION_SIZE	\
+ 	(2 * FSCRYPT_KEY_IDENTIFIER_SIZE + CONST_STRLEN(".uid.") + 10 + 1)
+ 
+-static void format_fs_keyring_description(
+-			char description[FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE],
+-			const struct super_block *sb)
+-{
+-	sprintf(description, "fscrypt-%s", sb->s_id);
+-}
+-
+-static void format_mk_description(
+-			char description[FSCRYPT_MK_DESCRIPTION_SIZE],
+-			const struct fscrypt_key_specifier *mk_spec)
+-{
+-	sprintf(description, "%*phN",
+-		master_key_spec_len(mk_spec), (u8 *)&mk_spec->u);
+-}
+-
+ static void format_mk_users_keyring_description(
+ 			char description[FSCRYPT_MK_USERS_DESCRIPTION_SIZE],
+ 			const u8 mk_identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
+@@ -199,20 +183,15 @@ static void format_mk_user_description(
+ /* Create ->s_master_keys if needed.  Synchronized by fscrypt_add_key_mutex. */
+ static int allocate_filesystem_keyring(struct super_block *sb)
+ {
+-	char description[FSCRYPT_FS_KEYRING_DESCRIPTION_SIZE];
+-	struct key *keyring;
++	struct fscrypt_keyring *keyring;
+ 
+ 	if (sb->s_master_keys)
+ 		return 0;
+ 
+-	format_fs_keyring_description(description, sb);
+-	keyring = keyring_alloc(description, GLOBAL_ROOT_UID, GLOBAL_ROOT_GID,
+-				current_cred(), KEY_POS_SEARCH |
+-				  KEY_USR_SEARCH | KEY_USR_READ | KEY_USR_VIEW,
+-				KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
+-	if (IS_ERR(keyring))
+-		return PTR_ERR(keyring);
+-
++	keyring = kzalloc(sizeof(*keyring), GFP_KERNEL);
++	if (!keyring)
++		return -ENOMEM;
++	spin_lock_init(&keyring->lock);
+ 	/*
+ 	 * Pairs with the smp_load_acquire() in fscrypt_find_master_key().
+ 	 * I.e., here we publish ->s_master_keys with a RELEASE barrier so that
+@@ -222,21 +201,80 @@ static int allocate_filesystem_keyring(struct super_block *sb)
+ 	return 0;
+ }
+ 
+-void fscrypt_sb_free(struct super_block *sb)
++/*
++ * Release all encryption keys that have been added to the filesystem, along
++ * with the keyring that contains them.
++ *
++ * This is called at unmount time.  The filesystem's underlying block device(s)
++ * are still available at this time; this is important because after user file
++ * accesses have been allowed, this function may need to evict keys from the
++ * keyslots of an inline crypto engine, which requires the block device(s).
++ *
++ * This is also called when the super_block is being freed.  This is needed to
++ * avoid a memory leak if mounting fails after the "test_dummy_encryption"
++ * option was processed, as in that case the unmount-time call isn't made.
++ */
++void fscrypt_destroy_keyring(struct super_block *sb)
+ {
+-	key_put(sb->s_master_keys);
++	struct fscrypt_keyring *keyring = sb->s_master_keys;
++	size_t i;
++
++	if (!keyring)
++		return;
++
++	for (i = 0; i < ARRAY_SIZE(keyring->key_hashtable); i++) {
++		struct hlist_head *bucket = &keyring->key_hashtable[i];
++		struct fscrypt_master_key *mk;
++		struct hlist_node *tmp;
++
++		hlist_for_each_entry_safe(mk, tmp, bucket, mk_node) {
++			/*
++			 * Since all inodes were already evicted, every key
++			 * remaining in the keyring should have an empty inode
++			 * list, and should only still be in the keyring due to
++			 * the single active ref associated with ->mk_secret.
++			 * There should be no structural refs beyond the one
++			 * associated with the active ref.
++			 */
++			WARN_ON(refcount_read(&mk->mk_active_refs) != 1);
++			WARN_ON(refcount_read(&mk->mk_struct_refs) != 1);
++			WARN_ON(!is_master_key_secret_present(&mk->mk_secret));
++			wipe_master_key_secret(&mk->mk_secret);
++			fscrypt_put_master_key_activeref(mk);
++		}
++	}
++	kfree_sensitive(keyring);
+ 	sb->s_master_keys = NULL;
+ }
+ 
++static struct hlist_head *
++fscrypt_mk_hash_bucket(struct fscrypt_keyring *keyring,
++		       const struct fscrypt_key_specifier *mk_spec)
++{
++	/*
++	 * Since key specifiers should be "random" values, it is sufficient to
++	 * use a trivial hash function that just takes the first several bits of
++	 * the key specifier.
++	 */
++	unsigned long i = get_unaligned((unsigned long *)&mk_spec->u);
++
++	return &keyring->key_hashtable[i % ARRAY_SIZE(keyring->key_hashtable)];
++}
++
+ /*
+- * Find the specified master key in ->s_master_keys.
+- * Returns ERR_PTR(-ENOKEY) if not found.
++ * Find the specified master key struct in ->s_master_keys and take a structural
++ * ref to it.  The structural ref guarantees that the key struct continues to
++ * exist, but it does *not* guarantee that ->s_master_keys continues to contain
++ * the key struct.  The structural ref needs to be dropped by
++ * fscrypt_put_master_key().  Returns NULL if the key struct is not found.
+  */
+-struct key *fscrypt_find_master_key(struct super_block *sb,
+-				    const struct fscrypt_key_specifier *mk_spec)
++struct fscrypt_master_key *
++fscrypt_find_master_key(struct super_block *sb,
++			const struct fscrypt_key_specifier *mk_spec)
+ {
+-	struct key *keyring;
+-	char description[FSCRYPT_MK_DESCRIPTION_SIZE];
++	struct fscrypt_keyring *keyring;
++	struct hlist_head *bucket;
++	struct fscrypt_master_key *mk;
+ 
+ 	/*
+ 	 * Pairs with the smp_store_release() in allocate_filesystem_keyring().
+@@ -246,10 +284,38 @@ struct key *fscrypt_find_master_key(struct super_block *sb,
+ 	 */
+ 	keyring = smp_load_acquire(&sb->s_master_keys);
+ 	if (keyring == NULL)
+-		return ERR_PTR(-ENOKEY); /* No keyring yet, so no keys yet. */
+-
+-	format_mk_description(description, mk_spec);
+-	return search_fscrypt_keyring(keyring, &key_type_fscrypt, description);
++		return NULL; /* No keyring yet, so no keys yet. */
++
++	bucket = fscrypt_mk_hash_bucket(keyring, mk_spec);
++	rcu_read_lock();
++	switch (mk_spec->type) {
++	case FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR:
++		hlist_for_each_entry_rcu(mk, bucket, mk_node) {
++			if (mk->mk_spec.type ==
++				FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR &&
++			    memcmp(mk->mk_spec.u.descriptor,
++				   mk_spec->u.descriptor,
++				   FSCRYPT_KEY_DESCRIPTOR_SIZE) == 0 &&
++			    refcount_inc_not_zero(&mk->mk_struct_refs))
++				goto out;
++		}
++		break;
++	case FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER:
++		hlist_for_each_entry_rcu(mk, bucket, mk_node) {
++			if (mk->mk_spec.type ==
++				FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER &&
++			    memcmp(mk->mk_spec.u.identifier,
++				   mk_spec->u.identifier,
++				   FSCRYPT_KEY_IDENTIFIER_SIZE) == 0 &&
++			    refcount_inc_not_zero(&mk->mk_struct_refs))
++				goto out;
++		}
++		break;
++	}
++	mk = NULL;
++out:
++	rcu_read_unlock();
++	return mk;
+ }
+ 
+ static int allocate_master_key_users_keyring(struct fscrypt_master_key *mk)
+@@ -277,17 +343,30 @@ static int allocate_master_key_users_keyring(struct fscrypt_master_key *mk)
+ static struct key *find_master_key_user(struct fscrypt_master_key *mk)
+ {
+ 	char description[FSCRYPT_MK_USER_DESCRIPTION_SIZE];
++	key_ref_t keyref;
+ 
+ 	format_mk_user_description(description, mk->mk_spec.u.identifier);
+-	return search_fscrypt_keyring(mk->mk_users, &key_type_fscrypt_user,
+-				      description);
++
++	/*
++	 * We need to mark the keyring reference as "possessed" so that we
++	 * acquire permission to search it, via the KEY_POS_SEARCH permission.
++	 */
++	keyref = keyring_search(make_key_ref(mk->mk_users, true /*possessed*/),
++				&key_type_fscrypt_user, description, false);
++	if (IS_ERR(keyref)) {
++		if (PTR_ERR(keyref) == -EAGAIN || /* not found */
++		    PTR_ERR(keyref) == -EKEYREVOKED) /* recently invalidated */
++			keyref = ERR_PTR(-ENOKEY);
++		return ERR_CAST(keyref);
++	}
++	return key_ref_to_ptr(keyref);
+ }
+ 
+ /*
+  * Give the current user a "key" in ->mk_users.  This charges the user's quota
+  * and marks the master key as added by the current user, so that it cannot be
+- * removed by another user with the key.  Either the master key's key->sem must
+- * be held for write, or the master key must be still undergoing initialization.
++ * removed by another user with the key.  Either ->mk_sem must be held for
++ * write, or the master key must be still undergoing initialization.
+  */
+ static int add_master_key_user(struct fscrypt_master_key *mk)
+ {
+@@ -309,7 +388,7 @@ static int add_master_key_user(struct fscrypt_master_key *mk)
+ 
+ /*
+  * Remove the current user's "key" from ->mk_users.
+- * The master key's key->sem must be held for write.
++ * ->mk_sem must be held for write.
+  *
+  * Returns 0 if removed, -ENOKEY if not found, or another -errno code.
+  */
+@@ -327,63 +406,49 @@ static int remove_master_key_user(struct fscrypt_master_key *mk)
+ }
+ 
+ /*
+- * Allocate a new fscrypt_master_key which contains the given secret, set it as
+- * the payload of a new 'struct key' of type fscrypt, and link the 'struct key'
+- * into the given keyring.  Synchronized by fscrypt_add_key_mutex.
++ * Allocate a new fscrypt_master_key, transfer the given secret over to it, and
++ * insert it into sb->s_master_keys.
+  */
+-static int add_new_master_key(struct fscrypt_master_key_secret *secret,
+-			      const struct fscrypt_key_specifier *mk_spec,
+-			      struct key *keyring)
++static int add_new_master_key(struct super_block *sb,
++			      struct fscrypt_master_key_secret *secret,
++			      const struct fscrypt_key_specifier *mk_spec)
+ {
++	struct fscrypt_keyring *keyring = sb->s_master_keys;
+ 	struct fscrypt_master_key *mk;
+-	char description[FSCRYPT_MK_DESCRIPTION_SIZE];
+-	struct key *key;
+ 	int err;
+ 
+ 	mk = kzalloc(sizeof(*mk), GFP_KERNEL);
+ 	if (!mk)
+ 		return -ENOMEM;
+ 
++	mk->mk_sb = sb;
++	init_rwsem(&mk->mk_sem);
++	refcount_set(&mk->mk_struct_refs, 1);
+ 	mk->mk_spec = *mk_spec;
+ 
+-	move_master_key_secret(&mk->mk_secret, secret);
+-
+-	refcount_set(&mk->mk_refcount, 1); /* secret is present */
+ 	INIT_LIST_HEAD(&mk->mk_decrypted_inodes);
+ 	spin_lock_init(&mk->mk_decrypted_inodes_lock);
+ 
+ 	if (mk_spec->type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
+ 		err = allocate_master_key_users_keyring(mk);
+ 		if (err)
+-			goto out_free_mk;
++			goto out_put;
+ 		err = add_master_key_user(mk);
+ 		if (err)
+-			goto out_free_mk;
++			goto out_put;
+ 	}
+ 
+-	/*
+-	 * Note that we don't charge this key to anyone's quota, since when
+-	 * ->mk_users is in use those keys are charged instead, and otherwise
+-	 * (when ->mk_users isn't in use) only root can add these keys.
+-	 */
+-	format_mk_description(description, mk_spec);
+-	key = key_alloc(&key_type_fscrypt, description,
+-			GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
+-			KEY_POS_SEARCH | KEY_USR_SEARCH | KEY_USR_VIEW,
+-			KEY_ALLOC_NOT_IN_QUOTA, NULL);
+-	if (IS_ERR(key)) {
+-		err = PTR_ERR(key);
+-		goto out_free_mk;
+-	}
+-	err = key_instantiate_and_link(key, mk, sizeof(*mk), keyring, NULL);
+-	key_put(key);
+-	if (err)
+-		goto out_free_mk;
++	move_master_key_secret(&mk->mk_secret, secret);
++	refcount_set(&mk->mk_active_refs, 1); /* ->mk_secret is present */
+ 
++	spin_lock(&keyring->lock);
++	hlist_add_head_rcu(&mk->mk_node,
++			   fscrypt_mk_hash_bucket(keyring, mk_spec));
++	spin_unlock(&keyring->lock);
+ 	return 0;
+ 
+-out_free_mk:
+-	free_master_key(mk);
++out_put:
++	fscrypt_put_master_key(mk);
+ 	return err;
+ }
+ 
+@@ -392,42 +457,34 @@ out_free_mk:
+ static int add_existing_master_key(struct fscrypt_master_key *mk,
+ 				   struct fscrypt_master_key_secret *secret)
+ {
+-	struct key *mk_user;
+-	bool rekey;
+ 	int err;
+ 
+ 	/*
+ 	 * If the current user is already in ->mk_users, then there's nothing to
+-	 * do.  (Not applicable for v1 policy keys, which have NULL ->mk_users.)
++	 * do.  Otherwise, we need to add the user to ->mk_users.  (Neither is
++	 * applicable for v1 policy keys, which have NULL ->mk_users.)
+ 	 */
+ 	if (mk->mk_users) {
+-		mk_user = find_master_key_user(mk);
++		struct key *mk_user = find_master_key_user(mk);
++
+ 		if (mk_user != ERR_PTR(-ENOKEY)) {
+ 			if (IS_ERR(mk_user))
+ 				return PTR_ERR(mk_user);
+ 			key_put(mk_user);
+ 			return 0;
+ 		}
+-	}
+-
+-	/* If we'll be re-adding ->mk_secret, try to take the reference. */
+-	rekey = !is_master_key_secret_present(&mk->mk_secret);
+-	if (rekey && !refcount_inc_not_zero(&mk->mk_refcount))
+-		return KEY_DEAD;
+-
+-	/* Add the current user to ->mk_users, if applicable. */
+-	if (mk->mk_users) {
+ 		err = add_master_key_user(mk);
+-		if (err) {
+-			if (rekey && refcount_dec_and_test(&mk->mk_refcount))
+-				return KEY_DEAD;
++		if (err)
+ 			return err;
+-		}
+ 	}
+ 
+ 	/* Re-add the secret if needed. */
+-	if (rekey)
++	if (!is_master_key_secret_present(&mk->mk_secret)) {
++		if (!refcount_inc_not_zero(&mk->mk_active_refs))
++			return KEY_DEAD;
+ 		move_master_key_secret(&mk->mk_secret, secret);
++	}
++
+ 	return 0;
+ }
+ 
+@@ -436,38 +493,36 @@ static int do_add_master_key(struct super_block *sb,
+ 			     const struct fscrypt_key_specifier *mk_spec)
+ {
+ 	static DEFINE_MUTEX(fscrypt_add_key_mutex);
+-	struct key *key;
++	struct fscrypt_master_key *mk;
+ 	int err;
+ 
+ 	mutex_lock(&fscrypt_add_key_mutex); /* serialize find + link */
+-retry:
+-	key = fscrypt_find_master_key(sb, mk_spec);
+-	if (IS_ERR(key)) {
+-		err = PTR_ERR(key);
+-		if (err != -ENOKEY)
+-			goto out_unlock;
++
++	mk = fscrypt_find_master_key(sb, mk_spec);
++	if (!mk) {
+ 		/* Didn't find the key in ->s_master_keys.  Add it. */
+ 		err = allocate_filesystem_keyring(sb);
+-		if (err)
+-			goto out_unlock;
+-		err = add_new_master_key(secret, mk_spec, sb->s_master_keys);
++		if (!err)
++			err = add_new_master_key(sb, secret, mk_spec);
+ 	} else {
+ 		/*
+ 		 * Found the key in ->s_master_keys.  Re-add the secret if
+ 		 * needed, and add the user to ->mk_users if needed.
+ 		 */
+-		down_write(&key->sem);
+-		err = add_existing_master_key(key->payload.data[0], secret);
+-		up_write(&key->sem);
++		down_write(&mk->mk_sem);
++		err = add_existing_master_key(mk, secret);
++		up_write(&mk->mk_sem);
+ 		if (err == KEY_DEAD) {
+-			/* Key being removed or needs to be removed */
+-			key_invalidate(key);
+-			key_put(key);
+-			goto retry;
++			/*
++			 * We found a key struct, but it's already been fully
++			 * removed.  Ignore the old struct and add a new one.
++			 * fscrypt_add_key_mutex means we don't need to worry
++			 * about concurrent adds.
++			 */
++			err = add_new_master_key(sb, secret, mk_spec);
+ 		}
+-		key_put(key);
++		fscrypt_put_master_key(mk);
+ 	}
+-out_unlock:
+ 	mutex_unlock(&fscrypt_add_key_mutex);
+ 	return err;
+ }
+@@ -771,19 +826,19 @@ int fscrypt_verify_key_added(struct super_block *sb,
+ 			     const u8 identifier[FSCRYPT_KEY_IDENTIFIER_SIZE])
+ {
+ 	struct fscrypt_key_specifier mk_spec;
+-	struct key *key, *mk_user;
+ 	struct fscrypt_master_key *mk;
++	struct key *mk_user;
+ 	int err;
+ 
+ 	mk_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
+ 	memcpy(mk_spec.u.identifier, identifier, FSCRYPT_KEY_IDENTIFIER_SIZE);
+ 
+-	key = fscrypt_find_master_key(sb, &mk_spec);
+-	if (IS_ERR(key)) {
+-		err = PTR_ERR(key);
++	mk = fscrypt_find_master_key(sb, &mk_spec);
++	if (!mk) {
++		err = -ENOKEY;
+ 		goto out;
+ 	}
+-	mk = key->payload.data[0];
++	down_read(&mk->mk_sem);
+ 	mk_user = find_master_key_user(mk);
+ 	if (IS_ERR(mk_user)) {
+ 		err = PTR_ERR(mk_user);
+@@ -791,7 +846,8 @@ int fscrypt_verify_key_added(struct super_block *sb,
+ 		key_put(mk_user);
+ 		err = 0;
+ 	}
+-	key_put(key);
++	up_read(&mk->mk_sem);
++	fscrypt_put_master_key(mk);
+ out:
+ 	if (err == -ENOKEY && capable(CAP_FOWNER))
+ 		err = 0;
+@@ -953,11 +1009,10 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
+ 	struct super_block *sb = file_inode(filp)->i_sb;
+ 	struct fscrypt_remove_key_arg __user *uarg = _uarg;
+ 	struct fscrypt_remove_key_arg arg;
+-	struct key *key;
+ 	struct fscrypt_master_key *mk;
+ 	u32 status_flags = 0;
+ 	int err;
+-	bool dead;
++	bool inodes_remain;
+ 
+ 	if (copy_from_user(&arg, uarg, sizeof(arg)))
+ 		return -EFAULT;
+@@ -977,12 +1032,10 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
+ 		return -EACCES;
+ 
+ 	/* Find the key being removed. */
+-	key = fscrypt_find_master_key(sb, &arg.key_spec);
+-	if (IS_ERR(key))
+-		return PTR_ERR(key);
+-	mk = key->payload.data[0];
+-
+-	down_write(&key->sem);
++	mk = fscrypt_find_master_key(sb, &arg.key_spec);
++	if (!mk)
++		return -ENOKEY;
++	down_write(&mk->mk_sem);
+ 
+ 	/* If relevant, remove current user's (or all users) claim to the key */
+ 	if (mk->mk_users && mk->mk_users->keys.nr_leaves_on_tree != 0) {
+@@ -991,7 +1044,7 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
+ 		else
+ 			err = remove_master_key_user(mk);
+ 		if (err) {
+-			up_write(&key->sem);
++			up_write(&mk->mk_sem);
+ 			goto out_put_key;
+ 		}
+ 		if (mk->mk_users->keys.nr_leaves_on_tree != 0) {
+@@ -1003,26 +1056,22 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
+ 			status_flags |=
+ 				FSCRYPT_KEY_REMOVAL_STATUS_FLAG_OTHER_USERS;
+ 			err = 0;
+-			up_write(&key->sem);
++			up_write(&mk->mk_sem);
+ 			goto out_put_key;
+ 		}
+ 	}
+ 
+ 	/* No user claims remaining.  Go ahead and wipe the secret. */
+-	dead = false;
++	err = -ENOKEY;
+ 	if (is_master_key_secret_present(&mk->mk_secret)) {
+ 		wipe_master_key_secret(&mk->mk_secret);
+-		dead = refcount_dec_and_test(&mk->mk_refcount);
+-	}
+-	up_write(&key->sem);
+-	if (dead) {
+-		/*
+-		 * No inodes reference the key, and we wiped the secret, so the
+-		 * key object is free to be removed from the keyring.
+-		 */
+-		key_invalidate(key);
++		fscrypt_put_master_key_activeref(mk);
+ 		err = 0;
+-	} else {
++	}
++	inodes_remain = refcount_read(&mk->mk_active_refs) > 0;
++	up_write(&mk->mk_sem);
++
++	if (inodes_remain) {
+ 		/* Some inodes still reference this key; try to evict them. */
+ 		err = try_to_lock_encrypted_files(sb, mk);
+ 		if (err == -EBUSY) {
+@@ -1038,7 +1087,7 @@ static int do_remove_key(struct file *filp, void __user *_uarg, bool all_users)
+ 	 * has been fully removed including all files locked.
+ 	 */
+ out_put_key:
+-	key_put(key);
++	fscrypt_put_master_key(mk);
+ 	if (err == 0)
+ 		err = put_user(status_flags, &uarg->removal_status_flags);
+ 	return err;
+@@ -1085,7 +1134,6 @@ int fscrypt_ioctl_get_key_status(struct file *filp, void __user *uarg)
+ {
+ 	struct super_block *sb = file_inode(filp)->i_sb;
+ 	struct fscrypt_get_key_status_arg arg;
+-	struct key *key;
+ 	struct fscrypt_master_key *mk;
+ 	int err;
+ 
+@@ -1102,19 +1150,18 @@ int fscrypt_ioctl_get_key_status(struct file *filp, void __user *uarg)
+ 	arg.user_count = 0;
+ 	memset(arg.__out_reserved, 0, sizeof(arg.__out_reserved));
+ 
+-	key = fscrypt_find_master_key(sb, &arg.key_spec);
+-	if (IS_ERR(key)) {
+-		if (key != ERR_PTR(-ENOKEY))
+-			return PTR_ERR(key);
++	mk = fscrypt_find_master_key(sb, &arg.key_spec);
++	if (!mk) {
+ 		arg.status = FSCRYPT_KEY_STATUS_ABSENT;
+ 		err = 0;
+ 		goto out;
+ 	}
+-	mk = key->payload.data[0];
+-	down_read(&key->sem);
++	down_read(&mk->mk_sem);
+ 
+ 	if (!is_master_key_secret_present(&mk->mk_secret)) {
+-		arg.status = FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED;
++		arg.status = refcount_read(&mk->mk_active_refs) > 0 ?
++			FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED :
++			FSCRYPT_KEY_STATUS_ABSENT /* raced with full removal */;
+ 		err = 0;
+ 		goto out_release_key;
+ 	}
+@@ -1136,8 +1183,8 @@ int fscrypt_ioctl_get_key_status(struct file *filp, void __user *uarg)
+ 	}
+ 	err = 0;
+ out_release_key:
+-	up_read(&key->sem);
+-	key_put(key);
++	up_read(&mk->mk_sem);
++	fscrypt_put_master_key(mk);
+ out:
+ 	if (!err && copy_to_user(uarg, &arg, sizeof(arg)))
+ 		err = -EFAULT;
+@@ -1149,13 +1196,9 @@ int __init fscrypt_init_keyring(void)
+ {
+ 	int err;
+ 
+-	err = register_key_type(&key_type_fscrypt);
+-	if (err)
+-		return err;
+-
+ 	err = register_key_type(&key_type_fscrypt_user);
+ 	if (err)
+-		goto err_unregister_fscrypt;
++		return err;
+ 
+ 	err = register_key_type(&key_type_fscrypt_provisioning);
+ 	if (err)
+@@ -1165,7 +1208,5 @@ int __init fscrypt_init_keyring(void)
+ 
+ err_unregister_fscrypt_user:
+ 	unregister_key_type(&key_type_fscrypt_user);
+-err_unregister_fscrypt:
+-	unregister_key_type(&key_type_fscrypt);
+ 	return err;
+ }
+diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c
+index fbc71abdabe32..e037a7b8e9e42 100644
+--- a/fs/crypto/keysetup.c
++++ b/fs/crypto/keysetup.c
+@@ -9,7 +9,6 @@
+  */
+ 
+ #include <crypto/skcipher.h>
+-#include <linux/key.h>
+ #include <linux/random.h>
+ 
+ #include "fscrypt_private.h"
+@@ -159,6 +158,7 @@ void fscrypt_destroy_prepared_key(struct fscrypt_prepared_key *prep_key)
+ {
+ 	crypto_free_skcipher(prep_key->tfm);
+ 	fscrypt_destroy_inline_crypt_key(prep_key);
++	memzero_explicit(prep_key, sizeof(*prep_key));
+ }
+ 
+ /* Given a per-file encryption key, set up the file's crypto transform object */
+@@ -412,20 +412,18 @@ static bool fscrypt_valid_master_key_size(const struct fscrypt_master_key *mk,
+ /*
+  * Find the master key, then set up the inode's actual encryption key.
+  *
+- * If the master key is found in the filesystem-level keyring, then the
+- * corresponding 'struct key' is returned in *master_key_ret with its semaphore
+- * read-locked.  This is needed to ensure that only one task links the
+- * fscrypt_info into ->mk_decrypted_inodes (as multiple tasks may race to create
+- * an fscrypt_info for the same inode), and to synchronize the master key being
+- * removed with a new inode starting to use it.
++ * If the master key is found in the filesystem-level keyring, then it is
++ * returned in *mk_ret with its semaphore read-locked.  This is needed to ensure
++ * that only one task links the fscrypt_info into ->mk_decrypted_inodes (as
++ * multiple tasks may race to create an fscrypt_info for the same inode), and to
++ * synchronize the master key being removed with a new inode starting to use it.
+  */
+ static int setup_file_encryption_key(struct fscrypt_info *ci,
+ 				     bool need_dirhash_key,
+-				     struct key **master_key_ret)
++				     struct fscrypt_master_key **mk_ret)
+ {
+-	struct key *key;
+-	struct fscrypt_master_key *mk = NULL;
+ 	struct fscrypt_key_specifier mk_spec;
++	struct fscrypt_master_key *mk;
+ 	int err;
+ 
+ 	err = fscrypt_select_encryption_impl(ci);
+@@ -436,11 +434,10 @@ static int setup_file_encryption_key(struct fscrypt_info *ci,
+ 	if (err)
+ 		return err;
+ 
+-	key = fscrypt_find_master_key(ci->ci_inode->i_sb, &mk_spec);
+-	if (IS_ERR(key)) {
+-		if (key != ERR_PTR(-ENOKEY) ||
+-		    ci->ci_policy.version != FSCRYPT_POLICY_V1)
+-			return PTR_ERR(key);
++	mk = fscrypt_find_master_key(ci->ci_inode->i_sb, &mk_spec);
++	if (!mk) {
++		if (ci->ci_policy.version != FSCRYPT_POLICY_V1)
++			return -ENOKEY;
+ 
+ 		/*
+ 		 * As a legacy fallback for v1 policies, search for the key in
+@@ -450,9 +447,7 @@ static int setup_file_encryption_key(struct fscrypt_info *ci,
+ 		 */
+ 		return fscrypt_setup_v1_file_key_via_subscribed_keyrings(ci);
+ 	}
+-
+-	mk = key->payload.data[0];
+-	down_read(&key->sem);
++	down_read(&mk->mk_sem);
+ 
+ 	/* Has the secret been removed (via FS_IOC_REMOVE_ENCRYPTION_KEY)? */
+ 	if (!is_master_key_secret_present(&mk->mk_secret)) {
+@@ -480,18 +475,18 @@ static int setup_file_encryption_key(struct fscrypt_info *ci,
+ 	if (err)
+ 		goto out_release_key;
+ 
+-	*master_key_ret = key;
++	*mk_ret = mk;
+ 	return 0;
+ 
+ out_release_key:
+-	up_read(&key->sem);
+-	key_put(key);
++	up_read(&mk->mk_sem);
++	fscrypt_put_master_key(mk);
+ 	return err;
+ }
+ 
+ static void put_crypt_info(struct fscrypt_info *ci)
+ {
+-	struct key *key;
++	struct fscrypt_master_key *mk;
+ 
+ 	if (!ci)
+ 		return;
+@@ -501,24 +496,18 @@ static void put_crypt_info(struct fscrypt_info *ci)
+ 	else if (ci->ci_owns_key)
+ 		fscrypt_destroy_prepared_key(&ci->ci_enc_key);
+ 
+-	key = ci->ci_master_key;
+-	if (key) {
+-		struct fscrypt_master_key *mk = key->payload.data[0];
+-
++	mk = ci->ci_master_key;
++	if (mk) {
+ 		/*
+ 		 * Remove this inode from the list of inodes that were unlocked
+-		 * with the master key.
+-		 *
+-		 * In addition, if we're removing the last inode from a key that
+-		 * already had its secret removed, invalidate the key so that it
+-		 * gets removed from ->s_master_keys.
++		 * with the master key.  In addition, if we're removing the last
++		 * inode from a master key struct that already had its secret
++		 * removed, then complete the full removal of the struct.
+ 		 */
+ 		spin_lock(&mk->mk_decrypted_inodes_lock);
+ 		list_del(&ci->ci_master_key_link);
+ 		spin_unlock(&mk->mk_decrypted_inodes_lock);
+-		if (refcount_dec_and_test(&mk->mk_refcount))
+-			key_invalidate(key);
+-		key_put(key);
++		fscrypt_put_master_key_activeref(mk);
+ 	}
+ 	memzero_explicit(ci, sizeof(*ci));
+ 	kmem_cache_free(fscrypt_info_cachep, ci);
+@@ -532,7 +521,7 @@ fscrypt_setup_encryption_info(struct inode *inode,
+ {
+ 	struct fscrypt_info *crypt_info;
+ 	struct fscrypt_mode *mode;
+-	struct key *master_key = NULL;
++	struct fscrypt_master_key *mk = NULL;
+ 	int res;
+ 
+ 	res = fscrypt_initialize(inode->i_sb->s_cop->flags);
+@@ -555,8 +544,7 @@ fscrypt_setup_encryption_info(struct inode *inode,
+ 	WARN_ON(mode->ivsize > FSCRYPT_MAX_IV_SIZE);
+ 	crypt_info->ci_mode = mode;
+ 
+-	res = setup_file_encryption_key(crypt_info, need_dirhash_key,
+-					&master_key);
++	res = setup_file_encryption_key(crypt_info, need_dirhash_key, &mk);
+ 	if (res)
+ 		goto out;
+ 
+@@ -571,12 +559,9 @@ fscrypt_setup_encryption_info(struct inode *inode,
+ 		 * We won the race and set ->i_crypt_info to our crypt_info.
+ 		 * Now link it into the master key's inode list.
+ 		 */
+-		if (master_key) {
+-			struct fscrypt_master_key *mk =
+-				master_key->payload.data[0];
+-
+-			refcount_inc(&mk->mk_refcount);
+-			crypt_info->ci_master_key = key_get(master_key);
++		if (mk) {
++			crypt_info->ci_master_key = mk;
++			refcount_inc(&mk->mk_active_refs);
+ 			spin_lock(&mk->mk_decrypted_inodes_lock);
+ 			list_add(&crypt_info->ci_master_key_link,
+ 				 &mk->mk_decrypted_inodes);
+@@ -586,9 +571,9 @@ fscrypt_setup_encryption_info(struct inode *inode,
+ 	}
+ 	res = 0;
+ out:
+-	if (master_key) {
+-		up_read(&master_key->sem);
+-		key_put(master_key);
++	if (mk) {
++		up_read(&mk->mk_sem);
++		fscrypt_put_master_key(mk);
+ 	}
+ 	put_crypt_info(crypt_info);
+ 	return res;
+@@ -753,7 +738,6 @@ EXPORT_SYMBOL(fscrypt_free_inode);
+ int fscrypt_drop_inode(struct inode *inode)
+ {
+ 	const struct fscrypt_info *ci = fscrypt_get_info(inode);
+-	const struct fscrypt_master_key *mk;
+ 
+ 	/*
+ 	 * If ci is NULL, then the inode doesn't have an encryption key set up
+@@ -763,7 +747,6 @@ int fscrypt_drop_inode(struct inode *inode)
+ 	 */
+ 	if (!ci || !ci->ci_master_key)
+ 		return 0;
+-	mk = ci->ci_master_key->payload.data[0];
+ 
+ 	/*
+ 	 * With proper, non-racy use of FS_IOC_REMOVE_ENCRYPTION_KEY, all inodes
+@@ -782,6 +765,6 @@ int fscrypt_drop_inode(struct inode *inode)
+ 	 * then the thread removing the key will either evict the inode itself
+ 	 * or will correctly detect that it wasn't evicted due to the race.
+ 	 */
+-	return !is_master_key_secret_present(&mk->mk_secret);
++	return !is_master_key_secret_present(&ci->ci_master_key->mk_secret);
+ }
+ EXPORT_SYMBOL_GPL(fscrypt_drop_inode);
+diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c
+index 80b8ca0f340b2..8485e7eaee2b3 100644
+--- a/fs/crypto/policy.c
++++ b/fs/crypto/policy.c
+@@ -744,12 +744,8 @@ int fscrypt_set_context(struct inode *inode, void *fs_data)
+ 	 * delayed key setup that requires the inode number.
+ 	 */
+ 	if (ci->ci_policy.version == FSCRYPT_POLICY_V2 &&
+-	    (ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) {
+-		const struct fscrypt_master_key *mk =
+-			ci->ci_master_key->payload.data[0];
+-
+-		fscrypt_hash_inode_number(ci, mk);
+-	}
++	    (ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32))
++		fscrypt_hash_inode_number(ci, ci->ci_master_key);
+ 
+ 	return inode->i_sb->s_cop->set_context(inode, &ctx, ctxsize, fs_data);
+ }
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index ad3a294a88eb2..eed8bd7812d58 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -145,9 +145,8 @@ static int ext4_update_backup_sb(struct super_block *sb,
+ 	if (ext4_has_metadata_csum(sb) &&
+ 	    es->s_checksum != ext4_superblock_csum(sb, es)) {
+ 		ext4_msg(sb, KERN_ERR, "Invalid checksum for backup "
+-		"superblock %llu\n", sb_block);
++		"superblock %llu", sb_block);
+ 		unlock_buffer(bh);
+-		err = -EFSBADCRC;
+ 		goto out_bh;
+ 	}
+ 	func(es, arg);
+diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
+index 54e7d3c95fd71..35ca468109be9 100644
+--- a/fs/ext4/migrate.c
++++ b/fs/ext4/migrate.c
+@@ -425,7 +425,8 @@ int ext4_ext_migrate(struct inode *inode)
+ 	 * already is extent-based, error out.
+ 	 */
+ 	if (!ext4_has_feature_extents(inode->i_sb) ||
+-	    (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
++	    ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) ||
++	    ext4_has_inline_data(inode))
+ 		return -EINVAL;
+ 
+ 	if (S_ISLNK(inode->i_mode) && inode->i_blocks == 0)
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 4183a4cb4a21e..be8136aafa22c 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2259,8 +2259,16 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
+ 	memset(de, 0, len); /* wipe old data */
+ 	de = (struct ext4_dir_entry_2 *) data2;
+ 	top = data2 + len;
+-	while ((char *)(de2 = ext4_next_entry(de, blocksize)) < top)
++	while ((char *)(de2 = ext4_next_entry(de, blocksize)) < top) {
++		if (ext4_check_dir_entry(dir, NULL, de, bh2, data2, len,
++					 (data2 + (blocksize - csum_size) -
++					  (char *) de))) {
++			brelse(bh2);
++			brelse(bh);
++			return -EFSCORRUPTED;
++		}
+ 		de = de2;
++	}
+ 	de->rec_len = ext4_rec_len_to_disk(data2 + (blocksize - csum_size) -
+ 					   (char *) de, blocksize);
+ 
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index 6dfe9ccae0c50..46b87ffeb3045 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -1158,6 +1158,7 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
+ 	while (group < sbi->s_groups_count) {
+ 		struct buffer_head *bh;
+ 		ext4_fsblk_t backup_block;
++		struct ext4_super_block *es;
+ 
+ 		/* Out of journal space, and can't get more - abort - so sad */
+ 		err = ext4_resize_ensure_credits_batch(handle, 1);
+@@ -1186,6 +1187,10 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data,
+ 		memcpy(bh->b_data, data, size);
+ 		if (rest)
+ 			memset(bh->b_data + size, 0, rest);
++		es = (struct ext4_super_block *) bh->b_data;
++		es->s_block_group_nr = cpu_to_le16(group);
++		if (ext4_has_metadata_csum(sb))
++			es->s_checksum = ext4_superblock_csum(sb, es);
+ 		set_buffer_uptodate(bh);
+ 		unlock_buffer(bh);
+ 		err = ext4_handle_dirty_metadata(handle, NULL, bh);
+diff --git a/fs/ext4/verity.c b/fs/ext4/verity.c
+index b051d19b5c8a0..94442c690ca7d 100644
+--- a/fs/ext4/verity.c
++++ b/fs/ext4/verity.c
+@@ -365,13 +365,14 @@ static struct page *ext4_read_merkle_tree_page(struct inode *inode,
+ 					       pgoff_t index,
+ 					       unsigned long num_ra_pages)
+ {
+-	DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index);
+ 	struct page *page;
+ 
+ 	index += ext4_verity_metadata_pos(inode) >> PAGE_SHIFT;
+ 
+ 	page = find_get_page_flags(inode->i_mapping, index, FGP_ACCESSED);
+ 	if (!page || !PageUptodate(page)) {
++		DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index);
++
+ 		if (page)
+ 			put_page(page);
+ 		else if (num_ra_pages > 1)
+diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c
+index 7b8f2b41c29b1..c0733f8670746 100644
+--- a/fs/f2fs/verity.c
++++ b/fs/f2fs/verity.c
+@@ -262,13 +262,14 @@ static struct page *f2fs_read_merkle_tree_page(struct inode *inode,
+ 					       pgoff_t index,
+ 					       unsigned long num_ra_pages)
+ {
+-	DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index);
+ 	struct page *page;
+ 
+ 	index += f2fs_verity_metadata_pos(inode) >> PAGE_SHIFT;
+ 
+ 	page = find_get_page_flags(inode->i_mapping, index, FGP_ACCESSED);
+ 	if (!page || !PageUptodate(page)) {
++		DEFINE_READAHEAD(ractl, NULL, NULL, inode->i_mapping, index);
++
+ 		if (page)
+ 			put_page(page);
+ 		else if (num_ra_pages > 1)
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 1a3afd469e3a9..71bfb663aac58 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -3001,6 +3001,10 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
+ 			goto out;
+ 	}
+ 
++	err = file_modified(file);
++	if (err)
++		goto out;
++
+ 	if (!(mode & FALLOC_FL_KEEP_SIZE))
+ 		set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
+ 
+diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c
+index b4e5657110457..e8deaacf1832a 100644
+--- a/fs/fuse/readdir.c
++++ b/fs/fuse/readdir.c
+@@ -77,8 +77,10 @@ static void fuse_add_dirent_to_cache(struct file *file,
+ 		goto unlock;
+ 
+ 	addr = kmap_local_page(page);
+-	if (!offset)
++	if (!offset) {
+ 		clear_page(addr);
++		SetPageUptodate(page);
++	}
+ 	memcpy(addr + offset, dirent, reclen);
+ 	kunmap_local(addr);
+ 	fi->rdc.size = (index << PAGE_SHIFT) + offset + reclen;
+@@ -516,6 +518,12 @@ retry_locked:
+ 
+ 	page = find_get_page_flags(file->f_mapping, index,
+ 				   FGP_ACCESSED | FGP_LOCK);
++	/* Page gone missing, then re-added to cache, but not initialized? */
++	if (page && !PageUptodate(page)) {
++		unlock_page(page);
++		put_page(page);
++		page = NULL;
++	}
+ 	spin_lock(&fi->rdc.lock);
+ 	if (!page) {
+ 		/*
+diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
+index 5c97cad741a73..ead8a0e06abf9 100644
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -228,8 +228,7 @@ again:
+  *
+  */
+ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
+-				  fmode_t type,
+-				  const nfs4_stateid *stateid,
++				  fmode_t type, const nfs4_stateid *stateid,
+ 				  unsigned long pagemod_limit)
+ {
+ 	struct nfs_delegation *delegation;
+@@ -239,25 +238,24 @@ void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
+ 	delegation = rcu_dereference(NFS_I(inode)->delegation);
+ 	if (delegation != NULL) {
+ 		spin_lock(&delegation->lock);
+-		if (nfs4_is_valid_delegation(delegation, 0)) {
+-			nfs4_stateid_copy(&delegation->stateid, stateid);
+-			delegation->type = type;
+-			delegation->pagemod_limit = pagemod_limit;
+-			oldcred = delegation->cred;
+-			delegation->cred = get_cred(cred);
+-			clear_bit(NFS_DELEGATION_NEED_RECLAIM,
+-				  &delegation->flags);
+-			spin_unlock(&delegation->lock);
+-			rcu_read_unlock();
+-			put_cred(oldcred);
+-			trace_nfs4_reclaim_delegation(inode, type);
+-			return;
+-		}
+-		/* We appear to have raced with a delegation return. */
++		nfs4_stateid_copy(&delegation->stateid, stateid);
++		delegation->type = type;
++		delegation->pagemod_limit = pagemod_limit;
++		oldcred = delegation->cred;
++		delegation->cred = get_cred(cred);
++		clear_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
++		if (test_and_clear_bit(NFS_DELEGATION_REVOKED,
++				       &delegation->flags))
++			atomic_long_inc(&nfs_active_delegations);
+ 		spin_unlock(&delegation->lock);
++		rcu_read_unlock();
++		put_cred(oldcred);
++		trace_nfs4_reclaim_delegation(inode, type);
++	} else {
++		rcu_read_unlock();
++		nfs_inode_set_delegation(inode, cred, type, stateid,
++					 pagemod_limit);
+ 	}
+-	rcu_read_unlock();
+-	nfs_inode_set_delegation(inode, cred, type, stateid, pagemod_limit);
+ }
+ 
+ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
+diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
+index 6dab9e4083729..21c9e97c3ba30 100644
+--- a/fs/nfs/nfs42proc.c
++++ b/fs/nfs/nfs42proc.c
+@@ -1093,6 +1093,9 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
+ 				&args.seq_args, &res.seq_res, 0);
+ 	trace_nfs4_clone(src_inode, dst_inode, &args, status);
+ 	if (status == 0) {
++		/* a zero-length count means clone to EOF in src */
++		if (count == 0 && res.dst_fattr->valid & NFS_ATTR_FATTR_SIZE)
++			count = nfs_size_to_loff_t(res.dst_fattr->size) - dst_offset;
+ 		nfs42_copy_dest_done(dst_inode, dst_offset, count);
+ 		status = nfs_post_op_update_inode(dst_inode, res.dst_fattr);
+ 	}
+diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
+index 3c5678aec006f..8ae2827da28d8 100644
+--- a/fs/nfs/nfs4client.c
++++ b/fs/nfs/nfs4client.c
+@@ -346,6 +346,7 @@ int nfs40_init_client(struct nfs_client *clp)
+ 	ret = nfs4_setup_slot_table(tbl, NFS4_MAX_SLOT_TABLE,
+ 					"NFSv4.0 transport Slot table");
+ 	if (ret) {
++		nfs4_shutdown_slot_table(tbl);
+ 		kfree(tbl);
+ 		return ret;
+ 	}
+diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
+index 9bab3e9c702a4..a629d7db9420a 100644
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -1787,6 +1787,7 @@ static void nfs4_state_mark_reclaim_helper(struct nfs_client *clp,
+ 
+ static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
+ {
++	set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
+ 	/* Mark all delegations for reclaim */
+ 	nfs_delegation_mark_reclaim(clp);
+ 	nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_reboot);
+@@ -2671,6 +2672,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
+ 			if (status < 0)
+ 				goto out_error;
+ 			nfs4_state_end_reclaim_reboot(clp);
++			continue;
+ 		}
+ 
+ 		/* Detect expired delegations... */
+diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
+index eeed4ae5b4ad9..173b38ffa4238 100644
+--- a/fs/nfsd/filecache.c
++++ b/fs/nfsd/filecache.c
+@@ -405,22 +405,15 @@ nfsd_file_unhash(struct nfsd_file *nf)
+ 	return false;
+ }
+ 
+-/*
+- * Return true if the file was unhashed.
+- */
+-static bool
++static void
+ nfsd_file_unhash_and_dispose(struct nfsd_file *nf, struct list_head *dispose)
+ {
+ 	trace_nfsd_file_unhash_and_dispose(nf);
+-	if (!nfsd_file_unhash(nf))
+-		return false;
+-	/* keep final reference for nfsd_file_lru_dispose */
+-	if (refcount_dec_not_one(&nf->nf_ref))
+-		return true;
+-
+-	nfsd_file_lru_remove(nf);
+-	list_add(&nf->nf_lru, dispose);
+-	return true;
++	if (nfsd_file_unhash(nf)) {
++		/* caller must call nfsd_file_dispose_list() later */
++		nfsd_file_lru_remove(nf);
++		list_add(&nf->nf_lru, dispose);
++	}
+ }
+ 
+ static void
+@@ -562,8 +555,6 @@ nfsd_file_dispose_list_delayed(struct list_head *dispose)
+  * @lock: LRU list lock (unused)
+  * @arg: dispose list
+  *
+- * Note this can deadlock with nfsd_file_cache_purge.
+- *
+  * Return values:
+  *   %LRU_REMOVED: @item was removed from the LRU
+  *   %LRU_ROTATE: @item is to be moved to the LRU tail
+@@ -748,8 +739,6 @@ nfsd_file_close_inode(struct inode *inode)
+  *
+  * Walk the LRU list and close any entries that have not been used since
+  * the last scan.
+- *
+- * Note this can deadlock with nfsd_file_cache_purge.
+  */
+ static void
+ nfsd_file_delayed_close(struct work_struct *work)
+@@ -891,16 +880,12 @@ out_err:
+ 	goto out;
+ }
+ 
+-/*
+- * Note this can deadlock with nfsd_file_lru_cb.
+- */
+ static void
+ __nfsd_file_cache_purge(struct net *net)
+ {
+ 	struct rhashtable_iter iter;
+ 	struct nfsd_file *nf;
+ 	LIST_HEAD(dispose);
+-	bool del;
+ 
+ 	rhashtable_walk_enter(&nfsd_file_rhash_tbl, &iter);
+ 	do {
+@@ -908,16 +893,8 @@ __nfsd_file_cache_purge(struct net *net)
+ 
+ 		nf = rhashtable_walk_next(&iter);
+ 		while (!IS_ERR_OR_NULL(nf)) {
+-			if (net && nf->nf_net != net)
+-				continue;
+-			del = nfsd_file_unhash_and_dispose(nf, &dispose);
+-
+-			/*
+-			 * Deadlock detected! Something marked this entry as
+-			 * unhased, but hasn't removed it from the hash list.
+-			 */
+-			WARN_ON_ONCE(!del);
+-
++			if (!net || nf->nf_net == net)
++				nfsd_file_unhash_and_dispose(nf, &dispose);
+ 			nf = rhashtable_walk_next(&iter);
+ 		}
+ 
+diff --git a/fs/super.c b/fs/super.c
+index 734ed584a946e..8d39e4f11cfa3 100644
+--- a/fs/super.c
++++ b/fs/super.c
+@@ -291,7 +291,7 @@ static void __put_super(struct super_block *s)
+ 		WARN_ON(s->s_inode_lru.node);
+ 		WARN_ON(!list_empty(&s->s_mounts));
+ 		security_sb_free(s);
+-		fscrypt_sb_free(s);
++		fscrypt_destroy_keyring(s);
+ 		put_user_ns(s->s_user_ns);
+ 		kfree(s->s_subtype);
+ 		call_rcu(&s->rcu, destroy_super_rcu);
+@@ -480,6 +480,7 @@ void generic_shutdown_super(struct super_block *sb)
+ 		evict_inodes(sb);
+ 		/* only nonzero refcount inodes can have marks */
+ 		fsnotify_sb_delete(sb);
++		fscrypt_destroy_keyring(sb);
+ 		security_sb_delete(sb);
+ 
+ 		if (sb->s_dio_done_wq) {
+diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
+index 34fb3431a8f36..292a5c40bd0c6 100644
+--- a/include/acpi/ghes.h
++++ b/include/acpi/ghes.h
+@@ -71,7 +71,7 @@ int ghes_register_vendor_record_notifier(struct notifier_block *nb);
+ void ghes_unregister_vendor_record_notifier(struct notifier_block *nb);
+ #endif
+ 
+-int ghes_estatus_pool_init(int num_ghes);
++int ghes_estatus_pool_init(unsigned int num_ghes);
+ 
+ /* From drivers/edac/ghes_edac.c */
+ 
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index 4459794b65db0..f87b2f5db9f83 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -1192,7 +1192,7 @@ efi_status_t efi_random_get_seed(void);
+ 	arch_efi_call_virt_teardown();					\
+ })
+ 
+-#define EFI_RANDOM_SEED_SIZE		64U
++#define EFI_RANDOM_SEED_SIZE		32U // BLAKE2S_HASH_SIZE
+ 
+ struct linux_efi_random_seed {
+ 	u32	size;
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 56a4b4b02477d..7203f5582fd44 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1472,7 +1472,7 @@ struct super_block {
+ 	const struct xattr_handler **s_xattr;
+ #ifdef CONFIG_FS_ENCRYPTION
+ 	const struct fscrypt_operations	*s_cop;
+-	struct key		*s_master_keys; /* master crypto keys in use */
++	struct fscrypt_keyring	*s_master_keys; /* master crypto keys in use */
+ #endif
+ #ifdef CONFIG_FS_VERITY
+ 	const struct fsverity_operations *s_vop;
+diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
+index 7d2f1e0f23b1f..d0e40a20ff810 100644
+--- a/include/linux/fscrypt.h
++++ b/include/linux/fscrypt.h
+@@ -312,7 +312,7 @@ fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy)
+ }
+ 
+ /* keyring.c */
+-void fscrypt_sb_free(struct super_block *sb);
++void fscrypt_destroy_keyring(struct super_block *sb);
+ int fscrypt_ioctl_add_key(struct file *filp, void __user *arg);
+ int fscrypt_add_test_dummy_key(struct super_block *sb,
+ 			       const struct fscrypt_dummy_policy *dummy_policy);
+@@ -526,7 +526,7 @@ fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy)
+ }
+ 
+ /* keyring.c */
+-static inline void fscrypt_sb_free(struct super_block *sb)
++static inline void fscrypt_destroy_keyring(struct super_block *sb)
+ {
+ }
+ 
+diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
+index 7a40f9bdc173e..dd8f994b8052b 100644
+--- a/include/linux/kvm_host.h
++++ b/include/linux/kvm_host.h
+@@ -1241,8 +1241,18 @@ int kvm_vcpu_write_guest(struct kvm_vcpu *vcpu, gpa_t gpa, const void *data,
+ void kvm_vcpu_mark_page_dirty(struct kvm_vcpu *vcpu, gfn_t gfn);
+ 
+ /**
+- * kvm_gfn_to_pfn_cache_init - prepare a cached kernel mapping and HPA for a
+- *                             given guest physical address.
++ * kvm_gpc_init - initialize gfn_to_pfn_cache.
++ *
++ * @gpc:	   struct gfn_to_pfn_cache object.
++ *
++ * This sets up a gfn_to_pfn_cache by initializing locks.  Note, the cache must
++ * be zero-allocated (or zeroed by the caller before init).
++ */
++void kvm_gpc_init(struct gfn_to_pfn_cache *gpc);
++
++/**
++ * kvm_gpc_activate - prepare a cached kernel mapping and HPA for a given guest
++ *                    physical address.
+  *
+  * @kvm:	   pointer to kvm instance.
+  * @gpc:	   struct gfn_to_pfn_cache object.
+@@ -1266,9 +1276,9 @@ void kvm_vcpu_mark_page_dirty(struct kvm_vcpu *vcpu, gfn_t gfn);
+  * kvm_gfn_to_pfn_cache_check() to ensure that the cache is valid before
+  * accessing the target page.
+  */
+-int kvm_gfn_to_pfn_cache_init(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+-			      struct kvm_vcpu *vcpu, enum pfn_cache_usage usage,
+-			      gpa_t gpa, unsigned long len);
++int kvm_gpc_activate(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
++		     struct kvm_vcpu *vcpu, enum pfn_cache_usage usage,
++		     gpa_t gpa, unsigned long len);
+ 
+ /**
+  * kvm_gfn_to_pfn_cache_check - check validity of a gfn_to_pfn_cache.
+@@ -1325,7 +1335,7 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ void kvm_gfn_to_pfn_cache_unmap(struct kvm *kvm, struct gfn_to_pfn_cache *gpc);
+ 
+ /**
+- * kvm_gfn_to_pfn_cache_destroy - destroy and unlink a gfn_to_pfn_cache.
++ * kvm_gpc_deactivate - deactivate and unlink a gfn_to_pfn_cache.
+  *
+  * @kvm:	   pointer to kvm instance.
+  * @gpc:	   struct gfn_to_pfn_cache object.
+@@ -1333,7 +1343,7 @@ void kvm_gfn_to_pfn_cache_unmap(struct kvm *kvm, struct gfn_to_pfn_cache *gpc);
+  * This removes a cache from the @kvm's list to be processed on MMU notifier
+  * invocation.
+  */
+-void kvm_gfn_to_pfn_cache_destroy(struct kvm *kvm, struct gfn_to_pfn_cache *gpc);
++void kvm_gpc_deactivate(struct kvm *kvm, struct gfn_to_pfn_cache *gpc);
+ 
+ void kvm_sigset_activate(struct kvm_vcpu *vcpu);
+ void kvm_sigset_deactivate(struct kvm_vcpu *vcpu);
+diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
+index 9689f38a0af1f..ec1896886dbd6 100644
+--- a/include/media/v4l2-subdev.h
++++ b/include/media/v4l2-subdev.h
+@@ -1046,6 +1046,8 @@ v4l2_subdev_get_pad_format(struct v4l2_subdev *sd,
+ 			   struct v4l2_subdev_state *state,
+ 			   unsigned int pad)
+ {
++	if (WARN_ON(!state))
++		return NULL;
+ 	if (WARN_ON(pad >= sd->entity.num_pads))
+ 		pad = 0;
+ 	return &state->pads[pad].try_fmt;
+@@ -1064,6 +1066,8 @@ v4l2_subdev_get_pad_crop(struct v4l2_subdev *sd,
+ 			 struct v4l2_subdev_state *state,
+ 			 unsigned int pad)
+ {
++	if (WARN_ON(!state))
++		return NULL;
+ 	if (WARN_ON(pad >= sd->entity.num_pads))
+ 		pad = 0;
+ 	return &state->pads[pad].try_crop;
+@@ -1082,6 +1086,8 @@ v4l2_subdev_get_pad_compose(struct v4l2_subdev *sd,
+ 			    struct v4l2_subdev_state *state,
+ 			    unsigned int pad)
+ {
++	if (WARN_ON(!state))
++		return NULL;
+ 	if (WARN_ON(pad >= sd->entity.num_pads))
+ 		pad = 0;
+ 	return &state->pads[pad].try_compose;
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 8a98ea9360fb7..f6e6838c82dfa 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1871,6 +1871,13 @@ void sock_kfree_s(struct sock *sk, void *mem, int size);
+ void sock_kzfree_s(struct sock *sk, void *mem, int size);
+ void sk_send_sigurg(struct sock *sk);
+ 
++static inline void sock_replace_proto(struct sock *sk, struct proto *proto)
++{
++	if (sk->sk_socket)
++		clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
++	WRITE_ONCE(sk->sk_prot, proto);
++}
++
+ struct sockcm_cookie {
+ 	u64 transmit_time;
+ 	u32 mark;
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index c5dd483a7de2f..d29f397f095ee 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -2653,15 +2653,12 @@ static __cold void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx)
+ 		io_poll_remove_all(ctx, NULL, true);
+ 	mutex_unlock(&ctx->uring_lock);
+ 
+-	/* failed during ring init, it couldn't have issued any requests */
+-	if (ctx->rings) {
++	/*
++	 * If we failed setting up the ctx, we might not have any rings
++	 * and therefore did not submit any requests
++	 */
++	if (ctx->rings)
+ 		io_kill_timeouts(ctx, NULL, true);
+-		/* if we failed setting up the ctx, we might not have any rings */
+-		io_iopoll_try_reap_events(ctx);
+-		/* drop cached put refs after potentially doing completions */
+-		if (current->io_uring)
+-			io_uring_drop_tctx_refs(current);
+-	}
+ 
+ 	INIT_WORK(&ctx->exit_work, io_ring_exit_work);
+ 	/*
+diff --git a/kernel/kprobes.c b/kernel/kprobes.c
+index ca9d834d0b843..917b92ae23821 100644
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -2425,8 +2425,11 @@ int enable_kprobe(struct kprobe *kp)
+ 	if (!kprobes_all_disarmed && kprobe_disabled(p)) {
+ 		p->flags &= ~KPROBE_FLAG_DISABLED;
+ 		ret = arm_kprobe(p);
+-		if (ret)
++		if (ret) {
+ 			p->flags |= KPROBE_FLAG_DISABLED;
++			if (p != kp)
++				kp->flags |= KPROBE_FLAG_DISABLED;
++		}
+ 	}
+ out:
+ 	mutex_unlock(&kprobe_mutex);
+diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c
+index aac63ca9c3d1e..e8143e3680744 100644
+--- a/kernel/trace/fprobe.c
++++ b/kernel/trace/fprobe.c
+@@ -141,6 +141,8 @@ static int fprobe_init_rethook(struct fprobe *fp, int num)
+ 		return -E2BIG;
+ 
+ 	fp->rethook = rethook_alloc((void *)fp, fprobe_exit_handler);
++	if (!fp->rethook)
++		return -ENOMEM;
+ 	for (i = 0; i < size; i++) {
+ 		struct fprobe_rethook_node *node;
+ 
+@@ -301,7 +303,8 @@ int unregister_fprobe(struct fprobe *fp)
+ {
+ 	int ret;
+ 
+-	if (!fp || fp->ops.func != fprobe_handler)
++	if (!fp || (fp->ops.saved_func != fprobe_handler &&
++		    fp->ops.saved_func != fprobe_kprobe_handler))
+ 		return -EINVAL;
+ 
+ 	/*
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 83362a1557916..8cc9eb60c3c2a 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -3031,18 +3031,8 @@ int ftrace_shutdown(struct ftrace_ops *ops, int command)
+ 		command |= FTRACE_UPDATE_TRACE_FUNC;
+ 	}
+ 
+-	if (!command || !ftrace_enabled) {
+-		/*
+-		 * If these are dynamic or per_cpu ops, they still
+-		 * need their data freed. Since, function tracing is
+-		 * not currently active, we can just free them
+-		 * without synchronizing all CPUs.
+-		 */
+-		if (ops->flags & FTRACE_OPS_FL_DYNAMIC)
+-			goto free_ops;
+-
+-		return 0;
+-	}
++	if (!command || !ftrace_enabled)
++		goto out;
+ 
+ 	/*
+ 	 * If the ops uses a trampoline, then it needs to be
+@@ -3079,6 +3069,7 @@ int ftrace_shutdown(struct ftrace_ops *ops, int command)
+ 	removed_ops = NULL;
+ 	ops->flags &= ~FTRACE_OPS_FL_REMOVING;
+ 
++out:
+ 	/*
+ 	 * Dynamic ops may be freed, we must make sure that all
+ 	 * callers are done before leaving this function.
+@@ -3106,7 +3097,6 @@ int ftrace_shutdown(struct ftrace_ops *ops, int command)
+ 		if (IS_ENABLED(CONFIG_PREEMPTION))
+ 			synchronize_rcu_tasks();
+ 
+- free_ops:
+ 		ftrace_trampoline_free(ops);
+ 	}
+ 
+diff --git a/kernel/trace/kprobe_event_gen_test.c b/kernel/trace/kprobe_event_gen_test.c
+index 80e04a1e19772..d81f7c51025c7 100644
+--- a/kernel/trace/kprobe_event_gen_test.c
++++ b/kernel/trace/kprobe_event_gen_test.c
+@@ -100,20 +100,20 @@ static int __init test_gen_kprobe_cmd(void)
+ 					 KPROBE_GEN_TEST_FUNC,
+ 					 KPROBE_GEN_TEST_ARG0, KPROBE_GEN_TEST_ARG1);
+ 	if (ret)
+-		goto free;
++		goto out;
+ 
+ 	/* Use kprobe_event_add_fields to add the rest of the fields */
+ 
+ 	ret = kprobe_event_add_fields(&cmd, KPROBE_GEN_TEST_ARG2, KPROBE_GEN_TEST_ARG3);
+ 	if (ret)
+-		goto free;
++		goto out;
+ 
+ 	/*
+ 	 * This actually creates the event.
+ 	 */
+ 	ret = kprobe_event_gen_cmd_end(&cmd);
+ 	if (ret)
+-		goto free;
++		goto out;
+ 
+ 	/*
+ 	 * Now get the gen_kprobe_test event file.  We need to prevent
+@@ -136,13 +136,11 @@ static int __init test_gen_kprobe_cmd(void)
+ 		goto delete;
+ 	}
+  out:
++	kfree(buf);
+ 	return ret;
+  delete:
+ 	/* We got an error after creating the event, delete it */
+ 	ret = kprobe_event_delete("gen_kprobe_test");
+- free:
+-	kfree(buf);
+-
+ 	goto out;
+ }
+ 
+@@ -170,14 +168,14 @@ static int __init test_gen_kretprobe_cmd(void)
+ 					    KPROBE_GEN_TEST_FUNC,
+ 					    "$retval");
+ 	if (ret)
+-		goto free;
++		goto out;
+ 
+ 	/*
+ 	 * This actually creates the event.
+ 	 */
+ 	ret = kretprobe_event_gen_cmd_end(&cmd);
+ 	if (ret)
+-		goto free;
++		goto out;
+ 
+ 	/*
+ 	 * Now get the gen_kretprobe_test event file.  We need to
+@@ -201,13 +199,11 @@ static int __init test_gen_kretprobe_cmd(void)
+ 		goto delete;
+ 	}
+  out:
++	kfree(buf);
+ 	return ret;
+  delete:
+ 	/* We got an error after creating the event, delete it */
+ 	ret = kprobe_event_delete("gen_kretprobe_test");
+- free:
+-	kfree(buf);
+-
+ 	goto out;
+ }
+ 
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index c3f354cfc5ba1..9c72571ffb0bf 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -937,6 +937,9 @@ void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu)
+ 	struct ring_buffer_per_cpu *cpu_buffer;
+ 	struct rb_irq_work *rbwork;
+ 
++	if (!buffer)
++		return;
++
+ 	if (cpu == RING_BUFFER_ALL_CPUS) {
+ 
+ 		/* Wake up individual ones too. One level recursion */
+@@ -945,7 +948,15 @@ void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu)
+ 
+ 		rbwork = &buffer->irq_work;
+ 	} else {
++		if (WARN_ON_ONCE(!buffer->buffers))
++			return;
++		if (WARN_ON_ONCE(cpu >= nr_cpu_ids))
++			return;
++
+ 		cpu_buffer = buffer->buffers[cpu];
++		/* The CPU buffer may not have been initialized yet */
++		if (!cpu_buffer)
++			return;
+ 		rbwork = &cpu_buffer->irq_work;
+ 	}
+ 
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 9777e7b109eee..f26ed278d9e3c 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -1003,10 +1003,21 @@ int hci_conn_del(struct hci_conn *conn)
+ 			hdev->acl_cnt += conn->sent;
+ 	} else {
+ 		struct hci_conn *acl = conn->link;
++
+ 		if (acl) {
+ 			acl->link = NULL;
+ 			hci_conn_drop(acl);
+ 		}
++
++		/* Unacked ISO frames */
++		if (conn->type == ISO_LINK) {
++			if (hdev->iso_pkts)
++				hdev->iso_cnt += conn->sent;
++			else if (hdev->le_pkts)
++				hdev->le_cnt += conn->sent;
++			else
++				hdev->acl_cnt += conn->sent;
++		}
+ 	}
+ 
+ 	if (conn->amp_mgr)
+@@ -1697,6 +1708,7 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
+ 		if (!cis)
+ 			return ERR_PTR(-ENOMEM);
+ 		cis->cleanup = cis_cleanup;
++		cis->dst_type = dst_type;
+ 	}
+ 
+ 	if (cis->state == BT_CONNECTED)
+@@ -2076,12 +2088,6 @@ struct hci_conn *hci_connect_cis(struct hci_dev *hdev, bdaddr_t *dst,
+ 	struct hci_conn *le;
+ 	struct hci_conn *cis;
+ 
+-	/* Convert from ISO socket address type to HCI address type  */
+-	if (dst_type == BDADDR_LE_PUBLIC)
+-		dst_type = ADDR_LE_DEV_PUBLIC;
+-	else
+-		dst_type = ADDR_LE_DEV_RANDOM;
+-
+ 	if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
+ 		le = hci_connect_le(hdev, dst, dst_type, false,
+ 				    BT_SECURITY_LOW,
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index 613039ba5dbf5..f825857db6d0b 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -235,6 +235,14 @@ static int iso_chan_add(struct iso_conn *conn, struct sock *sk,
+ 	return err;
+ }
+ 
++static inline u8 le_addr_type(u8 bdaddr_type)
++{
++	if (bdaddr_type == BDADDR_LE_PUBLIC)
++		return ADDR_LE_DEV_PUBLIC;
++	else
++		return ADDR_LE_DEV_RANDOM;
++}
++
+ static int iso_connect_bis(struct sock *sk)
+ {
+ 	struct iso_conn *conn;
+@@ -328,14 +336,16 @@ static int iso_connect_cis(struct sock *sk)
+ 	/* Just bind if DEFER_SETUP has been set */
+ 	if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
+ 		hcon = hci_bind_cis(hdev, &iso_pi(sk)->dst,
+-				    iso_pi(sk)->dst_type, &iso_pi(sk)->qos);
++				    le_addr_type(iso_pi(sk)->dst_type),
++				    &iso_pi(sk)->qos);
+ 		if (IS_ERR(hcon)) {
+ 			err = PTR_ERR(hcon);
+ 			goto done;
+ 		}
+ 	} else {
+ 		hcon = hci_connect_cis(hdev, &iso_pi(sk)->dst,
+-				       iso_pi(sk)->dst_type, &iso_pi(sk)->qos);
++				       le_addr_type(iso_pi(sk)->dst_type),
++				       &iso_pi(sk)->qos);
+ 		if (IS_ERR(hcon)) {
+ 			err = PTR_ERR(hcon);
+ 			goto done;
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 1f34b82ca0ec9..4df3d0ed6c80d 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -3764,7 +3764,8 @@ done:
+ 			l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+ 					   sizeof(rfc), (unsigned long) &rfc, endptr - ptr);
+ 
+-			if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
++			if (remote_efs &&
++			    test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
+ 				chan->remote_id = efs.id;
+ 				chan->remote_stype = efs.stype;
+ 				chan->remote_msdu = le16_to_cpu(efs.msdu);
+@@ -5813,6 +5814,19 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
+ 	BT_DBG("psm 0x%2.2x scid 0x%4.4x mtu %u mps %u", __le16_to_cpu(psm),
+ 	       scid, mtu, mps);
+ 
++	/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A
++	 * page 1059:
++	 *
++	 * Valid range: 0x0001-0x00ff
++	 *
++	 * Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges
++	 */
++	if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) {
++		result = L2CAP_CR_LE_BAD_PSM;
++		chan = NULL;
++		goto response;
++	}
++
+ 	/* Check if we have socket listening on psm */
+ 	pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src,
+ 					 &conn->hcon->dst, LE_LINK);
+@@ -6001,6 +6015,18 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
+ 
+ 	psm  = req->psm;
+ 
++	/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 3, Part A
++	 * page 1059:
++	 *
++	 * Valid range: 0x0001-0x00ff
++	 *
++	 * Table 4.15: L2CAP_LE_CREDIT_BASED_CONNECTION_REQ SPSM ranges
++	 */
++	if (!psm || __le16_to_cpu(psm) > L2CAP_PSM_LE_DYN_END) {
++		result = L2CAP_CR_LE_BAD_PSM;
++		goto response;
++	}
++
+ 	BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps);
+ 
+ 	memset(&pdu, 0, sizeof(pdu));
+@@ -6885,6 +6911,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan,
+ 			       struct l2cap_ctrl *control,
+ 			       struct sk_buff *skb, u8 event)
+ {
++	struct l2cap_ctrl local_control;
+ 	int err = 0;
+ 	bool skb_in_use = false;
+ 
+@@ -6909,15 +6936,32 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan,
+ 			chan->buffer_seq = chan->expected_tx_seq;
+ 			skb_in_use = true;
+ 
++			/* l2cap_reassemble_sdu may free skb, hence invalidate
++			 * control, so make a copy in advance to use it after
++			 * l2cap_reassemble_sdu returns and to avoid the race
++			 * condition, for example:
++			 *
++			 * The current thread calls:
++			 *   l2cap_reassemble_sdu
++			 *     chan->ops->recv == l2cap_sock_recv_cb
++			 *       __sock_queue_rcv_skb
++			 * Another thread calls:
++			 *   bt_sock_recvmsg
++			 *     skb_recv_datagram
++			 *     skb_free_datagram
++			 * Then the current thread tries to access control, but
++			 * it was freed by skb_free_datagram.
++			 */
++			local_control = *control;
+ 			err = l2cap_reassemble_sdu(chan, skb, control);
+ 			if (err)
+ 				break;
+ 
+-			if (control->final) {
++			if (local_control.final) {
+ 				if (!test_and_clear_bit(CONN_REJ_ACT,
+ 							&chan->conn_state)) {
+-					control->final = 0;
+-					l2cap_retransmit_all(chan, control);
++					local_control.final = 0;
++					l2cap_retransmit_all(chan, &local_control);
+ 					l2cap_ertm_send(chan);
+ 				}
+ 			}
+@@ -7297,11 +7341,27 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
+ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
+ 			   struct sk_buff *skb)
+ {
++	/* l2cap_reassemble_sdu may free skb, hence invalidate control, so store
++	 * the txseq field in advance to use it after l2cap_reassemble_sdu
++	 * returns and to avoid the race condition, for example:
++	 *
++	 * The current thread calls:
++	 *   l2cap_reassemble_sdu
++	 *     chan->ops->recv == l2cap_sock_recv_cb
++	 *       __sock_queue_rcv_skb
++	 * Another thread calls:
++	 *   bt_sock_recvmsg
++	 *     skb_recv_datagram
++	 *     skb_free_datagram
++	 * Then the current thread tries to access control, but it was freed by
++	 * skb_free_datagram.
++	 */
++	u16 txseq = control->txseq;
++
+ 	BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb,
+ 	       chan->rx_state);
+ 
+-	if (l2cap_classify_txseq(chan, control->txseq) ==
+-	    L2CAP_TXSEQ_EXPECTED) {
++	if (l2cap_classify_txseq(chan, txseq) == L2CAP_TXSEQ_EXPECTED) {
+ 		l2cap_pass_to_tx(chan, control);
+ 
+ 		BT_DBG("buffer_seq %u->%u", chan->buffer_seq,
+@@ -7324,8 +7384,8 @@ static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
+ 		}
+ 	}
+ 
+-	chan->last_acked_seq = control->txseq;
+-	chan->expected_tx_seq = __next_seq(chan, control->txseq);
++	chan->last_acked_seq = txseq;
++	chan->expected_tx_seq = __next_seq(chan, txseq);
+ 
+ 	return 0;
+ }
+@@ -7581,6 +7641,7 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
+ 				return;
+ 			}
+ 
++			l2cap_chan_hold(chan);
+ 			l2cap_chan_lock(chan);
+ 		} else {
+ 			BT_DBG("unknown cid 0x%4.4x", cid);
+@@ -8426,9 +8487,8 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
+ 		 * expected length.
+ 		 */
+ 		if (skb->len < L2CAP_LEN_SIZE) {
+-			if (l2cap_recv_frag(conn, skb, conn->mtu) < 0)
+-				goto drop;
+-			return;
++			l2cap_recv_frag(conn, skb, conn->mtu);
++			break;
+ 		}
+ 
+ 		len = get_unaligned_le16(skb->data) + L2CAP_HDR_SIZE;
+@@ -8472,7 +8532,7 @@ void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
+ 
+ 			/* Header still could not be read just continue */
+ 			if (conn->rx_skb->len < L2CAP_LEN_SIZE)
+-				return;
++				break;
+ 		}
+ 
+ 		if (skb->len > conn->rx_len) {
+diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
+index 5aeb3646e74c7..d087fd4c784ac 100644
+--- a/net/bridge/br_netlink.c
++++ b/net/bridge/br_netlink.c
+@@ -1332,7 +1332,7 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
+ 
+ 	if (data[IFLA_BR_FDB_FLUSH]) {
+ 		struct net_bridge_fdb_flush_desc desc = {
+-			.flags_mask = BR_FDB_STATIC
++			.flags_mask = BIT(BR_FDB_STATIC)
+ 		};
+ 
+ 		br_fdb_flush(br, &desc);
+diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
+index 612e367fff20d..ea733542244c7 100644
+--- a/net/bridge/br_sysfs_br.c
++++ b/net/bridge/br_sysfs_br.c
+@@ -345,7 +345,7 @@ static int set_flush(struct net_bridge *br, unsigned long val,
+ 		     struct netlink_ext_ack *extack)
+ {
+ 	struct net_bridge_fdb_flush_desc desc = {
+-		.flags_mask = BR_FDB_STATIC
++		.flags_mask = BIT(BR_FDB_STATIC)
+ 	};
+ 
+ 	br_fdb_flush(br, &desc);
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index 78cc8fb688140..84755db81e9d9 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -409,7 +409,7 @@ static int __neigh_ifdown(struct neigh_table *tbl, struct net_device *dev,
+ 	write_lock_bh(&tbl->lock);
+ 	neigh_flush_dev(tbl, dev, skip_perm);
+ 	pneigh_ifdown_and_unlock(tbl, dev);
+-	pneigh_queue_purge(&tbl->proxy_queue, dev_net(dev));
++	pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL);
+ 	if (skb_queue_empty_lockless(&tbl->proxy_queue))
+ 		del_timer_sync(&tbl->proxy_timer);
+ 	return 0;
+diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
+index cac48a741f27c..e537655e442b8 100644
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -1407,9 +1407,9 @@ static enum dsa_tag_protocol dsa_get_tag_protocol(struct dsa_port *dp,
+ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master,
+ 			      const char *user_protocol)
+ {
++	const struct dsa_device_ops *tag_ops = NULL;
+ 	struct dsa_switch *ds = dp->ds;
+ 	struct dsa_switch_tree *dst = ds->dst;
+-	const struct dsa_device_ops *tag_ops;
+ 	enum dsa_tag_protocol default_proto;
+ 
+ 	/* Find out which protocol the switch would prefer. */
+@@ -1432,10 +1432,17 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master,
+ 		}
+ 
+ 		tag_ops = dsa_find_tagger_by_name(user_protocol);
+-	} else {
+-		tag_ops = dsa_tag_driver_get(default_proto);
++		if (IS_ERR(tag_ops)) {
++			dev_warn(ds->dev,
++				 "Failed to find a tagging driver for protocol %s, using default\n",
++				 user_protocol);
++			tag_ops = NULL;
++		}
+ 	}
+ 
++	if (!tag_ops)
++		tag_ops = dsa_tag_driver_get(default_proto);
++
+ 	if (IS_ERR(tag_ops)) {
+ 		if (PTR_ERR(tag_ops) == -ENOPROTOOPT)
+ 			return -EPROBE_DEFER;
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 3ca0cc4678862..7f6d7c355e38e 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -748,6 +748,8 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags,
+ 		  (TCPF_ESTABLISHED | TCPF_SYN_RECV |
+ 		  TCPF_CLOSE_WAIT | TCPF_CLOSE)));
+ 
++	if (test_bit(SOCK_SUPPORT_ZC, &sock->flags))
++		set_bit(SOCK_SUPPORT_ZC, &newsock->flags);
+ 	sock_graft(sk2, newsock);
+ 
+ 	newsock->state = SS_CONNECTED;
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
+index a1626afe87a10..c501c329b1dbe 100644
+--- a/net/ipv4/tcp_bpf.c
++++ b/net/ipv4/tcp_bpf.c
+@@ -607,7 +607,7 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
+ 		} else {
+ 			sk->sk_write_space = psock->saved_write_space;
+ 			/* Pairs with lockless read in sk_clone_lock() */
+-			WRITE_ONCE(sk->sk_prot, psock->sk_proto);
++			sock_replace_proto(sk, psock->sk_proto);
+ 		}
+ 		return 0;
+ 	}
+@@ -620,7 +620,7 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
+ 	}
+ 
+ 	/* Pairs with lockless read in sk_clone_lock() */
+-	WRITE_ONCE(sk->sk_prot, &tcp_bpf_prots[family][config]);
++	sock_replace_proto(sk, &tcp_bpf_prots[family][config]);
+ 	return 0;
+ }
+ EXPORT_SYMBOL_GPL(tcp_bpf_update_proto);
+diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c
+index 7c27aa629af19..9ae50b1bd8444 100644
+--- a/net/ipv4/tcp_ulp.c
++++ b/net/ipv4/tcp_ulp.c
+@@ -136,6 +136,9 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops)
+ 	if (icsk->icsk_ulp_ops)
+ 		goto out_err;
+ 
++	if (sk->sk_socket)
++		clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
++
+ 	err = ulp_ops->init(sk);
+ 	if (err)
+ 		goto out_err;
+diff --git a/net/ipv4/udp_bpf.c b/net/ipv4/udp_bpf.c
+index ff15918b7bdc7..e5dc91d0e0793 100644
+--- a/net/ipv4/udp_bpf.c
++++ b/net/ipv4/udp_bpf.c
+@@ -141,14 +141,14 @@ int udp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore)
+ 
+ 	if (restore) {
+ 		sk->sk_write_space = psock->saved_write_space;
+-		WRITE_ONCE(sk->sk_prot, psock->sk_proto);
++		sock_replace_proto(sk, psock->sk_proto);
+ 		return 0;
+ 	}
+ 
+ 	if (sk->sk_family == AF_INET6)
+ 		udp_bpf_check_v6_needs_rebuild(psock->sk_proto);
+ 
+-	WRITE_ONCE(sk->sk_prot, &udp_bpf_prots[family]);
++	sock_replace_proto(sk, &udp_bpf_prots[family]);
+ 	return 0;
+ }
+ EXPORT_SYMBOL_GPL(udp_bpf_update_proto);
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 69252eb462b2d..2f355f0ec32ac 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -6555,10 +6555,16 @@ static void __net_exit ip6_route_net_exit(struct net *net)
+ static int __net_init ip6_route_net_init_late(struct net *net)
+ {
+ #ifdef CONFIG_PROC_FS
+-	proc_create_net("ipv6_route", 0, net->proc_net, &ipv6_route_seq_ops,
+-			sizeof(struct ipv6_route_iter));
+-	proc_create_net_single("rt6_stats", 0444, net->proc_net,
+-			rt6_stats_seq_show, NULL);
++	if (!proc_create_net("ipv6_route", 0, net->proc_net,
++			     &ipv6_route_seq_ops,
++			     sizeof(struct ipv6_route_iter)))
++		return -ENOMEM;
++
++	if (!proc_create_net_single("rt6_stats", 0444, net->proc_net,
++				    rt6_stats_seq_show, NULL)) {
++		remove_proc_entry("ipv6_route", net->proc_net);
++		return -ENOMEM;
++	}
+ #endif
+ 	return 0;
+ }
+diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
+index 6e391308431da..3adc291d9ce18 100644
+--- a/net/netfilter/ipset/ip_set_hash_gen.h
++++ b/net/netfilter/ipset/ip_set_hash_gen.h
+@@ -42,31 +42,8 @@
+ #define AHASH_MAX_SIZE			(6 * AHASH_INIT_SIZE)
+ /* Max muber of elements in the array block when tuned */
+ #define AHASH_MAX_TUNED			64
+-
+ #define AHASH_MAX(h)			((h)->bucketsize)
+ 
+-/* Max number of elements can be tuned */
+-#ifdef IP_SET_HASH_WITH_MULTI
+-static u8
+-tune_bucketsize(u8 curr, u32 multi)
+-{
+-	u32 n;
+-
+-	if (multi < curr)
+-		return curr;
+-
+-	n = curr + AHASH_INIT_SIZE;
+-	/* Currently, at listing one hash bucket must fit into a message.
+-	 * Therefore we have a hard limit here.
+-	 */
+-	return n > curr && n <= AHASH_MAX_TUNED ? n : curr;
+-}
+-#define TUNE_BUCKETSIZE(h, multi)	\
+-	((h)->bucketsize = tune_bucketsize((h)->bucketsize, multi))
+-#else
+-#define TUNE_BUCKETSIZE(h, multi)
+-#endif
+-
+ /* A hash bucket */
+ struct hbucket {
+ 	struct rcu_head rcu;	/* for call_rcu */
+@@ -936,7 +913,12 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
+ 		goto set_full;
+ 	/* Create a new slot */
+ 	if (n->pos >= n->size) {
+-		TUNE_BUCKETSIZE(h, multi);
++#ifdef IP_SET_HASH_WITH_MULTI
++		if (h->bucketsize >= AHASH_MAX_TUNED)
++			goto set_full;
++		else if (h->bucketsize < multi)
++			h->bucketsize += AHASH_INIT_SIZE;
++#endif
+ 		if (n->size >= AHASH_MAX(h)) {
+ 			/* Trigger rehashing */
+ 			mtype_data_next(&h->next, d);
+diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
+index f9b16f2b22191..fdacbc3c15bef 100644
+--- a/net/netfilter/ipvs/ip_vs_app.c
++++ b/net/netfilter/ipvs/ip_vs_app.c
+@@ -599,13 +599,19 @@ static const struct seq_operations ip_vs_app_seq_ops = {
+ int __net_init ip_vs_app_net_init(struct netns_ipvs *ipvs)
+ {
+ 	INIT_LIST_HEAD(&ipvs->app_list);
+-	proc_create_net("ip_vs_app", 0, ipvs->net->proc_net, &ip_vs_app_seq_ops,
+-			sizeof(struct seq_net_private));
++#ifdef CONFIG_PROC_FS
++	if (!proc_create_net("ip_vs_app", 0, ipvs->net->proc_net,
++			     &ip_vs_app_seq_ops,
++			     sizeof(struct seq_net_private)))
++		return -ENOMEM;
++#endif
+ 	return 0;
+ }
+ 
+ void __net_exit ip_vs_app_net_cleanup(struct netns_ipvs *ipvs)
+ {
+ 	unregister_ip_vs_app(ipvs, NULL /* all */);
++#ifdef CONFIG_PROC_FS
+ 	remove_proc_entry("ip_vs_app", ipvs->net->proc_net);
++#endif
+ }
+diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
+index fb67f1ca2495b..cb6d68220c265 100644
+--- a/net/netfilter/ipvs/ip_vs_conn.c
++++ b/net/netfilter/ipvs/ip_vs_conn.c
+@@ -1265,8 +1265,8 @@ static inline int todrop_entry(struct ip_vs_conn *cp)
+ 	 * The drop rate array needs tuning for real environments.
+ 	 * Called from timer bh only => no locking
+ 	 */
+-	static const char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
+-	static char todrop_counter[9] = {0};
++	static const signed char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
++	static signed char todrop_counter[9] = {0};
+ 	int i;
+ 
+ 	/* if the conn entry hasn't lasted for 60 seconds, don't drop it.
+@@ -1447,20 +1447,36 @@ int __net_init ip_vs_conn_net_init(struct netns_ipvs *ipvs)
+ {
+ 	atomic_set(&ipvs->conn_count, 0);
+ 
+-	proc_create_net("ip_vs_conn", 0, ipvs->net->proc_net,
+-			&ip_vs_conn_seq_ops, sizeof(struct ip_vs_iter_state));
+-	proc_create_net("ip_vs_conn_sync", 0, ipvs->net->proc_net,
+-			&ip_vs_conn_sync_seq_ops,
+-			sizeof(struct ip_vs_iter_state));
++#ifdef CONFIG_PROC_FS
++	if (!proc_create_net("ip_vs_conn", 0, ipvs->net->proc_net,
++			     &ip_vs_conn_seq_ops,
++			     sizeof(struct ip_vs_iter_state)))
++		goto err_conn;
++
++	if (!proc_create_net("ip_vs_conn_sync", 0, ipvs->net->proc_net,
++			     &ip_vs_conn_sync_seq_ops,
++			     sizeof(struct ip_vs_iter_state)))
++		goto err_conn_sync;
++#endif
++
+ 	return 0;
++
++#ifdef CONFIG_PROC_FS
++err_conn_sync:
++	remove_proc_entry("ip_vs_conn", ipvs->net->proc_net);
++err_conn:
++	return -ENOMEM;
++#endif
+ }
+ 
+ void __net_exit ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs)
+ {
+ 	/* flush all the connection entries first */
+ 	ip_vs_conn_flush(ipvs);
++#ifdef CONFIG_PROC_FS
+ 	remove_proc_entry("ip_vs_conn", ipvs->net->proc_net);
+ 	remove_proc_entry("ip_vs_conn_sync", ipvs->net->proc_net);
++#endif
+ }
+ 
+ int __init ip_vs_conn_init(void)
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 5897afd124668..879f4a1a27d54 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -8465,9 +8465,6 @@ static void nft_commit_release(struct nft_trans *trans)
+ 		nf_tables_chain_destroy(&trans->ctx);
+ 		break;
+ 	case NFT_MSG_DELRULE:
+-		if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
+-			nft_flow_rule_destroy(nft_trans_flow_rule(trans));
+-
+ 		nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
+ 		break;
+ 	case NFT_MSG_DELSET:
+@@ -8973,6 +8970,9 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
+ 			nft_rule_expr_deactivate(&trans->ctx,
+ 						 nft_trans_rule(trans),
+ 						 NFT_TRANS_COMMIT);
++
++			if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
++				nft_flow_rule_destroy(nft_trans_flow_rule(trans));
+ 			break;
+ 		case NFT_MSG_NEWSET:
+ 			nft_clear(net, nft_trans_set(trans));
+@@ -10030,6 +10030,8 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
+ 	nft_net = nft_pernet(net);
+ 	deleted = 0;
+ 	mutex_lock(&nft_net->commit_mutex);
++	if (!list_empty(&nf_tables_destroy_list))
++		rcu_barrier();
+ again:
+ 	list_for_each_entry(table, &nft_net->tables, list) {
+ 		if (nft_table_has_owner(table) &&
+diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c
+index 8b96a56d3a49b..0f77ae8ef944a 100644
+--- a/net/rose/rose_link.c
++++ b/net/rose/rose_link.c
+@@ -236,6 +236,9 @@ void rose_transmit_clear_request(struct rose_neigh *neigh, unsigned int lci, uns
+ 	unsigned char *dptr;
+ 	int len;
+ 
++	if (!neigh->dev)
++		return;
++
+ 	len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN + 3;
+ 
+ 	if ((skb = alloc_skb(len, GFP_ATOMIC)) == NULL)
+diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
+index f1e013e3f04a9..935d90874b1b7 100644
+--- a/net/sched/sch_red.c
++++ b/net/sched/sch_red.c
+@@ -72,6 +72,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ {
+ 	struct red_sched_data *q = qdisc_priv(sch);
+ 	struct Qdisc *child = q->qdisc;
++	unsigned int len;
+ 	int ret;
+ 
+ 	q->vars.qavg = red_calc_qavg(&q->parms,
+@@ -126,9 +127,10 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ 		break;
+ 	}
+ 
++	len = qdisc_pkt_len(skb);
+ 	ret = qdisc_enqueue(skb, child, to_free);
+ 	if (likely(ret == NET_XMIT_SUCCESS)) {
+-		qdisc_qstats_backlog_inc(sch, skb);
++		sch->qstats.backlog += len;
+ 		sch->q.qlen++;
+ 	} else if (net_xmit_drop_count(ret)) {
+ 		q->stats.pdrop++;
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
+index 0939cc3b915af..58ff5f33b3700 100644
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -3380,14 +3380,14 @@ static int __init smc_init(void)
+ 
+ 	rc = register_pernet_subsys(&smc_net_stat_ops);
+ 	if (rc)
+-		return rc;
++		goto out_pernet_subsys;
+ 
+ 	smc_ism_init();
+ 	smc_clc_init();
+ 
+ 	rc = smc_nl_init();
+ 	if (rc)
+-		goto out_pernet_subsys;
++		goto out_pernet_subsys_stat;
+ 
+ 	rc = smc_pnet_init();
+ 	if (rc)
+@@ -3480,6 +3480,8 @@ out_pnet:
+ 	smc_pnet_exit();
+ out_nl:
+ 	smc_nl_exit();
++out_pernet_subsys_stat:
++	unregister_pernet_subsys(&smc_net_stat_ops);
+ out_pernet_subsys:
+ 	unregister_pernet_subsys(&smc_net_ops);
+ 
+diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c
+index c65c90ad626ad..c1f559892ae8a 100644
+--- a/net/sunrpc/sysfs.c
++++ b/net/sunrpc/sysfs.c
+@@ -518,13 +518,16 @@ void rpc_sysfs_client_setup(struct rpc_clnt *clnt,
+ 			    struct net *net)
+ {
+ 	struct rpc_sysfs_client *rpc_client;
++	struct rpc_sysfs_xprt_switch *xswitch =
++		(struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs;
++
++	if (!xswitch)
++		return;
+ 
+ 	rpc_client = rpc_sysfs_client_alloc(rpc_sunrpc_client_kobj,
+ 					    net, clnt->cl_clid);
+ 	if (rpc_client) {
+ 		char name[] = "switch";
+-		struct rpc_sysfs_xprt_switch *xswitch =
+-			(struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs;
+ 		int ret;
+ 
+ 		clnt->cl_sysfs = rpc_client;
+@@ -558,6 +561,8 @@ void rpc_sysfs_xprt_switch_setup(struct rpc_xprt_switch *xprt_switch,
+ 		rpc_xprt_switch->xprt_switch = xprt_switch;
+ 		rpc_xprt_switch->xprt = xprt;
+ 		kobject_uevent(&rpc_xprt_switch->kobject, KOBJ_ADD);
++	} else {
++		xprt_switch->xps_sysfs = NULL;
+ 	}
+ }
+ 
+@@ -569,6 +574,9 @@ void rpc_sysfs_xprt_setup(struct rpc_xprt_switch *xprt_switch,
+ 	struct rpc_sysfs_xprt_switch *switch_obj =
+ 		(struct rpc_sysfs_xprt_switch *)xprt_switch->xps_sysfs;
+ 
++	if (!switch_obj)
++		return;
++
+ 	rpc_xprt = rpc_sysfs_xprt_alloc(&switch_obj->kobject, xprt, gfp_flags);
+ 	if (rpc_xprt) {
+ 		xprt->xprt_sysfs = rpc_xprt;
+diff --git a/net/unix/unix_bpf.c b/net/unix/unix_bpf.c
+index 7cf14c6b17254..e9bf155139612 100644
+--- a/net/unix/unix_bpf.c
++++ b/net/unix/unix_bpf.c
+@@ -145,12 +145,12 @@ int unix_dgram_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool re
+ 
+ 	if (restore) {
+ 		sk->sk_write_space = psock->saved_write_space;
+-		WRITE_ONCE(sk->sk_prot, psock->sk_proto);
++		sock_replace_proto(sk, psock->sk_proto);
+ 		return 0;
+ 	}
+ 
+ 	unix_dgram_bpf_check_needs_rebuild(psock->sk_proto);
+-	WRITE_ONCE(sk->sk_prot, &unix_dgram_bpf_prot);
++	sock_replace_proto(sk, &unix_dgram_bpf_prot);
+ 	return 0;
+ }
+ 
+@@ -158,12 +158,12 @@ int unix_stream_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool r
+ {
+ 	if (restore) {
+ 		sk->sk_write_space = psock->saved_write_space;
+-		WRITE_ONCE(sk->sk_prot, psock->sk_proto);
++		sock_replace_proto(sk, psock->sk_proto);
+ 		return 0;
+ 	}
+ 
+ 	unix_stream_bpf_check_needs_rebuild(psock->sk_proto);
+-	WRITE_ONCE(sk->sk_prot, &unix_stream_bpf_prot);
++	sock_replace_proto(sk, &unix_stream_bpf_prot);
+ 	return 0;
+ }
+ 
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index b4ee163154a68..e5ab2418f9d6b 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -1894,8 +1894,11 @@ static int vsock_connectible_wait_data(struct sock *sk,
+ 	err = 0;
+ 	transport = vsk->transport;
+ 
+-	while ((data = vsock_connectible_has_data(vsk)) == 0) {
++	while (1) {
+ 		prepare_to_wait(sk_sleep(sk), wait, TASK_INTERRUPTIBLE);
++		data = vsock_connectible_has_data(vsk);
++		if (data != 0)
++			break;
+ 
+ 		if (sk->sk_err != 0 ||
+ 		    (sk->sk_shutdown & RCV_SHUTDOWN) ||
+diff --git a/security/commoncap.c b/security/commoncap.c
+index 5fc8986c3c77c..bc751fa5adad7 100644
+--- a/security/commoncap.c
++++ b/security/commoncap.c
+@@ -401,8 +401,10 @@ int cap_inode_getsecurity(struct user_namespace *mnt_userns,
+ 				      &tmpbuf, size, GFP_NOFS);
+ 	dput(dentry);
+ 
+-	if (ret < 0 || !tmpbuf)
+-		return ret;
++	if (ret < 0 || !tmpbuf) {
++		size = ret;
++		goto out_free;
++	}
+ 
+ 	fs_ns = inode->i_sb->s_user_ns;
+ 	cap = (struct vfs_cap_data *) tmpbuf;
+diff --git a/tools/include/nolibc/string.h b/tools/include/nolibc/string.h
+index bef35bee9c44c..ad97c0d522b8e 100644
+--- a/tools/include/nolibc/string.h
++++ b/tools/include/nolibc/string.h
+@@ -19,9 +19,9 @@ static __attribute__((unused))
+ int memcmp(const void *s1, const void *s2, size_t n)
+ {
+ 	size_t ofs = 0;
+-	char c1 = 0;
++	int c1 = 0;
+ 
+-	while (ofs < n && !(c1 = ((char *)s1)[ofs] - ((char *)s2)[ofs])) {
++	while (ofs < n && !(c1 = ((unsigned char *)s1)[ofs] - ((unsigned char *)s2)[ofs])) {
+ 		ofs++;
+ 	}
+ 	return c1;
+@@ -125,14 +125,18 @@ char *strcpy(char *dst, const char *src)
+ }
+ 
+ /* this function is only used with arguments that are not constants or when
+- * it's not known because optimizations are disabled.
++ * it's not known because optimizations are disabled. Note that gcc 12
++ * recognizes an strlen() pattern and replaces it with a jump to strlen(),
++ * thus itself, hence the asm() statement below that's meant to disable this
++ * confusing practice.
+  */
+ static __attribute__((unused))
+-size_t nolibc_strlen(const char *str)
++size_t strlen(const char *str)
+ {
+ 	size_t len;
+ 
+-	for (len = 0; str[len]; len++);
++	for (len = 0; str[len]; len++)
++		asm("");
+ 	return len;
+ }
+ 
+@@ -140,13 +144,12 @@ size_t nolibc_strlen(const char *str)
+  * the two branches, then will rely on an external definition of strlen().
+  */
+ #if defined(__OPTIMIZE__)
++#define nolibc_strlen(x) strlen(x)
+ #define strlen(str) ({                          \
+ 	__builtin_constant_p((str)) ?           \
+ 		__builtin_strlen((str)) :       \
+ 		nolibc_strlen((str));           \
+ })
+-#else
+-#define strlen(str) nolibc_strlen((str))
+ #endif
+ 
+ static __attribute__((unused))
+diff --git a/tools/testing/selftests/landlock/Makefile b/tools/testing/selftests/landlock/Makefile
+index 6632bfff486b8..348e2dbdb4e0b 100644
+--- a/tools/testing/selftests/landlock/Makefile
++++ b/tools/testing/selftests/landlock/Makefile
+@@ -3,7 +3,6 @@
+ # First run: make -C ../../../.. headers_install
+ 
+ CFLAGS += -Wall -O2 $(KHDR_INCLUDES)
+-LDLIBS += -lcap
+ 
+ LOCAL_HDRS += common.h
+ 
+@@ -13,10 +12,12 @@ TEST_GEN_PROGS := $(src_test:.c=)
+ 
+ TEST_GEN_PROGS_EXTENDED := true
+ 
+-# Static linking for short targets:
++# Short targets:
++$(TEST_GEN_PROGS): LDLIBS += -lcap
+ $(TEST_GEN_PROGS_EXTENDED): LDFLAGS += -static
+ 
+ include ../lib.mk
+ 
+-# Static linking for targets with $(OUTPUT)/ prefix:
++# Targets with $(OUTPUT)/ prefix:
++$(TEST_GEN_PROGS): LDLIBS += -lcap
+ $(TEST_GEN_PROGS_EXTENDED): LDFLAGS += -static
+diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c
+index 68ff41d395452..346e47f155724 100644
+--- a/virt/kvm/pfncache.c
++++ b/virt/kvm/pfncache.c
+@@ -81,6 +81,9 @@ bool kvm_gfn_to_pfn_cache_check(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ {
+ 	struct kvm_memslots *slots = kvm_memslots(kvm);
+ 
++	if (!gpc->active)
++		return false;
++
+ 	if ((gpa & ~PAGE_MASK) + len > PAGE_SIZE)
+ 		return false;
+ 
+@@ -240,10 +243,11 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ {
+ 	struct kvm_memslots *slots = kvm_memslots(kvm);
+ 	unsigned long page_offset = gpa & ~PAGE_MASK;
+-	kvm_pfn_t old_pfn, new_pfn;
++	bool unmap_old = false;
+ 	unsigned long old_uhva;
++	kvm_pfn_t old_pfn;
+ 	void *old_khva;
+-	int ret = 0;
++	int ret;
+ 
+ 	/*
+ 	 * If must fit within a single page. The 'len' argument is
+@@ -261,6 +265,11 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ 
+ 	write_lock_irq(&gpc->lock);
+ 
++	if (!gpc->active) {
++		ret = -EINVAL;
++		goto out_unlock;
++	}
++
+ 	old_pfn = gpc->pfn;
+ 	old_khva = gpc->khva - offset_in_page(gpc->khva);
+ 	old_uhva = gpc->uhva;
+@@ -291,6 +300,7 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ 		/* If the HVA→PFN mapping was already valid, don't unmap it. */
+ 		old_pfn = KVM_PFN_ERR_FAULT;
+ 		old_khva = NULL;
++		ret = 0;
+ 	}
+ 
+  out:
+@@ -305,14 +315,15 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+ 		gpc->khva = NULL;
+ 	}
+ 
+-	/* Snapshot the new pfn before dropping the lock! */
+-	new_pfn = gpc->pfn;
++	/* Detect a pfn change before dropping the lock! */
++	unmap_old = (old_pfn != gpc->pfn);
+ 
++out_unlock:
+ 	write_unlock_irq(&gpc->lock);
+ 
+ 	mutex_unlock(&gpc->refresh_lock);
+ 
+-	if (old_pfn != new_pfn)
++	if (unmap_old)
+ 		gpc_unmap_khva(kvm, old_pfn, old_khva);
+ 
+ 	return ret;
+@@ -346,42 +357,61 @@ void kvm_gfn_to_pfn_cache_unmap(struct kvm *kvm, struct gfn_to_pfn_cache *gpc)
+ }
+ EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_unmap);
+ 
++void kvm_gpc_init(struct gfn_to_pfn_cache *gpc)
++{
++	rwlock_init(&gpc->lock);
++	mutex_init(&gpc->refresh_lock);
++}
++EXPORT_SYMBOL_GPL(kvm_gpc_init);
+ 
+-int kvm_gfn_to_pfn_cache_init(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
+-			      struct kvm_vcpu *vcpu, enum pfn_cache_usage usage,
+-			      gpa_t gpa, unsigned long len)
++int kvm_gpc_activate(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
++		     struct kvm_vcpu *vcpu, enum pfn_cache_usage usage,
++		     gpa_t gpa, unsigned long len)
+ {
+ 	WARN_ON_ONCE(!usage || (usage & KVM_GUEST_AND_HOST_USE_PFN) != usage);
+ 
+ 	if (!gpc->active) {
+-		rwlock_init(&gpc->lock);
+-		mutex_init(&gpc->refresh_lock);
+-
+ 		gpc->khva = NULL;
+ 		gpc->pfn = KVM_PFN_ERR_FAULT;
+ 		gpc->uhva = KVM_HVA_ERR_BAD;
+ 		gpc->vcpu = vcpu;
+ 		gpc->usage = usage;
+ 		gpc->valid = false;
+-		gpc->active = true;
+ 
+ 		spin_lock(&kvm->gpc_lock);
+ 		list_add(&gpc->list, &kvm->gpc_list);
+ 		spin_unlock(&kvm->gpc_lock);
++
++		/*
++		 * Activate the cache after adding it to the list, a concurrent
++		 * refresh must not establish a mapping until the cache is
++		 * reachable by mmu_notifier events.
++		 */
++		write_lock_irq(&gpc->lock);
++		gpc->active = true;
++		write_unlock_irq(&gpc->lock);
+ 	}
+ 	return kvm_gfn_to_pfn_cache_refresh(kvm, gpc, gpa, len);
+ }
+-EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_init);
++EXPORT_SYMBOL_GPL(kvm_gpc_activate);
+ 
+-void kvm_gfn_to_pfn_cache_destroy(struct kvm *kvm, struct gfn_to_pfn_cache *gpc)
++void kvm_gpc_deactivate(struct kvm *kvm, struct gfn_to_pfn_cache *gpc)
+ {
+ 	if (gpc->active) {
++		/*
++		 * Deactivate the cache before removing it from the list, KVM
++		 * must stall mmu_notifier events until all users go away, i.e.
++		 * until gpc->lock is dropped and refresh is guaranteed to fail.
++		 */
++		write_lock_irq(&gpc->lock);
++		gpc->active = false;
++		write_unlock_irq(&gpc->lock);
++
+ 		spin_lock(&kvm->gpc_lock);
+ 		list_del(&gpc->list);
+ 		spin_unlock(&kvm->gpc_lock);
+ 
+ 		kvm_gfn_to_pfn_cache_unmap(kvm, gpc);
+-		gpc->active = false;
+ 	}
+ }
+-EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_destroy);
++EXPORT_SYMBOL_GPL(kvm_gpc_deactivate);


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-09 19:00 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-11-09 19:00 UTC (permalink / raw
  To: gentoo-commits

commit:     b5e5b27b8f93dc75bf46515f069c294820553d54
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Nov  9 18:59:50 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Nov  9 18:59:50 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=b5e5b27b

bpf: mark get_entry_ip as __maybe_unused

Bug: https://bugs.gentoo.org/878831

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

 0000_README                                       |  4 ++++
 2910_bfp-mark-get-entry-ip-as--maybe-unused.patch | 11 +++++++++++
 2 files changed, 15 insertions(+)

diff --git a/0000_README b/0000_README
index 9f94b8ae..004afc57 100644
--- a/0000_README
+++ b/0000_README
@@ -95,6 +95,10 @@ Patch:  2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
 From:   https://bugs.gentoo.org/710790
 Desc:   tmp513 requies REGMAP_I2C to build.  Select it by default in Kconfig. See bug #710790. Thanks to Phil Stracchino
 
+Patch:  2910_bfp-mark-get-entry-ip-as--maybe-unused.patch
+From:   https://www.spinics.net/lists/stable/msg604665.html
+Desc:   bpf: mark get_entry_ip as __maybe_unused
+
 Patch:  2920_sign-file-patch-for-libressl.patch
 From:   https://bugs.gentoo.org/717166
 Desc:   sign-file: full functionality with modern LibreSSL

diff --git a/2910_bfp-mark-get-entry-ip-as--maybe-unused.patch b/2910_bfp-mark-get-entry-ip-as--maybe-unused.patch
new file mode 100644
index 00000000..a75b90c8
--- /dev/null
+++ b/2910_bfp-mark-get-entry-ip-as--maybe-unused.patch
@@ -0,0 +1,11 @@
+--- a/kernel/trace/bpf_trace.c	2022-11-09 13:30:24.192940988 -0500
++++ b/kernel/trace/bpf_trace.c	2022-11-09 13:30:59.029810818 -0500
+@@ -1027,7 +1027,7 @@ static const struct bpf_func_proto bpf_g
+ };
+ 
+ #ifdef CONFIG_X86_KERNEL_IBT
+-static unsigned long get_entry_ip(unsigned long fentry_ip)
++static unsigned long __maybe_unused get_entry_ip(unsigned long fentry_ip)
+ {
+ 	u32 instr;
+ 


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-03 15:27 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-11-03 15:27 UTC (permalink / raw
  To: gentoo-commits

commit:     7902df925836e53559cdf8bbc48da70d486faaf7
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Nov  3 15:27:02 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Nov  3 15:27:02 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=7902df92

Linux patch 6.0.7

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

 0000_README            |     4 +
 1006_linux-6.0.7.patch | 10948 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 10952 insertions(+)

diff --git a/0000_README b/0000_README
index a0b5ecc7..9f94b8ae 100644
--- a/0000_README
+++ b/0000_README
@@ -67,6 +67,10 @@ Patch:  1005_linux-6.0.6.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.6
 
+Patch:  1006_linux-6.0.7.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.7
+
 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/1006_linux-6.0.7.patch b/1006_linux-6.0.7.patch
new file mode 100644
index 00000000..d7ae366a
--- /dev/null
+++ b/1006_linux-6.0.7.patch
@@ -0,0 +1,10948 @@
+diff --git a/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
+index 1e2b9b627b126..2722dc7bb03da 100644
+--- a/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
++++ b/Documentation/devicetree/bindings/pinctrl/xlnx,zynqmp-pinctrl.yaml
+@@ -274,10 +274,6 @@ patternProperties:
+           slew-rate:
+             enum: [0, 1]
+ 
+-          output-enable:
+-            description:
+-              This will internally disable the tri-state for MIO pins.
+-
+           drive-strength:
+             description:
+               Selects the drive strength for MIO pins, in mA.
+diff --git a/Makefile b/Makefile
+index e6c10009d413a..c2144a4bb2efe 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 6
++SUBLEVEL = 7
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h
+index 8f777d6441a5d..80347382a3800 100644
+--- a/arch/arc/include/asm/io.h
++++ b/arch/arc/include/asm/io.h
+@@ -32,7 +32,7 @@ static inline void ioport_unmap(void __iomem *addr)
+ {
+ }
+ 
+-extern void iounmap(const void __iomem *addr);
++extern void iounmap(const volatile void __iomem *addr);
+ 
+ /*
+  * io{read,write}{16,32}be() macros
+diff --git a/arch/arc/include/asm/pgtable-levels.h b/arch/arc/include/asm/pgtable-levels.h
+index 64ca25d199bea..ef68758b69f7e 100644
+--- a/arch/arc/include/asm/pgtable-levels.h
++++ b/arch/arc/include/asm/pgtable-levels.h
+@@ -161,7 +161,7 @@
+ #define pmd_pfn(pmd)		((pmd_val(pmd) & PAGE_MASK) >> PAGE_SHIFT)
+ #define pmd_page(pmd)		virt_to_page(pmd_page_vaddr(pmd))
+ #define set_pmd(pmdp, pmd)	(*(pmdp) = pmd)
+-#define pmd_pgtable(pmd)	((pgtable_t) pmd_page_vaddr(pmd))
++#define pmd_pgtable(pmd)	((pgtable_t) pmd_page(pmd))
+ 
+ /*
+  * 4th level paging: pte
+diff --git a/arch/arc/mm/ioremap.c b/arch/arc/mm/ioremap.c
+index 0ee75aca6e109..712c2311daefb 100644
+--- a/arch/arc/mm/ioremap.c
++++ b/arch/arc/mm/ioremap.c
+@@ -94,7 +94,7 @@ void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size,
+ EXPORT_SYMBOL(ioremap_prot);
+ 
+ 
+-void iounmap(const void __iomem *addr)
++void iounmap(const volatile void __iomem *addr)
+ {
+ 	/* weird double cast to handle phys_addr_t > 32 bits */
+ 	if (arc_uncached_addr_space((phys_addr_t)(u32)addr))
+diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
+index 8aa0d276a6362..abc418650fec0 100644
+--- a/arch/arm64/include/asm/cputype.h
++++ b/arch/arm64/include/asm/cputype.h
+@@ -60,6 +60,7 @@
+ #define ARM_CPU_IMP_FUJITSU		0x46
+ #define ARM_CPU_IMP_HISI		0x48
+ #define ARM_CPU_IMP_APPLE		0x61
++#define ARM_CPU_IMP_AMPERE		0xC0
+ 
+ #define ARM_CPU_PART_AEM_V8		0xD0F
+ #define ARM_CPU_PART_FOUNDATION		0xD00
+@@ -123,6 +124,8 @@
+ #define APPLE_CPU_PART_M1_ICESTORM_MAX	0x028
+ #define APPLE_CPU_PART_M1_FIRESTORM_MAX	0x029
+ 
++#define AMPERE_CPU_PART_AMPERE1		0xAC3
++
+ #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
+ #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
+ #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
+@@ -172,6 +175,7 @@
+ #define MIDR_APPLE_M1_FIRESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO)
+ #define MIDR_APPLE_M1_ICESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX)
+ #define MIDR_APPLE_M1_FIRESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX)
++#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
+ 
+ /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
+ #define MIDR_FUJITSU_ERRATUM_010001		MIDR_FUJITSU_A64FX
+diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
+index 40be3a7c2c531..428cfabd11c49 100644
+--- a/arch/arm64/kernel/proton-pack.c
++++ b/arch/arm64/kernel/proton-pack.c
+@@ -868,6 +868,10 @@ u8 spectre_bhb_loop_affected(int scope)
+ 			MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+ 			{},
+ 		};
++		static const struct midr_range spectre_bhb_k11_list[] = {
++			MIDR_ALL_VERSIONS(MIDR_AMPERE1),
++			{},
++		};
+ 		static const struct midr_range spectre_bhb_k8_list[] = {
+ 			MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
+ 			MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
+@@ -878,6 +882,8 @@ u8 spectre_bhb_loop_affected(int scope)
+ 			k = 32;
+ 		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list))
+ 			k = 24;
++		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list))
++			k = 11;
+ 		else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list))
+ 			k =  8;
+ 
+diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S
+index 2ca1c037ea258..4d54b90f46274 100644
+--- a/arch/powerpc/kernel/interrupt_64.S
++++ b/arch/powerpc/kernel/interrupt_64.S
+@@ -565,15 +565,24 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
+ 	 * Returning to soft-disabled context.
+ 	 * Check if a MUST_HARD_MASK interrupt has become pending, in which
+ 	 * case we need to disable MSR[EE] in the return context.
++	 *
++	 * The MSR[EE] check catches among other things the short incoherency
++	 * in hard_irq_disable() between clearing MSR[EE] and setting
++	 * PACA_IRQ_HARD_DIS.
+ 	 */
+ 	ld	r12,_MSR(r1)
+ 	andi.	r10,r12,MSR_EE
+ 	beq	.Lfast_kernel_interrupt_return_\srr\() // EE already disabled
+ 	lbz	r11,PACAIRQHAPPENED(r13)
+ 	andi.	r10,r11,PACA_IRQ_MUST_HARD_MASK
+-	beq	.Lfast_kernel_interrupt_return_\srr\() // No HARD_MASK pending
++	bne	1f // HARD_MASK is pending
++	// No HARD_MASK pending, clear possible HARD_DIS set by interrupt
++	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
++	stb	r11,PACAIRQHAPPENED(r13)
++	b	.Lfast_kernel_interrupt_return_\srr\()
++
+ 
+-	/* Must clear MSR_EE from _MSR */
++1:	/* Must clear MSR_EE from _MSR */
+ #ifdef CONFIG_PPC_BOOK3S
+ 	li	r10,0
+ 	/* Clear valid before changing _MSR */
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index cea22ccb57cb9..9d5b7fa1b6225 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -402,14 +402,16 @@ config RISCV_ISA_SVPBMT
+ 
+ 	   If you don't know what to do here, say Y.
+ 
+-config CC_HAS_ZICBOM
++config TOOLCHAIN_HAS_ZICBOM
+ 	bool
+-	default y if 64BIT && $(cc-option,-mabi=lp64 -march=rv64ima_zicbom)
+-	default y if 32BIT && $(cc-option,-mabi=ilp32 -march=rv32ima_zicbom)
++	default y
++	depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zicbom)
++	depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zicbom)
++	depends on LLD_VERSION >= 150000 || LD_VERSION >= 23800
+ 
+ config RISCV_ISA_ZICBOM
+ 	bool "Zicbom extension support for non-coherent DMA operation"
+-	depends on CC_HAS_ZICBOM
++	depends on TOOLCHAIN_HAS_ZICBOM
+ 	depends on !XIP_KERNEL && MMU
+ 	select RISCV_DMA_NONCOHERENT
+ 	select RISCV_ALTERNATIVE
+@@ -424,6 +426,13 @@ config RISCV_ISA_ZICBOM
+ 
+ 	   If you don't know what to do here, say Y.
+ 
++config TOOLCHAIN_HAS_ZIHINTPAUSE
++	bool
++	default y
++	depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zihintpause)
++	depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zihintpause)
++	depends on LLD_VERSION >= 150000 || LD_VERSION >= 23600
++
+ config FPU
+ 	bool "FPU support"
+ 	default y
+diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
+index e7d52a2301e26..e5a608e37f456 100644
+--- a/arch/riscv/Makefile
++++ b/arch/riscv/Makefile
+@@ -59,12 +59,10 @@ toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zi
+ riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei
+ 
+ # Check if the toolchain supports Zicbom extension
+-toolchain-supports-zicbom := $(call cc-option-yn, -march=$(riscv-march-y)_zicbom)
+-riscv-march-$(toolchain-supports-zicbom) := $(riscv-march-y)_zicbom
++riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZICBOM) := $(riscv-march-y)_zicbom
+ 
+ # Check if the toolchain supports Zihintpause extension
+-toolchain-supports-zihintpause := $(call cc-option-yn, -march=$(riscv-march-y)_zihintpause)
+-riscv-march-$(toolchain-supports-zihintpause) := $(riscv-march-y)_zihintpause
++riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE) := $(riscv-march-y)_zihintpause
+ 
+ KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
+ KBUILD_AFLAGS += -march=$(riscv-march-y)
+diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
+index 273ece6b622f6..1470e556cdb17 100644
+--- a/arch/riscv/include/asm/cacheflush.h
++++ b/arch/riscv/include/asm/cacheflush.h
+@@ -42,16 +42,8 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
+ 
+ #endif /* CONFIG_SMP */
+ 
+-/*
+- * The T-Head CMO errata internally probe the CBOM block size, but otherwise
+- * don't depend on Zicbom.
+- */
+ extern unsigned int riscv_cbom_block_size;
+-#ifdef CONFIG_RISCV_ISA_ZICBOM
+ void riscv_init_cbom_blocksize(void);
+-#else
+-static inline void riscv_init_cbom_blocksize(void) { }
+-#endif
+ 
+ #ifdef CONFIG_RISCV_DMA_NONCOHERENT
+ void riscv_noncoherent_supported(void);
+diff --git a/arch/riscv/include/asm/jump_label.h b/arch/riscv/include/asm/jump_label.h
+index 38af2ec7b9bf9..6d58bbb5da467 100644
+--- a/arch/riscv/include/asm/jump_label.h
++++ b/arch/riscv/include/asm/jump_label.h
+@@ -14,8 +14,8 @@
+ 
+ #define JUMP_LABEL_NOP_SIZE 4
+ 
+-static __always_inline bool arch_static_branch(struct static_key *key,
+-					       bool branch)
++static __always_inline bool arch_static_branch(struct static_key * const key,
++					       const bool branch)
+ {
+ 	asm_volatile_goto(
+ 		"	.option push				\n\t"
+@@ -35,8 +35,8 @@ label:
+ 	return true;
+ }
+ 
+-static __always_inline bool arch_static_branch_jump(struct static_key *key,
+-						    bool branch)
++static __always_inline bool arch_static_branch_jump(struct static_key * const key,
++						    const bool branch)
+ {
+ 	asm_volatile_goto(
+ 		"	.option push				\n\t"
+diff --git a/arch/riscv/include/asm/kvm_vcpu_timer.h b/arch/riscv/include/asm/kvm_vcpu_timer.h
+index 0d8fdb8ec63aa..82f7260301da2 100644
+--- a/arch/riscv/include/asm/kvm_vcpu_timer.h
++++ b/arch/riscv/include/asm/kvm_vcpu_timer.h
+@@ -45,6 +45,7 @@ int kvm_riscv_vcpu_timer_deinit(struct kvm_vcpu *vcpu);
+ int kvm_riscv_vcpu_timer_reset(struct kvm_vcpu *vcpu);
+ void kvm_riscv_vcpu_timer_restore(struct kvm_vcpu *vcpu);
+ void kvm_riscv_guest_timer_init(struct kvm *kvm);
++void kvm_riscv_vcpu_timer_sync(struct kvm_vcpu *vcpu);
+ void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu);
+ bool kvm_riscv_vcpu_timer_pending(struct kvm_vcpu *vcpu);
+ 
+diff --git a/arch/riscv/include/asm/vdso/processor.h b/arch/riscv/include/asm/vdso/processor.h
+index 1e4f8b4aef79d..fa70cfe507aa1 100644
+--- a/arch/riscv/include/asm/vdso/processor.h
++++ b/arch/riscv/include/asm/vdso/processor.h
+@@ -21,7 +21,7 @@ static inline void cpu_relax(void)
+ 		 * Reduce instruction retirement.
+ 		 * This assumes the PC changes.
+ 		 */
+-#ifdef __riscv_zihintpause
++#ifdef CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE
+ 		__asm__ __volatile__ ("pause");
+ #else
+ 		/* Encoding of the pause instruction */
+diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h
+index 7351417afd62e..b9a4cf36be4bf 100644
+--- a/arch/riscv/include/uapi/asm/kvm.h
++++ b/arch/riscv/include/uapi/asm/kvm.h
+@@ -48,6 +48,7 @@ struct kvm_sregs {
+ /* CONFIG registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
+ struct kvm_riscv_config {
+ 	unsigned long isa;
++	unsigned long zicbom_block_size;
+ };
+ 
+ /* CORE registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
+diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
+index d0f08d5b42829..f692c0716aa7a 100644
+--- a/arch/riscv/kvm/vcpu.c
++++ b/arch/riscv/kvm/vcpu.c
+@@ -18,6 +18,7 @@
+ #include <linux/fs.h>
+ #include <linux/kvm_host.h>
+ #include <asm/csr.h>
++#include <asm/cacheflush.h>
+ #include <asm/hwcap.h>
+ 
+ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
+@@ -254,6 +255,11 @@ static int kvm_riscv_vcpu_get_reg_config(struct kvm_vcpu *vcpu,
+ 	case KVM_REG_RISCV_CONFIG_REG(isa):
+ 		reg_val = vcpu->arch.isa[0] & KVM_RISCV_BASE_ISA_MASK;
+ 		break;
++	case KVM_REG_RISCV_CONFIG_REG(zicbom_block_size):
++		if (!riscv_isa_extension_available(vcpu->arch.isa, ZICBOM))
++			return -EINVAL;
++		reg_val = riscv_cbom_block_size;
++		break;
+ 	default:
+ 		return -EINVAL;
+ 	}
+@@ -311,6 +317,8 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
+ 			return -EOPNOTSUPP;
+ 		}
+ 		break;
++	case KVM_REG_RISCV_CONFIG_REG(zicbom_block_size):
++		return -EOPNOTSUPP;
+ 	default:
+ 		return -EINVAL;
+ 	}
+@@ -690,6 +698,9 @@ void kvm_riscv_vcpu_sync_interrupts(struct kvm_vcpu *vcpu)
+ 				clear_bit(IRQ_VS_SOFT, &v->irqs_pending);
+ 		}
+ 	}
++
++	/* Sync-up timer CSRs */
++	kvm_riscv_vcpu_timer_sync(vcpu);
+ }
+ 
+ int kvm_riscv_vcpu_set_interrupt(struct kvm_vcpu *vcpu, unsigned int irq)
+diff --git a/arch/riscv/kvm/vcpu_timer.c b/arch/riscv/kvm/vcpu_timer.c
+index 185f2386a747e..ad34519c8a13d 100644
+--- a/arch/riscv/kvm/vcpu_timer.c
++++ b/arch/riscv/kvm/vcpu_timer.c
+@@ -320,20 +320,33 @@ void kvm_riscv_vcpu_timer_restore(struct kvm_vcpu *vcpu)
+ 	kvm_riscv_vcpu_timer_unblocking(vcpu);
+ }
+ 
+-void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu)
++void kvm_riscv_vcpu_timer_sync(struct kvm_vcpu *vcpu)
+ {
+ 	struct kvm_vcpu_timer *t = &vcpu->arch.timer;
+ 
+ 	if (!t->sstc_enabled)
+ 		return;
+ 
+-	t = &vcpu->arch.timer;
+ #if defined(CONFIG_32BIT)
+ 	t->next_cycles = csr_read(CSR_VSTIMECMP);
+ 	t->next_cycles |= (u64)csr_read(CSR_VSTIMECMPH) << 32;
+ #else
+ 	t->next_cycles = csr_read(CSR_VSTIMECMP);
+ #endif
++}
++
++void kvm_riscv_vcpu_timer_save(struct kvm_vcpu *vcpu)
++{
++	struct kvm_vcpu_timer *t = &vcpu->arch.timer;
++
++	if (!t->sstc_enabled)
++		return;
++
++	/*
++	 * The vstimecmp CSRs are saved by kvm_riscv_vcpu_timer_sync()
++	 * upon every VM exit so no need to save here.
++	 */
++
+ 	/* timer should be enabled for the remaining operations */
+ 	if (unlikely(!t->init_done))
+ 		return;
+diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
+index 6cb7d96ad9c7b..57b40a3504206 100644
+--- a/arch/riscv/mm/cacheflush.c
++++ b/arch/riscv/mm/cacheflush.c
+@@ -3,6 +3,7 @@
+  * Copyright (C) 2017 SiFive
+  */
+ 
++#include <linux/of.h>
+ #include <asm/cacheflush.h>
+ 
+ #ifdef CONFIG_SMP
+@@ -86,3 +87,40 @@ void flush_icache_pte(pte_t pte)
+ 		flush_icache_all();
+ }
+ #endif /* CONFIG_MMU */
++
++unsigned int riscv_cbom_block_size;
++EXPORT_SYMBOL_GPL(riscv_cbom_block_size);
++
++void riscv_init_cbom_blocksize(void)
++{
++	struct device_node *node;
++	unsigned long cbom_hartid;
++	u32 val, probed_block_size;
++	int ret;
++
++	probed_block_size = 0;
++	for_each_of_cpu_node(node) {
++		unsigned long hartid;
++
++		ret = riscv_of_processor_hartid(node, &hartid);
++		if (ret)
++			continue;
++
++		/* set block-size for cbom extension if available */
++		ret = of_property_read_u32(node, "riscv,cbom-block-size", &val);
++		if (ret)
++			continue;
++
++		if (!probed_block_size) {
++			probed_block_size = val;
++			cbom_hartid = hartid;
++		} else {
++			if (probed_block_size != val)
++				pr_warn("cbom-block-size mismatched between harts %lu and %lu\n",
++					cbom_hartid, hartid);
++		}
++	}
++
++	if (probed_block_size)
++		riscv_cbom_block_size = probed_block_size;
++}
+diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoherent.c
+index e3f9bdf47c5ff..d919efab6ebad 100644
+--- a/arch/riscv/mm/dma-noncoherent.c
++++ b/arch/riscv/mm/dma-noncoherent.c
+@@ -8,11 +8,8 @@
+ #include <linux/dma-direct.h>
+ #include <linux/dma-map-ops.h>
+ #include <linux/mm.h>
+-#include <linux/of.h>
+-#include <linux/of_device.h>
+ #include <asm/cacheflush.h>
+ 
+-unsigned int riscv_cbom_block_size;
+ static bool noncoherent_supported;
+ 
+ void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
+@@ -75,42 +72,6 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ 	dev->dma_coherent = coherent;
+ }
+ 
+-#ifdef CONFIG_RISCV_ISA_ZICBOM
+-void riscv_init_cbom_blocksize(void)
+-{
+-	struct device_node *node;
+-	unsigned long cbom_hartid;
+-	u32 val, probed_block_size;
+-	int ret;
+-
+-	probed_block_size = 0;
+-	for_each_of_cpu_node(node) {
+-		unsigned long hartid;
+-
+-		ret = riscv_of_processor_hartid(node, &hartid);
+-		if (ret)
+-			continue;
+-
+-		/* set block-size for cbom extension if available */
+-		ret = of_property_read_u32(node, "riscv,cbom-block-size", &val);
+-		if (ret)
+-			continue;
+-
+-		if (!probed_block_size) {
+-			probed_block_size = val;
+-			cbom_hartid = hartid;
+-		} else {
+-			if (probed_block_size != val)
+-				pr_warn("cbom-block-size mismatched between harts %lu and %lu\n",
+-					cbom_hartid, hartid);
+-		}
+-	}
+-
+-	if (probed_block_size)
+-		riscv_cbom_block_size = probed_block_size;
+-}
+-#endif
+-
+ void riscv_noncoherent_supported(void)
+ {
+ 	WARN(!riscv_cbom_block_size,
+diff --git a/arch/riscv/mm/kasan_init.c b/arch/riscv/mm/kasan_init.c
+index a22e418dbd82c..e1226709490fa 100644
+--- a/arch/riscv/mm/kasan_init.c
++++ b/arch/riscv/mm/kasan_init.c
+@@ -113,6 +113,8 @@ static void __init kasan_populate_pud(pgd_t *pgd,
+ 		base_pud = pt_ops.get_pud_virt(pfn_to_phys(_pgd_pfn(*pgd)));
+ 	} else if (pgd_none(*pgd)) {
+ 		base_pud = memblock_alloc(PTRS_PER_PUD * sizeof(pud_t), PAGE_SIZE);
++		memcpy(base_pud, (void *)kasan_early_shadow_pud,
++			sizeof(pud_t) * PTRS_PER_PUD);
+ 	} else {
+ 		base_pud = (pud_t *)pgd_page_vaddr(*pgd);
+ 		if (base_pud == lm_alias(kasan_early_shadow_pud)) {
+@@ -173,8 +175,11 @@ static void __init kasan_populate_p4d(pgd_t *pgd,
+ 		base_p4d = pt_ops.get_p4d_virt(pfn_to_phys(_pgd_pfn(*pgd)));
+ 	} else {
+ 		base_p4d = (p4d_t *)pgd_page_vaddr(*pgd);
+-		if (base_p4d == lm_alias(kasan_early_shadow_p4d))
++		if (base_p4d == lm_alias(kasan_early_shadow_p4d)) {
+ 			base_p4d = memblock_alloc(PTRS_PER_PUD * sizeof(p4d_t), PAGE_SIZE);
++			memcpy(base_p4d, (void *)kasan_early_shadow_p4d,
++				sizeof(p4d_t) * PTRS_PER_P4D);
++		}
+ 	}
+ 
+ 	p4dp = base_p4d + p4d_index(vaddr);
+diff --git a/arch/s390/boot/vmlinux.lds.S b/arch/s390/boot/vmlinux.lds.S
+index af5c6860e0a11..fa9d33b01b858 100644
+--- a/arch/s390/boot/vmlinux.lds.S
++++ b/arch/s390/boot/vmlinux.lds.S
+@@ -102,8 +102,17 @@ SECTIONS
+ 		_compressed_start = .;
+ 		*(.vmlinux.bin.compressed)
+ 		_compressed_end = .;
+-		FILL(0xff);
+-		. = ALIGN(4096);
++	}
++
++#define SB_TRAILER_SIZE 32
++	/* Trailer needed for Secure Boot */
++	. += SB_TRAILER_SIZE; /* make sure .sb.trailer does not overwrite the previous section */
++	. = ALIGN(4096) - SB_TRAILER_SIZE;
++	.sb.trailer : {
++		QUAD(0)
++		QUAD(0)
++		QUAD(0)
++		QUAD(0x000000207a49504c)
+ 	}
+ 	_end = .;
+ 
+diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h
+index e08c882dccaae..eaeaeb3ff0be3 100644
+--- a/arch/s390/include/asm/futex.h
++++ b/arch/s390/include/asm/futex.h
+@@ -17,7 +17,8 @@
+ 		"3: jl    1b\n"						\
+ 		"   lhi   %0,0\n"					\
+ 		"4: sacf  768\n"					\
+-		EX_TABLE(0b,4b) EX_TABLE(2b,4b) EX_TABLE(3b,4b)		\
++		EX_TABLE(0b,4b) EX_TABLE(1b,4b)				\
++		EX_TABLE(2b,4b) EX_TABLE(3b,4b)				\
+ 		: "=d" (ret), "=&d" (oldval), "=&d" (newval),		\
+ 		  "=m" (*uaddr)						\
+ 		: "0" (-EFAULT), "d" (oparg), "a" (uaddr),		\
+diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c
+index d7b3b193d1088..be0f1b62c33b3 100644
+--- a/arch/s390/lib/uaccess.c
++++ b/arch/s390/lib/uaccess.c
+@@ -156,7 +156,7 @@ unsigned long __clear_user(void __user *to, unsigned long size)
+ 	asm volatile(
+ 		"   lr	  0,%[spec]\n"
+ 		"0: mvcos 0(%1),0(%4),%0\n"
+-		"   jz	  4f\n"
++		"6: jz	  4f\n"
+ 		"1: algr  %0,%2\n"
+ 		"   slgr  %1,%2\n"
+ 		"   j	  0b\n"
+@@ -166,11 +166,11 @@ unsigned long __clear_user(void __user *to, unsigned long size)
+ 		"   clgr  %0,%3\n"	/* copy crosses next page boundary? */
+ 		"   jnh	  5f\n"
+ 		"3: mvcos 0(%1),0(%4),%3\n"
+-		"   slgr  %0,%3\n"
++		"7: slgr  %0,%3\n"
+ 		"   j	  5f\n"
+ 		"4: slgr  %0,%0\n"
+ 		"5:\n"
+-		EX_TABLE(0b,2b) EX_TABLE(3b,5b)
++		EX_TABLE(0b,2b) EX_TABLE(6b,2b) EX_TABLE(3b,5b) EX_TABLE(7b,5b)
+ 		: "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2)
+ 		: "a" (empty_zero_page), [spec] "d" (spec.val)
+ 		: "cc", "memory", "0");
+diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c
+index 080c88620723a..5880893329310 100644
+--- a/arch/s390/pci/pci_mmio.c
++++ b/arch/s390/pci/pci_mmio.c
+@@ -64,7 +64,7 @@ static inline int __pcistg_mio_inuser(
+ 	asm volatile (
+ 		"       sacf    256\n"
+ 		"0:     llgc    %[tmp],0(%[src])\n"
+-		"       sllg    %[val],%[val],8\n"
++		"4:	sllg	%[val],%[val],8\n"
+ 		"       aghi    %[src],1\n"
+ 		"       ogr     %[val],%[tmp]\n"
+ 		"       brctg   %[cnt],0b\n"
+@@ -72,7 +72,7 @@ static inline int __pcistg_mio_inuser(
+ 		"2:     ipm     %[cc]\n"
+ 		"       srl     %[cc],28\n"
+ 		"3:     sacf    768\n"
+-		EX_TABLE(0b, 3b) EX_TABLE(1b, 3b) EX_TABLE(2b, 3b)
++		EX_TABLE(0b, 3b) EX_TABLE(4b, 3b) EX_TABLE(1b, 3b) EX_TABLE(2b, 3b)
+ 		:
+ 		[src] "+a" (src), [cnt] "+d" (cnt),
+ 		[val] "+d" (val), [tmp] "=d" (tmp),
+@@ -215,10 +215,10 @@ static inline int __pcilg_mio_inuser(
+ 		"2:     ahi     %[shift],-8\n"
+ 		"       srlg    %[tmp],%[val],0(%[shift])\n"
+ 		"3:     stc     %[tmp],0(%[dst])\n"
+-		"       aghi    %[dst],1\n"
++		"5:	aghi	%[dst],1\n"
+ 		"       brctg   %[cnt],2b\n"
+ 		"4:     sacf    768\n"
+-		EX_TABLE(0b, 4b) EX_TABLE(1b, 4b) EX_TABLE(3b, 4b)
++		EX_TABLE(0b, 4b) EX_TABLE(1b, 4b) EX_TABLE(3b, 4b) EX_TABLE(5b, 4b)
+ 		:
+ 		[ioaddr_len] "+&d" (ioaddr_len.pair),
+ 		[cc] "+d" (cc), [val] "=d" (val),
+diff --git a/arch/x86/crypto/polyval-clmulni_glue.c b/arch/x86/crypto/polyval-clmulni_glue.c
+index b7664d0188510..8fa58b0f3cb3d 100644
+--- a/arch/x86/crypto/polyval-clmulni_glue.c
++++ b/arch/x86/crypto/polyval-clmulni_glue.c
+@@ -27,13 +27,17 @@
+ #include <asm/cpu_device_id.h>
+ #include <asm/simd.h>
+ 
++#define POLYVAL_ALIGN	16
++#define POLYVAL_ALIGN_ATTR __aligned(POLYVAL_ALIGN)
++#define POLYVAL_ALIGN_EXTRA ((POLYVAL_ALIGN - 1) & ~(CRYPTO_MINALIGN - 1))
++#define POLYVAL_CTX_SIZE (sizeof(struct polyval_tfm_ctx) + POLYVAL_ALIGN_EXTRA)
+ #define NUM_KEY_POWERS	8
+ 
+ struct polyval_tfm_ctx {
+ 	/*
+ 	 * These powers must be in the order h^8, ..., h^1.
+ 	 */
+-	u8 key_powers[NUM_KEY_POWERS][POLYVAL_BLOCK_SIZE];
++	u8 key_powers[NUM_KEY_POWERS][POLYVAL_BLOCK_SIZE] POLYVAL_ALIGN_ATTR;
+ };
+ 
+ struct polyval_desc_ctx {
+@@ -45,6 +49,11 @@ asmlinkage void clmul_polyval_update(const struct polyval_tfm_ctx *keys,
+ 	const u8 *in, size_t nblocks, u8 *accumulator);
+ asmlinkage void clmul_polyval_mul(u8 *op1, const u8 *op2);
+ 
++static inline struct polyval_tfm_ctx *polyval_tfm_ctx(struct crypto_shash *tfm)
++{
++	return PTR_ALIGN(crypto_shash_ctx(tfm), POLYVAL_ALIGN);
++}
++
+ static void internal_polyval_update(const struct polyval_tfm_ctx *keys,
+ 	const u8 *in, size_t nblocks, u8 *accumulator)
+ {
+@@ -72,7 +81,7 @@ static void internal_polyval_mul(u8 *op1, const u8 *op2)
+ static int polyval_x86_setkey(struct crypto_shash *tfm,
+ 			const u8 *key, unsigned int keylen)
+ {
+-	struct polyval_tfm_ctx *tctx = crypto_shash_ctx(tfm);
++	struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(tfm);
+ 	int i;
+ 
+ 	if (keylen != POLYVAL_BLOCK_SIZE)
+@@ -102,7 +111,7 @@ static int polyval_x86_update(struct shash_desc *desc,
+ 			 const u8 *src, unsigned int srclen)
+ {
+ 	struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+-	const struct polyval_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
++	const struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(desc->tfm);
+ 	u8 *pos;
+ 	unsigned int nblocks;
+ 	unsigned int n;
+@@ -143,7 +152,7 @@ static int polyval_x86_update(struct shash_desc *desc,
+ static int polyval_x86_final(struct shash_desc *desc, u8 *dst)
+ {
+ 	struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+-	const struct polyval_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
++	const struct polyval_tfm_ctx *tctx = polyval_tfm_ctx(desc->tfm);
+ 
+ 	if (dctx->bytes) {
+ 		internal_polyval_mul(dctx->buffer,
+@@ -167,7 +176,7 @@ static struct shash_alg polyval_alg = {
+ 		.cra_driver_name	= "polyval-clmulni",
+ 		.cra_priority		= 200,
+ 		.cra_blocksize		= POLYVAL_BLOCK_SIZE,
+-		.cra_ctxsize		= sizeof(struct polyval_tfm_ctx),
++		.cra_ctxsize		= POLYVAL_CTX_SIZE,
+ 		.cra_module		= THIS_MODULE,
+ 	},
+ };
+diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
+index 47fca6a7a8bcd..c811cb7d632f1 100644
+--- a/arch/x86/events/intel/lbr.c
++++ b/arch/x86/events/intel/lbr.c
+@@ -1869,7 +1869,7 @@ void __init intel_pmu_arch_lbr_init(void)
+ 	return;
+ 
+ clear_arch_lbr:
+-	clear_cpu_cap(&boot_cpu_data, X86_FEATURE_ARCH_LBR);
++	setup_clear_cpu_cap(X86_FEATURE_ARCH_LBR);
+ }
+ 
+ /**
+diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
+index 621f4b6cac4a3..8946f89761cc3 100644
+--- a/arch/x86/kernel/fpu/init.c
++++ b/arch/x86/kernel/fpu/init.c
+@@ -210,13 +210,6 @@ static void __init fpu__init_system_xstate_size_legacy(void)
+ 	fpstate_reset(&current->thread.fpu);
+ }
+ 
+-static void __init fpu__init_init_fpstate(void)
+-{
+-	/* Bring init_fpstate size and features up to date */
+-	init_fpstate.size		= fpu_kernel_cfg.max_size;
+-	init_fpstate.xfeatures		= fpu_kernel_cfg.max_features;
+-}
+-
+ /*
+  * Called on the boot CPU once per system bootup, to set up the initial
+  * FPU state that is later cloned into all processes:
+@@ -236,5 +229,4 @@ void __init fpu__init_system(struct cpuinfo_x86 *c)
+ 	fpu__init_system_xstate_size_legacy();
+ 	fpu__init_system_xstate(fpu_kernel_cfg.max_size);
+ 	fpu__init_task_struct_size();
+-	fpu__init_init_fpstate();
+ }
+diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
+index c8340156bfd2a..59e543b95a3c6 100644
+--- a/arch/x86/kernel/fpu/xstate.c
++++ b/arch/x86/kernel/fpu/xstate.c
+@@ -360,7 +360,7 @@ static void __init setup_init_fpu_buf(void)
+ 
+ 	print_xstate_features();
+ 
+-	xstate_init_xcomp_bv(&init_fpstate.regs.xsave, fpu_kernel_cfg.max_features);
++	xstate_init_xcomp_bv(&init_fpstate.regs.xsave, init_fpstate.xfeatures);
+ 
+ 	/*
+ 	 * Init all the features state with header.xfeatures being 0x0
+@@ -678,20 +678,6 @@ static unsigned int __init get_xsave_size_user(void)
+ 	return ebx;
+ }
+ 
+-/*
+- * Will the runtime-enumerated 'xstate_size' fit in the init
+- * task's statically-allocated buffer?
+- */
+-static bool __init is_supported_xstate_size(unsigned int test_xstate_size)
+-{
+-	if (test_xstate_size <= sizeof(init_fpstate.regs))
+-		return true;
+-
+-	pr_warn("x86/fpu: xstate buffer too small (%zu < %d), disabling xsave\n",
+-			sizeof(init_fpstate.regs), test_xstate_size);
+-	return false;
+-}
+-
+ static int __init init_xstate_size(void)
+ {
+ 	/* Recompute the context size for enabled features: */
+@@ -717,10 +703,6 @@ static int __init init_xstate_size(void)
+ 	kernel_default_size =
+ 		xstate_calculate_size(fpu_kernel_cfg.default_features, compacted);
+ 
+-	/* Ensure we have the space to store all default enabled features. */
+-	if (!is_supported_xstate_size(kernel_default_size))
+-		return -EINVAL;
+-
+ 	if (!paranoid_xstate_size_valid(kernel_size))
+ 		return -EINVAL;
+ 
+@@ -875,6 +857,19 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
+ 	update_regset_xstate_info(fpu_user_cfg.max_size,
+ 				  fpu_user_cfg.max_features);
+ 
++	/*
++	 * init_fpstate excludes dynamic states as they are large but init
++	 * state is zero.
++	 */
++	init_fpstate.size		= fpu_kernel_cfg.default_size;
++	init_fpstate.xfeatures		= fpu_kernel_cfg.default_features;
++
++	if (init_fpstate.size > sizeof(init_fpstate.regs)) {
++		pr_warn("x86/fpu: init_fpstate buffer too small (%zu < %d), disabling XSAVE\n",
++			sizeof(init_fpstate.regs), init_fpstate.size);
++		goto out_disable;
++	}
++
+ 	setup_init_fpu_buf();
+ 
+ 	/*
+@@ -1130,6 +1125,15 @@ void __copy_xstate_to_uabi_buf(struct membuf to, struct fpstate *fpstate,
+ 	 */
+ 	mask = fpstate->user_xfeatures;
+ 
++	/*
++	 * Dynamic features are not present in init_fpstate. When they are
++	 * in an all zeros init state, remove those from 'mask' to zero
++	 * those features in the user buffer instead of retrieving them
++	 * from init_fpstate.
++	 */
++	if (fpu_state_size_dynamic())
++		mask &= (header.xfeatures | xinit->header.xcomp_bv);
++
+ 	for_each_extended_xfeature(i, mask) {
+ 		/*
+ 		 * If there was a feature or alignment gap, zero the space
+diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c
+index 0ea57da929407..c059820dfaeaf 100644
+--- a/arch/x86/kernel/unwind_orc.c
++++ b/arch/x86/kernel/unwind_orc.c
+@@ -713,7 +713,7 @@ void __unwind_start(struct unwind_state *state, struct task_struct *task,
+ 	/* Otherwise, skip ahead to the user-specified starting frame: */
+ 	while (!unwind_done(state) &&
+ 	       (!on_stack(&state->stack_info, first_frame, sizeof(long)) ||
+-			state->sp < (unsigned long)first_frame))
++			state->sp <= (unsigned long)first_frame))
+ 		unwind_next_frame(state);
+ 
+ 	return;
+diff --git a/drivers/acpi/acpi_pcc.c b/drivers/acpi/acpi_pcc.c
+index ee4ce5ba1fb24..3e252be047b85 100644
+--- a/drivers/acpi/acpi_pcc.c
++++ b/drivers/acpi/acpi_pcc.c
+@@ -27,7 +27,7 @@
+  * Arbitrary retries in case the remote processor is slow to respond
+  * to PCC commands
+  */
+-#define PCC_CMD_WAIT_RETRIES_NUM	500
++#define PCC_CMD_WAIT_RETRIES_NUM	500ULL
+ 
+ struct pcc_data {
+ 	struct pcc_mbox_chan *pcc_chan;
+diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
+index 55a10e6d4e2a7..b7bb9df386de9 100644
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -2950,6 +2950,10 @@ static int genpd_iterate_idle_states(struct device_node *dn,
+ 		np = it.node;
+ 		if (!of_match_node(idle_state_match, np))
+ 			continue;
++
++		if (!of_device_is_available(np))
++			continue;
++
+ 		if (states) {
+ 			ret = genpd_parse_state(&states[i], np);
+ 			if (ret) {
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index 46d6100fa3a7f..a04098bc28c15 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -793,13 +793,13 @@ int __init random_init(const char *command_line)
+ #endif
+ 
+ 	for (i = 0, arch_bits = sizeof(entropy) * 8; i < ARRAY_SIZE(entropy);) {
+-		longs = arch_get_random_seed_longs(entropy, ARRAY_SIZE(entropy) - i);
++		longs = arch_get_random_seed_longs_early(entropy, ARRAY_SIZE(entropy) - i);
+ 		if (longs) {
+ 			_mix_pool_bytes(entropy, sizeof(*entropy) * longs);
+ 			i += longs;
+ 			continue;
+ 		}
+-		longs = arch_get_random_longs(entropy, ARRAY_SIZE(entropy) - i);
++		longs = arch_get_random_longs_early(entropy, ARRAY_SIZE(entropy) - i);
+ 		if (longs) {
+ 			_mix_pool_bytes(entropy, sizeof(*entropy) * longs);
+ 			i += longs;
+diff --git a/drivers/counter/104-quad-8.c b/drivers/counter/104-quad-8.c
+index 4407203e0c9b3..239f9a7dc5e76 100644
+--- a/drivers/counter/104-quad-8.c
++++ b/drivers/counter/104-quad-8.c
+@@ -231,34 +231,45 @@ static const enum counter_function quad8_count_functions_list[] = {
+ 	COUNTER_FUNCTION_QUADRATURE_X4,
+ };
+ 
++static int quad8_function_get(const struct quad8 *const priv, const size_t id,
++			      enum counter_function *const function)
++{
++	if (!priv->quadrature_mode[id]) {
++		*function = COUNTER_FUNCTION_PULSE_DIRECTION;
++		return 0;
++	}
++
++	switch (priv->quadrature_scale[id]) {
++	case 0:
++		*function = COUNTER_FUNCTION_QUADRATURE_X1_A;
++		return 0;
++	case 1:
++		*function = COUNTER_FUNCTION_QUADRATURE_X2_A;
++		return 0;
++	case 2:
++		*function = COUNTER_FUNCTION_QUADRATURE_X4;
++		return 0;
++	default:
++		/* should never reach this path */
++		return -EINVAL;
++	}
++}
++
+ static int quad8_function_read(struct counter_device *counter,
+ 			       struct counter_count *count,
+ 			       enum counter_function *function)
+ {
+ 	struct quad8 *const priv = counter_priv(counter);
+-	const int id = count->id;
+ 	unsigned long irqflags;
++	int retval;
+ 
+ 	spin_lock_irqsave(&priv->lock, irqflags);
+ 
+-	if (priv->quadrature_mode[id])
+-		switch (priv->quadrature_scale[id]) {
+-		case 0:
+-			*function = COUNTER_FUNCTION_QUADRATURE_X1_A;
+-			break;
+-		case 1:
+-			*function = COUNTER_FUNCTION_QUADRATURE_X2_A;
+-			break;
+-		case 2:
+-			*function = COUNTER_FUNCTION_QUADRATURE_X4;
+-			break;
+-		}
+-	else
+-		*function = COUNTER_FUNCTION_PULSE_DIRECTION;
++	retval = quad8_function_get(priv, count->id, function);
+ 
+ 	spin_unlock_irqrestore(&priv->lock, irqflags);
+ 
+-	return 0;
++	return retval;
+ }
+ 
+ static int quad8_function_write(struct counter_device *counter,
+@@ -358,6 +369,7 @@ static int quad8_action_read(struct counter_device *counter,
+ 			     enum counter_synapse_action *action)
+ {
+ 	struct quad8 *const priv = counter_priv(counter);
++	unsigned long irqflags;
+ 	int err;
+ 	enum counter_function function;
+ 	const size_t signal_a_id = count->synapses[0].signal->id;
+@@ -373,9 +385,21 @@ static int quad8_action_read(struct counter_device *counter,
+ 		return 0;
+ 	}
+ 
+-	err = quad8_function_read(counter, count, &function);
+-	if (err)
++	spin_lock_irqsave(&priv->lock, irqflags);
++
++	/* Get Count function and direction atomically */
++	err = quad8_function_get(priv, count->id, &function);
++	if (err) {
++		spin_unlock_irqrestore(&priv->lock, irqflags);
++		return err;
++	}
++	err = quad8_direction_read(counter, count, &direction);
++	if (err) {
++		spin_unlock_irqrestore(&priv->lock, irqflags);
+ 		return err;
++	}
++
++	spin_unlock_irqrestore(&priv->lock, irqflags);
+ 
+ 	/* Default action mode */
+ 	*action = COUNTER_SYNAPSE_ACTION_NONE;
+@@ -388,10 +412,6 @@ static int quad8_action_read(struct counter_device *counter,
+ 		return 0;
+ 	case COUNTER_FUNCTION_QUADRATURE_X1_A:
+ 		if (synapse->signal->id == signal_a_id) {
+-			err = quad8_direction_read(counter, count, &direction);
+-			if (err)
+-				return err;
+-
+ 			if (direction == COUNTER_COUNT_DIRECTION_FORWARD)
+ 				*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
+ 			else
+diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
+index 00844445143b6..30c7813c8f438 100644
+--- a/drivers/counter/microchip-tcb-capture.c
++++ b/drivers/counter/microchip-tcb-capture.c
+@@ -28,7 +28,6 @@ struct mchp_tc_data {
+ 	int qdec_mode;
+ 	int num_channels;
+ 	int channel[2];
+-	bool trig_inverted;
+ };
+ 
+ static const enum counter_function mchp_tc_count_functions[] = {
+@@ -153,7 +152,7 @@ static int mchp_tc_count_signal_read(struct counter_device *counter,
+ 
+ 	regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], SR), &sr);
+ 
+-	if (priv->trig_inverted)
++	if (signal->id == 1)
+ 		sigstatus = (sr & ATMEL_TC_MTIOB);
+ 	else
+ 		sigstatus = (sr & ATMEL_TC_MTIOA);
+@@ -171,6 +170,17 @@ static int mchp_tc_count_action_read(struct counter_device *counter,
+ 	struct mchp_tc_data *const priv = counter_priv(counter);
+ 	u32 cmr;
+ 
++	if (priv->qdec_mode) {
++		*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
++		return 0;
++	}
++
++	/* Only TIOA signal is evaluated in non-QDEC mode */
++	if (synapse->signal->id != 0) {
++		*action = COUNTER_SYNAPSE_ACTION_NONE;
++		return 0;
++	}
++
+ 	regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), &cmr);
+ 
+ 	switch (cmr & ATMEL_TC_ETRGEDG) {
+@@ -199,8 +209,8 @@ static int mchp_tc_count_action_write(struct counter_device *counter,
+ 	struct mchp_tc_data *const priv = counter_priv(counter);
+ 	u32 edge = ATMEL_TC_ETRGEDG_NONE;
+ 
+-	/* QDEC mode is rising edge only */
+-	if (priv->qdec_mode)
++	/* QDEC mode is rising edge only; only TIOA handled in non-QDEC mode */
++	if (priv->qdec_mode || synapse->signal->id != 0)
+ 		return -EINVAL;
+ 
+ 	switch (action) {
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index fc3ebeb0bbe59..6ff73c30769fa 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -27,6 +27,7 @@
+ #include <linux/pm_qos.h>
+ #include <trace/events/power.h>
+ 
++#include <asm/cpu.h>
+ #include <asm/div64.h>
+ #include <asm/msr.h>
+ #include <asm/cpu_device_id.h>
+@@ -280,10 +281,10 @@ static struct cpudata **all_cpu_data;
+  * structure is used to store those callbacks.
+  */
+ struct pstate_funcs {
+-	int (*get_max)(void);
+-	int (*get_max_physical)(void);
+-	int (*get_min)(void);
+-	int (*get_turbo)(void);
++	int (*get_max)(int cpu);
++	int (*get_max_physical)(int cpu);
++	int (*get_min)(int cpu);
++	int (*get_turbo)(int cpu);
+ 	int (*get_scaling)(void);
+ 	int (*get_cpu_scaling)(int cpu);
+ 	int (*get_aperf_mperf_shift)(void);
+@@ -398,16 +399,6 @@ static int intel_pstate_get_cppc_guaranteed(int cpu)
+ 
+ 	return cppc_perf.nominal_perf;
+ }
+-
+-static u32 intel_pstate_cppc_nominal(int cpu)
+-{
+-	u64 nominal_perf;
+-
+-	if (cppc_get_nominal_perf(cpu, &nominal_perf))
+-		return 0;
+-
+-	return nominal_perf;
+-}
+ #else /* CONFIG_ACPI_CPPC_LIB */
+ static inline void intel_pstate_set_itmt_prio(int cpu)
+ {
+@@ -531,35 +522,18 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu)
+ {
+ 	int perf_ctl_max_phys = cpu->pstate.max_pstate_physical;
+ 	int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling;
+-	int perf_ctl_turbo = pstate_funcs.get_turbo();
+-	int turbo_freq = perf_ctl_turbo * perf_ctl_scaling;
++	int perf_ctl_turbo = pstate_funcs.get_turbo(cpu->cpu);
+ 	int scaling = cpu->pstate.scaling;
+ 
+ 	pr_debug("CPU%d: perf_ctl_max_phys = %d\n", cpu->cpu, perf_ctl_max_phys);
+-	pr_debug("CPU%d: perf_ctl_max = %d\n", cpu->cpu, pstate_funcs.get_max());
+ 	pr_debug("CPU%d: perf_ctl_turbo = %d\n", cpu->cpu, perf_ctl_turbo);
+ 	pr_debug("CPU%d: perf_ctl_scaling = %d\n", cpu->cpu, perf_ctl_scaling);
+ 	pr_debug("CPU%d: HWP_CAP guaranteed = %d\n", cpu->cpu, cpu->pstate.max_pstate);
+ 	pr_debug("CPU%d: HWP_CAP highest = %d\n", cpu->cpu, cpu->pstate.turbo_pstate);
+ 	pr_debug("CPU%d: HWP-to-frequency scaling factor: %d\n", cpu->cpu, scaling);
+ 
+-	/*
+-	 * If the product of the HWP performance scaling factor and the HWP_CAP
+-	 * highest performance is greater than the maximum turbo frequency
+-	 * corresponding to the pstate_funcs.get_turbo() return value, the
+-	 * scaling factor is too high, so recompute it to make the HWP_CAP
+-	 * highest performance correspond to the maximum turbo frequency.
+-	 */
+-	cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * scaling;
+-	if (turbo_freq < cpu->pstate.turbo_freq) {
+-		cpu->pstate.turbo_freq = turbo_freq;
+-		scaling = DIV_ROUND_UP(turbo_freq, cpu->pstate.turbo_pstate);
+-		cpu->pstate.scaling = scaling;
+-
+-		pr_debug("CPU%d: refined HWP-to-frequency scaling factor: %d\n",
+-			 cpu->cpu, scaling);
+-	}
+-
++	cpu->pstate.turbo_freq = rounddown(cpu->pstate.turbo_pstate * scaling,
++					   perf_ctl_scaling);
+ 	cpu->pstate.max_freq = rounddown(cpu->pstate.max_pstate * scaling,
+ 					 perf_ctl_scaling);
+ 
+@@ -1740,7 +1714,7 @@ static void intel_pstate_hwp_enable(struct cpudata *cpudata)
+ 	intel_pstate_update_epp_defaults(cpudata);
+ }
+ 
+-static int atom_get_min_pstate(void)
++static int atom_get_min_pstate(int not_used)
+ {
+ 	u64 value;
+ 
+@@ -1748,7 +1722,7 @@ static int atom_get_min_pstate(void)
+ 	return (value >> 8) & 0x7F;
+ }
+ 
+-static int atom_get_max_pstate(void)
++static int atom_get_max_pstate(int not_used)
+ {
+ 	u64 value;
+ 
+@@ -1756,7 +1730,7 @@ static int atom_get_max_pstate(void)
+ 	return (value >> 16) & 0x7F;
+ }
+ 
+-static int atom_get_turbo_pstate(void)
++static int atom_get_turbo_pstate(int not_used)
+ {
+ 	u64 value;
+ 
+@@ -1834,23 +1808,23 @@ static void atom_get_vid(struct cpudata *cpudata)
+ 	cpudata->vid.turbo = value & 0x7f;
+ }
+ 
+-static int core_get_min_pstate(void)
++static int core_get_min_pstate(int cpu)
+ {
+ 	u64 value;
+ 
+-	rdmsrl(MSR_PLATFORM_INFO, value);
++	rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value);
+ 	return (value >> 40) & 0xFF;
+ }
+ 
+-static int core_get_max_pstate_physical(void)
++static int core_get_max_pstate_physical(int cpu)
+ {
+ 	u64 value;
+ 
+-	rdmsrl(MSR_PLATFORM_INFO, value);
++	rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &value);
+ 	return (value >> 8) & 0xFF;
+ }
+ 
+-static int core_get_tdp_ratio(u64 plat_info)
++static int core_get_tdp_ratio(int cpu, u64 plat_info)
+ {
+ 	/* Check how many TDP levels present */
+ 	if (plat_info & 0x600000000) {
+@@ -1860,13 +1834,13 @@ static int core_get_tdp_ratio(u64 plat_info)
+ 		int err;
+ 
+ 		/* Get the TDP level (0, 1, 2) to get ratios */
+-		err = rdmsrl_safe(MSR_CONFIG_TDP_CONTROL, &tdp_ctrl);
++		err = rdmsrl_safe_on_cpu(cpu, MSR_CONFIG_TDP_CONTROL, &tdp_ctrl);
+ 		if (err)
+ 			return err;
+ 
+ 		/* TDP MSR are continuous starting at 0x648 */
+ 		tdp_msr = MSR_CONFIG_TDP_NOMINAL + (tdp_ctrl & 0x03);
+-		err = rdmsrl_safe(tdp_msr, &tdp_ratio);
++		err = rdmsrl_safe_on_cpu(cpu, tdp_msr, &tdp_ratio);
+ 		if (err)
+ 			return err;
+ 
+@@ -1883,7 +1857,7 @@ static int core_get_tdp_ratio(u64 plat_info)
+ 	return -ENXIO;
+ }
+ 
+-static int core_get_max_pstate(void)
++static int core_get_max_pstate(int cpu)
+ {
+ 	u64 tar;
+ 	u64 plat_info;
+@@ -1891,10 +1865,10 @@ static int core_get_max_pstate(void)
+ 	int tdp_ratio;
+ 	int err;
+ 
+-	rdmsrl(MSR_PLATFORM_INFO, plat_info);
++	rdmsrl_on_cpu(cpu, MSR_PLATFORM_INFO, &plat_info);
+ 	max_pstate = (plat_info >> 8) & 0xFF;
+ 
+-	tdp_ratio = core_get_tdp_ratio(plat_info);
++	tdp_ratio = core_get_tdp_ratio(cpu, plat_info);
+ 	if (tdp_ratio <= 0)
+ 		return max_pstate;
+ 
+@@ -1903,7 +1877,7 @@ static int core_get_max_pstate(void)
+ 		return tdp_ratio;
+ 	}
+ 
+-	err = rdmsrl_safe(MSR_TURBO_ACTIVATION_RATIO, &tar);
++	err = rdmsrl_safe_on_cpu(cpu, MSR_TURBO_ACTIVATION_RATIO, &tar);
+ 	if (!err) {
+ 		int tar_levels;
+ 
+@@ -1918,13 +1892,13 @@ static int core_get_max_pstate(void)
+ 	return max_pstate;
+ }
+ 
+-static int core_get_turbo_pstate(void)
++static int core_get_turbo_pstate(int cpu)
+ {
+ 	u64 value;
+ 	int nont, ret;
+ 
+-	rdmsrl(MSR_TURBO_RATIO_LIMIT, value);
+-	nont = core_get_max_pstate();
++	rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value);
++	nont = core_get_max_pstate(cpu);
+ 	ret = (value) & 255;
+ 	if (ret <= nont)
+ 		ret = nont;
+@@ -1952,50 +1926,37 @@ static int knl_get_aperf_mperf_shift(void)
+ 	return 10;
+ }
+ 
+-static int knl_get_turbo_pstate(void)
++static int knl_get_turbo_pstate(int cpu)
+ {
+ 	u64 value;
+ 	int nont, ret;
+ 
+-	rdmsrl(MSR_TURBO_RATIO_LIMIT, value);
+-	nont = core_get_max_pstate();
++	rdmsrl_on_cpu(cpu, MSR_TURBO_RATIO_LIMIT, &value);
++	nont = core_get_max_pstate(cpu);
+ 	ret = (((value) >> 8) & 0xFF);
+ 	if (ret <= nont)
+ 		ret = nont;
+ 	return ret;
+ }
+ 
+-#ifdef CONFIG_ACPI_CPPC_LIB
+-static u32 hybrid_ref_perf;
+-
+-static int hybrid_get_cpu_scaling(int cpu)
++static void hybrid_get_type(void *data)
+ {
+-	return DIV_ROUND_UP(core_get_scaling() * hybrid_ref_perf,
+-			    intel_pstate_cppc_nominal(cpu));
++	u8 *cpu_type = data;
++
++	*cpu_type = get_this_hybrid_cpu_type();
+ }
+ 
+-static void intel_pstate_cppc_set_cpu_scaling(void)
++static int hybrid_get_cpu_scaling(int cpu)
+ {
+-	u32 min_nominal_perf = U32_MAX;
+-	int cpu;
++	u8 cpu_type = 0;
+ 
+-	for_each_present_cpu(cpu) {
+-		u32 nominal_perf = intel_pstate_cppc_nominal(cpu);
++	smp_call_function_single(cpu, hybrid_get_type, &cpu_type, 1);
++	/* P-cores have a smaller perf level-to-freqency scaling factor. */
++	if (cpu_type == 0x40)
++		return 78741;
+ 
+-		if (nominal_perf && nominal_perf < min_nominal_perf)
+-			min_nominal_perf = nominal_perf;
+-	}
+-
+-	if (min_nominal_perf < U32_MAX) {
+-		hybrid_ref_perf = min_nominal_perf;
+-		pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling;
+-	}
++	return core_get_scaling();
+ }
+-#else
+-static inline void intel_pstate_cppc_set_cpu_scaling(void)
+-{
+-}
+-#endif /* CONFIG_ACPI_CPPC_LIB */
+ 
+ static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
+ {
+@@ -2025,10 +1986,10 @@ static void intel_pstate_max_within_limits(struct cpudata *cpu)
+ 
+ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
+ {
+-	int perf_ctl_max_phys = pstate_funcs.get_max_physical();
++	int perf_ctl_max_phys = pstate_funcs.get_max_physical(cpu->cpu);
+ 	int perf_ctl_scaling = pstate_funcs.get_scaling();
+ 
+-	cpu->pstate.min_pstate = pstate_funcs.get_min();
++	cpu->pstate.min_pstate = pstate_funcs.get_min(cpu->cpu);
+ 	cpu->pstate.max_pstate_physical = perf_ctl_max_phys;
+ 	cpu->pstate.perf_ctl_scaling = perf_ctl_scaling;
+ 
+@@ -2044,8 +2005,8 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
+ 		}
+ 	} else {
+ 		cpu->pstate.scaling = perf_ctl_scaling;
+-		cpu->pstate.max_pstate = pstate_funcs.get_max();
+-		cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
++		cpu->pstate.max_pstate = pstate_funcs.get_max(cpu->cpu);
++		cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(cpu->cpu);
+ 	}
+ 
+ 	if (cpu->pstate.scaling == perf_ctl_scaling) {
+@@ -3221,9 +3182,9 @@ static unsigned int force_load __initdata;
+ 
+ static int __init intel_pstate_msrs_not_valid(void)
+ {
+-	if (!pstate_funcs.get_max() ||
+-	    !pstate_funcs.get_min() ||
+-	    !pstate_funcs.get_turbo())
++	if (!pstate_funcs.get_max(0) ||
++	    !pstate_funcs.get_min(0) ||
++	    !pstate_funcs.get_turbo(0))
+ 		return -ENODEV;
+ 
+ 	return 0;
+@@ -3450,7 +3411,7 @@ static int __init intel_pstate_init(void)
+ 				default_driver = &intel_pstate;
+ 
+ 			if (boot_cpu_has(X86_FEATURE_HYBRID_CPU))
+-				intel_pstate_cppc_set_cpu_scaling();
++				pstate_funcs.get_cpu_scaling = hybrid_get_cpu_scaling;
+ 
+ 			goto hwp_cpu_matched;
+ 		}
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+index 2170db83e41d9..93ad00453f4b3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+@@ -509,13 +509,13 @@ kfd_mem_dmamap_userptr(struct kgd_mem *mem,
+ 	struct ttm_tt *ttm = bo->tbo.ttm;
+ 	int ret;
+ 
++	if (WARN_ON(ttm->num_pages != src_ttm->num_pages))
++		return -EINVAL;
++
+ 	ttm->sg = kmalloc(sizeof(*ttm->sg), GFP_KERNEL);
+ 	if (unlikely(!ttm->sg))
+ 		return -ENOMEM;
+ 
+-	if (WARN_ON(ttm->num_pages != src_ttm->num_pages))
+-		return -EINVAL;
+-
+ 	/* Same sequence as in amdgpu_ttm_tt_pin_userptr */
+ 	ret = sg_alloc_table_from_pages(ttm->sg, src_ttm->pages,
+ 					ttm->num_pages, 0,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+index 8ee4e8491f391..4048ba1b661e3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+@@ -327,7 +327,10 @@ static int amdgpu_ctx_init(struct amdgpu_ctx_mgr *mgr, int32_t priority,
+ 	if (r)
+ 		return r;
+ 
+-	ctx->stable_pstate = current_stable_pstate;
++	if (mgr->adev->pm.stable_pstate_ctx)
++		ctx->stable_pstate = mgr->adev->pm.stable_pstate_ctx->stable_pstate;
++	else
++		ctx->stable_pstate = current_stable_pstate;
+ 
+ 	return 0;
+ }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 91665fe44e7ca..9170aeaad93e7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -3208,6 +3208,15 @@ static int amdgpu_device_ip_resume_phase2(struct amdgpu_device *adev)
+ 			return r;
+ 		}
+ 		adev->ip_blocks[i].status.hw = true;
++
++		if (adev->in_s0ix && adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_SMC) {
++			/* disable gfxoff for IP resume. The gfxoff will be re-enabled in
++			 * amdgpu_device_resume() after IP resume.
++			 */
++			amdgpu_gfx_off_ctrl(adev, false);
++			DRM_DEBUG("will disable gfxoff for re-initializing other blocks\n");
++		}
++
+ 	}
+ 
+ 	return 0;
+@@ -4180,6 +4189,13 @@ int amdgpu_device_resume(struct drm_device *dev, bool fbcon)
+ 	/* Make sure IB tests flushed */
+ 	flush_delayed_work(&adev->delayed_init_work);
+ 
++	if (adev->in_s0ix) {
++		/* re-enable gfxoff after IP resume. This re-enables gfxoff after
++		 * it was disabled for IP resume in amdgpu_device_ip_resume_phase2().
++		 */
++		amdgpu_gfx_off_ctrl(adev, true);
++		DRM_DEBUG("will enable gfxoff for the mission mode\n");
++	}
+ 	if (fbcon)
+ 		drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, false);
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+index 134575a3893c5..9e6c23266a1a0 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -424,8 +424,9 @@ error:
+ static bool amdgpu_mem_visible(struct amdgpu_device *adev,
+ 			       struct ttm_resource *mem)
+ {
+-	uint64_t mem_size = (u64)mem->num_pages << PAGE_SHIFT;
++	u64 mem_size = (u64)mem->num_pages << PAGE_SHIFT;
+ 	struct amdgpu_res_cursor cursor;
++	u64 end;
+ 
+ 	if (mem->mem_type == TTM_PL_SYSTEM ||
+ 	    mem->mem_type == TTM_PL_TT)
+@@ -434,12 +435,21 @@ static bool amdgpu_mem_visible(struct amdgpu_device *adev,
+ 		return false;
+ 
+ 	amdgpu_res_first(mem, 0, mem_size, &cursor);
++	end = cursor.start + cursor.size;
++	while (cursor.remaining) {
++		amdgpu_res_next(&cursor, cursor.size);
+ 
+-	/* ttm_resource_ioremap only supports contiguous memory */
+-	if (cursor.size != mem_size)
+-		return false;
++		if (!cursor.remaining)
++			break;
++
++		/* ttm_resource_ioremap only supports contiguous memory */
++		if (end != cursor.start)
++			return false;
++
++		end = cursor.start + cursor.size;
++	}
+ 
+-	return cursor.start + cursor.size <= adev->gmc.visible_vram_size;
++	return end <= adev->gmc.visible_vram_size;
+ }
+ 
+ /*
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
+index 4d304f22889e4..998b5d17b271b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
+@@ -32,8 +32,6 @@
+ #include "gc/gc_10_1_0_offset.h"
+ #include "soc15_common.h"
+ 
+-#define mmMM_ATC_L2_MISC_CG_Sienna_Cichlid                      0x064d
+-#define mmMM_ATC_L2_MISC_CG_Sienna_Cichlid_BASE_IDX             0
+ #define mmDAGB0_CNTL_MISC2_Sienna_Cichlid                       0x0070
+ #define mmDAGB0_CNTL_MISC2_Sienna_Cichlid_BASE_IDX              0
+ 
+@@ -574,7 +572,6 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
+ 	case IP_VERSION(2, 1, 0):
+ 	case IP_VERSION(2, 1, 1):
+ 	case IP_VERSION(2, 1, 2):
+-		def  = data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
+ 		def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid);
+ 		break;
+ 	default:
+@@ -608,8 +605,6 @@ static void mmhub_v2_0_update_medium_grain_clock_gating(struct amdgpu_device *ad
+ 	case IP_VERSION(2, 1, 0):
+ 	case IP_VERSION(2, 1, 1):
+ 	case IP_VERSION(2, 1, 2):
+-		if (def != data)
+-			WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data);
+ 		if (def1 != data1)
+ 			WREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid, data1);
+ 		break;
+@@ -634,8 +629,8 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
+ 	case IP_VERSION(2, 1, 0):
+ 	case IP_VERSION(2, 1, 1):
+ 	case IP_VERSION(2, 1, 2):
+-		def  = data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
+-		break;
++		/* There is no ATCL2 in MMHUB for 2.1.x */
++		return;
+ 	default:
+ 		def  = data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
+ 		break;
+@@ -646,18 +641,8 @@ static void mmhub_v2_0_update_medium_grain_light_sleep(struct amdgpu_device *ade
+ 	else
+ 		data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
+ 
+-	if (def != data) {
+-		switch (adev->ip_versions[MMHUB_HWIP][0]) {
+-		case IP_VERSION(2, 1, 0):
+-		case IP_VERSION(2, 1, 1):
+-		case IP_VERSION(2, 1, 2):
+-			WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid, data);
+-			break;
+-		default:
+-			WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
+-			break;
+-		}
+-	}
++	if (def != data)
++		WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
+ }
+ 
+ static int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev,
+@@ -695,7 +680,10 @@ static void mmhub_v2_0_get_clockgating(struct amdgpu_device *adev, u64 *flags)
+ 	case IP_VERSION(2, 1, 0):
+ 	case IP_VERSION(2, 1, 1):
+ 	case IP_VERSION(2, 1, 2):
+-		data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG_Sienna_Cichlid);
++		/* There is no ATCL2 in MMHUB for 2.1.x. Keep the status
++		 * based on DAGB
++		 */
++		data = MM_ATC_L2_MISC_CG__ENABLE_MASK;
+ 		data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2_Sienna_Cichlid);
+ 		break;
+ 	default:
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+index a5409531a2fdf..64f2412812624 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c
+@@ -795,6 +795,102 @@ static struct kfd_gpu_cache_info yellow_carp_cache_info[] = {
+ 	},
+ };
+ 
++static struct kfd_gpu_cache_info gfx1037_cache_info[] = {
++	{
++		/* TCP L1 Cache per CU */
++		.cache_size = 16,
++		.cache_level = 1,
++		.flags = (CRAT_CACHE_FLAGS_ENABLED |
++				CRAT_CACHE_FLAGS_DATA_CACHE |
++				CRAT_CACHE_FLAGS_SIMD_CACHE),
++		.num_cu_shared = 1,
++	},
++	{
++		/* Scalar L1 Instruction Cache per SQC */
++		.cache_size = 32,
++		.cache_level = 1,
++		.flags = (CRAT_CACHE_FLAGS_ENABLED |
++				CRAT_CACHE_FLAGS_INST_CACHE |
++				CRAT_CACHE_FLAGS_SIMD_CACHE),
++		.num_cu_shared = 2,
++	},
++	{
++		/* Scalar L1 Data Cache per SQC */
++		.cache_size = 16,
++		.cache_level = 1,
++		.flags = (CRAT_CACHE_FLAGS_ENABLED |
++				CRAT_CACHE_FLAGS_DATA_CACHE |
++				CRAT_CACHE_FLAGS_SIMD_CACHE),
++		.num_cu_shared = 2,
++	},
++	{
++		/* GL1 Data Cache per SA */
++		.cache_size = 128,
++		.cache_level = 1,
++		.flags = (CRAT_CACHE_FLAGS_ENABLED |
++				CRAT_CACHE_FLAGS_DATA_CACHE |
++				CRAT_CACHE_FLAGS_SIMD_CACHE),
++		.num_cu_shared = 2,
++	},
++	{
++		/* L2 Data Cache per GPU (Total Tex Cache) */
++		.cache_size = 256,
++		.cache_level = 2,
++		.flags = (CRAT_CACHE_FLAGS_ENABLED |
++				CRAT_CACHE_FLAGS_DATA_CACHE |
++				CRAT_CACHE_FLAGS_SIMD_CACHE),
++		.num_cu_shared = 2,
++	},
++};
++
++static struct kfd_gpu_cache_info gc_10_3_6_cache_info[] = {
++	{
++		/* TCP L1 Cache per CU */
++		.cache_size = 16,
++		.cache_level = 1,
++		.flags = (CRAT_CACHE_FLAGS_ENABLED |
++			  CRAT_CACHE_FLAGS_DATA_CACHE |
++			  CRAT_CACHE_FLAGS_SIMD_CACHE),
++		.num_cu_shared = 1,
++	},
++	{
++		/* Scalar L1 Instruction Cache per SQC */
++		.cache_size = 32,
++		.cache_level = 1,
++		.flags = (CRAT_CACHE_FLAGS_ENABLED |
++			  CRAT_CACHE_FLAGS_INST_CACHE |
++			  CRAT_CACHE_FLAGS_SIMD_CACHE),
++		.num_cu_shared = 2,
++	},
++	{
++		/* Scalar L1 Data Cache per SQC */
++		.cache_size = 16,
++		.cache_level = 1,
++		.flags = (CRAT_CACHE_FLAGS_ENABLED |
++			  CRAT_CACHE_FLAGS_DATA_CACHE |
++			  CRAT_CACHE_FLAGS_SIMD_CACHE),
++		.num_cu_shared = 2,
++	},
++	{
++		/* GL1 Data Cache per SA */
++		.cache_size = 128,
++		.cache_level = 1,
++		.flags = (CRAT_CACHE_FLAGS_ENABLED |
++			  CRAT_CACHE_FLAGS_DATA_CACHE |
++			  CRAT_CACHE_FLAGS_SIMD_CACHE),
++		.num_cu_shared = 2,
++	},
++	{
++		/* L2 Data Cache per GPU (Total Tex Cache) */
++		.cache_size = 256,
++		.cache_level = 2,
++		.flags = (CRAT_CACHE_FLAGS_ENABLED |
++			  CRAT_CACHE_FLAGS_DATA_CACHE |
++			  CRAT_CACHE_FLAGS_SIMD_CACHE),
++		.num_cu_shared = 2,
++	},
++};
++
+ static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev,
+ 		struct crat_subtype_computeunit *cu)
+ {
+@@ -1514,11 +1610,17 @@ static int kfd_fill_gpu_cache_info(struct kfd_dev *kdev,
+ 			num_of_cache_types = ARRAY_SIZE(beige_goby_cache_info);
+ 			break;
+ 		case IP_VERSION(10, 3, 3):
+-		case IP_VERSION(10, 3, 6): /* TODO: Double check these on production silicon */
+-		case IP_VERSION(10, 3, 7): /* TODO: Double check these on production silicon */
+ 			pcache_info = yellow_carp_cache_info;
+ 			num_of_cache_types = ARRAY_SIZE(yellow_carp_cache_info);
+ 			break;
++		case IP_VERSION(10, 3, 6):
++			pcache_info = gc_10_3_6_cache_info;
++			num_of_cache_types = ARRAY_SIZE(gc_10_3_6_cache_info);
++			break;
++		case IP_VERSION(10, 3, 7):
++			pcache_info = gfx1037_cache_info;
++			num_of_cache_types = ARRAY_SIZE(gfx1037_cache_info);
++			break;
+ 		case IP_VERSION(11, 0, 0):
+ 		case IP_VERSION(11, 0, 1):
+ 		case IP_VERSION(11, 0, 2):
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+index 987bde4dca3db..af239b5565ae9 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+@@ -1369,7 +1369,7 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
+ {
+ 	struct amdgpu_device *adev = drm_to_adev(plane->dev);
+ 	const struct drm_format_info *info = drm_format_info(format);
+-	struct hw_asic_id asic_id = adev->dm.dc->ctx->asic_id;
++	int i;
+ 
+ 	enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3;
+ 
+@@ -1386,49 +1386,13 @@ static bool dm_plane_format_mod_supported(struct drm_plane *plane,
+ 		return true;
+ 	}
+ 
+-	/* check if swizzle mode is supported by this version of DCN */
+-	switch (asic_id.chip_family) {
+-	case FAMILY_SI:
+-	case FAMILY_CI:
+-	case FAMILY_KV:
+-	case FAMILY_CZ:
+-	case FAMILY_VI:
+-		/* asics before AI does not have modifier support */
+-		return false;
+-	case FAMILY_AI:
+-	case FAMILY_RV:
+-	case FAMILY_NV:
+-	case FAMILY_VGH:
+-	case FAMILY_YELLOW_CARP:
+-	case AMDGPU_FAMILY_GC_10_3_6:
+-	case AMDGPU_FAMILY_GC_10_3_7:
+-		switch (AMD_FMT_MOD_GET(TILE, modifier)) {
+-		case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
+-		case AMD_FMT_MOD_TILE_GFX9_64K_D_X:
+-		case AMD_FMT_MOD_TILE_GFX9_64K_S_X:
+-		case AMD_FMT_MOD_TILE_GFX9_64K_D:
+-			return true;
+-		default:
+-			return false;
+-		}
+-		break;
+-	case AMDGPU_FAMILY_GC_11_0_0:
+-	case AMDGPU_FAMILY_GC_11_0_1:
+-		switch (AMD_FMT_MOD_GET(TILE, modifier)) {
+-		case AMD_FMT_MOD_TILE_GFX11_256K_R_X:
+-		case AMD_FMT_MOD_TILE_GFX9_64K_R_X:
+-		case AMD_FMT_MOD_TILE_GFX9_64K_D_X:
+-		case AMD_FMT_MOD_TILE_GFX9_64K_S_X:
+-		case AMD_FMT_MOD_TILE_GFX9_64K_D:
+-			return true;
+-		default:
+-			return false;
+-		}
+-		break;
+-	default:
+-		ASSERT(0); /* Unknown asic */
+-		break;
++	/* Check that the modifier is on the list of the plane's supported modifiers. */
++	for (i = 0; i < plane->modifier_count; i++) {
++		if (modifier == plane->modifiers[i])
++			break;
+ 	}
++	if (i == plane->modifier_count)
++		return false;
+ 
+ 	/*
+ 	 * For D swizzle the canonical modifier depends on the bpp, so check
+diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c
+index 49107a6cdac18..0dacbdb49a306 100644
+--- a/drivers/gpu/drm/bridge/parade-ps8640.c
++++ b/drivers/gpu/drm/bridge/parade-ps8640.c
+@@ -105,6 +105,7 @@ struct ps8640 {
+ 	struct gpio_desc *gpio_powerdown;
+ 	struct device_link *link;
+ 	bool pre_enabled;
++	bool need_post_hpd_delay;
+ };
+ 
+ static const struct regmap_config ps8640_regmap_config[] = {
+@@ -173,14 +174,31 @@ static int _ps8640_wait_hpd_asserted(struct ps8640 *ps_bridge, unsigned long wai
+ {
+ 	struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
+ 	int status;
++	int ret;
+ 
+ 	/*
+ 	 * Apparently something about the firmware in the chip signals that
+ 	 * HPD goes high by reporting GPIO9 as high (even though HPD isn't
+ 	 * actually connected to GPIO9).
+ 	 */
+-	return regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
+-					status & PS_GPIO9, wait_us / 10, wait_us);
++	ret = regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
++				       status & PS_GPIO9, wait_us / 10, wait_us);
++
++	/*
++	 * The first time we see HPD go high after a reset we delay an extra
++	 * 50 ms. The best guess is that the MCU is doing "stuff" during this
++	 * time (maybe talking to the panel) and we don't want to interrupt it.
++	 *
++	 * No locking is done around "need_post_hpd_delay". If we're here we
++	 * know we're holding a PM Runtime reference and the only other place
++	 * that touches this is PM Runtime resume.
++	 */
++	if (!ret && ps_bridge->need_post_hpd_delay) {
++		ps_bridge->need_post_hpd_delay = false;
++		msleep(50);
++	}
++
++	return ret;
+ }
+ 
+ static int ps8640_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long wait_us)
+@@ -376,6 +394,9 @@ static int __maybe_unused ps8640_resume(struct device *dev)
+ 	usleep_range(2000, 2500);
+ 	gpiod_set_value(ps_bridge->gpio_reset, 0);
+ 
++	/* We just reset things, so we need a delay after the first HPD */
++	ps_bridge->need_post_hpd_delay = true;
++
+ 	/*
+ 	 * Mystery 200 ms delay for the "MCU to be ready". It's unclear if
+ 	 * this is truly necessary since the MCU will already signal that
+diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
+index 3ed7eeacc706b..d4492b6d23d25 100644
+--- a/drivers/gpu/drm/i915/display/intel_dp.c
++++ b/drivers/gpu/drm/i915/display/intel_dp.c
+@@ -3923,6 +3923,8 @@ intel_dp_handle_hdmi_link_status_change(struct intel_dp *intel_dp)
+ 
+ 		drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, &intel_dp->attached_connector->base);
+ 
++		intel_dp->frl.is_trained = false;
++
+ 		/* Restart FRL training or fall back to TMDS mode */
+ 		intel_dp_check_frl_training(intel_dp);
+ 	}
+diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c
+index e8111fce56d03..dfa9a7c4ebc61 100644
+--- a/drivers/gpu/drm/i915/gt/intel_workarounds.c
++++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c
+@@ -2301,11 +2301,11 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
+ 	}
+ 
+ 	if (IS_DG1_GRAPHICS_STEP(i915, STEP_A0, STEP_B0) ||
+-	    IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
++	    IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915) || IS_ALDERLAKE_P(i915)) {
+ 		/*
+ 		 * Wa_1607030317:tgl
+ 		 * Wa_1607186500:tgl
+-		 * Wa_1607297627:tgl,rkl,dg1[a0]
++		 * Wa_1607297627:tgl,rkl,dg1[a0],adlp
+ 		 *
+ 		 * On TGL and RKL there are multiple entries for this WA in the
+ 		 * BSpec; some indicate this is an A0-only WA, others indicate
+diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
+index 6ed5786bcd299..744cca507946b 100644
+--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
++++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
+@@ -591,8 +591,15 @@ void intel_runtime_pm_enable(struct intel_runtime_pm *rpm)
+ 		pm_runtime_use_autosuspend(kdev);
+ 	}
+ 
+-	/* Enable by default */
+-	pm_runtime_allow(kdev);
++	/*
++	 *  FIXME: Temp hammer to keep autosupend disable on lmem supported platforms.
++	 *  As per PCIe specs 5.3.1.4.1, all iomem read write request over a PCIe
++	 *  function will be unsupported in case PCIe endpoint function is in D3.
++	 *  Let's keep i915 autosuspend control 'on' till we fix all known issue
++	 *  with lmem access in D3.
++	 */
++	if (!IS_DGFX(i915))
++		pm_runtime_allow(kdev);
+ 
+ 	/*
+ 	 * The core calls the driver load handler with an RPM reference held.
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
+index 55f443328d8e7..730355f9e2d48 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c
+@@ -91,7 +91,7 @@ struct a6xx_state_memobj {
+ static void *state_kcalloc(struct a6xx_gpu_state *a6xx_state, int nr, size_t objsize)
+ {
+ 	struct a6xx_state_memobj *obj =
+-		kzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL);
++		kvzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL);
+ 
+ 	if (!obj)
+ 		return NULL;
+@@ -1040,8 +1040,11 @@ static void a6xx_gpu_state_destroy(struct kref *kref)
+ 	if (a6xx_state->gmu_hfi)
+ 		kvfree(a6xx_state->gmu_hfi->data);
+ 
++	if (a6xx_state->gmu_debug)
++		kvfree(a6xx_state->gmu_debug->data);
++
+ 	list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node)
+-		kfree(obj);
++		kvfree(obj);
+ 
+ 	adreno_gpu_state_destroy(state);
+ 	kfree(a6xx_state);
+diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+index 382fb7f9e4976..5a0e8491cd3a0 100644
+--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+@@ -729,7 +729,12 @@ static char *adreno_gpu_ascii85_encode(u32 *src, size_t len)
+ 	return buf;
+ }
+ 
+-/* len is expected to be in bytes */
++/* len is expected to be in bytes
++ *
++ * WARNING: *ptr should be allocated with kvmalloc or friends.  It can be free'd
++ * with kvfree() and replaced with a newly kvmalloc'd buffer on the first call
++ * when the unencoded raw data is encoded
++ */
+ void adreno_show_object(struct drm_printer *p, void **ptr, int len,
+ 		bool *encoded)
+ {
+diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c
+index 7288041dd86ad..7444b75c42157 100644
+--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c
++++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c
+@@ -56,8 +56,9 @@ static int mdp4_lvds_connector_get_modes(struct drm_connector *connector)
+ 	return ret;
+ }
+ 
+-static int mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
+-				 struct drm_display_mode *mode)
++static enum drm_mode_status
++mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
++			       struct drm_display_mode *mode)
+ {
+ 	struct mdp4_lvds_connector *mdp4_lvds_connector =
+ 			to_mdp4_lvds_connector(connector);
+diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
+index 013ca02e17cbf..3ac139a4bbe8a 100644
+--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
++++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
+@@ -1245,8 +1245,7 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
+ {
+ 	int ret = 0;
+ 	const u8 *dpcd = ctrl->panel->dpcd;
+-	u8 encoding = DP_SET_ANSI_8B10B;
+-	u8 ssc;
++	u8 encoding[] = { 0, DP_SET_ANSI_8B10B };
+ 	u8 assr;
+ 	struct dp_link_info link_info = {0};
+ 
+@@ -1258,13 +1257,11 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
+ 
+ 	dp_aux_link_configure(ctrl->aux, &link_info);
+ 
+-	if (drm_dp_max_downspread(dpcd)) {
+-		ssc = DP_SPREAD_AMP_0_5;
+-		drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, &ssc, 1);
+-	}
++	if (drm_dp_max_downspread(dpcd))
++		encoding[0] |= DP_SPREAD_AMP_0_5;
+ 
+-	drm_dp_dpcd_write(ctrl->aux, DP_MAIN_LINK_CHANNEL_CODING_SET,
+-				&encoding, 1);
++	/* config DOWNSPREAD_CTRL and MAIN_LINK_CHANNEL_CODING_SET */
++	drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, encoding, 2);
+ 
+ 	if (drm_dp_alternate_scrambler_reset_cap(dpcd)) {
+ 		assr = DP_ALTERNATE_SCRAMBLER_RESET_ENABLE;
+diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
+index bfd0aeff3f0d0..a49f6dbbe8883 100644
+--- a/drivers/gpu/drm/msm/dp/dp_display.c
++++ b/drivers/gpu/drm/msm/dp/dp_display.c
+@@ -1249,7 +1249,7 @@ int dp_display_request_irq(struct msm_dp *dp_display)
+ 		return -EINVAL;
+ 	}
+ 
+-	rc = devm_request_irq(&dp->pdev->dev, dp->irq,
++	rc = devm_request_irq(dp_display->drm_dev->dev, dp->irq,
+ 			dp_display_irq_handler,
+ 			IRQF_TRIGGER_HIGH, "dp_display_isr", dp);
+ 	if (rc < 0) {
+@@ -1528,6 +1528,11 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
+ 	}
+ }
+ 
++static void of_dp_aux_depopulate_bus_void(void *data)
++{
++	of_dp_aux_depopulate_bus(data);
++}
++
+ static int dp_display_get_next_bridge(struct msm_dp *dp)
+ {
+ 	int rc;
+@@ -1552,10 +1557,16 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
+ 		 * panel driver is probed asynchronously but is the best we
+ 		 * can do without a bigger driver reorganization.
+ 		 */
+-		rc = devm_of_dp_aux_populate_ep_devices(dp_priv->aux);
++		rc = of_dp_aux_populate_bus(dp_priv->aux, NULL);
+ 		of_node_put(aux_bus);
+ 		if (rc)
+ 			goto error;
++
++		rc = devm_add_action_or_reset(dp->drm_dev->dev,
++						of_dp_aux_depopulate_bus_void,
++						dp_priv->aux);
++		if (rc)
++			goto error;
+ 	} else if (dp->is_edp) {
+ 		DRM_ERROR("eDP aux_bus not found\n");
+ 		return -ENODEV;
+@@ -1568,7 +1579,7 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
+ 	 * For DisplayPort interfaces external bridges are optional, so
+ 	 * silently ignore an error if one is not present (-ENODEV).
+ 	 */
+-	rc = dp_parser_find_next_bridge(dp_priv->parser);
++	rc = devm_dp_parser_find_next_bridge(dp->drm_dev->dev, dp_priv->parser);
+ 	if (!dp->is_edp && rc == -ENODEV)
+ 		return 0;
+ 
+@@ -1597,6 +1608,12 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
+ 		return -EINVAL;
+ 
+ 	priv = dev->dev_private;
++
++	if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
++		DRM_DEV_ERROR(dev->dev, "too many bridges\n");
++		return -ENOSPC;
++	}
++
+ 	dp_display->drm_dev = dev;
+ 
+ 	dp_priv = container_of(dp_display, struct dp_display_private, dp_display);
+diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
+index 6df25f7662e79..6db82f9b03afb 100644
+--- a/drivers/gpu/drm/msm/dp/dp_drm.c
++++ b/drivers/gpu/drm/msm/dp/dp_drm.c
+@@ -31,6 +31,36 @@ static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
+ 					connector_status_disconnected;
+ }
+ 
++static int dp_bridge_atomic_check(struct drm_bridge *bridge,
++			    struct drm_bridge_state *bridge_state,
++			    struct drm_crtc_state *crtc_state,
++			    struct drm_connector_state *conn_state)
++{
++	struct msm_dp *dp;
++
++	dp = to_dp_bridge(bridge)->dp_display;
++
++	drm_dbg_dp(dp->drm_dev, "is_connected = %s\n",
++		(dp->is_connected) ? "true" : "false");
++
++	/*
++	 * There is no protection in the DRM framework to check if the display
++	 * pipeline has been already disabled before trying to disable it again.
++	 * Hence if the sink is unplugged, the pipeline gets disabled, but the
++	 * crtc->active is still true. Any attempt to set the mode or manually
++	 * disable this encoder will result in the crash.
++	 *
++	 * TODO: add support for telling the DRM subsystem that the pipeline is
++	 * disabled by the hardware and thus all access to it should be forbidden.
++	 * After that this piece of code can be removed.
++	 */
++	if (bridge->ops & DRM_BRIDGE_OP_HPD)
++		return (dp->is_connected) ? 0 : -ENOTCONN;
++
++	return 0;
++}
++
++
+ /**
+  * dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
+  * @bridge: Poiner to drm bridge
+@@ -61,6 +91,9 @@ static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *
+ }
+ 
+ static const struct drm_bridge_funcs dp_bridge_ops = {
++	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
++	.atomic_destroy_state   = drm_atomic_helper_bridge_destroy_state,
++	.atomic_reset           = drm_atomic_helper_bridge_reset,
+ 	.enable       = dp_bridge_enable,
+ 	.disable      = dp_bridge_disable,
+ 	.post_disable = dp_bridge_post_disable,
+@@ -68,6 +101,7 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
+ 	.mode_valid   = dp_bridge_mode_valid,
+ 	.get_modes    = dp_bridge_get_modes,
+ 	.detect       = dp_bridge_detect,
++	.atomic_check = dp_bridge_atomic_check,
+ };
+ 
+ struct drm_bridge *dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
+diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
+index dd732215d55b4..dcbe893d66d7b 100644
+--- a/drivers/gpu/drm/msm/dp/dp_parser.c
++++ b/drivers/gpu/drm/msm/dp/dp_parser.c
+@@ -240,12 +240,12 @@ static int dp_parser_clock(struct dp_parser *parser)
+ 	return 0;
+ }
+ 
+-int dp_parser_find_next_bridge(struct dp_parser *parser)
++int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser)
+ {
+-	struct device *dev = &parser->pdev->dev;
++	struct platform_device *pdev = parser->pdev;
+ 	struct drm_bridge *bridge;
+ 
+-	bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
++	bridge = devm_drm_of_get_bridge(dev, pdev->dev.of_node, 1, 0);
+ 	if (IS_ERR(bridge))
+ 		return PTR_ERR(bridge);
+ 
+diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
+index 866c1a82bf1af..d30ab773db46d 100644
+--- a/drivers/gpu/drm/msm/dp/dp_parser.h
++++ b/drivers/gpu/drm/msm/dp/dp_parser.h
+@@ -138,8 +138,9 @@ struct dp_parser {
+ struct dp_parser *dp_parser_get(struct platform_device *pdev);
+ 
+ /**
+- * dp_parser_find_next_bridge() - find an additional bridge to DP
++ * devm_dp_parser_find_next_bridge() - find an additional bridge to DP
+  *
++ * @dev: device to tie bridge lifetime to
+  * @parser: dp_parser data from client
+  *
+  * This function is used to find any additional bridge attached to
+@@ -147,6 +148,6 @@ struct dp_parser *dp_parser_get(struct platform_device *pdev);
+  *
+  * Return: 0 if able to get the bridge, otherwise negative errno for failure.
+  */
+-int dp_parser_find_next_bridge(struct dp_parser *parser);
++int devm_dp_parser_find_next_bridge(struct device *dev, struct dp_parser *parser);
+ 
+ #endif
+diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
+index 1625328fa4302..3db85b5c0febd 100644
+--- a/drivers/gpu/drm/msm/dsi/dsi.c
++++ b/drivers/gpu/drm/msm/dsi/dsi.c
+@@ -227,6 +227,12 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
+ 		return -EINVAL;
+ 
+ 	priv = dev->dev_private;
++
++	if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
++		DRM_DEV_ERROR(dev->dev, "too many bridges\n");
++		return -ENOSPC;
++	}
++
+ 	msm_dsi->dev = dev;
+ 
+ 	ret = msm_dsi_host_modeset_init(msm_dsi->host, dev);
+diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
+index 93fe61b869670..f28fb21e38911 100644
+--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
++++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
+@@ -300,6 +300,11 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
+ 	struct platform_device *pdev = hdmi->pdev;
+ 	int ret;
+ 
++	if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) {
++		DRM_DEV_ERROR(dev->dev, "too many bridges\n");
++		return -ENOSPC;
++	}
++
+ 	hdmi->dev = dev;
+ 	hdmi->encoder = encoder;
+ 
+@@ -339,7 +344,7 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
+ 		goto fail;
+ 	}
+ 
+-	ret = devm_request_irq(&pdev->dev, hdmi->irq,
++	ret = devm_request_irq(dev->dev, hdmi->irq,
+ 			msm_hdmi_irq, IRQF_TRIGGER_HIGH,
+ 			"hdmi_isr", hdmi);
+ 	if (ret < 0) {
+diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
+index 0759e2d99f59c..869ba58f02544 100644
+--- a/drivers/gpu/drm/msm/msm_drv.c
++++ b/drivers/gpu/drm/msm/msm_drv.c
+@@ -241,6 +241,7 @@ static int msm_drm_uninit(struct device *dev)
+ 
+ 	for (i = 0; i < priv->num_bridges; i++)
+ 		drm_bridge_remove(priv->bridges[i]);
++	priv->num_bridges = 0;
+ 
+ 	pm_runtime_get_sync(dev);
+ 	msm_irq_uninstall(ddev);
+diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c
+index 8988b2ed2ea6f..dcd607a0c41a1 100644
+--- a/drivers/hwtracing/coresight/coresight-cti-core.c
++++ b/drivers/hwtracing/coresight/coresight-cti-core.c
+@@ -90,11 +90,9 @@ void cti_write_all_hw_regs(struct cti_drvdata *drvdata)
+ static int cti_enable_hw(struct cti_drvdata *drvdata)
+ {
+ 	struct cti_config *config = &drvdata->config;
+-	struct device *dev = &drvdata->csdev->dev;
+ 	unsigned long flags;
+ 	int rc = 0;
+ 
+-	pm_runtime_get_sync(dev->parent);
+ 	spin_lock_irqsave(&drvdata->spinlock, flags);
+ 
+ 	/* no need to do anything if enabled or unpowered*/
+@@ -119,7 +117,6 @@ cti_state_unchanged:
+ 	/* cannot enable due to error */
+ cti_err_not_enabled:
+ 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+-	pm_runtime_put(dev->parent);
+ 	return rc;
+ }
+ 
+@@ -153,7 +150,6 @@ cti_hp_not_enabled:
+ static int cti_disable_hw(struct cti_drvdata *drvdata)
+ {
+ 	struct cti_config *config = &drvdata->config;
+-	struct device *dev = &drvdata->csdev->dev;
+ 	struct coresight_device *csdev = drvdata->csdev;
+ 
+ 	spin_lock(&drvdata->spinlock);
+@@ -175,7 +171,6 @@ static int cti_disable_hw(struct cti_drvdata *drvdata)
+ 	coresight_disclaim_device_unlocked(csdev);
+ 	CS_LOCK(drvdata->base);
+ 	spin_unlock(&drvdata->spinlock);
+-	pm_runtime_put(dev->parent);
+ 	return 0;
+ 
+ 	/* not disabled this call */
+diff --git a/drivers/iio/accel/adxl367.c b/drivers/iio/accel/adxl367.c
+index 47feb375b70be..7c7d780407937 100644
+--- a/drivers/iio/accel/adxl367.c
++++ b/drivers/iio/accel/adxl367.c
+@@ -1185,17 +1185,30 @@ static ssize_t adxl367_get_fifo_watermark(struct device *dev,
+ 	return sysfs_emit(buf, "%d\n", fifo_watermark);
+ }
+ 
+-static IIO_CONST_ATTR(hwfifo_watermark_min, "1");
+-static IIO_CONST_ATTR(hwfifo_watermark_max,
+-		      __stringify(ADXL367_FIFO_MAX_WATERMARK));
++static ssize_t hwfifo_watermark_min_show(struct device *dev,
++					 struct device_attribute *attr,
++					 char *buf)
++{
++	return sysfs_emit(buf, "%s\n", "1");
++}
++
++static ssize_t hwfifo_watermark_max_show(struct device *dev,
++					 struct device_attribute *attr,
++					 char *buf)
++{
++	return sysfs_emit(buf, "%s\n", __stringify(ADXL367_FIFO_MAX_WATERMARK));
++}
++
++static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0);
++static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
+ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
+ 		       adxl367_get_fifo_watermark, NULL, 0);
+ static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
+ 		       adxl367_get_fifo_enabled, NULL, 0);
+ 
+ static const struct attribute *adxl367_fifo_attributes[] = {
+-	&iio_const_attr_hwfifo_watermark_min.dev_attr.attr,
+-	&iio_const_attr_hwfifo_watermark_max.dev_attr.attr,
++	&iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
++	&iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
+ 	&iio_dev_attr_hwfifo_watermark.dev_attr.attr,
+ 	&iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+ 	NULL,
+diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c
+index e3ecbaee61f70..bc53af809d5de 100644
+--- a/drivers/iio/accel/adxl372.c
++++ b/drivers/iio/accel/adxl372.c
+@@ -998,17 +998,30 @@ static ssize_t adxl372_get_fifo_watermark(struct device *dev,
+ 	return sprintf(buf, "%d\n", st->watermark);
+ }
+ 
+-static IIO_CONST_ATTR(hwfifo_watermark_min, "1");
+-static IIO_CONST_ATTR(hwfifo_watermark_max,
+-		      __stringify(ADXL372_FIFO_SIZE));
++static ssize_t hwfifo_watermark_min_show(struct device *dev,
++					 struct device_attribute *attr,
++					 char *buf)
++{
++	return sysfs_emit(buf, "%s\n", "1");
++}
++
++static ssize_t hwfifo_watermark_max_show(struct device *dev,
++					 struct device_attribute *attr,
++					 char *buf)
++{
++	return sysfs_emit(buf, "%s\n", __stringify(ADXL372_FIFO_SIZE));
++}
++
++static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0);
++static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
+ static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
+ 		       adxl372_get_fifo_watermark, NULL, 0);
+ static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
+ 		       adxl372_get_fifo_enabled, NULL, 0);
+ 
+ static const struct attribute *adxl372_fifo_attributes[] = {
+-	&iio_const_attr_hwfifo_watermark_min.dev_attr.attr,
+-	&iio_const_attr_hwfifo_watermark_max.dev_attr.attr,
++	&iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
++	&iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
+ 	&iio_dev_attr_hwfifo_watermark.dev_attr.attr,
+ 	&iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+ 	NULL,
+diff --git a/drivers/iio/light/tsl2583.c b/drivers/iio/light/tsl2583.c
+index 82662dab87c0f..94d75ec687c38 100644
+--- a/drivers/iio/light/tsl2583.c
++++ b/drivers/iio/light/tsl2583.c
+@@ -858,7 +858,7 @@ static int tsl2583_probe(struct i2c_client *clientp,
+ 					 TSL2583_POWER_OFF_DELAY_MS);
+ 	pm_runtime_use_autosuspend(&clientp->dev);
+ 
+-	ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
++	ret = iio_device_register(indio_dev);
+ 	if (ret) {
+ 		dev_err(&clientp->dev, "%s: iio registration failed\n",
+ 			__func__);
+diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
+index b652d2b39bcf2..a60ccf1836872 100644
+--- a/drivers/iio/temperature/ltc2983.c
++++ b/drivers/iio/temperature/ltc2983.c
+@@ -1385,13 +1385,6 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
+ 		return ret;
+ 	}
+ 
+-	st->iio_chan = devm_kzalloc(&st->spi->dev,
+-				    st->iio_channels * sizeof(*st->iio_chan),
+-				    GFP_KERNEL);
+-
+-	if (!st->iio_chan)
+-		return -ENOMEM;
+-
+ 	ret = regmap_update_bits(st->regmap, LTC2983_GLOBAL_CONFIG_REG,
+ 				 LTC2983_NOTCH_FREQ_MASK,
+ 				 LTC2983_NOTCH_FREQ(st->filter_notch_freq));
+@@ -1514,6 +1507,12 @@ static int ltc2983_probe(struct spi_device *spi)
+ 		gpiod_set_value_cansleep(gpio, 0);
+ 	}
+ 
++	st->iio_chan = devm_kzalloc(&spi->dev,
++				    st->iio_channels * sizeof(*st->iio_chan),
++				    GFP_KERNEL);
++	if (!st->iio_chan)
++		return -ENOMEM;
++
+ 	ret = ltc2983_setup(st, true);
+ 	if (ret)
+ 		return ret;
+diff --git a/drivers/media/i2c/ar0521.c b/drivers/media/i2c/ar0521.c
+index c7bdfc69b9be8..5c9c7c52cfc40 100644
+--- a/drivers/media/i2c/ar0521.c
++++ b/drivers/media/i2c/ar0521.c
+@@ -756,10 +756,12 @@ static int ar0521_power_on(struct device *dev)
+ 		gpiod_set_value(sensor->reset_gpio, 0);
+ 	usleep_range(4500, 5000); /* min 45000 clocks */
+ 
+-	for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++)
+-		if (ar0521_write_regs(sensor, initial_regs[cnt].data,
+-				      initial_regs[cnt].count))
++	for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++) {
++		ret = ar0521_write_regs(sensor, initial_regs[cnt].data,
++					initial_regs[cnt].count);
++		if (ret)
+ 			goto off;
++	}
+ 
+ 	ret = ar0521_write_reg(sensor, AR0521_REG_SERIAL_FORMAT,
+ 			       AR0521_REG_SERIAL_FORMAT_MIPI |
+diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c
+index b8f4f0d3e33d7..15d0f79231dd6 100644
+--- a/drivers/media/i2c/ov8865.c
++++ b/drivers/media/i2c/ov8865.c
+@@ -3034,11 +3034,13 @@ static int ov8865_probe(struct i2c_client *client)
+ 				       &rate);
+ 	if (!ret && sensor->extclk) {
+ 		ret = clk_set_rate(sensor->extclk, rate);
+-		if (ret)
+-			return dev_err_probe(dev, ret,
+-					     "failed to set clock rate\n");
++		if (ret) {
++			dev_err_probe(dev, ret, "failed to set clock rate\n");
++			goto error_endpoint;
++		}
+ 	} else if (ret && !sensor->extclk) {
+-		return dev_err_probe(dev, ret, "invalid clock config\n");
++		dev_err_probe(dev, ret, "invalid clock config\n");
++		goto error_endpoint;
+ 	}
+ 
+ 	sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk);
+diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
+index 8a3eed957ae6e..b779e0ba916ca 100644
+--- a/drivers/media/platform/amphion/vpu_v4l2.c
++++ b/drivers/media/platform/amphion/vpu_v4l2.c
+@@ -603,6 +603,10 @@ static int vpu_v4l2_release(struct vpu_inst *inst)
+ 		inst->workqueue = NULL;
+ 	}
+ 
++	if (inst->fh.m2m_ctx) {
++		v4l2_m2m_ctx_release(inst->fh.m2m_ctx);
++		inst->fh.m2m_ctx = NULL;
++	}
+ 	v4l2_ctrl_handler_free(&inst->ctrl_handler);
+ 	mutex_destroy(&inst->lock);
+ 	v4l2_fh_del(&inst->fh);
+@@ -685,13 +689,6 @@ int vpu_v4l2_close(struct file *file)
+ 
+ 	vpu_trace(vpu->dev, "tgid = %d, pid = %d, inst = %p\n", inst->tgid, inst->pid, inst);
+ 
+-	vpu_inst_lock(inst);
+-	if (inst->fh.m2m_ctx) {
+-		v4l2_m2m_ctx_release(inst->fh.m2m_ctx);
+-		inst->fh.m2m_ctx = NULL;
+-	}
+-	vpu_inst_unlock(inst);
+-
+ 	call_void_vop(inst, release);
+ 	vpu_inst_unregister(inst);
+ 	vpu_inst_put(inst);
+diff --git a/drivers/media/platform/sunxi/sun4i-csi/Kconfig b/drivers/media/platform/sunxi/sun4i-csi/Kconfig
+index 7960e6836f415..60610c04d6a76 100644
+--- a/drivers/media/platform/sunxi/sun4i-csi/Kconfig
++++ b/drivers/media/platform/sunxi/sun4i-csi/Kconfig
+@@ -3,7 +3,7 @@
+ config VIDEO_SUN4I_CSI
+ 	tristate "Allwinner A10 CMOS Sensor Interface Support"
+ 	depends on V4L_PLATFORM_DRIVERS
+-	depends on VIDEO_DEV && COMMON_CLK  && HAS_DMA
++	depends on VIDEO_DEV && COMMON_CLK && RESET_CONTROLLER && HAS_DMA
+ 	depends on ARCH_SUNXI || COMPILE_TEST
+ 	select MEDIA_CONTROLLER
+ 	select VIDEO_V4L2_SUBDEV_API
+diff --git a/drivers/media/platform/sunxi/sun6i-csi/Kconfig b/drivers/media/platform/sunxi/sun6i-csi/Kconfig
+index 0345901617d41..e5b6991ce7f04 100644
+--- a/drivers/media/platform/sunxi/sun6i-csi/Kconfig
++++ b/drivers/media/platform/sunxi/sun6i-csi/Kconfig
+@@ -2,7 +2,7 @@
+ config VIDEO_SUN6I_CSI
+ 	tristate "Allwinner V3s Camera Sensor Interface driver"
+ 	depends on V4L_PLATFORM_DRIVERS
+-	depends on VIDEO_DEV && COMMON_CLK  && HAS_DMA
++	depends on VIDEO_DEV && COMMON_CLK && RESET_CONTROLLER && HAS_DMA
+ 	depends on ARCH_SUNXI || COMPILE_TEST
+ 	select MEDIA_CONTROLLER
+ 	select VIDEO_V4L2_SUBDEV_API
+diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig b/drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig
+index eb982466abd30..08852f63692b6 100644
+--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig
++++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/Kconfig
+@@ -3,11 +3,11 @@ config VIDEO_SUN6I_MIPI_CSI2
+ 	tristate "Allwinner A31 MIPI CSI-2 Controller Driver"
+ 	depends on V4L_PLATFORM_DRIVERS && VIDEO_DEV
+ 	depends on ARCH_SUNXI || COMPILE_TEST
+-	depends on PM && COMMON_CLK
++	depends on PM && COMMON_CLK && RESET_CONTROLLER
++	depends on PHY_SUN6I_MIPI_DPHY
+ 	select MEDIA_CONTROLLER
+ 	select VIDEO_V4L2_SUBDEV_API
+ 	select V4L2_FWNODE
+-	select PHY_SUN6I_MIPI_DPHY
+ 	select GENERIC_PHY_MIPI_DPHY
+ 	select REGMAP_MMIO
+ 	help
+diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+index a4e3f9a6b2ff2..30d6c0c5161f4 100644
+--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
++++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+@@ -661,7 +661,8 @@ sun6i_mipi_csi2_resources_setup(struct sun6i_mipi_csi2_device *csi2_dev,
+ 	csi2_dev->reset = devm_reset_control_get_shared(dev, NULL);
+ 	if (IS_ERR(csi2_dev->reset)) {
+ 		dev_err(dev, "failed to get reset controller\n");
+-		return PTR_ERR(csi2_dev->reset);
++		ret = PTR_ERR(csi2_dev->reset);
++		goto error_clock_rate_exclusive;
+ 	}
+ 
+ 	/* D-PHY */
+@@ -669,13 +670,14 @@ sun6i_mipi_csi2_resources_setup(struct sun6i_mipi_csi2_device *csi2_dev,
+ 	csi2_dev->dphy = devm_phy_get(dev, "dphy");
+ 	if (IS_ERR(csi2_dev->dphy)) {
+ 		dev_err(dev, "failed to get MIPI D-PHY\n");
+-		return PTR_ERR(csi2_dev->dphy);
++		ret = PTR_ERR(csi2_dev->dphy);
++		goto error_clock_rate_exclusive;
+ 	}
+ 
+ 	ret = phy_init(csi2_dev->dphy);
+ 	if (ret) {
+ 		dev_err(dev, "failed to initialize MIPI D-PHY\n");
+-		return ret;
++		goto error_clock_rate_exclusive;
+ 	}
+ 
+ 	/* Runtime PM */
+@@ -683,6 +685,11 @@ sun6i_mipi_csi2_resources_setup(struct sun6i_mipi_csi2_device *csi2_dev,
+ 	pm_runtime_enable(dev);
+ 
+ 	return 0;
++
++error_clock_rate_exclusive:
++	clk_rate_exclusive_put(csi2_dev->clock_mod);
++
++	return ret;
+ }
+ 
+ static void
+@@ -712,9 +719,14 @@ static int sun6i_mipi_csi2_probe(struct platform_device *platform_dev)
+ 
+ 	ret = sun6i_mipi_csi2_bridge_setup(csi2_dev);
+ 	if (ret)
+-		return ret;
++		goto error_resources;
+ 
+ 	return 0;
++
++error_resources:
++	sun6i_mipi_csi2_resources_cleanup(csi2_dev);
++
++	return ret;
+ }
+ 
+ static int sun6i_mipi_csi2_remove(struct platform_device *platform_dev)
+diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig
+index 789d58ee12ea9..47a8c0fb7eb9f 100644
+--- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig
++++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig
+@@ -3,7 +3,7 @@ config VIDEO_SUN8I_A83T_MIPI_CSI2
+ 	tristate "Allwinner A83T MIPI CSI-2 Controller and D-PHY Driver"
+ 	depends on V4L_PLATFORM_DRIVERS && VIDEO_DEV
+ 	depends on ARCH_SUNXI || COMPILE_TEST
+-	depends on PM && COMMON_CLK
++	depends on PM && COMMON_CLK && RESET_CONTROLLER
+ 	select MEDIA_CONTROLLER
+ 	select VIDEO_V4L2_SUBDEV_API
+ 	select V4L2_FWNODE
+diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
+index d052ee77ef0aa..b032ec13a683a 100644
+--- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
++++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
+@@ -719,13 +719,15 @@ sun8i_a83t_mipi_csi2_resources_setup(struct sun8i_a83t_mipi_csi2_device *csi2_de
+ 	csi2_dev->clock_mipi = devm_clk_get(dev, "mipi");
+ 	if (IS_ERR(csi2_dev->clock_mipi)) {
+ 		dev_err(dev, "failed to acquire mipi clock\n");
+-		return PTR_ERR(csi2_dev->clock_mipi);
++		ret = PTR_ERR(csi2_dev->clock_mipi);
++		goto error_clock_rate_exclusive;
+ 	}
+ 
+ 	csi2_dev->clock_misc = devm_clk_get(dev, "misc");
+ 	if (IS_ERR(csi2_dev->clock_misc)) {
+ 		dev_err(dev, "failed to acquire misc clock\n");
+-		return PTR_ERR(csi2_dev->clock_misc);
++		ret = PTR_ERR(csi2_dev->clock_misc);
++		goto error_clock_rate_exclusive;
+ 	}
+ 
+ 	/* Reset */
+@@ -733,7 +735,8 @@ sun8i_a83t_mipi_csi2_resources_setup(struct sun8i_a83t_mipi_csi2_device *csi2_de
+ 	csi2_dev->reset = devm_reset_control_get_shared(dev, NULL);
+ 	if (IS_ERR(csi2_dev->reset)) {
+ 		dev_err(dev, "failed to get reset controller\n");
+-		return PTR_ERR(csi2_dev->reset);
++		ret = PTR_ERR(csi2_dev->reset);
++		goto error_clock_rate_exclusive;
+ 	}
+ 
+ 	/* D-PHY */
+@@ -741,7 +744,7 @@ sun8i_a83t_mipi_csi2_resources_setup(struct sun8i_a83t_mipi_csi2_device *csi2_de
+ 	ret = sun8i_a83t_dphy_register(csi2_dev);
+ 	if (ret) {
+ 		dev_err(dev, "failed to initialize MIPI D-PHY\n");
+-		return ret;
++		goto error_clock_rate_exclusive;
+ 	}
+ 
+ 	/* Runtime PM */
+@@ -749,6 +752,11 @@ sun8i_a83t_mipi_csi2_resources_setup(struct sun8i_a83t_mipi_csi2_device *csi2_de
+ 	pm_runtime_enable(dev);
+ 
+ 	return 0;
++
++error_clock_rate_exclusive:
++	clk_rate_exclusive_put(csi2_dev->clock_mod);
++
++	return ret;
+ }
+ 
+ static void
+@@ -778,9 +786,14 @@ static int sun8i_a83t_mipi_csi2_probe(struct platform_device *platform_dev)
+ 
+ 	ret = sun8i_a83t_mipi_csi2_bridge_setup(csi2_dev);
+ 	if (ret)
+-		return ret;
++		goto error_resources;
+ 
+ 	return 0;
++
++error_resources:
++	sun8i_a83t_mipi_csi2_resources_cleanup(csi2_dev);
++
++	return ret;
+ }
+ 
+ static int sun8i_a83t_mipi_csi2_remove(struct platform_device *platform_dev)
+diff --git a/drivers/media/platform/sunxi/sun8i-di/Kconfig b/drivers/media/platform/sunxi/sun8i-di/Kconfig
+index ff71e06ee2dfe..f688396913b79 100644
+--- a/drivers/media/platform/sunxi/sun8i-di/Kconfig
++++ b/drivers/media/platform/sunxi/sun8i-di/Kconfig
+@@ -4,7 +4,7 @@ config VIDEO_SUN8I_DEINTERLACE
+ 	depends on V4L_MEM2MEM_DRIVERS
+ 	depends on VIDEO_DEV
+ 	depends on ARCH_SUNXI || COMPILE_TEST
+-	depends on COMMON_CLK && OF
++	depends on COMMON_CLK && RESET_CONTROLLER && OF
+ 	depends on PM
+ 	select VIDEOBUF2_DMA_CONTIG
+ 	select V4L2_MEM2MEM_DEV
+diff --git a/drivers/media/platform/sunxi/sun8i-rotate/Kconfig b/drivers/media/platform/sunxi/sun8i-rotate/Kconfig
+index cfba29072d752..ee2c1f248c646 100644
+--- a/drivers/media/platform/sunxi/sun8i-rotate/Kconfig
++++ b/drivers/media/platform/sunxi/sun8i-rotate/Kconfig
+@@ -5,7 +5,7 @@ config VIDEO_SUN8I_ROTATE
+ 	depends on V4L_MEM2MEM_DRIVERS
+ 	depends on VIDEO_DEV
+ 	depends on ARCH_SUNXI || COMPILE_TEST
+-	depends on COMMON_CLK && OF
++	depends on COMMON_CLK && RESET_CONTROLLER && OF
+ 	depends on PM
+ 	select VIDEOBUF2_DMA_CONTIG
+ 	select V4L2_MEM2MEM_DEV
+diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c
+index 04b75666bad4d..f28440e6c9f89 100644
+--- a/drivers/media/test-drivers/vivid/vivid-core.c
++++ b/drivers/media/test-drivers/vivid/vivid-core.c
+@@ -339,6 +339,28 @@ static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a
+ 	return vivid_vid_out_g_fbuf(file, fh, a);
+ }
+ 
++/*
++ * Only support the framebuffer of one of the vivid instances.
++ * Anything else is rejected.
++ */
++bool vivid_validate_fb(const struct v4l2_framebuffer *a)
++{
++	struct vivid_dev *dev;
++	int i;
++
++	for (i = 0; i < n_devs; i++) {
++		dev = vivid_devs[i];
++		if (!dev || !dev->video_pbase)
++			continue;
++		if ((unsigned long)a->base == dev->video_pbase &&
++		    a->fmt.width <= dev->display_width &&
++		    a->fmt.height <= dev->display_height &&
++		    a->fmt.bytesperline <= dev->display_byte_stride)
++			return true;
++	}
++	return false;
++}
++
+ static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a)
+ {
+ 	struct video_device *vdev = video_devdata(file);
+@@ -920,8 +942,12 @@ static int vivid_detect_feature_set(struct vivid_dev *dev, int inst,
+ 
+ 	/* how many inputs do we have and of what type? */
+ 	dev->num_inputs = num_inputs[inst];
+-	if (dev->num_inputs < 1)
+-		dev->num_inputs = 1;
++	if (node_type & 0x20007) {
++		if (dev->num_inputs < 1)
++			dev->num_inputs = 1;
++	} else {
++		dev->num_inputs = 0;
++	}
+ 	if (dev->num_inputs >= MAX_INPUTS)
+ 		dev->num_inputs = MAX_INPUTS;
+ 	for (i = 0; i < dev->num_inputs; i++) {
+@@ -938,8 +964,12 @@ static int vivid_detect_feature_set(struct vivid_dev *dev, int inst,
+ 
+ 	/* how many outputs do we have and of what type? */
+ 	dev->num_outputs = num_outputs[inst];
+-	if (dev->num_outputs < 1)
+-		dev->num_outputs = 1;
++	if (node_type & 0x40300) {
++		if (dev->num_outputs < 1)
++			dev->num_outputs = 1;
++	} else {
++		dev->num_outputs = 0;
++	}
+ 	if (dev->num_outputs >= MAX_OUTPUTS)
+ 		dev->num_outputs = MAX_OUTPUTS;
+ 	for (i = 0; i < dev->num_outputs; i++) {
+diff --git a/drivers/media/test-drivers/vivid/vivid-core.h b/drivers/media/test-drivers/vivid/vivid-core.h
+index 176b72cb143b6..5def9b2a359ad 100644
+--- a/drivers/media/test-drivers/vivid/vivid-core.h
++++ b/drivers/media/test-drivers/vivid/vivid-core.h
+@@ -610,4 +610,6 @@ static inline bool vivid_is_hdmi_out(const struct vivid_dev *dev)
+ 	return dev->output_type[dev->output] == HDMI;
+ }
+ 
++bool vivid_validate_fb(const struct v4l2_framebuffer *a);
++
+ #endif
+diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+index b9caa4b26209e..99139a8cd4c4f 100644
+--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
++++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+@@ -452,6 +452,12 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)
+ 	tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap);
+ 	dev->crop_cap = dev->src_rect;
+ 	dev->crop_bounds_cap = dev->src_rect;
++	if (dev->bitmap_cap &&
++	    (dev->compose_cap.width != dev->crop_cap.width ||
++	     dev->compose_cap.height != dev->crop_cap.height)) {
++		vfree(dev->bitmap_cap);
++		dev->bitmap_cap = NULL;
++	}
+ 	dev->compose_cap = dev->crop_cap;
+ 	if (V4L2_FIELD_HAS_T_OR_B(dev->field_cap))
+ 		dev->compose_cap.height /= 2;
+@@ -909,6 +915,8 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
+ 	struct vivid_dev *dev = video_drvdata(file);
+ 	struct v4l2_rect *crop = &dev->crop_cap;
+ 	struct v4l2_rect *compose = &dev->compose_cap;
++	unsigned orig_compose_w = compose->width;
++	unsigned orig_compose_h = compose->height;
+ 	unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;
+ 	int ret;
+ 
+@@ -1025,17 +1033,17 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
+ 			s->r.height /= factor;
+ 		}
+ 		v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect);
+-		if (dev->bitmap_cap && (compose->width != s->r.width ||
+-					compose->height != s->r.height)) {
+-			vfree(dev->bitmap_cap);
+-			dev->bitmap_cap = NULL;
+-		}
+ 		*compose = s->r;
+ 		break;
+ 	default:
+ 		return -EINVAL;
+ 	}
+ 
++	if (dev->bitmap_cap && (compose->width != orig_compose_w ||
++				compose->height != orig_compose_h)) {
++		vfree(dev->bitmap_cap);
++		dev->bitmap_cap = NULL;
++	}
+ 	tpg_s_crop_compose(&dev->tpg, crop, compose);
+ 	return 0;
+ }
+@@ -1272,7 +1280,14 @@ int vivid_vid_cap_s_fbuf(struct file *file, void *fh,
+ 		return -EINVAL;
+ 	if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8)
+ 		return -EINVAL;
+-	if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage)
++	if (a->fmt.bytesperline > a->fmt.sizeimage / a->fmt.height)
++		return -EINVAL;
++
++	/*
++	 * Only support the framebuffer of one of the vivid instances.
++	 * Anything else is rejected.
++	 */
++	if (!vivid_validate_fb(a))
+ 		return -EINVAL;
+ 
+ 	dev->fb_vbase_cap = phys_to_virt((unsigned long)a->base);
+diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
+index af48705c704f8..003c32fed3f75 100644
+--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
++++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
+@@ -161,6 +161,20 @@ bool v4l2_valid_dv_timings(const struct v4l2_dv_timings *t,
+ 	    (bt->interlaced && !(caps & V4L2_DV_BT_CAP_INTERLACED)) ||
+ 	    (!bt->interlaced && !(caps & V4L2_DV_BT_CAP_PROGRESSIVE)))
+ 		return false;
++
++	/* sanity checks for the blanking timings */
++	if (!bt->interlaced &&
++	    (bt->il_vbackporch || bt->il_vsync || bt->il_vfrontporch))
++		return false;
++	if (bt->hfrontporch > 2 * bt->width ||
++	    bt->hsync > 1024 || bt->hbackporch > 1024)
++		return false;
++	if (bt->vfrontporch > 4096 ||
++	    bt->vsync > 128 || bt->vbackporch > 4096)
++		return false;
++	if (bt->interlaced && (bt->il_vfrontporch > 4096 ||
++	    bt->il_vsync > 128 || bt->il_vbackporch > 4096))
++		return false;
+ 	return fnc == NULL || fnc(t, fnc_handle);
+ }
+ EXPORT_SYMBOL_GPL(v4l2_valid_dv_timings);
+diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
+index 54cd009aee50e..db6d8a0999100 100644
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -134,6 +134,7 @@ struct mmc_blk_data {
+ 	 * track of the current selected device partition.
+ 	 */
+ 	unsigned int	part_curr;
++#define MMC_BLK_PART_INVALID	UINT_MAX	/* Unknown partition active */
+ 	int	area_type;
+ 
+ 	/* debugfs files (only in main mmc_blk_data) */
+@@ -987,33 +988,39 @@ static unsigned int mmc_blk_data_timeout_ms(struct mmc_host *host,
+ 	return ms;
+ }
+ 
++/*
++ * Attempts to reset the card and get back to the requested partition.
++ * Therefore any error here must result in cancelling the block layer
++ * request, it must not be reattempted without going through the mmc_blk
++ * partition sanity checks.
++ */
+ static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
+ 			 int type)
+ {
+ 	int err;
++	struct mmc_blk_data *main_md = dev_get_drvdata(&host->card->dev);
+ 
+ 	if (md->reset_done & type)
+ 		return -EEXIST;
+ 
+ 	md->reset_done |= type;
+ 	err = mmc_hw_reset(host->card);
++	/*
++	 * A successful reset will leave the card in the main partition, but
++	 * upon failure it might not be, so set it to MMC_BLK_PART_INVALID
++	 * in that case.
++	 */
++	main_md->part_curr = err ? MMC_BLK_PART_INVALID : main_md->part_type;
++	if (err)
++		return err;
+ 	/* Ensure we switch back to the correct partition */
+-	if (err) {
+-		struct mmc_blk_data *main_md =
+-			dev_get_drvdata(&host->card->dev);
+-		int part_err;
+-
+-		main_md->part_curr = main_md->part_type;
+-		part_err = mmc_blk_part_switch(host->card, md->part_type);
+-		if (part_err) {
+-			/*
+-			 * We have failed to get back into the correct
+-			 * partition, so we need to abort the whole request.
+-			 */
+-			return -ENODEV;
+-		}
+-	}
+-	return err;
++	if (mmc_blk_part_switch(host->card, md->part_type))
++		/*
++		 * We have failed to get back into the correct
++		 * partition, so we need to abort the whole request.
++		 */
++		return -ENODEV;
++	return 0;
+ }
+ 
+ static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type)
+@@ -1871,8 +1878,9 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
+ 		return;
+ 
+ 	/* Reset before last retry */
+-	if (mqrq->retries + 1 == MMC_MAX_RETRIES)
+-		mmc_blk_reset(md, card->host, type);
++	if (mqrq->retries + 1 == MMC_MAX_RETRIES &&
++	    mmc_blk_reset(md, card->host, type))
++		return;
+ 
+ 	/* Command errors fail fast, so use all MMC_MAX_RETRIES */
+ 	if (brq->sbc.error || brq->cmd.error)
+diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
+index fefaa901b50f3..b396e39007177 100644
+--- a/drivers/mmc/core/queue.c
++++ b/drivers/mmc/core/queue.c
+@@ -48,6 +48,7 @@ static enum mmc_issue_type mmc_cqe_issue_type(struct mmc_host *host,
+ 	case REQ_OP_DRV_OUT:
+ 	case REQ_OP_DISCARD:
+ 	case REQ_OP_SECURE_ERASE:
++	case REQ_OP_WRITE_ZEROES:
+ 		return MMC_ISSUE_SYNC;
+ 	case REQ_OP_FLUSH:
+ 		return mmc_cqe_can_dcmd(host) ? MMC_ISSUE_DCMD : MMC_ISSUE_SYNC;
+@@ -493,6 +494,13 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
+ 	if (blk_queue_quiesced(q))
+ 		blk_mq_unquiesce_queue(q);
+ 
++	/*
++	 * If the recovery completes the last (and only remaining) request in
++	 * the queue, and the card has been removed, we could end up here with
++	 * the recovery not quite finished yet, so cancel it.
++	 */
++	cancel_work_sync(&mq->recovery_work);
++
+ 	blk_mq_free_tag_set(&mq->tag_set);
+ 
+ 	/*
+diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
+index c6268c38c69e5..babf21a0adeb6 100644
+--- a/drivers/mmc/core/sdio_bus.c
++++ b/drivers/mmc/core/sdio_bus.c
+@@ -291,7 +291,8 @@ static void sdio_release_func(struct device *dev)
+ {
+ 	struct sdio_func *func = dev_to_sdio_func(dev);
+ 
+-	sdio_free_func_cis(func);
++	if (!(func->card->quirks & MMC_QUIRK_NONSTD_SDIO))
++		sdio_free_func_cis(func);
+ 
+ 	kfree(func->info);
+ 	kfree(func->tmpbuf);
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index e63608834411a..97a6ea4a3ac79 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -1074,9 +1074,10 @@ config MMC_SDHCI_OMAP
+ 
+ config MMC_SDHCI_AM654
+ 	tristate "Support for the SDHCI Controller in TI's AM654 SOCs"
+-	depends on MMC_SDHCI_PLTFM && OF && REGMAP_MMIO
++	depends on MMC_SDHCI_PLTFM && OF
+ 	select MMC_SDHCI_IO_ACCESSORS
+ 	select MMC_CQHCI
++	select REGMAP_MMIO
+ 	help
+ 	  This selects the Secure Digital Host Controller Interface (SDHCI)
+ 	  support present in TI's AM654 SOCs. The controller supports
+diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
+index 55981b0f0b10c..747df79d90eef 100644
+--- a/drivers/mmc/host/sdhci-esdhc-imx.c
++++ b/drivers/mmc/host/sdhci-esdhc-imx.c
+@@ -1660,6 +1660,10 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
+ 		host->mmc_host_ops.execute_tuning = usdhc_execute_tuning;
+ 	}
+ 
++	err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
++	if (err)
++		goto disable_ahb_clk;
++
+ 	if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING)
+ 		sdhci_esdhc_ops.platform_execute_tuning =
+ 					esdhc_executing_tuning;
+@@ -1667,13 +1671,15 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
+ 	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
+ 		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
+ 
+-	if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
++	if (host->caps & MMC_CAP_8_BIT_DATA &&
++	    imx_data->socdata->flags & ESDHC_FLAG_HS400)
+ 		host->mmc->caps2 |= MMC_CAP2_HS400;
+ 
+ 	if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23)
+ 		host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN;
+ 
+-	if (imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
++	if (host->caps & MMC_CAP_8_BIT_DATA &&
++	    imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
+ 		host->mmc->caps2 |= MMC_CAP2_HS400_ES;
+ 		host->mmc_host_ops.hs400_enhanced_strobe =
+ 					esdhc_hs400_enhanced_strobe;
+@@ -1695,10 +1701,6 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
+ 			goto disable_ahb_clk;
+ 	}
+ 
+-	err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
+-	if (err)
+-		goto disable_ahb_clk;
+-
+ 	sdhci_esdhc_imx_hwinit(host);
+ 
+ 	err = sdhci_add_host(host);
+diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
+index 622b7de96c7f6..b6f4bd3d93cd8 100644
+--- a/drivers/mmc/host/sdhci-pci-core.c
++++ b/drivers/mmc/host/sdhci-pci-core.c
+@@ -893,6 +893,12 @@ static bool glk_broken_cqhci(struct sdhci_pci_slot *slot)
+ 		dmi_match(DMI_SYS_VENDOR, "IRBIS"));
+ }
+ 
++static bool jsl_broken_hs400es(struct sdhci_pci_slot *slot)
++{
++	return slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_JSL_EMMC &&
++			dmi_match(DMI_BIOS_VENDOR, "ASUSTeK COMPUTER INC.");
++}
++
+ static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot)
+ {
+ 	int ret = byt_emmc_probe_slot(slot);
+@@ -901,9 +907,11 @@ static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot)
+ 		slot->host->mmc->caps2 |= MMC_CAP2_CQE;
+ 
+ 	if (slot->chip->pdev->device != PCI_DEVICE_ID_INTEL_GLK_EMMC) {
+-		slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES;
+-		slot->host->mmc_host_ops.hs400_enhanced_strobe =
+-						intel_hs400_enhanced_strobe;
++		if (!jsl_broken_hs400es(slot)) {
++			slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES;
++			slot->host->mmc_host_ops.hs400_enhanced_strobe =
++							intel_hs400_enhanced_strobe;
++		}
+ 		slot->host->mmc->caps2 |= MMC_CAP2_CQE_DCMD;
+ 	}
+ 
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index a9b8be9f40dc2..477707bcad972 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -562,7 +562,7 @@ static void mtd_check_of_node(struct mtd_info *mtd)
+ 	if (!mtd_is_partition(mtd))
+ 		return;
+ 	parent = mtd->parent;
+-	parent_dn = dev_of_node(&parent->dev);
++	parent_dn = of_node_get(dev_of_node(&parent->dev));
+ 	if (!parent_dn)
+ 		return;
+ 
+diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c
+index 056835fd45622..4c721704d2fdb 100644
+--- a/drivers/mtd/nand/raw/intel-nand-controller.c
++++ b/drivers/mtd/nand/raw/intel-nand-controller.c
+@@ -108,7 +108,6 @@
+ 
+ struct ebu_nand_cs {
+ 	void __iomem *chipaddr;
+-	dma_addr_t nand_pa;
+ 	u32 addr_sel;
+ };
+ 
+@@ -596,13 +595,11 @@ static int ebu_nand_probe(struct platform_device *pdev)
+ 	ebu_host->dev = dev;
+ 	nand_controller_init(&ebu_host->controller);
+ 
+-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ebunand");
+-	ebu_host->ebu = devm_ioremap_resource(&pdev->dev, res);
++	ebu_host->ebu = devm_platform_ioremap_resource_byname(pdev, "ebunand");
+ 	if (IS_ERR(ebu_host->ebu))
+ 		return PTR_ERR(ebu_host->ebu);
+ 
+-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hsnand");
+-	ebu_host->hsnand = devm_ioremap_resource(&pdev->dev, res);
++	ebu_host->hsnand = devm_platform_ioremap_resource_byname(pdev, "hsnand");
+ 	if (IS_ERR(ebu_host->hsnand))
+ 		return PTR_ERR(ebu_host->hsnand);
+ 
+@@ -614,31 +611,35 @@ static int ebu_nand_probe(struct platform_device *pdev)
+ 	ret = of_property_read_u32(chip_np, "reg", &cs);
+ 	if (ret) {
+ 		dev_err(dev, "failed to get chip select: %d\n", ret);
+-		return ret;
++		goto err_of_node_put;
+ 	}
+ 	if (cs >= MAX_CS) {
+ 		dev_err(dev, "got invalid chip select: %d\n", cs);
+-		return -EINVAL;
++		ret = -EINVAL;
++		goto err_of_node_put;
+ 	}
+ 
+ 	ebu_host->cs_num = cs;
+ 
+ 	resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs);
+-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname);
+-	ebu_host->cs[cs].chipaddr = devm_ioremap_resource(dev, res);
+-	if (IS_ERR(ebu_host->cs[cs].chipaddr))
+-		return PTR_ERR(ebu_host->cs[cs].chipaddr);
+-	ebu_host->cs[cs].nand_pa = res->start;
++	ebu_host->cs[cs].chipaddr = devm_platform_ioremap_resource_byname(pdev,
++									  resname);
++	if (IS_ERR(ebu_host->cs[cs].chipaddr)) {
++		ret = PTR_ERR(ebu_host->cs[cs].chipaddr);
++		goto err_of_node_put;
++	}
+ 
+ 	ebu_host->clk = devm_clk_get(dev, NULL);
+-	if (IS_ERR(ebu_host->clk))
+-		return dev_err_probe(dev, PTR_ERR(ebu_host->clk),
+-				     "failed to get clock\n");
++	if (IS_ERR(ebu_host->clk)) {
++		ret = dev_err_probe(dev, PTR_ERR(ebu_host->clk),
++				    "failed to get clock\n");
++		goto err_of_node_put;
++	}
+ 
+ 	ret = clk_prepare_enable(ebu_host->clk);
+ 	if (ret) {
+ 		dev_err(dev, "failed to enable clock: %d\n", ret);
+-		return ret;
++		goto err_of_node_put;
+ 	}
+ 	ebu_host->clk_rate = clk_get_rate(ebu_host->clk);
+ 
+@@ -703,6 +704,8 @@ err_cleanup_dma:
+ 	ebu_dma_cleanup(ebu_host);
+ err_disable_unprepare_clk:
+ 	clk_disable_unprepare(ebu_host->clk);
++err_of_node_put:
++	of_node_put(chip_np);
+ 
+ 	return ret;
+ }
+diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
+index 2455a581fd70c..b248c5f657d56 100644
+--- a/drivers/mtd/nand/raw/marvell_nand.c
++++ b/drivers/mtd/nand/raw/marvell_nand.c
+@@ -2672,7 +2672,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
+ 	chip->controller = &nfc->controller;
+ 	nand_set_flash_node(chip, np);
+ 
+-	if (!of_property_read_bool(np, "marvell,nand-keep-config"))
++	if (of_property_read_bool(np, "marvell,nand-keep-config"))
+ 		chip->options |= NAND_KEEP_TIMINGS;
+ 
+ 	mtd = nand_to_mtd(chip);
+diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c
+index e12f9f580a15f..a9b9031ce6167 100644
+--- a/drivers/mtd/nand/raw/tegra_nand.c
++++ b/drivers/mtd/nand/raw/tegra_nand.c
+@@ -1181,7 +1181,7 @@ static int tegra_nand_probe(struct platform_device *pdev)
+ 	pm_runtime_enable(&pdev->dev);
+ 	err = pm_runtime_resume_and_get(&pdev->dev);
+ 	if (err)
+-		return err;
++		goto err_dis_pm;
+ 
+ 	err = reset_control_reset(rst);
+ 	if (err) {
+@@ -1215,6 +1215,8 @@ static int tegra_nand_probe(struct platform_device *pdev)
+ err_put_pm:
+ 	pm_runtime_put_sync_suspend(ctrl->dev);
+ 	pm_runtime_force_suspend(ctrl->dev);
++err_dis_pm:
++	pm_runtime_disable(&pdev->dev);
+ 	return err;
+ }
+ 
+diff --git a/drivers/mtd/parsers/bcm47xxpart.c b/drivers/mtd/parsers/bcm47xxpart.c
+index 50fcf4c2174ba..13daf9bffd081 100644
+--- a/drivers/mtd/parsers/bcm47xxpart.c
++++ b/drivers/mtd/parsers/bcm47xxpart.c
+@@ -233,11 +233,11 @@ static int bcm47xxpart_parse(struct mtd_info *master,
+ 		}
+ 
+ 		/* Read middle of the block */
+-		err = mtd_read(master, offset + 0x8000, 0x4, &bytes_read,
++		err = mtd_read(master, offset + (blocksize / 2), 0x4, &bytes_read,
+ 			       (uint8_t *)buf);
+ 		if (err && !mtd_is_bitflip(err)) {
+ 			pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
+-			       offset + 0x8000, err);
++			       offset + (blocksize / 2), err);
+ 			continue;
+ 		}
+ 
+diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
+index f2c64006f8d75..bee8fc4c9f078 100644
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -2724,7 +2724,9 @@ static int spi_nor_init(struct spi_nor *nor)
+ 		 */
+ 		WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
+ 			  "enabling reset hack; may not recover from unexpected reboots\n");
+-		return nor->params->set_4byte_addr_mode(nor, true);
++		err = nor->params->set_4byte_addr_mode(nor, true);
++		if (err && err != -ENOTSUPP)
++			return err;
+ 	}
+ 
+ 	return 0;
+diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
+index c469b2f3e57d5..b0ed798ae70fe 100644
+--- a/drivers/net/can/mscan/mpc5xxx_can.c
++++ b/drivers/net/can/mscan/mpc5xxx_can.c
+@@ -322,14 +322,14 @@ static int mpc5xxx_can_probe(struct platform_device *ofdev)
+ 					       &mscan_clksrc);
+ 	if (!priv->can.clock.freq) {
+ 		dev_err(&ofdev->dev, "couldn't get MSCAN clock properties\n");
+-		goto exit_free_mscan;
++		goto exit_put_clock;
+ 	}
+ 
+ 	err = register_mscandev(dev, mscan_clksrc);
+ 	if (err) {
+ 		dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+ 			DRV_NAME, err);
+-		goto exit_free_mscan;
++		goto exit_put_clock;
+ 	}
+ 
+ 	dev_info(&ofdev->dev, "MSCAN at 0x%p, irq %d, clock %d Hz\n",
+@@ -337,7 +337,9 @@ static int mpc5xxx_can_probe(struct platform_device *ofdev)
+ 
+ 	return 0;
+ 
+-exit_free_mscan:
++exit_put_clock:
++	if (data->put_clock)
++		data->put_clock(ofdev);
+ 	free_candev(dev);
+ exit_dispose_irq:
+ 	irq_dispose_mapping(irq);
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
+index 27085b796e752..d77c8d6d191a6 100644
+--- a/drivers/net/can/rcar/rcar_canfd.c
++++ b/drivers/net/can/rcar/rcar_canfd.c
+@@ -1157,11 +1157,13 @@ static void rcar_canfd_handle_global_receive(struct rcar_canfd_global *gpriv, u3
+ {
+ 	struct rcar_canfd_channel *priv = gpriv->ch[ch];
+ 	u32 ridx = ch + RCANFD_RFFIFO_IDX;
+-	u32 sts;
++	u32 sts, cc;
+ 
+ 	/* Handle Rx interrupts */
+ 	sts = rcar_canfd_read(priv->base, RCANFD_RFSTS(gpriv, ridx));
+-	if (likely(sts & RCANFD_RFSTS_RFIF)) {
++	cc = rcar_canfd_read(priv->base, RCANFD_RFCC(gpriv, ridx));
++	if (likely(sts & RCANFD_RFSTS_RFIF &&
++		   cc & RCANFD_RFCC_RFIE)) {
+ 		if (napi_schedule_prep(&priv->napi)) {
+ 			/* Disable Rx FIFO interrupts */
+ 			rcar_canfd_clear_bit(priv->base,
+@@ -1244,11 +1246,9 @@ static void rcar_canfd_handle_channel_tx(struct rcar_canfd_global *gpriv, u32 ch
+ 
+ static irqreturn_t rcar_canfd_channel_tx_interrupt(int irq, void *dev_id)
+ {
+-	struct rcar_canfd_global *gpriv = dev_id;
+-	u32 ch;
++	struct rcar_canfd_channel *priv = dev_id;
+ 
+-	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels)
+-		rcar_canfd_handle_channel_tx(gpriv, ch);
++	rcar_canfd_handle_channel_tx(priv->gpriv, priv->channel);
+ 
+ 	return IRQ_HANDLED;
+ }
+@@ -1276,11 +1276,9 @@ static void rcar_canfd_handle_channel_err(struct rcar_canfd_global *gpriv, u32 c
+ 
+ static irqreturn_t rcar_canfd_channel_err_interrupt(int irq, void *dev_id)
+ {
+-	struct rcar_canfd_global *gpriv = dev_id;
+-	u32 ch;
++	struct rcar_canfd_channel *priv = dev_id;
+ 
+-	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels)
+-		rcar_canfd_handle_channel_err(gpriv, ch);
++	rcar_canfd_handle_channel_err(priv->gpriv, priv->channel);
+ 
+ 	return IRQ_HANDLED;
+ }
+@@ -1721,6 +1719,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
+ 	priv->ndev = ndev;
+ 	priv->base = gpriv->base;
+ 	priv->channel = ch;
++	priv->gpriv = gpriv;
+ 	priv->can.clock.freq = fcan_freq;
+ 	dev_info(&pdev->dev, "can_clk rate is %u\n", priv->can.clock.freq);
+ 
+@@ -1749,7 +1748,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
+ 		}
+ 		err = devm_request_irq(&pdev->dev, err_irq,
+ 				       rcar_canfd_channel_err_interrupt, 0,
+-				       irq_name, gpriv);
++				       irq_name, priv);
+ 		if (err) {
+ 			dev_err(&pdev->dev, "devm_request_irq CH Err(%d) failed, error %d\n",
+ 				err_irq, err);
+@@ -1763,7 +1762,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
+ 		}
+ 		err = devm_request_irq(&pdev->dev, tx_irq,
+ 				       rcar_canfd_channel_tx_interrupt, 0,
+-				       irq_name, gpriv);
++				       irq_name, priv);
+ 		if (err) {
+ 			dev_err(&pdev->dev, "devm_request_irq Tx (%d) failed, error %d\n",
+ 				tx_irq, err);
+@@ -1789,7 +1788,6 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
+ 
+ 	priv->can.do_set_mode = rcar_canfd_do_set_mode;
+ 	priv->can.do_get_berr_counter = rcar_canfd_get_berr_counter;
+-	priv->gpriv = gpriv;
+ 	SET_NETDEV_DEV(ndev, &pdev->dev);
+ 
+ 	netif_napi_add_weight(ndev, &priv->napi, rcar_canfd_rx_poll,
+diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c
+index c320de474f406..24883a65ca66a 100644
+--- a/drivers/net/can/spi/mcp251x.c
++++ b/drivers/net/can/spi/mcp251x.c
+@@ -1415,11 +1415,14 @@ static int mcp251x_can_probe(struct spi_device *spi)
+ 
+ 	ret = mcp251x_gpio_setup(priv);
+ 	if (ret)
+-		goto error_probe;
++		goto out_unregister_candev;
+ 
+ 	netdev_info(net, "MCP%x successfully initialized.\n", priv->model);
+ 	return 0;
+ 
++out_unregister_candev:
++	unregister_candev(net);
++
+ error_probe:
+ 	destroy_workqueue(priv->wq);
+ 	priv->wq = NULL;
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index 3dcd35979e6fd..3abfaa77e8935 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -1875,7 +1875,7 @@ static int kvaser_usb_hydra_start_chip(struct kvaser_usb_net_priv *priv)
+ {
+ 	int err;
+ 
+-	init_completion(&priv->start_comp);
++	reinit_completion(&priv->start_comp);
+ 
+ 	err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_START_CHIP_REQ,
+ 					       priv->channel);
+@@ -1893,7 +1893,7 @@ static int kvaser_usb_hydra_stop_chip(struct kvaser_usb_net_priv *priv)
+ {
+ 	int err;
+ 
+-	init_completion(&priv->stop_comp);
++	reinit_completion(&priv->stop_comp);
+ 
+ 	/* Make sure we do not report invalid BUS_OFF from CMD_CHIP_STATE_EVENT
+ 	 * see comment in kvaser_usb_hydra_update_state()
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 50f2ac8319ff8..19958037720f4 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -1320,7 +1320,7 @@ static int kvaser_usb_leaf_start_chip(struct kvaser_usb_net_priv *priv)
+ {
+ 	int err;
+ 
+-	init_completion(&priv->start_comp);
++	reinit_completion(&priv->start_comp);
+ 
+ 	err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_START_CHIP,
+ 					      priv->channel);
+@@ -1338,7 +1338,7 @@ static int kvaser_usb_leaf_stop_chip(struct kvaser_usb_net_priv *priv)
+ {
+ 	int err;
+ 
+-	init_completion(&priv->stop_comp);
++	reinit_completion(&priv->stop_comp);
+ 
+ 	err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP,
+ 					      priv->channel);
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
+index 2af3da4b2d053..f409d7bd1f1ee 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
+@@ -285,6 +285,9 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ 
+ 		/* Yellow Carp devices do not need cdr workaround */
+ 		pdata->vdata->an_cdr_workaround = 0;
++
++		/* Yellow Carp devices do not need rrc */
++		pdata->vdata->enable_rrc = 0;
+ 	} else {
+ 		pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
+ 		pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
+@@ -483,6 +486,7 @@ static struct xgbe_version_data xgbe_v2a = {
+ 	.tx_desc_prefetch		= 5,
+ 	.rx_desc_prefetch		= 5,
+ 	.an_cdr_workaround		= 1,
++	.enable_rrc			= 1,
+ };
+ 
+ static struct xgbe_version_data xgbe_v2b = {
+@@ -498,6 +502,7 @@ static struct xgbe_version_data xgbe_v2b = {
+ 	.tx_desc_prefetch		= 5,
+ 	.rx_desc_prefetch		= 5,
+ 	.an_cdr_workaround		= 1,
++	.enable_rrc			= 1,
+ };
+ 
+ static const struct pci_device_id xgbe_pci_table[] = {
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+index 2156600641b6c..601a9f2fa9bfc 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+@@ -239,6 +239,7 @@ enum xgbe_sfp_speed {
+ #define XGBE_SFP_BASE_BR_1GBE_MAX		0x0d
+ #define XGBE_SFP_BASE_BR_10GBE_MIN		0x64
+ #define XGBE_SFP_BASE_BR_10GBE_MAX		0x68
++#define XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX	0x78
+ 
+ #define XGBE_SFP_BASE_CU_CABLE_LEN		18
+ 
+@@ -284,6 +285,8 @@ struct xgbe_sfp_eeprom {
+ #define XGBE_BEL_FUSE_VENDOR	"BEL-FUSE        "
+ #define XGBE_BEL_FUSE_PARTNO	"1GBT-SFP06      "
+ 
++#define XGBE_MOLEX_VENDOR	"Molex Inc.      "
++
+ struct xgbe_sfp_ascii {
+ 	union {
+ 		char vendor[XGBE_SFP_BASE_VENDOR_NAME_LEN + 1];
+@@ -834,7 +837,11 @@ static bool xgbe_phy_sfp_bit_rate(struct xgbe_sfp_eeprom *sfp_eeprom,
+ 		break;
+ 	case XGBE_SFP_SPEED_10000:
+ 		min = XGBE_SFP_BASE_BR_10GBE_MIN;
+-		max = XGBE_SFP_BASE_BR_10GBE_MAX;
++		if (memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME],
++			   XGBE_MOLEX_VENDOR, XGBE_SFP_BASE_VENDOR_NAME_LEN) == 0)
++			max = XGBE_MOLEX_SFP_BASE_BR_10GBE_MAX;
++		else
++			max = XGBE_SFP_BASE_BR_10GBE_MAX;
+ 		break;
+ 	default:
+ 		return false;
+@@ -1151,7 +1158,10 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
+ 	}
+ 
+ 	/* Determine the type of SFP */
+-	if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR)
++	if (phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE &&
++	    xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000))
++		phy_data->sfp_base = XGBE_SFP_BASE_10000_CR;
++	else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR)
+ 		phy_data->sfp_base = XGBE_SFP_BASE_10000_SR;
+ 	else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_LR)
+ 		phy_data->sfp_base = XGBE_SFP_BASE_10000_LR;
+@@ -1167,9 +1177,6 @@ static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
+ 		phy_data->sfp_base = XGBE_SFP_BASE_1000_CX;
+ 	else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_T)
+ 		phy_data->sfp_base = XGBE_SFP_BASE_1000_T;
+-	else if ((phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE) &&
+-		 xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000))
+-		phy_data->sfp_base = XGBE_SFP_BASE_10000_CR;
+ 
+ 	switch (phy_data->sfp_base) {
+ 	case XGBE_SFP_BASE_1000_T:
+@@ -2640,7 +2647,7 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
+ 	}
+ 
+ 	/* No link, attempt a receiver reset cycle */
+-	if (phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) {
++	if (pdata->vdata->enable_rrc && phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) {
+ 		phy_data->rrc_count = 0;
+ 		xgbe_phy_rrc(pdata);
+ 	}
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
+index b875c430222e5..49d23abce73d2 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
++++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
+@@ -1013,6 +1013,7 @@ struct xgbe_version_data {
+ 	unsigned int tx_desc_prefetch;
+ 	unsigned int rx_desc_prefetch;
+ 	unsigned int an_cdr_workaround;
++	unsigned int enable_rrc;
+ };
+ 
+ struct xgbe_prv_data {
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
+index 02058fe79f52b..8b53d6688a4bd 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c
+@@ -1451,26 +1451,57 @@ static void aq_check_txsa_expiration(struct aq_nic_s *nic)
+ 			egress_sa_threshold_expired);
+ }
+ 
++#define AQ_LOCKED_MDO_DEF(mdo)						\
++static int aq_locked_mdo_##mdo(struct macsec_context *ctx)		\
++{									\
++	struct aq_nic_s *nic = netdev_priv(ctx->netdev);		\
++	int ret;							\
++	mutex_lock(&nic->macsec_mutex);					\
++	ret = aq_mdo_##mdo(ctx);					\
++	mutex_unlock(&nic->macsec_mutex);				\
++	return ret;							\
++}
++
++AQ_LOCKED_MDO_DEF(dev_open)
++AQ_LOCKED_MDO_DEF(dev_stop)
++AQ_LOCKED_MDO_DEF(add_secy)
++AQ_LOCKED_MDO_DEF(upd_secy)
++AQ_LOCKED_MDO_DEF(del_secy)
++AQ_LOCKED_MDO_DEF(add_rxsc)
++AQ_LOCKED_MDO_DEF(upd_rxsc)
++AQ_LOCKED_MDO_DEF(del_rxsc)
++AQ_LOCKED_MDO_DEF(add_rxsa)
++AQ_LOCKED_MDO_DEF(upd_rxsa)
++AQ_LOCKED_MDO_DEF(del_rxsa)
++AQ_LOCKED_MDO_DEF(add_txsa)
++AQ_LOCKED_MDO_DEF(upd_txsa)
++AQ_LOCKED_MDO_DEF(del_txsa)
++AQ_LOCKED_MDO_DEF(get_dev_stats)
++AQ_LOCKED_MDO_DEF(get_tx_sc_stats)
++AQ_LOCKED_MDO_DEF(get_tx_sa_stats)
++AQ_LOCKED_MDO_DEF(get_rx_sc_stats)
++AQ_LOCKED_MDO_DEF(get_rx_sa_stats)
++
+ const struct macsec_ops aq_macsec_ops = {
+-	.mdo_dev_open = aq_mdo_dev_open,
+-	.mdo_dev_stop = aq_mdo_dev_stop,
+-	.mdo_add_secy = aq_mdo_add_secy,
+-	.mdo_upd_secy = aq_mdo_upd_secy,
+-	.mdo_del_secy = aq_mdo_del_secy,
+-	.mdo_add_rxsc = aq_mdo_add_rxsc,
+-	.mdo_upd_rxsc = aq_mdo_upd_rxsc,
+-	.mdo_del_rxsc = aq_mdo_del_rxsc,
+-	.mdo_add_rxsa = aq_mdo_add_rxsa,
+-	.mdo_upd_rxsa = aq_mdo_upd_rxsa,
+-	.mdo_del_rxsa = aq_mdo_del_rxsa,
+-	.mdo_add_txsa = aq_mdo_add_txsa,
+-	.mdo_upd_txsa = aq_mdo_upd_txsa,
+-	.mdo_del_txsa = aq_mdo_del_txsa,
+-	.mdo_get_dev_stats = aq_mdo_get_dev_stats,
+-	.mdo_get_tx_sc_stats = aq_mdo_get_tx_sc_stats,
+-	.mdo_get_tx_sa_stats = aq_mdo_get_tx_sa_stats,
+-	.mdo_get_rx_sc_stats = aq_mdo_get_rx_sc_stats,
+-	.mdo_get_rx_sa_stats = aq_mdo_get_rx_sa_stats,
++	.mdo_dev_open = aq_locked_mdo_dev_open,
++	.mdo_dev_stop = aq_locked_mdo_dev_stop,
++	.mdo_add_secy = aq_locked_mdo_add_secy,
++	.mdo_upd_secy = aq_locked_mdo_upd_secy,
++	.mdo_del_secy = aq_locked_mdo_del_secy,
++	.mdo_add_rxsc = aq_locked_mdo_add_rxsc,
++	.mdo_upd_rxsc = aq_locked_mdo_upd_rxsc,
++	.mdo_del_rxsc = aq_locked_mdo_del_rxsc,
++	.mdo_add_rxsa = aq_locked_mdo_add_rxsa,
++	.mdo_upd_rxsa = aq_locked_mdo_upd_rxsa,
++	.mdo_del_rxsa = aq_locked_mdo_del_rxsa,
++	.mdo_add_txsa = aq_locked_mdo_add_txsa,
++	.mdo_upd_txsa = aq_locked_mdo_upd_txsa,
++	.mdo_del_txsa = aq_locked_mdo_del_txsa,
++	.mdo_get_dev_stats = aq_locked_mdo_get_dev_stats,
++	.mdo_get_tx_sc_stats = aq_locked_mdo_get_tx_sc_stats,
++	.mdo_get_tx_sa_stats = aq_locked_mdo_get_tx_sa_stats,
++	.mdo_get_rx_sc_stats = aq_locked_mdo_get_rx_sc_stats,
++	.mdo_get_rx_sa_stats = aq_locked_mdo_get_rx_sa_stats,
+ };
+ 
+ int aq_macsec_init(struct aq_nic_s *nic)
+@@ -1492,6 +1523,7 @@ int aq_macsec_init(struct aq_nic_s *nic)
+ 
+ 	nic->ndev->features |= NETIF_F_HW_MACSEC;
+ 	nic->ndev->macsec_ops = &aq_macsec_ops;
++	mutex_init(&nic->macsec_mutex);
+ 
+ 	return 0;
+ }
+@@ -1515,7 +1547,7 @@ int aq_macsec_enable(struct aq_nic_s *nic)
+ 	if (!nic->macsec_cfg)
+ 		return 0;
+ 
+-	rtnl_lock();
++	mutex_lock(&nic->macsec_mutex);
+ 
+ 	if (nic->aq_fw_ops->send_macsec_req) {
+ 		struct macsec_cfg_request cfg = { 0 };
+@@ -1564,7 +1596,7 @@ int aq_macsec_enable(struct aq_nic_s *nic)
+ 	ret = aq_apply_macsec_cfg(nic);
+ 
+ unlock:
+-	rtnl_unlock();
++	mutex_unlock(&nic->macsec_mutex);
+ 	return ret;
+ }
+ 
+@@ -1576,9 +1608,9 @@ void aq_macsec_work(struct aq_nic_s *nic)
+ 	if (!netif_carrier_ok(nic->ndev))
+ 		return;
+ 
+-	rtnl_lock();
++	mutex_lock(&nic->macsec_mutex);
+ 	aq_check_txsa_expiration(nic);
+-	rtnl_unlock();
++	mutex_unlock(&nic->macsec_mutex);
+ }
+ 
+ int aq_macsec_rx_sa_cnt(struct aq_nic_s *nic)
+@@ -1589,21 +1621,30 @@ int aq_macsec_rx_sa_cnt(struct aq_nic_s *nic)
+ 	if (!cfg)
+ 		return 0;
+ 
++	mutex_lock(&nic->macsec_mutex);
++
+ 	for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
+ 		if (!test_bit(i, &cfg->rxsc_idx_busy))
+ 			continue;
+ 		cnt += hweight_long(cfg->aq_rxsc[i].rx_sa_idx_busy);
+ 	}
+ 
++	mutex_unlock(&nic->macsec_mutex);
+ 	return cnt;
+ }
+ 
+ int aq_macsec_tx_sc_cnt(struct aq_nic_s *nic)
+ {
++	int cnt;
++
+ 	if (!nic->macsec_cfg)
+ 		return 0;
+ 
+-	return hweight_long(nic->macsec_cfg->txsc_idx_busy);
++	mutex_lock(&nic->macsec_mutex);
++	cnt = hweight_long(nic->macsec_cfg->txsc_idx_busy);
++	mutex_unlock(&nic->macsec_mutex);
++
++	return cnt;
+ }
+ 
+ int aq_macsec_tx_sa_cnt(struct aq_nic_s *nic)
+@@ -1614,12 +1655,15 @@ int aq_macsec_tx_sa_cnt(struct aq_nic_s *nic)
+ 	if (!cfg)
+ 		return 0;
+ 
++	mutex_lock(&nic->macsec_mutex);
++
+ 	for (i = 0; i < AQ_MACSEC_MAX_SC; i++) {
+ 		if (!test_bit(i, &cfg->txsc_idx_busy))
+ 			continue;
+ 		cnt += hweight_long(cfg->aq_txsc[i].tx_sa_idx_busy);
+ 	}
+ 
++	mutex_unlock(&nic->macsec_mutex);
+ 	return cnt;
+ }
+ 
+@@ -1691,6 +1735,8 @@ u64 *aq_macsec_get_stats(struct aq_nic_s *nic, u64 *data)
+ 	if (!cfg)
+ 		return data;
+ 
++	mutex_lock(&nic->macsec_mutex);
++
+ 	aq_macsec_update_stats(nic);
+ 
+ 	common_stats = &cfg->stats;
+@@ -1773,5 +1819,7 @@ u64 *aq_macsec_get_stats(struct aq_nic_s *nic, u64 *data)
+ 
+ 	data += i;
+ 
++	mutex_unlock(&nic->macsec_mutex);
++
+ 	return data;
+ }
+diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
+index 935ba889bd9a8..ad33f8586532b 100644
+--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
++++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
+@@ -157,6 +157,8 @@ struct aq_nic_s {
+ 	struct mutex fwreq_mutex;
+ #if IS_ENABLED(CONFIG_MACSEC)
+ 	struct aq_macsec_cfg *macsec_cfg;
++	/* mutex to protect data in macsec_cfg */
++	struct mutex macsec_mutex;
+ #endif
+ 	/* PTP support */
+ 	struct aq_ptp_s *aq_ptp;
+diff --git a/drivers/net/ethernet/broadcom/bcm4908_enet.c b/drivers/net/ethernet/broadcom/bcm4908_enet.c
+index c131d81184893..5ec429663f4c2 100644
+--- a/drivers/net/ethernet/broadcom/bcm4908_enet.c
++++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c
+@@ -561,8 +561,6 @@ static int bcm4908_enet_start_xmit(struct sk_buff *skb, struct net_device *netde
+ 
+ 	if (++ring->write_idx == ring->length - 1)
+ 		ring->write_idx = 0;
+-	enet->netdev->stats.tx_bytes += skb->len;
+-	enet->netdev->stats.tx_packets++;
+ 
+ 	return NETDEV_TX_OK;
+ }
+@@ -635,6 +633,7 @@ static int bcm4908_enet_poll_tx(struct napi_struct *napi, int weight)
+ 	struct bcm4908_enet_dma_ring_bd *buf_desc;
+ 	struct bcm4908_enet_dma_ring_slot *slot;
+ 	struct device *dev = enet->dev;
++	unsigned int bytes = 0;
+ 	int handled = 0;
+ 
+ 	while (handled < weight && tx_ring->read_idx != tx_ring->write_idx) {
+@@ -645,12 +644,17 @@ static int bcm4908_enet_poll_tx(struct napi_struct *napi, int weight)
+ 
+ 		dma_unmap_single(dev, slot->dma_addr, slot->len, DMA_TO_DEVICE);
+ 		dev_kfree_skb(slot->skb);
+-		if (++tx_ring->read_idx == tx_ring->length)
+-			tx_ring->read_idx = 0;
+ 
+ 		handled++;
++		bytes += slot->len;
++
++		if (++tx_ring->read_idx == tx_ring->length)
++			tx_ring->read_idx = 0;
+ 	}
+ 
++	enet->netdev->stats.tx_packets += handled;
++	enet->netdev->stats.tx_bytes += bytes;
++
+ 	if (handled < weight) {
+ 		napi_complete_done(napi, handled);
+ 		bcm4908_enet_dma_ring_intrs_on(enet, tx_ring);
+diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
+index 47fc8e6963d59..2f01d4b0a9aa1 100644
+--- a/drivers/net/ethernet/broadcom/bcmsysport.c
++++ b/drivers/net/ethernet/broadcom/bcmsysport.c
+@@ -1991,6 +1991,9 @@ static int bcm_sysport_open(struct net_device *dev)
+ 		goto out_clk_disable;
+ 	}
+ 
++	/* Indicate that the MAC is responsible for PHY PM */
++	phydev->mac_managed_pm = true;
++
+ 	/* Reset house keeping link status */
+ 	priv->old_duplex = -1;
+ 	priv->old_link = -1;
+diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
+index a2897549f9c4d..aa1b03f8bfe91 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -805,6 +805,7 @@ static int macb_mii_probe(struct net_device *dev)
+ 
+ 	bp->phylink_config.dev = &dev->dev;
+ 	bp->phylink_config.type = PHYLINK_NETDEV;
++	bp->phylink_config.mac_managed_pm = true;
+ 
+ 	if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+ 		bp->phylink_config.poll_fixed_state = true;
+diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
+index 9f5b921039bd4..d0fd3045ce111 100644
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -2090,7 +2090,12 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
+ 	else
+ 		enetc_rxbdr_wr(hw, idx, ENETC_RBBSR, ENETC_RXB_DMA_SIZE);
+ 
++	/* Also prepare the consumer index in case page allocation never
++	 * succeeds. In that case, hardware will never advance producer index
++	 * to match consumer index, and will drop all frames.
++	 */
+ 	enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0);
++	enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, 1);
+ 
+ 	/* enable Rx ints by setting pkt thr to 1 */
+ 	enetc_rxbdr_wr(hw, idx, ENETC_RBICR0, ENETC_RBICR0_ICEN | 0x1);
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index 92c55e1a55076..a486435ceee2c 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -2347,6 +2347,31 @@ static u32 fec_enet_register_offset[] = {
+ 	IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR,
+ 	IEEE_R_FDXFC, IEEE_R_OCTETS_OK
+ };
++/* for i.MX6ul */
++static u32 fec_enet_register_offset_6ul[] = {
++	FEC_IEVENT, FEC_IMASK, FEC_R_DES_ACTIVE_0, FEC_X_DES_ACTIVE_0,
++	FEC_ECNTRL, FEC_MII_DATA, FEC_MII_SPEED, FEC_MIB_CTRLSTAT, FEC_R_CNTRL,
++	FEC_X_CNTRL, FEC_ADDR_LOW, FEC_ADDR_HIGH, FEC_OPD, FEC_TXIC0, FEC_RXIC0,
++	FEC_HASH_TABLE_HIGH, FEC_HASH_TABLE_LOW, FEC_GRP_HASH_TABLE_HIGH,
++	FEC_GRP_HASH_TABLE_LOW, FEC_X_WMRK, FEC_R_DES_START_0,
++	FEC_X_DES_START_0, FEC_R_BUFF_SIZE_0, FEC_R_FIFO_RSFL, FEC_R_FIFO_RSEM,
++	FEC_R_FIFO_RAEM, FEC_R_FIFO_RAFL, FEC_RACC,
++	RMON_T_DROP, RMON_T_PACKETS, RMON_T_BC_PKT, RMON_T_MC_PKT,
++	RMON_T_CRC_ALIGN, RMON_T_UNDERSIZE, RMON_T_OVERSIZE, RMON_T_FRAG,
++	RMON_T_JAB, RMON_T_COL, RMON_T_P64, RMON_T_P65TO127, RMON_T_P128TO255,
++	RMON_T_P256TO511, RMON_T_P512TO1023, RMON_T_P1024TO2047,
++	RMON_T_P_GTE2048, RMON_T_OCTETS,
++	IEEE_T_DROP, IEEE_T_FRAME_OK, IEEE_T_1COL, IEEE_T_MCOL, IEEE_T_DEF,
++	IEEE_T_LCOL, IEEE_T_EXCOL, IEEE_T_MACERR, IEEE_T_CSERR, IEEE_T_SQE,
++	IEEE_T_FDXFC, IEEE_T_OCTETS_OK,
++	RMON_R_PACKETS, RMON_R_BC_PKT, RMON_R_MC_PKT, RMON_R_CRC_ALIGN,
++	RMON_R_UNDERSIZE, RMON_R_OVERSIZE, RMON_R_FRAG, RMON_R_JAB,
++	RMON_R_RESVD_O, RMON_R_P64, RMON_R_P65TO127, RMON_R_P128TO255,
++	RMON_R_P256TO511, RMON_R_P512TO1023, RMON_R_P1024TO2047,
++	RMON_R_P_GTE2048, RMON_R_OCTETS,
++	IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR,
++	IEEE_R_FDXFC, IEEE_R_OCTETS_OK
++};
+ #else
+ static __u32 fec_enet_register_version = 1;
+ static u32 fec_enet_register_offset[] = {
+@@ -2371,7 +2396,24 @@ static void fec_enet_get_regs(struct net_device *ndev,
+ 	u32 *buf = (u32 *)regbuf;
+ 	u32 i, off;
+ 	int ret;
++#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
++	defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \
++	defined(CONFIG_ARM64) || defined(CONFIG_COMPILE_TEST)
++	u32 *reg_list;
++	u32 reg_cnt;
+ 
++	if (!of_machine_is_compatible("fsl,imx6ul")) {
++		reg_list = fec_enet_register_offset;
++		reg_cnt = ARRAY_SIZE(fec_enet_register_offset);
++	} else {
++		reg_list = fec_enet_register_offset_6ul;
++		reg_cnt = ARRAY_SIZE(fec_enet_register_offset_6ul);
++	}
++#else
++	/* coldfire */
++	static u32 *reg_list = fec_enet_register_offset;
++	static const u32 reg_cnt = ARRAY_SIZE(fec_enet_register_offset);
++#endif
+ 	ret = pm_runtime_resume_and_get(dev);
+ 	if (ret < 0)
+ 		return;
+@@ -2380,8 +2422,8 @@ static void fec_enet_get_regs(struct net_device *ndev,
+ 
+ 	memset(buf, 0, regs->len);
+ 
+-	for (i = 0; i < ARRAY_SIZE(fec_enet_register_offset); i++) {
+-		off = fec_enet_register_offset[i];
++	for (i = 0; i < reg_cnt; i++) {
++		off = reg_list[i];
+ 
+ 		if ((off == FEC_R_BOUND || off == FEC_R_FSTART) &&
+ 		    !(fep->quirks & FEC_QUIRK_HAS_FRREG))
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c b/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c
+index 19eb839177ec2..061952c6c21a4 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c
+@@ -85,6 +85,7 @@ static int hinic_dbg_get_func_table(struct hinic_dev *nic_dev, int idx)
+ 	struct tag_sml_funcfg_tbl *funcfg_table_elem;
+ 	struct hinic_cmd_lt_rd *read_data;
+ 	u16 out_size = sizeof(*read_data);
++	int ret = ~0;
+ 	int err;
+ 
+ 	read_data = kzalloc(sizeof(*read_data), GFP_KERNEL);
+@@ -111,20 +112,25 @@ static int hinic_dbg_get_func_table(struct hinic_dev *nic_dev, int idx)
+ 
+ 	switch (idx) {
+ 	case VALID:
+-		return funcfg_table_elem->dw0.bs.valid;
++		ret = funcfg_table_elem->dw0.bs.valid;
++		break;
+ 	case RX_MODE:
+-		return funcfg_table_elem->dw0.bs.nic_rx_mode;
++		ret = funcfg_table_elem->dw0.bs.nic_rx_mode;
++		break;
+ 	case MTU:
+-		return funcfg_table_elem->dw1.bs.mtu;
++		ret = funcfg_table_elem->dw1.bs.mtu;
++		break;
+ 	case RQ_DEPTH:
+-		return funcfg_table_elem->dw13.bs.cfg_rq_depth;
++		ret = funcfg_table_elem->dw13.bs.cfg_rq_depth;
++		break;
+ 	case QUEUE_NUM:
+-		return funcfg_table_elem->dw13.bs.cfg_q_num;
++		ret = funcfg_table_elem->dw13.bs.cfg_q_num;
++		break;
+ 	}
+ 
+ 	kfree(read_data);
+ 
+-	return ~0;
++	return ret;
+ }
+ 
+ static ssize_t hinic_dbg_cmd_read(struct file *filp, char __user *buffer, size_t count,
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
+index a627237f694bb..afa816cfcdf4a 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
+@@ -929,7 +929,7 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,
+ 
+ err_set_cmdq_depth:
+ 	hinic_ceq_unregister_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ);
+-
++	free_cmdq(&cmdqs->cmdq[HINIC_CMDQ_SYNC]);
+ err_cmdq_ctxt:
+ 	hinic_wqs_cmdq_free(&cmdqs->cmdq_pages, cmdqs->saved_wqs,
+ 			    HINIC_MAX_CMDQ_TYPES);
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
+index 2127a48749a8c..1cd812c566724 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
+@@ -883,7 +883,7 @@ int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev,
+ 	if (err)
+ 		return -EINVAL;
+ 
+-	interrupt_info->lli_credit_cnt = temp_info.lli_timer_cnt;
++	interrupt_info->lli_credit_cnt = temp_info.lli_credit_cnt;
+ 	interrupt_info->lli_timer_cnt = temp_info.lli_timer_cnt;
+ 
+ 	err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
+diff --git a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
+index df555847afb56..61c1da0c52a0b 100644
+--- a/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
++++ b/drivers/net/ethernet/huawei/hinic/hinic_sriov.c
+@@ -1175,7 +1175,6 @@ int hinic_vf_func_init(struct hinic_hwdev *hwdev)
+ 			dev_err(&hwdev->hwif->pdev->dev,
+ 				"Failed to register VF, err: %d, status: 0x%x, out size: 0x%x\n",
+ 				err, register_info.status, out_size);
+-			hinic_unregister_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC);
+ 			return -EIO;
+ 		}
+ 	} else {
+diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c
+index 5dc302880f5f6..acecf25a60413 100644
+--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c
++++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c
+@@ -2900,6 +2900,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
+ 	ret = of_device_register(&port->ofdev);
+ 	if (ret) {
+ 		pr_err("failed to register device. ret=%d\n", ret);
++		put_device(&port->ofdev.dev);
+ 		goto out;
+ 	}
+ 
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+index af5fe84db5961..6f0d4160ff82f 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+@@ -3185,10 +3185,17 @@ static int i40e_get_rss_hash_opts(struct i40e_pf *pf, struct ethtool_rxnfc *cmd)
+ 
+ 		if (cmd->flow_type == TCP_V4_FLOW ||
+ 		    cmd->flow_type == UDP_V4_FLOW) {
+-			if (i_set & I40E_L3_SRC_MASK)
+-				cmd->data |= RXH_IP_SRC;
+-			if (i_set & I40E_L3_DST_MASK)
+-				cmd->data |= RXH_IP_DST;
++			if (hw->mac.type == I40E_MAC_X722) {
++				if (i_set & I40E_X722_L3_SRC_MASK)
++					cmd->data |= RXH_IP_SRC;
++				if (i_set & I40E_X722_L3_DST_MASK)
++					cmd->data |= RXH_IP_DST;
++			} else {
++				if (i_set & I40E_L3_SRC_MASK)
++					cmd->data |= RXH_IP_SRC;
++				if (i_set & I40E_L3_DST_MASK)
++					cmd->data |= RXH_IP_DST;
++			}
+ 		} else if (cmd->flow_type == TCP_V6_FLOW ||
+ 			  cmd->flow_type == UDP_V6_FLOW) {
+ 			if (i_set & I40E_L3_V6_SRC_MASK)
+@@ -3546,12 +3553,15 @@ static int i40e_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
+ 
+ /**
+  * i40e_get_rss_hash_bits - Read RSS Hash bits from register
++ * @hw: hw structure
+  * @nfc: pointer to user request
+  * @i_setc: bits currently set
+  *
+  * Returns value of bits to be set per user request
+  **/
+-static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
++static u64 i40e_get_rss_hash_bits(struct i40e_hw *hw,
++				  struct ethtool_rxnfc *nfc,
++				  u64 i_setc)
+ {
+ 	u64 i_set = i_setc;
+ 	u64 src_l3 = 0, dst_l3 = 0;
+@@ -3570,8 +3580,13 @@ static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
+ 		dst_l3 = I40E_L3_V6_DST_MASK;
+ 	} else if (nfc->flow_type == TCP_V4_FLOW ||
+ 		  nfc->flow_type == UDP_V4_FLOW) {
+-		src_l3 = I40E_L3_SRC_MASK;
+-		dst_l3 = I40E_L3_DST_MASK;
++		if (hw->mac.type == I40E_MAC_X722) {
++			src_l3 = I40E_X722_L3_SRC_MASK;
++			dst_l3 = I40E_X722_L3_DST_MASK;
++		} else {
++			src_l3 = I40E_L3_SRC_MASK;
++			dst_l3 = I40E_L3_DST_MASK;
++		}
+ 	} else {
+ 		/* Any other flow type are not supported here */
+ 		return i_set;
+@@ -3589,6 +3604,7 @@ static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc)
+ 	return i_set;
+ }
+ 
++#define FLOW_PCTYPES_SIZE 64
+ /**
+  * i40e_set_rss_hash_opt - Enable/Disable flow types for RSS hash
+  * @pf: pointer to the physical function struct
+@@ -3601,9 +3617,11 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
+ 	struct i40e_hw *hw = &pf->hw;
+ 	u64 hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) |
+ 		   ((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32);
+-	u8 flow_pctype = 0;
++	DECLARE_BITMAP(flow_pctypes, FLOW_PCTYPES_SIZE);
+ 	u64 i_set, i_setc;
+ 
++	bitmap_zero(flow_pctypes, FLOW_PCTYPES_SIZE);
++
+ 	if (pf->flags & I40E_FLAG_MFP_ENABLED) {
+ 		dev_err(&pf->pdev->dev,
+ 			"Change of RSS hash input set is not supported when MFP mode is enabled\n");
+@@ -3619,36 +3637,35 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
+ 
+ 	switch (nfc->flow_type) {
+ 	case TCP_V4_FLOW:
+-		flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
++		set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, flow_pctypes);
+ 		if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+-			hena |=
+-			  BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
++			set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK,
++				flow_pctypes);
+ 		break;
+ 	case TCP_V6_FLOW:
+-		flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
+-		if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+-			hena |=
+-			  BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK);
++		set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, flow_pctypes);
+ 		if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+-			hena |=
+-			  BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK);
++			set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK,
++				flow_pctypes);
+ 		break;
+ 	case UDP_V4_FLOW:
+-		flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
+-		if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+-			hena |=
+-			  BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) |
+-			  BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP);
+-
++		set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, flow_pctypes);
++		if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
++			set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP,
++				flow_pctypes);
++			set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP,
++				flow_pctypes);
++		}
+ 		hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4);
+ 		break;
+ 	case UDP_V6_FLOW:
+-		flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
+-		if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE)
+-			hena |=
+-			  BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) |
+-			  BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP);
+-
++		set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, flow_pctypes);
++		if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) {
++			set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP,
++				flow_pctypes);
++			set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP,
++				flow_pctypes);
++		}
+ 		hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6);
+ 		break;
+ 	case AH_ESP_V4_FLOW:
+@@ -3681,17 +3698,20 @@ static int i40e_set_rss_hash_opt(struct i40e_pf *pf, struct ethtool_rxnfc *nfc)
+ 		return -EINVAL;
+ 	}
+ 
+-	if (flow_pctype) {
+-		i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0,
+-					       flow_pctype)) |
+-			((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1,
+-					       flow_pctype)) << 32);
+-		i_set = i40e_get_rss_hash_bits(nfc, i_setc);
+-		i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_pctype),
+-				  (u32)i_set);
+-		i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_pctype),
+-				  (u32)(i_set >> 32));
+-		hena |= BIT_ULL(flow_pctype);
++	if (bitmap_weight(flow_pctypes, FLOW_PCTYPES_SIZE)) {
++		u8 flow_id;
++
++		for_each_set_bit(flow_id, flow_pctypes, FLOW_PCTYPES_SIZE) {
++			i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id)) |
++				 ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id)) << 32);
++			i_set = i40e_get_rss_hash_bits(&pf->hw, nfc, i_setc);
++
++			i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id),
++					  (u32)i_set);
++			i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id),
++					  (u32)(i_set >> 32));
++			hena |= BIT_ULL(flow_id);
++		}
+ 	}
+ 
+ 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
+index 7b3f30beb757a..388c3d36d96a5 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
+@@ -1404,6 +1404,10 @@ struct i40e_lldp_variables {
+ #define I40E_PFQF_CTL_0_HASHLUTSIZE_512	0x00010000
+ 
+ /* INPUT SET MASK for RSS, flow director, and flexible payload */
++#define I40E_X722_L3_SRC_SHIFT		49
++#define I40E_X722_L3_SRC_MASK		(0x3ULL << I40E_X722_L3_SRC_SHIFT)
++#define I40E_X722_L3_DST_SHIFT		41
++#define I40E_X722_L3_DST_MASK		(0x3ULL << I40E_X722_L3_DST_SHIFT)
+ #define I40E_L3_SRC_SHIFT		47
+ #define I40E_L3_SRC_MASK		(0x3ULL << I40E_L3_SRC_SHIFT)
+ #define I40E_L3_V6_SRC_SHIFT		43
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+index 7e9f6a69eb10c..72ddcefc45b1e 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+@@ -1536,10 +1536,12 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
+ 	if (test_bit(__I40E_VF_RESETS_DISABLED, pf->state))
+ 		return true;
+ 
+-	/* If the VFs have been disabled, this means something else is
+-	 * resetting the VF, so we shouldn't continue.
+-	 */
+-	if (test_and_set_bit(__I40E_VF_DISABLE, pf->state))
++	/* Bail out if VFs are disabled. */
++	if (test_bit(__I40E_VF_DISABLE, pf->state))
++		return true;
++
++	/* If VF is being reset already we don't need to continue. */
++	if (test_and_set_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
+ 		return true;
+ 
+ 	i40e_trigger_vf_reset(vf, flr);
+@@ -1576,7 +1578,7 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
+ 	i40e_cleanup_reset_vf(vf);
+ 
+ 	i40e_flush(hw);
+-	clear_bit(__I40E_VF_DISABLE, pf->state);
++	clear_bit(I40E_VF_STATE_RESETTING, &vf->vf_states);
+ 
+ 	return true;
+ }
+@@ -1609,8 +1611,12 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
+ 		return false;
+ 
+ 	/* Begin reset on all VFs at once */
+-	for (v = 0; v < pf->num_alloc_vfs; v++)
+-		i40e_trigger_vf_reset(&pf->vf[v], flr);
++	for (v = 0; v < pf->num_alloc_vfs; v++) {
++		vf = &pf->vf[v];
++		/* If VF is being reset no need to trigger reset again */
++		if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
++			i40e_trigger_vf_reset(&pf->vf[v], flr);
++	}
+ 
+ 	/* HW requires some time to make sure it can flush the FIFO for a VF
+ 	 * when it resets it. Poll the VPGEN_VFRSTAT register for each VF in
+@@ -1626,9 +1632,11 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
+ 		 */
+ 		while (v < pf->num_alloc_vfs) {
+ 			vf = &pf->vf[v];
+-			reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
+-			if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK))
+-				break;
++			if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) {
++				reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
++				if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK))
++					break;
++			}
+ 
+ 			/* If the current VF has finished resetting, move on
+ 			 * to the next VF in sequence.
+@@ -1656,6 +1664,10 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
+ 		if (pf->vf[v].lan_vsi_idx == 0)
+ 			continue;
+ 
++		/* If VF is reset in another thread just continue */
++		if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
++			continue;
++
+ 		i40e_vsi_stop_rings_no_wait(pf->vsi[pf->vf[v].lan_vsi_idx]);
+ 	}
+ 
+@@ -1667,6 +1679,10 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
+ 		if (pf->vf[v].lan_vsi_idx == 0)
+ 			continue;
+ 
++		/* If VF is reset in another thread just continue */
++		if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
++			continue;
++
+ 		i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[v].lan_vsi_idx]);
+ 	}
+ 
+@@ -1676,8 +1692,13 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
+ 	mdelay(50);
+ 
+ 	/* Finish the reset on each VF */
+-	for (v = 0; v < pf->num_alloc_vfs; v++)
++	for (v = 0; v < pf->num_alloc_vfs; v++) {
++		/* If VF is reset in another thread just continue */
++		if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
++			continue;
++
+ 		i40e_cleanup_reset_vf(&pf->vf[v]);
++	}
+ 
+ 	i40e_flush(hw);
+ 	clear_bit(__I40E_VF_DISABLE, pf->state);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+index a554d0a0b09bd..358bbdb587951 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+@@ -39,6 +39,7 @@ enum i40e_vf_states {
+ 	I40E_VF_STATE_MC_PROMISC,
+ 	I40E_VF_STATE_UC_PROMISC,
+ 	I40E_VF_STATE_PRE_ENABLE,
++	I40E_VF_STATE_RESETTING
+ };
+ 
+ /* VF capabilities */
+diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c
+index 7cedbe1fdfd77..bd04d9f333495 100644
+--- a/drivers/net/ethernet/lantiq_etop.c
++++ b/drivers/net/ethernet/lantiq_etop.c
+@@ -485,7 +485,6 @@ ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
+ 	len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+ 
+ 	if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
+-		dev_kfree_skb_any(skb);
+ 		netdev_err(dev, "tx ring full\n");
+ 		netif_tx_stop_queue(txq);
+ 		return NETDEV_TX_BUSY;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+index 0377392848d92..46ba4c2faad21 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+@@ -2004,7 +2004,7 @@ void mlx5_cmd_init_async_ctx(struct mlx5_core_dev *dev,
+ 	ctx->dev = dev;
+ 	/* Starts at 1 to avoid doing wake_up if we are not cleaning up */
+ 	atomic_set(&ctx->num_inflight, 1);
+-	init_waitqueue_head(&ctx->wait);
++	init_completion(&ctx->inflight_done);
+ }
+ EXPORT_SYMBOL(mlx5_cmd_init_async_ctx);
+ 
+@@ -2018,8 +2018,8 @@ EXPORT_SYMBOL(mlx5_cmd_init_async_ctx);
+  */
+ void mlx5_cmd_cleanup_async_ctx(struct mlx5_async_ctx *ctx)
+ {
+-	atomic_dec(&ctx->num_inflight);
+-	wait_event(ctx->wait, atomic_read(&ctx->num_inflight) == 0);
++	if (!atomic_dec_and_test(&ctx->num_inflight))
++		wait_for_completion(&ctx->inflight_done);
+ }
+ EXPORT_SYMBOL(mlx5_cmd_cleanup_async_ctx);
+ 
+@@ -2032,7 +2032,7 @@ static void mlx5_cmd_exec_cb_handler(int status, void *_work)
+ 	status = cmd_status_err(ctx->dev, status, work->opcode, work->out);
+ 	work->user_callback(status, work);
+ 	if (atomic_dec_and_test(&ctx->num_inflight))
+-		wake_up(&ctx->wait);
++		complete(&ctx->inflight_done);
+ }
+ 
+ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
+@@ -2050,7 +2050,7 @@ int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size,
+ 	ret = cmd_exec(ctx->dev, in, in_size, out, out_size,
+ 		       mlx5_cmd_exec_cb_handler, work, false);
+ 	if (ret && atomic_dec_and_test(&ctx->num_inflight))
+-		wake_up(&ctx->wait);
++		complete(&ctx->inflight_done);
+ 
+ 	return ret;
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
+index 92dbbec472ec6..f324a0c6f8695 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
+@@ -6,6 +6,7 @@
+ 
+ #include "en.h"
+ #include "en_stats.h"
++#include "en/txrx.h"
+ #include <linux/ptp_classify.h>
+ 
+ #define MLX5E_PTP_CHANNEL_IX 0
+@@ -68,6 +69,14 @@ static inline bool mlx5e_use_ptpsq(struct sk_buff *skb)
+ 		fk.ports.dst == htons(PTP_EV_PORT));
+ }
+ 
++static inline bool mlx5e_ptpsq_fifo_has_room(struct mlx5e_txqsq *sq)
++{
++	if (!sq->ptpsq)
++		return true;
++
++	return mlx5e_skb_fifo_has_room(&sq->ptpsq->skb_fifo);
++}
++
+ int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params,
+ 		   u8 lag_port, struct mlx5e_ptp **cp);
+ void mlx5e_ptp_close(struct mlx5e_ptp *c);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
+index 10c9a8a79d005..2e42d7c5451e9 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
+@@ -96,6 +96,7 @@ struct mlx5e_tc_flow {
+ 	struct encap_flow_item encaps[MLX5_MAX_FLOW_FWD_VPORTS];
+ 	struct mlx5e_tc_flow *peer_flow;
+ 	struct mlx5e_mod_hdr_handle *mh; /* attached mod header instance */
++	struct mlx5e_mod_hdr_handle *slow_mh; /* attached mod header instance for slow path */
+ 	struct mlx5e_hairpin_entry *hpe; /* attached hairpin instance */
+ 	struct list_head hairpin; /* flows sharing the same hairpin */
+ 	struct list_head peer;    /* flows with peer flow */
+@@ -111,6 +112,7 @@ struct mlx5e_tc_flow {
+ 	struct completion del_hw_done;
+ 	struct mlx5_flow_attr *attr;
+ 	struct list_head attrs;
++	u32 chain_mapping;
+ };
+ 
+ struct mlx5_flow_handle *
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+index c208ea307bffb..ff8ca7a7e1036 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+@@ -57,6 +57,12 @@ netdev_tx_t mlx5e_xmit(struct sk_buff *skb, struct net_device *dev);
+ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget);
+ void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq);
+ 
++static inline bool
++mlx5e_skb_fifo_has_room(struct mlx5e_skb_fifo *fifo)
++{
++	return (*fifo->pc - *fifo->cc) < fifo->mask;
++}
++
+ static inline bool
+ mlx5e_wqc_has_room_for(struct mlx5_wq_cyc *wq, u16 cc, u16 pc, u16 n)
+ {
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+index 2a8fd70206220..a715601865d31 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+@@ -101,7 +101,6 @@ static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
+ 	struct xfrm_replay_state_esn *replay_esn;
+ 	u32 seq_bottom = 0;
+ 	u8 overlap;
+-	u32 *esn;
+ 
+ 	if (!(sa_entry->x->props.flags & XFRM_STATE_ESN)) {
+ 		sa_entry->esn_state.trigger = 0;
+@@ -116,11 +115,9 @@ static bool mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry)
+ 
+ 	sa_entry->esn_state.esn = xfrm_replay_seqhi(sa_entry->x,
+ 						    htonl(seq_bottom));
+-	esn = &sa_entry->esn_state.esn;
+ 
+ 	sa_entry->esn_state.trigger = 1;
+ 	if (unlikely(overlap && seq_bottom < MLX5E_IPSEC_ESN_SCOPE_MID)) {
+-		++(*esn);
+ 		sa_entry->esn_state.overlap = 0;
+ 		return true;
+ 	} else if (unlikely(!overlap &&
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+index f154bda668adf..a687f047e3aeb 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+@@ -1394,8 +1394,13 @@ mlx5e_tc_offload_to_slow_path(struct mlx5_eswitch *esw,
+ 			      struct mlx5e_tc_flow *flow,
+ 			      struct mlx5_flow_spec *spec)
+ {
++	struct mlx5e_tc_mod_hdr_acts mod_acts = {};
++	struct mlx5e_mod_hdr_handle *mh = NULL;
+ 	struct mlx5_flow_attr *slow_attr;
+ 	struct mlx5_flow_handle *rule;
++	bool fwd_and_modify_cap;
++	u32 chain_mapping = 0;
++	int err;
+ 
+ 	slow_attr = mlx5_alloc_flow_attr(MLX5_FLOW_NAMESPACE_FDB);
+ 	if (!slow_attr)
+@@ -1406,13 +1411,56 @@ mlx5e_tc_offload_to_slow_path(struct mlx5_eswitch *esw,
+ 	slow_attr->esw_attr->split_count = 0;
+ 	slow_attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH;
+ 
++	fwd_and_modify_cap = MLX5_CAP_ESW_FLOWTABLE((esw)->dev, fdb_modify_header_fwd_to_table);
++	if (!fwd_and_modify_cap)
++		goto skip_restore;
++
++	err = mlx5_chains_get_chain_mapping(esw_chains(esw), flow->attr->chain, &chain_mapping);
++	if (err)
++		goto err_get_chain;
++
++	err = mlx5e_tc_match_to_reg_set(esw->dev, &mod_acts, MLX5_FLOW_NAMESPACE_FDB,
++					CHAIN_TO_REG, chain_mapping);
++	if (err)
++		goto err_reg_set;
++
++	mh = mlx5e_mod_hdr_attach(esw->dev, get_mod_hdr_table(flow->priv, flow),
++				  MLX5_FLOW_NAMESPACE_FDB, &mod_acts);
++	if (IS_ERR(mh)) {
++		err = PTR_ERR(mh);
++		goto err_attach;
++	}
++
++	slow_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
++	slow_attr->modify_hdr = mlx5e_mod_hdr_get(mh);
++
++skip_restore:
+ 	rule = mlx5e_tc_offload_fdb_rules(esw, flow, spec, slow_attr);
+-	if (!IS_ERR(rule))
+-		flow_flag_set(flow, SLOW);
++	if (IS_ERR(rule)) {
++		err = PTR_ERR(rule);
++		goto err_offload;
++	}
+ 
++	flow->slow_mh = mh;
++	flow->chain_mapping = chain_mapping;
++	flow_flag_set(flow, SLOW);
++
++	mlx5e_mod_hdr_dealloc(&mod_acts);
+ 	kfree(slow_attr);
+ 
+ 	return rule;
++
++err_offload:
++	if (fwd_and_modify_cap)
++		mlx5e_mod_hdr_detach(esw->dev, get_mod_hdr_table(flow->priv, flow), mh);
++err_attach:
++err_reg_set:
++	if (fwd_and_modify_cap)
++		mlx5_chains_put_chain_mapping(esw_chains(esw), chain_mapping);
++err_get_chain:
++	mlx5e_mod_hdr_dealloc(&mod_acts);
++	kfree(slow_attr);
++	return ERR_PTR(err);
+ }
+ 
+ void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw,
+@@ -1430,7 +1478,17 @@ void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw,
+ 	slow_attr->action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+ 	slow_attr->esw_attr->split_count = 0;
+ 	slow_attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH;
++	if (flow->slow_mh) {
++		slow_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
++		slow_attr->modify_hdr = mlx5e_mod_hdr_get(flow->slow_mh);
++	}
+ 	mlx5e_tc_unoffload_fdb_rules(esw, flow, slow_attr);
++	if (flow->slow_mh) {
++		mlx5e_mod_hdr_detach(esw->dev, get_mod_hdr_table(flow->priv, flow), flow->slow_mh);
++		mlx5_chains_put_chain_mapping(esw_chains(esw), flow->chain_mapping);
++		flow->chain_mapping = 0;
++		flow->slow_mh = NULL;
++	}
+ 	flow_flag_clear(flow, SLOW);
+ 	kfree(slow_attr);
+ }
+@@ -3994,6 +4052,7 @@ parse_tc_fdb_actions(struct mlx5e_priv *priv,
+ 	struct mlx5e_tc_flow_parse_attr *parse_attr;
+ 	struct mlx5_flow_attr *attr = flow->attr;
+ 	struct mlx5_esw_flow_attr *esw_attr;
++	struct net_device *filter_dev;
+ 	int err;
+ 
+ 	err = flow_action_supported(flow_action, extack);
+@@ -4002,6 +4061,7 @@ parse_tc_fdb_actions(struct mlx5e_priv *priv,
+ 
+ 	esw_attr = attr->esw_attr;
+ 	parse_attr = attr->parse_attr;
++	filter_dev = parse_attr->filter_dev;
+ 	parse_state = &parse_attr->parse_state;
+ 	mlx5e_tc_act_init_parse_state(parse_state, flow, flow_action, extack);
+ 	parse_state->ct_priv = get_ct_priv(priv);
+@@ -4011,13 +4071,21 @@ parse_tc_fdb_actions(struct mlx5e_priv *priv,
+ 		return err;
+ 
+ 	/* Forward to/from internal port can only have 1 dest */
+-	if ((netif_is_ovs_master(parse_attr->filter_dev) || esw_attr->dest_int_port) &&
++	if ((netif_is_ovs_master(filter_dev) || esw_attr->dest_int_port) &&
+ 	    esw_attr->out_count > 1) {
+ 		NL_SET_ERR_MSG_MOD(extack,
+ 				   "Rules with internal port can have only one destination");
+ 		return -EOPNOTSUPP;
+ 	}
+ 
++	/* Forward from tunnel/internal port to internal port is not supported */
++	if ((mlx5e_get_tc_tun(filter_dev) || netif_is_ovs_master(filter_dev)) &&
++	    esw_attr->dest_int_port) {
++		NL_SET_ERR_MSG_MOD(extack,
++				   "Forwarding from tunnel/internal port to internal port is not supported");
++		return -EOPNOTSUPP;
++	}
++
+ 	err = actions_prepare_mod_hdr_actions(priv, flow, attr, extack);
+ 	if (err)
+ 		return err;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+index 27f791feb5174..4d45150a3f8ef 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+@@ -391,6 +391,11 @@ mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb,
+ 	if (unlikely(sq->ptpsq)) {
+ 		mlx5e_skb_cb_hwtstamp_init(skb);
+ 		mlx5e_skb_fifo_push(&sq->ptpsq->skb_fifo, skb);
++		if (!netif_tx_queue_stopped(sq->txq) &&
++		    !mlx5e_skb_fifo_has_room(&sq->ptpsq->skb_fifo)) {
++			netif_tx_stop_queue(sq->txq);
++			sq->stats->stopped++;
++		}
+ 		skb_get(skb);
+ 	}
+ 
+@@ -867,6 +872,7 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget)
+ 
+ 	if (netif_tx_queue_stopped(sq->txq) &&
+ 	    mlx5e_wqc_has_room_for(&sq->wq, sq->cc, sq->pc, sq->stop_room) &&
++	    mlx5e_ptpsq_fifo_has_room(sq) &&
+ 	    !test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) {
+ 		netif_tx_wake_queue(sq->txq);
+ 		stats->wake++;
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+index e8896f3683626..07c583996c297 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+@@ -358,6 +358,23 @@ static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
+ 		err = -ETIMEDOUT;
+ 	}
+ 
++	do {
++		err = pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &reg16);
++		if (err)
++			return err;
++		if (reg16 == dev_id)
++			break;
++		msleep(20);
++	} while (!time_after(jiffies, timeout));
++
++	if (reg16 == dev_id) {
++		mlx5_core_info(dev, "Firmware responds to PCI config cycles again\n");
++	} else {
++		mlx5_core_err(dev, "Firmware is not responsive (0x%04x) after %llu ms\n",
++			      reg16, mlx5_tout_ms(dev, PCI_TOGGLE));
++		err = -ETIMEDOUT;
++	}
++
+ restore:
+ 	list_for_each_entry(sdev, &bridge_bus->devices, bus_list) {
+ 		pci_cfg_access_unlock(sdev);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c
+index 21e14507ff5c0..7cd9dda53774a 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c
+@@ -3,6 +3,7 @@
+ 
+ #include <linux/mlx5/device.h>
+ #include <linux/mlx5/transobj.h>
++#include "clock.h"
+ #include "aso.h"
+ #include "wq.h"
+ 
+@@ -179,6 +180,7 @@ static int create_aso_sq(struct mlx5_core_dev *mdev, int pdn,
+ {
+ 	void *in, *sqc, *wq;
+ 	int inlen, err;
++	u8 ts_format;
+ 
+ 	inlen = MLX5_ST_SZ_BYTES(create_sq_in) +
+ 		sizeof(u64) * sq->wq_ctrl.buf.npages;
+@@ -195,6 +197,11 @@ static int create_aso_sq(struct mlx5_core_dev *mdev, int pdn,
+ 	MLX5_SET(sqc,  sqc, state, MLX5_SQC_STATE_RST);
+ 	MLX5_SET(sqc,  sqc, flush_in_error_en, 1);
+ 
++	ts_format = mlx5_is_real_time_sq(mdev) ?
++			MLX5_TIMESTAMP_FORMAT_REAL_TIME :
++			MLX5_TIMESTAMP_FORMAT_FREE_RUNNING;
++	MLX5_SET(sqc, sqc, ts_format, ts_format);
++
+ 	MLX5_SET(wq,   wq, wq_type,       MLX5_WQ_TYPE_CYCLIC);
+ 	MLX5_SET(wq,   wq, uar_page,      mdev->mlx5e_res.hw_objs.bfreg.index);
+ 	MLX5_SET(wq,   wq, log_wq_pg_sz,  sq->wq_ctrl.buf.page_shift -
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c
+index 839a01da110f3..8ff16318e32dc 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c
+@@ -122,7 +122,7 @@ void mlx5_mpfs_cleanup(struct mlx5_core_dev *dev)
+ {
+ 	struct mlx5_mpfs *mpfs = dev->priv.mpfs;
+ 
+-	if (!MLX5_ESWITCH_MANAGER(dev))
++	if (!mpfs)
+ 		return;
+ 
+ 	WARN_ON(!hlist_empty(mpfs->hash));
+@@ -137,7 +137,7 @@ int mlx5_mpfs_add_mac(struct mlx5_core_dev *dev, u8 *mac)
+ 	int err = 0;
+ 	u32 index;
+ 
+-	if (!MLX5_ESWITCH_MANAGER(dev))
++	if (!mpfs)
+ 		return 0;
+ 
+ 	mutex_lock(&mpfs->lock);
+@@ -185,7 +185,7 @@ int mlx5_mpfs_del_mac(struct mlx5_core_dev *dev, u8 *mac)
+ 	int err = 0;
+ 	u32 index;
+ 
+-	if (!MLX5_ESWITCH_MANAGER(dev))
++	if (!mpfs)
+ 		return 0;
+ 
+ 	mutex_lock(&mpfs->lock);
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+index 89b2d9cea33f0..e5e32430b6afd 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -1833,6 +1833,10 @@ static void mlx5_pci_resume(struct pci_dev *pdev)
+ 
+ 	err = mlx5_load_one(dev, false);
+ 
++	if (!err)
++		devlink_health_reporter_state_update(dev->priv.health.fw_fatal_reporter,
++						     DEVLINK_HEALTH_REPORTER_STATE_HEALTHY);
++
+ 	mlx5_pci_trace(dev, "Done, err = %d, device %s\n", err,
+ 		       !err ? "recovered" : "Failed");
+ }
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
+index ddfaf78911881..91ff19f676951 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
+@@ -1200,7 +1200,8 @@ free_rule:
+ 	}
+ 
+ remove_from_nic_tbl:
+-	mlx5dr_matcher_remove_from_tbl_nic(dmn, nic_matcher);
++	if (!nic_matcher->rules)
++		mlx5dr_matcher_remove_from_tbl_nic(dmn, nic_matcher);
+ 
+ free_hw_ste:
+ 	mlx5dr_domain_nic_unlock(nic_dmn);
+diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
+index 2b3eb5ed82338..97839f1b456c6 100644
+--- a/drivers/net/ethernet/micrel/ksz884x.c
++++ b/drivers/net/ethernet/micrel/ksz884x.c
+@@ -6851,7 +6851,7 @@ static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id)
+ 	char banner[sizeof(version)];
+ 	struct ksz_switch *sw = NULL;
+ 
+-	result = pci_enable_device(pdev);
++	result = pcim_enable_device(pdev);
+ 	if (result)
+ 		return result;
+ 
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
+index e58a27fd8b508..fea42542be280 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_ethtool.c
+@@ -656,7 +656,15 @@ void lan966x_stats_get(struct net_device *dev,
+ 	stats->rx_dropped = dev->stats.rx_dropped +
+ 		lan966x->stats[idx + SYS_COUNT_RX_LONG] +
+ 		lan966x->stats[idx + SYS_COUNT_DR_LOCAL] +
+-		lan966x->stats[idx + SYS_COUNT_DR_TAIL];
++		lan966x->stats[idx + SYS_COUNT_DR_TAIL] +
++		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_0] +
++		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_1] +
++		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_2] +
++		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_3] +
++		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_4] +
++		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_5] +
++		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_6] +
++		lan966x->stats[idx + SYS_COUNT_RX_RED_PRIO_7];
+ 
+ 	for (i = 0; i < LAN966X_NUM_TC; i++) {
+ 		stats->rx_dropped +=
+diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+index 51f8a08163777..69f741db25b1f 100644
+--- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
++++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+@@ -309,6 +309,7 @@ static void lan966x_fdma_tx_disable(struct lan966x_tx *tx)
+ 		lan966x, FDMA_CH_DB_DISCARD);
+ 
+ 	tx->activated = false;
++	tx->last_in_use = -1;
+ }
+ 
+ static void lan966x_fdma_tx_reload(struct lan966x_tx *tx)
+@@ -687,17 +688,14 @@ static int lan966x_qsys_sw_status(struct lan966x *lan966x)
+ 
+ static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
+ {
+-	void *rx_dcbs, *tx_dcbs, *tx_dcbs_buf;
+-	dma_addr_t rx_dma, tx_dma;
++	dma_addr_t rx_dma;
++	void *rx_dcbs;
+ 	u32 size;
+ 	int err;
+ 
+ 	/* Store these for later to free them */
+ 	rx_dma = lan966x->rx.dma;
+-	tx_dma = lan966x->tx.dma;
+ 	rx_dcbs = lan966x->rx.dcbs;
+-	tx_dcbs = lan966x->tx.dcbs;
+-	tx_dcbs_buf = lan966x->tx.dcbs_buf;
+ 
+ 	napi_synchronize(&lan966x->napi);
+ 	napi_disable(&lan966x->napi);
+@@ -715,17 +713,6 @@ static int lan966x_fdma_reload(struct lan966x *lan966x, int new_mtu)
+ 	size = ALIGN(size, PAGE_SIZE);
+ 	dma_free_coherent(lan966x->dev, size, rx_dcbs, rx_dma);
+ 
+-	lan966x_fdma_tx_disable(&lan966x->tx);
+-	err = lan966x_fdma_tx_alloc(&lan966x->tx);
+-	if (err)
+-		goto restore_tx;
+-
+-	size = sizeof(struct lan966x_tx_dcb) * FDMA_DCB_MAX;
+-	size = ALIGN(size, PAGE_SIZE);
+-	dma_free_coherent(lan966x->dev, size, tx_dcbs, tx_dma);
+-
+-	kfree(tx_dcbs_buf);
+-
+ 	lan966x_fdma_wakeup_netdev(lan966x);
+ 	napi_enable(&lan966x->napi);
+ 
+@@ -735,11 +722,6 @@ restore:
+ 	lan966x->rx.dcbs = rx_dcbs;
+ 	lan966x_fdma_rx_start(&lan966x->rx);
+ 
+-restore_tx:
+-	lan966x->tx.dma = tx_dma;
+-	lan966x->tx.dcbs = tx_dcbs;
+-	lan966x->tx.dcbs_buf = tx_dcbs_buf;
+-
+ 	return err;
+ }
+ 
+diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
+index b0c5a44785fa4..386c8640381b8 100644
+--- a/drivers/net/ethernet/socionext/netsec.c
++++ b/drivers/net/ethernet/socionext/netsec.c
+@@ -1961,11 +1961,13 @@ static int netsec_register_mdio(struct netsec_priv *priv, u32 phy_addr)
+ 			ret = PTR_ERR(priv->phydev);
+ 			dev_err(priv->dev, "get_phy_device err(%d)\n", ret);
+ 			priv->phydev = NULL;
++			mdiobus_unregister(bus);
+ 			return -ENODEV;
+ 		}
+ 
+ 		ret = phy_device_register(priv->phydev);
+ 		if (ret) {
++			phy_device_free(priv->phydev);
+ 			mdiobus_unregister(bus);
+ 			dev_err(priv->dev,
+ 				"phy_device_register err(%d)\n", ret);
+diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c
+index f0c8de2c60755..db80a17a7e210 100644
+--- a/drivers/net/ethernet/socionext/sni_ave.c
++++ b/drivers/net/ethernet/socionext/sni_ave.c
+@@ -1229,6 +1229,8 @@ static int ave_init(struct net_device *ndev)
+ 
+ 	phy_support_asym_pause(phydev);
+ 
++	phydev->mac_managed_pm = true;
++
+ 	phy_attached_info(phydev);
+ 
+ 	return 0;
+@@ -1757,6 +1759,10 @@ static int ave_resume(struct device *dev)
+ 
+ 	ave_global_reset(ndev);
+ 
++	ret = phy_init_hw(ndev->phydev);
++	if (ret)
++		return ret;
++
+ 	ave_ethtool_get_wol(ndev, &wol);
+ 	wol.wolopts = priv->wolopts;
+ 	__ave_ethtool_set_wol(ndev, &wol);
+diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c
+index b5f4df1a07a3d..0052968e881e7 100644
+--- a/drivers/net/netdevsim/bus.c
++++ b/drivers/net/netdevsim/bus.c
+@@ -117,6 +117,10 @@ static const struct attribute_group *nsim_bus_dev_attr_groups[] = {
+ 
+ static void nsim_bus_dev_release(struct device *dev)
+ {
++	struct nsim_bus_dev *nsim_bus_dev;
++
++	nsim_bus_dev = container_of(dev, struct nsim_bus_dev, dev);
++	kfree(nsim_bus_dev);
+ }
+ 
+ static struct device_type nsim_bus_dev_type = {
+@@ -291,6 +295,8 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queu
+ 
+ err_nsim_bus_dev_id_free:
+ 	ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
++	put_device(&nsim_bus_dev->dev);
++	nsim_bus_dev = NULL;
+ err_nsim_bus_dev_free:
+ 	kfree(nsim_bus_dev);
+ 	return ERR_PTR(err);
+@@ -300,9 +306,8 @@ static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
+ {
+ 	/* Disallow using nsim_bus_dev */
+ 	smp_store_release(&nsim_bus_dev->init, false);
+-	device_unregister(&nsim_bus_dev->dev);
+ 	ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
+-	kfree(nsim_bus_dev);
++	device_unregister(&nsim_bus_dev->dev);
+ }
+ 
+ static struct device_driver nsim_driver = {
+diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
+index e88f783c297eb..b17e4e94a060e 100644
+--- a/drivers/net/netdevsim/dev.c
++++ b/drivers/net/netdevsim/dev.c
+@@ -309,8 +309,10 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
+ 	if (IS_ERR(nsim_dev->ddir))
+ 		return PTR_ERR(nsim_dev->ddir);
+ 	nsim_dev->ports_ddir = debugfs_create_dir("ports", nsim_dev->ddir);
+-	if (IS_ERR(nsim_dev->ports_ddir))
+-		return PTR_ERR(nsim_dev->ports_ddir);
++	if (IS_ERR(nsim_dev->ports_ddir)) {
++		err = PTR_ERR(nsim_dev->ports_ddir);
++		goto err_ddir;
++	}
+ 	debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir,
+ 			    &nsim_dev->fw_update_status);
+ 	debugfs_create_u32("fw_update_overwrite_mask", 0600, nsim_dev->ddir,
+@@ -346,7 +348,7 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
+ 	nsim_dev->nodes_ddir = debugfs_create_dir("rate_nodes", nsim_dev->ddir);
+ 	if (IS_ERR(nsim_dev->nodes_ddir)) {
+ 		err = PTR_ERR(nsim_dev->nodes_ddir);
+-		goto err_out;
++		goto err_ports_ddir;
+ 	}
+ 	debugfs_create_bool("fail_trap_drop_counter_get", 0600,
+ 			    nsim_dev->ddir,
+@@ -354,8 +356,9 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
+ 	nsim_udp_tunnels_debugfs_create(nsim_dev);
+ 	return 0;
+ 
+-err_out:
++err_ports_ddir:
+ 	debugfs_remove_recursive(nsim_dev->ports_ddir);
++err_ddir:
+ 	debugfs_remove_recursive(nsim_dev->ddir);
+ 	return err;
+ }
+@@ -442,7 +445,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ 				     &params);
+ 	if (err) {
+ 		pr_err("Failed to register IPv4 top resource\n");
+-		goto out;
++		goto err_out;
+ 	}
+ 
+ 	err = devl_resource_register(devlink, "fib", (u64)-1,
+@@ -450,7 +453,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ 				     NSIM_RESOURCE_IPV4, &params);
+ 	if (err) {
+ 		pr_err("Failed to register IPv4 FIB resource\n");
+-		return err;
++		goto err_out;
+ 	}
+ 
+ 	err = devl_resource_register(devlink, "fib-rules", (u64)-1,
+@@ -458,7 +461,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ 				     NSIM_RESOURCE_IPV4, &params);
+ 	if (err) {
+ 		pr_err("Failed to register IPv4 FIB rules resource\n");
+-		return err;
++		goto err_out;
+ 	}
+ 
+ 	/* Resources for IPv6 */
+@@ -468,7 +471,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ 				     &params);
+ 	if (err) {
+ 		pr_err("Failed to register IPv6 top resource\n");
+-		goto out;
++		goto err_out;
+ 	}
+ 
+ 	err = devl_resource_register(devlink, "fib", (u64)-1,
+@@ -476,7 +479,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ 				     NSIM_RESOURCE_IPV6, &params);
+ 	if (err) {
+ 		pr_err("Failed to register IPv6 FIB resource\n");
+-		return err;
++		goto err_out;
+ 	}
+ 
+ 	err = devl_resource_register(devlink, "fib-rules", (u64)-1,
+@@ -484,7 +487,7 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ 				     NSIM_RESOURCE_IPV6, &params);
+ 	if (err) {
+ 		pr_err("Failed to register IPv6 FIB rules resource\n");
+-		return err;
++		goto err_out;
+ 	}
+ 
+ 	/* Resources for nexthops */
+@@ -492,8 +495,14 @@ static int nsim_dev_resources_register(struct devlink *devlink)
+ 				     NSIM_RESOURCE_NEXTHOPS,
+ 				     DEVLINK_RESOURCE_ID_PARENT_TOP,
+ 				     &params);
++	if (err) {
++		pr_err("Failed to register NEXTHOPS resource\n");
++		goto err_out;
++	}
++	return 0;
+ 
+-out:
++err_out:
++	devl_resources_unregister(devlink);
+ 	return err;
+ }
+ 
+diff --git a/drivers/nfc/virtual_ncidev.c b/drivers/nfc/virtual_ncidev.c
+index f577449e49350..85c06dbb2c449 100644
+--- a/drivers/nfc/virtual_ncidev.c
++++ b/drivers/nfc/virtual_ncidev.c
+@@ -54,16 +54,19 @@ static int virtual_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+ 	mutex_lock(&nci_mutex);
+ 	if (state != virtual_ncidev_enabled) {
+ 		mutex_unlock(&nci_mutex);
++		kfree_skb(skb);
+ 		return 0;
+ 	}
+ 
+ 	if (send_buff) {
+ 		mutex_unlock(&nci_mutex);
++		kfree_skb(skb);
+ 		return -1;
+ 	}
+ 	send_buff = skb_copy(skb, GFP_KERNEL);
+ 	mutex_unlock(&nci_mutex);
+ 	wake_up_interruptible(&wq);
++	consume_skb(skb);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c
+index 3a9ee9c8af116..2991fe0bb0f2c 100644
+--- a/drivers/pinctrl/pinctrl-ingenic.c
++++ b/drivers/pinctrl/pinctrl-ingenic.c
+@@ -667,7 +667,7 @@ static u8 jz4755_lcd_24bit_funcs[] = { 1, 1, 1, 1, 0, 0, };
+ static const struct group_desc jz4755_groups[] = {
+ 	INGENIC_PIN_GROUP("uart0-data", jz4755_uart0_data, 0),
+ 	INGENIC_PIN_GROUP("uart0-hwflow", jz4755_uart0_hwflow, 0),
+-	INGENIC_PIN_GROUP("uart1-data", jz4755_uart1_data, 0),
++	INGENIC_PIN_GROUP("uart1-data", jz4755_uart1_data, 1),
+ 	INGENIC_PIN_GROUP("uart2-data", jz4755_uart2_data, 1),
+ 	INGENIC_PIN_GROUP("ssi-dt-b", jz4755_ssi_dt_b, 0),
+ 	INGENIC_PIN_GROUP("ssi-dt-f", jz4755_ssi_dt_f, 0),
+@@ -721,7 +721,7 @@ static const char *jz4755_ssi_groups[] = {
+ 	"ssi-ce1-b", "ssi-ce1-f",
+ };
+ static const char *jz4755_mmc0_groups[] = { "mmc0-1bit", "mmc0-4bit", };
+-static const char *jz4755_mmc1_groups[] = { "mmc0-1bit", "mmc0-4bit", };
++static const char *jz4755_mmc1_groups[] = { "mmc1-1bit", "mmc1-4bit", };
+ static const char *jz4755_i2c_groups[] = { "i2c-data", };
+ static const char *jz4755_cim_groups[] = { "cim-data", };
+ static const char *jz4755_lcd_groups[] = {
+diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
+index c7df8c5fe5854..105771ff82e62 100644
+--- a/drivers/pinctrl/pinctrl-ocelot.c
++++ b/drivers/pinctrl/pinctrl-ocelot.c
+@@ -1863,19 +1863,28 @@ static void ocelot_irq_unmask_level(struct irq_data *data)
+ 	if (val & bit)
+ 		ack = true;
+ 
++	/* Try to clear any rising edges */
++	if (!active && ack)
++		regmap_write_bits(info->map, REG(OCELOT_GPIO_INTR, info, gpio),
++				  bit, bit);
++
+ 	/* Enable the interrupt now */
+ 	gpiochip_enable_irq(chip, gpio);
+ 	regmap_update_bits(info->map, REG(OCELOT_GPIO_INTR_ENA, info, gpio),
+ 			   bit, bit);
+ 
+ 	/*
+-	 * In case the interrupt line is still active and the interrupt
+-	 * controller has not seen any changes in the interrupt line, then it
+-	 * means that there happen another interrupt while the line was active.
++	 * In case the interrupt line is still active then it means that
++	 * there happen another interrupt while the line was active.
+ 	 * So we missed that one, so we need to kick the interrupt again
+ 	 * handler.
+ 	 */
+-	if (active && !ack) {
++	regmap_read(info->map, REG(OCELOT_GPIO_IN, info, gpio), &val);
++	if ((!(val & bit) && trigger_level == IRQ_TYPE_LEVEL_LOW) ||
++	      (val & bit && trigger_level == IRQ_TYPE_LEVEL_HIGH))
++		active = true;
++
++	if (active) {
+ 		struct ocelot_irq_work *work;
+ 
+ 		work = kmalloc(sizeof(*work), GFP_ATOMIC);
+diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c
+index 7d2fbf8a02cd6..c98f35ad89217 100644
+--- a/drivers/pinctrl/pinctrl-zynqmp.c
++++ b/drivers/pinctrl/pinctrl-zynqmp.c
+@@ -412,10 +412,6 @@ static int zynqmp_pinconf_cfg_set(struct pinctrl_dev *pctldev,
+ 
+ 			break;
+ 		case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+-			param = PM_PINCTRL_CONFIG_TRI_STATE;
+-			arg = PM_PINCTRL_TRI_STATE_ENABLE;
+-			ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
+-			break;
+ 		case PIN_CONFIG_MODE_LOW_POWER:
+ 			/*
+ 			 * These cases are mentioned in dts but configurable
+@@ -424,11 +420,6 @@ static int zynqmp_pinconf_cfg_set(struct pinctrl_dev *pctldev,
+ 			 */
+ 			ret = 0;
+ 			break;
+-		case PIN_CONFIG_OUTPUT_ENABLE:
+-			param = PM_PINCTRL_CONFIG_TRI_STATE;
+-			arg = PM_PINCTRL_TRI_STATE_DISABLE;
+-			ret = zynqmp_pm_pinctrl_set_config(pin, param, arg);
+-			break;
+ 		default:
+ 			dev_warn(pctldev->dev,
+ 				 "unsupported configuration parameter '%u'\n",
+diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
+index a2abfe987ab12..8bf8b21954fe4 100644
+--- a/drivers/pinctrl/qcom/pinctrl-msm.c
++++ b/drivers/pinctrl/qcom/pinctrl-msm.c
+@@ -51,6 +51,7 @@
+  *                  detection.
+  * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller
+  * @disabled_for_mux: These IRQs were disabled because we muxed away.
++ * @ever_gpio:      This bit is set the first time we mux a pin to gpio_func.
+  * @soc:            Reference to soc_data of platform specific data.
+  * @regs:           Base addresses for the TLMM tiles.
+  * @phys_base:      Physical base address
+@@ -72,6 +73,7 @@ struct msm_pinctrl {
+ 	DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
+ 	DECLARE_BITMAP(skip_wake_irqs, MAX_NR_GPIO);
+ 	DECLARE_BITMAP(disabled_for_mux, MAX_NR_GPIO);
++	DECLARE_BITMAP(ever_gpio, MAX_NR_GPIO);
+ 
+ 	const struct msm_pinctrl_soc_data *soc;
+ 	void __iomem *regs[MAX_NR_TILES];
+@@ -218,6 +220,25 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
+ 
+ 	val = msm_readl_ctl(pctrl, g);
+ 
++	/*
++	 * If this is the first time muxing to GPIO and the direction is
++	 * output, make sure that we're not going to be glitching the pin
++	 * by reading the current state of the pin and setting it as the
++	 * output.
++	 */
++	if (i == gpio_func && (val & BIT(g->oe_bit)) &&
++	    !test_and_set_bit(group, pctrl->ever_gpio)) {
++		u32 io_val = msm_readl_io(pctrl, g);
++
++		if (io_val & BIT(g->in_bit)) {
++			if (!(io_val & BIT(g->out_bit)))
++				msm_writel_io(io_val | BIT(g->out_bit), pctrl, g);
++		} else {
++			if (io_val & BIT(g->out_bit))
++				msm_writel_io(io_val & ~BIT(g->out_bit), pctrl, g);
++		}
++	}
++
+ 	if (egpio_func && i == egpio_func) {
+ 		if (val & BIT(g->egpio_present))
+ 			val &= ~BIT(g->egpio_enable);
+diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c
+index fc326fdf483fb..6ccb9b38483ca 100644
+--- a/drivers/platform/x86/amd/pmc.c
++++ b/drivers/platform/x86/amd/pmc.c
+@@ -151,9 +151,7 @@ struct amd_pmc_dev {
+ 	struct device *dev;
+ 	struct pci_dev *rdev;
+ 	struct mutex lock; /* generic mutex lock */
+-#if IS_ENABLED(CONFIG_DEBUG_FS)
+ 	struct dentry *dbgfs_dir;
+-#endif /* CONFIG_DEBUG_FS */
+ };
+ 
+ static bool enable_stb;
+@@ -369,7 +367,6 @@ static void amd_pmc_validate_deepest(struct amd_pmc_dev *pdev)
+ }
+ #endif
+ 
+-#ifdef CONFIG_DEBUG_FS
+ static int smu_fw_info_show(struct seq_file *s, void *unused)
+ {
+ 	struct amd_pmc_dev *dev = s->private;
+@@ -504,15 +501,6 @@ static void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
+ 					    &amd_pmc_stb_debugfs_fops);
+ 	}
+ }
+-#else
+-static inline void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
+-{
+-}
+-
+-static inline void amd_pmc_dbgfs_unregister(struct amd_pmc_dev *dev)
+-{
+-}
+-#endif /* CONFIG_DEBUG_FS */
+ 
+ static void amd_pmc_dump_registers(struct amd_pmc_dev *dev)
+ {
+diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
+index 913b6ddd040b8..c7db953985002 100644
+--- a/drivers/s390/cio/css.c
++++ b/drivers/s390/cio/css.c
+@@ -753,13 +753,9 @@ static int __unset_online(struct device *dev, void *data)
+ {
+ 	struct idset *set = data;
+ 	struct subchannel *sch = to_subchannel(dev);
+-	struct ccw_device *cdev;
+ 
+-	if (sch->st == SUBCHANNEL_TYPE_IO) {
+-		cdev = sch_get_cdev(sch);
+-		if (cdev && cdev->online)
+-			idset_sch_del(set, sch->schid);
+-	}
++	if (sch->st == SUBCHANNEL_TYPE_IO && sch->config.ena)
++		idset_sch_del(set, sch->schid);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
+index fa1fcbfb946f9..6188f6e214648 100644
+--- a/drivers/scsi/qla2xxx/qla_attr.c
++++ b/drivers/scsi/qla2xxx/qla_attr.c
+@@ -3330,11 +3330,34 @@ struct fc_function_template qla2xxx_transport_vport_functions = {
+ 	.bsg_timeout = qla24xx_bsg_timeout,
+ };
+ 
++static uint
++qla2x00_get_host_supported_speeds(scsi_qla_host_t *vha, uint speeds)
++{
++	uint supported_speeds = FC_PORTSPEED_UNKNOWN;
++
++	if (speeds & FDMI_PORT_SPEED_64GB)
++		supported_speeds |= FC_PORTSPEED_64GBIT;
++	if (speeds & FDMI_PORT_SPEED_32GB)
++		supported_speeds |= FC_PORTSPEED_32GBIT;
++	if (speeds & FDMI_PORT_SPEED_16GB)
++		supported_speeds |= FC_PORTSPEED_16GBIT;
++	if (speeds & FDMI_PORT_SPEED_8GB)
++		supported_speeds |= FC_PORTSPEED_8GBIT;
++	if (speeds & FDMI_PORT_SPEED_4GB)
++		supported_speeds |= FC_PORTSPEED_4GBIT;
++	if (speeds & FDMI_PORT_SPEED_2GB)
++		supported_speeds |= FC_PORTSPEED_2GBIT;
++	if (speeds & FDMI_PORT_SPEED_1GB)
++		supported_speeds |= FC_PORTSPEED_1GBIT;
++
++	return supported_speeds;
++}
++
+ void
+ qla2x00_init_host_attr(scsi_qla_host_t *vha)
+ {
+ 	struct qla_hw_data *ha = vha->hw;
+-	u32 speeds = FC_PORTSPEED_UNKNOWN;
++	u32 speeds = 0, fdmi_speed = 0;
+ 
+ 	fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count;
+ 	fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name);
+@@ -3344,7 +3367,8 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha)
+ 	fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports;
+ 	fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count;
+ 
+-	speeds = qla25xx_fdmi_port_speed_capability(ha);
++	fdmi_speed = qla25xx_fdmi_port_speed_capability(ha);
++	speeds = qla2x00_get_host_supported_speeds(vha, fdmi_speed);
+ 
+ 	fc_host_supported_speeds(vha->host) = speeds;
+ }
+diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
+index 3e891bf22470e..5a995b5653f1b 100644
+--- a/drivers/spi/spi-aspeed-smc.c
++++ b/drivers/spi/spi-aspeed-smc.c
+@@ -398,7 +398,7 @@ static void aspeed_spi_get_windows(struct aspeed_spi *aspi,
+ 		windows[cs].cs = cs;
+ 		windows[cs].size = data->segment_end(aspi, reg_val) -
+ 			data->segment_start(aspi, reg_val);
+-		windows[cs].offset = cs ? windows[cs - 1].offset + windows[cs - 1].size : 0;
++		windows[cs].offset = data->segment_start(aspi, reg_val) - aspi->ahb_base_phy;
+ 		dev_vdbg(aspi->dev, "CE%d offset=0x%.8x size=0x%x\n", cs,
+ 			 windows[cs].offset, windows[cs].size);
+ 	}
+diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
+index 7d89510dc3f00..678dc51ef0174 100644
+--- a/drivers/spi/spi-qup.c
++++ b/drivers/spi/spi-qup.c
+@@ -1057,6 +1057,8 @@ static int spi_qup_probe(struct platform_device *pdev)
+ 	else
+ 		master->num_chipselect = num_cs;
+ 
++	master->use_gpio_descriptors = true;
++	master->max_native_cs = SPI_NUM_CHIPSELECTS;
+ 	master->bus_num = pdev->id;
+ 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
+ 	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
+diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c
+index 0e7c38b2bfe32..67915d76a87f2 100644
+--- a/drivers/staging/media/atomisp/pci/sh_css_params.c
++++ b/drivers/staging/media/atomisp/pci/sh_css_params.c
+@@ -950,8 +950,8 @@ sh_css_set_black_frame(struct ia_css_stream *stream,
+ 		params->fpn_config.data = NULL;
+ 	}
+ 	if (!params->fpn_config.data) {
+-		params->fpn_config.data = kvmalloc(height * width *
+-						   sizeof(short), GFP_KERNEL);
++		params->fpn_config.data = kvmalloc(array3_size(height, width, sizeof(short)),
++						   GFP_KERNEL);
+ 		if (!params->fpn_config.data) {
+ 			IA_CSS_ERROR("out of memory");
+ 			IA_CSS_LEAVE_ERR_PRIVATE(-ENOMEM);
+diff --git a/drivers/staging/media/sunxi/cedrus/Kconfig b/drivers/staging/media/sunxi/cedrus/Kconfig
+index 21c13f9b6e333..621944f9907a6 100644
+--- a/drivers/staging/media/sunxi/cedrus/Kconfig
++++ b/drivers/staging/media/sunxi/cedrus/Kconfig
+@@ -2,6 +2,7 @@
+ config VIDEO_SUNXI_CEDRUS
+ 	tristate "Allwinner Cedrus VPU driver"
+ 	depends on VIDEO_DEV
++	depends on RESET_CONTROLLER
+ 	depends on HAS_DMA
+ 	depends on OF
+ 	select MEDIA_CONTROLLER
+diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
+index 999b7c9697fcd..0722d21313055 100644
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -388,6 +388,15 @@ static const struct usb_device_id usb_quirk_list[] = {
+ 	/* Kingston DataTraveler 3.0 */
+ 	{ USB_DEVICE(0x0951, 0x1666), .driver_info = USB_QUIRK_NO_LPM },
+ 
++	/* NVIDIA Jetson devices in Force Recovery mode */
++	{ USB_DEVICE(0x0955, 0x7018), .driver_info = USB_QUIRK_RESET_RESUME },
++	{ USB_DEVICE(0x0955, 0x7019), .driver_info = USB_QUIRK_RESET_RESUME },
++	{ USB_DEVICE(0x0955, 0x7418), .driver_info = USB_QUIRK_RESET_RESUME },
++	{ USB_DEVICE(0x0955, 0x7721), .driver_info = USB_QUIRK_RESET_RESUME },
++	{ USB_DEVICE(0x0955, 0x7c18), .driver_info = USB_QUIRK_RESET_RESUME },
++	{ USB_DEVICE(0x0955, 0x7e19), .driver_info = USB_QUIRK_RESET_RESUME },
++	{ USB_DEVICE(0x0955, 0x7f21), .driver_info = USB_QUIRK_RESET_RESUME },
++
+ 	/* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */
+ 	{ USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF },
+ 
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 68d986361c495..d03e1a9c144c1 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -23,6 +23,7 @@
+ #include <linux/delay.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/of.h>
++#include <linux/of_graph.h>
+ #include <linux/acpi.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/reset.h>
+@@ -85,7 +86,7 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
+ 		 * mode. If the controller supports DRD but the dr_mode is not
+ 		 * specified or set to OTG, then set the mode to peripheral.
+ 		 */
+-		if (mode == USB_DR_MODE_OTG &&
++		if (mode == USB_DR_MODE_OTG && !dwc->edev &&
+ 		    (!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) ||
+ 		     !device_property_read_bool(dwc->dev, "usb-role-switch")) &&
+ 		    !DWC3_VER_IS_PRIOR(DWC3, 330A))
+@@ -1690,6 +1691,46 @@ static void dwc3_check_params(struct dwc3 *dwc)
+ 	}
+ }
+ 
++static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
++{
++	struct device *dev = dwc->dev;
++	struct device_node *np_phy;
++	struct extcon_dev *edev = NULL;
++	const char *name;
++
++	if (device_property_read_bool(dev, "extcon"))
++		return extcon_get_edev_by_phandle(dev, 0);
++
++	/*
++	 * Device tree platforms should get extcon via phandle.
++	 * On ACPI platforms, we get the name from a device property.
++	 * This device property is for kernel internal use only and
++	 * is expected to be set by the glue code.
++	 */
++	if (device_property_read_string(dev, "linux,extcon-name", &name) == 0)
++		return extcon_get_extcon_dev(name);
++
++	/*
++	 * Try to get an extcon device from the USB PHY controller's "port"
++	 * node. Check if it has the "port" node first, to avoid printing the
++	 * error message from underlying code, as it's a valid case: extcon
++	 * device (and "port" node) may be missing in case of "usb-role-switch"
++	 * or OTG mode.
++	 */
++	np_phy = of_parse_phandle(dev->of_node, "phys", 0);
++	if (of_graph_is_present(np_phy)) {
++		struct device_node *np_conn;
++
++		np_conn = of_graph_get_remote_node(np_phy, -1, -1);
++		if (np_conn)
++			edev = extcon_find_edev_by_node(np_conn);
++		of_node_put(np_conn);
++	}
++	of_node_put(np_phy);
++
++	return edev;
++}
++
+ static int dwc3_probe(struct platform_device *pdev)
+ {
+ 	struct device		*dev = &pdev->dev;
+@@ -1840,6 +1881,12 @@ static int dwc3_probe(struct platform_device *pdev)
+ 		goto err2;
+ 	}
+ 
++	dwc->edev = dwc3_get_extcon(dwc);
++	if (IS_ERR(dwc->edev)) {
++		ret = dev_err_probe(dwc->dev, PTR_ERR(dwc->edev), "failed to get extcon\n");
++		goto err3;
++	}
++
+ 	ret = dwc3_get_dr_mode(dwc);
+ 	if (ret)
+ 		goto err3;
+diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
+index 8cad9e7d33687..039bf241769af 100644
+--- a/drivers/usb/dwc3/drd.c
++++ b/drivers/usb/dwc3/drd.c
+@@ -8,7 +8,6 @@
+  */
+ 
+ #include <linux/extcon.h>
+-#include <linux/of_graph.h>
+ #include <linux/of_platform.h>
+ #include <linux/platform_device.h>
+ #include <linux/property.h>
+@@ -439,51 +438,6 @@ static int dwc3_drd_notifier(struct notifier_block *nb,
+ 	return NOTIFY_DONE;
+ }
+ 
+-static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
+-{
+-	struct device *dev = dwc->dev;
+-	struct device_node *np_phy;
+-	struct extcon_dev *edev = NULL;
+-	const char *name;
+-
+-	if (device_property_read_bool(dev, "extcon"))
+-		return extcon_get_edev_by_phandle(dev, 0);
+-
+-	/*
+-	 * Device tree platforms should get extcon via phandle.
+-	 * On ACPI platforms, we get the name from a device property.
+-	 * This device property is for kernel internal use only and
+-	 * is expected to be set by the glue code.
+-	 */
+-	if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) {
+-		edev = extcon_get_extcon_dev(name);
+-		if (!edev)
+-			return ERR_PTR(-EPROBE_DEFER);
+-
+-		return edev;
+-	}
+-
+-	/*
+-	 * Try to get an extcon device from the USB PHY controller's "port"
+-	 * node. Check if it has the "port" node first, to avoid printing the
+-	 * error message from underlying code, as it's a valid case: extcon
+-	 * device (and "port" node) may be missing in case of "usb-role-switch"
+-	 * or OTG mode.
+-	 */
+-	np_phy = of_parse_phandle(dev->of_node, "phys", 0);
+-	if (of_graph_is_present(np_phy)) {
+-		struct device_node *np_conn;
+-
+-		np_conn = of_graph_get_remote_node(np_phy, -1, -1);
+-		if (np_conn)
+-			edev = extcon_find_edev_by_node(np_conn);
+-		of_node_put(np_conn);
+-	}
+-	of_node_put(np_phy);
+-
+-	return edev;
+-}
+-
+ #if IS_ENABLED(CONFIG_USB_ROLE_SWITCH)
+ #define ROLE_SWITCH 1
+ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
+@@ -588,10 +542,6 @@ int dwc3_drd_init(struct dwc3 *dwc)
+ 	    device_property_read_bool(dwc->dev, "usb-role-switch"))
+ 		return dwc3_setup_role_switch(dwc);
+ 
+-	dwc->edev = dwc3_get_extcon(dwc);
+-	if (IS_ERR(dwc->edev))
+-		return PTR_ERR(dwc->edev);
+-
+ 	if (dwc->edev) {
+ 		dwc->edev_nb.notifier_call = dwc3_drd_notifier;
+ 		ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST,
+diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c
+index 6c14a79279f9a..fea5290de83fb 100644
+--- a/drivers/usb/dwc3/dwc3-st.c
++++ b/drivers/usb/dwc3/dwc3-st.c
+@@ -251,7 +251,7 @@ static int st_dwc3_probe(struct platform_device *pdev)
+ 	/* Manage SoftReset */
+ 	reset_control_deassert(dwc3_data->rstc_rst);
+ 
+-	child = of_get_child_by_name(node, "usb");
++	child = of_get_compatible_child(node, "snps,dwc3");
+ 	if (!child) {
+ 		dev_err(&pdev->dev, "failed to find dwc3 core node\n");
+ 		ret = -ENODEV;
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index eca945feeec3e..0ed9826a4c470 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1277,8 +1277,8 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
+ 			trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
+ 		}
+ 
+-		/* always enable Interrupt on Missed ISOC */
+-		trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
++		if (!no_interrupt && !chain)
++			trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
+ 		break;
+ 
+ 	case USB_ENDPOINT_XFER_BULK:
+@@ -1683,6 +1683,16 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int
+ 	cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
+ 	memset(&params, 0, sizeof(params));
+ 	ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
++	/*
++	 * If the End Transfer command was timed out while the device is
++	 * not in SETUP phase, it's possible that an incoming Setup packet
++	 * may prevent the command's completion. Let's retry when the
++	 * ep0state returns to EP0_SETUP_PHASE.
++	 */
++	if (ret == -ETIMEDOUT && dep->dwc->ep0state != EP0_SETUP_PHASE) {
++		dep->flags |= DWC3_EP_DELAY_STOP;
++		return 0;
++	}
+ 	WARN_ON_ONCE(ret);
+ 	dep->resource_index = 0;
+ 
+@@ -2501,6 +2511,9 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
+ 	if (dwc->ep0state != EP0_SETUP_PHASE) {
+ 		int ret;
+ 
++		if (dwc->delayed_status)
++			dwc3_ep0_send_delayed_status(dwc);
++
+ 		reinit_completion(&dwc->ep0_in_setup);
+ 
+ 		spin_unlock_irqrestore(&dwc->lock, flags);
+@@ -3215,6 +3228,10 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep,
+ 	if (event->status & DEPEVT_STATUS_SHORT && !chain)
+ 		return 1;
+ 
++	if ((trb->ctrl & DWC3_TRB_CTRL_ISP_IMI) &&
++	    DWC3_TRB_SIZE_TRBSTS(trb->size) == DWC3_TRBSTS_MISSED_ISOC)
++		return 1;
++
+ 	if ((trb->ctrl & DWC3_TRB_CTRL_IOC) ||
+ 	    (trb->ctrl & DWC3_TRB_CTRL_LST))
+ 		return 1;
+diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c
+index ec500ee499eed..0aa3d7e1f3cc3 100644
+--- a/drivers/usb/gadget/function/uvc_queue.c
++++ b/drivers/usb/gadget/function/uvc_queue.c
+@@ -304,6 +304,7 @@ int uvcg_queue_enable(struct uvc_video_queue *queue, int enable)
+ 
+ 		queue->sequence = 0;
+ 		queue->buf_used = 0;
++		queue->flags &= ~UVC_QUEUE_DROP_INCOMPLETE;
+ 	} else {
+ 		ret = vb2_streamoff(&queue->queue, queue->queue.type);
+ 		if (ret < 0)
+@@ -329,10 +330,11 @@ int uvcg_queue_enable(struct uvc_video_queue *queue, int enable)
+ void uvcg_complete_buffer(struct uvc_video_queue *queue,
+ 					  struct uvc_buffer *buf)
+ {
+-	if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
+-	     buf->length != buf->bytesused) {
+-		buf->state = UVC_BUF_STATE_QUEUED;
++	if (queue->flags & UVC_QUEUE_DROP_INCOMPLETE) {
++		queue->flags &= ~UVC_QUEUE_DROP_INCOMPLETE;
++		buf->state = UVC_BUF_STATE_ERROR;
+ 		vb2_set_plane_payload(&buf->buf.vb2_buf, 0, 0);
++		vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_ERROR);
+ 		return;
+ 	}
+ 
+diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
+index bb037fcc90e69..dd1c6b2ca7c6f 100644
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -88,6 +88,7 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
+ 		struct uvc_buffer *buf)
+ {
+ 	void *mem = req->buf;
++	struct uvc_request *ureq = req->context;
+ 	int len = video->req_size;
+ 	int ret;
+ 
+@@ -113,13 +114,14 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
+ 		video->queue.buf_used = 0;
+ 		buf->state = UVC_BUF_STATE_DONE;
+ 		list_del(&buf->queue);
+-		uvcg_complete_buffer(&video->queue, buf);
+ 		video->fid ^= UVC_STREAM_FID;
++		ureq->last_buf = buf;
+ 
+ 		video->payload_size = 0;
+ 	}
+ 
+ 	if (video->payload_size == video->max_payload_size ||
++	    video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE ||
+ 	    buf->bytesused == video->queue.buf_used)
+ 		video->payload_size = 0;
+ }
+@@ -155,10 +157,10 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
+ 	sg = sg_next(sg);
+ 
+ 	for_each_sg(sg, iter, ureq->sgt.nents - 1, i) {
+-		if (!len || !buf->sg || !sg_dma_len(buf->sg))
++		if (!len || !buf->sg || !buf->sg->length)
+ 			break;
+ 
+-		sg_left = sg_dma_len(buf->sg) - buf->offset;
++		sg_left = buf->sg->length - buf->offset;
+ 		part = min_t(unsigned int, len, sg_left);
+ 
+ 		sg_set_page(iter, sg_page(buf->sg), part, buf->offset);
+@@ -180,7 +182,8 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
+ 	req->length -= len;
+ 	video->queue.buf_used += req->length - header_len;
+ 
+-	if (buf->bytesused == video->queue.buf_used || !buf->sg) {
++	if (buf->bytesused == video->queue.buf_used || !buf->sg ||
++			video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) {
+ 		video->queue.buf_used = 0;
+ 		buf->state = UVC_BUF_STATE_DONE;
+ 		buf->offset = 0;
+@@ -195,6 +198,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
+ 		struct uvc_buffer *buf)
+ {
+ 	void *mem = req->buf;
++	struct uvc_request *ureq = req->context;
+ 	int len = video->req_size;
+ 	int ret;
+ 
+@@ -209,12 +213,13 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
+ 
+ 	req->length = video->req_size - len;
+ 
+-	if (buf->bytesused == video->queue.buf_used) {
++	if (buf->bytesused == video->queue.buf_used ||
++			video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) {
+ 		video->queue.buf_used = 0;
+ 		buf->state = UVC_BUF_STATE_DONE;
+ 		list_del(&buf->queue);
+-		uvcg_complete_buffer(&video->queue, buf);
+ 		video->fid ^= UVC_STREAM_FID;
++		ureq->last_buf = buf;
+ 	}
+ }
+ 
+@@ -255,6 +260,11 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
+ 	case 0:
+ 		break;
+ 
++	case -EXDEV:
++		uvcg_dbg(&video->uvc->func, "VS request missed xfer.\n");
++		queue->flags |= UVC_QUEUE_DROP_INCOMPLETE;
++		break;
++
+ 	case -ESHUTDOWN:	/* disconnect from host. */
+ 		uvcg_dbg(&video->uvc->func, "VS request cancelled.\n");
+ 		uvcg_queue_cancel(queue, 1);
+@@ -431,7 +441,8 @@ static void uvcg_video_pump(struct work_struct *work)
+ 
+ 		/* Endpoint now owns the request */
+ 		req = NULL;
+-		video->req_int_count++;
++		if (buf->state != UVC_BUF_STATE_DONE)
++			video->req_int_count++;
+ 	}
+ 
+ 	if (!req)
+diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
+index b0dfca43fbdce..4f3bc27c1c628 100644
+--- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c
++++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c
+@@ -591,6 +591,7 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
+ 		d->gadget.max_speed = USB_SPEED_HIGH;
+ 	d->gadget.speed = USB_SPEED_UNKNOWN;
+ 	d->gadget.dev.of_node = vhub->pdev->dev.of_node;
++	d->gadget.dev.of_node_reused = true;
+ 
+ 	rc = usb_add_gadget_udc(d->port_dev, &d->gadget);
+ 	if (rc != 0)
+diff --git a/drivers/usb/gadget/udc/bdc/bdc_udc.c b/drivers/usb/gadget/udc/bdc/bdc_udc.c
+index 5ac0ef88334eb..53ffaf4e2e376 100644
+--- a/drivers/usb/gadget/udc/bdc/bdc_udc.c
++++ b/drivers/usb/gadget/udc/bdc/bdc_udc.c
+@@ -151,6 +151,7 @@ static void bdc_uspc_disconnected(struct bdc *bdc, bool reinit)
+ 	bdc->delayed_status = false;
+ 	bdc->reinit = reinit;
+ 	bdc->test_mode = false;
++	usb_gadget_set_state(&bdc->gadget, USB_STATE_NOTATTACHED);
+ }
+ 
+ /* TNotify wkaeup timer */
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index 9e56aa28efcd4..81ca2bc1f0bef 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -889,15 +889,19 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
+ 		if (dev->eps[i].stream_info)
+ 			xhci_free_stream_info(xhci,
+ 					dev->eps[i].stream_info);
+-		/* Endpoints on the TT/root port lists should have been removed
+-		 * when usb_disable_device() was called for the device.
+-		 * We can't drop them anyway, because the udev might have gone
+-		 * away by this point, and we can't tell what speed it was.
++		/*
++		 * Endpoints are normally deleted from the bandwidth list when
++		 * endpoints are dropped, before device is freed.
++		 * If host is dying or being removed then endpoints aren't
++		 * dropped cleanly, so delete the endpoint from list here.
++		 * Only applicable for hosts with software bandwidth checking.
+ 		 */
+-		if (!list_empty(&dev->eps[i].bw_endpoint_list))
+-			xhci_warn(xhci, "Slot %u endpoint %u "
+-					"not removed from BW list!\n",
+-					slot_id, i);
++
++		if (!list_empty(&dev->eps[i].bw_endpoint_list)) {
++			list_del_init(&dev->eps[i].bw_endpoint_list);
++			xhci_dbg(xhci, "Slot %u endpoint %u not removed from BW list!\n",
++				 slot_id, i);
++		}
+ 	}
+ 	/* If this is a hub, free the TT(s) from the TT list */
+ 	xhci_free_tt_info(xhci, dev, slot_id);
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index dce6c0ec8d340..0a8d37c5af030 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -58,25 +58,13 @@
+ #define PCI_DEVICE_ID_INTEL_CML_XHCI			0xa3af
+ #define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI		0x9a13
+ #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI		0x1138
+-#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI		0x461e
+-#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI		0x464e
+-#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI	0x51ed
+-#define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_XHCI		0xa71e
+-#define PCI_DEVICE_ID_INTEL_METEOR_LAKE_XHCI		0x7ec0
++#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI		0x51ed
+ 
+ #define PCI_DEVICE_ID_AMD_RENOIR_XHCI			0x1639
+ #define PCI_DEVICE_ID_AMD_PROMONTORYA_4			0x43b9
+ #define PCI_DEVICE_ID_AMD_PROMONTORYA_3			0x43ba
+ #define PCI_DEVICE_ID_AMD_PROMONTORYA_2			0x43bb
+ #define PCI_DEVICE_ID_AMD_PROMONTORYA_1			0x43bc
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_1		0x161a
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_2		0x161b
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_3		0x161d
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_4		0x161e
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_5		0x15d6
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_6		0x15d7
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_7		0x161c
+-#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_8		0x161f
+ 
+ #define PCI_DEVICE_ID_ASMEDIA_1042_XHCI			0x1042
+ #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI		0x1142
+@@ -257,6 +245,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ 	     pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI))
+ 		xhci->quirks |= XHCI_MISSING_CAS;
+ 
++	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
++	    pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI)
++		xhci->quirks |= XHCI_RESET_TO_DEFAULT;
++
+ 	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+ 	    (pdev->device == PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_XHCI ||
+ 	     pdev->device == PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_XHCI ||
+@@ -268,12 +260,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ 	     pdev->device == PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_XHCI ||
+ 	     pdev->device == PCI_DEVICE_ID_INTEL_ICE_LAKE_XHCI ||
+ 	     pdev->device == PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI ||
+-	     pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI ||
+-	     pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI ||
+-	     pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI ||
+-	     pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI ||
+-	     pdev->device == PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_XHCI ||
+-	     pdev->device == PCI_DEVICE_ID_INTEL_METEOR_LAKE_XHCI))
++	     pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI))
+ 		xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
+ 
+ 	if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
+@@ -306,8 +293,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ 	}
+ 
+ 	if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+-		pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI)
++		pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) {
++		/*
++		 * try to tame the ASMedia 1042 controller which reports 0.96
++		 * but appears to behave more like 1.0
++		 */
++		xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
+ 		xhci->quirks |= XHCI_BROKEN_STREAMS;
++	}
+ 	if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+ 		pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) {
+ 		xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+@@ -336,15 +329,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ 	     pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4))
+ 		xhci->quirks |= XHCI_NO_SOFT_RETRY;
+ 
+-	if (pdev->vendor == PCI_VENDOR_ID_AMD &&
+-	    (pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_1 ||
+-	    pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_2 ||
+-	    pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_3 ||
+-	    pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_4 ||
+-	    pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_5 ||
+-	    pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_6 ||
+-	    pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_7 ||
+-	    pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_8))
++	/* xHC spec requires PCI devices to support D3hot and D3cold */
++	if (xhci->hci_version >= 0x120)
+ 		xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
+ 
+ 	if (xhci->quirks & XHCI_RESET_ON_RESUME)
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index a7ef675f00fdd..44078a05a0fed 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -810,9 +810,15 @@ void xhci_shutdown(struct usb_hcd *hcd)
+ 
+ 	spin_lock_irq(&xhci->lock);
+ 	xhci_halt(xhci);
+-	/* Workaround for spurious wakeups at shutdown with HSW */
+-	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP)
++
++	/*
++	 * Workaround for spurious wakeps at shutdown with HSW, and for boot
++	 * firmware delay in ADL-P PCH if port are left in U3 at shutdown
++	 */
++	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP ||
++	    xhci->quirks & XHCI_RESET_TO_DEFAULT)
+ 		xhci_reset(xhci, XHCI_RESET_SHORT_USEC);
++
+ 	spin_unlock_irq(&xhci->lock);
+ 
+ 	xhci_cleanup_msix(xhci);
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 6dfbf73ee840d..a6daf37ff4bf7 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1900,6 +1900,7 @@ struct xhci_hcd {
+ #define XHCI_BROKEN_D3COLD	BIT_ULL(41)
+ #define XHCI_EP_CTX_BROKEN_DCS	BIT_ULL(42)
+ #define XHCI_SUSPEND_RESUME_CLKS	BIT_ULL(43)
++#define XHCI_RESET_TO_DEFAULT	BIT_ULL(44)
+ 
+ 	unsigned int		num_active_eps;
+ 	unsigned int		limit_active_eps;
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index 74fb5a4c6f21b..a7987fc764cc6 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -183,16 +183,6 @@ out:
+ }
+ EXPORT_SYMBOL_GPL(ucsi_send_command);
+ 
+-int ucsi_resume(struct ucsi *ucsi)
+-{
+-	u64 command;
+-
+-	/* Restore UCSI notification enable mask after system resume */
+-	command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
+-
+-	return ucsi_send_command(ucsi, command, NULL, 0);
+-}
+-EXPORT_SYMBOL_GPL(ucsi_resume);
+ /* -------------------------------------------------------------------------- */
+ 
+ struct ucsi_work {
+@@ -744,6 +734,7 @@ static void ucsi_partner_change(struct ucsi_connector *con)
+ 
+ static int ucsi_check_connection(struct ucsi_connector *con)
+ {
++	u8 prev_flags = con->status.flags;
+ 	u64 command;
+ 	int ret;
+ 
+@@ -754,10 +745,13 @@ static int ucsi_check_connection(struct ucsi_connector *con)
+ 		return ret;
+ 	}
+ 
++	if (con->status.flags == prev_flags)
++		return 0;
++
+ 	if (con->status.flags & UCSI_CONSTAT_CONNECTED) {
+-		if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) ==
+-		    UCSI_CONSTAT_PWR_OPMODE_PD)
+-			ucsi_partner_task(con, ucsi_check_altmodes, 30, 0);
++		ucsi_register_partner(con);
++		ucsi_pwr_opmode_change(con);
++		ucsi_partner_change(con);
+ 	} else {
+ 		ucsi_partner_change(con);
+ 		ucsi_port_psy_changed(con);
+@@ -1276,6 +1270,28 @@ err:
+ 	return ret;
+ }
+ 
++int ucsi_resume(struct ucsi *ucsi)
++{
++	struct ucsi_connector *con;
++	u64 command;
++	int ret;
++
++	/* Restore UCSI notification enable mask after system resume */
++	command = UCSI_SET_NOTIFICATION_ENABLE | ucsi->ntfy;
++	ret = ucsi_send_command(ucsi, command, NULL, 0);
++	if (ret < 0)
++		return ret;
++
++	for (con = ucsi->connector; con->port; con++) {
++		mutex_lock(&con->lock);
++		ucsi_check_connection(con);
++		mutex_unlock(&con->lock);
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL_GPL(ucsi_resume);
++
+ static void ucsi_init_work(struct work_struct *work)
+ {
+ 	struct ucsi *ucsi = container_of(work, struct ucsi, work.work);
+diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c
+index 8873c1644a295..ce0c8ef80c043 100644
+--- a/drivers/usb/typec/ucsi/ucsi_acpi.c
++++ b/drivers/usb/typec/ucsi/ucsi_acpi.c
+@@ -185,6 +185,15 @@ static int ucsi_acpi_remove(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
++static int ucsi_acpi_resume(struct device *dev)
++{
++	struct ucsi_acpi *ua = dev_get_drvdata(dev);
++
++	return ucsi_resume(ua->ucsi);
++}
++
++static DEFINE_SIMPLE_DEV_PM_OPS(ucsi_acpi_pm_ops, NULL, ucsi_acpi_resume);
++
+ static const struct acpi_device_id ucsi_acpi_match[] = {
+ 	{ "PNP0CA0", 0 },
+ 	{ },
+@@ -194,6 +203,7 @@ MODULE_DEVICE_TABLE(acpi, ucsi_acpi_match);
+ static struct platform_driver ucsi_acpi_platform_driver = {
+ 	.driver = {
+ 		.name = "ucsi_acpi",
++		.pm = pm_ptr(&ucsi_acpi_pm_ops),
+ 		.acpi_match_table = ACPI_PTR(ucsi_acpi_match),
+ 	},
+ 	.probe = ucsi_acpi_probe,
+diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c
+index 9223d3d4089f1..013a382bf5f48 100644
+--- a/drivers/video/aperture.c
++++ b/drivers/video/aperture.c
+@@ -351,12 +351,9 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na
+ 		size = pci_resource_len(pdev, bar);
+ 		ret = aperture_remove_conflicting_devices(base, size, primary, name);
+ 		if (ret)
+-			break;
++			return ret;
+ 	}
+ 
+-	if (ret)
+-		return ret;
+-
+ 	/*
+ 	 * If a driver asked to unregister a platform device registered by
+ 	 * sysfb, then can be assumed that this is a driver for a display
+diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
+index e65bdc499c236..9343b7a4ac899 100644
+--- a/drivers/video/fbdev/smscufx.c
++++ b/drivers/video/fbdev/smscufx.c
+@@ -97,7 +97,6 @@ struct ufx_data {
+ 	struct kref kref;
+ 	int fb_count;
+ 	bool virtualized; /* true when physical usb device not present */
+-	struct delayed_work free_framebuffer_work;
+ 	atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */
+ 	atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
+ 	u8 *edid; /* null until we read edid from hw or get from sysfs */
+@@ -1117,15 +1116,24 @@ static void ufx_free(struct kref *kref)
+ {
+ 	struct ufx_data *dev = container_of(kref, struct ufx_data, kref);
+ 
+-	/* this function will wait for all in-flight urbs to complete */
+-	if (dev->urbs.count > 0)
+-		ufx_free_urb_list(dev);
++	kfree(dev);
++}
+ 
+-	pr_debug("freeing ufx_data %p", dev);
++static void ufx_ops_destory(struct fb_info *info)
++{
++	struct ufx_data *dev = info->par;
++	int node = info->node;
+ 
+-	kfree(dev);
++	/* Assume info structure is freed after this point */
++	framebuffer_release(info);
++
++	pr_debug("fb_info for /dev/fb%d has been freed", node);
++
++	/* release reference taken by kref_init in probe() */
++	kref_put(&dev->kref, ufx_free);
+ }
+ 
++
+ static void ufx_release_urb_work(struct work_struct *work)
+ {
+ 	struct urb_node *unode = container_of(work, struct urb_node,
+@@ -1134,14 +1142,9 @@ static void ufx_release_urb_work(struct work_struct *work)
+ 	up(&unode->dev->urbs.limit_sem);
+ }
+ 
+-static void ufx_free_framebuffer_work(struct work_struct *work)
++static void ufx_free_framebuffer(struct ufx_data *dev)
+ {
+-	struct ufx_data *dev = container_of(work, struct ufx_data,
+-					    free_framebuffer_work.work);
+ 	struct fb_info *info = dev->info;
+-	int node = info->node;
+-
+-	unregister_framebuffer(info);
+ 
+ 	if (info->cmap.len != 0)
+ 		fb_dealloc_cmap(&info->cmap);
+@@ -1153,11 +1156,6 @@ static void ufx_free_framebuffer_work(struct work_struct *work)
+ 
+ 	dev->info = NULL;
+ 
+-	/* Assume info structure is freed after this point */
+-	framebuffer_release(info);
+-
+-	pr_debug("fb_info for /dev/fb%d has been freed", node);
+-
+ 	/* ref taken in probe() as part of registering framebfufer */
+ 	kref_put(&dev->kref, ufx_free);
+ }
+@@ -1169,11 +1167,13 @@ static int ufx_ops_release(struct fb_info *info, int user)
+ {
+ 	struct ufx_data *dev = info->par;
+ 
++	mutex_lock(&disconnect_mutex);
++
+ 	dev->fb_count--;
+ 
+ 	/* We can't free fb_info here - fbmem will touch it when we return */
+ 	if (dev->virtualized && (dev->fb_count == 0))
+-		schedule_delayed_work(&dev->free_framebuffer_work, HZ);
++		ufx_free_framebuffer(dev);
+ 
+ 	if ((dev->fb_count == 0) && (info->fbdefio)) {
+ 		fb_deferred_io_cleanup(info);
+@@ -1186,6 +1186,8 @@ static int ufx_ops_release(struct fb_info *info, int user)
+ 
+ 	kref_put(&dev->kref, ufx_free);
+ 
++	mutex_unlock(&disconnect_mutex);
++
+ 	return 0;
+ }
+ 
+@@ -1292,6 +1294,7 @@ static const struct fb_ops ufx_ops = {
+ 	.fb_blank = ufx_ops_blank,
+ 	.fb_check_var = ufx_ops_check_var,
+ 	.fb_set_par = ufx_ops_set_par,
++	.fb_destroy = ufx_ops_destory,
+ };
+ 
+ /* Assumes &info->lock held by caller
+@@ -1673,9 +1676,6 @@ static int ufx_usb_probe(struct usb_interface *interface,
+ 		goto destroy_modedb;
+ 	}
+ 
+-	INIT_DELAYED_WORK(&dev->free_framebuffer_work,
+-			  ufx_free_framebuffer_work);
+-
+ 	retval = ufx_reg_read(dev, 0x3000, &id_rev);
+ 	check_warn_goto_error(retval, "error %d reading 0x3000 register from device", retval);
+ 	dev_dbg(dev->gdev, "ID_REV register value 0x%08x", id_rev);
+@@ -1748,10 +1748,12 @@ e_nomem:
+ static void ufx_usb_disconnect(struct usb_interface *interface)
+ {
+ 	struct ufx_data *dev;
++	struct fb_info *info;
+ 
+ 	mutex_lock(&disconnect_mutex);
+ 
+ 	dev = usb_get_intfdata(interface);
++	info = dev->info;
+ 
+ 	pr_debug("USB disconnect starting\n");
+ 
+@@ -1765,12 +1767,15 @@ static void ufx_usb_disconnect(struct usb_interface *interface)
+ 
+ 	/* if clients still have us open, will be freed on last close */
+ 	if (dev->fb_count == 0)
+-		schedule_delayed_work(&dev->free_framebuffer_work, 0);
++		ufx_free_framebuffer(dev);
+ 
+-	/* release reference taken by kref_init in probe() */
+-	kref_put(&dev->kref, ufx_free);
++	/* this function will wait for all in-flight urbs to complete */
++	if (dev->urbs.count > 0)
++		ufx_free_urb_list(dev);
+ 
+-	/* consider ufx_data freed */
++	pr_debug("freeing ufx_data %p", dev);
++
++	unregister_framebuffer(info);
+ 
+ 	mutex_unlock(&disconnect_mutex);
+ }
+diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c
+index 7753e586e65a0..3feb6e40d56d8 100644
+--- a/drivers/video/fbdev/stifb.c
++++ b/drivers/video/fbdev/stifb.c
+@@ -1055,7 +1055,8 @@ stifb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+ {
+ 	struct stifb_info *fb = container_of(info, struct stifb_info, info);
+ 
+-	if (rect->rop != ROP_COPY)
++	if (rect->rop != ROP_COPY ||
++	    (fb->id == S9000_ID_HCRX && fb->info.var.bits_per_pixel == 32))
+ 		return cfb_fillrect(info, rect);
+ 
+ 	SETUP_HW(fb);
+diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
+index 63c7ebb0da898..6a11025e58502 100644
+--- a/fs/binfmt_elf.c
++++ b/fs/binfmt_elf.c
+@@ -911,7 +911,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
+ 		interp_elf_ex = kmalloc(sizeof(*interp_elf_ex), GFP_KERNEL);
+ 		if (!interp_elf_ex) {
+ 			retval = -ENOMEM;
+-			goto out_free_ph;
++			goto out_free_file;
+ 		}
+ 
+ 		/* Get the exec headers */
+@@ -1354,6 +1354,7 @@ out:
+ out_free_dentry:
+ 	kfree(interp_elf_ex);
+ 	kfree(interp_elf_phdata);
++out_free_file:
+ 	allow_write_access(interpreter);
+ 	if (interpreter)
+ 		fput(interpreter);
+diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
+index 6e663275aeb13..c7511b4317763 100644
+--- a/fs/erofs/zdata.c
++++ b/fs/erofs/zdata.c
+@@ -765,13 +765,13 @@ retry:
+ 	if (fe->pcl->pageofs_out != (map->m_la & ~PAGE_MASK))
+ 		fe->pcl->multibases = true;
+ 
+-	if ((map->m_flags & EROFS_MAP_FULL_MAPPED) &&
+-	    fe->pcl->length == map->m_llen)
+-		fe->pcl->partial = false;
+ 	if (fe->pcl->length < offset + end - map->m_la) {
+ 		fe->pcl->length = offset + end - map->m_la;
+ 		fe->pcl->pageofs_out = map->m_la & ~PAGE_MASK;
+ 	}
++	if ((map->m_flags & EROFS_MAP_FULL_MAPPED) &&
++	     fe->pcl->length == map->m_llen)
++		fe->pcl->partial = false;
+ next_part:
+ 	/* shorten the remaining extent to update progress */
+ 	map->m_llen = offset + cur - map->m_la;
+diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
+index d58549ca1df9b..63fd2f1460265 100644
+--- a/fs/erofs/zmap.c
++++ b/fs/erofs/zmap.c
+@@ -61,8 +61,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
+ 
+ 	pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize +
+ 		    vi->xattr_isize, 8);
+-	kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos),
+-				   EROFS_KMAP_ATOMIC);
++	kaddr = erofs_read_metabuf(&buf, sb, erofs_blknr(pos), EROFS_KMAP);
+ 	if (IS_ERR(kaddr)) {
+ 		err = PTR_ERR(kaddr);
+ 		goto out_unlock;
+@@ -79,7 +78,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
+ 		erofs_err(sb, "unknown HEAD%u format %u for nid %llu, please upgrade kernel",
+ 			  headnr + 1, vi->z_algorithmtype[headnr], vi->nid);
+ 		err = -EOPNOTSUPP;
+-		goto unmap_done;
++		goto out_put_metabuf;
+ 	}
+ 
+ 	vi->z_logical_clusterbits = LOG_BLOCK_SIZE + (h->h_clusterbits & 7);
+@@ -89,7 +88,7 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
+ 		erofs_err(sb, "per-inode big pcluster without sb feature for nid %llu",
+ 			  vi->nid);
+ 		err = -EFSCORRUPTED;
+-		goto unmap_done;
++		goto out_put_metabuf;
+ 	}
+ 	if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION &&
+ 	    !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^
+@@ -97,12 +96,8 @@ static int z_erofs_fill_inode_lazy(struct inode *inode)
+ 		erofs_err(sb, "big pcluster head1/2 of compact indexes should be consistent for nid %llu",
+ 			  vi->nid);
+ 		err = -EFSCORRUPTED;
+-		goto unmap_done;
++		goto out_put_metabuf;
+ 	}
+-unmap_done:
+-	erofs_put_metabuf(&buf);
+-	if (err)
+-		goto out_unlock;
+ 
+ 	if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) {
+ 		struct erofs_map_blocks map = {
+@@ -121,11 +116,13 @@ unmap_done:
+ 			err = -EFSCORRUPTED;
+ 		}
+ 		if (err < 0)
+-			goto out_unlock;
++			goto out_put_metabuf;
+ 	}
+ 	/* paired with smp_mb() at the beginning of the function */
+ 	smp_mb();
+ 	set_bit(EROFS_I_Z_INITED_BIT, &vi->flags);
++out_put_metabuf:
++	erofs_put_metabuf(&buf);
+ out_unlock:
+ 	clear_and_wake_up_bit(EROFS_I_BL_Z_BIT, &vi->flags);
+ 	return err;
+diff --git a/fs/exec.c b/fs/exec.c
+index d046dbb9cbd08..6f3d6fce178f2 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -1196,11 +1196,11 @@ static int unshare_sighand(struct task_struct *me)
+ 			return -ENOMEM;
+ 
+ 		refcount_set(&newsighand->count, 1);
+-		memcpy(newsighand->action, oldsighand->action,
+-		       sizeof(newsighand->action));
+ 
+ 		write_lock_irq(&tasklist_lock);
+ 		spin_lock(&oldsighand->siglock);
++		memcpy(newsighand->action, oldsighand->action,
++		       sizeof(newsighand->action));
+ 		rcu_assign_pointer(me->sighand, newsighand);
+ 		spin_unlock(&oldsighand->siglock);
+ 		write_unlock_irq(&tasklist_lock);
+diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
+index 1cc88ba6de907..2e9313988871b 100644
+--- a/fs/kernfs/dir.c
++++ b/fs/kernfs/dir.c
+@@ -1585,8 +1585,11 @@ int kernfs_remove_by_name_ns(struct kernfs_node *parent, const char *name,
+ 	down_write(&root->kernfs_rwsem);
+ 
+ 	kn = kernfs_find_ns(parent, name, ns);
+-	if (kn)
++	if (kn) {
++		kernfs_get(kn);
+ 		__kernfs_remove(kn);
++		kernfs_put(kn);
++	}
+ 
+ 	up_write(&root->kernfs_rwsem);
+ 
+diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c
+index e56510964b229..8ba8c4c507707 100644
+--- a/fs/squashfs/file.c
++++ b/fs/squashfs/file.c
+@@ -506,8 +506,9 @@ static int squashfs_readahead_fragment(struct page **page,
+ 		squashfs_i(inode)->fragment_size);
+ 	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
+ 	unsigned int n, mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1;
++	int error = buffer->error;
+ 
+-	if (buffer->error)
++	if (error)
+ 		goto out;
+ 
+ 	expected += squashfs_i(inode)->fragment_offset;
+@@ -529,7 +530,7 @@ static int squashfs_readahead_fragment(struct page **page,
+ 
+ out:
+ 	squashfs_cache_put(buffer);
+-	return buffer->error;
++	return error;
+ }
+ 
+ static void squashfs_readahead(struct readahead_control *ractl)
+@@ -557,6 +558,13 @@ static void squashfs_readahead(struct readahead_control *ractl)
+ 		int res, bsize;
+ 		u64 block = 0;
+ 		unsigned int expected;
++		struct page *last_page;
++
++		expected = start >> msblk->block_log == file_end ?
++			   (i_size_read(inode) & (msblk->block_size - 1)) :
++			    msblk->block_size;
++
++		max_pages = (expected + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ 
+ 		nr_pages = __readahead_batch(ractl, pages, max_pages);
+ 		if (!nr_pages)
+@@ -566,13 +574,10 @@ static void squashfs_readahead(struct readahead_control *ractl)
+ 			goto skip_pages;
+ 
+ 		index = pages[0]->index >> shift;
++
+ 		if ((pages[nr_pages - 1]->index >> shift) != index)
+ 			goto skip_pages;
+ 
+-		expected = index == file_end ?
+-			   (i_size_read(inode) & (msblk->block_size - 1)) :
+-			    msblk->block_size;
+-
+ 		if (index == file_end && squashfs_i(inode)->fragment_block !=
+ 						SQUASHFS_INVALID_BLK) {
+ 			res = squashfs_readahead_fragment(pages, nr_pages,
+@@ -593,15 +598,15 @@ static void squashfs_readahead(struct readahead_control *ractl)
+ 
+ 		res = squashfs_read_data(inode->i_sb, block, bsize, NULL, actor);
+ 
+-		squashfs_page_actor_free(actor);
++		last_page = squashfs_page_actor_free(actor);
+ 
+ 		if (res == expected) {
+ 			int bytes;
+ 
+ 			/* Last page (if present) may have trailing bytes not filled */
+ 			bytes = res % PAGE_SIZE;
+-			if (pages[nr_pages - 1]->index == file_end && bytes)
+-				memzero_page(pages[nr_pages - 1], bytes,
++			if (index == file_end && bytes && last_page)
++				memzero_page(last_page, bytes,
+ 					     PAGE_SIZE - bytes);
+ 
+ 			for (i = 0; i < nr_pages; i++) {
+diff --git a/fs/squashfs/page_actor.c b/fs/squashfs/page_actor.c
+index 54b93bf4a25c1..81af6c4ca1157 100644
+--- a/fs/squashfs/page_actor.c
++++ b/fs/squashfs/page_actor.c
+@@ -71,11 +71,13 @@ static void *handle_next_page(struct squashfs_page_actor *actor)
+ 			(actor->next_index != actor->page[actor->next_page]->index)) {
+ 		actor->next_index++;
+ 		actor->returned_pages++;
++		actor->last_page = NULL;
+ 		return actor->alloc_buffer ? actor->tmp_buffer : ERR_PTR(-ENOMEM);
+ 	}
+ 
+ 	actor->next_index++;
+ 	actor->returned_pages++;
++	actor->last_page = actor->page[actor->next_page];
+ 	return actor->pageaddr = kmap_local_page(actor->page[actor->next_page++]);
+ }
+ 
+@@ -125,6 +127,7 @@ struct squashfs_page_actor *squashfs_page_actor_init_special(struct squashfs_sb_
+ 	actor->returned_pages = 0;
+ 	actor->next_index = page[0]->index & ~((1 << (msblk->block_log - PAGE_SHIFT)) - 1);
+ 	actor->pageaddr = NULL;
++	actor->last_page = NULL;
+ 	actor->alloc_buffer = msblk->decompressor->alloc_buffer;
+ 	actor->squashfs_first_page = direct_first_page;
+ 	actor->squashfs_next_page = direct_next_page;
+diff --git a/fs/squashfs/page_actor.h b/fs/squashfs/page_actor.h
+index 95ffbb543d913..97d4983559b19 100644
+--- a/fs/squashfs/page_actor.h
++++ b/fs/squashfs/page_actor.h
+@@ -16,6 +16,7 @@ struct squashfs_page_actor {
+ 	void    *(*squashfs_first_page)(struct squashfs_page_actor *);
+ 	void    *(*squashfs_next_page)(struct squashfs_page_actor *);
+ 	void    (*squashfs_finish_page)(struct squashfs_page_actor *);
++	struct page *last_page;
+ 	int	pages;
+ 	int	length;
+ 	int	next_page;
+@@ -29,10 +30,13 @@ extern struct squashfs_page_actor *squashfs_page_actor_init(void **buffer,
+ extern struct squashfs_page_actor *squashfs_page_actor_init_special(
+ 				struct squashfs_sb_info *msblk,
+ 				struct page **page, int pages, int length);
+-static inline void squashfs_page_actor_free(struct squashfs_page_actor *actor)
++static inline struct page *squashfs_page_actor_free(struct squashfs_page_actor *actor)
+ {
++	struct page *last_page = actor->last_page;
++
+ 	kfree(actor->tmp_buffer);
+ 	kfree(actor);
++	return last_page;
+ }
+ static inline void *squashfs_first_page(struct squashfs_page_actor *actor)
+ {
+diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
+index c32de987fa71c..454dab40baf69 100644
+--- a/include/linux/mlx5/driver.h
++++ b/include/linux/mlx5/driver.h
+@@ -973,7 +973,7 @@ void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode);
+ struct mlx5_async_ctx {
+ 	struct mlx5_core_dev *dev;
+ 	atomic_t num_inflight;
+-	struct wait_queue_head wait;
++	struct completion inflight_done;
+ };
+ 
+ struct mlx5_async_work;
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index ee8b9ecdc03b7..00df832584471 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -736,11 +736,14 @@ struct perf_event {
+ 	struct fasync_struct		*fasync;
+ 
+ 	/* delayed work for NMIs and such */
+-	int				pending_wakeup;
+-	int				pending_kill;
+-	int				pending_disable;
++	unsigned int			pending_wakeup;
++	unsigned int			pending_kill;
++	unsigned int			pending_disable;
++	unsigned int			pending_sigtrap;
+ 	unsigned long			pending_addr;	/* SIGTRAP */
+-	struct irq_work			pending;
++	struct irq_work			pending_irq;
++	struct callback_head		pending_task;
++	unsigned int			pending_work;
+ 
+ 	atomic_t			event_limit;
+ 
+@@ -857,6 +860,14 @@ struct perf_event_context {
+ #endif
+ 	void				*task_ctx_data; /* pmu specific data */
+ 	struct rcu_head			rcu_head;
++
++	/*
++	 * Sum (event->pending_sigtrap + event->pending_work)
++	 *
++	 * The SIGTRAP is targeted at ctx->task, as such it won't do changing
++	 * that until the signal is delivered.
++	 */
++	local_t				nr_pending;
+ };
+ 
+ /*
+diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h
+index e1b8a915e9e9f..31d86b8c0634f 100644
+--- a/include/linux/userfaultfd_k.h
++++ b/include/linux/userfaultfd_k.h
+@@ -146,9 +146,9 @@ static inline bool userfaultfd_armed(struct vm_area_struct *vma)
+ static inline bool vma_can_userfault(struct vm_area_struct *vma,
+ 				     unsigned long vm_flags)
+ {
+-	if (vm_flags & VM_UFFD_MINOR)
+-		return is_vm_hugetlb_page(vma) || vma_is_shmem(vma);
+-
++	if ((vm_flags & VM_UFFD_MINOR) &&
++	    (!is_vm_hugetlb_page(vma) && !vma_is_shmem(vma)))
++		return false;
+ #ifndef CONFIG_PTE_MARKER_UFFD_WP
+ 	/*
+ 	 * If user requested uffd-wp but not enabled pte markers for
+diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
+index b708d63995f45..2ae2be4c87e5a 100644
+--- a/include/media/v4l2-common.h
++++ b/include/media/v4l2-common.h
+@@ -175,7 +175,8 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
+  *
+  * @sd: pointer to &struct v4l2_subdev
+  * @client: pointer to struct i2c_client
+- * @devname: the name of the device; if NULL, the I²C device's name will be used
++ * @devname: the name of the device; if NULL, the I²C device drivers's name
++ *           will be used
+  * @postfix: sub-device specific string to put right after the I²C device name;
+  *	     may be NULL
+  */
+diff --git a/include/net/sock.h b/include/net/sock.h
+index d08cfe190a78b..8a98ea9360fb7 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -2567,7 +2567,7 @@ static inline gfp_t gfp_any(void)
+ 
+ static inline gfp_t gfp_memcg_charge(void)
+ {
+-	return in_softirq() ? GFP_NOWAIT : GFP_KERNEL;
++	return in_softirq() ? GFP_ATOMIC : GFP_KERNEL;
+ }
+ 
+ static inline long sock_rcvtimeo(const struct sock *sk, bool noblock)
+diff --git a/include/sound/control.h b/include/sound/control.h
+index eae443ba79ba5..cc3dcc6cfb0f2 100644
+--- a/include/sound/control.h
++++ b/include/sound/control.h
+@@ -138,6 +138,7 @@ int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
+ int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace);
+ int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
+ int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
++void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, const char *name);
+ int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, int active);
+ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);
+ struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);
+diff --git a/include/sound/soc-acpi-intel-match.h b/include/sound/soc-acpi-intel-match.h
+index bc7fd46ec2bc8..ac750afa7bc6c 100644
+--- a/include/sound/soc-acpi-intel-match.h
++++ b/include/sound/soc-acpi-intel-match.h
+@@ -30,6 +30,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_ehl_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_jsl_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[];
++extern struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[];
+ 
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cnl_sdw_machines[];
+@@ -38,6 +39,7 @@ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_sdw_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_sdw_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[];
++extern struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[];
+ extern struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[];
+ 
+ /*
+diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
+index 01e630f2ec786..fbe40307934d0 100644
+--- a/include/uapi/linux/videodev2.h
++++ b/include/uapi/linux/videodev2.h
+@@ -1602,7 +1602,8 @@ struct v4l2_bt_timings {
+ 	((bt)->width + V4L2_DV_BT_BLANKING_WIDTH(bt))
+ #define V4L2_DV_BT_BLANKING_HEIGHT(bt) \
+ 	((bt)->vfrontporch + (bt)->vsync + (bt)->vbackporch + \
+-	 (bt)->il_vfrontporch + (bt)->il_vsync + (bt)->il_vbackporch)
++	 ((bt)->interlaced ? \
++	  ((bt)->il_vfrontporch + (bt)->il_vsync + (bt)->il_vbackporch) : 0))
+ #define V4L2_DV_BT_FRAME_HEIGHT(bt) \
+ 	((bt)->height + V4L2_DV_BT_BLANKING_HEIGHT(bt))
+ 
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 36fd4b509294a..0d23d4bcd81cc 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -4436,6 +4436,11 @@ static int btf_func_proto_check(struct btf_verifier_env *env,
+ 			return -EINVAL;
+ 		}
+ 
++		if (btf_type_is_resolve_source_only(ret_type)) {
++			btf_verifier_log_type(env, t, "Invalid return type");
++			return -EINVAL;
++		}
++
+ 		if (btf_type_needs_resolve(ret_type) &&
+ 		    !env_type_is_resolved(env, ret_type_id)) {
+ 			err = btf_resolve(env, ret_type, ret_type_id);
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index ff4bffc502c67..072ab26269c0b 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -54,6 +54,7 @@
+ #include <linux/highmem.h>
+ #include <linux/pgtable.h>
+ #include <linux/buildid.h>
++#include <linux/task_work.h>
+ 
+ #include "internal.h"
+ 
+@@ -2268,11 +2269,26 @@ event_sched_out(struct perf_event *event,
+ 	event->pmu->del(event, 0);
+ 	event->oncpu = -1;
+ 
+-	if (READ_ONCE(event->pending_disable) >= 0) {
+-		WRITE_ONCE(event->pending_disable, -1);
++	if (event->pending_disable) {
++		event->pending_disable = 0;
+ 		perf_cgroup_event_disable(event, ctx);
+ 		state = PERF_EVENT_STATE_OFF;
+ 	}
++
++	if (event->pending_sigtrap) {
++		bool dec = true;
++
++		event->pending_sigtrap = 0;
++		if (state != PERF_EVENT_STATE_OFF &&
++		    !event->pending_work) {
++			event->pending_work = 1;
++			dec = false;
++			task_work_add(current, &event->pending_task, TWA_RESUME);
++		}
++		if (dec)
++			local_dec(&event->ctx->nr_pending);
++	}
++
+ 	perf_event_set_state(event, state);
+ 
+ 	if (!is_software_event(event))
+@@ -2424,7 +2440,7 @@ static void __perf_event_disable(struct perf_event *event,
+  * hold the top-level event's child_mutex, so any descendant that
+  * goes to exit will block in perf_event_exit_event().
+  *
+- * When called from perf_pending_event it's OK because event->ctx
++ * When called from perf_pending_irq it's OK because event->ctx
+  * is the current context on this CPU and preemption is disabled,
+  * hence we can't get into perf_event_task_sched_out for this context.
+  */
+@@ -2463,9 +2479,8 @@ EXPORT_SYMBOL_GPL(perf_event_disable);
+ 
+ void perf_event_disable_inatomic(struct perf_event *event)
+ {
+-	WRITE_ONCE(event->pending_disable, smp_processor_id());
+-	/* can fail, see perf_pending_event_disable() */
+-	irq_work_queue(&event->pending);
++	event->pending_disable = 1;
++	irq_work_queue(&event->pending_irq);
+ }
+ 
+ #define MAX_INTERRUPTS (~0ULL)
+@@ -3420,11 +3435,23 @@ static void perf_event_context_sched_out(struct task_struct *task, int ctxn,
+ 		raw_spin_lock_nested(&next_ctx->lock, SINGLE_DEPTH_NESTING);
+ 		if (context_equiv(ctx, next_ctx)) {
+ 
++			perf_pmu_disable(pmu);
++
++			/* PMIs are disabled; ctx->nr_pending is stable. */
++			if (local_read(&ctx->nr_pending) ||
++			    local_read(&next_ctx->nr_pending)) {
++				/*
++				 * Must not swap out ctx when there's pending
++				 * events that rely on the ctx->task relation.
++				 */
++				raw_spin_unlock(&next_ctx->lock);
++				rcu_read_unlock();
++				goto inside_switch;
++			}
++
+ 			WRITE_ONCE(ctx->task, next);
+ 			WRITE_ONCE(next_ctx->task, task);
+ 
+-			perf_pmu_disable(pmu);
+-
+ 			if (cpuctx->sched_cb_usage && pmu->sched_task)
+ 				pmu->sched_task(ctx, false);
+ 
+@@ -3465,6 +3492,7 @@ unlock:
+ 		raw_spin_lock(&ctx->lock);
+ 		perf_pmu_disable(pmu);
+ 
++inside_switch:
+ 		if (cpuctx->sched_cb_usage && pmu->sched_task)
+ 			pmu->sched_task(ctx, false);
+ 		task_ctx_sched_out(cpuctx, ctx, EVENT_ALL);
+@@ -4931,7 +4959,7 @@ static void perf_addr_filters_splice(struct perf_event *event,
+ 
+ static void _free_event(struct perf_event *event)
+ {
+-	irq_work_sync(&event->pending);
++	irq_work_sync(&event->pending_irq);
+ 
+ 	unaccount_event(event);
+ 
+@@ -6431,7 +6459,8 @@ static void perf_sigtrap(struct perf_event *event)
+ 		return;
+ 
+ 	/*
+-	 * perf_pending_event() can race with the task exiting.
++	 * Both perf_pending_task() and perf_pending_irq() can race with the
++	 * task exiting.
+ 	 */
+ 	if (current->flags & PF_EXITING)
+ 		return;
+@@ -6440,23 +6469,33 @@ static void perf_sigtrap(struct perf_event *event)
+ 		      event->attr.type, event->attr.sig_data);
+ }
+ 
+-static void perf_pending_event_disable(struct perf_event *event)
++/*
++ * Deliver the pending work in-event-context or follow the context.
++ */
++static void __perf_pending_irq(struct perf_event *event)
+ {
+-	int cpu = READ_ONCE(event->pending_disable);
++	int cpu = READ_ONCE(event->oncpu);
+ 
++	/*
++	 * If the event isn't running; we done. event_sched_out() will have
++	 * taken care of things.
++	 */
+ 	if (cpu < 0)
+ 		return;
+ 
++	/*
++	 * Yay, we hit home and are in the context of the event.
++	 */
+ 	if (cpu == smp_processor_id()) {
+-		WRITE_ONCE(event->pending_disable, -1);
+-
+-		if (event->attr.sigtrap) {
++		if (event->pending_sigtrap) {
++			event->pending_sigtrap = 0;
+ 			perf_sigtrap(event);
+-			atomic_set_release(&event->event_limit, 1); /* rearm event */
+-			return;
++			local_dec(&event->ctx->nr_pending);
++		}
++		if (event->pending_disable) {
++			event->pending_disable = 0;
++			perf_event_disable_local(event);
+ 		}
+-
+-		perf_event_disable_local(event);
+ 		return;
+ 	}
+ 
+@@ -6476,35 +6515,62 @@ static void perf_pending_event_disable(struct perf_event *event)
+ 	 *				  irq_work_queue(); // FAILS
+ 	 *
+ 	 *  irq_work_run()
+-	 *    perf_pending_event()
++	 *    perf_pending_irq()
+ 	 *
+ 	 * But the event runs on CPU-B and wants disabling there.
+ 	 */
+-	irq_work_queue_on(&event->pending, cpu);
++	irq_work_queue_on(&event->pending_irq, cpu);
+ }
+ 
+-static void perf_pending_event(struct irq_work *entry)
++static void perf_pending_irq(struct irq_work *entry)
+ {
+-	struct perf_event *event = container_of(entry, struct perf_event, pending);
++	struct perf_event *event = container_of(entry, struct perf_event, pending_irq);
+ 	int rctx;
+ 
+-	rctx = perf_swevent_get_recursion_context();
+ 	/*
+ 	 * If we 'fail' here, that's OK, it means recursion is already disabled
+ 	 * and we won't recurse 'further'.
+ 	 */
++	rctx = perf_swevent_get_recursion_context();
+ 
+-	perf_pending_event_disable(event);
+-
++	/*
++	 * The wakeup isn't bound to the context of the event -- it can happen
++	 * irrespective of where the event is.
++	 */
+ 	if (event->pending_wakeup) {
+ 		event->pending_wakeup = 0;
+ 		perf_event_wakeup(event);
+ 	}
+ 
++	__perf_pending_irq(event);
++
+ 	if (rctx >= 0)
+ 		perf_swevent_put_recursion_context(rctx);
+ }
+ 
++static void perf_pending_task(struct callback_head *head)
++{
++	struct perf_event *event = container_of(head, struct perf_event, pending_task);
++	int rctx;
++
++	/*
++	 * If we 'fail' here, that's OK, it means recursion is already disabled
++	 * and we won't recurse 'further'.
++	 */
++	preempt_disable_notrace();
++	rctx = perf_swevent_get_recursion_context();
++
++	if (event->pending_work) {
++		event->pending_work = 0;
++		perf_sigtrap(event);
++		local_dec(&event->ctx->nr_pending);
++	}
++
++	if (rctx >= 0)
++		perf_swevent_put_recursion_context(rctx);
++	preempt_enable_notrace();
++}
++
+ #ifdef CONFIG_GUEST_PERF_EVENTS
+ struct perf_guest_info_callbacks __rcu *perf_guest_cbs;
+ 
+@@ -9188,8 +9254,8 @@ int perf_event_account_interrupt(struct perf_event *event)
+  */
+ 
+ static int __perf_event_overflow(struct perf_event *event,
+-				   int throttle, struct perf_sample_data *data,
+-				   struct pt_regs *regs)
++				 int throttle, struct perf_sample_data *data,
++				 struct pt_regs *regs)
+ {
+ 	int events = atomic_read(&event->event_limit);
+ 	int ret = 0;
+@@ -9212,24 +9278,36 @@ static int __perf_event_overflow(struct perf_event *event,
+ 	if (events && atomic_dec_and_test(&event->event_limit)) {
+ 		ret = 1;
+ 		event->pending_kill = POLL_HUP;
+-		event->pending_addr = data->addr;
+-
+ 		perf_event_disable_inatomic(event);
+ 	}
+ 
++	if (event->attr.sigtrap) {
++		/*
++		 * Should not be able to return to user space without processing
++		 * pending_sigtrap (kernel events can overflow multiple times).
++		 */
++		WARN_ON_ONCE(event->pending_sigtrap && event->attr.exclude_kernel);
++		if (!event->pending_sigtrap) {
++			event->pending_sigtrap = 1;
++			local_inc(&event->ctx->nr_pending);
++		}
++		event->pending_addr = data->addr;
++		irq_work_queue(&event->pending_irq);
++	}
++
+ 	READ_ONCE(event->overflow_handler)(event, data, regs);
+ 
+ 	if (*perf_event_fasync(event) && event->pending_kill) {
+ 		event->pending_wakeup = 1;
+-		irq_work_queue(&event->pending);
++		irq_work_queue(&event->pending_irq);
+ 	}
+ 
+ 	return ret;
+ }
+ 
+ int perf_event_overflow(struct perf_event *event,
+-			  struct perf_sample_data *data,
+-			  struct pt_regs *regs)
++			struct perf_sample_data *data,
++			struct pt_regs *regs)
+ {
+ 	return __perf_event_overflow(event, 1, data, regs);
+ }
+@@ -11537,8 +11615,8 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+ 
+ 
+ 	init_waitqueue_head(&event->waitq);
+-	event->pending_disable = -1;
+-	init_irq_work(&event->pending, perf_pending_event);
++	init_irq_work(&event->pending_irq, perf_pending_irq);
++	init_task_work(&event->pending_task, perf_pending_task);
+ 
+ 	mutex_init(&event->mmap_mutex);
+ 	raw_spin_lock_init(&event->addr_filters.lock);
+@@ -11560,9 +11638,6 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+ 	if (parent_event)
+ 		event->event_caps = parent_event->event_caps;
+ 
+-	if (event->attr.sigtrap)
+-		atomic_set(&event->event_limit, 1);
+-
+ 	if (task) {
+ 		event->attach_state = PERF_ATTACH_TASK;
+ 		/*
+diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
+index 726132039c388..273a0fe7910a5 100644
+--- a/kernel/events/ring_buffer.c
++++ b/kernel/events/ring_buffer.c
+@@ -22,7 +22,7 @@ static void perf_output_wakeup(struct perf_output_handle *handle)
+ 	atomic_set(&handle->rb->poll, EPOLLIN);
+ 
+ 	handle->event->pending_wakeup = 1;
+-	irq_work_queue(&handle->event->pending);
++	irq_work_queue(&handle->event->pending_irq);
+ }
+ 
+ /*
+diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
+index 89c71fce225dd..537dd3beafc16 100644
+--- a/kernel/power/hibernate.c
++++ b/kernel/power/hibernate.c
+@@ -641,7 +641,7 @@ static void power_down(void)
+ 	int error;
+ 
+ 	if (hibernation_mode == HIBERNATION_SUSPEND) {
+-		error = suspend_devices_and_enter(PM_SUSPEND_MEM);
++		error = suspend_devices_and_enter(mem_sleep_current);
+ 		if (error) {
+ 			hibernation_mode = hibernation_ops ?
+ 						HIBERNATION_PLATFORM :
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index eb435941e92fd..5b52727dcc1c4 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -1402,30 +1402,32 @@ static void rcu_poll_gp_seq_end(unsigned long *snap)
+ // where caller does not hold the root rcu_node structure's lock.
+ static void rcu_poll_gp_seq_start_unlocked(unsigned long *snap)
+ {
++	unsigned long flags;
+ 	struct rcu_node *rnp = rcu_get_root();
+ 
+ 	if (rcu_init_invoked()) {
+ 		lockdep_assert_irqs_enabled();
+-		raw_spin_lock_irq_rcu_node(rnp);
++		raw_spin_lock_irqsave_rcu_node(rnp, flags);
+ 	}
+ 	rcu_poll_gp_seq_start(snap);
+ 	if (rcu_init_invoked())
+-		raw_spin_unlock_irq_rcu_node(rnp);
++		raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
+ }
+ 
+ // Make the polled API aware of the end of a grace period, but where
+ // caller does not hold the root rcu_node structure's lock.
+ static void rcu_poll_gp_seq_end_unlocked(unsigned long *snap)
+ {
++	unsigned long flags;
+ 	struct rcu_node *rnp = rcu_get_root();
+ 
+ 	if (rcu_init_invoked()) {
+ 		lockdep_assert_irqs_enabled();
+-		raw_spin_lock_irq_rcu_node(rnp);
++		raw_spin_lock_irqsave_rcu_node(rnp, flags);
+ 	}
+ 	rcu_poll_gp_seq_end(snap);
+ 	if (rcu_init_invoked())
+-		raw_spin_unlock_irq_rcu_node(rnp);
++		raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
+ }
+ 
+ /*
+diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
+index e26688d387aeb..f34b489636ffb 100644
+--- a/kernel/sched/sched.h
++++ b/kernel/sched/sched.h
+@@ -1197,6 +1197,14 @@ static inline bool is_migration_disabled(struct task_struct *p)
+ #endif
+ }
+ 
++DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
++
++#define cpu_rq(cpu)		(&per_cpu(runqueues, (cpu)))
++#define this_rq()		this_cpu_ptr(&runqueues)
++#define task_rq(p)		cpu_rq(task_cpu(p))
++#define cpu_curr(cpu)		(cpu_rq(cpu)->curr)
++#define raw_rq()		raw_cpu_ptr(&runqueues)
++
+ struct sched_group;
+ #ifdef CONFIG_SCHED_CORE
+ static inline struct cpumask *sched_group_span(struct sched_group *sg);
+@@ -1284,7 +1292,7 @@ static inline bool sched_group_cookie_match(struct rq *rq,
+ 		return true;
+ 
+ 	for_each_cpu_and(cpu, sched_group_span(group), p->cpus_ptr) {
+-		if (sched_core_cookie_match(rq, p))
++		if (sched_core_cookie_match(cpu_rq(cpu), p))
+ 			return true;
+ 	}
+ 	return false;
+@@ -1399,14 +1407,6 @@ static inline void update_idle_core(struct rq *rq)
+ static inline void update_idle_core(struct rq *rq) { }
+ #endif
+ 
+-DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
+-
+-#define cpu_rq(cpu)		(&per_cpu(runqueues, (cpu)))
+-#define this_rq()		this_cpu_ptr(&runqueues)
+-#define task_rq(p)		cpu_rq(task_cpu(p))
+-#define cpu_curr(cpu)		(cpu_rq(cpu)->curr)
+-#define raw_rq()		raw_cpu_ptr(&runqueues)
+-
+ #ifdef CONFIG_FAIR_GROUP_SCHED
+ static inline struct task_struct *task_of(struct sched_entity *se)
+ {
+diff --git a/mm/huge_memory.c b/mm/huge_memory.c
+index f42bb51e023a0..9558dbf3954ce 100644
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -2445,7 +2445,16 @@ static void __split_huge_page_tail(struct page *head, int tail,
+ 			page_tail);
+ 	page_tail->mapping = head->mapping;
+ 	page_tail->index = head->index + tail;
+-	page_tail->private = 0;
++
++	/*
++	 * page->private should not be set in tail pages with the exception
++	 * of swap cache pages that store the swp_entry_t in tail pages.
++	 * Fix up and warn once if private is unexpectedly set.
++	 */
++	if (!folio_test_swapcache(page_folio(head))) {
++		VM_WARN_ON_ONCE_PAGE(page_tail->private != 0, page_tail);
++		page_tail->private = 0;
++	}
+ 
+ 	/* Page flags must be visible before we make the page non-compound. */
+ 	smp_wmb();
+diff --git a/mm/kmemleak.c b/mm/kmemleak.c
+index 1eddc0132f7f5..613d34b57c5d9 100644
+--- a/mm/kmemleak.c
++++ b/mm/kmemleak.c
+@@ -1463,6 +1463,27 @@ static void scan_gray_list(void)
+ 	WARN_ON(!list_empty(&gray_list));
+ }
+ 
++/*
++ * Conditionally call resched() in a object iteration loop while making sure
++ * that the given object won't go away without RCU read lock by performing a
++ * get_object() if !pinned.
++ *
++ * Return: false if can't do a cond_resched() due to get_object() failure
++ *	   true otherwise
++ */
++static bool kmemleak_cond_resched(struct kmemleak_object *object, bool pinned)
++{
++	if (!pinned && !get_object(object))
++		return false;
++
++	rcu_read_unlock();
++	cond_resched();
++	rcu_read_lock();
++	if (!pinned)
++		put_object(object);
++	return true;
++}
++
+ /*
+  * Scan data sections and all the referenced memory blocks allocated via the
+  * kernel's standard allocators. This function must be called with the
+@@ -1474,7 +1495,7 @@ static void kmemleak_scan(void)
+ 	struct zone *zone;
+ 	int __maybe_unused i;
+ 	int new_leaks = 0;
+-	int loop1_cnt = 0;
++	int loop_cnt = 0;
+ 
+ 	jiffies_last_scan = jiffies;
+ 
+@@ -1483,7 +1504,6 @@ static void kmemleak_scan(void)
+ 	list_for_each_entry_rcu(object, &object_list, object_list) {
+ 		bool obj_pinned = false;
+ 
+-		loop1_cnt++;
+ 		raw_spin_lock_irq(&object->lock);
+ #ifdef DEBUG
+ 		/*
+@@ -1517,24 +1537,11 @@ static void kmemleak_scan(void)
+ 		raw_spin_unlock_irq(&object->lock);
+ 
+ 		/*
+-		 * Do a cond_resched() to avoid soft lockup every 64k objects.
+-		 * Make sure a reference has been taken so that the object
+-		 * won't go away without RCU read lock.
++		 * Do a cond_resched() every 64k objects to avoid soft lockup.
+ 		 */
+-		if (!(loop1_cnt & 0xffff)) {
+-			if (!obj_pinned && !get_object(object)) {
+-				/* Try the next object instead */
+-				loop1_cnt--;
+-				continue;
+-			}
+-
+-			rcu_read_unlock();
+-			cond_resched();
+-			rcu_read_lock();
+-
+-			if (!obj_pinned)
+-				put_object(object);
+-		}
++		if (!(++loop_cnt & 0xffff) &&
++		    !kmemleak_cond_resched(object, obj_pinned))
++			loop_cnt--; /* Try again on next object */
+ 	}
+ 	rcu_read_unlock();
+ 
+@@ -1601,7 +1608,15 @@ static void kmemleak_scan(void)
+ 	 * scan and color them gray until the next scan.
+ 	 */
+ 	rcu_read_lock();
++	loop_cnt = 0;
+ 	list_for_each_entry_rcu(object, &object_list, object_list) {
++		/*
++		 * Do a cond_resched() every 64k objects to avoid soft lockup.
++		 */
++		if (!(++loop_cnt & 0xffff) &&
++		    !kmemleak_cond_resched(object, false))
++			loop_cnt--;	/* Try again on next object */
++
+ 		/*
+ 		 * This is racy but we can save the overhead of lock/unlock
+ 		 * calls. The missed objects, if any, should be caught in
+@@ -1635,7 +1650,15 @@ static void kmemleak_scan(void)
+ 	 * Scanning result reporting.
+ 	 */
+ 	rcu_read_lock();
++	loop_cnt = 0;
+ 	list_for_each_entry_rcu(object, &object_list, object_list) {
++		/*
++		 * Do a cond_resched() every 64k objects to avoid soft lockup.
++		 */
++		if (!(++loop_cnt & 0xffff) &&
++		    !kmemleak_cond_resched(object, false))
++			loop_cnt--;	/* Try again on next object */
++
+ 		/*
+ 		 * This is racy but we can save the overhead of lock/unlock
+ 		 * calls. The missed objects, if any, should be caught in
+diff --git a/mm/madvise.c b/mm/madvise.c
+index 9ff51650f4f07..98ed17a4471a0 100644
+--- a/mm/madvise.c
++++ b/mm/madvise.c
+@@ -811,7 +811,14 @@ static bool madvise_dontneed_free_valid_vma(struct vm_area_struct *vma,
+ 	if (start & ~huge_page_mask(hstate_vma(vma)))
+ 		return false;
+ 
+-	*end = ALIGN(*end, huge_page_size(hstate_vma(vma)));
++	/*
++	 * Madvise callers expect the length to be rounded up to PAGE_SIZE
++	 * boundaries, and may be unaware that this VMA uses huge pages.
++	 * Avoid unexpected data loss by rounding down the number of
++	 * huge pages freed.
++	 */
++	*end = ALIGN_DOWN(*end, huge_page_size(hstate_vma(vma)));
++
+ 	return true;
+ }
+ 
+@@ -826,6 +833,9 @@ static long madvise_dontneed_free(struct vm_area_struct *vma,
+ 	if (!madvise_dontneed_free_valid_vma(vma, start, &end, behavior))
+ 		return -EINVAL;
+ 
++	if (start == end)
++		return 0;
++
+ 	if (!userfaultfd_remove(vma, start, end)) {
+ 		*prev = NULL; /* mmap_lock has been dropped, prev is stale */
+ 
+diff --git a/mm/migrate.c b/mm/migrate.c
+index 6a1597c92261d..524248466bb82 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -1558,6 +1558,13 @@ out:
+ 	 */
+ 	list_splice(&ret_pages, from);
+ 
++	/*
++	 * Return 0 in case all subpages of fail-to-migrate THPs are
++	 * migrated successfully.
++	 */
++	if (list_empty(from))
++		rc = 0;
++
+ 	count_vm_events(PGMIGRATE_SUCCESS, nr_succeeded);
+ 	count_vm_events(PGMIGRATE_FAIL, nr_failed_pages);
+ 	count_vm_events(THP_MIGRATION_SUCCESS, nr_thp_succeeded);
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index d04211f0ef0b1..19749f5409e72 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -804,6 +804,7 @@ static void prep_compound_tail(struct page *head, int tail_idx)
+ 
+ 	p->mapping = TAIL_MAPPING;
+ 	set_compound_head(p, head);
++	set_page_private(p, 0);
+ }
+ 
+ void prep_compound_page(struct page *page, unsigned int order)
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index d7d86c944d76d..55f29c9f9e08e 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -342,10 +342,12 @@ static void j1939_session_skb_drop_old(struct j1939_session *session)
+ 		__skb_unlink(do_skb, &session->skb_queue);
+ 		/* drop ref taken in j1939_session_skb_queue() */
+ 		skb_unref(do_skb);
++		spin_unlock_irqrestore(&session->skb_queue.lock, flags);
+ 
+ 		kfree_skb(do_skb);
++	} else {
++		spin_unlock_irqrestore(&session->skb_queue.lock, flags);
+ 	}
+-	spin_unlock_irqrestore(&session->skb_queue.lock, flags);
+ }
+ 
+ void j1939_session_skb_queue(struct j1939_session *session,
+diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
+index 0ec2f5906a27c..f64654df71a29 100644
+--- a/net/core/net_namespace.c
++++ b/net/core/net_namespace.c
+@@ -117,6 +117,7 @@ static int net_assign_generic(struct net *net, unsigned int id, void *data)
+ 
+ static int ops_init(const struct pernet_operations *ops, struct net *net)
+ {
++	struct net_generic *ng;
+ 	int err = -ENOMEM;
+ 	void *data = NULL;
+ 
+@@ -135,7 +136,13 @@ static int ops_init(const struct pernet_operations *ops, struct net *net)
+ 	if (!err)
+ 		return 0;
+ 
++	if (ops->id && ops->size) {
+ cleanup:
++		ng = rcu_dereference_protected(net->gen,
++					       lockdep_is_held(&pernet_ops_rwsem));
++		ng->ptr[*ops->id] = NULL;
++	}
++
+ 	kfree(data);
+ 
+ out:
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 417463da4fac7..5e1a8eeb5e322 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -3868,7 +3868,7 @@ int skb_append_pagefrags(struct sk_buff *skb, struct page *page,
+ 	} else if (i < MAX_SKB_FRAGS) {
+ 		skb_zcopy_downgrade_managed(skb);
+ 		get_page(page);
+-		skb_fill_page_desc(skb, i, page, offset, size);
++		skb_fill_page_desc_noacc(skb, i, page, offset, size);
+ 	} else {
+ 		return -EMSGSIZE;
+ 	}
+diff --git a/net/ethtool/eeprom.c b/net/ethtool/eeprom.c
+index 1c94bb8ea03f2..49c0a2a77f02d 100644
+--- a/net/ethtool/eeprom.c
++++ b/net/ethtool/eeprom.c
+@@ -124,7 +124,7 @@ static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
+ 	if (ret)
+ 		goto err_free;
+ 
+-	ret = get_module_eeprom_by_page(dev, &page_data, info->extack);
++	ret = get_module_eeprom_by_page(dev, &page_data, info ? info->extack : NULL);
+ 	if (ret < 0)
+ 		goto err_ops;
+ 
+diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
+index 6e55fae4c6860..1fa2fe041ec03 100644
+--- a/net/ieee802154/socket.c
++++ b/net/ieee802154/socket.c
+@@ -502,8 +502,10 @@ static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len)
+ 	if (err < 0)
+ 		goto out;
+ 
+-	if (addr->family != AF_IEEE802154)
++	if (addr->family != AF_IEEE802154) {
++		err = -EINVAL;
+ 		goto out;
++	}
+ 
+ 	ieee802154_addr_from_sa(&haddr, &addr->addr);
+ 	dev = ieee802154_get_dev(sock_net(sk), &haddr);
+diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
+index 853a75a8fbafc..d8ef05347fd98 100644
+--- a/net/ipv4/nexthop.c
++++ b/net/ipv4/nexthop.c
+@@ -2534,7 +2534,7 @@ static int nh_create_ipv4(struct net *net, struct nexthop *nh,
+ 	if (!err) {
+ 		nh->nh_flags = fib_nh->fib_nh_flags;
+ 		fib_info_update_nhc_saddr(net, &fib_nh->nh_common,
+-					  fib_nh->fib_nh_scope);
++					  !fib_nh->fib_nh_scope ? 0 : fib_nh->fib_nh_scope - 1);
+ 	} else {
+ 		fib_nh_release(net, fib_nh);
+ 	}
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index bc2ea12221f95..0640453fce54b 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -2192,7 +2192,8 @@ void tcp_enter_loss(struct sock *sk)
+  */
+ static bool tcp_check_sack_reneging(struct sock *sk, int flag)
+ {
+-	if (flag & FLAG_SACK_RENEGING) {
++	if (flag & FLAG_SACK_RENEGING &&
++	    flag & FLAG_SND_UNA_ADVANCED) {
+ 		struct tcp_sock *tp = tcp_sk(sk);
+ 		unsigned long delay = max(usecs_to_jiffies(tp->srtt_us >> 4),
+ 					  msecs_to_jiffies(10));
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index 5b019ba2b9d21..fe9a6022db66d 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -1853,11 +1853,13 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
+ 	__skb_push(skb, hdrlen);
+ 
+ no_coalesce:
++	limit = (u32)READ_ONCE(sk->sk_rcvbuf) + (u32)(READ_ONCE(sk->sk_sndbuf) >> 1);
++
+ 	/* Only socket owner can try to collapse/prune rx queues
+ 	 * to reduce memory overhead, so add a little headroom here.
+ 	 * Few sockets backlog are possibly concurrently non empty.
+ 	 */
+-	limit = READ_ONCE(sk->sk_rcvbuf) + READ_ONCE(sk->sk_sndbuf) + 64*1024;
++	limit += 64 * 1024;
+ 
+ 	if (unlikely(sk_add_backlog(sk, skb, limit))) {
+ 		bh_unlock_sock(sk);
+diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
+index 80cb50d459e4c..409e8dded7c65 100644
+--- a/net/ipv6/ip6_gre.c
++++ b/net/ipv6/ip6_gre.c
+@@ -1175,14 +1175,16 @@ static void ip6gre_tnl_link_config_route(struct ip6_tnl *t, int set_mtu,
+ 				dev->needed_headroom = dst_len;
+ 
+ 			if (set_mtu) {
+-				dev->mtu = rt->dst.dev->mtu - t_hlen;
++				int mtu = rt->dst.dev->mtu - t_hlen;
++
+ 				if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+-					dev->mtu -= 8;
++					mtu -= 8;
+ 				if (dev->type == ARPHRD_ETHER)
+-					dev->mtu -= ETH_HLEN;
++					mtu -= ETH_HLEN;
+ 
+-				if (dev->mtu < IPV6_MIN_MTU)
+-					dev->mtu = IPV6_MIN_MTU;
++				if (mtu < IPV6_MIN_MTU)
++					mtu = IPV6_MIN_MTU;
++				WRITE_ONCE(dev->mtu, mtu);
+ 			}
+ 		}
+ 		ip6_rt_put(rt);
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index 79c6a827dea9f..616487b146982 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -1450,8 +1450,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
+ 	struct net_device *tdev = NULL;
+ 	struct __ip6_tnl_parm *p = &t->parms;
+ 	struct flowi6 *fl6 = &t->fl.u.ip6;
+-	unsigned int mtu;
+ 	int t_hlen;
++	int mtu;
+ 
+ 	__dev_addr_set(dev, &p->laddr, sizeof(struct in6_addr));
+ 	memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
+@@ -1498,12 +1498,13 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
+ 			dev->hard_header_len = tdev->hard_header_len + t_hlen;
+ 			mtu = min_t(unsigned int, tdev->mtu, IP6_MAX_MTU);
+ 
+-			dev->mtu = mtu - t_hlen;
++			mtu = mtu - t_hlen;
+ 			if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+-				dev->mtu -= 8;
++				mtu -= 8;
+ 
+-			if (dev->mtu < IPV6_MIN_MTU)
+-				dev->mtu = IPV6_MIN_MTU;
++			if (mtu < IPV6_MIN_MTU)
++				mtu = IPV6_MIN_MTU;
++			WRITE_ONCE(dev->mtu, mtu);
+ 		}
+ 	}
+ }
+diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
+index e0dcc7a193df2..b61066ac8648e 100644
+--- a/net/ipv6/ipv6_sockglue.c
++++ b/net/ipv6/ipv6_sockglue.c
+@@ -419,6 +419,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
+ 		rtnl_lock();
+ 	lock_sock(sk);
+ 
++	/* Another thread has converted the socket into IPv4 with
++	 * IPV6_ADDRFORM concurrently.
++	 */
++	if (unlikely(sk->sk_family != AF_INET6))
++		goto unlock;
++
+ 	switch (optname) {
+ 
+ 	case IPV6_ADDRFORM:
+@@ -994,6 +1000,7 @@ done:
+ 		break;
+ 	}
+ 
++unlock:
+ 	release_sock(sk);
+ 	if (needs_rtnl)
+ 		rtnl_unlock();
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index 6b73b7a5f1755..59b2d9a6210c8 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -1124,10 +1124,12 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
+ 
+ 	if (tdev && !netif_is_l3_master(tdev)) {
+ 		int t_hlen = tunnel->hlen + sizeof(struct iphdr);
++		int mtu;
+ 
+-		dev->mtu = tdev->mtu - t_hlen;
+-		if (dev->mtu < IPV6_MIN_MTU)
+-			dev->mtu = IPV6_MIN_MTU;
++		mtu = tdev->mtu - t_hlen;
++		if (mtu < IPV6_MIN_MTU)
++			mtu = IPV6_MIN_MTU;
++		WRITE_ONCE(dev->mtu, mtu);
+ 	}
+ }
+ 
+diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
+index 1215c863e1c41..befc62606cdf0 100644
+--- a/net/kcm/kcmsock.c
++++ b/net/kcm/kcmsock.c
+@@ -162,7 +162,8 @@ static void kcm_rcv_ready(struct kcm_sock *kcm)
+ 	/* Buffer limit is okay now, add to ready list */
+ 	list_add_tail(&kcm->wait_rx_list,
+ 		      &kcm->mux->kcm_rx_waiters);
+-	kcm->rx_wait = true;
++	/* paired with lockless reads in kcm_rfree() */
++	WRITE_ONCE(kcm->rx_wait, true);
+ }
+ 
+ static void kcm_rfree(struct sk_buff *skb)
+@@ -178,7 +179,7 @@ static void kcm_rfree(struct sk_buff *skb)
+ 	/* For reading rx_wait and rx_psock without holding lock */
+ 	smp_mb__after_atomic();
+ 
+-	if (!kcm->rx_wait && !kcm->rx_psock &&
++	if (!READ_ONCE(kcm->rx_wait) && !READ_ONCE(kcm->rx_psock) &&
+ 	    sk_rmem_alloc_get(sk) < sk->sk_rcvlowat) {
+ 		spin_lock_bh(&mux->rx_lock);
+ 		kcm_rcv_ready(kcm);
+@@ -237,7 +238,8 @@ try_again:
+ 		if (kcm_queue_rcv_skb(&kcm->sk, skb)) {
+ 			/* Should mean socket buffer full */
+ 			list_del(&kcm->wait_rx_list);
+-			kcm->rx_wait = false;
++			/* paired with lockless reads in kcm_rfree() */
++			WRITE_ONCE(kcm->rx_wait, false);
+ 
+ 			/* Commit rx_wait to read in kcm_free */
+ 			smp_wmb();
+@@ -280,10 +282,12 @@ static struct kcm_sock *reserve_rx_kcm(struct kcm_psock *psock,
+ 	kcm = list_first_entry(&mux->kcm_rx_waiters,
+ 			       struct kcm_sock, wait_rx_list);
+ 	list_del(&kcm->wait_rx_list);
+-	kcm->rx_wait = false;
++	/* paired with lockless reads in kcm_rfree() */
++	WRITE_ONCE(kcm->rx_wait, false);
+ 
+ 	psock->rx_kcm = kcm;
+-	kcm->rx_psock = psock;
++	/* paired with lockless reads in kcm_rfree() */
++	WRITE_ONCE(kcm->rx_psock, psock);
+ 
+ 	spin_unlock_bh(&mux->rx_lock);
+ 
+@@ -310,7 +314,8 @@ static void unreserve_rx_kcm(struct kcm_psock *psock,
+ 	spin_lock_bh(&mux->rx_lock);
+ 
+ 	psock->rx_kcm = NULL;
+-	kcm->rx_psock = NULL;
++	/* paired with lockless reads in kcm_rfree() */
++	WRITE_ONCE(kcm->rx_psock, NULL);
+ 
+ 	/* Commit kcm->rx_psock before sk_rmem_alloc_get to sync with
+ 	 * kcm_rfree
+@@ -834,7 +839,7 @@ static ssize_t kcm_sendpage(struct socket *sock, struct page *page,
+ 	}
+ 
+ 	get_page(page);
+-	skb_fill_page_desc(skb, i, page, offset, size);
++	skb_fill_page_desc_noacc(skb, i, page, offset, size);
+ 	skb_shinfo(skb)->flags |= SKBFL_SHARED_FRAG;
+ 
+ coalesced:
+@@ -1240,7 +1245,8 @@ static void kcm_recv_disable(struct kcm_sock *kcm)
+ 	if (!kcm->rx_psock) {
+ 		if (kcm->rx_wait) {
+ 			list_del(&kcm->wait_rx_list);
+-			kcm->rx_wait = false;
++			/* paired with lockless reads in kcm_rfree() */
++			WRITE_ONCE(kcm->rx_wait, false);
+ 		}
+ 
+ 		requeue_rx_msgs(mux, &kcm->sk.sk_receive_queue);
+@@ -1793,7 +1799,8 @@ static void kcm_done(struct kcm_sock *kcm)
+ 
+ 	if (kcm->rx_wait) {
+ 		list_del(&kcm->wait_rx_list);
+-		kcm->rx_wait = false;
++		/* paired with lockless reads in kcm_rfree() */
++		WRITE_ONCE(kcm->rx_wait, false);
+ 	}
+ 	/* Move any pending receive messages to other kcm sockets */
+ 	requeue_rx_msgs(mux, &sk->sk_receive_queue);
+diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c
+index c439125ef2b91..726b47a4611b5 100644
+--- a/net/mac802154/rx.c
++++ b/net/mac802154/rx.c
+@@ -132,7 +132,7 @@ static int
+ ieee802154_parse_frame_start(struct sk_buff *skb, struct ieee802154_hdr *hdr)
+ {
+ 	int hlen;
+-	struct ieee802154_mac_cb *cb = mac_cb_init(skb);
++	struct ieee802154_mac_cb *cb = mac_cb(skb);
+ 
+ 	skb_reset_mac_header(skb);
+ 
+@@ -294,8 +294,9 @@ void
+ ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, u8 lqi)
+ {
+ 	struct ieee802154_local *local = hw_to_local(hw);
++	struct ieee802154_mac_cb *cb = mac_cb_init(skb);
+ 
+-	mac_cb(skb)->lqi = lqi;
++	cb->lqi = lqi;
+ 	skb->pkt_type = IEEE802154_RX_MSG;
+ 	skb_queue_tail(&local->skb_queue, skb);
+ 	tasklet_schedule(&local->tasklet);
+diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
+index f8897a70c11d4..b568f55998f3c 100644
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -2867,7 +2867,7 @@ static void mptcp_close(struct sock *sk, long timeout)
+ 	sock_put(sk);
+ }
+ 
+-static void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)
++void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)
+ {
+ #if IS_ENABLED(CONFIG_MPTCP_IPV6)
+ 	const struct ipv6_pinfo *ssk6 = inet6_sk(ssk);
+@@ -3613,7 +3613,6 @@ static int mptcp_stream_accept(struct socket *sock, struct socket *newsock,
+ 		if (mptcp_is_fully_established(newsk))
+ 			mptcp_pm_fully_established(msk, msk->first, GFP_KERNEL);
+ 
+-		mptcp_copy_inaddrs(newsk, msk->first);
+ 		mptcp_rcv_space_init(msk, msk->first);
+ 		mptcp_propagate_sndbuf(newsk, msk->first);
+ 
+diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
+index 8f372b8f059c6..c1eaa16855921 100644
+--- a/net/mptcp/protocol.h
++++ b/net/mptcp/protocol.h
+@@ -597,6 +597,7 @@ int mptcp_is_checksum_enabled(const struct net *net);
+ int mptcp_allow_join_id0(const struct net *net);
+ unsigned int mptcp_stale_loss_cnt(const struct net *net);
+ int mptcp_get_pm_type(const struct net *net);
++void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk);
+ void mptcp_subflow_fully_established(struct mptcp_subflow_context *subflow,
+ 				     struct mptcp_options_received *mp_opt);
+ bool __mptcp_retransmit_pending_data(struct sock *sk);
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 07dd23d0fe04a..02a54d59697b5 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -723,6 +723,8 @@ create_child:
+ 				goto dispose_child;
+ 			}
+ 
++			if (new_msk)
++				mptcp_copy_inaddrs(new_msk, child);
+ 			subflow_drop_ctx(child);
+ 			goto out;
+ 		}
+@@ -750,6 +752,11 @@ create_child:
+ 			ctx->conn = new_msk;
+ 			new_msk = NULL;
+ 
++			/* set msk addresses early to ensure mptcp_pm_get_local_id()
++			 * uses the correct data
++			 */
++			mptcp_copy_inaddrs(ctx->conn, child);
++
+ 			/* with OoO packets we can reach here without ingress
+ 			 * mpc option
+ 			 */
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 93c596e3b22b9..8a22574ed7ad6 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -1606,7 +1606,8 @@ static void ovs_dp_reset_user_features(struct sk_buff *skb,
+ 	if (IS_ERR(dp))
+ 		return;
+ 
+-	WARN(dp->user_features, "Dropping previously announced user features\n");
++	pr_warn("%s: Dropping previously announced user features\n",
++		ovs_dp_name(dp));
+ 	dp->user_features = 0;
+ }
+ 
+diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
+index 14fd05fd6107d..d92ec92f0b71d 100644
+--- a/net/tipc/topsrv.c
++++ b/net/tipc/topsrv.c
+@@ -450,12 +450,19 @@ static void tipc_conn_data_ready(struct sock *sk)
+ static void tipc_topsrv_accept(struct work_struct *work)
+ {
+ 	struct tipc_topsrv *srv = container_of(work, struct tipc_topsrv, awork);
+-	struct socket *lsock = srv->listener;
+-	struct socket *newsock;
++	struct socket *newsock, *lsock;
+ 	struct tipc_conn *con;
+ 	struct sock *newsk;
+ 	int ret;
+ 
++	spin_lock_bh(&srv->idr_lock);
++	if (!srv->listener) {
++		spin_unlock_bh(&srv->idr_lock);
++		return;
++	}
++	lsock = srv->listener;
++	spin_unlock_bh(&srv->idr_lock);
++
+ 	while (1) {
+ 		ret = kernel_accept(lsock, &newsock, O_NONBLOCK);
+ 		if (ret < 0)
+@@ -489,7 +496,7 @@ static void tipc_topsrv_listener_data_ready(struct sock *sk)
+ 
+ 	read_lock_bh(&sk->sk_callback_lock);
+ 	srv = sk->sk_user_data;
+-	if (srv->listener)
++	if (srv)
+ 		queue_work(srv->rcv_wq, &srv->awork);
+ 	read_unlock_bh(&sk->sk_callback_lock);
+ }
+@@ -699,8 +706,9 @@ static void tipc_topsrv_stop(struct net *net)
+ 	__module_get(lsock->sk->sk_prot_creator->owner);
+ 	srv->listener = NULL;
+ 	spin_unlock_bh(&srv->idr_lock);
+-	sock_release(lsock);
++
+ 	tipc_topsrv_work_stop(srv);
++	sock_release(lsock);
+ 	idr_destroy(&srv->conn_idr);
+ 	kfree(srv);
+ }
+diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c
+index faf6b03131ee4..51ed2f34b276d 100644
+--- a/sound/aoa/soundbus/i2sbus/core.c
++++ b/sound/aoa/soundbus/i2sbus/core.c
+@@ -147,6 +147,7 @@ static int i2sbus_get_and_fixup_rsrc(struct device_node *np, int index,
+ 	return rc;
+ }
+ 
++/* Returns 1 if added, 0 for otherwise; don't return a negative value! */
+ /* FIXME: look at device node refcounting */
+ static int i2sbus_add_dev(struct macio_dev *macio,
+ 			  struct i2sbus_control *control,
+@@ -213,7 +214,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
+ 	 * either as the second one in that case is just a modem. */
+ 	if (!ok) {
+ 		kfree(dev);
+-		return -ENODEV;
++		return 0;
+ 	}
+ 
+ 	mutex_init(&dev->lock);
+@@ -302,6 +303,10 @@ static int i2sbus_add_dev(struct macio_dev *macio,
+ 
+ 	if (soundbus_add_one(&dev->sound)) {
+ 		printk(KERN_DEBUG "i2sbus: device registration error!\n");
++		if (dev->sound.ofdev.dev.kobj.state_initialized) {
++			soundbus_dev_put(&dev->sound);
++			return 0;
++		}
+ 		goto err;
+ 	}
+ 
+diff --git a/sound/core/control.c b/sound/core/control.c
+index a7271927d875f..50e7ba66f1876 100644
+--- a/sound/core/control.c
++++ b/sound/core/control.c
+@@ -753,6 +753,29 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
+ }
+ EXPORT_SYMBOL(snd_ctl_rename_id);
+ 
++/**
++ * snd_ctl_rename - rename the control on the card
++ * @card: the card instance
++ * @kctl: the control to rename
++ * @name: the new name
++ *
++ * Renames the specified control on the card to the new name.
++ *
++ * Make sure to take the control write lock - down_write(&card->controls_rwsem).
++ */
++void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl,
++		    const char *name)
++{
++	remove_hash_entries(card, kctl);
++
++	if (strscpy(kctl->id.name, name, sizeof(kctl->id.name)) < 0)
++		pr_warn("ALSA: Renamed control new name '%s' truncated to '%s'\n",
++			name, kctl->id.name);
++
++	add_hash_entries(card, kctl);
++}
++EXPORT_SYMBOL(snd_ctl_rename);
++
+ #ifndef CONFIG_SND_CTL_FAST_LOOKUP
+ static struct snd_kcontrol *
+ snd_ctl_find_numid_slow(struct snd_card *card, unsigned int numid)
+diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
+index cb60a07d39a8e..ff685321f1a11 100644
+--- a/sound/pci/ac97/ac97_codec.c
++++ b/sound/pci/ac97/ac97_codec.c
+@@ -2009,6 +2009,7 @@ static int snd_ac97_dev_register(struct snd_device *device)
+ 	err = device_register(&ac97->dev);
+ 	if (err < 0) {
+ 		ac97_err(ac97, "Can't register ac97 bus\n");
++		put_device(&ac97->dev);
+ 		ac97->dev.bus = NULL;
+ 		return err;
+ 	}
+@@ -2655,11 +2656,18 @@ EXPORT_SYMBOL(snd_ac97_resume);
+  */
+ static void set_ctl_name(char *dst, const char *src, const char *suffix)
+ {
+-	if (suffix)
+-		sprintf(dst, "%s %s", src, suffix);
+-	else
+-		strcpy(dst, src);
+-}	
++	const size_t msize = SNDRV_CTL_ELEM_ID_NAME_MAXLEN;
++
++	if (suffix) {
++		if (snprintf(dst, msize, "%s %s", src, suffix) >= msize)
++			pr_warn("ALSA: AC97 control name '%s %s' truncated to '%s'\n",
++				src, suffix, dst);
++	} else {
++		if (strscpy(dst, src, msize) < 0)
++			pr_warn("ALSA: AC97 control name '%s' truncated to '%s'\n",
++				src, dst);
++	}
++}
+ 
+ /* remove the control with the given name and optional suffix */
+ static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
+@@ -2686,8 +2694,11 @@ static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
+ 			       const char *dst, const char *suffix)
+ {
+ 	struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix);
++	char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
++
+ 	if (kctl) {
+-		set_ctl_name(kctl->id.name, dst, suffix);
++		set_ctl_name(name, dst, suffix);
++		snd_ctl_rename(ac97->bus->card, kctl, name);
+ 		return 0;
+ 	}
+ 	return -ENOENT;
+@@ -2706,11 +2717,17 @@ static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
+ 			     const char *s2, const char *suffix)
+ {
+ 	struct snd_kcontrol *kctl1, *kctl2;
++	char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
++
+ 	kctl1 = ctl_find(ac97, s1, suffix);
+ 	kctl2 = ctl_find(ac97, s2, suffix);
+ 	if (kctl1 && kctl2) {
+-		set_ctl_name(kctl1->id.name, s2, suffix);
+-		set_ctl_name(kctl2->id.name, s1, suffix);
++		set_ctl_name(name, s2, suffix);
++		snd_ctl_rename(ac97->bus->card, kctl1, name);
++
++		set_ctl_name(name, s1, suffix);
++		snd_ctl_rename(ac97->bus->card, kctl2, name);
++
+ 		return 0;
+ 	}
+ 	return -ENOENT;
+diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
+index 0aa7af049b1b9..6cbb2bc4a0483 100644
+--- a/sound/pci/au88x0/au88x0.h
++++ b/sound/pci/au88x0/au88x0.h
+@@ -141,7 +141,7 @@ struct snd_vortex {
+ #ifndef CHIP_AU8810
+ 	stream_t dma_wt[NR_WT];
+ 	wt_voice_t wt_voice[NR_WT];	/* WT register cache. */
+-	char mixwt[(NR_WT / NR_WTPB) * 6];	/* WT mixin objects */
++	s8 mixwt[(NR_WT / NR_WTPB) * 6];	/* WT mixin objects */
+ #endif
+ 
+ 	/* Global resources */
+@@ -235,8 +235,8 @@ static int vortex_alsafmt_aspfmt(snd_pcm_format_t alsafmt, vortex_t *v);
+ static void vortex_connect_default(vortex_t * vortex, int en);
+ static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch,
+ 				 int dir, int type, int subdev);
+-static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
+-				  int restype);
++static int vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
++				 int restype);
+ #ifndef CHIP_AU8810
+ static int vortex_wt_allocroute(vortex_t * vortex, int dma, int nr_ch);
+ static void vortex_wt_connect(vortex_t * vortex, int en);
+diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
+index 2ed5100b8caea..f217c02dfdfa4 100644
+--- a/sound/pci/au88x0/au88x0_core.c
++++ b/sound/pci/au88x0/au88x0_core.c
+@@ -1998,7 +1998,7 @@ static const int resnum[VORTEX_RESOURCE_LAST] =
+  out: Mean checkout if != 0. Else mean Checkin resource.
+  restype: Indicates type of resource to be checked in or out.
+ */
+-static char
++static int
+ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
+ {
+ 	int i, qty = resnum[restype], resinuse = 0;
+diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
+index 05f56015ddd87..f6381c098d4f6 100644
+--- a/sound/pci/ca0106/ca0106_mixer.c
++++ b/sound/pci/ca0106/ca0106_mixer.c
+@@ -720,7 +720,7 @@ static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
+ {
+ 	struct snd_kcontrol *kctl = ctl_find(card, src);
+ 	if (kctl) {
+-		strcpy(kctl->id.name, dst);
++		snd_ctl_rename(card, kctl, dst);
+ 		return 0;
+ 	}
+ 	return -ENOENT;
+diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
+index e9c0fe3b84461..3c115f8ab96c0 100644
+--- a/sound/pci/emu10k1/emumixer.c
++++ b/sound/pci/emu10k1/emumixer.c
+@@ -1767,7 +1767,7 @@ static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
+ {
+ 	struct snd_kcontrol *kctl = ctl_find(card, src);
+ 	if (kctl) {
+-		strcpy(kctl->id.name, dst);
++		snd_ctl_rename(card, kctl, dst);
+ 		return 0;
+ 	}
+ 	return -ENOENT;
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 8f7905e0b376b..6e25a0f89f6b4 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -2141,7 +2141,7 @@ static void rename_ctl(struct hda_codec *codec, const char *oldname,
+ 
+ 	kctl = snd_hda_find_mixer_ctl(codec, oldname);
+ 	if (kctl)
+-		strcpy(kctl->id.name, newname);
++		snd_ctl_rename(codec->card, kctl, newname);
+ }
+ 
+ static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
+@@ -9333,6 +9333,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
+ 	SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED),
++	SND_PCI_QUIRK(0x103c, 0x896d, "HP ZBook Firefly 16 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8972, "HP EliteBook 840 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+@@ -9351,6 +9352,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x103c, 0x89aa, "HP EliteBook 630 G9", ALC236_FIXUP_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x89ac, "HP EliteBook 640 G9", ALC236_FIXUP_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x89ae, "HP EliteBook 650 G9", ALC236_FIXUP_HP_GPIO_LED),
++	SND_PCI_QUIRK(0x103c, 0x89c0, "HP ZBook Power 15.6 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
+@@ -9405,6 +9407,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC),
+ 	SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
+ 	SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
++	SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402", ALC245_FIXUP_CS35L41_SPI_2),
+ 	SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
+ 	SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
+ 	SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
+diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
+index dcc43a81ae0e8..65add92c88aa6 100644
+--- a/sound/pci/rme9652/hdsp.c
++++ b/sound/pci/rme9652/hdsp.c
+@@ -433,7 +433,7 @@ struct hdsp_midi {
+     struct snd_rawmidi           *rmidi;
+     struct snd_rawmidi_substream *input;
+     struct snd_rawmidi_substream *output;
+-    char                     istimer; /* timer in use */
++    signed char		     istimer; /* timer in use */
+     struct timer_list	     timer;
+     spinlock_t               lock;
+     int			     pending;
+@@ -480,7 +480,7 @@ struct hdsp {
+ 	pid_t                 playback_pid;
+ 	int                   running;
+ 	int                   system_sample_rate;
+-	const char           *channel_map;
++	const signed char    *channel_map;
+ 	int                   dev;
+ 	int                   irq;
+ 	unsigned long         port;
+@@ -502,7 +502,7 @@ struct hdsp {
+    where the data for that channel can be read/written from/to.
+ */
+ 
+-static const char channel_map_df_ss[HDSP_MAX_CHANNELS] = {
++static const signed char channel_map_df_ss[HDSP_MAX_CHANNELS] = {
+ 	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 	18, 19, 20, 21, 22, 23, 24, 25
+ };
+@@ -517,7 +517,7 @@ static const char channel_map_mf_ss[HDSP_MAX_CHANNELS] = { /* Multiface */
+ 	-1, -1, -1, -1, -1, -1, -1, -1
+ };
+ 
+-static const char channel_map_ds[HDSP_MAX_CHANNELS] = {
++static const signed char channel_map_ds[HDSP_MAX_CHANNELS] = {
+ 	/* ADAT channels are remapped */
+ 	1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
+ 	/* channels 12 and 13 are S/PDIF */
+@@ -526,7 +526,7 @@ static const char channel_map_ds[HDSP_MAX_CHANNELS] = {
+ 	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+ };
+ 
+-static const char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
++static const signed char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
+ 	/* ADAT channels */
+ 	0, 1, 2, 3, 4, 5, 6, 7,
+ 	/* SPDIF */
+@@ -540,7 +540,7 @@ static const char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
+ 	-1, -1
+ };
+ 
+-static const char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
++static const signed char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
+ 	/* ADAT */
+ 	1, 3, 5, 7,
+ 	/* SPDIF */
+@@ -554,7 +554,7 @@ static const char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
+ 	-1, -1, -1, -1, -1, -1
+ };
+ 
+-static const char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = {
++static const signed char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = {
+ 	/* ADAT is disabled in this mode */
+ 	/* SPDIF */
+ 	8, 9,
+@@ -3939,7 +3939,7 @@ static snd_pcm_uframes_t snd_hdsp_hw_pointer(struct snd_pcm_substream *substream
+ 	return hdsp_hw_pointer(hdsp);
+ }
+ 
+-static char *hdsp_channel_buffer_location(struct hdsp *hdsp,
++static signed char *hdsp_channel_buffer_location(struct hdsp *hdsp,
+ 					     int stream,
+ 					     int channel)
+ 
+@@ -3964,7 +3964,7 @@ static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream,
+ 				  void __user *src, unsigned long count)
+ {
+ 	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+-	char *channel_buf;
++	signed char *channel_buf;
+ 
+ 	if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES))
+ 		return -EINVAL;
+@@ -3982,7 +3982,7 @@ static int snd_hdsp_playback_copy_kernel(struct snd_pcm_substream *substream,
+ 					 void *src, unsigned long count)
+ {
+ 	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+-	char *channel_buf;
++	signed char *channel_buf;
+ 
+ 	channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel);
+ 	if (snd_BUG_ON(!channel_buf))
+@@ -3996,7 +3996,7 @@ static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream,
+ 				 void __user *dst, unsigned long count)
+ {
+ 	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+-	char *channel_buf;
++	signed char *channel_buf;
+ 
+ 	if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES))
+ 		return -EINVAL;
+@@ -4014,7 +4014,7 @@ static int snd_hdsp_capture_copy_kernel(struct snd_pcm_substream *substream,
+ 					void *dst, unsigned long count)
+ {
+ 	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+-	char *channel_buf;
++	signed char *channel_buf;
+ 
+ 	channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel);
+ 	if (snd_BUG_ON(!channel_buf))
+@@ -4028,7 +4028,7 @@ static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream,
+ 			       unsigned long count)
+ {
+ 	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+-	char *channel_buf;
++	signed char *channel_buf;
+ 
+ 	channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
+ 	if (snd_BUG_ON(!channel_buf))
+diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
+index 1d614fe89a6ae..e7c320afefe86 100644
+--- a/sound/pci/rme9652/rme9652.c
++++ b/sound/pci/rme9652/rme9652.c
+@@ -230,7 +230,7 @@ struct snd_rme9652 {
+ 	int last_spdif_sample_rate;	/* so that we can catch externally ... */
+ 	int last_adat_sample_rate;	/* ... induced rate changes            */
+ 
+-	const char *channel_map;
++	const signed char *channel_map;
+ 
+ 	struct snd_card *card;
+ 	struct snd_pcm *pcm;
+@@ -247,12 +247,12 @@ struct snd_rme9652 {
+    where the data for that channel can be read/written from/to.
+ */
+ 
+-static const char channel_map_9652_ss[26] = {
++static const signed char channel_map_9652_ss[26] = {
+ 	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 	18, 19, 20, 21, 22, 23, 24, 25
+ };
+ 
+-static const char channel_map_9636_ss[26] = {
++static const signed char channel_map_9636_ss[26] = {
+ 	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
+ 	/* channels 16 and 17 are S/PDIF */
+ 	24, 25,
+@@ -260,7 +260,7 @@ static const char channel_map_9636_ss[26] = {
+ 	-1, -1, -1, -1, -1, -1, -1, -1
+ };
+ 
+-static const char channel_map_9652_ds[26] = {
++static const signed char channel_map_9652_ds[26] = {
+ 	/* ADAT channels are remapped */
+ 	1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
+ 	/* channels 12 and 13 are S/PDIF */
+@@ -269,7 +269,7 @@ static const char channel_map_9652_ds[26] = {
+ 	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+ };
+ 
+-static const char channel_map_9636_ds[26] = {
++static const signed char channel_map_9636_ds[26] = {
+ 	/* ADAT channels are remapped */
+ 	1, 3, 5, 7, 9, 11, 13, 15,
+ 	/* channels 8 and 9 are S/PDIF */
+@@ -1819,7 +1819,7 @@ static snd_pcm_uframes_t snd_rme9652_hw_pointer(struct snd_pcm_substream *substr
+ 	return rme9652_hw_pointer(rme9652);
+ }
+ 
+-static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
++static signed char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
+ 					     int stream,
+ 					     int channel)
+ 
+@@ -1847,7 +1847,7 @@ static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream,
+ 				     void __user *src, unsigned long count)
+ {
+ 	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+-	char *channel_buf;
++	signed char *channel_buf;
+ 
+ 	if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES))
+ 		return -EINVAL;
+@@ -1867,7 +1867,7 @@ static int snd_rme9652_playback_copy_kernel(struct snd_pcm_substream *substream,
+ 					    void *src, unsigned long count)
+ {
+ 	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+-	char *channel_buf;
++	signed char *channel_buf;
+ 
+ 	channel_buf = rme9652_channel_buffer_location(rme9652,
+ 						      substream->pstr->stream,
+@@ -1883,7 +1883,7 @@ static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream,
+ 				    void __user *dst, unsigned long count)
+ {
+ 	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+-	char *channel_buf;
++	signed char *channel_buf;
+ 
+ 	if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES))
+ 		return -EINVAL;
+@@ -1903,7 +1903,7 @@ static int snd_rme9652_capture_copy_kernel(struct snd_pcm_substream *substream,
+ 					   void *dst, unsigned long count)
+ {
+ 	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+-	char *channel_buf;
++	signed char *channel_buf;
+ 
+ 	channel_buf = rme9652_channel_buffer_location(rme9652,
+ 						      substream->pstr->stream,
+@@ -1919,7 +1919,7 @@ static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream,
+ 				  unsigned long count)
+ {
+ 	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+-	char *channel_buf;
++	signed char *channel_buf;
+ 
+ 	channel_buf = rme9652_channel_buffer_location (rme9652,
+ 						       substream->pstr->stream,
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
+index d16b4efb88a77..932f08549788a 100644
+--- a/sound/soc/codecs/Kconfig
++++ b/sound/soc/codecs/Kconfig
+@@ -1599,6 +1599,7 @@ config SND_SOC_TFA989X
+ config SND_SOC_TLV320ADC3XXX
+ 	tristate "Texas Instruments TLV320ADC3001/3101 audio ADC"
+ 	depends on I2C
++	depends on GPIOLIB
+ 	help
+ 	 Enable support for Texas Instruments TLV320ADC3001 and TLV320ADC3101
+ 	 ADCs.
+diff --git a/sound/soc/codecs/tlv320adc3xxx.c b/sound/soc/codecs/tlv320adc3xxx.c
+index 748998e48af97..8a0965cd3e667 100644
+--- a/sound/soc/codecs/tlv320adc3xxx.c
++++ b/sound/soc/codecs/tlv320adc3xxx.c
+@@ -1450,7 +1450,7 @@ static struct i2c_driver adc3xxx_i2c_driver = {
+ 		   .of_match_table = tlv320adc3xxx_of_match,
+ 		  },
+ 	.probe_new = adc3xxx_i2c_probe,
+-	.remove = adc3xxx_i2c_remove,
++	.remove = __exit_p(adc3xxx_i2c_remove),
+ 	.id_table = adc3xxx_i2c_id,
+ };
+ 
+diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile
+index 8ca8f872ec80c..41054cf09ec9d 100644
+--- a/sound/soc/intel/common/Makefile
++++ b/sound/soc/intel/common/Makefile
+@@ -9,7 +9,7 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m
+ 	soc-acpi-intel-cml-match.o soc-acpi-intel-icl-match.o \
+ 	soc-acpi-intel-tgl-match.o soc-acpi-intel-ehl-match.o \
+ 	soc-acpi-intel-jsl-match.o soc-acpi-intel-adl-match.o \
+-	soc-acpi-intel-mtl-match.o \
++	soc-acpi-intel-rpl-match.o soc-acpi-intel-mtl-match.o \
+ 	soc-acpi-intel-hda-match.o \
+ 	soc-acpi-intel-sdw-mockup-match.o
+ 
+diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c
+new file mode 100644
+index 0000000000000..0b77401e4e6f9
+--- /dev/null
++++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c
+@@ -0,0 +1,51 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * soc-apci-intel-rpl-match.c - tables and support for RPL ACPI enumeration.
++ *
++ * Copyright (c) 2022 Intel Corporation.
++ */
++
++#include <sound/soc-acpi.h>
++#include <sound/soc-acpi-intel-match.h>
++
++static const struct snd_soc_acpi_endpoint single_endpoint = {
++	.num = 0,
++	.aggregated = 0,
++	.group_position = 0,
++	.group_id = 0,
++};
++
++static const struct snd_soc_acpi_adr_device rt711_0_adr[] = {
++	{
++		.adr = 0x000020025D071100ull,
++		.num_endpoints = 1,
++		.endpoints = &single_endpoint,
++		.name_prefix = "rt711"
++	}
++};
++
++static const struct snd_soc_acpi_link_adr rpl_rvp[] = {
++	{
++		.mask = BIT(0),
++		.num_adr = ARRAY_SIZE(rt711_0_adr),
++		.adr_d = rt711_0_adr,
++	},
++	{}
++};
++
++struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = {
++	{},
++};
++EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_rpl_machines);
++
++/* this table is used when there is no I2S codec present */
++struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = {
++	{
++		.link_mask = 0x1, /* link0 required */
++		.links = rpl_rvp,
++		.drv_name = "sof_sdw",
++		.sof_tplg_filename = "sof-rpl-rt711.tplg",
++	},
++	{},
++};
++EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_rpl_sdw_machines);
+diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
+index 8a56f38dc7e86..54353842dc07f 100644
+--- a/sound/soc/qcom/lpass-cpu.c
++++ b/sound/soc/qcom/lpass-cpu.c
+@@ -782,10 +782,20 @@ static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg)
+ 		return true;
+ 	if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v))
+ 		return true;
++	if (reg == LPASS_HDMI_TX_VBIT_CTL_ADDR(v))
++		return true;
++	if (reg == LPASS_HDMI_TX_PARITY_ADDR(v))
++		return true;
+ 
+ 	for (i = 0; i < v->hdmi_rdma_channels; ++i) {
+ 		if (reg == LPAIF_HDMI_RDMACURR_REG(v, i))
+ 			return true;
++		if (reg == LPASS_HDMI_TX_DMA_ADDR(v, i))
++			return true;
++		if (reg == LPASS_HDMI_TX_CH_LSB_ADDR(v, i))
++			return true;
++		if (reg == LPASS_HDMI_TX_CH_MSB_ADDR(v, i))
++			return true;
+ 	}
+ 	return false;
+ }
+diff --git a/sound/soc/sof/intel/pci-mtl.c b/sound/soc/sof/intel/pci-mtl.c
+index 899b00d53d64f..9f39da984e9fa 100644
+--- a/sound/soc/sof/intel/pci-mtl.c
++++ b/sound/soc/sof/intel/pci-mtl.c
+@@ -38,7 +38,7 @@ static const struct sof_dev_desc mtl_desc = {
+ 		[SOF_INTEL_IPC4] = "intel/sof-ace-tplg",
+ 	},
+ 	.default_fw_filename = {
+-		[SOF_INTEL_IPC4] = "dsp_basefw.bin",
++		[SOF_INTEL_IPC4] = "sof-mtl.ri",
+ 	},
+ 	.nocodec_tplg_filename = "sof-mtl-nocodec.tplg",
+ 	.ops = &sof_mtl_ops,
+diff --git a/sound/soc/sof/intel/pci-tgl.c b/sound/soc/sof/intel/pci-tgl.c
+index ccc44ba3ad94d..4644a78bc95d2 100644
+--- a/sound/soc/sof/intel/pci-tgl.c
++++ b/sound/soc/sof/intel/pci-tgl.c
+@@ -159,6 +159,90 @@ static const struct sof_dev_desc adl_desc = {
+ 	.ops_init = sof_tgl_ops_init,
+ };
+ 
++static const struct sof_dev_desc adl_n_desc = {
++	.machines               = snd_soc_acpi_intel_adl_machines,
++	.alt_machines           = snd_soc_acpi_intel_adl_sdw_machines,
++	.use_acpi_target_states = true,
++	.resindex_lpe_base      = 0,
++	.resindex_pcicfg_base   = -1,
++	.resindex_imr_base      = -1,
++	.irqindex_host_ipc      = -1,
++	.chip_info = &tgl_chip_info,
++	.ipc_supported_mask	= BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
++	.ipc_default		= SOF_IPC,
++	.default_fw_path = {
++		[SOF_IPC] = "intel/sof",
++		[SOF_INTEL_IPC4] = "intel/avs/adl-n",
++	},
++	.default_tplg_path = {
++		[SOF_IPC] = "intel/sof-tplg",
++		[SOF_INTEL_IPC4] = "intel/avs-tplg",
++	},
++	.default_fw_filename = {
++		[SOF_IPC] = "sof-adl-n.ri",
++		[SOF_INTEL_IPC4] = "dsp_basefw.bin",
++	},
++	.nocodec_tplg_filename = "sof-adl-nocodec.tplg",
++	.ops = &sof_tgl_ops,
++	.ops_init = sof_tgl_ops_init,
++};
++
++static const struct sof_dev_desc rpls_desc = {
++	.machines               = snd_soc_acpi_intel_rpl_machines,
++	.alt_machines           = snd_soc_acpi_intel_rpl_sdw_machines,
++	.use_acpi_target_states	= true,
++	.resindex_lpe_base      = 0,
++	.resindex_pcicfg_base   = -1,
++	.resindex_imr_base      = -1,
++	.irqindex_host_ipc      = -1,
++	.chip_info = &adls_chip_info,
++	.ipc_supported_mask	= BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
++	.ipc_default		= SOF_IPC,
++	.default_fw_path = {
++		[SOF_IPC] = "intel/sof",
++		[SOF_INTEL_IPC4] = "intel/avs/rpl-s",
++	},
++	.default_tplg_path = {
++		[SOF_IPC] = "intel/sof-tplg",
++		[SOF_INTEL_IPC4] = "intel/avs-tplg",
++	},
++	.default_fw_filename = {
++		[SOF_IPC] = "sof-rpl-s.ri",
++		[SOF_INTEL_IPC4] = "dsp_basefw.bin",
++	},
++	.nocodec_tplg_filename = "sof-rpl-nocodec.tplg",
++	.ops = &sof_tgl_ops,
++	.ops_init = sof_tgl_ops_init,
++};
++
++static const struct sof_dev_desc rpl_desc = {
++	.machines               = snd_soc_acpi_intel_rpl_machines,
++	.alt_machines           = snd_soc_acpi_intel_rpl_sdw_machines,
++	.use_acpi_target_states = true,
++	.resindex_lpe_base      = 0,
++	.resindex_pcicfg_base   = -1,
++	.resindex_imr_base      = -1,
++	.irqindex_host_ipc      = -1,
++	.chip_info = &tgl_chip_info,
++	.ipc_supported_mask	= BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
++	.ipc_default		= SOF_IPC,
++	.default_fw_path = {
++		[SOF_IPC] = "intel/sof",
++		[SOF_INTEL_IPC4] = "intel/avs/rpl",
++	},
++	.default_tplg_path = {
++		[SOF_IPC] = "intel/sof-tplg",
++		[SOF_INTEL_IPC4] = "intel/avs-tplg",
++	},
++	.default_fw_filename = {
++		[SOF_IPC] = "sof-rpl.ri",
++		[SOF_INTEL_IPC4] = "dsp_basefw.bin",
++	},
++	.nocodec_tplg_filename = "sof-rpl-nocodec.tplg",
++	.ops = &sof_tgl_ops,
++	.ops_init = sof_tgl_ops_init,
++};
++
+ /* PCI IDs */
+ static const struct pci_device_id sof_pci_ids[] = {
+ 	{ PCI_DEVICE(0x8086, 0xa0c8), /* TGL-LP */
+@@ -172,7 +256,7 @@ static const struct pci_device_id sof_pci_ids[] = {
+ 	{ PCI_DEVICE(0x8086, 0x7ad0), /* ADL-S */
+ 		.driver_data = (unsigned long)&adls_desc},
+ 	{ PCI_DEVICE(0x8086, 0x7a50), /* RPL-S */
+-		.driver_data = (unsigned long)&adls_desc},
++		.driver_data = (unsigned long)&rpls_desc},
+ 	{ PCI_DEVICE(0x8086, 0x51c8), /* ADL-P */
+ 		.driver_data = (unsigned long)&adl_desc},
+ 	{ PCI_DEVICE(0x8086, 0x51cd), /* ADL-P */
+@@ -180,13 +264,13 @@ static const struct pci_device_id sof_pci_ids[] = {
+ 	{ PCI_DEVICE(0x8086, 0x51c9), /* ADL-PS */
+ 		.driver_data = (unsigned long)&adl_desc},
+ 	{ PCI_DEVICE(0x8086, 0x51ca), /* RPL-P */
+-		.driver_data = (unsigned long)&adl_desc},
++		.driver_data = (unsigned long)&rpl_desc},
+ 	{ PCI_DEVICE(0x8086, 0x51cb), /* RPL-P */
+-		.driver_data = (unsigned long)&adl_desc},
++		.driver_data = (unsigned long)&rpl_desc},
+ 	{ PCI_DEVICE(0x8086, 0x51cc), /* ADL-M */
+ 		.driver_data = (unsigned long)&adl_desc},
+ 	{ PCI_DEVICE(0x8086, 0x54c8), /* ADL-N */
+-		.driver_data = (unsigned long)&adl_desc},
++		.driver_data = (unsigned long)&adl_n_desc},
+ 	{ 0, }
+ };
+ MODULE_DEVICE_TABLE(pci, sof_pci_ids);
+diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c
+index 5ed8e36d2e043..a870759d179ed 100644
+--- a/sound/synth/emux/emux.c
++++ b/sound/synth/emux/emux.c
+@@ -126,15 +126,10 @@ EXPORT_SYMBOL(snd_emux_register);
+  */
+ int snd_emux_free(struct snd_emux *emu)
+ {
+-	unsigned long flags;
+-
+ 	if (! emu)
+ 		return -EINVAL;
+ 
+-	spin_lock_irqsave(&emu->voice_lock, flags);
+-	if (emu->timer_active)
+-		del_timer(&emu->tlist);
+-	spin_unlock_irqrestore(&emu->voice_lock, flags);
++	del_timer_sync(&emu->tlist);
+ 
+ 	snd_emux_proc_free(emu);
+ 	snd_emux_delete_virmidi(emu);
+diff --git a/sound/usb/implicit.c b/sound/usb/implicit.c
+index e1bf1b5da423c..f3e8484b3d9cb 100644
+--- a/sound/usb/implicit.c
++++ b/sound/usb/implicit.c
+@@ -47,6 +47,8 @@ struct snd_usb_implicit_fb_match {
+ static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
+ 	/* Fixed EP */
+ 	/* FIXME: check the availability of generic matching */
++	IMPLICIT_FB_FIXED_DEV(0x0763, 0x2030, 0x81, 3), /* M-Audio Fast Track C400 */
++	IMPLICIT_FB_FIXED_DEV(0x0763, 0x2031, 0x81, 3), /* M-Audio Fast Track C600 */
+ 	IMPLICIT_FB_FIXED_DEV(0x0763, 0x2080, 0x81, 2), /* M-Audio FastTrack Ultra */
+ 	IMPLICIT_FB_FIXED_DEV(0x0763, 0x2081, 0x81, 2), /* M-Audio FastTrack Ultra */
+ 	IMPLICIT_FB_FIXED_DEV(0x2466, 0x8010, 0x81, 2), /* Fractal Audio Axe-Fx III */
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
+index a5641956ef102..9105ec623120a 100644
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -1631,7 +1631,7 @@ static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
+ 	if (!found)
+ 		return;
+ 
+-	strscpy(kctl->id.name, "Headphone", sizeof(kctl->id.name));
++	snd_ctl_rename(card, kctl, "Headphone");
+ }
+ 
+ static const struct usb_feature_control_info *get_feature_control_info(int control)
+diff --git a/tools/iio/iio_utils.c b/tools/iio/iio_utils.c
+index aadee6d34c74c..8d35893b2fa85 100644
+--- a/tools/iio/iio_utils.c
++++ b/tools/iio/iio_utils.c
+@@ -547,6 +547,10 @@ static int calc_digits(int num)
+ {
+ 	int count = 0;
+ 
++	/* It takes a digit to represent zero */
++	if (!num)
++		return 1;
++
+ 	while (num != 0) {
+ 		num /= 10;
+ 		count++;
+diff --git a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json
+index 6970203cb2470..6443a061e22a1 100644
+--- a/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json
++++ b/tools/perf/pmu-events/arch/arm64/hisilicon/hip08/metrics.json
+@@ -112,21 +112,21 @@
+         "MetricName": "indirect_branch"
+     },
+     {
+-        "MetricExpr": "(armv8_pmuv3_0@event\\=0x1014@ + armv8_pmuv3_0@event\\=0x1018@) / BR_MIS_PRED",
++        "MetricExpr": "(armv8_pmuv3_0@event\\=0x1013@ + armv8_pmuv3_0@event\\=0x1016@) / BR_MIS_PRED",
+         "PublicDescription": "Push branch L3 topdown metric",
+         "BriefDescription": "Push branch L3 topdown metric",
+         "MetricGroup": "TopDownL3",
+         "MetricName": "push_branch"
+     },
+     {
+-        "MetricExpr": "armv8_pmuv3_0@event\\=0x100c@ / BR_MIS_PRED",
++        "MetricExpr": "armv8_pmuv3_0@event\\=0x100d@ / BR_MIS_PRED",
+         "PublicDescription": "Pop branch L3 topdown metric",
+         "BriefDescription": "Pop branch L3 topdown metric",
+         "MetricGroup": "TopDownL3",
+         "MetricName": "pop_branch"
+     },
+     {
+-        "MetricExpr": "(BR_MIS_PRED - armv8_pmuv3_0@event\\=0x1010@ - armv8_pmuv3_0@event\\=0x1014@ - armv8_pmuv3_0@event\\=0x1018@ - armv8_pmuv3_0@event\\=0x100c@) / BR_MIS_PRED",
++        "MetricExpr": "(BR_MIS_PRED - armv8_pmuv3_0@event\\=0x1010@ - armv8_pmuv3_0@event\\=0x1013@ - armv8_pmuv3_0@event\\=0x1016@ - armv8_pmuv3_0@event\\=0x100d@) / BR_MIS_PRED",
+         "PublicDescription": "Other branch L3 topdown metric",
+         "BriefDescription": "Other branch L3 topdown metric",
+         "MetricGroup": "TopDownL3",
+diff --git a/tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json
+index 8ba3e81c9808b..fe050d44374ba 100644
+--- a/tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json
++++ b/tools/perf/pmu-events/arch/powerpc/power10/nest_metrics.json
+@@ -1,13 +1,13 @@
+ [
+     {
+       "MetricName": "VEC_GROUP_PUMP_RETRY_RATIO_P01",
+-      "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP01\\,chip\\=?@ / hv_24x7@PM_PB_VG_PUMP01\\,chip\\=?@) * 100",
++      "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP01\\,chip\\=?@ / (1 + hv_24x7@PM_PB_VG_PUMP01\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "VEC_GROUP_PUMP_RETRY_RATIO_P23",
+-      "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP23\\,chip\\=?@ / hv_24x7@PM_PB_VG_PUMP23\\,chip\\=?@) * 100",
++      "MetricExpr": "(hv_24x7@PM_PB_RTY_VG_PUMP23\\,chip\\=?@ / (1 + hv_24x7@PM_PB_VG_PUMP23\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+@@ -61,13 +61,13 @@
+     },
+     {
+       "MetricName": "REMOTE_NODE_PUMPS_RETRIES_RATIO_P01",
+-      "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP01\\,chip\\=?@ / hv_24x7@PM_PB_RNS_PUMP01\\,chip\\=?@) * 100",
++      "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP01\\,chip\\=?@ / (1 + hv_24x7@PM_PB_RNS_PUMP01\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "REMOTE_NODE_PUMPS_RETRIES_RATIO_P23",
+-      "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP23\\,chip\\=?@ / hv_24x7@PM_PB_RNS_PUMP23\\,chip\\=?@) * 100",
++      "MetricExpr": "(hv_24x7@PM_PB_RTY_RNS_PUMP23\\,chip\\=?@ / (1 + hv_24x7@PM_PB_RNS_PUMP23\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+@@ -151,193 +151,193 @@
+     },
+     {
+       "MetricName": "XLINK0_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK1_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK2_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK3_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK4_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK5_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK6_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK7_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK0_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK1_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK2_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK3_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK4_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK5_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK6_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "XLINK7_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_XLINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_XLINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_XLINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK0_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK1_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK2_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK3_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK4_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK5_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK6_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK7_OUT_TOTAL_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_TOTAL_UTIL\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_TOTAL_UTIL\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK0_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK0_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK0_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK0_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK1_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK1_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK1_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK1_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK2_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK2_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK2_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK2_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK3_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK3_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK3_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK3_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK4_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK4_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK4_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK4_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK5_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK5_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK5_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK5_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK6_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK6_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK6_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK6_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+     {
+       "MetricName": "ALINK7_OUT_DATA_UTILIZATION",
+-      "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_DATA\\,chip\\=?@) / (hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
++      "MetricExpr": "((hv_24x7@PM_ALINK7_OUT_ODD_DATA\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_DATA\\,chip\\=?@) / (1 + hv_24x7@PM_ALINK7_OUT_ODD_AVLBL_CYCLES\\,chip\\=?@ + hv_24x7@PM_ALINK7_OUT_EVEN_AVLBL_CYCLES\\,chip\\=?@)) * 100",
+       "ScaleUnit": "1.063%",
+       "AggregationMode": "PerChip"
+     },
+diff --git a/tools/perf/pmu-events/arch/s390/cf_z16/pai.json b/tools/perf/pmu-events/arch/s390/cf_z16/pai.json
+deleted file mode 100644
+index cf8563d059b9e..0000000000000
+--- a/tools/perf/pmu-events/arch/s390/cf_z16/pai.json
++++ /dev/null
+@@ -1,1101 +0,0 @@
+-[
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4096",
+-		"EventName": "CRYPTO_ALL",
+-		"BriefDescription": "CRYPTO ALL",
+-		"PublicDescription": "Sums of all non zero cryptography counters"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4097",
+-		"EventName": "KM_DEA",
+-		"BriefDescription": "KM DEA",
+-		"PublicDescription": "KM-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4098",
+-		"EventName": "KM_TDEA_128",
+-		"BriefDescription": "KM TDEA 128",
+-		"PublicDescription": "KM-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4099",
+-		"EventName": "KM_TDEA_192",
+-		"BriefDescription": "KM TDEA 192",
+-		"PublicDescription": "KM-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4100",
+-		"EventName": "KM_ENCRYPTED_DEA",
+-		"BriefDescription": "KM ENCRYPTED DEA",
+-		"PublicDescription": "KM-Encrypted-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4101",
+-		"EventName": "KM_ENCRYPTED_TDEA_128",
+-		"BriefDescription": "KM ENCRYPTED TDEA 128",
+-		"PublicDescription": "KM-Encrypted-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4102",
+-		"EventName": "KM_ENCRYPTED_TDEA_192",
+-		"BriefDescription": "KM ENCRYPTED TDEA 192",
+-		"PublicDescription": "KM-Encrypted-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4103",
+-		"EventName": "KM_AES_128",
+-		"BriefDescription": "KM AES 128",
+-		"PublicDescription": "KM-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4104",
+-		"EventName": "KM_AES_192",
+-		"BriefDescription": "KM AES 192",
+-		"PublicDescription": "KM-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4105",
+-		"EventName": "KM_AES_256",
+-		"BriefDescription": "KM AES 256",
+-		"PublicDescription": "KM-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4106",
+-		"EventName": "KM_ENCRYPTED_AES_128",
+-		"BriefDescription": "KM ENCRYPTED AES 128",
+-		"PublicDescription": "KM-Encrypted-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4107",
+-		"EventName": "KM_ENCRYPTED_AES_192",
+-		"BriefDescription": "KM ENCRYPTED AES 192",
+-		"PublicDescription": "KM-Encrypted-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4108",
+-		"EventName": "KM_ENCRYPTED_AES_256",
+-		"BriefDescription": "KM ENCRYPTED AES 256",
+-		"PublicDescription": "KM-Encrypted-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4109",
+-		"EventName": "KM_XTS_AES_128",
+-		"BriefDescription": "KM XTS AES 128",
+-		"PublicDescription": "KM-XTS-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4110",
+-		"EventName": "KM_XTS_AES_256",
+-		"BriefDescription": "KM XTS AES 256",
+-		"PublicDescription": "KM-XTS-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4111",
+-		"EventName": "KM_XTS_ENCRYPTED_AES_128",
+-		"BriefDescription": "KM XTS ENCRYPTED AES 128",
+-		"PublicDescription": "KM-XTS-Encrypted-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4112",
+-		"EventName": "KM_XTS_ENCRYPTED_AES_256",
+-		"BriefDescription": "KM XTS ENCRYPTED AES 256",
+-		"PublicDescription": "KM-XTS-Encrypted-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4113",
+-		"EventName": "KMC_DEA",
+-		"BriefDescription": "KMC DEA",
+-		"PublicDescription": "KMC-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4114",
+-		"EventName": "KMC_TDEA_128",
+-		"BriefDescription": "KMC TDEA 128",
+-		"PublicDescription": "KMC-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4115",
+-		"EventName": "KMC_TDEA_192",
+-		"BriefDescription": "KMC TDEA 192",
+-		"PublicDescription": "KMC-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4116",
+-		"EventName": "KMC_ENCRYPTED_DEA",
+-		"BriefDescription": "KMC ENCRYPTED DEA",
+-		"PublicDescription": "KMC-Encrypted-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4117",
+-		"EventName": "KMC_ENCRYPTED_TDEA_128",
+-		"BriefDescription": "KMC ENCRYPTED TDEA 128",
+-		"PublicDescription": "KMC-Encrypted-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4118",
+-		"EventName": "KMC_ENCRYPTED_TDEA_192",
+-		"BriefDescription": "KMC ENCRYPTED TDEA 192",
+-		"PublicDescription": "KMC-Encrypted-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4119",
+-		"EventName": "KMC_AES_128",
+-		"BriefDescription": "KMC AES 128",
+-		"PublicDescription": "KMC-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4120",
+-		"EventName": "KMC_AES_192",
+-		"BriefDescription": "KMC AES 192",
+-		"PublicDescription": "KMC-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4121",
+-		"EventName": "KMC_AES_256",
+-		"BriefDescription": "KMC AES 256",
+-		"PublicDescription": "KMC-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4122",
+-		"EventName": "KMC_ENCRYPTED_AES_128",
+-		"BriefDescription": "KMC ENCRYPTED AES 128",
+-		"PublicDescription": "KMC-Encrypted-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4123",
+-		"EventName": "KMC_ENCRYPTED_AES_192",
+-		"BriefDescription": "KMC ENCRYPTED AES 192",
+-		"PublicDescription": "KMC-Encrypted-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4124",
+-		"EventName": "KMC_ENCRYPTED_AES_256",
+-		"BriefDescription": "KMC ENCRYPTED AES 256",
+-		"PublicDescription": "KMC-Encrypted-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4125",
+-		"EventName": "KMC_PRNG",
+-		"BriefDescription": "KMC PRNG",
+-		"PublicDescription": "KMC-PRNG function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4126",
+-		"EventName": "KMA_GCM_AES_128",
+-		"BriefDescription": "KMA GCM AES 128",
+-		"PublicDescription": "KMA-GCM-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4127",
+-		"EventName": "KMA_GCM_AES_192",
+-		"BriefDescription": "KMA GCM AES 192",
+-		"PublicDescription": "KMA-GCM-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4128",
+-		"EventName": "KMA_GCM_AES_256",
+-		"BriefDescription": "KMA GCM AES 256",
+-		"PublicDescription": "KMA-GCM-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4129",
+-		"EventName": "KMA_GCM_ENCRYPTED_AES_128",
+-		"BriefDescription": "KMA GCM ENCRYPTED AES 128",
+-		"PublicDescription": "KMA-GCM-Encrypted-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4130",
+-		"EventName": "KMA_GCM_ENCRYPTED_AES_192",
+-		"BriefDescription": "KMA GCM ENCRYPTED AES 192",
+-		"PublicDescription": "KMA-GCM-Encrypted-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4131",
+-		"EventName": "KMA_GCM_ENCRYPTED_AES_256",
+-		"BriefDescription": "KMA GCM ENCRYPTED AES 256",
+-		"PublicDescription": "KMA-GCM-Encrypted-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4132",
+-		"EventName": "KMF_DEA",
+-		"BriefDescription": "KMF DEA",
+-		"PublicDescription": "KMF-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4133",
+-		"EventName": "KMF_TDEA_128",
+-		"BriefDescription": "KMF TDEA 128",
+-		"PublicDescription": "KMF-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4134",
+-		"EventName": "KMF_TDEA_192",
+-		"BriefDescription": "KMF TDEA 192",
+-		"PublicDescription": "KMF-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4135",
+-		"EventName": "KMF_ENCRYPTED_DEA",
+-		"BriefDescription": "KMF ENCRYPTED DEA",
+-		"PublicDescription": "KMF-Encrypted-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4136",
+-		"EventName": "KMF_ENCRYPTED_TDEA_128",
+-		"BriefDescription": "KMF ENCRYPTED TDEA 128",
+-		"PublicDescription": "KMF-Encrypted-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4137",
+-		"EventName": "KMF_ENCRYPTED_TDEA_192",
+-		"BriefDescription": "KMF ENCRYPTED TDEA 192",
+-		"PublicDescription": "KMF-Encrypted-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4138",
+-		"EventName": "KMF_AES_128",
+-		"BriefDescription": "KMF AES 128",
+-		"PublicDescription": "KMF-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4139",
+-		"EventName": "KMF_AES_192",
+-		"BriefDescription": "KMF AES 192",
+-		"PublicDescription": "KMF-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4140",
+-		"EventName": "KMF_AES_256",
+-		"BriefDescription": "KMF AES 256",
+-		"PublicDescription": "KMF-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4141",
+-		"EventName": "KMF_ENCRYPTED_AES_128",
+-		"BriefDescription": "KMF ENCRYPTED AES 128",
+-		"PublicDescription": "KMF-Encrypted-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4142",
+-		"EventName": "KMF_ENCRYPTED_AES_192",
+-		"BriefDescription": "KMF ENCRYPTED AES 192",
+-		"PublicDescription": "KMF-Encrypted-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4143",
+-		"EventName": "KMF_ENCRYPTED_AES_256",
+-		"BriefDescription": "KMF ENCRYPTED AES 256",
+-		"PublicDescription": "KMF-Encrypted-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4144",
+-		"EventName": "KMCTR_DEA",
+-		"BriefDescription": "KMCTR DEA",
+-		"PublicDescription": "KMCTR-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4145",
+-		"EventName": "KMCTR_TDEA_128",
+-		"BriefDescription": "KMCTR TDEA 128",
+-		"PublicDescription": "KMCTR-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4146",
+-		"EventName": "KMCTR_TDEA_192",
+-		"BriefDescription": "KMCTR TDEA 192",
+-		"PublicDescription": "KMCTR-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4147",
+-		"EventName": "KMCTR_ENCRYPTED_DEA",
+-		"BriefDescription": "KMCTR ENCRYPTED DEA",
+-		"PublicDescription": "KMCTR-Encrypted-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4148",
+-		"EventName": "KMCTR_ENCRYPTED_TDEA_128",
+-		"BriefDescription": "KMCTR ENCRYPTED TDEA 128",
+-		"PublicDescription": "KMCTR-Encrypted-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4149",
+-		"EventName": "KMCTR_ENCRYPTED_TDEA_192",
+-		"BriefDescription": "KMCTR ENCRYPTED TDEA 192",
+-		"PublicDescription": "KMCTR-Encrypted-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4150",
+-		"EventName": "KMCTR_AES_128",
+-		"BriefDescription": "KMCTR AES 128",
+-		"PublicDescription": "KMCTR-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4151",
+-		"EventName": "KMCTR_AES_192",
+-		"BriefDescription": "KMCTR AES 192",
+-		"PublicDescription": "KMCTR-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4152",
+-		"EventName": "KMCTR_AES_256",
+-		"BriefDescription": "KMCTR AES 256",
+-		"PublicDescription": "KMCTR-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4153",
+-		"EventName": "KMCTR_ENCRYPTED_AES_128",
+-		"BriefDescription": "KMCTR ENCRYPTED AES 128",
+-		"PublicDescription": "KMCTR-Encrypted-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4154",
+-		"EventName": "KMCTR_ENCRYPTED_AES_192",
+-		"BriefDescription": "KMCTR ENCRYPTED AES 192",
+-		"PublicDescription": "KMCTR-Encrypted-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4155",
+-		"EventName": "KMCTR_ENCRYPTED_AES_256",
+-		"BriefDescription": "KMCTR ENCRYPTED AES 256",
+-		"PublicDescription": "KMCTR-Encrypted-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4156",
+-		"EventName": "KMO_DEA",
+-		"BriefDescription": "KMO DEA",
+-		"PublicDescription": "KMO-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4157",
+-		"EventName": "KMO_TDEA_128",
+-		"BriefDescription": "KMO TDEA 128",
+-		"PublicDescription": "KMO-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4158",
+-		"EventName": "KMO_TDEA_192",
+-		"BriefDescription": "KMO TDEA 192",
+-		"PublicDescription": "KMO-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4159",
+-		"EventName": "KMO_ENCRYPTED_DEA",
+-		"BriefDescription": "KMO ENCRYPTED DEA",
+-		"PublicDescription": "KMO-Encrypted-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4160",
+-		"EventName": "KMO_ENCRYPTED_TDEA_128",
+-		"BriefDescription": "KMO ENCRYPTED TDEA 128",
+-		"PublicDescription": "KMO-Encrypted-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4161",
+-		"EventName": "KMO_ENCRYPTED_TDEA_192",
+-		"BriefDescription": "KMO ENCRYPTED TDEA 192",
+-		"PublicDescription": "KMO-Encrypted-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4162",
+-		"EventName": "KMO_AES_128",
+-		"BriefDescription": "KMO AES 128",
+-		"PublicDescription": "KMO-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4163",
+-		"EventName": "KMO_AES_192",
+-		"BriefDescription": "KMO AES 192",
+-		"PublicDescription": "KMO-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4164",
+-		"EventName": "KMO_AES_256",
+-		"BriefDescription": "KMO AES 256",
+-		"PublicDescription": "KMO-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4165",
+-		"EventName": "KMO_ENCRYPTED_AES_128",
+-		"BriefDescription": "KMO ENCRYPTED AES 128",
+-		"PublicDescription": "KMO-Encrypted-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4166",
+-		"EventName": "KMO_ENCRYPTED_AES_192",
+-		"BriefDescription": "KMO ENCRYPTED AES 192",
+-		"PublicDescription": "KMO-Encrypted-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4167",
+-		"EventName": "KMO_ENCRYPTED_AES_256",
+-		"BriefDescription": "KMO ENCRYPTED AES 256",
+-		"PublicDescription": "KMO-Encrypted-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4168",
+-		"EventName": "KIMD_SHA_1",
+-		"BriefDescription": "KIMD SHA 1",
+-		"PublicDescription": "KIMD-SHA-1 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4169",
+-		"EventName": "KIMD_SHA_256",
+-		"BriefDescription": "KIMD SHA 256",
+-		"PublicDescription": "KIMD-SHA-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4170",
+-		"EventName": "KIMD_SHA_512",
+-		"BriefDescription": "KIMD SHA 512",
+-		"PublicDescription": "KIMD-SHA-512 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4171",
+-		"EventName": "KIMD_SHA3_224",
+-		"BriefDescription": "KIMD SHA3 224",
+-		"PublicDescription": "KIMD-SHA3-224 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4172",
+-		"EventName": "KIMD_SHA3_256",
+-		"BriefDescription": "KIMD SHA3 256",
+-		"PublicDescription": "KIMD-SHA3-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4173",
+-		"EventName": "KIMD_SHA3_384",
+-		"BriefDescription": "KIMD SHA3 384",
+-		"PublicDescription": "KIMD-SHA3-384 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4174",
+-		"EventName": "KIMD_SHA3_512",
+-		"BriefDescription": "KIMD SHA3 512",
+-		"PublicDescription": "KIMD-SHA3-512 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4175",
+-		"EventName": "KIMD_SHAKE_128",
+-		"BriefDescription": "KIMD SHAKE 128",
+-		"PublicDescription": "KIMD-SHAKE-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4176",
+-		"EventName": "KIMD_SHAKE_256",
+-		"BriefDescription": "KIMD SHAKE 256",
+-		"PublicDescription": "KIMD-SHAKE-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4177",
+-		"EventName": "KIMD_GHASH",
+-		"BriefDescription": "KIMD GHASH",
+-		"PublicDescription": "KIMD-GHASH function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4178",
+-		"EventName": "KLMD_SHA_1",
+-		"BriefDescription": "KLMD SHA 1",
+-		"PublicDescription": "KLMD-SHA-1 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4179",
+-		"EventName": "KLMD_SHA_256",
+-		"BriefDescription": "KLMD SHA 256",
+-		"PublicDescription": "KLMD-SHA-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4180",
+-		"EventName": "KLMD_SHA_512",
+-		"BriefDescription": "KLMD SHA 512",
+-		"PublicDescription": "KLMD-SHA-512 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4181",
+-		"EventName": "KLMD_SHA3_224",
+-		"BriefDescription": "KLMD SHA3 224",
+-		"PublicDescription": "KLMD-SHA3-224 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4182",
+-		"EventName": "KLMD_SHA3_256",
+-		"BriefDescription": "KLMD SHA3 256",
+-		"PublicDescription": "KLMD-SHA3-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4183",
+-		"EventName": "KLMD_SHA3_384",
+-		"BriefDescription": "KLMD SHA3 384",
+-		"PublicDescription": "KLMD-SHA3-384 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4184",
+-		"EventName": "KLMD_SHA3_512",
+-		"BriefDescription": "KLMD SHA3 512",
+-		"PublicDescription": "KLMD-SHA3-512 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4185",
+-		"EventName": "KLMD_SHAKE_128",
+-		"BriefDescription": "KLMD SHAKE 128",
+-		"PublicDescription": "KLMD-SHAKE-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4186",
+-		"EventName": "KLMD_SHAKE_256",
+-		"BriefDescription": "KLMD SHAKE 256",
+-		"PublicDescription": "KLMD-SHAKE-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4187",
+-		"EventName": "KMAC_DEA",
+-		"BriefDescription": "KMAC DEA",
+-		"PublicDescription": "KMAC-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4188",
+-		"EventName": "KMAC_TDEA_128",
+-		"BriefDescription": "KMAC TDEA 128",
+-		"PublicDescription": "KMAC-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4189",
+-		"EventName": "KMAC_TDEA_192",
+-		"BriefDescription": "KMAC TDEA 192",
+-		"PublicDescription": "KMAC-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4190",
+-		"EventName": "KMAC_ENCRYPTED_DEA",
+-		"BriefDescription": "KMAC ENCRYPTED DEA",
+-		"PublicDescription": "KMAC-Encrypted-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4191",
+-		"EventName": "KMAC_ENCRYPTED_TDEA_128",
+-		"BriefDescription": "KMAC ENCRYPTED TDEA 128",
+-		"PublicDescription": "KMAC-Encrypted-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4192",
+-		"EventName": "KMAC_ENCRYPTED_TDEA_192",
+-		"BriefDescription": "KMAC ENCRYPTED TDEA 192",
+-		"PublicDescription": "KMAC-Encrypted-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4193",
+-		"EventName": "KMAC_AES_128",
+-		"BriefDescription": "KMAC AES 128",
+-		"PublicDescription": "KMAC-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4194",
+-		"EventName": "KMAC_AES_192",
+-		"BriefDescription": "KMAC AES 192",
+-		"PublicDescription": "KMAC-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4195",
+-		"EventName": "KMAC_AES_256",
+-		"BriefDescription": "KMAC AES 256",
+-		"PublicDescription": "KMAC-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4196",
+-		"EventName": "KMAC_ENCRYPTED_AES_128",
+-		"BriefDescription": "KMAC ENCRYPTED AES 128",
+-		"PublicDescription": "KMAC-Encrypted-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4197",
+-		"EventName": "KMAC_ENCRYPTED_AES_192",
+-		"BriefDescription": "KMAC ENCRYPTED AES 192",
+-		"PublicDescription": "KMAC-Encrypted-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4198",
+-		"EventName": "KMAC_ENCRYPTED_AES_256",
+-		"BriefDescription": "KMAC ENCRYPTED AES 256",
+-		"PublicDescription": "KMAC-Encrypted-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4199",
+-		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_DEA",
+-		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING DEA",
+-		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4200",
+-		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_128",
+-		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING TDEA 128",
+-		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-TDEA-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4201",
+-		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_192",
+-		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING TDEA 192",
+-		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-TDEA-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4202",
+-		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_DEA",
+-		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED DEA",
+-		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-DEA function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4203",
+-		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_128",
+-		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED TDEA 128",
+-		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-TDEA- 128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4204",
+-		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_192",
+-		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED TDEA 192",
+-		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-TDEA- 192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4205",
+-		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_128",
+-		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 128",
+-		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4206",
+-		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_192",
+-		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 192",
+-		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4207",
+-		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_256",
+-		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 256",
+-		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4208",
+-		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_128",
+-		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 128",
+-		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4209",
+-		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_192",
+-		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 192",
+-		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 192 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4210",
+-		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_256A",
+-		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 256A",
+-		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 256A function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4211",
+-		"EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_AES_128",
+-		"BriefDescription": "PCC COMPUTE XTS PARAMETER USING AES 128",
+-		"PublicDescription": "PCC-Compute-XTS-Parameter-Using-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4212",
+-		"EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_AES_256",
+-		"BriefDescription": "PCC COMPUTE XTS PARAMETER USING AES 256",
+-		"PublicDescription": "PCC-Compute-XTS-Parameter-Using-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4213",
+-		"EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_128",
+-		"BriefDescription": "PCC COMPUTE XTS PARAMETER USING ENCRYPTED AES 128",
+-		"PublicDescription": "PCC-Compute-XTS-Parameter-Using-Encrypted-AES-128 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4214",
+-		"EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_256",
+-		"BriefDescription": "PCC COMPUTE XTS PARAMETER USING ENCRYPTED AES 256",
+-		"PublicDescription": "PCC-Compute-XTS-Parameter-Using-Encrypted-AES-256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4215",
+-		"EventName": "PCC_SCALAR_MULTIPLY_P256",
+-		"BriefDescription": "PCC SCALAR MULTIPLY P256",
+-		"PublicDescription": "PCC-Scalar-Multiply-P256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4216",
+-		"EventName": "PCC_SCALAR_MULTIPLY_P384",
+-		"BriefDescription": "PCC SCALAR MULTIPLY P384",
+-		"PublicDescription": "PCC-Scalar-Multiply-P384 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4217",
+-		"EventName": "PCC_SCALAR_MULTIPLY_P521",
+-		"BriefDescription": "PCC SCALAR MULTIPLY P521",
+-		"PublicDescription": "PCC-Scalar-Multiply-P521 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4218",
+-		"EventName": "PCC_SCALAR_MULTIPLY_ED25519",
+-		"BriefDescription": "PCC SCALAR MULTIPLY ED25519",
+-		"PublicDescription": "PCC-Scalar-Multiply-Ed25519 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4219",
+-		"EventName": "PCC_SCALAR_MULTIPLY_ED448",
+-		"BriefDescription": "PCC SCALAR MULTIPLY ED448",
+-		"PublicDescription": "PCC-Scalar-Multiply-Ed448 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4220",
+-		"EventName": "PCC_SCALAR_MULTIPLY_X25519",
+-		"BriefDescription": "PCC SCALAR MULTIPLY X25519",
+-		"PublicDescription": "PCC-Scalar-Multiply-X25519 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4221",
+-		"EventName": "PCC_SCALAR_MULTIPLY_X448",
+-		"BriefDescription": "PCC SCALAR MULTIPLY X448",
+-		"PublicDescription": "PCC-Scalar-Multiply-X448 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4222",
+-		"EventName": "PRNO_SHA_512_DRNG",
+-		"BriefDescription": "PRNO SHA 512 DRNG",
+-		"PublicDescription": "PRNO-SHA-512-DRNG function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4223",
+-		"EventName": "PRNO_TRNG_QUERY_RAW_TO_CONDITIONED_RATIO",
+-		"BriefDescription": "PRNO TRNG QUERY RAW TO CONDITIONED RATIO",
+-		"PublicDescription": "PRNO-TRNG-Query-Raw-to-Conditioned-Ratio function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4224",
+-		"EventName": "PRNO_TRNG",
+-		"BriefDescription": "PRNO TRNG",
+-		"PublicDescription": "PRNO-TRNG function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4225",
+-		"EventName": "KDSA_ECDSA_VERIFY_P256",
+-		"BriefDescription": "KDSA ECDSA VERIFY P256",
+-		"PublicDescription": "KDSA-ECDSA-Verify-P256 function ending with CC=0 or CC=2"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4226",
+-		"EventName": "KDSA_ECDSA_VERIFY_P384",
+-		"BriefDescription": "KDSA ECDSA VERIFY P384",
+-		"PublicDescription": "KDSA-ECDSA-Verify-P384 function ending with CC=0 or CC=2"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4227",
+-		"EventName": "KDSA_ECDSA_VERIFY_P521",
+-		"BriefDescription": "KDSA ECDSA VERIFY P521",
+-		"PublicDescription": "KDSA-ECDSA-Verify-P521 function ending with CC=0 or CC=2"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4228",
+-		"EventName": "KDSA_ECDSA_SIGN_P256",
+-		"BriefDescription": "KDSA ECDSA SIGN P256",
+-		"PublicDescription": "KDSA-ECDSA-Sign-P256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4229",
+-		"EventName": "KDSA_ECDSA_SIGN_P384",
+-		"BriefDescription": "KDSA ECDSA SIGN P384",
+-		"PublicDescription": "KDSA-ECDSA-Sign-P384 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4230",
+-		"EventName": "KDSA_ECDSA_SIGN_P521",
+-		"BriefDescription": "KDSA ECDSA SIGN P521",
+-		"PublicDescription": "KDSA-ECDSA-Sign-P521 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4231",
+-		"EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P256",
+-		"BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P256",
+-		"PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P256 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4232",
+-		"EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P384",
+-		"BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P384",
+-		"PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P384 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4233",
+-		"EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P521",
+-		"BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P521",
+-		"PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P521 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4234",
+-		"EventName": "KDSA_EDDSA_VERIFY_ED25519",
+-		"BriefDescription": "KDSA EDDSA VERIFY ED25519",
+-		"PublicDescription": "KDSA-EdDSA-Verify-Ed25519 function ending with CC=0 or CC=2"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4235",
+-		"EventName": "KDSA_EDDSA_VERIFY_ED448",
+-		"BriefDescription": "KDSA EDDSA VERIFY ED448",
+-		"PublicDescription": "KDSA-EdDSA-Verify-Ed448 function ending with CC=0 or CC=2"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4236",
+-		"EventName": "KDSA_EDDSA_SIGN_ED25519",
+-		"BriefDescription": "KDSA EDDSA SIGN ED25519",
+-		"PublicDescription": "KDSA-EdDSA-Sign-Ed25519 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4237",
+-		"EventName": "KDSA_EDDSA_SIGN_ED448",
+-		"BriefDescription": "KDSA EDDSA SIGN ED448",
+-		"PublicDescription": "KDSA-EdDSA-Sign-Ed448 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4238",
+-		"EventName": "KDSA_ENCRYPTED_EDDSA_SIGN_ED25519",
+-		"BriefDescription": "KDSA ENCRYPTED EDDSA SIGN ED25519",
+-		"PublicDescription": "KDSA-Encrypted-EdDSA-Sign-Ed25519 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4239",
+-		"EventName": "KDSA_ENCRYPTED_EDDSA_SIGN_ED448",
+-		"BriefDescription": "KDSA ENCRYPTED EDDSA SIGN ED448",
+-		"PublicDescription": "KDSA-Encrypted-EdDSA-Sign-Ed448 function ending with CC=0"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4240",
+-		"EventName": "PCKMO_ENCRYPT_DEA_KEY",
+-		"BriefDescription": "PCKMO ENCRYPT DEA KEY",
+-		"PublicDescription": "PCKMO-Encrypt-DEA-key function"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4241",
+-		"EventName": "PCKMO_ENCRYPT_TDEA_128_KEY",
+-		"BriefDescription": "PCKMO ENCRYPT TDEA 128 KEY",
+-		"PublicDescription": "PCKMO-Encrypt-TDEA-128-key function"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4242",
+-		"EventName": "PCKMO_ENCRYPT_TDEA_192_KEY",
+-		"BriefDescription": "PCKMO ENCRYPT TDEA 192 KEY",
+-		"PublicDescription": "PCKMO-Encrypt-TDEA-192-key function"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4243",
+-		"EventName": "PCKMO_ENCRYPT_AES_128_KEY",
+-		"BriefDescription": "PCKMO ENCRYPT AES 128 KEY",
+-		"PublicDescription": "PCKMO-Encrypt-AES-128-key function"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4244",
+-		"EventName": "PCKMO_ENCRYPT_AES_192_KEY",
+-		"BriefDescription": "PCKMO ENCRYPT AES 192 KEY",
+-		"PublicDescription": "PCKMO-Encrypt-AES-192-key function"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4245",
+-		"EventName": "PCKMO_ENCRYPT_AES_256_KEY",
+-		"BriefDescription": "PCKMO ENCRYPT AES 256 KEY",
+-		"PublicDescription": "PCKMO-Encrypt-AES-256-key function"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4246",
+-		"EventName": "PCKMO_ENCRYPT_ECC_P256_KEY",
+-		"BriefDescription": "PCKMO ENCRYPT ECC P256 KEY",
+-		"PublicDescription": "PCKMO-Encrypt-ECC-P256-key function"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4247",
+-		"EventName": "PCKMO_ENCRYPT_ECC_P384_KEY",
+-		"BriefDescription": "PCKMO ENCRYPT ECC P384 KEY",
+-		"PublicDescription": "PCKMO-Encrypt-ECC-P384-key function"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4248",
+-		"EventName": "PCKMO_ENCRYPT_ECC_P521_KEY",
+-		"BriefDescription": "PCKMO ENCRYPT ECC P521 KEY",
+-		"PublicDescription": "PCKMO-Encrypt-ECC-P521-key function"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4249",
+-		"EventName": "PCKMO_ENCRYPT_ECC_ED25519_KEY",
+-		"BriefDescription": "PCKMO ENCRYPT ECC ED25519 KEY",
+-		"PublicDescription": "PCKMO-Encrypt-ECC-Ed25519-key function"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4250",
+-		"EventName": "PCKMO_ENCRYPT_ECC_ED448_KEY",
+-		"BriefDescription": "PCKMO ENCRYPT ECC ED448 KEY",
+-		"PublicDescription": "PCKMO-Encrypt-ECC-Ed448-key function"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4251",
+-		"EventName": "IBM_RESERVED_155",
+-		"BriefDescription": "IBM RESERVED_155",
+-		"PublicDescription": "Reserved for IBM use"
+-	},
+-	{
+-		"Unit": "PAI-CRYPTO",
+-		"EventCode": "4252",
+-		"EventName": "IBM_RESERVED_156",
+-		"BriefDescription": "IBM RESERVED_156",
+-		"PublicDescription": "Reserved for IBM use"
+-	}
+-]
+diff --git a/tools/perf/pmu-events/arch/s390/cf_z16/pai_crypto.json b/tools/perf/pmu-events/arch/s390/cf_z16/pai_crypto.json
+new file mode 100644
+index 0000000000000..cf8563d059b9e
+--- /dev/null
++++ b/tools/perf/pmu-events/arch/s390/cf_z16/pai_crypto.json
+@@ -0,0 +1,1101 @@
++[
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4096",
++		"EventName": "CRYPTO_ALL",
++		"BriefDescription": "CRYPTO ALL",
++		"PublicDescription": "Sums of all non zero cryptography counters"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4097",
++		"EventName": "KM_DEA",
++		"BriefDescription": "KM DEA",
++		"PublicDescription": "KM-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4098",
++		"EventName": "KM_TDEA_128",
++		"BriefDescription": "KM TDEA 128",
++		"PublicDescription": "KM-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4099",
++		"EventName": "KM_TDEA_192",
++		"BriefDescription": "KM TDEA 192",
++		"PublicDescription": "KM-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4100",
++		"EventName": "KM_ENCRYPTED_DEA",
++		"BriefDescription": "KM ENCRYPTED DEA",
++		"PublicDescription": "KM-Encrypted-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4101",
++		"EventName": "KM_ENCRYPTED_TDEA_128",
++		"BriefDescription": "KM ENCRYPTED TDEA 128",
++		"PublicDescription": "KM-Encrypted-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4102",
++		"EventName": "KM_ENCRYPTED_TDEA_192",
++		"BriefDescription": "KM ENCRYPTED TDEA 192",
++		"PublicDescription": "KM-Encrypted-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4103",
++		"EventName": "KM_AES_128",
++		"BriefDescription": "KM AES 128",
++		"PublicDescription": "KM-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4104",
++		"EventName": "KM_AES_192",
++		"BriefDescription": "KM AES 192",
++		"PublicDescription": "KM-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4105",
++		"EventName": "KM_AES_256",
++		"BriefDescription": "KM AES 256",
++		"PublicDescription": "KM-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4106",
++		"EventName": "KM_ENCRYPTED_AES_128",
++		"BriefDescription": "KM ENCRYPTED AES 128",
++		"PublicDescription": "KM-Encrypted-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4107",
++		"EventName": "KM_ENCRYPTED_AES_192",
++		"BriefDescription": "KM ENCRYPTED AES 192",
++		"PublicDescription": "KM-Encrypted-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4108",
++		"EventName": "KM_ENCRYPTED_AES_256",
++		"BriefDescription": "KM ENCRYPTED AES 256",
++		"PublicDescription": "KM-Encrypted-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4109",
++		"EventName": "KM_XTS_AES_128",
++		"BriefDescription": "KM XTS AES 128",
++		"PublicDescription": "KM-XTS-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4110",
++		"EventName": "KM_XTS_AES_256",
++		"BriefDescription": "KM XTS AES 256",
++		"PublicDescription": "KM-XTS-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4111",
++		"EventName": "KM_XTS_ENCRYPTED_AES_128",
++		"BriefDescription": "KM XTS ENCRYPTED AES 128",
++		"PublicDescription": "KM-XTS-Encrypted-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4112",
++		"EventName": "KM_XTS_ENCRYPTED_AES_256",
++		"BriefDescription": "KM XTS ENCRYPTED AES 256",
++		"PublicDescription": "KM-XTS-Encrypted-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4113",
++		"EventName": "KMC_DEA",
++		"BriefDescription": "KMC DEA",
++		"PublicDescription": "KMC-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4114",
++		"EventName": "KMC_TDEA_128",
++		"BriefDescription": "KMC TDEA 128",
++		"PublicDescription": "KMC-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4115",
++		"EventName": "KMC_TDEA_192",
++		"BriefDescription": "KMC TDEA 192",
++		"PublicDescription": "KMC-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4116",
++		"EventName": "KMC_ENCRYPTED_DEA",
++		"BriefDescription": "KMC ENCRYPTED DEA",
++		"PublicDescription": "KMC-Encrypted-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4117",
++		"EventName": "KMC_ENCRYPTED_TDEA_128",
++		"BriefDescription": "KMC ENCRYPTED TDEA 128",
++		"PublicDescription": "KMC-Encrypted-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4118",
++		"EventName": "KMC_ENCRYPTED_TDEA_192",
++		"BriefDescription": "KMC ENCRYPTED TDEA 192",
++		"PublicDescription": "KMC-Encrypted-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4119",
++		"EventName": "KMC_AES_128",
++		"BriefDescription": "KMC AES 128",
++		"PublicDescription": "KMC-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4120",
++		"EventName": "KMC_AES_192",
++		"BriefDescription": "KMC AES 192",
++		"PublicDescription": "KMC-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4121",
++		"EventName": "KMC_AES_256",
++		"BriefDescription": "KMC AES 256",
++		"PublicDescription": "KMC-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4122",
++		"EventName": "KMC_ENCRYPTED_AES_128",
++		"BriefDescription": "KMC ENCRYPTED AES 128",
++		"PublicDescription": "KMC-Encrypted-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4123",
++		"EventName": "KMC_ENCRYPTED_AES_192",
++		"BriefDescription": "KMC ENCRYPTED AES 192",
++		"PublicDescription": "KMC-Encrypted-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4124",
++		"EventName": "KMC_ENCRYPTED_AES_256",
++		"BriefDescription": "KMC ENCRYPTED AES 256",
++		"PublicDescription": "KMC-Encrypted-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4125",
++		"EventName": "KMC_PRNG",
++		"BriefDescription": "KMC PRNG",
++		"PublicDescription": "KMC-PRNG function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4126",
++		"EventName": "KMA_GCM_AES_128",
++		"BriefDescription": "KMA GCM AES 128",
++		"PublicDescription": "KMA-GCM-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4127",
++		"EventName": "KMA_GCM_AES_192",
++		"BriefDescription": "KMA GCM AES 192",
++		"PublicDescription": "KMA-GCM-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4128",
++		"EventName": "KMA_GCM_AES_256",
++		"BriefDescription": "KMA GCM AES 256",
++		"PublicDescription": "KMA-GCM-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4129",
++		"EventName": "KMA_GCM_ENCRYPTED_AES_128",
++		"BriefDescription": "KMA GCM ENCRYPTED AES 128",
++		"PublicDescription": "KMA-GCM-Encrypted-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4130",
++		"EventName": "KMA_GCM_ENCRYPTED_AES_192",
++		"BriefDescription": "KMA GCM ENCRYPTED AES 192",
++		"PublicDescription": "KMA-GCM-Encrypted-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4131",
++		"EventName": "KMA_GCM_ENCRYPTED_AES_256",
++		"BriefDescription": "KMA GCM ENCRYPTED AES 256",
++		"PublicDescription": "KMA-GCM-Encrypted-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4132",
++		"EventName": "KMF_DEA",
++		"BriefDescription": "KMF DEA",
++		"PublicDescription": "KMF-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4133",
++		"EventName": "KMF_TDEA_128",
++		"BriefDescription": "KMF TDEA 128",
++		"PublicDescription": "KMF-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4134",
++		"EventName": "KMF_TDEA_192",
++		"BriefDescription": "KMF TDEA 192",
++		"PublicDescription": "KMF-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4135",
++		"EventName": "KMF_ENCRYPTED_DEA",
++		"BriefDescription": "KMF ENCRYPTED DEA",
++		"PublicDescription": "KMF-Encrypted-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4136",
++		"EventName": "KMF_ENCRYPTED_TDEA_128",
++		"BriefDescription": "KMF ENCRYPTED TDEA 128",
++		"PublicDescription": "KMF-Encrypted-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4137",
++		"EventName": "KMF_ENCRYPTED_TDEA_192",
++		"BriefDescription": "KMF ENCRYPTED TDEA 192",
++		"PublicDescription": "KMF-Encrypted-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4138",
++		"EventName": "KMF_AES_128",
++		"BriefDescription": "KMF AES 128",
++		"PublicDescription": "KMF-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4139",
++		"EventName": "KMF_AES_192",
++		"BriefDescription": "KMF AES 192",
++		"PublicDescription": "KMF-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4140",
++		"EventName": "KMF_AES_256",
++		"BriefDescription": "KMF AES 256",
++		"PublicDescription": "KMF-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4141",
++		"EventName": "KMF_ENCRYPTED_AES_128",
++		"BriefDescription": "KMF ENCRYPTED AES 128",
++		"PublicDescription": "KMF-Encrypted-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4142",
++		"EventName": "KMF_ENCRYPTED_AES_192",
++		"BriefDescription": "KMF ENCRYPTED AES 192",
++		"PublicDescription": "KMF-Encrypted-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4143",
++		"EventName": "KMF_ENCRYPTED_AES_256",
++		"BriefDescription": "KMF ENCRYPTED AES 256",
++		"PublicDescription": "KMF-Encrypted-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4144",
++		"EventName": "KMCTR_DEA",
++		"BriefDescription": "KMCTR DEA",
++		"PublicDescription": "KMCTR-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4145",
++		"EventName": "KMCTR_TDEA_128",
++		"BriefDescription": "KMCTR TDEA 128",
++		"PublicDescription": "KMCTR-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4146",
++		"EventName": "KMCTR_TDEA_192",
++		"BriefDescription": "KMCTR TDEA 192",
++		"PublicDescription": "KMCTR-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4147",
++		"EventName": "KMCTR_ENCRYPTED_DEA",
++		"BriefDescription": "KMCTR ENCRYPTED DEA",
++		"PublicDescription": "KMCTR-Encrypted-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4148",
++		"EventName": "KMCTR_ENCRYPTED_TDEA_128",
++		"BriefDescription": "KMCTR ENCRYPTED TDEA 128",
++		"PublicDescription": "KMCTR-Encrypted-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4149",
++		"EventName": "KMCTR_ENCRYPTED_TDEA_192",
++		"BriefDescription": "KMCTR ENCRYPTED TDEA 192",
++		"PublicDescription": "KMCTR-Encrypted-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4150",
++		"EventName": "KMCTR_AES_128",
++		"BriefDescription": "KMCTR AES 128",
++		"PublicDescription": "KMCTR-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4151",
++		"EventName": "KMCTR_AES_192",
++		"BriefDescription": "KMCTR AES 192",
++		"PublicDescription": "KMCTR-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4152",
++		"EventName": "KMCTR_AES_256",
++		"BriefDescription": "KMCTR AES 256",
++		"PublicDescription": "KMCTR-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4153",
++		"EventName": "KMCTR_ENCRYPTED_AES_128",
++		"BriefDescription": "KMCTR ENCRYPTED AES 128",
++		"PublicDescription": "KMCTR-Encrypted-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4154",
++		"EventName": "KMCTR_ENCRYPTED_AES_192",
++		"BriefDescription": "KMCTR ENCRYPTED AES 192",
++		"PublicDescription": "KMCTR-Encrypted-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4155",
++		"EventName": "KMCTR_ENCRYPTED_AES_256",
++		"BriefDescription": "KMCTR ENCRYPTED AES 256",
++		"PublicDescription": "KMCTR-Encrypted-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4156",
++		"EventName": "KMO_DEA",
++		"BriefDescription": "KMO DEA",
++		"PublicDescription": "KMO-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4157",
++		"EventName": "KMO_TDEA_128",
++		"BriefDescription": "KMO TDEA 128",
++		"PublicDescription": "KMO-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4158",
++		"EventName": "KMO_TDEA_192",
++		"BriefDescription": "KMO TDEA 192",
++		"PublicDescription": "KMO-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4159",
++		"EventName": "KMO_ENCRYPTED_DEA",
++		"BriefDescription": "KMO ENCRYPTED DEA",
++		"PublicDescription": "KMO-Encrypted-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4160",
++		"EventName": "KMO_ENCRYPTED_TDEA_128",
++		"BriefDescription": "KMO ENCRYPTED TDEA 128",
++		"PublicDescription": "KMO-Encrypted-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4161",
++		"EventName": "KMO_ENCRYPTED_TDEA_192",
++		"BriefDescription": "KMO ENCRYPTED TDEA 192",
++		"PublicDescription": "KMO-Encrypted-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4162",
++		"EventName": "KMO_AES_128",
++		"BriefDescription": "KMO AES 128",
++		"PublicDescription": "KMO-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4163",
++		"EventName": "KMO_AES_192",
++		"BriefDescription": "KMO AES 192",
++		"PublicDescription": "KMO-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4164",
++		"EventName": "KMO_AES_256",
++		"BriefDescription": "KMO AES 256",
++		"PublicDescription": "KMO-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4165",
++		"EventName": "KMO_ENCRYPTED_AES_128",
++		"BriefDescription": "KMO ENCRYPTED AES 128",
++		"PublicDescription": "KMO-Encrypted-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4166",
++		"EventName": "KMO_ENCRYPTED_AES_192",
++		"BriefDescription": "KMO ENCRYPTED AES 192",
++		"PublicDescription": "KMO-Encrypted-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4167",
++		"EventName": "KMO_ENCRYPTED_AES_256",
++		"BriefDescription": "KMO ENCRYPTED AES 256",
++		"PublicDescription": "KMO-Encrypted-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4168",
++		"EventName": "KIMD_SHA_1",
++		"BriefDescription": "KIMD SHA 1",
++		"PublicDescription": "KIMD-SHA-1 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4169",
++		"EventName": "KIMD_SHA_256",
++		"BriefDescription": "KIMD SHA 256",
++		"PublicDescription": "KIMD-SHA-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4170",
++		"EventName": "KIMD_SHA_512",
++		"BriefDescription": "KIMD SHA 512",
++		"PublicDescription": "KIMD-SHA-512 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4171",
++		"EventName": "KIMD_SHA3_224",
++		"BriefDescription": "KIMD SHA3 224",
++		"PublicDescription": "KIMD-SHA3-224 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4172",
++		"EventName": "KIMD_SHA3_256",
++		"BriefDescription": "KIMD SHA3 256",
++		"PublicDescription": "KIMD-SHA3-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4173",
++		"EventName": "KIMD_SHA3_384",
++		"BriefDescription": "KIMD SHA3 384",
++		"PublicDescription": "KIMD-SHA3-384 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4174",
++		"EventName": "KIMD_SHA3_512",
++		"BriefDescription": "KIMD SHA3 512",
++		"PublicDescription": "KIMD-SHA3-512 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4175",
++		"EventName": "KIMD_SHAKE_128",
++		"BriefDescription": "KIMD SHAKE 128",
++		"PublicDescription": "KIMD-SHAKE-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4176",
++		"EventName": "KIMD_SHAKE_256",
++		"BriefDescription": "KIMD SHAKE 256",
++		"PublicDescription": "KIMD-SHAKE-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4177",
++		"EventName": "KIMD_GHASH",
++		"BriefDescription": "KIMD GHASH",
++		"PublicDescription": "KIMD-GHASH function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4178",
++		"EventName": "KLMD_SHA_1",
++		"BriefDescription": "KLMD SHA 1",
++		"PublicDescription": "KLMD-SHA-1 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4179",
++		"EventName": "KLMD_SHA_256",
++		"BriefDescription": "KLMD SHA 256",
++		"PublicDescription": "KLMD-SHA-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4180",
++		"EventName": "KLMD_SHA_512",
++		"BriefDescription": "KLMD SHA 512",
++		"PublicDescription": "KLMD-SHA-512 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4181",
++		"EventName": "KLMD_SHA3_224",
++		"BriefDescription": "KLMD SHA3 224",
++		"PublicDescription": "KLMD-SHA3-224 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4182",
++		"EventName": "KLMD_SHA3_256",
++		"BriefDescription": "KLMD SHA3 256",
++		"PublicDescription": "KLMD-SHA3-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4183",
++		"EventName": "KLMD_SHA3_384",
++		"BriefDescription": "KLMD SHA3 384",
++		"PublicDescription": "KLMD-SHA3-384 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4184",
++		"EventName": "KLMD_SHA3_512",
++		"BriefDescription": "KLMD SHA3 512",
++		"PublicDescription": "KLMD-SHA3-512 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4185",
++		"EventName": "KLMD_SHAKE_128",
++		"BriefDescription": "KLMD SHAKE 128",
++		"PublicDescription": "KLMD-SHAKE-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4186",
++		"EventName": "KLMD_SHAKE_256",
++		"BriefDescription": "KLMD SHAKE 256",
++		"PublicDescription": "KLMD-SHAKE-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4187",
++		"EventName": "KMAC_DEA",
++		"BriefDescription": "KMAC DEA",
++		"PublicDescription": "KMAC-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4188",
++		"EventName": "KMAC_TDEA_128",
++		"BriefDescription": "KMAC TDEA 128",
++		"PublicDescription": "KMAC-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4189",
++		"EventName": "KMAC_TDEA_192",
++		"BriefDescription": "KMAC TDEA 192",
++		"PublicDescription": "KMAC-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4190",
++		"EventName": "KMAC_ENCRYPTED_DEA",
++		"BriefDescription": "KMAC ENCRYPTED DEA",
++		"PublicDescription": "KMAC-Encrypted-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4191",
++		"EventName": "KMAC_ENCRYPTED_TDEA_128",
++		"BriefDescription": "KMAC ENCRYPTED TDEA 128",
++		"PublicDescription": "KMAC-Encrypted-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4192",
++		"EventName": "KMAC_ENCRYPTED_TDEA_192",
++		"BriefDescription": "KMAC ENCRYPTED TDEA 192",
++		"PublicDescription": "KMAC-Encrypted-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4193",
++		"EventName": "KMAC_AES_128",
++		"BriefDescription": "KMAC AES 128",
++		"PublicDescription": "KMAC-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4194",
++		"EventName": "KMAC_AES_192",
++		"BriefDescription": "KMAC AES 192",
++		"PublicDescription": "KMAC-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4195",
++		"EventName": "KMAC_AES_256",
++		"BriefDescription": "KMAC AES 256",
++		"PublicDescription": "KMAC-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4196",
++		"EventName": "KMAC_ENCRYPTED_AES_128",
++		"BriefDescription": "KMAC ENCRYPTED AES 128",
++		"PublicDescription": "KMAC-Encrypted-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4197",
++		"EventName": "KMAC_ENCRYPTED_AES_192",
++		"BriefDescription": "KMAC ENCRYPTED AES 192",
++		"PublicDescription": "KMAC-Encrypted-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4198",
++		"EventName": "KMAC_ENCRYPTED_AES_256",
++		"BriefDescription": "KMAC ENCRYPTED AES 256",
++		"PublicDescription": "KMAC-Encrypted-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4199",
++		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_DEA",
++		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING DEA",
++		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4200",
++		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_128",
++		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING TDEA 128",
++		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-TDEA-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4201",
++		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_192",
++		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING TDEA 192",
++		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-TDEA-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4202",
++		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_DEA",
++		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED DEA",
++		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-DEA function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4203",
++		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_128",
++		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED TDEA 128",
++		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-TDEA- 128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4204",
++		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_192",
++		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED TDEA 192",
++		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-TDEA- 192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4205",
++		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_128",
++		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 128",
++		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4206",
++		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_192",
++		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 192",
++		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4207",
++		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_256",
++		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING AES 256",
++		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4208",
++		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_128",
++		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 128",
++		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4209",
++		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_192",
++		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 192",
++		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 192 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4210",
++		"EventName": "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_256A",
++		"BriefDescription": "PCC COMPUTE LAST BLOCK CMAC USING ENCRYPTED AES 256A",
++		"PublicDescription": "PCC-Compute-Last-Block-CMAC-Using-Encrypted-AES- 256A function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4211",
++		"EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_AES_128",
++		"BriefDescription": "PCC COMPUTE XTS PARAMETER USING AES 128",
++		"PublicDescription": "PCC-Compute-XTS-Parameter-Using-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4212",
++		"EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_AES_256",
++		"BriefDescription": "PCC COMPUTE XTS PARAMETER USING AES 256",
++		"PublicDescription": "PCC-Compute-XTS-Parameter-Using-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4213",
++		"EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_128",
++		"BriefDescription": "PCC COMPUTE XTS PARAMETER USING ENCRYPTED AES 128",
++		"PublicDescription": "PCC-Compute-XTS-Parameter-Using-Encrypted-AES-128 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4214",
++		"EventName": "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_256",
++		"BriefDescription": "PCC COMPUTE XTS PARAMETER USING ENCRYPTED AES 256",
++		"PublicDescription": "PCC-Compute-XTS-Parameter-Using-Encrypted-AES-256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4215",
++		"EventName": "PCC_SCALAR_MULTIPLY_P256",
++		"BriefDescription": "PCC SCALAR MULTIPLY P256",
++		"PublicDescription": "PCC-Scalar-Multiply-P256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4216",
++		"EventName": "PCC_SCALAR_MULTIPLY_P384",
++		"BriefDescription": "PCC SCALAR MULTIPLY P384",
++		"PublicDescription": "PCC-Scalar-Multiply-P384 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4217",
++		"EventName": "PCC_SCALAR_MULTIPLY_P521",
++		"BriefDescription": "PCC SCALAR MULTIPLY P521",
++		"PublicDescription": "PCC-Scalar-Multiply-P521 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4218",
++		"EventName": "PCC_SCALAR_MULTIPLY_ED25519",
++		"BriefDescription": "PCC SCALAR MULTIPLY ED25519",
++		"PublicDescription": "PCC-Scalar-Multiply-Ed25519 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4219",
++		"EventName": "PCC_SCALAR_MULTIPLY_ED448",
++		"BriefDescription": "PCC SCALAR MULTIPLY ED448",
++		"PublicDescription": "PCC-Scalar-Multiply-Ed448 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4220",
++		"EventName": "PCC_SCALAR_MULTIPLY_X25519",
++		"BriefDescription": "PCC SCALAR MULTIPLY X25519",
++		"PublicDescription": "PCC-Scalar-Multiply-X25519 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4221",
++		"EventName": "PCC_SCALAR_MULTIPLY_X448",
++		"BriefDescription": "PCC SCALAR MULTIPLY X448",
++		"PublicDescription": "PCC-Scalar-Multiply-X448 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4222",
++		"EventName": "PRNO_SHA_512_DRNG",
++		"BriefDescription": "PRNO SHA 512 DRNG",
++		"PublicDescription": "PRNO-SHA-512-DRNG function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4223",
++		"EventName": "PRNO_TRNG_QUERY_RAW_TO_CONDITIONED_RATIO",
++		"BriefDescription": "PRNO TRNG QUERY RAW TO CONDITIONED RATIO",
++		"PublicDescription": "PRNO-TRNG-Query-Raw-to-Conditioned-Ratio function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4224",
++		"EventName": "PRNO_TRNG",
++		"BriefDescription": "PRNO TRNG",
++		"PublicDescription": "PRNO-TRNG function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4225",
++		"EventName": "KDSA_ECDSA_VERIFY_P256",
++		"BriefDescription": "KDSA ECDSA VERIFY P256",
++		"PublicDescription": "KDSA-ECDSA-Verify-P256 function ending with CC=0 or CC=2"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4226",
++		"EventName": "KDSA_ECDSA_VERIFY_P384",
++		"BriefDescription": "KDSA ECDSA VERIFY P384",
++		"PublicDescription": "KDSA-ECDSA-Verify-P384 function ending with CC=0 or CC=2"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4227",
++		"EventName": "KDSA_ECDSA_VERIFY_P521",
++		"BriefDescription": "KDSA ECDSA VERIFY P521",
++		"PublicDescription": "KDSA-ECDSA-Verify-P521 function ending with CC=0 or CC=2"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4228",
++		"EventName": "KDSA_ECDSA_SIGN_P256",
++		"BriefDescription": "KDSA ECDSA SIGN P256",
++		"PublicDescription": "KDSA-ECDSA-Sign-P256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4229",
++		"EventName": "KDSA_ECDSA_SIGN_P384",
++		"BriefDescription": "KDSA ECDSA SIGN P384",
++		"PublicDescription": "KDSA-ECDSA-Sign-P384 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4230",
++		"EventName": "KDSA_ECDSA_SIGN_P521",
++		"BriefDescription": "KDSA ECDSA SIGN P521",
++		"PublicDescription": "KDSA-ECDSA-Sign-P521 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4231",
++		"EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P256",
++		"BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P256",
++		"PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P256 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4232",
++		"EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P384",
++		"BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P384",
++		"PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P384 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4233",
++		"EventName": "KDSA_ENCRYPTED_ECDSA_SIGN_P521",
++		"BriefDescription": "KDSA ENCRYPTED ECDSA SIGN P521",
++		"PublicDescription": "KDSA-Encrypted-ECDSA-Sign-P521 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4234",
++		"EventName": "KDSA_EDDSA_VERIFY_ED25519",
++		"BriefDescription": "KDSA EDDSA VERIFY ED25519",
++		"PublicDescription": "KDSA-EdDSA-Verify-Ed25519 function ending with CC=0 or CC=2"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4235",
++		"EventName": "KDSA_EDDSA_VERIFY_ED448",
++		"BriefDescription": "KDSA EDDSA VERIFY ED448",
++		"PublicDescription": "KDSA-EdDSA-Verify-Ed448 function ending with CC=0 or CC=2"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4236",
++		"EventName": "KDSA_EDDSA_SIGN_ED25519",
++		"BriefDescription": "KDSA EDDSA SIGN ED25519",
++		"PublicDescription": "KDSA-EdDSA-Sign-Ed25519 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4237",
++		"EventName": "KDSA_EDDSA_SIGN_ED448",
++		"BriefDescription": "KDSA EDDSA SIGN ED448",
++		"PublicDescription": "KDSA-EdDSA-Sign-Ed448 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4238",
++		"EventName": "KDSA_ENCRYPTED_EDDSA_SIGN_ED25519",
++		"BriefDescription": "KDSA ENCRYPTED EDDSA SIGN ED25519",
++		"PublicDescription": "KDSA-Encrypted-EdDSA-Sign-Ed25519 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4239",
++		"EventName": "KDSA_ENCRYPTED_EDDSA_SIGN_ED448",
++		"BriefDescription": "KDSA ENCRYPTED EDDSA SIGN ED448",
++		"PublicDescription": "KDSA-Encrypted-EdDSA-Sign-Ed448 function ending with CC=0"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4240",
++		"EventName": "PCKMO_ENCRYPT_DEA_KEY",
++		"BriefDescription": "PCKMO ENCRYPT DEA KEY",
++		"PublicDescription": "PCKMO-Encrypt-DEA-key function"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4241",
++		"EventName": "PCKMO_ENCRYPT_TDEA_128_KEY",
++		"BriefDescription": "PCKMO ENCRYPT TDEA 128 KEY",
++		"PublicDescription": "PCKMO-Encrypt-TDEA-128-key function"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4242",
++		"EventName": "PCKMO_ENCRYPT_TDEA_192_KEY",
++		"BriefDescription": "PCKMO ENCRYPT TDEA 192 KEY",
++		"PublicDescription": "PCKMO-Encrypt-TDEA-192-key function"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4243",
++		"EventName": "PCKMO_ENCRYPT_AES_128_KEY",
++		"BriefDescription": "PCKMO ENCRYPT AES 128 KEY",
++		"PublicDescription": "PCKMO-Encrypt-AES-128-key function"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4244",
++		"EventName": "PCKMO_ENCRYPT_AES_192_KEY",
++		"BriefDescription": "PCKMO ENCRYPT AES 192 KEY",
++		"PublicDescription": "PCKMO-Encrypt-AES-192-key function"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4245",
++		"EventName": "PCKMO_ENCRYPT_AES_256_KEY",
++		"BriefDescription": "PCKMO ENCRYPT AES 256 KEY",
++		"PublicDescription": "PCKMO-Encrypt-AES-256-key function"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4246",
++		"EventName": "PCKMO_ENCRYPT_ECC_P256_KEY",
++		"BriefDescription": "PCKMO ENCRYPT ECC P256 KEY",
++		"PublicDescription": "PCKMO-Encrypt-ECC-P256-key function"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4247",
++		"EventName": "PCKMO_ENCRYPT_ECC_P384_KEY",
++		"BriefDescription": "PCKMO ENCRYPT ECC P384 KEY",
++		"PublicDescription": "PCKMO-Encrypt-ECC-P384-key function"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4248",
++		"EventName": "PCKMO_ENCRYPT_ECC_P521_KEY",
++		"BriefDescription": "PCKMO ENCRYPT ECC P521 KEY",
++		"PublicDescription": "PCKMO-Encrypt-ECC-P521-key function"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4249",
++		"EventName": "PCKMO_ENCRYPT_ECC_ED25519_KEY",
++		"BriefDescription": "PCKMO ENCRYPT ECC ED25519 KEY",
++		"PublicDescription": "PCKMO-Encrypt-ECC-Ed25519-key function"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4250",
++		"EventName": "PCKMO_ENCRYPT_ECC_ED448_KEY",
++		"BriefDescription": "PCKMO ENCRYPT ECC ED448 KEY",
++		"PublicDescription": "PCKMO-Encrypt-ECC-Ed448-key function"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4251",
++		"EventName": "IBM_RESERVED_155",
++		"BriefDescription": "IBM RESERVED_155",
++		"PublicDescription": "Reserved for IBM use"
++	},
++	{
++		"Unit": "PAI-CRYPTO",
++		"EventCode": "4252",
++		"EventName": "IBM_RESERVED_156",
++		"BriefDescription": "IBM RESERVED_156",
++		"PublicDescription": "Reserved for IBM use"
++	}
++]
+diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
+index 6edab8a16de6a..aded2caff3a23 100644
+--- a/tools/perf/util/auxtrace.c
++++ b/tools/perf/util/auxtrace.c
+@@ -2308,11 +2308,19 @@ struct sym_args {
+ 	bool		near;
+ };
+ 
++static bool kern_sym_name_match(const char *kname, const char *name)
++{
++	size_t n = strlen(name);
++
++	return !strcmp(kname, name) ||
++	       (!strncmp(kname, name, n) && kname[n] == '\t');
++}
++
+ static bool kern_sym_match(struct sym_args *args, const char *name, char type)
+ {
+ 	/* A function with the same name, and global or the n'th found or any */
+ 	return kallsyms__is_function(type) &&
+-	       !strcmp(name, args->name) &&
++	       kern_sym_name_match(name, args->name) &&
+ 	       ((args->global && isupper(type)) ||
+ 		(args->selected && ++(args->cnt) == args->idx) ||
+ 		(!args->global && !args->selected));
+diff --git a/tools/testing/selftests/drivers/net/bonding/Makefile b/tools/testing/selftests/drivers/net/bonding/Makefile
+index 1d866658e541e..c61299c10e367 100644
+--- a/tools/testing/selftests/drivers/net/bonding/Makefile
++++ b/tools/testing/selftests/drivers/net/bonding/Makefile
+@@ -5,6 +5,8 @@ TEST_PROGS := bond-break-lacpdu-tx.sh \
+ 	      dev_addr_lists.sh \
+ 	      bond-arp-interval-causes-panic.sh
+ 
+-TEST_FILES := lag_lib.sh
++TEST_FILES := \
++	lag_lib.sh \
++	net_forwarding_lib.sh
+ 
+ include ../../../lib.mk
+diff --git a/tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh b/tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh
+index e6fa24eded5b8..5cfe7d8ebc256 100755
+--- a/tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh
++++ b/tools/testing/selftests/drivers/net/bonding/dev_addr_lists.sh
+@@ -14,7 +14,7 @@ ALL_TESTS="
+ REQUIRE_MZ=no
+ NUM_NETIFS=0
+ lib_dir=$(dirname "$0")
+-source "$lib_dir"/../../../net/forwarding/lib.sh
++source "$lib_dir"/net_forwarding_lib.sh
+ 
+ source "$lib_dir"/lag_lib.sh
+ 
+diff --git a/tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh b/tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh
+new file mode 120000
+index 0000000000000..39c96828c5eff
+--- /dev/null
++++ b/tools/testing/selftests/drivers/net/bonding/net_forwarding_lib.sh
+@@ -0,0 +1 @@
++../../../net/forwarding/lib.sh
+\ No newline at end of file
+diff --git a/tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh b/tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh
+index dca8be6092b92..a1f269ee84dac 100755
+--- a/tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh
++++ b/tools/testing/selftests/drivers/net/dsa/test_bridge_fdb_stress.sh
+@@ -18,8 +18,8 @@ NUM_NETIFS=1
+ REQUIRE_JQ="no"
+ REQUIRE_MZ="no"
+ NETIF_CREATE="no"
+-lib_dir=$(dirname $0)/../../../net/forwarding
+-source $lib_dir/lib.sh
++lib_dir=$(dirname "$0")
++source "$lib_dir"/lib.sh
+ 
+ cleanup() {
+ 	echo "Cleaning up"
+diff --git a/tools/testing/selftests/drivers/net/team/Makefile b/tools/testing/selftests/drivers/net/team/Makefile
+index 642d8df1c137b..6a86e61e8bfe5 100644
+--- a/tools/testing/selftests/drivers/net/team/Makefile
++++ b/tools/testing/selftests/drivers/net/team/Makefile
+@@ -3,4 +3,8 @@
+ 
+ TEST_PROGS := dev_addr_lists.sh
+ 
++TEST_FILES := \
++	lag_lib.sh \
++	net_forwarding_lib.sh
++
+ include ../../../lib.mk
+diff --git a/tools/testing/selftests/drivers/net/team/dev_addr_lists.sh b/tools/testing/selftests/drivers/net/team/dev_addr_lists.sh
+index debda72629564..33913112d5ca0 100755
+--- a/tools/testing/selftests/drivers/net/team/dev_addr_lists.sh
++++ b/tools/testing/selftests/drivers/net/team/dev_addr_lists.sh
+@@ -11,14 +11,14 @@ ALL_TESTS="
+ REQUIRE_MZ=no
+ NUM_NETIFS=0
+ lib_dir=$(dirname "$0")
+-source "$lib_dir"/../../../net/forwarding/lib.sh
++source "$lib_dir"/net_forwarding_lib.sh
+ 
+-source "$lib_dir"/../bonding/lag_lib.sh
++source "$lib_dir"/lag_lib.sh
+ 
+ 
+ destroy()
+ {
+-	local ifnames=(dummy0 dummy1 team0 mv0)
++	local ifnames=(dummy1 dummy2 team0 mv0)
+ 	local ifname
+ 
+ 	for ifname in "${ifnames[@]}"; do
+diff --git a/tools/testing/selftests/drivers/net/team/lag_lib.sh b/tools/testing/selftests/drivers/net/team/lag_lib.sh
+new file mode 120000
+index 0000000000000..e1347a10afde6
+--- /dev/null
++++ b/tools/testing/selftests/drivers/net/team/lag_lib.sh
+@@ -0,0 +1 @@
++../bonding/lag_lib.sh
+\ No newline at end of file
+diff --git a/tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh b/tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh
+new file mode 120000
+index 0000000000000..39c96828c5eff
+--- /dev/null
++++ b/tools/testing/selftests/drivers/net/team/net_forwarding_lib.sh
+@@ -0,0 +1 @@
++../../../net/forwarding/lib.sh
+\ No newline at end of file
+diff --git a/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc b/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc
+index db522577ff787..d3a79da215c8b 100644
+--- a/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc
++++ b/tools/testing/selftests/ftrace/test.d/dynevent/test_duplicates.tc
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+ # SPDX-License-Identifier: GPL-2.0
+ # description: Generic dynamic event - check if duplicate events are caught
+-# requires: dynamic_events "e[:[<group>/]<event>] <attached-group>.<attached-event> [<args>]":README
++# requires: dynamic_events "e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]":README
+ 
+ echo 0 > events/enable
+ 
+diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc
+index 914fe2e5d0309..6461c375694f0 100644
+--- a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc
++++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-eprobe.tc
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+ # SPDX-License-Identifier: GPL-2.0
+ # description: event trigger - test inter-event histogram trigger eprobe on synthetic event
+-# requires: dynamic_events synthetic_events events/syscalls/sys_enter_openat/hist "e[:[<group>/]<event>] <attached-group>.<attached-event> [<args>]":README
++# requires: dynamic_events synthetic_events events/syscalls/sys_enter_openat/hist "e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]":README
+ 
+ echo 0 > events/enable
+ 
+diff --git a/tools/testing/selftests/kvm/memslot_modification_stress_test.c b/tools/testing/selftests/kvm/memslot_modification_stress_test.c
+index 6ee7e1dde4043..bb1d17a1171bc 100644
+--- a/tools/testing/selftests/kvm/memslot_modification_stress_test.c
++++ b/tools/testing/selftests/kvm/memslot_modification_stress_test.c
+@@ -67,7 +67,7 @@ struct memslot_antagonist_args {
+ static void add_remove_memslot(struct kvm_vm *vm, useconds_t delay,
+ 			       uint64_t nr_modifications)
+ {
+-	const uint64_t pages = 1;
++	uint64_t pages = max_t(int, vm->page_size, getpagesize()) / vm->page_size;
+ 	uint64_t gpa;
+ 	int i;
+ 
+diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk
+index 9d4cb94cf4374..a3ea3d4a206d0 100644
+--- a/tools/testing/selftests/lib.mk
++++ b/tools/testing/selftests/lib.mk
+@@ -70,7 +70,7 @@ endef
+ run_tests: all
+ ifdef building_out_of_srctree
+ 	@if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \
+-		rsync -aq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \
++		rsync -aLq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \
+ 	fi
+ 	@if [ "X$(TEST_PROGS)" != "X" ]; then \
+ 		$(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) \
+@@ -84,7 +84,7 @@ endif
+ 
+ define INSTALL_SINGLE_RULE
+ 	$(if $(INSTALL_LIST),@mkdir -p $(INSTALL_PATH))
+-	$(if $(INSTALL_LIST),rsync -a $(INSTALL_LIST) $(INSTALL_PATH)/)
++	$(if $(INSTALL_LIST),rsync -aL $(INSTALL_LIST) $(INSTALL_PATH)/)
+ endef
+ 
+ define INSTALL_RULE


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-11-01 12:46 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-11-01 12:46 UTC (permalink / raw
  To: gentoo-commits

commit:     5ceffccd28e7d4cc987afb63c276189d7d3925e0
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Tue Nov  1 12:45:24 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Tue Nov  1 12:45:24 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=5ceffccd

btrfs: don't use btrfs_chunk::sub_stripes from disk

Bug: https://bugs.gentoo.org/878023

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

 0000_README                            |  8 ++-
 1900_btrfs-chunk-sub_stripes-fix.patch | 92 ++++++++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+), 2 deletions(-)

diff --git a/0000_README b/0000_README
index 68ada3e5..a0b5ecc7 100644
--- a/0000_README
+++ b/0000_README
@@ -76,8 +76,12 @@ From:   http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/
 Desc:   Enable link security restrictions by default.
 
 Patch:  1700_sparc-address-warray-bound-warnings.patch
-From:	https://github.com/KSPP/linux/issues/109
-Desc:	Address -Warray-bounds warnings 
+From:		https://github.com/KSPP/linux/issues/109
+Desc:		Address -Warray-bounds warnings 
+
+Patch:  1900_btrfs-chunk-sub_stripes-fix.patch
+From:		https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
+Desc:		btrfs: Don't use btrfs_chunk::sub_stripes from disk
 
 Patch:  2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
 From:   https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw

diff --git a/1900_btrfs-chunk-sub_stripes-fix.patch b/1900_btrfs-chunk-sub_stripes-fix.patch
new file mode 100644
index 00000000..2ffe02fe
--- /dev/null
+++ b/1900_btrfs-chunk-sub_stripes-fix.patch
@@ -0,0 +1,92 @@
+From 76a66ba101329316a5d7f4275070be22eb85fdf2 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Fri, 21 Oct 2022 08:43:45 +0800
+Subject: btrfs: don't use btrfs_chunk::sub_stripes from disk
+
+[BUG]
+There are two reports (the earliest one from LKP, a more recent one from
+kernel bugzilla) that we can have some chunks with 0 as sub_stripes.
+
+This will cause divide-by-zero errors at btrfs_rmap_block, which is
+introduced by a recent kernel patch ac0677348f3c ("btrfs: merge
+calculations for simple striped profiles in btrfs_rmap_block"):
+
+		if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
+				 BTRFS_BLOCK_GROUP_RAID10)) {
+			stripe_nr = stripe_nr * map->num_stripes + i;
+			stripe_nr = div_u64(stripe_nr, map->sub_stripes); <<<
+		}
+
+[CAUSE]
+From the more recent report, it has been proven that we have some chunks
+with 0 as sub_stripes, mostly caused by older mkfs.
+
+It turns out that the mkfs.btrfs fix is only introduced in 6718ab4d33aa
+("btrfs-progs: Initialize sub_stripes to 1 in btrfs_alloc_data_chunk")
+which is included in v5.4 btrfs-progs release.
+
+So there would be quite some old filesystems with such 0 sub_stripes.
+
+[FIX]
+Just don't trust the sub_stripes values from disk.
+
+We have a trusted btrfs_raid_array[] to fetch the correct sub_stripes
+numbers for each profile and that are fixed.
+
+By this, we can keep the compatibility with older filesystems while
+still avoid divide-by-zero bugs.
+
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Reported-by: Viktor Kuzmin <kvaster@gmail.com>
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216559
+Fixes: ac0677348f3c ("btrfs: merge calculations for simple striped profiles in btrfs_rmap_block")
+CC: stable@vger.kernel.org # 6.0
+Reviewed-by: Su Yue <glass@fydeos.io>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/volumes.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+(limited to 'fs/btrfs/volumes.c')
+
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 94ba46d579205..a8d4bc6a19379 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -7142,6 +7142,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ 	u64 devid;
+ 	u64 type;
+ 	u8 uuid[BTRFS_UUID_SIZE];
++	int index;
+ 	int num_stripes;
+ 	int ret;
+ 	int i;
+@@ -7149,6 +7150,7 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ 	logical = key->offset;
+ 	length = btrfs_chunk_length(leaf, chunk);
+ 	type = btrfs_chunk_type(leaf, chunk);
++	index = btrfs_bg_flags_to_raid_index(type);
+ 	num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
+ 
+ #if BITS_PER_LONG == 32
+@@ -7202,7 +7204,15 @@ static int read_one_chunk(struct btrfs_key *key, struct extent_buffer *leaf,
+ 	map->io_align = btrfs_chunk_io_align(leaf, chunk);
+ 	map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
+ 	map->type = type;
+-	map->sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
++	/*
++	 * We can't use the sub_stripes value, as for profiles other than
++	 * RAID10, they may have 0 as sub_stripes for filesystems created by
++	 * older mkfs (<v5.4).
++	 * In that case, it can cause divide-by-zero errors later.
++	 * Since currently sub_stripes is fixed for each profile, let's
++	 * use the trusted value instead.
++	 */
++	map->sub_stripes = btrfs_raid_array[index].sub_stripes;
+ 	map->verified_stripes = 0;
+ 	em->orig_block_len = btrfs_calc_stripe_length(em);
+ 	for (i = 0; i < num_stripes; i++) {
+-- 
+cgit 


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-10-29  9:54 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-10-29  9:54 UTC (permalink / raw
  To: gentoo-commits

commit:     09961889c2417cfb42ef549dedc4e7bbc9b7f082
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Oct 29 09:54:21 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Oct 29 09:54:21 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=09961889

Linux patch 6.0.6

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

 0000_README            |    4 +
 1005_linux-6.0.6.patch | 3748 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 3752 insertions(+)

diff --git a/0000_README b/0000_README
index 85528522..68ada3e5 100644
--- a/0000_README
+++ b/0000_README
@@ -63,6 +63,10 @@ Patch:  1004_linux-6.0.5.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.5
 
+Patch:  1005_linux-6.0.6.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.6
+
 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/1005_linux-6.0.6.patch b/1005_linux-6.0.6.patch
new file mode 100644
index 00000000..fe496b3f
--- /dev/null
+++ b/1005_linux-6.0.6.patch
@@ -0,0 +1,3748 @@
+diff --git a/Makefile b/Makefile
+index 62a7398c8d06f..e6c10009d413a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 5
++SUBLEVEL = 6
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
+index 9d3299a702423..a4dff86d39f0a 100644
+--- a/arch/arm64/kvm/vgic/vgic-its.c
++++ b/arch/arm64/kvm/vgic/vgic-its.c
+@@ -2149,7 +2149,7 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, u32 esz,
+ 
+ 	memset(entry, 0, esz);
+ 
+-	while (len > 0) {
++	while (true) {
+ 		int next_offset;
+ 		size_t byte_offset;
+ 
+@@ -2162,6 +2162,9 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, u32 esz,
+ 			return next_offset;
+ 
+ 		byte_offset = next_offset * esz;
++		if (byte_offset >= len)
++			break;
++
+ 		id += next_offset;
+ 		gpa += byte_offset;
+ 		len -= byte_offset;
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 159c025ebb03e..4728d3f5d5c40 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -1961,7 +1961,6 @@ config EFI
+ config EFI_STUB
+ 	bool "EFI stub support"
+ 	depends on EFI
+-	depends on $(cc-option,-mabi=ms) || X86_32
+ 	select RELOCATABLE
+ 	help
+ 	  This kernel feature allows a bzImage to be loaded directly
+diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
+index 0bef44d30a278..2fd52b65deac1 100644
+--- a/arch/x86/include/asm/iommu.h
++++ b/arch/x86/include/asm/iommu.h
+@@ -25,8 +25,10 @@ arch_rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr)
+ {
+ 	u64 start = rmrr->base_address;
+ 	u64 end = rmrr->end_address + 1;
++	int entry_type;
+ 
+-	if (e820__mapped_all(start, end, E820_TYPE_RESERVED))
++	entry_type = e820__get_entry_type(start, end);
++	if (entry_type == E820_TYPE_RESERVED || entry_type == E820_TYPE_NVS)
+ 		return 0;
+ 
+ 	pr_err(FW_BUG "No firmware reserved region can cover this RMRR [%#018Lx-%#018Lx], contact BIOS vendor for fixes\n",
+diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
+index 615bc6efa1dd4..72869276326bb 100644
+--- a/arch/x86/kernel/cpu/microcode/amd.c
++++ b/arch/x86/kernel/cpu/microcode/amd.c
+@@ -440,7 +440,13 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode, size_t size, bool save_p
+ 		return ret;
+ 
+ 	native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+-	if (rev >= mc->hdr.patch_id)
++
++	/*
++	 * Allow application of the same revision to pick up SMT-specific
++	 * changes even if the revision of the other SMT thread is already
++	 * up-to-date.
++	 */
++	if (rev > mc->hdr.patch_id)
+ 		return ret;
+ 
+ 	if (!__apply_microcode_amd(mc)) {
+@@ -528,8 +534,12 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
+ 
+ 	native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
+ 
+-	/* Check whether we have saved a new patch already: */
+-	if (*new_rev && rev < mc->hdr.patch_id) {
++	/*
++	 * Check whether a new patch has been saved already. Also, allow application of
++	 * the same revision in order to pick up SMT-thread-specific configuration even
++	 * if the sibling SMT thread already has an up-to-date revision.
++	 */
++	if (*new_rev && rev <= mc->hdr.patch_id) {
+ 		if (!__apply_microcode_amd(mc)) {
+ 			*new_rev = mc->hdr.patch_id;
+ 			return;
+diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
+index bb1c3f5f60c81..a5c51a14fbce8 100644
+--- a/arch/x86/kernel/cpu/resctrl/core.c
++++ b/arch/x86/kernel/cpu/resctrl/core.c
+@@ -66,9 +66,6 @@ struct rdt_hw_resource rdt_resources_all[] = {
+ 			.rid			= RDT_RESOURCE_L3,
+ 			.name			= "L3",
+ 			.cache_level		= 3,
+-			.cache = {
+-				.min_cbm_bits	= 1,
+-			},
+ 			.domains		= domain_init(RDT_RESOURCE_L3),
+ 			.parse_ctrlval		= parse_cbm,
+ 			.format_str		= "%d=%0*x",
+@@ -83,9 +80,6 @@ struct rdt_hw_resource rdt_resources_all[] = {
+ 			.rid			= RDT_RESOURCE_L2,
+ 			.name			= "L2",
+ 			.cache_level		= 2,
+-			.cache = {
+-				.min_cbm_bits	= 1,
+-			},
+ 			.domains		= domain_init(RDT_RESOURCE_L2),
+ 			.parse_ctrlval		= parse_cbm,
+ 			.format_str		= "%d=%0*x",
+@@ -877,6 +871,7 @@ static __init void rdt_init_res_defs_intel(void)
+ 			r->cache.arch_has_sparse_bitmaps = false;
+ 			r->cache.arch_has_empty_bitmaps = false;
+ 			r->cache.arch_has_per_cpu_cfg = false;
++			r->cache.min_cbm_bits = 1;
+ 		} else if (r->rid == RDT_RESOURCE_MBA) {
+ 			hw_res->msr_base = MSR_IA32_MBA_THRTL_BASE;
+ 			hw_res->msr_update = mba_wrmsr_intel;
+@@ -897,6 +892,7 @@ static __init void rdt_init_res_defs_amd(void)
+ 			r->cache.arch_has_sparse_bitmaps = true;
+ 			r->cache.arch_has_empty_bitmaps = true;
+ 			r->cache.arch_has_per_cpu_cfg = true;
++			r->cache.min_cbm_bits = 0;
+ 		} else if (r->rid == RDT_RESOURCE_MBA) {
+ 			hw_res->msr_base = MSR_IA32_MBA_BW_BASE;
+ 			hw_res->msr_update = mba_wrmsr_amd;
+diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c
+index 132a2de44d2fe..5e868b62a7c4e 100644
+--- a/arch/x86/kernel/cpu/topology.c
++++ b/arch/x86/kernel/cpu/topology.c
+@@ -96,6 +96,7 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
+ 	unsigned int ht_mask_width, core_plus_mask_width, die_plus_mask_width;
+ 	unsigned int core_select_mask, core_level_siblings;
+ 	unsigned int die_select_mask, die_level_siblings;
++	unsigned int pkg_mask_width;
+ 	bool die_level_present = false;
+ 	int leaf;
+ 
+@@ -111,10 +112,10 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
+ 	core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx);
+ 	core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
+ 	die_level_siblings = LEVEL_MAX_SIBLINGS(ebx);
+-	die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
++	pkg_mask_width = die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
+ 
+ 	sub_index = 1;
+-	do {
++	while (true) {
+ 		cpuid_count(leaf, sub_index, &eax, &ebx, &ecx, &edx);
+ 
+ 		/*
+@@ -132,10 +133,15 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
+ 			die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
+ 		}
+ 
++		if (LEAFB_SUBTYPE(ecx) != INVALID_TYPE)
++			pkg_mask_width = BITS_SHIFT_NEXT_LEVEL(eax);
++		else
++			break;
++
+ 		sub_index++;
+-	} while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE);
++	}
+ 
+-	core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width;
++	core_select_mask = (~(-1 << pkg_mask_width)) >> ht_mask_width;
+ 	die_select_mask = (~(-1 << die_plus_mask_width)) >>
+ 				core_plus_mask_width;
+ 
+@@ -148,7 +154,7 @@ int detect_extended_topology(struct cpuinfo_x86 *c)
+ 	}
+ 
+ 	c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid,
+-				die_plus_mask_width);
++				pkg_mask_width);
+ 	/*
+ 	 * Reinit the apicid, now that we have extended initial_apicid.
+ 	 */
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index e2435090f2258..86c3b29f1abc0 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -6406,26 +6406,22 @@ static int kvm_add_msr_filter(struct kvm_x86_msr_filter *msr_filter,
+ 	return 0;
+ }
+ 
+-static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp)
++static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm,
++				       struct kvm_msr_filter *filter)
+ {
+-	struct kvm_msr_filter __user *user_msr_filter = argp;
+ 	struct kvm_x86_msr_filter *new_filter, *old_filter;
+-	struct kvm_msr_filter filter;
+ 	bool default_allow;
+ 	bool empty = true;
+ 	int r = 0;
+ 	u32 i;
+ 
+-	if (copy_from_user(&filter, user_msr_filter, sizeof(filter)))
+-		return -EFAULT;
+-
+-	if (filter.flags & ~KVM_MSR_FILTER_DEFAULT_DENY)
++	if (filter->flags & ~KVM_MSR_FILTER_DEFAULT_DENY)
+ 		return -EINVAL;
+ 
+-	for (i = 0; i < ARRAY_SIZE(filter.ranges); i++)
+-		empty &= !filter.ranges[i].nmsrs;
++	for (i = 0; i < ARRAY_SIZE(filter->ranges); i++)
++		empty &= !filter->ranges[i].nmsrs;
+ 
+-	default_allow = !(filter.flags & KVM_MSR_FILTER_DEFAULT_DENY);
++	default_allow = !(filter->flags & KVM_MSR_FILTER_DEFAULT_DENY);
+ 	if (empty && !default_allow)
+ 		return -EINVAL;
+ 
+@@ -6433,8 +6429,8 @@ static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp)
+ 	if (!new_filter)
+ 		return -ENOMEM;
+ 
+-	for (i = 0; i < ARRAY_SIZE(filter.ranges); i++) {
+-		r = kvm_add_msr_filter(new_filter, &filter.ranges[i]);
++	for (i = 0; i < ARRAY_SIZE(filter->ranges); i++) {
++		r = kvm_add_msr_filter(new_filter, &filter->ranges[i]);
+ 		if (r) {
+ 			kvm_free_msr_filter(new_filter);
+ 			return r;
+@@ -6457,6 +6453,62 @@ static int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, void __user *argp)
+ 	return 0;
+ }
+ 
++#ifdef CONFIG_KVM_COMPAT
++/* for KVM_X86_SET_MSR_FILTER */
++struct kvm_msr_filter_range_compat {
++	__u32 flags;
++	__u32 nmsrs;
++	__u32 base;
++	__u32 bitmap;
++};
++
++struct kvm_msr_filter_compat {
++	__u32 flags;
++	struct kvm_msr_filter_range_compat ranges[KVM_MSR_FILTER_MAX_RANGES];
++};
++
++#define KVM_X86_SET_MSR_FILTER_COMPAT _IOW(KVMIO, 0xc6, struct kvm_msr_filter_compat)
++
++long kvm_arch_vm_compat_ioctl(struct file *filp, unsigned int ioctl,
++			      unsigned long arg)
++{
++	void __user *argp = (void __user *)arg;
++	struct kvm *kvm = filp->private_data;
++	long r = -ENOTTY;
++
++	switch (ioctl) {
++	case KVM_X86_SET_MSR_FILTER_COMPAT: {
++		struct kvm_msr_filter __user *user_msr_filter = argp;
++		struct kvm_msr_filter_compat filter_compat;
++		struct kvm_msr_filter filter;
++		int i;
++
++		if (copy_from_user(&filter_compat, user_msr_filter,
++				   sizeof(filter_compat)))
++			return -EFAULT;
++
++		filter.flags = filter_compat.flags;
++		for (i = 0; i < ARRAY_SIZE(filter.ranges); i++) {
++			struct kvm_msr_filter_range_compat *cr;
++
++			cr = &filter_compat.ranges[i];
++			filter.ranges[i] = (struct kvm_msr_filter_range) {
++				.flags = cr->flags,
++				.nmsrs = cr->nmsrs,
++				.base = cr->base,
++				.bitmap = (__u8 *)(ulong)cr->bitmap,
++			};
++		}
++
++		r = kvm_vm_ioctl_set_msr_filter(kvm, &filter);
++		break;
++	}
++	}
++
++	return r;
++}
++#endif
++
+ #ifdef CONFIG_HAVE_KVM_PM_NOTIFIER
+ static int kvm_arch_suspend_notifier(struct kvm *kvm)
+ {
+@@ -6879,9 +6931,16 @@ set_pit2_out:
+ 	case KVM_SET_PMU_EVENT_FILTER:
+ 		r = kvm_vm_ioctl_set_pmu_event_filter(kvm, argp);
+ 		break;
+-	case KVM_X86_SET_MSR_FILTER:
+-		r = kvm_vm_ioctl_set_msr_filter(kvm, argp);
++	case KVM_X86_SET_MSR_FILTER: {
++		struct kvm_msr_filter __user *user_msr_filter = argp;
++		struct kvm_msr_filter filter;
++
++		if (copy_from_user(&filter, user_msr_filter, sizeof(filter)))
++			return -EFAULT;
++
++		r = kvm_vm_ioctl_set_msr_filter(kvm, &filter);
+ 		break;
++	}
+ 	default:
+ 		r = -ENOTTY;
+ 	}
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 887b8682eb690..fe840536e6ac4 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -3028,8 +3028,11 @@ static void blk_mq_clear_rq_mapping(struct blk_mq_tags *drv_tags,
+ 	struct page *page;
+ 	unsigned long flags;
+ 
+-	/* There is no need to clear a driver tags own mapping */
+-	if (drv_tags == tags)
++	/*
++	 * There is no need to clear mapping if driver tags is not initialized
++	 * or the mapping belongs to the driver tags.
++	 */
++	if (!drv_tags || drv_tags == tags)
+ 		return;
+ 
+ 	list_for_each_entry(page, &tags->page_list, lru) {
+diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
+index 72f1fb77abcd0..e648158368a7d 100644
+--- a/drivers/acpi/acpi_extlog.c
++++ b/drivers/acpi/acpi_extlog.c
+@@ -12,6 +12,7 @@
+ #include <linux/ratelimit.h>
+ #include <linux/edac.h>
+ #include <linux/ras.h>
++#include <acpi/ghes.h>
+ #include <asm/cpu.h>
+ #include <asm/mce.h>
+ 
+@@ -138,8 +139,8 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
+ 	int	cpu = mce->extcpu;
+ 	struct acpi_hest_generic_status *estatus, *tmp;
+ 	struct acpi_hest_generic_data *gdata;
+-	const guid_t *fru_id = &guid_null;
+-	char *fru_text = "";
++	const guid_t *fru_id;
++	char *fru_text;
+ 	guid_t *sec_type;
+ 	static u32 err_seq;
+ 
+@@ -160,17 +161,23 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
+ 
+ 	/* log event via trace */
+ 	err_seq++;
+-	gdata = (struct acpi_hest_generic_data *)(tmp + 1);
+-	if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
+-		fru_id = (guid_t *)gdata->fru_id;
+-	if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
+-		fru_text = gdata->fru_text;
+-	sec_type = (guid_t *)gdata->section_type;
+-	if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
+-		struct cper_sec_mem_err *mem = (void *)(gdata + 1);
+-		if (gdata->error_data_length >= sizeof(*mem))
+-			trace_extlog_mem_event(mem, err_seq, fru_id, fru_text,
+-					       (u8)gdata->error_severity);
++	apei_estatus_for_each_section(tmp, gdata) {
++		if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
++			fru_id = (guid_t *)gdata->fru_id;
++		else
++			fru_id = &guid_null;
++		if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
++			fru_text = gdata->fru_text;
++		else
++			fru_text = "";
++		sec_type = (guid_t *)gdata->section_type;
++		if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
++			struct cper_sec_mem_err *mem = (void *)(gdata + 1);
++
++			if (gdata->error_data_length >= sizeof(*mem))
++				trace_extlog_mem_event(mem, err_seq, fru_id, fru_text,
++						       (u8)gdata->error_severity);
++		}
+ 	}
+ 
+ out:
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
+index 5d7f38016a243..68a566f696845 100644
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -514,6 +514,70 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
+ 		DMI_MATCH(DMI_BOARD_NAME, "PF5LUXG"),
+ 		},
+ 	},
++	/*
++	 * More Tongfang devices with the same issue as the Clevo NL5xRU and
++	 * NL5xNU/TUXEDO Aura 15 Gen1 and Gen2. See the description above.
++	 */
++	{
++	.callback = video_detect_force_native,
++	.ident = "TongFang GKxNRxx",
++	.matches = {
++		DMI_MATCH(DMI_BOARD_NAME, "GKxNRxx"),
++		},
++	},
++	{
++	.callback = video_detect_force_native,
++	.ident = "TongFang GKxNRxx",
++	.matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
++		DMI_MATCH(DMI_BOARD_NAME, "POLARIS1501A1650TI"),
++		},
++	},
++	{
++	.callback = video_detect_force_native,
++	.ident = "TongFang GKxNRxx",
++	.matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
++		DMI_MATCH(DMI_BOARD_NAME, "POLARIS1501A2060"),
++		},
++	},
++	{
++	.callback = video_detect_force_native,
++	.ident = "TongFang GKxNRxx",
++	.matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
++		DMI_MATCH(DMI_BOARD_NAME, "POLARIS1701A1650TI"),
++		},
++	},
++	{
++	.callback = video_detect_force_native,
++	.ident = "TongFang GKxNRxx",
++	.matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
++		DMI_MATCH(DMI_BOARD_NAME, "POLARIS1701A2060"),
++		},
++	},
++	{
++	.callback = video_detect_force_native,
++	.ident = "TongFang GMxNGxx",
++	.matches = {
++		DMI_MATCH(DMI_BOARD_NAME, "GMxNGxx"),
++		},
++	},
++	{
++	.callback = video_detect_force_native,
++	.ident = "TongFang GMxZGxx",
++	.matches = {
++		DMI_MATCH(DMI_BOARD_NAME, "GMxZGxx"),
++		},
++	},
++	{
++	.callback = video_detect_force_native,
++	.ident = "TongFang GMxRGxx",
++	.matches = {
++		DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
++		},
++	},
+ 	/*
+ 	 * Desktops which falsely report a backlight and which our heuristics
+ 	 * for this do not catch.
+diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
+index ad11a4c52fbeb..6f3286c8506d3 100644
+--- a/drivers/ata/ahci.h
++++ b/drivers/ata/ahci.h
+@@ -252,7 +252,7 @@ enum {
+ 	PCS_7				= 0x94, /* 7+ port PCS (Denverton) */
+ 
+ 	/* em constants */
+-	EM_MAX_SLOTS			= 8,
++	EM_MAX_SLOTS			= SATA_PMP_MAX_PORTS,
+ 	EM_MAX_RETRY			= 5,
+ 
+ 	/* em_ctl bits */
+diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
+index 79aa9f2853129..20382f3962f50 100644
+--- a/drivers/ata/ahci_imx.c
++++ b/drivers/ata/ahci_imx.c
+@@ -1230,4 +1230,4 @@ module_platform_driver(imx_ahci_driver);
+ MODULE_DESCRIPTION("Freescale i.MX AHCI SATA platform driver");
+ MODULE_AUTHOR("Richard Zhu <Hong-Xing.Zhu@freescale.com>");
+ MODULE_LICENSE("GPL");
+-MODULE_ALIAS("ahci:imx");
++MODULE_ALIAS("platform:" DRV_NAME);
+diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
+index 8f7f144e54f3a..7f9bcc82fc9c4 100644
+--- a/drivers/block/drbd/drbd_req.c
++++ b/drivers/block/drbd/drbd_req.c
+@@ -30,11 +30,6 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device, struct bio
+ 		return NULL;
+ 	memset(req, 0, sizeof(*req));
+ 
+-	req->private_bio = bio_alloc_clone(device->ldev->backing_bdev, bio_src,
+-					   GFP_NOIO, &drbd_io_bio_set);
+-	req->private_bio->bi_private = req;
+-	req->private_bio->bi_end_io = drbd_request_endio;
+-
+ 	req->rq_state = (bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0)
+ 		      | (bio_op(bio_src) == REQ_OP_WRITE_ZEROES ? RQ_ZEROES : 0)
+ 		      | (bio_op(bio_src) == REQ_OP_DISCARD ? RQ_UNMAP : 0);
+@@ -1219,9 +1214,12 @@ drbd_request_prepare(struct drbd_device *device, struct bio *bio)
+ 	/* Update disk stats */
+ 	req->start_jif = bio_start_io_acct(req->master_bio);
+ 
+-	if (!get_ldev(device)) {
+-		bio_put(req->private_bio);
+-		req->private_bio = NULL;
++	if (get_ldev(device)) {
++		req->private_bio = bio_alloc_clone(device->ldev->backing_bdev,
++						   bio, GFP_NOIO,
++						   &drbd_io_bio_set);
++		req->private_bio->bi_private = req;
++		req->private_bio->bi_end_io = drbd_request_endio;
+ 	}
+ 
+ 	/* process discards always from our submitter thread */
+diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c
+index 863548f59c3e5..82e0339d7722b 100644
+--- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
++++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
+@@ -213,6 +213,7 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev,
+ 	int speed = 0, pvs = 0, pvs_ver = 0;
+ 	u8 *speedbin;
+ 	size_t len;
++	int ret = 0;
+ 
+ 	speedbin = nvmem_cell_read(speedbin_nvmem, &len);
+ 
+@@ -230,7 +231,8 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev,
+ 		break;
+ 	default:
+ 		dev_err(cpu_dev, "Unable to read nvmem data. Defaulting to 0!\n");
+-		return -ENODEV;
++		ret = -ENODEV;
++		goto len_error;
+ 	}
+ 
+ 	snprintf(*pvs_name, sizeof("speedXX-pvsXX-vXX"), "speed%d-pvs%d-v%d",
+@@ -238,8 +240,9 @@ static int qcom_cpufreq_krait_name_version(struct device *cpu_dev,
+ 
+ 	drv->versions = (1 << speed);
+ 
++len_error:
+ 	kfree(speedbin);
+-	return 0;
++	return ret;
+ }
+ 
+ static const struct qcom_cpufreq_match_data match_data_kryo = {
+@@ -262,7 +265,8 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
+ 	struct nvmem_cell *speedbin_nvmem;
+ 	struct device_node *np;
+ 	struct device *cpu_dev;
+-	char *pvs_name = "speedXX-pvsXX-vXX";
++	char pvs_name_buffer[] = "speedXX-pvsXX-vXX";
++	char *pvs_name = pvs_name_buffer;
+ 	unsigned cpu;
+ 	const struct of_device_id *match;
+ 	int ret;
+diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c
+index 1216046cf4c2e..0ea7631d9c27e 100644
+--- a/drivers/cpufreq/tegra194-cpufreq.c
++++ b/drivers/cpufreq/tegra194-cpufreq.c
+@@ -592,6 +592,7 @@ static const struct of_device_id tegra194_cpufreq_of_match[] = {
+ 	{ .compatible = "nvidia,tegra234-ccplex-cluster", .data = &tegra234_cpufreq_soc },
+ 	{ /* sentinel */ }
+ };
++MODULE_DEVICE_TABLE(of, tegra194_cpufreq_of_match);
+ 
+ static struct platform_driver tegra194_ccplex_driver = {
+ 	.driver = {
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+index 56424f75dd2cc..65181efba50ec 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+@@ -1504,11 +1504,6 @@ static int sdma_v4_0_start(struct amdgpu_device *adev)
+ 		WREG32_SDMA(i, mmSDMA0_CNTL, temp);
+ 
+ 		if (!amdgpu_sriov_vf(adev)) {
+-			ring = &adev->sdma.instance[i].ring;
+-			adev->nbio.funcs->sdma_doorbell_range(adev, i,
+-				ring->use_doorbell, ring->doorbell_index,
+-				adev->doorbell_index.sdma_doorbell_range);
+-
+ 			/* unhalt engine */
+ 			temp = RREG32_SDMA(i, mmSDMA0_F32_CNTL);
+ 			temp = REG_SET_FIELD(temp, SDMA0_F32_CNTL, HALT, 0);
+diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
+index 183024d7c184e..e3b2b6b4f1a66 100644
+--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
+@@ -1211,6 +1211,20 @@ static int soc15_common_sw_fini(void *handle)
+ 	return 0;
+ }
+ 
++static void soc15_sdma_doorbell_range_init(struct amdgpu_device *adev)
++{
++	int i;
++
++	/* sdma doorbell range is programed by hypervisor */
++	if (!amdgpu_sriov_vf(adev)) {
++		for (i = 0; i < adev->sdma.num_instances; i++) {
++			adev->nbio.funcs->sdma_doorbell_range(adev, i,
++				true, adev->doorbell_index.sdma_engine[i] << 1,
++				adev->doorbell_index.sdma_doorbell_range);
++		}
++	}
++}
++
+ static int soc15_common_hw_init(void *handle)
+ {
+ 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+@@ -1230,6 +1244,13 @@ static int soc15_common_hw_init(void *handle)
+ 
+ 	/* enable the doorbell aperture */
+ 	soc15_enable_doorbell_aperture(adev, true);
++	/* HW doorbell routing policy: doorbell writing not
++	 * in SDMA/IH/MM/ACV range will be routed to CP. So
++	 * we need to init SDMA doorbell range prior
++	 * to CP ip block init and ring test.  IH already
++	 * happens before CP.
++	 */
++	soc15_sdma_doorbell_range_init(adev);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/Makefile b/drivers/gpu/drm/amd/display/dc/dml/Makefile
+index cb81ed2fbd539..d0c6cf61c676a 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile
++++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile
+@@ -77,7 +77,7 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn30/dcn30_fpu.o := $(dml_ccflags)
+ CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/dcn32_fpu.o := $(dml_ccflags)
+ CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_mode_vba_32.o := $(dml_ccflags) $(frame_warn_flag)
+ CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_rq_dlg_calc_32.o := $(dml_ccflags)
+-CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_mode_vba_util_32.o := $(dml_ccflags)
++CFLAGS_$(AMDDALPATH)/dc/dml/dcn32/display_mode_vba_util_32.o := $(dml_ccflags) $(frame_warn_flag)
+ CFLAGS_$(AMDDALPATH)/dc/dml/dcn321/dcn321_fpu.o := $(dml_ccflags)
+ CFLAGS_$(AMDDALPATH)/dc/dml/dcn31/dcn31_fpu.o := $(dml_ccflags)
+ CFLAGS_$(AMDDALPATH)/dc/dml/dcn301/dcn301_fpu.o := $(dml_ccflags)
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
+index 6b8dfa1e7650d..c186ace7f83b9 100644
+--- a/drivers/gpu/drm/vc4/vc4_drv.c
++++ b/drivers/gpu/drm/vc4/vc4_drv.c
+@@ -490,6 +490,7 @@ module_init(vc4_drm_register);
+ module_exit(vc4_drm_unregister);
+ 
+ MODULE_ALIAS("platform:vc4-drm");
++MODULE_SOFTDEP("pre: snd-soc-hdmi-codec");
+ MODULE_DESCRIPTION("Broadcom VC4 DRM Driver");
+ MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
+ MODULE_LICENSE("GPL v2");
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
+index 1e5f68704d7d8..780a19a75c3f5 100644
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -2871,6 +2871,15 @@ static int vc4_hdmi_runtime_resume(struct device *dev)
+ 	u32 __maybe_unused value;
+ 	int ret;
+ 
++	/*
++	 * The HSM clock is in the HDMI power domain, so we need to set
++	 * its frequency while the power domain is active so that it
++	 * keeps its rate.
++	 */
++	ret = clk_set_min_rate(vc4_hdmi->hsm_clock, HSM_MIN_CLOCK_FREQ);
++	if (ret)
++		return ret;
++
+ 	ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
+ 	if (ret)
+ 		return ret;
+diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
+index 664a624a363d0..c9c968d4b36a3 100644
+--- a/drivers/hid/hid-magicmouse.c
++++ b/drivers/hid/hid-magicmouse.c
+@@ -480,7 +480,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
+ 		magicmouse_raw_event(hdev, report, data + 2, data[1]);
+ 		magicmouse_raw_event(hdev, report, data + 2 + data[1],
+ 			size - 2 - data[1]);
+-		break;
++		return 0;
+ 	default:
+ 		return 0;
+ 	}
+diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
+index ccf0af5b988a7..8bf32c6c85d95 100644
+--- a/drivers/hwmon/coretemp.c
++++ b/drivers/hwmon/coretemp.c
+@@ -46,9 +46,6 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
+ #define TOTAL_ATTRS		(MAX_CORE_ATTRS + 1)
+ #define MAX_CORE_DATA		(NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
+ 
+-#define TO_CORE_ID(cpu)		(cpu_data(cpu).cpu_core_id)
+-#define TO_ATTR_NO(cpu)		(TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
+-
+ #ifdef CONFIG_SMP
+ #define for_each_sibling(i, cpu) \
+ 	for_each_cpu(i, topology_sibling_cpumask(cpu))
+@@ -91,6 +88,8 @@ struct temp_data {
+ struct platform_data {
+ 	struct device		*hwmon_dev;
+ 	u16			pkg_id;
++	u16			cpu_map[NUM_REAL_CORES];
++	struct ida		ida;
+ 	struct cpumask		cpumask;
+ 	struct temp_data	*core_data[MAX_CORE_DATA];
+ 	struct device_attribute name_attr;
+@@ -441,7 +440,7 @@ static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag)
+ 							MSR_IA32_THERM_STATUS;
+ 	tdata->is_pkg_data = pkg_flag;
+ 	tdata->cpu = cpu;
+-	tdata->cpu_core_id = TO_CORE_ID(cpu);
++	tdata->cpu_core_id = topology_core_id(cpu);
+ 	tdata->attr_size = MAX_CORE_ATTRS;
+ 	mutex_init(&tdata->update_lock);
+ 	return tdata;
+@@ -454,7 +453,7 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu,
+ 	struct platform_data *pdata = platform_get_drvdata(pdev);
+ 	struct cpuinfo_x86 *c = &cpu_data(cpu);
+ 	u32 eax, edx;
+-	int err, attr_no;
++	int err, index, attr_no;
+ 
+ 	/*
+ 	 * Find attr number for sysfs:
+@@ -462,14 +461,26 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu,
+ 	 * The attr number is always core id + 2
+ 	 * The Pkgtemp will always show up as temp1_*, if available
+ 	 */
+-	attr_no = pkg_flag ? PKG_SYSFS_ATTR_NO : TO_ATTR_NO(cpu);
++	if (pkg_flag) {
++		attr_no = PKG_SYSFS_ATTR_NO;
++	} else {
++		index = ida_alloc(&pdata->ida, GFP_KERNEL);
++		if (index < 0)
++			return index;
++		pdata->cpu_map[index] = topology_core_id(cpu);
++		attr_no = index + BASE_SYSFS_ATTR_NO;
++	}
+ 
+-	if (attr_no > MAX_CORE_DATA - 1)
+-		return -ERANGE;
++	if (attr_no > MAX_CORE_DATA - 1) {
++		err = -ERANGE;
++		goto ida_free;
++	}
+ 
+ 	tdata = init_temp_data(cpu, pkg_flag);
+-	if (!tdata)
+-		return -ENOMEM;
++	if (!tdata) {
++		err = -ENOMEM;
++		goto ida_free;
++	}
+ 
+ 	/* Test if we can access the status register */
+ 	err = rdmsr_safe_on_cpu(cpu, tdata->status_reg, &eax, &edx);
+@@ -505,6 +516,9 @@ static int create_core_data(struct platform_device *pdev, unsigned int cpu,
+ exit_free:
+ 	pdata->core_data[attr_no] = NULL;
+ 	kfree(tdata);
++ida_free:
++	if (!pkg_flag)
++		ida_free(&pdata->ida, index);
+ 	return err;
+ }
+ 
+@@ -524,6 +538,9 @@ static void coretemp_remove_core(struct platform_data *pdata, int indx)
+ 
+ 	kfree(pdata->core_data[indx]);
+ 	pdata->core_data[indx] = NULL;
++
++	if (indx >= BASE_SYSFS_ATTR_NO)
++		ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO);
+ }
+ 
+ static int coretemp_probe(struct platform_device *pdev)
+@@ -537,6 +554,7 @@ static int coretemp_probe(struct platform_device *pdev)
+ 		return -ENOMEM;
+ 
+ 	pdata->pkg_id = pdev->id;
++	ida_init(&pdata->ida);
+ 	platform_set_drvdata(pdev, pdata);
+ 
+ 	pdata->hwmon_dev = devm_hwmon_device_register_with_groups(dev, DRVNAME,
+@@ -553,6 +571,7 @@ static int coretemp_remove(struct platform_device *pdev)
+ 		if (pdata->core_data[i])
+ 			coretemp_remove_core(pdata, i);
+ 
++	ida_destroy(&pdata->ida);
+ 	return 0;
+ }
+ 
+@@ -647,7 +666,7 @@ static int coretemp_cpu_offline(unsigned int cpu)
+ 	struct platform_device *pdev = coretemp_get_pdev(cpu);
+ 	struct platform_data *pd;
+ 	struct temp_data *tdata;
+-	int indx, target;
++	int i, indx = -1, target;
+ 
+ 	/*
+ 	 * Don't execute this on suspend as the device remove locks
+@@ -660,12 +679,19 @@ static int coretemp_cpu_offline(unsigned int cpu)
+ 	if (!pdev)
+ 		return 0;
+ 
+-	/* The core id is too big, just return */
+-	indx = TO_ATTR_NO(cpu);
+-	if (indx > MAX_CORE_DATA - 1)
++	pd = platform_get_drvdata(pdev);
++
++	for (i = 0; i < NUM_REAL_CORES; i++) {
++		if (pd->cpu_map[i] == topology_core_id(cpu)) {
++			indx = i + BASE_SYSFS_ATTR_NO;
++			break;
++		}
++	}
++
++	/* Too many cores and this core is not populated, just return */
++	if (indx < 0)
+ 		return 0;
+ 
+-	pd = platform_get_drvdata(pdev);
+ 	tdata = pd->core_data[indx];
+ 
+ 	cpumask_clear_cpu(cpu, &pd->cpumask);
+diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c
+index ea48e6a9cfca7..1cf89f885d61e 100644
+--- a/drivers/i2c/busses/i2c-qcom-cci.c
++++ b/drivers/i2c/busses/i2c-qcom-cci.c
+@@ -639,6 +639,11 @@ static int cci_probe(struct platform_device *pdev)
+ 	if (ret < 0)
+ 		goto error;
+ 
++	pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
++	pm_runtime_use_autosuspend(dev);
++	pm_runtime_set_active(dev);
++	pm_runtime_enable(dev);
++
+ 	for (i = 0; i < cci->data->num_masters; i++) {
+ 		if (!cci->master[i].cci)
+ 			continue;
+@@ -650,14 +655,12 @@ static int cci_probe(struct platform_device *pdev)
+ 		}
+ 	}
+ 
+-	pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
+-	pm_runtime_use_autosuspend(dev);
+-	pm_runtime_set_active(dev);
+-	pm_runtime_enable(dev);
+-
+ 	return 0;
+ 
+ error_i2c:
++	pm_runtime_disable(dev);
++	pm_runtime_dont_use_autosuspend(dev);
++
+ 	for (--i ; i >= 0; i--) {
+ 		if (cci->master[i].cci) {
+ 			i2c_del_adapter(&cci->master[i].adap);
+diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
+index 31bc50e538a34..ecc0b05b2796c 100644
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -2400,6 +2400,7 @@ static int __init si_domain_init(int hw)
+ 
+ 	if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
+ 		domain_exit(si_domain);
++		si_domain = NULL;
+ 		return -EFAULT;
+ 	}
+ 
+@@ -3042,6 +3043,10 @@ free_iommu:
+ 		disable_dmar_iommu(iommu);
+ 		free_dmar_iommu(iommu);
+ 	}
++	if (si_domain) {
++		domain_exit(si_domain);
++		si_domain = NULL;
++	}
+ 
+ 	return ret;
+ }
+diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
+index 09c7ed2650ca4..9c5ef818ca365 100644
+--- a/drivers/md/dm-bufio.c
++++ b/drivers/md/dm-bufio.c
+@@ -795,7 +795,8 @@ static void __make_buffer_clean(struct dm_buffer *b)
+ {
+ 	BUG_ON(b->hold_count);
+ 
+-	if (!b->state)	/* fast case */
++	/* smp_load_acquire() pairs with read_endio()'s smp_mb__before_atomic() */
++	if (!smp_load_acquire(&b->state))	/* fast case */
+ 		return;
+ 
+ 	wait_on_bit_io(&b->state, B_READING, TASK_UNINTERRUPTIBLE);
+@@ -816,7 +817,7 @@ static struct dm_buffer *__get_unclaimed_buffer(struct dm_bufio_client *c)
+ 		BUG_ON(test_bit(B_DIRTY, &b->state));
+ 
+ 		if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep &&
+-		    unlikely(test_bit(B_READING, &b->state)))
++		    unlikely(test_bit_acquire(B_READING, &b->state)))
+ 			continue;
+ 
+ 		if (!b->hold_count) {
+@@ -1058,7 +1059,7 @@ found_buffer:
+ 	 * If the user called both dm_bufio_prefetch and dm_bufio_get on
+ 	 * the same buffer, it would deadlock if we waited.
+ 	 */
+-	if (nf == NF_GET && unlikely(test_bit(B_READING, &b->state)))
++	if (nf == NF_GET && unlikely(test_bit_acquire(B_READING, &b->state)))
+ 		return NULL;
+ 
+ 	b->hold_count++;
+@@ -1218,7 +1219,7 @@ void dm_bufio_release(struct dm_buffer *b)
+ 		 * invalid buffer.
+ 		 */
+ 		if ((b->read_error || b->write_error) &&
+-		    !test_bit(B_READING, &b->state) &&
++		    !test_bit_acquire(B_READING, &b->state) &&
+ 		    !test_bit(B_WRITING, &b->state) &&
+ 		    !test_bit(B_DIRTY, &b->state)) {
+ 			__unlink_buffer(b);
+@@ -1479,7 +1480,7 @@ EXPORT_SYMBOL_GPL(dm_bufio_release_move);
+ 
+ static void forget_buffer_locked(struct dm_buffer *b)
+ {
+-	if (likely(!b->hold_count) && likely(!b->state)) {
++	if (likely(!b->hold_count) && likely(!smp_load_acquire(&b->state))) {
+ 		__unlink_buffer(b);
+ 		__free_buffer_wake(b);
+ 	}
+@@ -1639,7 +1640,7 @@ static bool __try_evict_buffer(struct dm_buffer *b, gfp_t gfp)
+ {
+ 	if (!(gfp & __GFP_FS) ||
+ 	    (static_branch_unlikely(&no_sleep_enabled) && b->c->no_sleep)) {
+-		if (test_bit(B_READING, &b->state) ||
++		if (test_bit_acquire(B_READING, &b->state) ||
+ 		    test_bit(B_WRITING, &b->state) ||
+ 		    test_bit(B_DIRTY, &b->state))
+ 			return false;
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 60549b65c799c..b4a2cb5333fcc 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2065,7 +2065,6 @@ static struct mapped_device *alloc_dev(int minor)
+ 	md->disk->minors = 1;
+ 	md->disk->flags |= GENHD_FL_NO_PART;
+ 	md->disk->fops = &dm_blk_dops;
+-	md->disk->queue = md->queue;
+ 	md->disk->private_data = md;
+ 	sprintf(md->disk->disk_name, "dm-%d", minor);
+ 
+diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c
+index 60de4200375dd..ab6a29ffc81e2 100644
+--- a/drivers/media/platform/qcom/venus/helpers.c
++++ b/drivers/media/platform/qcom/venus/helpers.c
+@@ -1800,7 +1800,7 @@ bool venus_helper_check_format(struct venus_inst *inst, u32 v4l2_pixfmt)
+ 	struct venus_core *core = inst->core;
+ 	u32 fmt = to_hfi_raw_fmt(v4l2_pixfmt);
+ 	struct hfi_plat_caps *caps;
+-	u32 buftype;
++	bool found;
+ 
+ 	if (!fmt)
+ 		return false;
+@@ -1809,12 +1809,13 @@ bool venus_helper_check_format(struct venus_inst *inst, u32 v4l2_pixfmt)
+ 	if (!caps)
+ 		return false;
+ 
+-	if (inst->session_type == VIDC_SESSION_TYPE_DEC)
+-		buftype = HFI_BUFFER_OUTPUT2;
+-	else
+-		buftype = HFI_BUFFER_OUTPUT;
++	found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT, fmt);
++	if (found)
++		goto done;
+ 
+-	return find_fmt_from_caps(caps, buftype, fmt);
++	found = find_fmt_from_caps(caps, HFI_BUFFER_OUTPUT2, fmt);
++done:
++	return found;
+ }
+ EXPORT_SYMBOL_GPL(venus_helper_check_format);
+ 
+diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
+index ac0bb45d07f4b..4ceaba37e2e57 100644
+--- a/drivers/media/platform/qcom/venus/vdec.c
++++ b/drivers/media/platform/qcom/venus/vdec.c
+@@ -183,6 +183,8 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)
+ 		else
+ 			return NULL;
+ 		fmt = find_format(inst, pixmp->pixelformat, f->type);
++		if (!fmt)
++			return NULL;
+ 	}
+ 
+ 	pixmp->width = clamp(pixmp->width, frame_width_min(inst),
+diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
+index 39d2b03e26317..c76ba24c1f559 100644
+--- a/drivers/media/rc/mceusb.c
++++ b/drivers/media/rc/mceusb.c
+@@ -1077,7 +1077,7 @@ static int mceusb_set_timeout(struct rc_dev *dev, unsigned int timeout)
+ 	struct mceusb_dev *ir = dev->priv;
+ 	unsigned int units;
+ 
+-	units = DIV_ROUND_CLOSEST(timeout, MCE_TIME_UNIT);
++	units = DIV_ROUND_UP(timeout, MCE_TIME_UNIT);
+ 
+ 	cmdbuf[2] = units >> 8;
+ 	cmdbuf[3] = units;
+diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
+index c181346388a41..300c9345ee2be 100644
+--- a/drivers/net/dsa/qca/qca8k-8xxx.c
++++ b/drivers/net/dsa/qca/qca8k-8xxx.c
+@@ -137,27 +137,42 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
+ 	struct qca8k_mgmt_eth_data *mgmt_eth_data;
+ 	struct qca8k_priv *priv = ds->priv;
+ 	struct qca_mgmt_ethhdr *mgmt_ethhdr;
++	u32 command;
+ 	u8 len, cmd;
++	int i;
+ 
+ 	mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb);
+ 	mgmt_eth_data = &priv->mgmt_eth_data;
+ 
+-	cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command);
+-	len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command);
++	command = get_unaligned_le32(&mgmt_ethhdr->command);
++	cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command);
++	len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command);
+ 
+ 	/* Make sure the seq match the requested packet */
+-	if (mgmt_ethhdr->seq == mgmt_eth_data->seq)
++	if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq)
+ 		mgmt_eth_data->ack = true;
+ 
+ 	if (cmd == MDIO_READ) {
+-		mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data;
++		u32 *val = mgmt_eth_data->data;
++
++		*val = get_unaligned_le32(&mgmt_ethhdr->mdio_data);
+ 
+ 		/* Get the rest of the 12 byte of data.
+ 		 * The read/write function will extract the requested data.
+ 		 */
+-		if (len > QCA_HDR_MGMT_DATA1_LEN)
+-			memcpy(mgmt_eth_data->data + 1, skb->data,
+-			       QCA_HDR_MGMT_DATA2_LEN);
++		if (len > QCA_HDR_MGMT_DATA1_LEN) {
++			__le32 *data2 = (__le32 *)skb->data;
++			int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN,
++					     len - QCA_HDR_MGMT_DATA1_LEN);
++
++			val++;
++
++			for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) {
++				*val = get_unaligned_le32(data2);
++				val++;
++				data2++;
++			}
++		}
+ 	}
+ 
+ 	complete(&mgmt_eth_data->rw_done);
+@@ -169,8 +184,10 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
+ 	struct qca_mgmt_ethhdr *mgmt_ethhdr;
+ 	unsigned int real_len;
+ 	struct sk_buff *skb;
+-	u32 *data2;
++	__le32 *data2;
++	u32 command;
+ 	u16 hdr;
++	int i;
+ 
+ 	skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN);
+ 	if (!skb)
+@@ -199,20 +216,32 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
+ 	hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0));
+ 	hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG);
+ 
+-	mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
+-	mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
+-	mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
+-	mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
++	command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
++	command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
++	command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
++	command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
+ 					   QCA_HDR_MGMT_CHECK_CODE_VAL);
+ 
++	put_unaligned_le32(command, &mgmt_ethhdr->command);
++
+ 	if (cmd == MDIO_WRITE)
+-		mgmt_ethhdr->mdio_data = *val;
++		put_unaligned_le32(*val, &mgmt_ethhdr->mdio_data);
+ 
+ 	mgmt_ethhdr->hdr = htons(hdr);
+ 
+ 	data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN);
+-	if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN)
+-		memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN);
++	if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) {
++		int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN,
++				     len - QCA_HDR_MGMT_DATA1_LEN);
++
++		val++;
++
++		for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) {
++			put_unaligned_le32(*val, data2);
++			data2++;
++			val++;
++		}
++	}
+ 
+ 	return skb;
+ }
+@@ -220,9 +249,11 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
+ static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num)
+ {
+ 	struct qca_mgmt_ethhdr *mgmt_ethhdr;
++	u32 seq;
+ 
++	seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
+ 	mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data;
+-	mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
++	put_unaligned_le32(seq, &mgmt_ethhdr->seq);
+ }
+ 
+ static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
+@@ -1487,9 +1518,9 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk
+ 	struct qca8k_priv *priv = ds->priv;
+ 	const struct qca8k_mib_desc *mib;
+ 	struct mib_ethhdr *mib_ethhdr;
+-	int i, mib_len, offset = 0;
+-	u64 *data;
++	__le32 *data2;
+ 	u8 port;
++	int i;
+ 
+ 	mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb);
+ 	mib_eth_data = &priv->mib_eth_data;
+@@ -1501,28 +1532,24 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk
+ 	if (port != mib_eth_data->req_port)
+ 		goto exit;
+ 
+-	data = mib_eth_data->data;
++	data2 = (__le32 *)skb->data;
+ 
+ 	for (i = 0; i < priv->info->mib_count; i++) {
+ 		mib = &ar8327_mib[i];
+ 
+ 		/* First 3 mib are present in the skb head */
+ 		if (i < 3) {
+-			data[i] = mib_ethhdr->data[i];
++			mib_eth_data->data[i] = get_unaligned_le32(mib_ethhdr->data + i);
+ 			continue;
+ 		}
+ 
+-		mib_len = sizeof(uint32_t);
+-
+ 		/* Some mib are 64 bit wide */
+ 		if (mib->size == 2)
+-			mib_len = sizeof(uint64_t);
+-
+-		/* Copy the mib value from packet to the */
+-		memcpy(data + i, skb->data + offset, mib_len);
++			mib_eth_data->data[i] = get_unaligned_le64((__le64 *)data2);
++		else
++			mib_eth_data->data[i] = get_unaligned_le32(data2);
+ 
+-		/* Set the offset for the next mib */
+-		offset += mib_len;
++		data2 += mib->size;
+ 	}
+ 
+ exit:
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+index a36803e79e92e..8a6f788f62944 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+@@ -613,6 +613,7 @@ static int bnxt_dl_reload_up(struct devlink *dl, enum devlink_reload_action acti
+ 
+ static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack)
+ {
++	bool rc = false;
+ 	u32 datalen;
+ 	u16 index;
+ 	u8 *buf;
+@@ -632,20 +633,20 @@ static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack)
+ 
+ 	if (bnxt_get_nvram_item(bp->dev, index, 0, datalen, buf)) {
+ 		NL_SET_ERR_MSG_MOD(extack, "nvm test vpd read error");
+-		goto err;
++		goto done;
+ 	}
+ 
+ 	if (bnxt_flash_nvram(bp->dev, BNX_DIR_TYPE_VPD, BNX_DIR_ORDINAL_FIRST,
+ 			     BNX_DIR_EXT_NONE, 0, 0, buf, datalen)) {
+ 		NL_SET_ERR_MSG_MOD(extack, "nvm test vpd write error");
+-		goto err;
++		goto done;
+ 	}
+ 
+-	return true;
++	rc = true;
+ 
+-err:
++done:
+ 	kfree(buf);
+-	return false;
++	return rc;
+ }
+ 
+ static bool bnxt_dl_selftest_check(struct devlink *dl, unsigned int id,
+diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c
+index 00fafc0f85121..430eccea8e5e9 100644
+--- a/drivers/net/ethernet/hisilicon/hns/hnae.c
++++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
+@@ -419,8 +419,10 @@ int hnae_ae_register(struct hnae_ae_dev *hdev, struct module *owner)
+ 	hdev->cls_dev.release = hnae_release;
+ 	(void)dev_set_name(&hdev->cls_dev, "hnae%d", hdev->id);
+ 	ret = device_register(&hdev->cls_dev);
+-	if (ret)
++	if (ret) {
++		put_device(&hdev->cls_dev);
+ 		return ret;
++	}
+ 
+ 	__module_get(THIS_MODULE);
+ 
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+index e9cd0fa6a0d2f..af5fe84db5961 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+@@ -2181,9 +2181,6 @@ static int i40e_set_ringparam(struct net_device *netdev,
+ 			 */
+ 			rx_rings[i].tail = hw->hw_addr + I40E_PRTGEN_STATUS;
+ 			err = i40e_setup_rx_descriptors(&rx_rings[i]);
+-			if (err)
+-				goto rx_unwind;
+-			err = i40e_alloc_rx_bi(&rx_rings[i]);
+ 			if (err)
+ 				goto rx_unwind;
+ 
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index e3d9804aeb25e..b3336d31f8a9d 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -3565,12 +3565,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
+ 	if (ring->vsi->type == I40E_VSI_MAIN)
+ 		xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq);
+ 
+-	kfree(ring->rx_bi);
+ 	ring->xsk_pool = i40e_xsk_pool(ring);
+ 	if (ring->xsk_pool) {
+-		ret = i40e_alloc_rx_bi_zc(ring);
+-		if (ret)
+-			return ret;
+ 		ring->rx_buf_len =
+ 		  xsk_pool_get_rx_frame_size(ring->xsk_pool);
+ 		/* For AF_XDP ZC, we disallow packets to span on
+@@ -3588,9 +3584,6 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
+ 			 ring->queue_index);
+ 
+ 	} else {
+-		ret = i40e_alloc_rx_bi(ring);
+-		if (ret)
+-			return ret;
+ 		ring->rx_buf_len = vsi->rx_buf_len;
+ 		if (ring->vsi->type == I40E_VSI_MAIN) {
+ 			ret = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
+@@ -13304,6 +13297,14 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
+ 		i40e_reset_and_rebuild(pf, true, true);
+ 	}
+ 
++	if (!i40e_enabled_xdp_vsi(vsi) && prog) {
++		if (i40e_realloc_rx_bi_zc(vsi, true))
++			return -ENOMEM;
++	} else if (i40e_enabled_xdp_vsi(vsi) && !prog) {
++		if (i40e_realloc_rx_bi_zc(vsi, false))
++			return -ENOMEM;
++	}
++
+ 	for (i = 0; i < vsi->num_queue_pairs; i++)
+ 		WRITE_ONCE(vsi->rx_rings[i]->xdp_prog, vsi->xdp_prog);
+ 
+@@ -13536,6 +13537,7 @@ int i40e_queue_pair_disable(struct i40e_vsi *vsi, int queue_pair)
+ 
+ 	i40e_queue_pair_disable_irq(vsi, queue_pair);
+ 	err = i40e_queue_pair_toggle_rings(vsi, queue_pair, false /* off */);
++	i40e_clean_rx_ring(vsi->rx_rings[queue_pair]);
+ 	i40e_queue_pair_toggle_napi(vsi, queue_pair, false /* off */);
+ 	i40e_queue_pair_clean_rings(vsi, queue_pair);
+ 	i40e_queue_pair_reset_stats(vsi, queue_pair);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+index 69e67eb6aea72..b97c95f89fa02 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+@@ -1457,14 +1457,6 @@ err:
+ 	return -ENOMEM;
+ }
+ 
+-int i40e_alloc_rx_bi(struct i40e_ring *rx_ring)
+-{
+-	unsigned long sz = sizeof(*rx_ring->rx_bi) * rx_ring->count;
+-
+-	rx_ring->rx_bi = kzalloc(sz, GFP_KERNEL);
+-	return rx_ring->rx_bi ? 0 : -ENOMEM;
+-}
+-
+ static void i40e_clear_rx_bi(struct i40e_ring *rx_ring)
+ {
+ 	memset(rx_ring->rx_bi, 0, sizeof(*rx_ring->rx_bi) * rx_ring->count);
+@@ -1593,6 +1585,11 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring)
+ 
+ 	rx_ring->xdp_prog = rx_ring->vsi->xdp_prog;
+ 
++	rx_ring->rx_bi =
++		kcalloc(rx_ring->count, sizeof(*rx_ring->rx_bi), GFP_KERNEL);
++	if (!rx_ring->rx_bi)
++		return -ENOMEM;
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
+index 41f86e9535a00..768290dc6f48b 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
+@@ -469,7 +469,6 @@ int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size);
+ bool __i40e_chk_linearize(struct sk_buff *skb);
+ int i40e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
+ 		  u32 flags);
+-int i40e_alloc_rx_bi(struct i40e_ring *rx_ring);
+ 
+ /**
+  * i40e_get_head - Retrieve head from head writeback
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.c b/drivers/net/ethernet/intel/i40e/i40e_xsk.c
+index 6d4009e0cbd62..cd7b52fb6b46c 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_xsk.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.c
+@@ -10,14 +10,6 @@
+ #include "i40e_txrx_common.h"
+ #include "i40e_xsk.h"
+ 
+-int i40e_alloc_rx_bi_zc(struct i40e_ring *rx_ring)
+-{
+-	unsigned long sz = sizeof(*rx_ring->rx_bi_zc) * rx_ring->count;
+-
+-	rx_ring->rx_bi_zc = kzalloc(sz, GFP_KERNEL);
+-	return rx_ring->rx_bi_zc ? 0 : -ENOMEM;
+-}
+-
+ void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring)
+ {
+ 	memset(rx_ring->rx_bi_zc, 0,
+@@ -29,6 +21,58 @@ static struct xdp_buff **i40e_rx_bi(struct i40e_ring *rx_ring, u32 idx)
+ 	return &rx_ring->rx_bi_zc[idx];
+ }
+ 
++/**
++ * i40e_realloc_rx_xdp_bi - reallocate SW ring for either XSK or normal buffer
++ * @rx_ring: Current rx ring
++ * @pool_present: is pool for XSK present
++ *
++ * Try allocating memory and return ENOMEM, if failed to allocate.
++ * If allocation was successful, substitute buffer with allocated one.
++ * Returns 0 on success, negative on failure
++ */
++static int i40e_realloc_rx_xdp_bi(struct i40e_ring *rx_ring, bool pool_present)
++{
++	size_t elem_size = pool_present ? sizeof(*rx_ring->rx_bi_zc) :
++					  sizeof(*rx_ring->rx_bi);
++	void *sw_ring = kcalloc(rx_ring->count, elem_size, GFP_KERNEL);
++
++	if (!sw_ring)
++		return -ENOMEM;
++
++	if (pool_present) {
++		kfree(rx_ring->rx_bi);
++		rx_ring->rx_bi = NULL;
++		rx_ring->rx_bi_zc = sw_ring;
++	} else {
++		kfree(rx_ring->rx_bi_zc);
++		rx_ring->rx_bi_zc = NULL;
++		rx_ring->rx_bi = sw_ring;
++	}
++	return 0;
++}
++
++/**
++ * i40e_realloc_rx_bi_zc - reallocate rx SW rings
++ * @vsi: Current VSI
++ * @zc: is zero copy set
++ *
++ * Reallocate buffer for rx_rings that might be used by XSK.
++ * XDP requires more memory, than rx_buf provides.
++ * Returns 0 on success, negative on failure
++ */
++int i40e_realloc_rx_bi_zc(struct i40e_vsi *vsi, bool zc)
++{
++	struct i40e_ring *rx_ring;
++	unsigned long q;
++
++	for_each_set_bit(q, vsi->af_xdp_zc_qps, vsi->alloc_queue_pairs) {
++		rx_ring = vsi->rx_rings[q];
++		if (i40e_realloc_rx_xdp_bi(rx_ring, zc))
++			return -ENOMEM;
++	}
++	return 0;
++}
++
+ /**
+  * i40e_xsk_pool_enable - Enable/associate an AF_XDP buffer pool to a
+  * certain ring/qid
+@@ -69,6 +113,10 @@ static int i40e_xsk_pool_enable(struct i40e_vsi *vsi,
+ 		if (err)
+ 			return err;
+ 
++		err = i40e_realloc_rx_xdp_bi(vsi->rx_rings[qid], true);
++		if (err)
++			return err;
++
+ 		err = i40e_queue_pair_enable(vsi, qid);
+ 		if (err)
+ 			return err;
+@@ -113,6 +161,9 @@ static int i40e_xsk_pool_disable(struct i40e_vsi *vsi, u16 qid)
+ 	xsk_pool_dma_unmap(pool, I40E_RX_DMA_ATTR);
+ 
+ 	if (if_running) {
++		err = i40e_realloc_rx_xdp_bi(vsi->rx_rings[qid], false);
++		if (err)
++			return err;
+ 		err = i40e_queue_pair_enable(vsi, qid);
+ 		if (err)
+ 			return err;
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.h b/drivers/net/ethernet/intel/i40e/i40e_xsk.h
+index bb962987f300a..821df248f8bee 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_xsk.h
++++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.h
+@@ -32,7 +32,7 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget);
+ 
+ bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi, struct i40e_ring *tx_ring);
+ int i40e_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags);
+-int i40e_alloc_rx_bi_zc(struct i40e_ring *rx_ring);
++int i40e_realloc_rx_bi_zc(struct i40e_vsi *vsi, bool zc);
+ void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring);
+ 
+ #endif /* _I40E_XSK_H_ */
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index b344632beaddf..84433f3a3e228 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4028,19 +4028,23 @@ static int mtk_probe(struct platform_device *pdev)
+ 			eth->irq[i] = platform_get_irq(pdev, i);
+ 		if (eth->irq[i] < 0) {
+ 			dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
+-			return -ENXIO;
++			err = -ENXIO;
++			goto err_wed_exit;
+ 		}
+ 	}
+ 	for (i = 0; i < ARRAY_SIZE(eth->clks); i++) {
+ 		eth->clks[i] = devm_clk_get(eth->dev,
+ 					    mtk_clks_source_name[i]);
+ 		if (IS_ERR(eth->clks[i])) {
+-			if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER)
+-				return -EPROBE_DEFER;
++			if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER) {
++				err = -EPROBE_DEFER;
++				goto err_wed_exit;
++			}
+ 			if (eth->soc->required_clks & BIT(i)) {
+ 				dev_err(&pdev->dev, "clock %s not found\n",
+ 					mtk_clks_source_name[i]);
+-				return -EINVAL;
++				err = -EINVAL;
++				goto err_wed_exit;
+ 			}
+ 			eth->clks[i] = NULL;
+ 		}
+@@ -4051,7 +4055,7 @@ static int mtk_probe(struct platform_device *pdev)
+ 
+ 	err = mtk_hw_init(eth);
+ 	if (err)
+-		return err;
++		goto err_wed_exit;
+ 
+ 	eth->hwlro = MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO);
+ 
+@@ -4140,6 +4144,8 @@ err_free_dev:
+ 	mtk_free_dev(eth);
+ err_deinit_hw:
+ 	mtk_hw_deinit(eth);
++err_wed_exit:
++	mtk_wed_exit();
+ 
+ 	return err;
+ }
+@@ -4159,6 +4165,7 @@ static int mtk_remove(struct platform_device *pdev)
+ 		phylink_disconnect_phy(mac->phylink);
+ 	}
+ 
++	mtk_wed_exit();
+ 	mtk_hw_deinit(eth);
+ 
+ 	netif_napi_del(&eth->tx_napi);
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
+index 29be2fcafea3b..614147ad6116a 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -808,16 +808,16 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ 
+ 	pdev = of_find_device_by_node(np);
+ 	if (!pdev)
+-		return;
++		goto err_of_node_put;
+ 
+ 	get_device(&pdev->dev);
+ 	irq = platform_get_irq(pdev, 0);
+ 	if (irq < 0)
+-		return;
++		goto err_put_device;
+ 
+ 	regs = syscon_regmap_lookup_by_phandle(np, NULL);
+ 	if (IS_ERR(regs))
+-		return;
++		goto err_put_device;
+ 
+ 	rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops);
+ 
+@@ -853,8 +853,16 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ 
+ 	hw_list[index] = hw;
+ 
++	mutex_unlock(&hw_lock);
++
++	return;
++
+ unlock:
+ 	mutex_unlock(&hw_lock);
++err_put_device:
++	put_device(&pdev->dev);
++err_of_node_put:
++	of_node_put(np);
+ }
+ 
+ void mtk_wed_exit(void)
+@@ -875,6 +883,7 @@ void mtk_wed_exit(void)
+ 		hw_list[i] = NULL;
+ 		debugfs_remove(hw->debugfs_dir);
+ 		put_device(hw->dev);
++		of_node_put(hw->node);
+ 		kfree(hw);
+ 	}
+ }
+diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+index 0be79c5167813..6ae6d79193a3c 100644
+--- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c
++++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+@@ -2820,11 +2820,15 @@ err_out:
+ 	 * than the full array, but leave the qcq shells in place
+ 	 */
+ 	for (i = lif->nxqs; i < lif->ionic->ntxqs_per_lif; i++) {
+-		lif->txqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
+-		ionic_qcq_free(lif, lif->txqcqs[i]);
++		if (lif->txqcqs && lif->txqcqs[i]) {
++			lif->txqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
++			ionic_qcq_free(lif, lif->txqcqs[i]);
++		}
+ 
+-		lif->rxqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
+-		ionic_qcq_free(lif, lif->rxqcqs[i]);
++		if (lif->rxqcqs && lif->rxqcqs[i]) {
++			lif->rxqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
++			ionic_qcq_free(lif, lif->rxqcqs[i]);
++		}
+ 	}
+ 
+ 	if (err)
+diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
+index d1e1aa19a68ed..7022fb2005a2f 100644
+--- a/drivers/net/ethernet/sfc/ef10.c
++++ b/drivers/net/ethernet/sfc/ef10.c
+@@ -3277,6 +3277,30 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
+ 	bool was_enabled = efx->port_enabled;
+ 	int rc;
+ 
++#ifdef CONFIG_SFC_SRIOV
++	/* If this function is a VF and we have access to the parent PF,
++	 * then use the PF control path to attempt to change the VF MAC address.
++	 */
++	if (efx->pci_dev->is_virtfn && efx->pci_dev->physfn) {
++		struct efx_nic *efx_pf = pci_get_drvdata(efx->pci_dev->physfn);
++		struct efx_ef10_nic_data *nic_data = efx->nic_data;
++		u8 mac[ETH_ALEN];
++
++		/* net_dev->dev_addr can be zeroed by efx_net_stop in
++		 * efx_ef10_sriov_set_vf_mac, so pass in a copy.
++		 */
++		ether_addr_copy(mac, efx->net_dev->dev_addr);
++
++		rc = efx_ef10_sriov_set_vf_mac(efx_pf, nic_data->vf_index, mac);
++		if (!rc)
++			return 0;
++
++		netif_dbg(efx, drv, efx->net_dev,
++			  "Updating VF mac via PF failed (%d), setting directly\n",
++			  rc);
++	}
++#endif
++
+ 	efx_device_detach_sync(efx);
+ 	efx_net_stop(efx->net_dev);
+ 
+@@ -3297,40 +3321,6 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
+ 		efx_net_open(efx->net_dev);
+ 	efx_device_attach_if_not_resetting(efx);
+ 
+-#ifdef CONFIG_SFC_SRIOV
+-	if (efx->pci_dev->is_virtfn && efx->pci_dev->physfn) {
+-		struct efx_ef10_nic_data *nic_data = efx->nic_data;
+-		struct pci_dev *pci_dev_pf = efx->pci_dev->physfn;
+-
+-		if (rc == -EPERM) {
+-			struct efx_nic *efx_pf;
+-
+-			/* Switch to PF and change MAC address on vport */
+-			efx_pf = pci_get_drvdata(pci_dev_pf);
+-
+-			rc = efx_ef10_sriov_set_vf_mac(efx_pf,
+-						       nic_data->vf_index,
+-						       efx->net_dev->dev_addr);
+-		} else if (!rc) {
+-			struct efx_nic *efx_pf = pci_get_drvdata(pci_dev_pf);
+-			struct efx_ef10_nic_data *nic_data = efx_pf->nic_data;
+-			unsigned int i;
+-
+-			/* MAC address successfully changed by VF (with MAC
+-			 * spoofing) so update the parent PF if possible.
+-			 */
+-			for (i = 0; i < efx_pf->vf_count; ++i) {
+-				struct ef10_vf *vf = nic_data->vf + i;
+-
+-				if (vf->efx == efx) {
+-					ether_addr_copy(vf->mac,
+-							efx->net_dev->dev_addr);
+-					return 0;
+-				}
+-			}
+-		}
+-	} else
+-#endif
+ 	if (rc == -EPERM) {
+ 		netif_err(efx, drv, efx->net_dev,
+ 			  "Cannot change MAC address; use sfboot to enable"
+diff --git a/drivers/net/ethernet/sfc/filter.h b/drivers/net/ethernet/sfc/filter.h
+index 4d928839d2922..f569d07ef2676 100644
+--- a/drivers/net/ethernet/sfc/filter.h
++++ b/drivers/net/ethernet/sfc/filter.h
+@@ -161,9 +161,9 @@ struct efx_filter_spec {
+ 	u32	priority:2;
+ 	u32	flags:6;
+ 	u32	dmaq_id:12;
+-	u32	vport_id;
+ 	u32	rss_context;
+-	__be16	outer_vid __aligned(4); /* allow jhash2() of match values */
++	u32	vport_id;
++	__be16	outer_vid;
+ 	__be16	inner_vid;
+ 	u8	loc_mac[ETH_ALEN];
+ 	u8	rem_mac[ETH_ALEN];
+diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c
+index 4826e6a7e4ce3..9220afeddee81 100644
+--- a/drivers/net/ethernet/sfc/rx_common.c
++++ b/drivers/net/ethernet/sfc/rx_common.c
+@@ -660,17 +660,17 @@ bool efx_filter_spec_equal(const struct efx_filter_spec *left,
+ 	     (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX)))
+ 		return false;
+ 
+-	return memcmp(&left->outer_vid, &right->outer_vid,
++	return memcmp(&left->vport_id, &right->vport_id,
+ 		      sizeof(struct efx_filter_spec) -
+-		      offsetof(struct efx_filter_spec, outer_vid)) == 0;
++		      offsetof(struct efx_filter_spec, vport_id)) == 0;
+ }
+ 
+ u32 efx_filter_spec_hash(const struct efx_filter_spec *spec)
+ {
+-	BUILD_BUG_ON(offsetof(struct efx_filter_spec, outer_vid) & 3);
+-	return jhash2((const u32 *)&spec->outer_vid,
++	BUILD_BUG_ON(offsetof(struct efx_filter_spec, vport_id) & 3);
++	return jhash2((const u32 *)&spec->vport_id,
+ 		      (sizeof(struct efx_filter_spec) -
+-		       offsetof(struct efx_filter_spec, outer_vid)) / 4,
++		       offsetof(struct efx_filter_spec, vport_id)) / 4,
+ 		      0);
+ }
+ 
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 9083159b93f14..bc060ef558d37 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -1214,6 +1214,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
+ 	if (priv->plat->tx_queues_to_use > 1)
+ 		priv->phylink_config.mac_capabilities &=
+ 			~(MAC_10HD | MAC_100HD | MAC_1000HD);
++	priv->phylink_config.mac_managed_pm = true;
+ 
+ 	phylink = phylink_create(&priv->phylink_config, fwnode,
+ 				 mode, &stmmac_phylink_mac_ops);
+diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
+index 8549e0e356c9b..b60db8b6f4774 100644
+--- a/drivers/net/phy/dp83822.c
++++ b/drivers/net/phy/dp83822.c
+@@ -254,8 +254,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
+ 				DP83822_EEE_ERROR_CHANGE_INT_EN);
+ 
+ 		if (!dp83822->fx_enabled)
+-			misr_status |= DP83822_MDI_XOVER_INT_EN |
+-				       DP83822_ANEG_ERR_INT_EN |
++			misr_status |= DP83822_ANEG_ERR_INT_EN |
+ 				       DP83822_WOL_PKT_INT_EN;
+ 
+ 		err = phy_write(phydev, MII_DP83822_MISR2, misr_status);
+diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
+index 6939563d3b7c5..417527f8bbf55 100644
+--- a/drivers/net/phy/dp83867.c
++++ b/drivers/net/phy/dp83867.c
+@@ -853,6 +853,14 @@ static int dp83867_config_init(struct phy_device *phydev)
+ 		else
+ 			val &= ~DP83867_SGMII_TYPE;
+ 		phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL, val);
++
++		/* This is a SW workaround for link instability if RX_CTRL is
++		 * not strapped to mode 3 or 4 in HW. This is required for SGMII
++		 * in addition to clearing bit 7, handled above.
++		 */
++		if (dp83867->rxctrl_strap_quirk)
++			phy_set_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
++					 BIT(8));
+ 	}
+ 
+ 	val = phy_read(phydev, DP83867_CFG3);
+diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
+index 9bd69328dc4d4..7bbbe69a7b0af 100644
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -1431,6 +1431,9 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
+ 	if (phy_interrupt_is_valid(phy))
+ 		phy_request_interrupt(phy);
+ 
++	if (pl->config->mac_managed_pm)
++		phy->mac_managed_pm = true;
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+index e5b1f6249763a..9c92f20c4aeb4 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+@@ -152,6 +152,7 @@ static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr)
+ 		{ 0x820c8000, 0x0c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */
+ 		{ 0x820cc000, 0x0e000, 0x1000 }, /* WF_UMAC_TOP (PP) */
+ 		{ 0x820cd000, 0x0f000, 0x1000 }, /* WF_MDP_TOP */
++		{ 0x74030000, 0x10000, 0x10000 }, /* PCIE_MAC_IREG */
+ 		{ 0x820ce000, 0x21c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */
+ 		{ 0x820cf000, 0x22000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */
+ 		{ 0x820e0000, 0x20000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c
+index 5efda694fb9d5..19facf31e4e14 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c
+@@ -59,6 +59,8 @@ int mt7921e_mcu_init(struct mt7921_dev *dev)
+ 	if (err)
+ 		return err;
+ 
++	mt76_rmw_field(dev, MT_PCIE_MAC_PM, MT_PCIE_MAC_PM_L0S_DIS, 1);
++
+ 	err = mt7921_run_firmware(dev);
+ 
+ 	mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/regs.h b/drivers/net/wireless/mediatek/mt76/mt7921/regs.h
+index ea643260ceb66..c65582acfa55d 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/regs.h
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/regs.h
+@@ -440,6 +440,8 @@
+ #define MT_PCIE_MAC_BASE		0x10000
+ #define MT_PCIE_MAC(ofs)		(MT_PCIE_MAC_BASE + (ofs))
+ #define MT_PCIE_MAC_INT_ENABLE		MT_PCIE_MAC(0x188)
++#define MT_PCIE_MAC_PM			MT_PCIE_MAC(0x194)
++#define MT_PCIE_MAC_PM_L0S_DIS		BIT(8)
+ 
+ #define MT_DMA_SHDL(ofs)		(0x7c026000 + (ofs))
+ #define MT_DMASHDL_SW_CONTROL		MT_DMA_SHDL(0x004)
+diff --git a/drivers/net/wwan/wwan_hwsim.c b/drivers/net/wwan/wwan_hwsim.c
+index fad642f9ffd8d..857a55b625fea 100644
+--- a/drivers/net/wwan/wwan_hwsim.c
++++ b/drivers/net/wwan/wwan_hwsim.c
+@@ -311,7 +311,7 @@ err_unreg_dev:
+ 	return ERR_PTR(err);
+ 
+ err_free_dev:
+-	kfree(dev);
++	put_device(&dev->dev);
+ 
+ 	return ERR_PTR(err);
+ }
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 59e4b188fc71c..ed47c256dbd27 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -3256,8 +3256,12 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl)
+ 		return ret;
+ 
+ 	if (!ctrl->identified && !nvme_discovery_ctrl(ctrl)) {
++		/*
++		 * Do not return errors unless we are in a controller reset,
++		 * the controller works perfectly fine without hwmon.
++		 */
+ 		ret = nvme_hwmon_init(ctrl);
+-		if (ret < 0)
++		if (ret == -EINTR)
+ 			return ret;
+ 	}
+ 
+diff --git a/drivers/nvme/host/hwmon.c b/drivers/nvme/host/hwmon.c
+index 0a586d7129201..9e6e56c20ec99 100644
+--- a/drivers/nvme/host/hwmon.c
++++ b/drivers/nvme/host/hwmon.c
+@@ -12,7 +12,7 @@
+ 
+ struct nvme_hwmon_data {
+ 	struct nvme_ctrl *ctrl;
+-	struct nvme_smart_log log;
++	struct nvme_smart_log *log;
+ 	struct mutex read_lock;
+ };
+ 
+@@ -60,14 +60,14 @@ static int nvme_set_temp_thresh(struct nvme_ctrl *ctrl, int sensor, bool under,
+ static int nvme_hwmon_get_smart_log(struct nvme_hwmon_data *data)
+ {
+ 	return nvme_get_log(data->ctrl, NVME_NSID_ALL, NVME_LOG_SMART, 0,
+-			   NVME_CSI_NVM, &data->log, sizeof(data->log), 0);
++			   NVME_CSI_NVM, data->log, sizeof(*data->log), 0);
+ }
+ 
+ static int nvme_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+ 			   u32 attr, int channel, long *val)
+ {
+ 	struct nvme_hwmon_data *data = dev_get_drvdata(dev);
+-	struct nvme_smart_log *log = &data->log;
++	struct nvme_smart_log *log = data->log;
+ 	int temp;
+ 	int err;
+ 
+@@ -163,7 +163,7 @@ static umode_t nvme_hwmon_is_visible(const void *_data,
+ 	case hwmon_temp_max:
+ 	case hwmon_temp_min:
+ 		if ((!channel && data->ctrl->wctemp) ||
+-		    (channel && data->log.temp_sensor[channel - 1])) {
++		    (channel && data->log->temp_sensor[channel - 1])) {
+ 			if (data->ctrl->quirks &
+ 			    NVME_QUIRK_NO_TEMP_THRESH_CHANGE)
+ 				return 0444;
+@@ -176,7 +176,7 @@ static umode_t nvme_hwmon_is_visible(const void *_data,
+ 		break;
+ 	case hwmon_temp_input:
+ 	case hwmon_temp_label:
+-		if (!channel || data->log.temp_sensor[channel - 1])
++		if (!channel || data->log->temp_sensor[channel - 1])
+ 			return 0444;
+ 		break;
+ 	default:
+@@ -230,7 +230,13 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl)
+ 
+ 	data = kzalloc(sizeof(*data), GFP_KERNEL);
+ 	if (!data)
+-		return 0;
++		return -ENOMEM;
++
++	data->log = kzalloc(sizeof(*data->log), GFP_KERNEL);
++	if (!data->log) {
++		err = -ENOMEM;
++		goto err_free_data;
++	}
+ 
+ 	data->ctrl = ctrl;
+ 	mutex_init(&data->read_lock);
+@@ -238,8 +244,7 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl)
+ 	err = nvme_hwmon_get_smart_log(data);
+ 	if (err) {
+ 		dev_warn(dev, "Failed to read smart log (error %d)\n", err);
+-		kfree(data);
+-		return err;
++		goto err_free_log;
+ 	}
+ 
+ 	hwmon = hwmon_device_register_with_info(dev, "nvme",
+@@ -247,11 +252,17 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl)
+ 						NULL);
+ 	if (IS_ERR(hwmon)) {
+ 		dev_warn(dev, "Failed to instantiate hwmon device\n");
+-		kfree(data);
+-		return PTR_ERR(hwmon);
++		err = PTR_ERR(hwmon);
++		goto err_free_log;
+ 	}
+ 	ctrl->hwmon_device = hwmon;
+ 	return 0;
++
++err_free_log:
++	kfree(data->log);
++err_free_data:
++	kfree(data);
++	return err;
+ }
+ 
+ void nvme_hwmon_exit(struct nvme_ctrl *ctrl)
+@@ -262,6 +273,7 @@ void nvme_hwmon_exit(struct nvme_ctrl *ctrl)
+ 
+ 		hwmon_device_unregister(ctrl->hwmon_device);
+ 		ctrl->hwmon_device = NULL;
++		kfree(data->log);
+ 		kfree(data);
+ 	}
+ }
+diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
+index 14677145bbba0..aecb5853f8da4 100644
+--- a/drivers/nvme/target/core.c
++++ b/drivers/nvme/target/core.c
+@@ -1176,7 +1176,7 @@ static void nvmet_start_ctrl(struct nvmet_ctrl *ctrl)
+ 	 * reset the keep alive timer when the controller is enabled.
+ 	 */
+ 	if (ctrl->kato)
+-		mod_delayed_work(system_wq, &ctrl->ka_work, ctrl->kato * HZ);
++		mod_delayed_work(nvmet_wq, &ctrl->ka_work, ctrl->kato * HZ);
+ }
+ 
+ static void nvmet_clear_ctrl(struct nvmet_ctrl *ctrl)
+diff --git a/drivers/platform/x86/amd/pmc.c b/drivers/platform/x86/amd/pmc.c
+index 700eb19e84500..fc326fdf483fb 100644
+--- a/drivers/platform/x86/amd/pmc.c
++++ b/drivers/platform/x86/amd/pmc.c
+@@ -635,6 +635,13 @@ static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg)
+ 	struct rtc_time tm;
+ 	int rc;
+ 
++	/* we haven't yet read SMU version */
++	if (!pdev->major) {
++		rc = amd_pmc_get_smu_version(pdev);
++		if (rc)
++			return rc;
++	}
++
+ 	if (pdev->major < 64 || (pdev->major == 64 && pdev->minor < 53))
+ 		return 0;
+ 
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index 1a02134438fcc..47e210095315e 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -4822,7 +4822,7 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
+ 	rc = lpfc_vmid_res_alloc(phba, vport);
+ 
+ 	if (rc)
+-		goto out;
++		goto out_put_shost;
+ 
+ 	/* Initialize all internally managed lists. */
+ 	INIT_LIST_HEAD(&vport->fc_nodes);
+@@ -4840,16 +4840,17 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
+ 
+ 	error = scsi_add_host_with_dma(shost, dev, &phba->pcidev->dev);
+ 	if (error)
+-		goto out_put_shost;
++		goto out_free_vmid;
+ 
+ 	spin_lock_irq(&phba->port_list_lock);
+ 	list_add_tail(&vport->listentry, &phba->port_list);
+ 	spin_unlock_irq(&phba->port_list_lock);
+ 	return vport;
+ 
+-out_put_shost:
++out_free_vmid:
+ 	kfree(vport->vmid);
+ 	bitmap_free(vport->vmid_priority_range);
++out_put_shost:
+ 	scsi_host_put(shost);
+ out:
+ 	return NULL;
+diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c
+index d1c539cefba87..2234bb8d48b34 100644
+--- a/drivers/staging/media/ipu3/ipu3-v4l2.c
++++ b/drivers/staging/media/ipu3/ipu3-v4l2.c
+@@ -192,33 +192,30 @@ static int imgu_subdev_get_selection(struct v4l2_subdev *sd,
+ 				     struct v4l2_subdev_state *sd_state,
+ 				     struct v4l2_subdev_selection *sel)
+ {
+-	struct v4l2_rect *try_sel, *r;
+-	struct imgu_v4l2_subdev *imgu_sd = container_of(sd,
+-							struct imgu_v4l2_subdev,
+-							subdev);
++	struct imgu_v4l2_subdev *imgu_sd =
++		container_of(sd, struct imgu_v4l2_subdev, subdev);
+ 
+ 	if (sel->pad != IMGU_NODE_IN)
+ 		return -EINVAL;
+ 
+ 	switch (sel->target) {
+ 	case V4L2_SEL_TGT_CROP:
+-		try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad);
+-		r = &imgu_sd->rect.eff;
+-		break;
++		if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
++			sel->r = *v4l2_subdev_get_try_crop(sd, sd_state,
++							   sel->pad);
++		else
++			sel->r = imgu_sd->rect.eff;
++		return 0;
+ 	case V4L2_SEL_TGT_COMPOSE:
+-		try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad);
+-		r = &imgu_sd->rect.bds;
+-		break;
++		if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
++			sel->r = *v4l2_subdev_get_try_compose(sd, sd_state,
++							      sel->pad);
++		else
++			sel->r = imgu_sd->rect.bds;
++		return 0;
+ 	default:
+ 		return -EINVAL;
+ 	}
+-
+-	if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
+-		sel->r = *try_sel;
+-	else
+-		sel->r = *r;
+-
+-	return 0;
+ }
+ 
+ static int imgu_subdev_set_selection(struct v4l2_subdev *sd,
+diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c
+index 101e13c2cf41c..9223d3d4089f1 100644
+--- a/drivers/video/aperture.c
++++ b/drivers/video/aperture.c
+@@ -357,6 +357,17 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na
+ 	if (ret)
+ 		return ret;
+ 
++	/*
++	 * If a driver asked to unregister a platform device registered by
++	 * sysfb, then can be assumed that this is a driver for a display
++	 * that is set up by the system firmware and has a generic driver.
++	 *
++	 * Drivers for devices that don't have a generic driver will never
++	 * ask for this, so let's assume that a real driver for the display
++	 * was already probed and prevent sysfb to register devices later.
++	 */
++	sysfb_disable();
++
+ 	/*
+ 	 * WARNING: Apparently we must kick fbdev drivers before vgacon,
+ 	 * otherwise the vga fbdev driver falls over.
+diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
+index d385357e19b61..ccc818b409774 100644
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -138,6 +138,7 @@ struct share_check {
+ 	u64 root_objectid;
+ 	u64 inum;
+ 	int share_count;
++	bool have_delayed_delete_refs;
+ };
+ 
+ static inline int extent_is_shared(struct share_check *sc)
+@@ -820,16 +821,11 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
+ 			    struct preftrees *preftrees, struct share_check *sc)
+ {
+ 	struct btrfs_delayed_ref_node *node;
+-	struct btrfs_delayed_extent_op *extent_op = head->extent_op;
+ 	struct btrfs_key key;
+-	struct btrfs_key tmp_op_key;
+ 	struct rb_node *n;
+ 	int count;
+ 	int ret = 0;
+ 
+-	if (extent_op && extent_op->update_key)
+-		btrfs_disk_key_to_cpu(&tmp_op_key, &extent_op->key);
+-
+ 	spin_lock(&head->lock);
+ 	for (n = rb_first_cached(&head->ref_tree); n; n = rb_next(n)) {
+ 		node = rb_entry(n, struct btrfs_delayed_ref_node,
+@@ -855,10 +851,16 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
+ 		case BTRFS_TREE_BLOCK_REF_KEY: {
+ 			/* NORMAL INDIRECT METADATA backref */
+ 			struct btrfs_delayed_tree_ref *ref;
++			struct btrfs_key *key_ptr = NULL;
++
++			if (head->extent_op && head->extent_op->update_key) {
++				btrfs_disk_key_to_cpu(&key, &head->extent_op->key);
++				key_ptr = &key;
++			}
+ 
+ 			ref = btrfs_delayed_node_to_tree_ref(node);
+ 			ret = add_indirect_ref(fs_info, preftrees, ref->root,
+-					       &tmp_op_key, ref->level + 1,
++					       key_ptr, ref->level + 1,
+ 					       node->bytenr, count, sc,
+ 					       GFP_ATOMIC);
+ 			break;
+@@ -884,13 +886,22 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
+ 			key.offset = ref->offset;
+ 
+ 			/*
+-			 * Found a inum that doesn't match our known inum, we
+-			 * know it's shared.
++			 * If we have a share check context and a reference for
++			 * another inode, we can't exit immediately. This is
++			 * because even if this is a BTRFS_ADD_DELAYED_REF
++			 * reference we may find next a BTRFS_DROP_DELAYED_REF
++			 * which cancels out this ADD reference.
++			 *
++			 * If this is a DROP reference and there was no previous
++			 * ADD reference, then we need to signal that when we
++			 * process references from the extent tree (through
++			 * add_inline_refs() and add_keyed_refs()), we should
++			 * not exit early if we find a reference for another
++			 * inode, because one of the delayed DROP references
++			 * may cancel that reference in the extent tree.
+ 			 */
+-			if (sc && sc->inum && ref->objectid != sc->inum) {
+-				ret = BACKREF_FOUND_SHARED;
+-				goto out;
+-			}
++			if (sc && count < 0)
++				sc->have_delayed_delete_refs = true;
+ 
+ 			ret = add_indirect_ref(fs_info, preftrees, ref->root,
+ 					       &key, 0, node->bytenr, count, sc,
+@@ -920,7 +931,7 @@ static int add_delayed_refs(const struct btrfs_fs_info *fs_info,
+ 	}
+ 	if (!ret)
+ 		ret = extent_is_shared(sc);
+-out:
++
+ 	spin_unlock(&head->lock);
+ 	return ret;
+ }
+@@ -1023,7 +1034,8 @@ static int add_inline_refs(const struct btrfs_fs_info *fs_info,
+ 			key.type = BTRFS_EXTENT_DATA_KEY;
+ 			key.offset = btrfs_extent_data_ref_offset(leaf, dref);
+ 
+-			if (sc && sc->inum && key.objectid != sc->inum) {
++			if (sc && sc->inum && key.objectid != sc->inum &&
++			    !sc->have_delayed_delete_refs) {
+ 				ret = BACKREF_FOUND_SHARED;
+ 				break;
+ 			}
+@@ -1033,6 +1045,7 @@ static int add_inline_refs(const struct btrfs_fs_info *fs_info,
+ 			ret = add_indirect_ref(fs_info, preftrees, root,
+ 					       &key, 0, bytenr, count,
+ 					       sc, GFP_NOFS);
++
+ 			break;
+ 		}
+ 		default:
+@@ -1122,7 +1135,8 @@ static int add_keyed_refs(struct btrfs_root *extent_root,
+ 			key.type = BTRFS_EXTENT_DATA_KEY;
+ 			key.offset = btrfs_extent_data_ref_offset(leaf, dref);
+ 
+-			if (sc && sc->inum && key.objectid != sc->inum) {
++			if (sc && sc->inum && key.objectid != sc->inum &&
++			    !sc->have_delayed_delete_refs) {
+ 				ret = BACKREF_FOUND_SHARED;
+ 				break;
+ 			}
+@@ -1544,6 +1558,7 @@ int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
+ 		.root_objectid = root->root_key.objectid,
+ 		.inum = inum,
+ 		.share_count = 0,
++		.have_delayed_delete_refs = false,
+ 	};
+ 
+ 	ulist_init(roots);
+@@ -1578,6 +1593,7 @@ int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
+ 			break;
+ 		bytenr = node->val;
+ 		shared.share_count = 0;
++		shared.have_delayed_delete_refs = false;
+ 		cond_resched();
+ 	}
+ 
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index 8042d7280dec1..6bc8be9ed2a56 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -1297,8 +1297,11 @@ static ssize_t cifs_copy_file_range(struct file *src_file, loff_t off,
+ 	ssize_t rc;
+ 	struct cifsFileInfo *cfile = dst_file->private_data;
+ 
+-	if (cfile->swapfile)
+-		return -EOPNOTSUPP;
++	if (cfile->swapfile) {
++		rc = -EOPNOTSUPP;
++		free_xid(xid);
++		return rc;
++	}
+ 
+ 	rc = cifs_file_copychunk_range(xid, src_file, off, dst_file, destoff,
+ 					len, flags);
+diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
+index 08f7392716e2f..05c78a18ade07 100644
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -551,8 +551,10 @@ int cifs_create(struct user_namespace *mnt_userns, struct inode *inode,
+ 	cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n",
+ 		 inode, direntry, direntry);
+ 
+-	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
+-		return -EIO;
++	if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) {
++		rc = -EIO;
++		goto out_free_xid;
++	}
+ 
+ 	tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
+ 	rc = PTR_ERR(tlink);
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 7d756721e1a68..5c045dd697846 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -1882,11 +1882,13 @@ int cifs_flock(struct file *file, int cmd, struct file_lock *fl)
+ 	struct cifsFileInfo *cfile;
+ 	__u32 type;
+ 
+-	rc = -EACCES;
+ 	xid = get_xid();
+ 
+-	if (!(fl->fl_flags & FL_FLOCK))
+-		return -ENOLCK;
++	if (!(fl->fl_flags & FL_FLOCK)) {
++		rc = -ENOLCK;
++		free_xid(xid);
++		return rc;
++	}
+ 
+ 	cfile = (struct cifsFileInfo *)file->private_data;
+ 	tcon = tlink_tcon(cfile->tlink);
+@@ -1905,8 +1907,9 @@ int cifs_flock(struct file *file, int cmd, struct file_lock *fl)
+ 		 * if no lock or unlock then nothing to do since we do not
+ 		 * know what it is
+ 		 */
++		rc = -EOPNOTSUPP;
+ 		free_xid(xid);
+-		return -EOPNOTSUPP;
++		return rc;
+ 	}
+ 
+ 	rc = cifs_setlk(file, fl, type, wait_flag, posix_lck, lock, unlock,
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index 3af3b05b6c740..11cd06aa74f0a 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -496,6 +496,7 @@ out:
+ 		cifs_put_tcp_session(chan->server, 0);
+ 	}
+ 
++	free_xid(xid);
+ 	return rc;
+ }
+ 
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index b02552e5f3eeb..14376437187ae 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -530,6 +530,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ 	p = buf;
+ 
+ 	spin_lock(&ses->iface_lock);
++	ses->iface_count = 0;
+ 	/*
+ 	 * Go through iface_list and do kref_put to remove
+ 	 * any unused ifaces. ifaces in use will be removed
+@@ -650,9 +651,9 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ 			kref_put(&iface->refcount, release_iface);
+ 		} else
+ 			list_add_tail(&info->iface_head, &ses->iface_list);
+-		spin_unlock(&ses->iface_lock);
+ 
+ 		ses->iface_count++;
++		spin_unlock(&ses->iface_lock);
+ 		ses->iface_last_update = jiffies;
+ next_iface:
+ 		nb_iface++;
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 5016d742576d0..92a1d0695ebdf 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -1526,7 +1526,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
+ 					  &blob_length, ses, server,
+ 					  sess_data->nls_cp);
+ 	if (rc)
+-		goto out_err;
++		goto out;
+ 
+ 	if (use_spnego) {
+ 		/* BB eventually need to add this */
+diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
+index 5792ca9e0d5ef..6e663275aeb13 100644
+--- a/fs/erofs/zdata.c
++++ b/fs/erofs/zdata.c
+@@ -838,15 +838,13 @@ static void z_erofs_do_decompressed_bvec(struct z_erofs_decompress_backend *be,
+ 
+ 	if (!((bvec->offset + be->pcl->pageofs_out) & ~PAGE_MASK)) {
+ 		unsigned int pgnr;
+-		struct page *oldpage;
+ 
+ 		pgnr = (bvec->offset + be->pcl->pageofs_out) >> PAGE_SHIFT;
+ 		DBG_BUGON(pgnr >= be->nr_pages);
+-		oldpage = be->decompressed_pages[pgnr];
+-		be->decompressed_pages[pgnr] = bvec->page;
+-
+-		if (!oldpage)
++		if (!be->decompressed_pages[pgnr]) {
++			be->decompressed_pages[pgnr] = bvec->page;
+ 			return;
++		}
+ 	}
+ 
+ 	/* (cold path) one pcluster is requested multiple times */
+diff --git a/fs/erofs/zdata.h b/fs/erofs/zdata.h
+index e7f04c4fbb81c..d98c952129852 100644
+--- a/fs/erofs/zdata.h
++++ b/fs/erofs/zdata.h
+@@ -126,10 +126,10 @@ static inline unsigned int z_erofs_pclusterpages(struct z_erofs_pcluster *pcl)
+ }
+ 
+ /*
+- * bit 31: I/O error occurred on this page
+- * bit 0 - 30: remaining parts to complete this page
++ * bit 30: I/O error occurred on this page
++ * bit 0 - 29: remaining parts to complete this page
+  */
+-#define Z_EROFS_PAGE_EIO			(1 << 31)
++#define Z_EROFS_PAGE_EIO			(1 << 30)
+ 
+ static inline void z_erofs_onlinepage_init(struct page *page)
+ {
+diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
+index b26f304baa52e..e5d20da585287 100644
+--- a/fs/ext4/fast_commit.c
++++ b/fs/ext4/fast_commit.c
+@@ -710,10 +710,10 @@ static u8 *ext4_fc_reserve_space(struct super_block *sb, int len, u32 *crc)
+ 	 * After allocating len, we should have space at least for a 0 byte
+ 	 * padding.
+ 	 */
+-	if (len + sizeof(struct ext4_fc_tl) > bsize)
++	if (len + EXT4_FC_TAG_BASE_LEN > bsize)
+ 		return NULL;
+ 
+-	if (bsize - off - 1 > len + sizeof(struct ext4_fc_tl)) {
++	if (bsize - off - 1 > len + EXT4_FC_TAG_BASE_LEN) {
+ 		/*
+ 		 * Only allocate from current buffer if we have enough space for
+ 		 * this request AND we have space to add a zero byte padding.
+@@ -730,10 +730,10 @@ static u8 *ext4_fc_reserve_space(struct super_block *sb, int len, u32 *crc)
+ 	/* Need to add PAD tag */
+ 	tl = (struct ext4_fc_tl *)(sbi->s_fc_bh->b_data + off);
+ 	tl->fc_tag = cpu_to_le16(EXT4_FC_TAG_PAD);
+-	pad_len = bsize - off - 1 - sizeof(struct ext4_fc_tl);
++	pad_len = bsize - off - 1 - EXT4_FC_TAG_BASE_LEN;
+ 	tl->fc_len = cpu_to_le16(pad_len);
+ 	if (crc)
+-		*crc = ext4_chksum(sbi, *crc, tl, sizeof(*tl));
++		*crc = ext4_chksum(sbi, *crc, tl, EXT4_FC_TAG_BASE_LEN);
+ 	if (pad_len > 0)
+ 		ext4_fc_memzero(sb, tl + 1, pad_len, crc);
+ 	ext4_fc_submit_bh(sb, false);
+@@ -775,7 +775,7 @@ static int ext4_fc_write_tail(struct super_block *sb, u32 crc)
+ 	 * ext4_fc_reserve_space takes care of allocating an extra block if
+ 	 * there's no enough space on this block for accommodating this tail.
+ 	 */
+-	dst = ext4_fc_reserve_space(sb, sizeof(tl) + sizeof(tail), &crc);
++	dst = ext4_fc_reserve_space(sb, EXT4_FC_TAG_BASE_LEN + sizeof(tail), &crc);
+ 	if (!dst)
+ 		return -ENOSPC;
+ 
+@@ -785,8 +785,8 @@ static int ext4_fc_write_tail(struct super_block *sb, u32 crc)
+ 	tl.fc_len = cpu_to_le16(bsize - off - 1 + sizeof(struct ext4_fc_tail));
+ 	sbi->s_fc_bytes = round_up(sbi->s_fc_bytes, bsize);
+ 
+-	ext4_fc_memcpy(sb, dst, &tl, sizeof(tl), &crc);
+-	dst += sizeof(tl);
++	ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, &crc);
++	dst += EXT4_FC_TAG_BASE_LEN;
+ 	tail.fc_tid = cpu_to_le32(sbi->s_journal->j_running_transaction->t_tid);
+ 	ext4_fc_memcpy(sb, dst, &tail.fc_tid, sizeof(tail.fc_tid), &crc);
+ 	dst += sizeof(tail.fc_tid);
+@@ -808,15 +808,15 @@ static bool ext4_fc_add_tlv(struct super_block *sb, u16 tag, u16 len, u8 *val,
+ 	struct ext4_fc_tl tl;
+ 	u8 *dst;
+ 
+-	dst = ext4_fc_reserve_space(sb, sizeof(tl) + len, crc);
++	dst = ext4_fc_reserve_space(sb, EXT4_FC_TAG_BASE_LEN + len, crc);
+ 	if (!dst)
+ 		return false;
+ 
+ 	tl.fc_tag = cpu_to_le16(tag);
+ 	tl.fc_len = cpu_to_le16(len);
+ 
+-	ext4_fc_memcpy(sb, dst, &tl, sizeof(tl), crc);
+-	ext4_fc_memcpy(sb, dst + sizeof(tl), val, len, crc);
++	ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc);
++	ext4_fc_memcpy(sb, dst + EXT4_FC_TAG_BASE_LEN, val, len, crc);
+ 
+ 	return true;
+ }
+@@ -828,8 +828,8 @@ static bool ext4_fc_add_dentry_tlv(struct super_block *sb, u32 *crc,
+ 	struct ext4_fc_dentry_info fcd;
+ 	struct ext4_fc_tl tl;
+ 	int dlen = fc_dentry->fcd_name.len;
+-	u8 *dst = ext4_fc_reserve_space(sb, sizeof(tl) + sizeof(fcd) + dlen,
+-					crc);
++	u8 *dst = ext4_fc_reserve_space(sb,
++			EXT4_FC_TAG_BASE_LEN + sizeof(fcd) + dlen, crc);
+ 
+ 	if (!dst)
+ 		return false;
+@@ -838,8 +838,8 @@ static bool ext4_fc_add_dentry_tlv(struct super_block *sb, u32 *crc,
+ 	fcd.fc_ino = cpu_to_le32(fc_dentry->fcd_ino);
+ 	tl.fc_tag = cpu_to_le16(fc_dentry->fcd_op);
+ 	tl.fc_len = cpu_to_le16(sizeof(fcd) + dlen);
+-	ext4_fc_memcpy(sb, dst, &tl, sizeof(tl), crc);
+-	dst += sizeof(tl);
++	ext4_fc_memcpy(sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc);
++	dst += EXT4_FC_TAG_BASE_LEN;
+ 	ext4_fc_memcpy(sb, dst, &fcd, sizeof(fcd), crc);
+ 	dst += sizeof(fcd);
+ 	ext4_fc_memcpy(sb, dst, fc_dentry->fcd_name.name, dlen, crc);
+@@ -876,13 +876,13 @@ static int ext4_fc_write_inode(struct inode *inode, u32 *crc)
+ 
+ 	ret = -ECANCELED;
+ 	dst = ext4_fc_reserve_space(inode->i_sb,
+-			sizeof(tl) + inode_len + sizeof(fc_inode.fc_ino), crc);
++		EXT4_FC_TAG_BASE_LEN + inode_len + sizeof(fc_inode.fc_ino), crc);
+ 	if (!dst)
+ 		goto err;
+ 
+-	if (!ext4_fc_memcpy(inode->i_sb, dst, &tl, sizeof(tl), crc))
++	if (!ext4_fc_memcpy(inode->i_sb, dst, &tl, EXT4_FC_TAG_BASE_LEN, crc))
+ 		goto err;
+-	dst += sizeof(tl);
++	dst += EXT4_FC_TAG_BASE_LEN;
+ 	if (!ext4_fc_memcpy(inode->i_sb, dst, &fc_inode, sizeof(fc_inode), crc))
+ 		goto err;
+ 	dst += sizeof(fc_inode);
+@@ -1346,7 +1346,7 @@ struct dentry_info_args {
+ };
+ 
+ static inline void tl_to_darg(struct dentry_info_args *darg,
+-			      struct  ext4_fc_tl *tl, u8 *val)
++			      struct ext4_fc_tl *tl, u8 *val)
+ {
+ 	struct ext4_fc_dentry_info fcd;
+ 
+@@ -1355,8 +1355,14 @@ static inline void tl_to_darg(struct dentry_info_args *darg,
+ 	darg->parent_ino = le32_to_cpu(fcd.fc_parent_ino);
+ 	darg->ino = le32_to_cpu(fcd.fc_ino);
+ 	darg->dname = val + offsetof(struct ext4_fc_dentry_info, fc_dname);
+-	darg->dname_len = le16_to_cpu(tl->fc_len) -
+-		sizeof(struct ext4_fc_dentry_info);
++	darg->dname_len = tl->fc_len - sizeof(struct ext4_fc_dentry_info);
++}
++
++static inline void ext4_fc_get_tl(struct ext4_fc_tl *tl, u8 *val)
++{
++	memcpy(tl, val, EXT4_FC_TAG_BASE_LEN);
++	tl->fc_len = le16_to_cpu(tl->fc_len);
++	tl->fc_tag = le16_to_cpu(tl->fc_tag);
+ }
+ 
+ /* Unlink replay function */
+@@ -1521,7 +1527,7 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
+ 	struct ext4_inode *raw_fc_inode;
+ 	struct inode *inode = NULL;
+ 	struct ext4_iloc iloc;
+-	int inode_len, ino, ret, tag = le16_to_cpu(tl->fc_tag);
++	int inode_len, ino, ret, tag = tl->fc_tag;
+ 	struct ext4_extent_header *eh;
+ 
+ 	memcpy(&fc_inode, val, sizeof(fc_inode));
+@@ -1546,7 +1552,7 @@ static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
+ 	if (ret)
+ 		goto out;
+ 
+-	inode_len = le16_to_cpu(tl->fc_len) - sizeof(struct ext4_fc_inode);
++	inode_len = tl->fc_len - sizeof(struct ext4_fc_inode);
+ 	raw_inode = ext4_raw_inode(&iloc);
+ 
+ 	memcpy(raw_inode, raw_fc_inode, offsetof(struct ext4_inode, i_block));
+@@ -1980,6 +1986,34 @@ void ext4_fc_replay_cleanup(struct super_block *sb)
+ 	kfree(sbi->s_fc_replay_state.fc_modified_inodes);
+ }
+ 
++static inline bool ext4_fc_tag_len_isvalid(struct ext4_fc_tl *tl,
++					   u8 *val, u8 *end)
++{
++	if (val + tl->fc_len > end)
++		return false;
++
++	/* Here only check ADD_RANGE/TAIL/HEAD which will read data when do
++	 * journal rescan before do CRC check. Other tags length check will
++	 * rely on CRC check.
++	 */
++	switch (tl->fc_tag) {
++	case EXT4_FC_TAG_ADD_RANGE:
++		return (sizeof(struct ext4_fc_add_range) == tl->fc_len);
++	case EXT4_FC_TAG_TAIL:
++		return (sizeof(struct ext4_fc_tail) <= tl->fc_len);
++	case EXT4_FC_TAG_HEAD:
++		return (sizeof(struct ext4_fc_head) == tl->fc_len);
++	case EXT4_FC_TAG_DEL_RANGE:
++	case EXT4_FC_TAG_LINK:
++	case EXT4_FC_TAG_UNLINK:
++	case EXT4_FC_TAG_CREAT:
++	case EXT4_FC_TAG_INODE:
++	case EXT4_FC_TAG_PAD:
++	default:
++		return true;
++	}
++}
++
+ /*
+  * Recovery Scan phase handler
+  *
+@@ -2036,12 +2070,18 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ 	}
+ 
+ 	state->fc_replay_expected_off++;
+-	for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) {
+-		memcpy(&tl, cur, sizeof(tl));
+-		val = cur + sizeof(tl);
++	for (cur = start; cur < end - EXT4_FC_TAG_BASE_LEN;
++	     cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) {
++		ext4_fc_get_tl(&tl, cur);
++		val = cur + EXT4_FC_TAG_BASE_LEN;
++		if (!ext4_fc_tag_len_isvalid(&tl, val, end)) {
++			ret = state->fc_replay_num_tags ?
++				JBD2_FC_REPLAY_STOP : -ECANCELED;
++			goto out_err;
++		}
+ 		ext4_debug("Scan phase, tag:%s, blk %lld\n",
+-			  tag2str(le16_to_cpu(tl.fc_tag)), bh->b_blocknr);
+-		switch (le16_to_cpu(tl.fc_tag)) {
++			   tag2str(tl.fc_tag), bh->b_blocknr);
++		switch (tl.fc_tag) {
+ 		case EXT4_FC_TAG_ADD_RANGE:
+ 			memcpy(&ext, val, sizeof(ext));
+ 			ex = (struct ext4_extent *)&ext.fc_ex;
+@@ -2061,13 +2101,13 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ 		case EXT4_FC_TAG_PAD:
+ 			state->fc_cur_tag++;
+ 			state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
+-					sizeof(tl) + le16_to_cpu(tl.fc_len));
++				EXT4_FC_TAG_BASE_LEN + tl.fc_len);
+ 			break;
+ 		case EXT4_FC_TAG_TAIL:
+ 			state->fc_cur_tag++;
+ 			memcpy(&tail, val, sizeof(tail));
+ 			state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
+-						sizeof(tl) +
++						EXT4_FC_TAG_BASE_LEN +
+ 						offsetof(struct ext4_fc_tail,
+ 						fc_crc));
+ 			if (le32_to_cpu(tail.fc_tid) == expected_tid &&
+@@ -2094,7 +2134,7 @@ static int ext4_fc_replay_scan(journal_t *journal,
+ 			}
+ 			state->fc_cur_tag++;
+ 			state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
+-					    sizeof(tl) + le16_to_cpu(tl.fc_len));
++				EXT4_FC_TAG_BASE_LEN + tl.fc_len);
+ 			break;
+ 		default:
+ 			ret = state->fc_replay_num_tags ?
+@@ -2149,19 +2189,20 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
+ 	start = (u8 *)bh->b_data;
+ 	end = (__u8 *)bh->b_data + journal->j_blocksize - 1;
+ 
+-	for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) {
+-		memcpy(&tl, cur, sizeof(tl));
+-		val = cur + sizeof(tl);
++	for (cur = start; cur < end - EXT4_FC_TAG_BASE_LEN;
++	     cur = cur + EXT4_FC_TAG_BASE_LEN + tl.fc_len) {
++		ext4_fc_get_tl(&tl, cur);
++		val = cur + EXT4_FC_TAG_BASE_LEN;
+ 
+ 		if (state->fc_replay_num_tags == 0) {
+ 			ret = JBD2_FC_REPLAY_STOP;
+ 			ext4_fc_set_bitmaps_and_counters(sb);
+ 			break;
+ 		}
+-		ext4_debug("Replay phase, tag:%s\n",
+-				tag2str(le16_to_cpu(tl.fc_tag)));
++
++		ext4_debug("Replay phase, tag:%s\n", tag2str(tl.fc_tag));
+ 		state->fc_replay_num_tags--;
+-		switch (le16_to_cpu(tl.fc_tag)) {
++		switch (tl.fc_tag) {
+ 		case EXT4_FC_TAG_LINK:
+ 			ret = ext4_fc_replay_link(sb, &tl, val);
+ 			break;
+@@ -2182,19 +2223,18 @@ static int ext4_fc_replay(journal_t *journal, struct buffer_head *bh,
+ 			break;
+ 		case EXT4_FC_TAG_PAD:
+ 			trace_ext4_fc_replay(sb, EXT4_FC_TAG_PAD, 0,
+-					     le16_to_cpu(tl.fc_len), 0);
++					     tl.fc_len, 0);
+ 			break;
+ 		case EXT4_FC_TAG_TAIL:
+-			trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL, 0,
+-					     le16_to_cpu(tl.fc_len), 0);
++			trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL,
++					     0, tl.fc_len, 0);
+ 			memcpy(&tail, val, sizeof(tail));
+ 			WARN_ON(le32_to_cpu(tail.fc_tid) != expected_tid);
+ 			break;
+ 		case EXT4_FC_TAG_HEAD:
+ 			break;
+ 		default:
+-			trace_ext4_fc_replay(sb, le16_to_cpu(tl.fc_tag), 0,
+-					     le16_to_cpu(tl.fc_len), 0);
++			trace_ext4_fc_replay(sb, tl.fc_tag, 0, tl.fc_len, 0);
+ 			ret = -ECANCELED;
+ 			break;
+ 		}
+diff --git a/fs/ext4/fast_commit.h b/fs/ext4/fast_commit.h
+index 1db12847a83b6..a6154c3ed1357 100644
+--- a/fs/ext4/fast_commit.h
++++ b/fs/ext4/fast_commit.h
+@@ -70,6 +70,9 @@ struct ext4_fc_tail {
+ 	__le32 fc_crc;
+ };
+ 
++/* Tag base length */
++#define EXT4_FC_TAG_BASE_LEN (sizeof(struct ext4_fc_tl))
++
+ /*
+  * Fast commit status codes
+  */
+diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
+index 961d1cf54388e..05f32989bad6f 100644
+--- a/fs/ocfs2/namei.c
++++ b/fs/ocfs2/namei.c
+@@ -232,6 +232,7 @@ static int ocfs2_mknod(struct user_namespace *mnt_userns,
+ 	handle_t *handle = NULL;
+ 	struct ocfs2_super *osb;
+ 	struct ocfs2_dinode *dirfe;
++	struct ocfs2_dinode *fe = NULL;
+ 	struct buffer_head *new_fe_bh = NULL;
+ 	struct inode *inode = NULL;
+ 	struct ocfs2_alloc_context *inode_ac = NULL;
+@@ -382,6 +383,7 @@ static int ocfs2_mknod(struct user_namespace *mnt_userns,
+ 		goto leave;
+ 	}
+ 
++	fe = (struct ocfs2_dinode *) new_fe_bh->b_data;
+ 	if (S_ISDIR(mode)) {
+ 		status = ocfs2_fill_new_dir(osb, handle, dir, inode,
+ 					    new_fe_bh, data_ac, meta_ac);
+@@ -454,8 +456,11 @@ roll_back:
+ leave:
+ 	if (status < 0 && did_quota_inode)
+ 		dquot_free_inode(inode);
+-	if (handle)
++	if (handle) {
++		if (status < 0 && fe)
++			ocfs2_set_links_count(fe, 0);
+ 		ocfs2_commit_trans(osb, handle);
++	}
+ 
+ 	ocfs2_inode_unlock(dir, 1);
+ 	if (did_block_signals)
+@@ -632,18 +637,9 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
+ 		return status;
+ 	}
+ 
+-	status = __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh,
++	return __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh,
+ 				    parent_fe_bh, handle, inode_ac,
+ 				    fe_blkno, suballoc_loc, suballoc_bit);
+-	if (status < 0) {
+-		u64 bg_blkno = ocfs2_which_suballoc_group(fe_blkno, suballoc_bit);
+-		int tmp = ocfs2_free_suballoc_bits(handle, inode_ac->ac_inode,
+-				inode_ac->ac_bh, suballoc_bit, bg_blkno, 1);
+-		if (tmp)
+-			mlog_errno(tmp);
+-	}
+-
+-	return status;
+ }
+ 
+ static int ocfs2_mkdir(struct user_namespace *mnt_userns,
+@@ -2028,8 +2024,11 @@ bail:
+ 					ocfs2_clusters_to_bytes(osb->sb, 1));
+ 	if (status < 0 && did_quota_inode)
+ 		dquot_free_inode(inode);
+-	if (handle)
++	if (handle) {
++		if (status < 0 && fe)
++			ocfs2_set_links_count(fe, 0);
+ 		ocfs2_commit_trans(osb, handle);
++	}
+ 
+ 	ocfs2_inode_unlock(dir, 1);
+ 	if (did_block_signals)
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index 4e0023643f8be..1e7bbc0873a42 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -969,7 +969,7 @@ static int show_smaps_rollup(struct seq_file *m, void *v)
+ 		vma = vma->vm_next;
+ 	}
+ 
+-	show_vma_header_prefix(m, priv->mm->mmap->vm_start,
++	show_vma_header_prefix(m, priv->mm->mmap ? priv->mm->mmap->vm_start : 0,
+ 			       last_vma_end, 0, 0, 0, 0);
+ 	seq_pad(m, ' ');
+ 	seq_puts(m, "[rollup]\n");
+diff --git a/include/linux/dsa/tag_qca.h b/include/linux/dsa/tag_qca.h
+index 50be7cbd93a5b..b1b5720d89a59 100644
+--- a/include/linux/dsa/tag_qca.h
++++ b/include/linux/dsa/tag_qca.h
+@@ -61,9 +61,9 @@ struct sk_buff;
+ 
+ /* Special struct emulating a Ethernet header */
+ struct qca_mgmt_ethhdr {
+-	u32 command;		/* command bit 31:0 */
+-	u32 seq;		/* seq 63:32 */
+-	u32 mdio_data;		/* first 4byte mdio */
++	__le32 command;		/* command bit 31:0 */
++	__le32 seq;		/* seq 63:32 */
++	__le32 mdio_data;		/* first 4byte mdio */
+ 	__be16 hdr;		/* qca hdr */
+ } __packed;
+ 
+@@ -73,7 +73,7 @@ enum mdio_cmd {
+ };
+ 
+ struct mib_ethhdr {
+-	u32 data[3];		/* first 3 mib counter */
++	__le32 data[3];		/* first 3 mib counter */
+ 	__be16 hdr;		/* qca hdr */
+ } __packed;
+ 
+diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
+index f4519d3689e10..7a40f9bdc173e 100644
+--- a/include/linux/kvm_host.h
++++ b/include/linux/kvm_host.h
+@@ -1391,6 +1391,8 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
+ 			    struct kvm_enable_cap *cap);
+ long kvm_arch_vm_ioctl(struct file *filp,
+ 		       unsigned int ioctl, unsigned long arg);
++long kvm_arch_vm_compat_ioctl(struct file *filp, unsigned int ioctl,
++			      unsigned long arg);
+ 
+ int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu);
+ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu);
+diff --git a/include/linux/phylink.h b/include/linux/phylink.h
+index 6d06896fc20d8..a3adf7fe7eaf4 100644
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -88,6 +88,7 @@ enum phylink_op_type {
+  *	(See commit 7cceb599d15d ("net: phylink: avoid mac_config calls")
+  * @poll_fixed_state: if true, starts link_poll,
+  *		      if MAC link is at %MLO_AN_FIXED mode.
++ * @mac_managed_pm: if true, indicate the MAC driver is responsible for PHY PM.
+  * @ovr_an_inband: if true, override PCS to MLO_AN_INBAND
+  * @get_fixed_state: callback to execute to determine the fixed link state,
+  *		     if MAC link is at %MLO_AN_FIXED mode.
+@@ -100,6 +101,7 @@ struct phylink_config {
+ 	enum phylink_op_type type;
+ 	bool legacy_pre_march2020;
+ 	bool poll_fixed_state;
++	bool mac_managed_pm;
+ 	bool ovr_an_inband;
+ 	void (*get_fixed_state)(struct phylink_config *config,
+ 				struct phylink_link_state *state);
+diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
+index ec693fe7c5539..f2958fb5ae08b 100644
+--- a/include/net/sch_generic.h
++++ b/include/net/sch_generic.h
+@@ -1137,7 +1137,6 @@ static inline void __qdisc_reset_queue(struct qdisc_skb_head *qh)
+ static inline void qdisc_reset_queue(struct Qdisc *sch)
+ {
+ 	__qdisc_reset_queue(&sch->q);
+-	sch->qstats.backlog = 0;
+ }
+ 
+ static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
+diff --git a/include/net/sock_reuseport.h b/include/net/sock_reuseport.h
+index 473b0b0fa4abc..efc9085c68927 100644
+--- a/include/net/sock_reuseport.h
++++ b/include/net/sock_reuseport.h
+@@ -43,21 +43,20 @@ struct sock *reuseport_migrate_sock(struct sock *sk,
+ extern int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog);
+ extern int reuseport_detach_prog(struct sock *sk);
+ 
+-static inline bool reuseport_has_conns(struct sock *sk, bool set)
++static inline bool reuseport_has_conns(struct sock *sk)
+ {
+ 	struct sock_reuseport *reuse;
+ 	bool ret = false;
+ 
+ 	rcu_read_lock();
+ 	reuse = rcu_dereference(sk->sk_reuseport_cb);
+-	if (reuse) {
+-		if (set)
+-			reuse->has_conns = 1;
+-		ret = reuse->has_conns;
+-	}
++	if (reuse && reuse->has_conns)
++		ret = true;
+ 	rcu_read_unlock();
+ 
+ 	return ret;
+ }
+ 
++void reuseport_has_conns_set(struct sock *sk);
++
+ #endif  /* _SOCK_REUSEPORT_H */
+diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
+index 45809ae6f64ef..5121b20a91936 100644
+--- a/io_uring/io_uring.h
++++ b/io_uring/io_uring.h
+@@ -229,12 +229,12 @@ static inline unsigned int io_sqring_entries(struct io_ring_ctx *ctx)
+ 
+ static inline bool io_run_task_work(void)
+ {
+-	if (test_thread_flag(TIF_NOTIFY_SIGNAL)) {
++	if (task_work_pending(current)) {
++		if (test_thread_flag(TIF_NOTIFY_SIGNAL))
++			clear_notify_signal();
+ 		__set_current_state(TASK_RUNNING);
+-		clear_notify_signal();
+-		if (task_work_pending(current))
+-			task_work_run();
+-		return true;
++		task_work_run();
++		return 1;
+ 	}
+ 
+ 	return false;
+diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c
+index 4a7e5d030c782..90d2fc6fd80e4 100644
+--- a/io_uring/msg_ring.c
++++ b/io_uring/msg_ring.c
+@@ -95,6 +95,9 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags)
+ 
+ 	msg->src_fd = array_index_nospec(msg->src_fd, ctx->nr_user_files);
+ 	file_ptr = io_fixed_file_slot(&ctx->file_table, msg->src_fd)->file_ptr;
++	if (!file_ptr)
++		goto out_unlock;
++
+ 	src_file = (struct file *) (file_ptr & FFS_MASK);
+ 	get_file(src_file);
+ 
+diff --git a/io_uring/rw.c b/io_uring/rw.c
+index 60c08a944e2fb..93d7cb5eb9fe5 100644
+--- a/io_uring/rw.c
++++ b/io_uring/rw.c
+@@ -192,8 +192,6 @@ static void io_req_io_end(struct io_kiocb *req)
+ {
+ 	struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
+ 
+-	WARN_ON(!in_task());
+-
+ 	if (rw->kiocb.ki_flags & IOCB_WRITE) {
+ 		kiocb_end_write(req);
+ 		fsnotify_modify(req->file);
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 513b523ba75b3..ecc197d24efb7 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -2928,11 +2928,11 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
+ 		page = alloc_buddy_huge_page_with_mpol(h, vma, addr);
+ 		if (!page)
+ 			goto out_uncharge_cgroup;
++		spin_lock_irq(&hugetlb_lock);
+ 		if (!avoid_reserve && vma_has_reserves(vma, gbl_chg)) {
+ 			SetHPageRestoreReserve(page);
+ 			h->resv_huge_pages--;
+ 		}
+-		spin_lock_irq(&hugetlb_lock);
+ 		list_add(&page->lru, &h->hugepage_activelist);
+ 		/* Fall through */
+ 	}
+diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c
+index 829db9eba0cb9..aaf64b9539150 100644
+--- a/net/atm/mpoa_proc.c
++++ b/net/atm/mpoa_proc.c
+@@ -219,11 +219,12 @@ static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
+ 	if (!page)
+ 		return -ENOMEM;
+ 
+-	for (p = page, len = 0; len < nbytes; p++, len++) {
++	for (p = page, len = 0; len < nbytes; p++) {
+ 		if (get_user(*p, buff++)) {
+ 			free_page((unsigned long)page);
+ 			return -EFAULT;
+ 		}
++		len += 1;
+ 		if (*p == '\0' || *p == '\n')
+ 			break;
+ 	}
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 56c8b0921c9fd..2c14f48d24573 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -5136,11 +5136,13 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
+ 	case TC_ACT_SHOT:
+ 		mini_qdisc_qstats_cpu_drop(miniq);
+ 		kfree_skb_reason(skb, SKB_DROP_REASON_TC_INGRESS);
++		*ret = NET_RX_DROP;
+ 		return NULL;
+ 	case TC_ACT_STOLEN:
+ 	case TC_ACT_QUEUED:
+ 	case TC_ACT_TRAP:
+ 		consume_skb(skb);
++		*ret = NET_RX_SUCCESS;
+ 		return NULL;
+ 	case TC_ACT_REDIRECT:
+ 		/* skb_mac_header check was done by cls/act_bpf, so
+@@ -5153,8 +5155,10 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
+ 			*another = true;
+ 			break;
+ 		}
++		*ret = NET_RX_SUCCESS;
+ 		return NULL;
+ 	case TC_ACT_CONSUMED:
++		*ret = NET_RX_SUCCESS;
+ 		return NULL;
+ 	default:
+ 		break;
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index ca70525621c71..1efdc47a999b4 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -500,11 +500,11 @@ bool sk_msg_is_readable(struct sock *sk)
+ }
+ EXPORT_SYMBOL_GPL(sk_msg_is_readable);
+ 
+-static struct sk_msg *alloc_sk_msg(void)
++static struct sk_msg *alloc_sk_msg(gfp_t gfp)
+ {
+ 	struct sk_msg *msg;
+ 
+-	msg = kzalloc(sizeof(*msg), __GFP_NOWARN | GFP_KERNEL);
++	msg = kzalloc(sizeof(*msg), gfp | __GFP_NOWARN);
+ 	if (unlikely(!msg))
+ 		return NULL;
+ 	sg_init_marker(msg->sg.data, NR_MSG_FRAG_IDS);
+@@ -520,7 +520,7 @@ static struct sk_msg *sk_psock_create_ingress_msg(struct sock *sk,
+ 	if (!sk_rmem_schedule(sk, skb, skb->truesize))
+ 		return NULL;
+ 
+-	return alloc_sk_msg();
++	return alloc_sk_msg(GFP_KERNEL);
+ }
+ 
+ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
+@@ -597,7 +597,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
+ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb,
+ 				     u32 off, u32 len)
+ {
+-	struct sk_msg *msg = alloc_sk_msg();
++	struct sk_msg *msg = alloc_sk_msg(GFP_ATOMIC);
+ 	struct sock *sk = psock->sk;
+ 	int err;
+ 
+diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c
+index 5daa1fa542490..fb90e1e00773b 100644
+--- a/net/core/sock_reuseport.c
++++ b/net/core/sock_reuseport.c
+@@ -21,6 +21,22 @@ static DEFINE_IDA(reuseport_ida);
+ static int reuseport_resurrect(struct sock *sk, struct sock_reuseport *old_reuse,
+ 			       struct sock_reuseport *reuse, bool bind_inany);
+ 
++void reuseport_has_conns_set(struct sock *sk)
++{
++	struct sock_reuseport *reuse;
++
++	if (!rcu_access_pointer(sk->sk_reuseport_cb))
++		return;
++
++	spin_lock_bh(&reuseport_lock);
++	reuse = rcu_dereference_protected(sk->sk_reuseport_cb,
++					  lockdep_is_held(&reuseport_lock));
++	if (likely(reuse))
++		reuse->has_conns = 1;
++	spin_unlock_bh(&reuseport_lock);
++}
++EXPORT_SYMBOL(reuseport_has_conns_set);
++
+ static int reuseport_sock_index(struct sock *sk,
+ 				const struct sock_reuseport *reuse,
+ 				bool closed)
+diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
+index 5bf357734b113..a50429a62f744 100644
+--- a/net/hsr/hsr_forward.c
++++ b/net/hsr/hsr_forward.c
+@@ -150,15 +150,15 @@ struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame,
+ 				       struct hsr_port *port)
+ {
+ 	if (!frame->skb_std) {
+-		if (frame->skb_hsr) {
++		if (frame->skb_hsr)
+ 			frame->skb_std =
+ 				create_stripped_skb_hsr(frame->skb_hsr, frame);
+-		} else {
+-			/* Unexpected */
+-			WARN_ONCE(1, "%s:%d: Unexpected frame received (port_src %s)\n",
+-				  __FILE__, __LINE__, port->dev->name);
++		else
++			netdev_warn_once(port->dev,
++					 "Unexpected frame received in hsr_get_untagged_frame()\n");
++
++		if (!frame->skb_std)
+ 			return NULL;
+-		}
+ 	}
+ 
+ 	return skb_clone(frame->skb_std, GFP_ATOMIC);
+diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
+index 405a8c2aea641..5e66add7befac 100644
+--- a/net/ipv4/datagram.c
++++ b/net/ipv4/datagram.c
+@@ -70,7 +70,7 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
+ 	}
+ 	inet->inet_daddr = fl4->daddr;
+ 	inet->inet_dport = usin->sin_port;
+-	reuseport_has_conns(sk, true);
++	reuseport_has_conns_set(sk);
+ 	sk->sk_state = TCP_ESTABLISHED;
+ 	sk_set_txhash(sk);
+ 	inet->inet_id = prandom_u32();
+diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c
+index 8cd3224d913e0..26b3b0e2adcd7 100644
+--- a/net/ipv4/netfilter/ipt_rpfilter.c
++++ b/net/ipv4/netfilter/ipt_rpfilter.c
+@@ -78,7 +78,8 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
+ 	flow.flowi4_mark = info->flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0;
+ 	flow.flowi4_tos = iph->tos & IPTOS_RT_MASK;
+ 	flow.flowi4_scope = RT_SCOPE_UNIVERSE;
+-	flow.flowi4_oif = l3mdev_master_ifindex_rcu(xt_in(par));
++	flow.flowi4_l3mdev = l3mdev_master_ifindex_rcu(xt_in(par));
++	flow.flowi4_uid = sock_net_uid(xt_net(par), NULL);
+ 
+ 	return rpfilter_lookup_reverse(xt_net(par), &flow, xt_in(par), info->flags) ^ invert;
+ }
+diff --git a/net/ipv4/netfilter/nft_fib_ipv4.c b/net/ipv4/netfilter/nft_fib_ipv4.c
+index 7ade04ff972d7..fc65d69f23e16 100644
+--- a/net/ipv4/netfilter/nft_fib_ipv4.c
++++ b/net/ipv4/netfilter/nft_fib_ipv4.c
+@@ -65,6 +65,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ 	struct flowi4 fl4 = {
+ 		.flowi4_scope = RT_SCOPE_UNIVERSE,
+ 		.flowi4_iif = LOOPBACK_IFINDEX,
++		.flowi4_uid = sock_net_uid(nft_net(pkt), NULL),
+ 	};
+ 	const struct net_device *oif;
+ 	const struct net_device *found;
+@@ -84,7 +85,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ 		oif = NULL;
+ 
+ 	if (priv->flags & NFTA_FIB_F_IIF)
+-		fl4.flowi4_oif = l3mdev_master_ifindex_rcu(oif);
++		fl4.flowi4_l3mdev = l3mdev_master_ifindex_rcu(oif);
+ 
+ 	if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
+ 	    nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 516b11c136daf..d9099754ac69d 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -448,7 +448,7 @@ static struct sock *udp4_lib_lookup2(struct net *net,
+ 			result = lookup_reuseport(net, sk, skb,
+ 						  saddr, sport, daddr, hnum);
+ 			/* Fall back to scoring if group has connections */
+-			if (result && !reuseport_has_conns(sk, false))
++			if (result && !reuseport_has_conns(sk))
+ 				return result;
+ 
+ 			result = result ? : sk;
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 10ce86bf228e1..d5967cba5b568 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -7214,9 +7214,11 @@ err_reg_dflt:
+ 	__addrconf_sysctl_unregister(net, all, NETCONFA_IFINDEX_ALL);
+ err_reg_all:
+ 	kfree(dflt);
++	net->ipv6.devconf_dflt = NULL;
+ #endif
+ err_alloc_dflt:
+ 	kfree(all);
++	net->ipv6.devconf_all = NULL;
+ err_alloc_all:
+ 	kfree(net->ipv6.inet6_addr_lst);
+ err_alloc_addr:
+diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
+index df665d4e8f0f1..5ecb56522f9d6 100644
+--- a/net/ipv6/datagram.c
++++ b/net/ipv6/datagram.c
+@@ -256,7 +256,7 @@ ipv4_connected:
+ 		goto out;
+ 	}
+ 
+-	reuseport_has_conns(sk, true);
++	reuseport_has_conns_set(sk);
+ 	sk->sk_state = TCP_ESTABLISHED;
+ 	sk_set_txhash(sk);
+ out:
+diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c
+index d800801a5dd27..a01d9b842bd07 100644
+--- a/net/ipv6/netfilter/ip6t_rpfilter.c
++++ b/net/ipv6/netfilter/ip6t_rpfilter.c
+@@ -37,8 +37,10 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
+ 	bool ret = false;
+ 	struct flowi6 fl6 = {
+ 		.flowi6_iif = LOOPBACK_IFINDEX,
++		.flowi6_l3mdev = l3mdev_master_ifindex_rcu(dev),
+ 		.flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK,
+ 		.flowi6_proto = iph->nexthdr,
++		.flowi6_uid = sock_net_uid(net, NULL),
+ 		.daddr = iph->saddr,
+ 	};
+ 	int lookup_flags;
+@@ -55,9 +57,7 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
+ 	if (rpfilter_addr_linklocal(&iph->saddr)) {
+ 		lookup_flags |= RT6_LOOKUP_F_IFACE;
+ 		fl6.flowi6_oif = dev->ifindex;
+-	/* Set flowi6_oif for vrf devices to lookup route in l3mdev domain. */
+-	} else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev) ||
+-		  (flags & XT_RPFILTER_LOOSE) == 0)
++	} else if ((flags & XT_RPFILTER_LOOSE) == 0)
+ 		fl6.flowi6_oif = dev->ifindex;
+ 
+ 	rt = (void *)ip6_route_lookup(net, &fl6, skb, lookup_flags);
+@@ -72,9 +72,7 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
+ 		goto out;
+ 	}
+ 
+-	if (rt->rt6i_idev->dev == dev ||
+-	    l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) == dev->ifindex ||
+-	    (flags & XT_RPFILTER_LOOSE))
++	if (rt->rt6i_idev->dev == dev || (flags & XT_RPFILTER_LOOSE))
+ 		ret = true;
+  out:
+ 	ip6_rt_put(rt);
+diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c
+index 1d7e520d9966c..36dc14b34388c 100644
+--- a/net/ipv6/netfilter/nft_fib_ipv6.c
++++ b/net/ipv6/netfilter/nft_fib_ipv6.c
+@@ -41,9 +41,8 @@ static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv,
+ 	if (ipv6_addr_type(&fl6->daddr) & IPV6_ADDR_LINKLOCAL) {
+ 		lookup_flags |= RT6_LOOKUP_F_IFACE;
+ 		fl6->flowi6_oif = get_ifindex(dev ? dev : pkt->skb->dev);
+-	} else if ((priv->flags & NFTA_FIB_F_IIF) &&
+-		   (netif_is_l3_master(dev) || netif_is_l3_slave(dev))) {
+-		fl6->flowi6_oif = dev->ifindex;
++	} else if (priv->flags & NFTA_FIB_F_IIF) {
++		fl6->flowi6_l3mdev = l3mdev_master_ifindex_rcu(dev);
+ 	}
+ 
+ 	if (ipv6_addr_type(&fl6->saddr) & IPV6_ADDR_UNICAST)
+@@ -67,6 +66,7 @@ static u32 __nft_fib6_eval_type(const struct nft_fib *priv,
+ 	struct flowi6 fl6 = {
+ 		.flowi6_iif = LOOPBACK_IFINDEX,
+ 		.flowi6_proto = pkt->tprot,
++		.flowi6_uid = sock_net_uid(nft_net(pkt), NULL),
+ 	};
+ 	u32 ret = 0;
+ 
+@@ -164,6 +164,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ 	struct flowi6 fl6 = {
+ 		.flowi6_iif = LOOPBACK_IFINDEX,
+ 		.flowi6_proto = pkt->tprot,
++		.flowi6_uid = sock_net_uid(nft_net(pkt), NULL),
+ 	};
+ 	struct rt6_info *rt;
+ 	int lookup_flags;
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index 3366d6a77ff29..fb667e02e9760 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -182,7 +182,7 @@ static struct sock *udp6_lib_lookup2(struct net *net,
+ 			result = lookup_reuseport(net, sk, skb,
+ 						  saddr, sport, daddr, hnum);
+ 			/* Fall back to scoring if group has connections */
+-			if (result && !reuseport_has_conns(sk, false))
++			if (result && !reuseport_has_conns(sk))
+ 				return result;
+ 
+ 			result = result ? : sk;
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 63c70141b3e5d..5897afd124668 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5865,8 +5865,9 @@ static bool nft_setelem_valid_key_end(const struct nft_set *set,
+ 			  (NFT_SET_CONCAT | NFT_SET_INTERVAL)) {
+ 		if (flags & NFT_SET_ELEM_INTERVAL_END)
+ 			return false;
+-		if (!nla[NFTA_SET_ELEM_KEY_END] &&
+-		    !(flags & NFT_SET_ELEM_CATCHALL))
++
++		if (nla[NFTA_SET_ELEM_KEY_END] &&
++		    flags & NFT_SET_ELEM_CATCHALL)
+ 			return false;
+ 	} else {
+ 		if (nla[NFTA_SET_ELEM_KEY_END])
+diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
+index bf87b50837a84..67ee8ae3f310b 100644
+--- a/net/sched/sch_api.c
++++ b/net/sched/sch_api.c
+@@ -1081,12 +1081,13 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
+ 
+ skip:
+ 		if (!ingress) {
+-			notify_and_destroy(net, skb, n, classid,
+-					   rtnl_dereference(dev->qdisc), new);
++			old = rtnl_dereference(dev->qdisc);
+ 			if (new && !new->ops->attach)
+ 				qdisc_refcount_inc(new);
+ 			rcu_assign_pointer(dev->qdisc, new ? : &noop_qdisc);
+ 
++			notify_and_destroy(net, skb, n, classid, old, new);
++
+ 			if (new && new->ops->attach)
+ 				new->ops->attach(new);
+ 		} else {
+diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
+index 4c8e994cf0a53..816fd0d7ba38a 100644
+--- a/net/sched/sch_atm.c
++++ b/net/sched/sch_atm.c
+@@ -577,7 +577,6 @@ static void atm_tc_reset(struct Qdisc *sch)
+ 	pr_debug("atm_tc_reset(sch %p,[qdisc %p])\n", sch, p);
+ 	list_for_each_entry(flow, &p->flows, list)
+ 		qdisc_reset(flow->q);
+-	sch->q.qlen = 0;
+ }
+ 
+ static void atm_tc_destroy(struct Qdisc *sch)
+diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
+index a43a58a73d096..9530d65e6002a 100644
+--- a/net/sched/sch_cake.c
++++ b/net/sched/sch_cake.c
+@@ -2224,8 +2224,12 @@ retry:
+ 
+ static void cake_reset(struct Qdisc *sch)
+ {
++	struct cake_sched_data *q = qdisc_priv(sch);
+ 	u32 c;
+ 
++	if (!q->tins)
++		return;
++
+ 	for (c = 0; c < CAKE_MAX_TINS; c++)
+ 		cake_clear_tin(sch, c);
+ }
+diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
+index 91a0dc463c482..ba99ce05cd527 100644
+--- a/net/sched/sch_cbq.c
++++ b/net/sched/sch_cbq.c
+@@ -975,7 +975,6 @@ cbq_reset(struct Qdisc *sch)
+ 			cl->cpriority = cl->priority;
+ 		}
+ 	}
+-	sch->q.qlen = 0;
+ }
+ 
+ 
+diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
+index 2adbd945bf15a..25d2daaa81227 100644
+--- a/net/sched/sch_choke.c
++++ b/net/sched/sch_choke.c
+@@ -315,8 +315,6 @@ static void choke_reset(struct Qdisc *sch)
+ 		rtnl_qdisc_drop(skb, sch);
+ 	}
+ 
+-	sch->q.qlen = 0;
+-	sch->qstats.backlog = 0;
+ 	if (q->tab)
+ 		memset(q->tab, 0, (q->tab_mask + 1) * sizeof(struct sk_buff *));
+ 	q->head = q->tail = 0;
+diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
+index 18e4f7a0b2912..4e5b1cf11b858 100644
+--- a/net/sched/sch_drr.c
++++ b/net/sched/sch_drr.c
+@@ -441,8 +441,6 @@ static void drr_reset_qdisc(struct Qdisc *sch)
+ 			qdisc_reset(cl->qdisc);
+ 		}
+ 	}
+-	sch->qstats.backlog = 0;
+-	sch->q.qlen = 0;
+ }
+ 
+ static void drr_destroy_qdisc(struct Qdisc *sch)
+diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
+index 4c100d1052699..7da6dc38a3828 100644
+--- a/net/sched/sch_dsmark.c
++++ b/net/sched/sch_dsmark.c
+@@ -409,8 +409,6 @@ static void dsmark_reset(struct Qdisc *sch)
+ 	pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p);
+ 	if (p->q)
+ 		qdisc_reset(p->q);
+-	sch->qstats.backlog = 0;
+-	sch->q.qlen = 0;
+ }
+ 
+ static void dsmark_destroy(struct Qdisc *sch)
+diff --git a/net/sched/sch_etf.c b/net/sched/sch_etf.c
+index c48f91075b5c6..d96103b0e2bf5 100644
+--- a/net/sched/sch_etf.c
++++ b/net/sched/sch_etf.c
+@@ -445,9 +445,6 @@ static void etf_reset(struct Qdisc *sch)
+ 	timesortedlist_clear(sch);
+ 	__qdisc_reset_queue(&sch->q);
+ 
+-	sch->qstats.backlog = 0;
+-	sch->q.qlen = 0;
+-
+ 	q->last = 0;
+ }
+ 
+diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
+index d733934935533..8de4365886e84 100644
+--- a/net/sched/sch_ets.c
++++ b/net/sched/sch_ets.c
+@@ -727,8 +727,6 @@ static void ets_qdisc_reset(struct Qdisc *sch)
+ 	}
+ 	for (band = 0; band < q->nbands; band++)
+ 		qdisc_reset(q->classes[band].qdisc);
+-	sch->qstats.backlog = 0;
+-	sch->q.qlen = 0;
+ }
+ 
+ static void ets_qdisc_destroy(struct Qdisc *sch)
+diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
+index 839e1235db053..23a042adb74d8 100644
+--- a/net/sched/sch_fq_codel.c
++++ b/net/sched/sch_fq_codel.c
+@@ -347,8 +347,6 @@ static void fq_codel_reset(struct Qdisc *sch)
+ 		codel_vars_init(&flow->cvars);
+ 	}
+ 	memset(q->backlogs, 0, q->flows_cnt * sizeof(u32));
+-	sch->q.qlen = 0;
+-	sch->qstats.backlog = 0;
+ 	q->memory_usage = 0;
+ }
+ 
+diff --git a/net/sched/sch_fq_pie.c b/net/sched/sch_fq_pie.c
+index d6aba6edd16e5..35c35465226bd 100644
+--- a/net/sched/sch_fq_pie.c
++++ b/net/sched/sch_fq_pie.c
+@@ -521,9 +521,6 @@ static void fq_pie_reset(struct Qdisc *sch)
+ 		INIT_LIST_HEAD(&flow->flowchain);
+ 		pie_vars_init(&flow->vars);
+ 	}
+-
+-	sch->q.qlen = 0;
+-	sch->qstats.backlog = 0;
+ }
+ 
+ static void fq_pie_destroy(struct Qdisc *sch)
+diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
+index d3979a6000e7d..03efc40e42fc4 100644
+--- a/net/sched/sch_hfsc.c
++++ b/net/sched/sch_hfsc.c
+@@ -1484,8 +1484,6 @@ hfsc_reset_qdisc(struct Qdisc *sch)
+ 	}
+ 	q->eligible = RB_ROOT;
+ 	qdisc_watchdog_cancel(&q->watchdog);
+-	sch->qstats.backlog = 0;
+-	sch->q.qlen = 0;
+ }
+ 
+ static void
+diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
+index 23a9d6242429f..cb5872d22ecf4 100644
+--- a/net/sched/sch_htb.c
++++ b/net/sched/sch_htb.c
+@@ -1008,8 +1008,6 @@ static void htb_reset(struct Qdisc *sch)
+ 	}
+ 	qdisc_watchdog_cancel(&q->watchdog);
+ 	__qdisc_reset_queue(&q->direct_queue);
+-	sch->q.qlen = 0;
+-	sch->qstats.backlog = 0;
+ 	memset(q->hlevel, 0, sizeof(q->hlevel));
+ 	memset(q->row_mask, 0, sizeof(q->row_mask));
+ }
+diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
+index cd8ab90c4765d..f28050c7f12d6 100644
+--- a/net/sched/sch_multiq.c
++++ b/net/sched/sch_multiq.c
+@@ -152,7 +152,6 @@ multiq_reset(struct Qdisc *sch)
+ 
+ 	for (band = 0; band < q->bands; band++)
+ 		qdisc_reset(q->queues[band]);
+-	sch->q.qlen = 0;
+ 	q->curband = 0;
+ }
+ 
+diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
+index 3b8d7197c06bf..c03a11dd990f4 100644
+--- a/net/sched/sch_prio.c
++++ b/net/sched/sch_prio.c
+@@ -135,8 +135,6 @@ prio_reset(struct Qdisc *sch)
+ 
+ 	for (prio = 0; prio < q->bands; prio++)
+ 		qdisc_reset(q->queues[prio]);
+-	sch->qstats.backlog = 0;
+-	sch->q.qlen = 0;
+ }
+ 
+ static int prio_offload(struct Qdisc *sch, struct tc_prio_qopt *qopt)
+diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
+index d4ce58c90f9fb..13246a9dc5c1c 100644
+--- a/net/sched/sch_qfq.c
++++ b/net/sched/sch_qfq.c
+@@ -1458,8 +1458,6 @@ static void qfq_reset_qdisc(struct Qdisc *sch)
+ 			qdisc_reset(cl->qdisc);
+ 		}
+ 	}
+-	sch->qstats.backlog = 0;
+-	sch->q.qlen = 0;
+ }
+ 
+ static void qfq_destroy_qdisc(struct Qdisc *sch)
+diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
+index 40adf1f07a82d..f1e013e3f04a9 100644
+--- a/net/sched/sch_red.c
++++ b/net/sched/sch_red.c
+@@ -176,8 +176,6 @@ static void red_reset(struct Qdisc *sch)
+ 	struct red_sched_data *q = qdisc_priv(sch);
+ 
+ 	qdisc_reset(q->qdisc);
+-	sch->qstats.backlog = 0;
+-	sch->q.qlen = 0;
+ 	red_restart(&q->vars);
+ }
+ 
+diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
+index 2829455211f8c..0490eb5b98dee 100644
+--- a/net/sched/sch_sfb.c
++++ b/net/sched/sch_sfb.c
+@@ -455,9 +455,8 @@ static void sfb_reset(struct Qdisc *sch)
+ {
+ 	struct sfb_sched_data *q = qdisc_priv(sch);
+ 
+-	qdisc_reset(q->qdisc);
+-	sch->qstats.backlog = 0;
+-	sch->q.qlen = 0;
++	if (likely(q->qdisc))
++		qdisc_reset(q->qdisc);
+ 	q->slot = 0;
+ 	q->double_buffering = false;
+ 	sfb_zero_all_buckets(q);
+diff --git a/net/sched/sch_skbprio.c b/net/sched/sch_skbprio.c
+index 7a5e4c4547156..df72fb83d9c7d 100644
+--- a/net/sched/sch_skbprio.c
++++ b/net/sched/sch_skbprio.c
+@@ -213,9 +213,6 @@ static void skbprio_reset(struct Qdisc *sch)
+ 	struct skbprio_sched_data *q = qdisc_priv(sch);
+ 	int prio;
+ 
+-	sch->qstats.backlog = 0;
+-	sch->q.qlen = 0;
+-
+ 	for (prio = 0; prio < SKBPRIO_MAX_PRIORITY; prio++)
+ 		__skb_queue_purge(&q->qdiscs[prio]);
+ 
+diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
+index 86675a79da1e4..5bffc37022e0b 100644
+--- a/net/sched/sch_taprio.c
++++ b/net/sched/sch_taprio.c
+@@ -1638,8 +1638,6 @@ static void taprio_reset(struct Qdisc *sch)
+ 			if (q->qdiscs[i])
+ 				qdisc_reset(q->qdiscs[i]);
+ 	}
+-	sch->qstats.backlog = 0;
+-	sch->q.qlen = 0;
+ }
+ 
+ static void taprio_destroy(struct Qdisc *sch)
+diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
+index 36079fdde2cb5..e031c1a41ea6b 100644
+--- a/net/sched/sch_tbf.c
++++ b/net/sched/sch_tbf.c
+@@ -330,8 +330,6 @@ static void tbf_reset(struct Qdisc *sch)
+ 	struct tbf_sched_data *q = qdisc_priv(sch);
+ 
+ 	qdisc_reset(q->qdisc);
+-	sch->qstats.backlog = 0;
+-	sch->q.qlen = 0;
+ 	q->t_c = ktime_get_ns();
+ 	q->tokens = q->buffer;
+ 	q->ptokens = q->mtu;
+diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
+index 6af6b95bdb672..79aaab51cbf5c 100644
+--- a/net/sched/sch_teql.c
++++ b/net/sched/sch_teql.c
+@@ -124,7 +124,6 @@ teql_reset(struct Qdisc *sch)
+ 	struct teql_sched_data *dat = qdisc_priv(sch);
+ 
+ 	skb_queue_purge(&dat->q);
+-	sch->q.qlen = 0;
+ }
+ 
+ static void
+diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
+index df89c2e08cbf4..828dd3a4126ab 100644
+--- a/net/smc/smc_core.c
++++ b/net/smc/smc_core.c
+@@ -896,7 +896,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
+ 		}
+ 		memcpy(lgr->pnet_id, ibdev->pnetid[ibport - 1],
+ 		       SMC_MAX_PNETID_LEN);
+-		if (smc_wr_alloc_lgr_mem(lgr))
++		rc = smc_wr_alloc_lgr_mem(lgr);
++		if (rc)
+ 			goto free_wq;
+ 		smc_llc_lgr_init(lgr, smc);
+ 
+diff --git a/net/tipc/discover.c b/net/tipc/discover.c
+index da69e1abf68ff..e8630707901e3 100644
+--- a/net/tipc/discover.c
++++ b/net/tipc/discover.c
+@@ -148,8 +148,8 @@ static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d,
+ {
+ 	struct net *net = d->net;
+ 	struct tipc_net *tn = tipc_net(net);
+-	bool trial = time_before(jiffies, tn->addr_trial_end);
+ 	u32 self = tipc_own_addr(net);
++	bool trial = time_before(jiffies, tn->addr_trial_end) && !self;
+ 
+ 	if (mtyp == DSC_TRIAL_FAIL_MSG) {
+ 		if (!trial)
+diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
+index 5522865deae95..14fd05fd6107d 100644
+--- a/net/tipc/topsrv.c
++++ b/net/tipc/topsrv.c
+@@ -568,7 +568,7 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
+ 	sub.seq.upper = upper;
+ 	sub.timeout = TIPC_WAIT_FOREVER;
+ 	sub.filter = filter;
+-	*(u32 *)&sub.usr_handle = port;
++	*(u64 *)&sub.usr_handle = (u64)port;
+ 
+ 	con = tipc_conn_alloc(tipc_topsrv(net));
+ 	if (IS_ERR(con))
+diff --git a/net/tls/tls_strp.c b/net/tls/tls_strp.c
+index 9b79e334dbd9e..955ac3e0bf4d3 100644
+--- a/net/tls/tls_strp.c
++++ b/net/tls/tls_strp.c
+@@ -273,7 +273,7 @@ static int tls_strp_read_copyin(struct tls_strparser *strp)
+ 	return desc.error;
+ }
+ 
+-static int tls_strp_read_short(struct tls_strparser *strp)
++static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
+ {
+ 	struct skb_shared_info *shinfo;
+ 	struct page *page;
+@@ -283,7 +283,7 @@ static int tls_strp_read_short(struct tls_strparser *strp)
+ 	 * to read the data out. Otherwise the connection will stall.
+ 	 * Without pressure threshold of INT_MAX will never be ready.
+ 	 */
+-	if (likely(!tcp_epollin_ready(strp->sk, INT_MAX)))
++	if (likely(qshort && !tcp_epollin_ready(strp->sk, INT_MAX)))
+ 		return 0;
+ 
+ 	shinfo = skb_shinfo(strp->anchor);
+@@ -315,6 +315,27 @@ static int tls_strp_read_short(struct tls_strparser *strp)
+ 	return 0;
+ }
+ 
++static bool tls_strp_check_no_dup(struct tls_strparser *strp)
++{
++	unsigned int len = strp->stm.offset + strp->stm.full_len;
++	struct sk_buff *skb;
++	u32 seq;
++
++	skb = skb_shinfo(strp->anchor)->frag_list;
++	seq = TCP_SKB_CB(skb)->seq;
++
++	while (skb->len < len) {
++		seq += skb->len;
++		len -= skb->len;
++		skb = skb->next;
++
++		if (TCP_SKB_CB(skb)->seq != seq)
++			return false;
++	}
++
++	return true;
++}
++
+ static void tls_strp_load_anchor_with_queue(struct tls_strparser *strp, int len)
+ {
+ 	struct tcp_sock *tp = tcp_sk(strp->sk);
+@@ -373,7 +394,7 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
+ 		return tls_strp_read_copyin(strp);
+ 
+ 	if (inq < strp->stm.full_len)
+-		return tls_strp_read_short(strp);
++		return tls_strp_read_copy(strp, true);
+ 
+ 	if (!strp->stm.full_len) {
+ 		tls_strp_load_anchor_with_queue(strp, inq);
+@@ -387,9 +408,12 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
+ 		strp->stm.full_len = sz;
+ 
+ 		if (!strp->stm.full_len || inq < strp->stm.full_len)
+-			return tls_strp_read_short(strp);
++			return tls_strp_read_copy(strp, true);
+ 	}
+ 
++	if (!tls_strp_check_no_dup(strp))
++		return tls_strp_read_copy(strp, false);
++
+ 	strp->msg_ready = 1;
+ 	tls_rx_msg_ready(strp);
+ 
+diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
+index fe5fcf571c564..64a6a37dc36d9 100644
+--- a/security/selinux/ss/services.c
++++ b/security/selinux/ss/services.c
+@@ -2022,7 +2022,8 @@ static inline int convert_context_handle_invalid_context(
+  * in `newc'.  Verify that the context is valid
+  * under the new policy.
+  */
+-static int convert_context(struct context *oldc, struct context *newc, void *p)
++static int convert_context(struct context *oldc, struct context *newc, void *p,
++			   gfp_t gfp_flags)
+ {
+ 	struct convert_context_args *args;
+ 	struct ocontext *oc;
+@@ -2036,7 +2037,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p)
+ 	args = p;
+ 
+ 	if (oldc->str) {
+-		s = kstrdup(oldc->str, GFP_KERNEL);
++		s = kstrdup(oldc->str, gfp_flags);
+ 		if (!s)
+ 			return -ENOMEM;
+ 
+diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
+index a54b8652bfb50..db5cce385bf86 100644
+--- a/security/selinux/ss/sidtab.c
++++ b/security/selinux/ss/sidtab.c
+@@ -325,7 +325,7 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context,
+ 		}
+ 
+ 		rc = convert->func(context, &dst_convert->context,
+-				   convert->args);
++				   convert->args, GFP_ATOMIC);
+ 		if (rc) {
+ 			context_destroy(&dst->context);
+ 			goto out_unlock;
+@@ -404,7 +404,7 @@ static int sidtab_convert_tree(union sidtab_entry_inner *edst,
+ 		while (i < SIDTAB_LEAF_ENTRIES && *pos < count) {
+ 			rc = convert->func(&esrc->ptr_leaf->entries[i].context,
+ 					   &edst->ptr_leaf->entries[i].context,
+-					   convert->args);
++					   convert->args, GFP_KERNEL);
+ 			if (rc)
+ 				return rc;
+ 			(*pos)++;
+diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h
+index 4eff0e49dcb22..9fce0d553fe2c 100644
+--- a/security/selinux/ss/sidtab.h
++++ b/security/selinux/ss/sidtab.h
+@@ -65,7 +65,7 @@ struct sidtab_isid_entry {
+ };
+ 
+ struct sidtab_convert_params {
+-	int (*func)(struct context *oldc, struct context *newc, void *args);
++	int (*func)(struct context *oldc, struct context *newc, void *args, gfp_t gfp_flags);
+ 	void *args;
+ 	struct sidtab *target;
+ };
+diff --git a/tools/verification/dot2/dot2c.py b/tools/verification/dot2/dot2c.py
+index fa73353f7e560..be8a364a469b9 100644
+--- a/tools/verification/dot2/dot2c.py
++++ b/tools/verification/dot2/dot2c.py
+@@ -111,7 +111,7 @@ class Dot2c(Automata):
+ 
+     def format_aut_init_header(self):
+         buff = []
+-        buff.append("struct %s %s = {" % (self.struct_automaton_def, self.var_automaton_def))
++        buff.append("static struct %s %s = {" % (self.struct_automaton_def, self.var_automaton_def))
+         return buff
+ 
+     def __get_string_vector_per_line_content(self, buff):
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 584a5bab3af39..4c5259828efdc 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -4834,6 +4834,12 @@ struct compat_kvm_clear_dirty_log {
+ 	};
+ };
+ 
++long __weak kvm_arch_vm_compat_ioctl(struct file *filp, unsigned int ioctl,
++				     unsigned long arg)
++{
++	return -ENOTTY;
++}
++
+ static long kvm_vm_compat_ioctl(struct file *filp,
+ 			   unsigned int ioctl, unsigned long arg)
+ {
+@@ -4842,6 +4848,11 @@ static long kvm_vm_compat_ioctl(struct file *filp,
+ 
+ 	if (kvm->mm != current->mm || kvm->vm_dead)
+ 		return -EIO;
++
++	r = kvm_arch_vm_compat_ioctl(filp, ioctl, arg);
++	if (r != -ENOTTY)
++		return r;
++
+ 	switch (ioctl) {
+ #ifdef CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT
+ 	case KVM_CLEAR_DIRTY_LOG: {


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-10-26 11:24 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-10-26 11:24 UTC (permalink / raw
  To: gentoo-commits

commit:     08c794c0b0d8d1d28994c04d849ea380b928a60e
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 26 11:24:09 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Oct 26 11:24:09 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=08c794c0

Linux patches 6.0.4 and 6.0.5

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

 0000_README            |    8 +
 1003_linux-6.0.4.patch | 1011 ++++++++++++++++++++++++++++++++++++++++++++++++
 1004_linux-6.0.5.patch |  159 ++++++++
 3 files changed, 1178 insertions(+)

diff --git a/0000_README b/0000_README
index e5b9be05..85528522 100644
--- a/0000_README
+++ b/0000_README
@@ -55,6 +55,14 @@ Patch:  1002_linux-6.0.3.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.3
 
+Patch:  1003_linux-6.0.4.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.4
+
+Patch:  1004_linux-6.0.5.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.5
+
 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/1003_linux-6.0.4.patch b/1003_linux-6.0.4.patch
new file mode 100644
index 00000000..4b203225
--- /dev/null
+++ b/1003_linux-6.0.4.patch
@@ -0,0 +1,1011 @@
+diff --git a/Makefile b/Makefile
+index d4297b3d0735a..f2e41dccdd89d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 3
++SUBLEVEL = 4
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
+index e4080ad96089a..aa6d109fac08b 100644
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -269,6 +269,8 @@ static __init int efivar_ssdt_load(void)
+ 			acpi_status ret = acpi_load_table(data, NULL);
+ 			if (ret)
+ 				pr_err("failed to load table: %u\n", ret);
++			else
++				continue;
+ 		} else {
+ 			pr_err("failed to get var data: 0x%lx\n", status);
+ 		}
+diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
+index dd74d2ad31840..433b615871395 100644
+--- a/drivers/firmware/efi/vars.c
++++ b/drivers/firmware/efi/vars.c
+@@ -7,6 +7,7 @@
+  */
+ 
+ #include <linux/types.h>
++#include <linux/sizes.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+@@ -20,19 +21,19 @@ static struct efivars *__efivars;
+ 
+ static DEFINE_SEMAPHORE(efivars_lock);
+ 
+-efi_status_t check_var_size(u32 attributes, unsigned long size)
++static efi_status_t check_var_size(u32 attributes, unsigned long size)
+ {
+ 	const struct efivar_operations *fops;
+ 
+ 	fops = __efivars->ops;
+ 
+ 	if (!fops->query_variable_store)
+-		return EFI_UNSUPPORTED;
++		return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
+ 
+ 	return fops->query_variable_store(attributes, size, false);
+ }
+-EXPORT_SYMBOL_NS_GPL(check_var_size, EFIVAR);
+ 
++static
+ efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size)
+ {
+ 	const struct efivar_operations *fops;
+@@ -40,11 +41,10 @@ efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size)
+ 	fops = __efivars->ops;
+ 
+ 	if (!fops->query_variable_store)
+-		return EFI_UNSUPPORTED;
++		return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
+ 
+ 	return fops->query_variable_store(attributes, size, true);
+ }
+-EXPORT_SYMBOL_NS_GPL(check_var_size_nonblocking, EFIVAR);
+ 
+ /**
+  * efivars_kobject - get the kobject for the registered efivars
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+index 25e1f5ed7ead1..91665fe44e7ca 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -2926,6 +2926,14 @@ static int amdgpu_device_ip_suspend_phase1(struct amdgpu_device *adev)
+ 	amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
+ 	amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
+ 
++	/*
++	 * Per PMFW team's suggestion, driver needs to handle gfxoff
++	 * and df cstate features disablement for gpu reset(e.g. Mode1Reset)
++	 * scenario. Add the missing df cstate disablement here.
++	 */
++	if (amdgpu_dpm_set_df_cstate(adev, DF_CSTATE_DISALLOW))
++		dev_warn(adev->dev, "Failed to disallow df cstate");
++
+ 	for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
+ 		if (!adev->ip_blocks[i].status.valid)
+ 			continue;
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_4.h b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_4.h
+index ae2d337158f3b..f77401709d83c 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_4.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/pmfw_if/smu13_driver_if_v13_0_4.h
+@@ -27,7 +27,7 @@
+ // *** IMPORTANT ***
+ // SMU TEAM: Always increment the interface version if
+ // any structure is changed in this file
+-#define PMFW_DRIVER_IF_VERSION 5
++#define PMFW_DRIVER_IF_VERSION 7
+ 
+ typedef struct {
+   int32_t value;
+@@ -163,8 +163,8 @@ typedef struct {
+   uint16_t DclkFrequency;               //[MHz]
+   uint16_t MemclkFrequency;             //[MHz]
+   uint16_t spare;                       //[centi]
+-  uint16_t UvdActivity;                 //[centi]
+   uint16_t GfxActivity;                 //[centi]
++  uint16_t UvdActivity;                 //[centi]
+ 
+   uint16_t Voltage[2];                  //[mV] indices: VDDCR_VDD, VDDCR_SOC
+   uint16_t Current[2];                  //[mA] indices: VDDCR_VDD, VDDCR_SOC
+@@ -199,6 +199,19 @@ typedef struct {
+   uint16_t DeviceState;
+   uint16_t CurTemp;                     //[centi-Celsius]
+   uint16_t spare2;
++
++  uint16_t AverageGfxclkFrequency;
++  uint16_t AverageFclkFrequency;
++  uint16_t AverageGfxActivity;
++  uint16_t AverageSocclkFrequency;
++  uint16_t AverageVclkFrequency;
++  uint16_t AverageVcnActivity;
++  uint16_t AverageDRAMReads;          //Filtered DF Bandwidth::DRAM Reads
++  uint16_t AverageDRAMWrites;         //Filtered DF Bandwidth::DRAM Writes
++  uint16_t AverageSocketPower;        //Filtered value of CurrentSocketPower
++  uint16_t AverageCorePower;          //Filtered of [sum of CorePower[8]])
++  uint16_t AverageCoreC0Residency[8]; //Filtered of [average C0 residency %  per core]
++  uint32_t MetricsCounter;            //Counts the # of metrics table parameter reads per update to the metrics table, i.e. if the metrics table update happens every 1 second, this value could be up to 1000 if the smu collected metrics data every cycle, or as low as 0 if the smu was asleep the whole time. Reset to 0 after writing.
+ } SmuMetrics_t;
+ 
+ typedef struct {
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+index f442bf085a318..f75b9688f5129 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+@@ -28,7 +28,7 @@
+ #define SMU13_DRIVER_IF_VERSION_INV 0xFFFFFFFF
+ #define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x04
+ #define SMU13_DRIVER_IF_VERSION_ALDE 0x08
+-#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x05
++#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0 0x30
+ #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x2C
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
+index 445005571f76f..9cd005131f566 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
+@@ -2242,9 +2242,17 @@ static void arcturus_get_unique_id(struct smu_context *smu)
+ static int arcturus_set_df_cstate(struct smu_context *smu,
+ 				  enum pp_df_cstate state)
+ {
++	struct amdgpu_device *adev = smu->adev;
+ 	uint32_t smu_version;
+ 	int ret;
+ 
++	/*
++	 * Arcturus does not need the cstate disablement
++	 * prerequisite for gpu reset.
++	 */
++	if (amdgpu_in_reset(adev) || adev->in_suspend)
++		return 0;
++
+ 	ret = smu_cmn_get_smc_version(smu, NULL, &smu_version);
+ 	if (ret) {
+ 		dev_err(smu->adev->dev, "Failed to get smu version!\n");
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
+index 619aee51b1238..d30ec3005ea19 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
+@@ -1640,6 +1640,15 @@ static bool aldebaran_is_baco_supported(struct smu_context *smu)
+ static int aldebaran_set_df_cstate(struct smu_context *smu,
+ 				   enum pp_df_cstate state)
+ {
++	struct amdgpu_device *adev = smu->adev;
++
++	/*
++	 * Aldebaran does not need the cstate disablement
++	 * prerequisite for gpu reset.
++	 */
++	if (amdgpu_in_reset(adev) || adev->in_suspend)
++		return 0;
++
+ 	return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, state, NULL);
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+index 1d454485e0d91..29529328152d0 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+@@ -119,6 +119,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] =
+ 	MSG_MAP(NotifyPowerSource,		PPSMC_MSG_NotifyPowerSource,           0),
+ 	MSG_MAP(Mode1Reset,			PPSMC_MSG_Mode1Reset,                  0),
+ 	MSG_MAP(PrepareMp1ForUnload,		PPSMC_MSG_PrepareMp1ForUnload,         0),
++	MSG_MAP(DFCstateControl,		PPSMC_MSG_SetExternalClientDfCstateAllow, 0),
+ };
+ 
+ static struct cmn2asic_mapping smu_v13_0_0_clk_map[SMU_CLK_COUNT] = {
+@@ -1753,6 +1754,15 @@ static int smu_v13_0_0_set_mp1_state(struct smu_context *smu,
+ 	return ret;
+ }
+ 
++static int smu_v13_0_0_set_df_cstate(struct smu_context *smu,
++				     enum pp_df_cstate state)
++{
++	return smu_cmn_send_smc_msg_with_param(smu,
++					       SMU_MSG_DFCstateControl,
++					       state,
++					       NULL);
++}
++
+ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
+ 	.get_allowed_feature_mask = smu_v13_0_0_get_allowed_feature_mask,
+ 	.set_default_dpm_table = smu_v13_0_0_set_default_dpm_table,
+@@ -1822,6 +1832,7 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
+ 	.mode1_reset_is_support = smu_v13_0_0_is_mode1_reset_supported,
+ 	.mode1_reset = smu_v13_0_mode1_reset,
+ 	.set_mp1_state = smu_v13_0_0_set_mp1_state,
++	.set_df_cstate = smu_v13_0_0_set_df_cstate,
+ };
+ 
+ void smu_v13_0_0_set_ppt_funcs(struct smu_context *smu)
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+index c422bf8a09b1d..c4102cfb734c2 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+@@ -121,6 +121,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_7_message_map[SMU_MSG_MAX_COUNT] =
+ 	MSG_MAP(Mode1Reset,             PPSMC_MSG_Mode1Reset,                  0),
+ 	MSG_MAP(PrepareMp1ForUnload,		PPSMC_MSG_PrepareMp1ForUnload,         0),
+ 	MSG_MAP(SetMGpuFanBoostLimitRpm,	PPSMC_MSG_SetMGpuFanBoostLimitRpm,     0),
++	MSG_MAP(DFCstateControl,		PPSMC_MSG_SetExternalClientDfCstateAllow, 0),
+ };
+ 
+ static struct cmn2asic_mapping smu_v13_0_7_clk_map[SMU_CLK_COUNT] = {
+@@ -1587,6 +1588,16 @@ static bool smu_v13_0_7_is_mode1_reset_supported(struct smu_context *smu)
+ 
+ 	return true;
+ }
++
++static int smu_v13_0_7_set_df_cstate(struct smu_context *smu,
++				     enum pp_df_cstate state)
++{
++	return smu_cmn_send_smc_msg_with_param(smu,
++					       SMU_MSG_DFCstateControl,
++					       state,
++					       NULL);
++}
++
+ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
+ 	.get_allowed_feature_mask = smu_v13_0_7_get_allowed_feature_mask,
+ 	.set_default_dpm_table = smu_v13_0_7_set_default_dpm_table,
+@@ -1649,6 +1660,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
+ 	.mode1_reset_is_support = smu_v13_0_7_is_mode1_reset_supported,
+ 	.mode1_reset = smu_v13_0_mode1_reset,
+ 	.set_mp1_state = smu_v13_0_7_set_mp1_state,
++	.set_df_cstate = smu_v13_0_7_set_df_cstate,
+ };
+ 
+ void smu_v13_0_7_set_ppt_funcs(struct smu_context *smu)
+diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
+index 7d6eb9ad7a026..459571e2cc575 100644
+--- a/drivers/gpu/drm/i915/display/intel_bios.c
++++ b/drivers/gpu/drm/i915/display/intel_bios.c
+@@ -135,18 +135,6 @@ static u32 raw_block_offset(const void *bdb, enum bdb_block_id section_id)
+ 	return block - bdb;
+ }
+ 
+-/* size of the block excluding the header */
+-static u32 raw_block_size(const void *bdb, enum bdb_block_id section_id)
+-{
+-	const void *block;
+-
+-	block = find_raw_section(bdb, section_id);
+-	if (!block)
+-		return 0;
+-
+-	return get_blocksize(block);
+-}
+-
+ struct bdb_block_entry {
+ 	struct list_head node;
+ 	enum bdb_block_id section_id;
+@@ -231,9 +219,14 @@ static bool validate_lfp_data_ptrs(const void *bdb,
+ {
+ 	int fp_timing_size, dvo_timing_size, panel_pnp_id_size, panel_name_size;
+ 	int data_block_size, lfp_data_size;
++	const void *data_block;
+ 	int i;
+ 
+-	data_block_size = raw_block_size(bdb, BDB_LVDS_LFP_DATA);
++	data_block = find_raw_section(bdb, BDB_LVDS_LFP_DATA);
++	if (!data_block)
++		return false;
++
++	data_block_size = get_blocksize(data_block);
+ 	if (data_block_size == 0)
+ 		return false;
+ 
+@@ -261,21 +254,6 @@ static bool validate_lfp_data_ptrs(const void *bdb,
+ 	if (16 * lfp_data_size > data_block_size)
+ 		return false;
+ 
+-	/*
+-	 * Except for vlv/chv machines all real VBTs seem to have 6
+-	 * unaccounted bytes in the fp_timing table. And it doesn't
+-	 * appear to be a really intentional hole as the fp_timing
+-	 * 0xffff terminator is always within those 6 missing bytes.
+-	 */
+-	if (fp_timing_size + dvo_timing_size + panel_pnp_id_size != lfp_data_size &&
+-	    fp_timing_size + 6 + dvo_timing_size + panel_pnp_id_size != lfp_data_size)
+-		return false;
+-
+-	if (ptrs->ptr[0].fp_timing.offset + fp_timing_size > ptrs->ptr[0].dvo_timing.offset ||
+-	    ptrs->ptr[0].dvo_timing.offset + dvo_timing_size != ptrs->ptr[0].panel_pnp_id.offset ||
+-	    ptrs->ptr[0].panel_pnp_id.offset + panel_pnp_id_size != lfp_data_size)
+-		return false;
+-
+ 	/* make sure the table entries have uniform size */
+ 	for (i = 1; i < 16; i++) {
+ 		if (ptrs->ptr[i].fp_timing.table_size != fp_timing_size ||
+@@ -289,6 +267,23 @@ static bool validate_lfp_data_ptrs(const void *bdb,
+ 			return false;
+ 	}
+ 
++	/*
++	 * Except for vlv/chv machines all real VBTs seem to have 6
++	 * unaccounted bytes in the fp_timing table. And it doesn't
++	 * appear to be a really intentional hole as the fp_timing
++	 * 0xffff terminator is always within those 6 missing bytes.
++	 */
++	if (fp_timing_size + 6 + dvo_timing_size + panel_pnp_id_size == lfp_data_size)
++		fp_timing_size += 6;
++
++	if (fp_timing_size + dvo_timing_size + panel_pnp_id_size != lfp_data_size)
++		return false;
++
++	if (ptrs->ptr[0].fp_timing.offset + fp_timing_size != ptrs->ptr[0].dvo_timing.offset ||
++	    ptrs->ptr[0].dvo_timing.offset + dvo_timing_size != ptrs->ptr[0].panel_pnp_id.offset ||
++	    ptrs->ptr[0].panel_pnp_id.offset + panel_pnp_id_size != lfp_data_size)
++		return false;
++
+ 	/* make sure the tables fit inside the data block */
+ 	for (i = 0; i < 16; i++) {
+ 		if (ptrs->ptr[i].fp_timing.offset + fp_timing_size > data_block_size ||
+@@ -300,6 +295,15 @@ static bool validate_lfp_data_ptrs(const void *bdb,
+ 	if (ptrs->panel_name.offset + 16 * panel_name_size > data_block_size)
+ 		return false;
+ 
++	/* make sure fp_timing terminators are present at expected locations */
++	for (i = 0; i < 16; i++) {
++		const u16 *t = data_block + ptrs->ptr[i].fp_timing.offset +
++			fp_timing_size - 2;
++
++		if (*t != 0xffff)
++			return false;
++	}
++
+ 	return true;
+ }
+ 
+@@ -333,18 +337,6 @@ static bool fixup_lfp_data_ptrs(const void *bdb, void *ptrs_block)
+ 	return validate_lfp_data_ptrs(bdb, ptrs);
+ }
+ 
+-static const void *find_fp_timing_terminator(const u8 *data, int size)
+-{
+-	int i;
+-
+-	for (i = 0; i < size - 1; i++) {
+-		if (data[i] == 0xff && data[i+1] == 0xff)
+-			return &data[i];
+-	}
+-
+-	return NULL;
+-}
+-
+ static int make_lfp_data_ptr(struct lvds_lfp_data_ptr_table *table,
+ 			     int table_size, int total_size)
+ {
+@@ -368,11 +360,22 @@ static void next_lfp_data_ptr(struct lvds_lfp_data_ptr_table *next,
+ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
+ 				    const void *bdb)
+ {
+-	int i, size, table_size, block_size, offset;
+-	const void *t0, *t1, *block;
++	int i, size, table_size, block_size, offset, fp_timing_size;
+ 	struct bdb_lvds_lfp_data_ptrs *ptrs;
++	const void *block;
+ 	void *ptrs_block;
+ 
++	/*
++	 * The hardcoded fp_timing_size is only valid for
++	 * modernish VBTs. All older VBTs definitely should
++	 * include block 41 and thus we don't need to
++	 * generate one.
++	 */
++	if (i915->vbt.version < 155)
++		return NULL;
++
++	fp_timing_size = 38;
++
+ 	block = find_raw_section(bdb, BDB_LVDS_LFP_DATA);
+ 	if (!block)
+ 		return NULL;
+@@ -381,17 +384,8 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
+ 
+ 	block_size = get_blocksize(block);
+ 
+-	size = block_size;
+-	t0 = find_fp_timing_terminator(block, size);
+-	if (!t0)
+-		return NULL;
+-
+-	size -= t0 - block - 2;
+-	t1 = find_fp_timing_terminator(t0 + 2, size);
+-	if (!t1)
+-		return NULL;
+-
+-	size = t1 - t0;
++	size = fp_timing_size + sizeof(struct lvds_dvo_timing) +
++		sizeof(struct lvds_pnp_id);
+ 	if (size * 16 > block_size)
+ 		return NULL;
+ 
+@@ -409,7 +403,7 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
+ 	table_size = sizeof(struct lvds_dvo_timing);
+ 	size = make_lfp_data_ptr(&ptrs->ptr[0].dvo_timing, table_size, size);
+ 
+-	table_size = t0 - block + 2;
++	table_size = fp_timing_size;
+ 	size = make_lfp_data_ptr(&ptrs->ptr[0].fp_timing, table_size, size);
+ 
+ 	if (ptrs->ptr[0].fp_timing.table_size)
+@@ -424,14 +418,14 @@ static void *generate_lfp_data_ptrs(struct drm_i915_private *i915,
+ 		return NULL;
+ 	}
+ 
+-	size = t1 - t0;
++	size = fp_timing_size + sizeof(struct lvds_dvo_timing) +
++		sizeof(struct lvds_pnp_id);
+ 	for (i = 1; i < 16; i++) {
+ 		next_lfp_data_ptr(&ptrs->ptr[i].fp_timing, &ptrs->ptr[i-1].fp_timing, size);
+ 		next_lfp_data_ptr(&ptrs->ptr[i].dvo_timing, &ptrs->ptr[i-1].dvo_timing, size);
+ 		next_lfp_data_ptr(&ptrs->ptr[i].panel_pnp_id, &ptrs->ptr[i-1].panel_pnp_id, size);
+ 	}
+ 
+-	size = t1 - t0;
+ 	table_size = sizeof(struct lvds_lfp_panel_name);
+ 
+ 	if (16 * (size + table_size) <= block_size) {
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 50bab12d9476f..043cf1cc87946 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -1142,6 +1142,7 @@
+ #define USB_DEVICE_ID_SONY_PS4_CONTROLLER_2	0x09cc
+ #define USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE	0x0ba0
+ #define USB_DEVICE_ID_SONY_PS5_CONTROLLER	0x0ce6
++#define USB_DEVICE_ID_SONY_PS5_CONTROLLER_2	0x0df2
+ #define USB_DEVICE_ID_SONY_MOTION_CONTROLLER	0x03d5
+ #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER	0x042f
+ #define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER		0x0002
+diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
+index b1b5721b5d8f7..d21d868e29ab4 100644
+--- a/drivers/hid/hid-playstation.c
++++ b/drivers/hid/hid-playstation.c
+@@ -46,6 +46,7 @@ struct ps_device {
+ 	uint32_t fw_version;
+ 
+ 	int (*parse_report)(struct ps_device *dev, struct hid_report *report, u8 *data, int size);
++	void (*remove)(struct ps_device *dev);
+ };
+ 
+ /* Calibration data for playstation motion sensors. */
+@@ -174,6 +175,7 @@ struct dualsense {
+ 	struct led_classdev player_leds[5];
+ 
+ 	struct work_struct output_worker;
++	bool output_worker_initialized;
+ 	void *output_report_dmabuf;
+ 	uint8_t output_seq; /* Sequence number for output report. */
+ };
+@@ -299,6 +301,7 @@ static const struct {int x; int y; } ps_gamepad_hat_mapping[] = {
+ 	{0, 0},
+ };
+ 
++static inline void dualsense_schedule_work(struct dualsense *ds);
+ static void dualsense_set_lightbar(struct dualsense *ds, uint8_t red, uint8_t green, uint8_t blue);
+ 
+ /*
+@@ -792,6 +795,7 @@ err_free:
+ 	return ret;
+ }
+ 
++
+ static int dualsense_get_firmware_info(struct dualsense *ds)
+ {
+ 	uint8_t *buf;
+@@ -881,7 +885,7 @@ static int dualsense_player_led_set_brightness(struct led_classdev *led, enum le
+ 	ds->update_player_leds = true;
+ 	spin_unlock_irqrestore(&ds->base.lock, flags);
+ 
+-	schedule_work(&ds->output_worker);
++	dualsense_schedule_work(ds);
+ 
+ 	return 0;
+ }
+@@ -925,6 +929,16 @@ static void dualsense_init_output_report(struct dualsense *ds, struct dualsense_
+ 	}
+ }
+ 
++static inline void dualsense_schedule_work(struct dualsense *ds)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(&ds->base.lock, flags);
++	if (ds->output_worker_initialized)
++		schedule_work(&ds->output_worker);
++	spin_unlock_irqrestore(&ds->base.lock, flags);
++}
++
+ /*
+  * Helper function to send DualSense output reports. Applies a CRC at the end of a report
+  * for Bluetooth reports.
+@@ -1085,7 +1099,7 @@ static int dualsense_parse_report(struct ps_device *ps_dev, struct hid_report *r
+ 		spin_unlock_irqrestore(&ps_dev->lock, flags);
+ 
+ 		/* Schedule updating of microphone state at hardware level. */
+-		schedule_work(&ds->output_worker);
++		dualsense_schedule_work(ds);
+ 	}
+ 	ds->last_btn_mic_state = btn_mic_state;
+ 
+@@ -1200,10 +1214,22 @@ static int dualsense_play_effect(struct input_dev *dev, void *data, struct ff_ef
+ 	ds->motor_right = effect->u.rumble.weak_magnitude / 256;
+ 	spin_unlock_irqrestore(&ds->base.lock, flags);
+ 
+-	schedule_work(&ds->output_worker);
++	dualsense_schedule_work(ds);
+ 	return 0;
+ }
+ 
++static void dualsense_remove(struct ps_device *ps_dev)
++{
++	struct dualsense *ds = container_of(ps_dev, struct dualsense, base);
++	unsigned long flags;
++
++	spin_lock_irqsave(&ds->base.lock, flags);
++	ds->output_worker_initialized = false;
++	spin_unlock_irqrestore(&ds->base.lock, flags);
++
++	cancel_work_sync(&ds->output_worker);
++}
++
+ static int dualsense_reset_leds(struct dualsense *ds)
+ {
+ 	struct dualsense_output_report report;
+@@ -1240,7 +1266,7 @@ static void dualsense_set_lightbar(struct dualsense *ds, uint8_t red, uint8_t gr
+ 	ds->lightbar_blue = blue;
+ 	spin_unlock_irqrestore(&ds->base.lock, flags);
+ 
+-	schedule_work(&ds->output_worker);
++	dualsense_schedule_work(ds);
+ }
+ 
+ static void dualsense_set_player_leds(struct dualsense *ds)
+@@ -1263,7 +1289,7 @@ static void dualsense_set_player_leds(struct dualsense *ds)
+ 
+ 	ds->update_player_leds = true;
+ 	ds->player_leds_state = player_ids[player_id];
+-	schedule_work(&ds->output_worker);
++	dualsense_schedule_work(ds);
+ }
+ 
+ static struct ps_device *dualsense_create(struct hid_device *hdev)
+@@ -1302,7 +1328,9 @@ static struct ps_device *dualsense_create(struct hid_device *hdev)
+ 	ps_dev->battery_capacity = 100; /* initial value until parse_report. */
+ 	ps_dev->battery_status = POWER_SUPPLY_STATUS_UNKNOWN;
+ 	ps_dev->parse_report = dualsense_parse_report;
++	ps_dev->remove = dualsense_remove;
+ 	INIT_WORK(&ds->output_worker, dualsense_output_worker);
++	ds->output_worker_initialized = true;
+ 	hid_set_drvdata(hdev, ds);
+ 
+ 	max_output_report_size = sizeof(struct dualsense_output_report_bt);
+@@ -1439,7 +1467,8 @@ static int ps_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ 		goto err_stop;
+ 	}
+ 
+-	if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER) {
++	if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER ||
++		hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) {
+ 		dev = dualsense_create(hdev);
+ 		if (IS_ERR(dev)) {
+ 			hid_err(hdev, "Failed to create dualsense.\n");
+@@ -1470,6 +1499,9 @@ static void ps_remove(struct hid_device *hdev)
+ 	ps_devices_list_remove(dev);
+ 	ps_device_release_player_id(dev);
+ 
++	if (dev->remove)
++		dev->remove(dev);
++
+ 	hid_hw_close(hdev);
+ 	hid_hw_stop(hdev);
+ }
+@@ -1477,6 +1509,8 @@ static void ps_remove(struct hid_device *hdev)
+ static const struct hid_device_id ps_devices[] = {
+ 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER) },
+ 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER) },
++	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) },
++	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) },
+ 	{ }
+ };
+ MODULE_DEVICE_TABLE(hid, ps_devices);
+diff --git a/drivers/md/dm-clone-target.c b/drivers/md/dm-clone-target.c
+index 811b0a5379d03..2f1cc66d26412 100644
+--- a/drivers/md/dm-clone-target.c
++++ b/drivers/md/dm-clone-target.c
+@@ -2035,7 +2035,7 @@ static void disable_passdown_if_not_supported(struct clone *clone)
+ 		reason = "max discard sectors smaller than a region";
+ 
+ 	if (reason) {
+-		DMWARN("Destination device (%pd) %s: Disabling discard passdown.",
++		DMWARN("Destination device (%pg) %s: Disabling discard passdown.",
+ 		       dest_dev, reason);
+ 		clear_bit(DM_CLONE_DISCARD_PASSDOWN, &clone->flags);
+ 	}
+diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
+index 4691a33bc374f..2a4b3efb7e12b 100644
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -1051,13 +1051,13 @@ static void amd_get_iomux_res(struct amd_gpio *gpio_dev)
+ 
+ 	index = device_property_match_string(dev, "pinctrl-resource-names",  "iomux");
+ 	if (index < 0) {
+-		dev_warn(dev, "failed to get iomux index\n");
++		dev_dbg(dev, "iomux not supported\n");
+ 		goto out_no_pinmux;
+ 	}
+ 
+ 	gpio_dev->iomux_base = devm_platform_ioremap_resource(gpio_dev->pdev, index);
+ 	if (IS_ERR(gpio_dev->iomux_base)) {
+-		dev_warn(dev, "Failed to get iomux %d io resource\n", index);
++		dev_dbg(dev, "iomux not supported %d io resource\n", index);
+ 		goto out_no_pinmux;
+ 	}
+ 
+diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c
+index 46cd799af148d..bf3e4edeceda9 100644
+--- a/drivers/thermal/intel/intel_powerclamp.c
++++ b/drivers/thermal/intel/intel_powerclamp.c
+@@ -531,11 +531,7 @@ static int start_power_clamp(void)
+ 	cpus_read_lock();
+ 
+ 	/* prefer BSP */
+-	control_cpu = 0;
+-	if (!cpu_online(control_cpu)) {
+-		control_cpu = get_cpu();
+-		put_cpu();
+-	}
++	control_cpu = cpumask_first(cpu_online_mask);
+ 
+ 	clamping = true;
+ 	schedule_delayed_work(&poll_pkg_cstate_work, 0);
+diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c
+index d245826a9324d..101e13c2cf41c 100644
+--- a/drivers/video/aperture.c
++++ b/drivers/video/aperture.c
+@@ -335,30 +335,36 @@ EXPORT_SYMBOL(aperture_remove_conflicting_devices);
+  */
+ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name)
+ {
++	bool primary = false;
+ 	resource_size_t base, size;
+ 	int bar, ret;
+ 
+-	/*
+-	 * WARNING: Apparently we must kick fbdev drivers before vgacon,
+-	 * otherwise the vga fbdev driver falls over.
+-	 */
+-#if IS_REACHABLE(CONFIG_FB)
+-	ret = remove_conflicting_pci_framebuffers(pdev, name);
+-	if (ret)
+-		return ret;
++#ifdef CONFIG_X86
++	primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
+ #endif
+-	ret = vga_remove_vgacon(pdev);
+-	if (ret)
+-		return ret;
+ 
+ 	for (bar = 0; bar < PCI_STD_NUM_BARS; ++bar) {
+ 		if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
+ 			continue;
++
+ 		base = pci_resource_start(pdev, bar);
+ 		size = pci_resource_len(pdev, bar);
+-		aperture_detach_devices(base, size);
++		ret = aperture_remove_conflicting_devices(base, size, primary, name);
++		if (ret)
++			break;
+ 	}
+ 
++	if (ret)
++		return ret;
++
++	/*
++	 * WARNING: Apparently we must kick fbdev drivers before vgacon,
++	 * otherwise the vga fbdev driver falls over.
++	 */
++	ret = vga_remove_vgacon(pdev);
++	if (ret)
++		return ret;
++
+ 	return 0;
+ 
+ }
+diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
+index bda4d304feb68..4ed0960e6c058 100644
+--- a/drivers/video/fbdev/core/fbmem.c
++++ b/drivers/video/fbdev/core/fbmem.c
+@@ -1787,54 +1787,6 @@ int remove_conflicting_framebuffers(struct apertures_struct *a,
+ }
+ EXPORT_SYMBOL(remove_conflicting_framebuffers);
+ 
+-/**
+- * remove_conflicting_pci_framebuffers - remove firmware-configured framebuffers for PCI devices
+- * @pdev: PCI device
+- * @name: requesting driver name
+- *
+- * This function removes framebuffer devices (eg. initialized by firmware)
+- * using memory range configured for any of @pdev's memory bars.
+- *
+- * The function assumes that PCI device with shadowed ROM drives a primary
+- * display and so kicks out vga16fb.
+- */
+-int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, const char *name)
+-{
+-	struct apertures_struct *ap;
+-	bool primary = false;
+-	int err, idx, bar;
+-
+-	for (idx = 0, bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
+-		if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
+-			continue;
+-		idx++;
+-	}
+-
+-	ap = alloc_apertures(idx);
+-	if (!ap)
+-		return -ENOMEM;
+-
+-	for (idx = 0, bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
+-		if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM))
+-			continue;
+-		ap->ranges[idx].base = pci_resource_start(pdev, bar);
+-		ap->ranges[idx].size = pci_resource_len(pdev, bar);
+-		pci_dbg(pdev, "%s: bar %d: 0x%lx -> 0x%lx\n", __func__, bar,
+-			(unsigned long)pci_resource_start(pdev, bar),
+-			(unsigned long)pci_resource_end(pdev, bar));
+-		idx++;
+-	}
+-
+-#ifdef CONFIG_X86
+-	primary = pdev->resource[PCI_ROM_RESOURCE].flags &
+-					IORESOURCE_ROM_SHADOW;
+-#endif
+-	err = remove_conflicting_framebuffers(ap, name, primary);
+-	kfree(ap);
+-	return err;
+-}
+-EXPORT_SYMBOL(remove_conflicting_pci_framebuffers);
+-
+ /**
+  *	register_framebuffer - registers a frame buffer device
+  *	@fb_info: frame buffer info structure
+diff --git a/fs/efivarfs/vars.c b/fs/efivarfs/vars.c
+index a0ef63cfcecba..9e4f47808bd5a 100644
+--- a/fs/efivarfs/vars.c
++++ b/fs/efivarfs/vars.c
+@@ -651,22 +651,6 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, u32 attributes,
+ 	if (err)
+ 		return err;
+ 
+-	/*
+-	 * Ensure that the available space hasn't shrunk below the safe level
+-	 */
+-	status = check_var_size(attributes, *size + ucs2_strsize(name, 1024));
+-	if (status != EFI_SUCCESS) {
+-		if (status != EFI_UNSUPPORTED) {
+-			err = efi_status_to_err(status);
+-			goto out;
+-		}
+-
+-		if (*size > 65536) {
+-			err = -ENOSPC;
+-			goto out;
+-		}
+-	}
+-
+ 	status = efivar_set_variable_locked(name, vendor, attributes, *size,
+ 					    data, false);
+ 	if (status != EFI_SUCCESS) {
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index d2b84c2fec39f..4459794b65db0 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -1055,9 +1055,6 @@ efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor,
+ efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+ 				 u32 attr, unsigned long data_size, void *data);
+ 
+-efi_status_t check_var_size(u32 attributes, unsigned long size);
+-efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size);
+-
+ #if IS_ENABLED(CONFIG_EFI_CAPSULE_LOADER)
+ extern bool efi_capsule_pending(int *reset_type);
+ 
+diff --git a/include/linux/fb.h b/include/linux/fb.h
+index 07fcd0e566826..b91c770165600 100644
+--- a/include/linux/fb.h
++++ b/include/linux/fb.h
+@@ -615,8 +615,6 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
+ /* drivers/video/fbmem.c */
+ extern int register_framebuffer(struct fb_info *fb_info);
+ extern void unregister_framebuffer(struct fb_info *fb_info);
+-extern int remove_conflicting_pci_framebuffers(struct pci_dev *pdev,
+-					       const char *name);
+ extern int remove_conflicting_framebuffers(struct apertures_struct *a,
+ 					   const char *name, bool primary);
+ extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
+diff --git a/include/linux/net.h b/include/linux/net.h
+index 711c3593c3b8d..18d942bbdf6e0 100644
+--- a/include/linux/net.h
++++ b/include/linux/net.h
+@@ -41,6 +41,7 @@ struct net;
+ #define SOCK_NOSPACE		2
+ #define SOCK_PASSCRED		3
+ #define SOCK_PASSSEC		4
++#define SOCK_SUPPORT_ZC		5
+ 
+ #ifndef ARCH_HAS_SOCKET_TYPES
+ /**
+diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c
+index c6536d4b2da0b..6f1d0e5df23ad 100644
+--- a/io_uring/io-wq.c
++++ b/io_uring/io-wq.c
+@@ -1164,10 +1164,10 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
+ 		wqe = kzalloc_node(sizeof(struct io_wqe), GFP_KERNEL, alloc_node);
+ 		if (!wqe)
+ 			goto err;
++		wq->wqes[node] = wqe;
+ 		if (!alloc_cpumask_var(&wqe->cpu_mask, GFP_KERNEL))
+ 			goto err;
+ 		cpumask_copy(wqe->cpu_mask, cpumask_of_node(node));
+-		wq->wqes[node] = wqe;
+ 		wqe->node = alloc_node;
+ 		wqe->acct[IO_WQ_ACCT_BOUND].max_workers = bounded;
+ 		wqe->acct[IO_WQ_ACCT_UNBOUND].max_workers =
+diff --git a/io_uring/net.c b/io_uring/net.c
+index 4878bf40f8b1c..7804ac77745b1 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -1001,6 +1001,8 @@ int io_send_zc(struct io_kiocb *req, unsigned int issue_flags)
+ 	sock = sock_from_file(req->file);
+ 	if (unlikely(!sock))
+ 		return -ENOTSOCK;
++	if (!test_bit(SOCK_SUPPORT_ZC, &sock->flags))
++		return -EOPNOTSUPP;
+ 
+ 	msg.msg_name = NULL;
+ 	msg.msg_control = NULL;
+diff --git a/kernel/gcov/gcc_4_7.c b/kernel/gcov/gcc_4_7.c
+index 460c12b7dfea2..7971e989e425b 100644
+--- a/kernel/gcov/gcc_4_7.c
++++ b/kernel/gcov/gcc_4_7.c
+@@ -30,6 +30,13 @@
+ 
+ #define GCOV_TAG_FUNCTION_LENGTH	3
+ 
++/* Since GCC 12.1 sizes are in BYTES and not in WORDS (4B). */
++#if (__GNUC__ >= 12)
++#define GCOV_UNIT_SIZE				4
++#else
++#define GCOV_UNIT_SIZE				1
++#endif
++
+ static struct gcov_info *gcov_info_head;
+ 
+ /**
+@@ -383,12 +390,18 @@ size_t convert_to_gcda(char *buffer, struct gcov_info *info)
+ 	pos += store_gcov_u32(buffer, pos, info->version);
+ 	pos += store_gcov_u32(buffer, pos, info->stamp);
+ 
++#if (__GNUC__ >= 12)
++	/* Use zero as checksum of the compilation unit. */
++	pos += store_gcov_u32(buffer, pos, 0);
++#endif
++
+ 	for (fi_idx = 0; fi_idx < info->n_functions; fi_idx++) {
+ 		fi_ptr = info->functions[fi_idx];
+ 
+ 		/* Function record. */
+ 		pos += store_gcov_u32(buffer, pos, GCOV_TAG_FUNCTION);
+-		pos += store_gcov_u32(buffer, pos, GCOV_TAG_FUNCTION_LENGTH);
++		pos += store_gcov_u32(buffer, pos,
++			GCOV_TAG_FUNCTION_LENGTH * GCOV_UNIT_SIZE);
+ 		pos += store_gcov_u32(buffer, pos, fi_ptr->ident);
+ 		pos += store_gcov_u32(buffer, pos, fi_ptr->lineno_checksum);
+ 		pos += store_gcov_u32(buffer, pos, fi_ptr->cfg_checksum);
+@@ -402,7 +415,8 @@ size_t convert_to_gcda(char *buffer, struct gcov_info *info)
+ 			/* Counter record. */
+ 			pos += store_gcov_u32(buffer, pos,
+ 					      GCOV_TAG_FOR_COUNTER(ct_idx));
+-			pos += store_gcov_u32(buffer, pos, ci_ptr->num * 2);
++			pos += store_gcov_u32(buffer, pos,
++				ci_ptr->num * 2 * GCOV_UNIT_SIZE);
+ 
+ 			for (cv_idx = 0; cv_idx < ci_ptr->num; cv_idx++) {
+ 				pos += store_gcov_u64(buffer, pos,
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 5f1d84d901c71..5fbd0a5b48f7e 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -457,6 +457,7 @@ void tcp_init_sock(struct sock *sk)
+ 	WRITE_ONCE(sk->sk_sndbuf, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_wmem[1]));
+ 	WRITE_ONCE(sk->sk_rcvbuf, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[1]));
+ 
++	set_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
+ 	sk_sockets_allocated_inc(sk);
+ }
+ EXPORT_SYMBOL(tcp_init_sock);
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 560d9eadeaa58..516b11c136daf 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1620,6 +1620,7 @@ int udp_init_sock(struct sock *sk)
+ {
+ 	skb_queue_head_init(&udp_sk(sk)->reader_queue);
+ 	sk->sk_destruct = udp_destruct_sock;
++	set_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags);
+ 	return 0;
+ }
+ EXPORT_SYMBOL_GPL(udp_init_sock);
+diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
+index 4ae8b9574778b..384426d7e9ddc 100644
+--- a/sound/pci/hda/hda_codec.c
++++ b/sound/pci/hda/hda_codec.c
+@@ -931,28 +931,8 @@ snd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr,
+ 	}
+ 
+ 	codec->bus = bus;
+-	codec->depop_delay = -1;
+-	codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
+-	codec->core.dev.release = snd_hda_codec_dev_release;
+-	codec->core.exec_verb = codec_exec_verb;
+ 	codec->core.type = HDA_DEV_LEGACY;
+ 
+-	mutex_init(&codec->spdif_mutex);
+-	mutex_init(&codec->control_mutex);
+-	snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
+-	snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
+-	snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
+-	snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
+-	snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
+-	snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
+-	snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
+-	snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8);
+-	INIT_LIST_HEAD(&codec->conn_list);
+-	INIT_LIST_HEAD(&codec->pcm_list_head);
+-	INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
+-	refcount_set(&codec->pcm_ref, 1);
+-	init_waitqueue_head(&codec->remove_sleep);
+-
+ 	return codec;
+ }
+ EXPORT_SYMBOL_GPL(snd_hda_codec_device_init);
+@@ -1005,8 +985,29 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
+ 	if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
+ 		return -EINVAL;
+ 
++	codec->core.dev.release = snd_hda_codec_dev_release;
++	codec->core.exec_verb = codec_exec_verb;
++
+ 	codec->card = card;
+ 	codec->addr = codec_addr;
++	mutex_init(&codec->spdif_mutex);
++	mutex_init(&codec->control_mutex);
++	snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
++	snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
++	snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
++	snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
++	snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
++	snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
++	snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
++	snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8);
++	INIT_LIST_HEAD(&codec->conn_list);
++	INIT_LIST_HEAD(&codec->pcm_list_head);
++	refcount_set(&codec->pcm_ref, 1);
++	init_waitqueue_head(&codec->remove_sleep);
++
++	INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
++	codec->depop_delay = -1;
++	codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
+ 
+ #ifdef CONFIG_PM
+ 	codec->power_jiffies = jiffies;

diff --git a/1004_linux-6.0.5.patch b/1004_linux-6.0.5.patch
new file mode 100644
index 00000000..e13708b0
--- /dev/null
+++ b/1004_linux-6.0.5.patch
@@ -0,0 +1,159 @@
+diff --git a/Makefile b/Makefile
+index f2e41dccdd89d..62a7398c8d06f 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 4
++SUBLEVEL = 5
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
+index f7405a58877e2..73303458e8866 100644
+--- a/drivers/clk/tegra/clk-tegra114.c
++++ b/drivers/clk/tegra/clk-tegra114.c
+@@ -1166,6 +1166,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
+ 	{ TEGRA114_CLK_I2S3_SYNC, TEGRA114_CLK_CLK_MAX, 24000000, 0 },
+ 	{ TEGRA114_CLK_I2S4_SYNC, TEGRA114_CLK_CLK_MAX, 24000000, 0 },
+ 	{ TEGRA114_CLK_VIMCLK_SYNC, TEGRA114_CLK_CLK_MAX, 24000000, 0 },
++	{ TEGRA114_CLK_PWM, TEGRA114_CLK_PLL_P, 408000000, 0 },
+ 	/* must be the last entry */
+ 	{ TEGRA114_CLK_CLK_MAX, TEGRA114_CLK_CLK_MAX, 0, 0 },
+ };
+diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
+index 934520aab6e38..7628cc470a275 100644
+--- a/drivers/clk/tegra/clk-tegra124.c
++++ b/drivers/clk/tegra/clk-tegra124.c
+@@ -1330,6 +1330,7 @@ static struct tegra_clk_init_table common_init_table[] __initdata = {
+ 	{ TEGRA124_CLK_I2S3_SYNC, TEGRA124_CLK_CLK_MAX, 24576000, 0 },
+ 	{ TEGRA124_CLK_I2S4_SYNC, TEGRA124_CLK_CLK_MAX, 24576000, 0 },
+ 	{ TEGRA124_CLK_VIMCLK_SYNC, TEGRA124_CLK_CLK_MAX, 24576000, 0 },
++	{ TEGRA124_CLK_PWM, TEGRA124_CLK_PLL_P, 408000000, 0 },
+ 	/* must be the last entry */
+ 	{ TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0 },
+ };
+diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
+index 8a4514f6d5033..422d782475532 100644
+--- a/drivers/clk/tegra/clk-tegra20.c
++++ b/drivers/clk/tegra/clk-tegra20.c
+@@ -1044,6 +1044,7 @@ static struct tegra_clk_init_table init_table[] = {
+ 	{ TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0 },
+ 	{ TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0 },
+ 	{ TEGRA20_CLK_VDE, TEGRA20_CLK_PLL_C, 300000000, 0 },
++	{ TEGRA20_CLK_PWM, TEGRA20_CLK_PLL_P, 48000000, 0 },
+ 	/* must be the last entry */
+ 	{ TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0 },
+ };
+diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
+index 499f999e91e13..a3488aaac3f78 100644
+--- a/drivers/clk/tegra/clk-tegra210.c
++++ b/drivers/clk/tegra/clk-tegra210.c
+@@ -3597,6 +3597,7 @@ static struct tegra_clk_init_table init_table[] __initdata = {
+ 	{ TEGRA210_CLK_VIMCLK_SYNC, TEGRA210_CLK_CLK_MAX, 24576000, 0 },
+ 	{ TEGRA210_CLK_HDA, TEGRA210_CLK_PLL_P, 51000000, 0 },
+ 	{ TEGRA210_CLK_HDA2CODEC_2X, TEGRA210_CLK_PLL_P, 48000000, 0 },
++	{ TEGRA210_CLK_PWM, TEGRA210_CLK_PLL_P, 48000000, 0 },
+ 	/* This MUST be the last entry. */
+ 	{ TEGRA210_CLK_CLK_MAX, TEGRA210_CLK_CLK_MAX, 0, 0 },
+ };
+diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
+index 04b4961238209..98ec1a50e8542 100644
+--- a/drivers/clk/tegra/clk-tegra30.c
++++ b/drivers/clk/tegra/clk-tegra30.c
+@@ -1237,6 +1237,7 @@ static struct tegra_clk_init_table init_table[] = {
+ 	{ TEGRA30_CLK_VIMCLK_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 },
+ 	{ TEGRA30_CLK_HDA, TEGRA30_CLK_PLL_P, 102000000, 0 },
+ 	{ TEGRA30_CLK_HDA2CODEC_2X, TEGRA30_CLK_PLL_P, 48000000, 0 },
++	{ TEGRA30_CLK_PWM, TEGRA30_CLK_PLL_P, 48000000, 0 },
+ 	/* must be the last entry */
+ 	{ TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 },
+ };
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index 015b0440df5dc..85404c62a1c27 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -48,25 +48,6 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
+ 			      struct btrfs_free_space *info, u64 offset,
+ 			      u64 bytes, bool update_stats);
+ 
+-static void __btrfs_remove_free_space_cache_locked(
+-				struct btrfs_free_space_ctl *ctl)
+-{
+-	struct btrfs_free_space *info;
+-	struct rb_node *node;
+-
+-	while ((node = rb_last(&ctl->free_space_offset)) != NULL) {
+-		info = rb_entry(node, struct btrfs_free_space, offset_index);
+-		if (!info->bitmap) {
+-			unlink_free_space(ctl, info, true);
+-			kmem_cache_free(btrfs_free_space_cachep, info);
+-		} else {
+-			free_bitmap(ctl, info);
+-		}
+-
+-		cond_resched_lock(&ctl->tree_lock);
+-	}
+-}
+-
+ static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
+ 					       struct btrfs_path *path,
+ 					       u64 offset)
+@@ -900,14 +881,7 @@ out:
+ 	return ret;
+ free_cache:
+ 	io_ctl_drop_pages(&io_ctl);
+-
+-	/*
+-	 * We need to call the _locked variant so we don't try to update the
+-	 * discard counters.
+-	 */
+-	spin_lock(&ctl->tree_lock);
+-	__btrfs_remove_free_space_cache_locked(ctl);
+-	spin_unlock(&ctl->tree_lock);
++	__btrfs_remove_free_space_cache(ctl);
+ 	goto out;
+ }
+ 
+@@ -1033,13 +1007,7 @@ int load_free_space_cache(struct btrfs_block_group *block_group)
+ 		if (ret == 0)
+ 			ret = 1;
+ 	} else {
+-		/*
+-		 * We need to call the _locked variant so we don't try to update
+-		 * the discard counters.
+-		 */
+-		spin_lock(&tmp_ctl.tree_lock);
+ 		__btrfs_remove_free_space_cache(&tmp_ctl);
+-		spin_unlock(&tmp_ctl.tree_lock);
+ 		btrfs_warn(fs_info,
+ 			   "block group %llu has wrong amount of free space",
+ 			   block_group->start);
+@@ -3002,6 +2970,25 @@ static void __btrfs_return_cluster_to_free_space(
+ 	btrfs_put_block_group(block_group);
+ }
+ 
++static void __btrfs_remove_free_space_cache_locked(
++				struct btrfs_free_space_ctl *ctl)
++{
++	struct btrfs_free_space *info;
++	struct rb_node *node;
++
++	while ((node = rb_last(&ctl->free_space_offset)) != NULL) {
++		info = rb_entry(node, struct btrfs_free_space, offset_index);
++		if (!info->bitmap) {
++			unlink_free_space(ctl, info, true);
++			kmem_cache_free(btrfs_free_space_cachep, info);
++		} else {
++			free_bitmap(ctl, info);
++		}
++
++		cond_resched_lock(&ctl->tree_lock);
++	}
++}
++
+ void __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl)
+ {
+ 	spin_lock(&ctl->tree_lock);


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-10-21 13:14 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-10-21 13:14 UTC (permalink / raw
  To: gentoo-commits

commit:     c9bd447eacb73b2cbe152115f2b1795409415cb8
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Oct 21 13:13:33 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Oct 21 13:13:33 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c9bd447e

Linux patch 6.0.3

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

 0000_README            |     4 +
 1002_linux-6.0.3.patch | 32375 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 32379 insertions(+)

diff --git a/0000_README b/0000_README
index 5fd3d6cf..e5b9be05 100644
--- a/0000_README
+++ b/0000_README
@@ -51,6 +51,10 @@ Patch:  1001_linux-6.0.2.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.2
 
+Patch:  1002_linux-6.0.3.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.3
+
 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/1002_linux-6.0.3.patch b/1002_linux-6.0.3.patch
new file mode 100644
index 00000000..562d06c9
--- /dev/null
+++ b/1002_linux-6.0.3.patch
@@ -0,0 +1,32375 @@
+diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
+index e81ba6f5e1c87..6e1b925f30bf0 100644
+--- a/Documentation/ABI/testing/sysfs-bus-iio
++++ b/Documentation/ABI/testing/sysfs-bus-iio
+@@ -196,7 +196,7 @@ Description:
+ 		Raw capacitance measurement from channel Y. Units after
+ 		application of scale and offset are nanofarads.
+ 
+-What:		/sys/.../iio:deviceX/in_capacitanceY-in_capacitanceZ_raw
++What:		/sys/.../iio:deviceX/in_capacitanceY-capacitanceZ_raw
+ KernelVersion:	3.2
+ Contact:	linux-iio@vger.kernel.org
+ Description:
+diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
+index 426fa892d311a..2bc11a61c4d01 100644
+--- a/Documentation/admin-guide/kernel-parameters.txt
++++ b/Documentation/admin-guide/kernel-parameters.txt
+@@ -3805,6 +3805,10 @@
+ 
+ 	nox2apic	[X86-64,APIC] Do not enable x2APIC mode.
+ 
++			NOTE: this parameter will be ignored on systems with the
++			LEGACY_XAPIC_DISABLED bit set in the
++			IA32_XAPIC_DISABLE_STATUS MSR.
++
+ 	nps_mtm_hs_ctr=	[KNL,ARC]
+ 			This parameter sets the maximum duration, in
+ 			cycles, each HW thread of the CTOP can run
+diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
+index fda97b3fcf018..b8ae278a4c873 100644
+--- a/Documentation/arm64/silicon-errata.rst
++++ b/Documentation/arm64/silicon-errata.rst
+@@ -76,6 +76,8 @@ stable kernels.
+ +----------------+-----------------+-----------------+-----------------------------+
+ | ARM            | Cortex-A55      | #1530923        | ARM64_ERRATUM_1530923       |
+ +----------------+-----------------+-----------------+-----------------------------+
++| ARM            | Cortex-A55      | #2441007        | ARM64_ERRATUM_2441007       |
+++----------------+-----------------+-----------------+-----------------------------+
+ | ARM            | Cortex-A57      | #832075         | ARM64_ERRATUM_832075        |
+ +----------------+-----------------+-----------------+-----------------------------+
+ | ARM            | Cortex-A57      | #852523         | N/A                         |
+diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
+index 6cd6953e175b3..b2ef2449aed99 100644
+--- a/Documentation/filesystems/vfs.rst
++++ b/Documentation/filesystems/vfs.rst
+@@ -274,6 +274,9 @@ or bottom half).
+ 	This is specifically for the inode itself being marked dirty,
+ 	not its data.  If the update needs to be persisted by fdatasync(),
+ 	then I_DIRTY_DATASYNC will be set in the flags argument.
++	I_DIRTY_TIME will be set in the flags in case lazytime is enabled
++	and struct inode has times updated since the last ->dirty_inode
++	call.
+ 
+ ``write_inode``
+ 	this method is called when the VFS needs to write an inode to
+diff --git a/Documentation/trace/coresight/coresight-cpu-debug.rst b/Documentation/trace/coresight/coresight-cpu-debug.rst
+index 993dd294b81ba..836b35532667c 100644
+--- a/Documentation/trace/coresight/coresight-cpu-debug.rst
++++ b/Documentation/trace/coresight/coresight-cpu-debug.rst
+@@ -117,7 +117,8 @@ divide into below cases:
+ Device Tree Bindings
+ --------------------
+ 
+-See Documentation/devicetree/bindings/arm/coresight-cpu-debug.txt for details.
++See Documentation/devicetree/bindings/arm/arm,coresight-cpu-debug.yaml for
++details.
+ 
+ 
+ How to use the module
+diff --git a/Makefile b/Makefile
+index aa449693ad09d..d4297b3d0735a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 2
++SUBLEVEL = 3
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 87badeae3181e..11ecf09aadc86 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1671,7 +1671,6 @@ config CMDLINE
+ choice
+ 	prompt "Kernel command line type" if CMDLINE != ""
+ 	default CMDLINE_FROM_BOOTLOADER
+-	depends on ATAGS
+ 
+ config CMDLINE_FROM_BOOTLOADER
+ 	bool "Use bootloader kernel arguments if available"
+diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
+index cb2e069dc73fd..abfed1aa2baa8 100644
+--- a/arch/arm/boot/compressed/misc.c
++++ b/arch/arm/boot/compressed/misc.c
+@@ -23,7 +23,9 @@ unsigned int __machine_arch_type;
+ #include <linux/types.h>
+ #include <linux/linkage.h>
+ #include "misc.h"
++#ifdef CONFIG_ARCH_EP93XX
+ #include "misc-ep93xx.h"
++#endif
+ 
+ static void putstr(const char *ptr);
+ 
+diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S
+index 1bcb68ac4b011..3fcb3e62dc569 100644
+--- a/arch/arm/boot/compressed/vmlinux.lds.S
++++ b/arch/arm/boot/compressed/vmlinux.lds.S
+@@ -23,6 +23,7 @@ SECTIONS
+     *(.ARM.extab*)
+     *(.note.*)
+     *(.rel.*)
++    *(.printk_index)
+     /*
+      * Discard any r/w data - this produces a link error if we have any,
+      * which is required for PIC decompression.  Local data generates
+@@ -57,6 +58,7 @@ SECTIONS
+     *(.rodata)
+     *(.rodata.*)
+     *(.data.rel.ro)
++    *(.data.rel.ro.*)
+   }
+   .piggydata : {
+     *(.piggydata)
+diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+index d1e0db6e57307..a41902e3815cd 100644
+--- a/arch/arm/boot/dts/armada-385-turris-omnia.dts
++++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts
+@@ -476,7 +476,7 @@
+ 		marvell,function = "spi0";
+ 	};
+ 
+-	spi0cs1_pins: spi0cs1-pins {
++	spi0cs2_pins: spi0cs2-pins {
+ 		marvell,pins = "mpp26";
+ 		marvell,function = "spi0";
+ 	};
+@@ -511,7 +511,7 @@
+ 		};
+ 	};
+ 
+-	/* MISO, MOSI, SCLK and CS1 are routed to pin header CN11 */
++	/* MISO, MOSI, SCLK and CS2 are routed to pin header CN11 */
+ };
+ 
+ &uart0 {
+diff --git a/arch/arm/boot/dts/exynos4412-midas.dtsi b/arch/arm/boot/dts/exynos4412-midas.dtsi
+index b967397a46c5b..8e1c19a8ad06d 100644
+--- a/arch/arm/boot/dts/exynos4412-midas.dtsi
++++ b/arch/arm/boot/dts/exynos4412-midas.dtsi
+@@ -586,7 +586,7 @@
+ 		clocks = <&camera 1>;
+ 		clock-names = "extclk";
+ 		samsung,camclk-out = <1>;
+-		gpios = <&gpm1 6 GPIO_ACTIVE_HIGH>;
++		gpios = <&gpm1 6 GPIO_ACTIVE_LOW>;
+ 
+ 		port {
+ 			is_s5k6a3_ep: endpoint {
+diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
+index 6db09dba07ffd..a3905e27b9cd9 100644
+--- a/arch/arm/boot/dts/exynos4412-origen.dts
++++ b/arch/arm/boot/dts/exynos4412-origen.dts
+@@ -95,7 +95,7 @@
+ };
+ 
+ &ehci {
+-	samsung,vbus-gpio = <&gpx3 5 1>;
++	samsung,vbus-gpio = <&gpx3 5 GPIO_ACTIVE_HIGH>;
+ 	status = "okay";
+ 	phys = <&exynos_usbphy 2>, <&exynos_usbphy 3>;
+ 	phy-names = "hsic0", "hsic1";
+diff --git a/arch/arm/boot/dts/imx6dl-riotboard.dts b/arch/arm/boot/dts/imx6dl-riotboard.dts
+index e7d9bfbfd0e4d..e7be05f205d32 100644
+--- a/arch/arm/boot/dts/imx6dl-riotboard.dts
++++ b/arch/arm/boot/dts/imx6dl-riotboard.dts
+@@ -90,6 +90,7 @@
+ 	pinctrl-0 = <&pinctrl_enet>;
+ 	phy-mode = "rgmii-id";
+ 	phy-handle = <&rgmii_phy>;
++	/delete-property/ interrupts;
+ 	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ 			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ 	fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi
+index 8e0ed209ede06..dc919e09a505f 100644
+--- a/arch/arm/boot/dts/imx6dl.dtsi
++++ b/arch/arm/boot/dts/imx6dl.dtsi
+@@ -84,6 +84,9 @@
+ 		ocram: sram@900000 {
+ 			compatible = "mmio-sram";
+ 			reg = <0x00900000 0x20000>;
++			ranges = <0 0x00900000 0x20000>;
++			#address-cells = <1>;
++			#size-cells = <1>;
+ 			clocks = <&clks IMX6QDL_CLK_OCRAM>;
+ 		};
+ 
+diff --git a/arch/arm/boot/dts/imx6q-arm2.dts b/arch/arm/boot/dts/imx6q-arm2.dts
+index 0b40f52268b3c..75586299d9cab 100644
+--- a/arch/arm/boot/dts/imx6q-arm2.dts
++++ b/arch/arm/boot/dts/imx6q-arm2.dts
+@@ -178,6 +178,7 @@
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&pinctrl_enet>;
+ 	phy-mode = "rgmii";
++	/delete-property/ interrupts;
+ 	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ 			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ 	fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6q-evi.dts b/arch/arm/boot/dts/imx6q-evi.dts
+index c63f371ede8b9..78d941fef5dfb 100644
+--- a/arch/arm/boot/dts/imx6q-evi.dts
++++ b/arch/arm/boot/dts/imx6q-evi.dts
+@@ -146,6 +146,7 @@
+ 	pinctrl-0 = <&pinctrl_enet>;
+ 	phy-mode = "rgmii";
+ 	phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
++	/delete-property/ interrupts;
+ 	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ 			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ 	fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6q-mccmon6.dts b/arch/arm/boot/dts/imx6q-mccmon6.dts
+index 55692c73943d6..64ab01018b71e 100644
+--- a/arch/arm/boot/dts/imx6q-mccmon6.dts
++++ b/arch/arm/boot/dts/imx6q-mccmon6.dts
+@@ -100,6 +100,7 @@
+ 	pinctrl-0 = <&pinctrl_enet>;
+ 	phy-mode = "rgmii";
+ 	phy-reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
++	/delete-property/ interrupts;
+ 	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ 			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ 	status = "okay";
+diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
+index 3b77eae40e395..df86049a695b1 100644
+--- a/arch/arm/boot/dts/imx6q.dtsi
++++ b/arch/arm/boot/dts/imx6q.dtsi
+@@ -163,6 +163,9 @@
+ 		ocram: sram@900000 {
+ 			compatible = "mmio-sram";
+ 			reg = <0x00900000 0x40000>;
++			ranges = <0 0x00900000 0x40000>;
++			#address-cells = <1>;
++			#size-cells = <1>;
+ 			clocks = <&clks IMX6QDL_CLK_OCRAM>;
+ 		};
+ 
+diff --git a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi
+index 6b791d515e294..683f6e58ab230 100644
+--- a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi
+@@ -263,6 +263,10 @@
+ 	phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+ };
+ 
++&hdmi {
++	ddc-i2c-bus = <&i2c2>;
++};
++
+ &i2c_intern {
+ 	pmic@8 {
+ 		compatible = "fsl,pfuze100";
+@@ -387,7 +391,7 @@
+ 
+ /* HDMI_CTRL */
+ &i2c2 {
+-	clock-frequency = <375000>;
++	clock-frequency = <100000>;
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&pinctrl_i2c2>;
+ };
+diff --git a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
+index 0ad4cb4f1e828..a53a5d0766a51 100644
+--- a/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
+@@ -192,6 +192,7 @@
+ 	phy-mode = "rgmii";
+ 	phy-handle = <&ethphy>;
+ 	phy-reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
++	/delete-property/ interrupts;
+ 	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ 			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ 	fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
+index beaa2dcd436ce..57c21a01f126d 100644
+--- a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi
+@@ -334,6 +334,7 @@
+ 	phy-mode = "rgmii";
+ 	phy-handle = <&ethphy>;
+ 	phy-reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
++	/delete-property/ interrupts;
+ 	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ 			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ 	fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
+index ee7e2371f94bd..000e9dc97b1ac 100644
+--- a/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_som2.dtsi
+@@ -263,6 +263,7 @@
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&pinctrl_enet>;
+ 	phy-mode = "rgmii";
++	/delete-property/ interrupts;
+ 	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ 			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ 	fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+index 904d5d051d63c..731759bdd7f57 100644
+--- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+@@ -267,6 +267,7 @@
+ 	phy-mode = "rgmii";
+ 	phy-handle = <&ethphy>;
+ 	phy-reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
++	/delete-property/ interrupts;
+ 	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ 			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ 	fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
+index 1368a47620372..3dbb460ef102e 100644
+--- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
+@@ -295,6 +295,7 @@
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&pinctrl_enet>;
+ 	phy-mode = "rgmii-id";
++	/delete-property/ interrupts;
+ 	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ 			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ 	fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi b/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi
+index 7dc3f0005b0f0..0a36e1bce375d 100644
+--- a/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-tqma6a.dtsi
+@@ -7,6 +7,7 @@
+ #include <dt-bindings/gpio/gpio.h>
+ 
+ &fec {
++	/delete-property/ interrupts;
+ 	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ 			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ 	fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qdl-ts7970.dtsi b/arch/arm/boot/dts/imx6qdl-ts7970.dtsi
+index d6ba4b2a60f6f..c096d25a6f5b5 100644
+--- a/arch/arm/boot/dts/imx6qdl-ts7970.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-ts7970.dtsi
+@@ -192,6 +192,7 @@
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&pinctrl_enet>;
+ 	phy-mode = "rgmii";
++	/delete-property/ interrupts;
+ 	interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
+ 			      <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
+ 	fsl,err006687-workaround-present;
+diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi
+index 0503655138363..fc164991d2ae8 100644
+--- a/arch/arm/boot/dts/imx6qp.dtsi
++++ b/arch/arm/boot/dts/imx6qp.dtsi
+@@ -9,12 +9,18 @@
+ 		ocram2: sram@940000 {
+ 			compatible = "mmio-sram";
+ 			reg = <0x00940000 0x20000>;
++			ranges = <0 0x00940000 0x20000>;
++			#address-cells = <1>;
++			#size-cells = <1>;
+ 			clocks = <&clks IMX6QDL_CLK_OCRAM>;
+ 		};
+ 
+ 		ocram3: sram@960000 {
+ 			compatible = "mmio-sram";
+ 			reg = <0x00960000 0x20000>;
++			ranges = <0 0x00960000 0x20000>;
++			#address-cells = <1>;
++			#size-cells = <1>;
+ 			clocks = <&clks IMX6QDL_CLK_OCRAM>;
+ 		};
+ 
+diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
+index 06a515121dfc5..01122ddfdc0d3 100644
+--- a/arch/arm/boot/dts/imx6sl.dtsi
++++ b/arch/arm/boot/dts/imx6sl.dtsi
+@@ -61,10 +61,10 @@
+ 				<792000  1175000>,
+ 				<396000  975000>;
+ 			fsl,soc-operating-points =
+-				/* ARM kHz      SOC-PU uV */
+-				<996000         1225000>,
+-				<792000         1175000>,
+-				<396000         1175000>;
++				/* ARM kHz	SOC-PU uV */
++				<996000		1225000>,
++				<792000		1175000>,
++				<396000		1175000>;
+ 			clock-latency = <61036>; /* two CLK32 periods */
+ 			#cooling-cells = <2>;
+ 			clocks = <&clks IMX6SL_CLK_ARM>, <&clks IMX6SL_CLK_PLL2_PFD2>,
+@@ -115,6 +115,9 @@
+ 		ocram: sram@900000 {
+ 			compatible = "mmio-sram";
+ 			reg = <0x00900000 0x20000>;
++			ranges = <0 0x00900000 0x20000>;
++			#address-cells = <1>;
++			#size-cells = <1>;
+ 			clocks = <&clks IMX6SL_CLK_OCRAM>;
+ 		};
+ 
+@@ -222,7 +225,7 @@
+ 
+ 				uart5: serial@2018000 {
+ 					compatible = "fsl,imx6sl-uart",
+-						   "fsl,imx6q-uart", "fsl,imx21-uart";
++						     "fsl,imx6q-uart", "fsl,imx21-uart";
+ 					reg = <0x02018000 0x4000>;
+ 					interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>;
+ 					clocks = <&clks IMX6SL_CLK_UART>,
+@@ -235,7 +238,7 @@
+ 
+ 				uart1: serial@2020000 {
+ 					compatible = "fsl,imx6sl-uart",
+-						   "fsl,imx6q-uart", "fsl,imx21-uart";
++						     "fsl,imx6q-uart", "fsl,imx21-uart";
+ 					reg = <0x02020000 0x4000>;
+ 					interrupts = <0 26 IRQ_TYPE_LEVEL_HIGH>;
+ 					clocks = <&clks IMX6SL_CLK_UART>,
+@@ -248,7 +251,7 @@
+ 
+ 				uart2: serial@2024000 {
+ 					compatible = "fsl,imx6sl-uart",
+-						   "fsl,imx6q-uart", "fsl,imx21-uart";
++						     "fsl,imx6q-uart", "fsl,imx21-uart";
+ 					reg = <0x02024000 0x4000>;
+ 					interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH>;
+ 					clocks = <&clks IMX6SL_CLK_UART>,
+@@ -309,7 +312,7 @@
+ 
+ 				uart3: serial@2034000 {
+ 					compatible = "fsl,imx6sl-uart",
+-						   "fsl,imx6q-uart", "fsl,imx21-uart";
++						     "fsl,imx6q-uart", "fsl,imx21-uart";
+ 					reg = <0x02034000 0x4000>;
+ 					interrupts = <0 28 IRQ_TYPE_LEVEL_HIGH>;
+ 					clocks = <&clks IMX6SL_CLK_UART>,
+@@ -322,7 +325,7 @@
+ 
+ 				uart4: serial@2038000 {
+ 					compatible = "fsl,imx6sl-uart",
+-						   "fsl,imx6q-uart", "fsl,imx21-uart";
++						     "fsl,imx6q-uart", "fsl,imx21-uart";
+ 					reg = <0x02038000 0x4000>;
+ 					interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>;
+ 					clocks = <&clks IMX6SL_CLK_UART>,
+@@ -711,7 +714,7 @@
+ 						#power-domain-cells = <0>;
+ 						power-supply = <&reg_pu>;
+ 						clocks = <&clks IMX6SL_CLK_GPU2D_OVG>,
+-						         <&clks IMX6SL_CLK_GPU2D_PODF>;
++							 <&clks IMX6SL_CLK_GPU2D_PODF>;
+ 					};
+ 
+ 					pd_disp: power-domain@2 {
+diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi
+index d4a000c3dde70..2873369a57c02 100644
+--- a/arch/arm/boot/dts/imx6sll.dtsi
++++ b/arch/arm/boot/dts/imx6sll.dtsi
+@@ -115,6 +115,9 @@
+ 		ocram: sram@900000 {
+ 			compatible = "mmio-sram";
+ 			reg = <0x00900000 0x20000>;
++			ranges = <0 0x00900000 0x20000>;
++			#address-cells = <1>;
++			#size-cells = <1>;
+ 		};
+ 
+ 		intc: interrupt-controller@a01000 {
+diff --git a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
+index 35861bbea94e6..c84ea1fac5e98 100644
+--- a/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
++++ b/arch/arm/boot/dts/imx6sx-udoo-neo.dtsi
+@@ -226,7 +226,7 @@
+ &iomuxc {
+ 	pinctrl_bt_reg: btreggrp {
+ 		fsl,pins =
+-			<MX6SX_PAD_KEY_ROW2__GPIO2_IO_17        0x15059>;
++			<MX6SX_PAD_KEY_ROW2__GPIO2_IO_17	0x15059>;
+ 	};
+ 
+ 	pinctrl_enet1: enet1grp {
+@@ -306,7 +306,6 @@
+ 		>;
+ 	};
+ 
+-
+ 	pinctrl_uart1: uart1grp {
+ 		fsl,pins =
+ 			<MX6SX_PAD_GPIO1_IO04__UART1_DCE_TX	0x1b0b1>,
+@@ -347,24 +346,23 @@
+ 
+ 	pinctrl_otg1_reg: otg1grp {
+ 		fsl,pins =
+-			<MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9        0x10b0>;
++			<MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9	0x10b0>;
+ 	};
+ 
+-
+ 	pinctrl_otg2_reg: otg2grp {
+ 		fsl,pins =
+-			<MX6SX_PAD_NAND_RE_B__GPIO4_IO_12        0x10b0>;
++			<MX6SX_PAD_NAND_RE_B__GPIO4_IO_12	0x10b0>;
+ 	};
+ 
+ 	pinctrl_usb_otg1: usbotg1grp {
+ 		fsl,pins =
+-			<MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID    0x17059>,
+-			<MX6SX_PAD_GPIO1_IO08__USB_OTG1_OC       0x10b0>;
++			<MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID	0x17059>,
++			<MX6SX_PAD_GPIO1_IO08__USB_OTG1_OC	0x10b0>;
+ 	};
+ 
+ 	pinctrl_usb_otg2: usbot2ggrp {
+ 		fsl,pins =
+-			<MX6SX_PAD_QSPI1A_DATA0__USB_OTG2_OC     0x10b0>;
++			<MX6SX_PAD_QSPI1A_DATA0__USB_OTG2_OC	0x10b0>;
+ 	};
+ 
+ 	pinctrl_usdhc2: usdhc2grp {
+diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
+index 4d075e2bf7496..2611eef3b2a20 100644
+--- a/arch/arm/boot/dts/imx6sx.dtsi
++++ b/arch/arm/boot/dts/imx6sx.dtsi
+@@ -164,12 +164,18 @@
+ 		ocram_s: sram@8f8000 {
+ 			compatible = "mmio-sram";
+ 			reg = <0x008f8000 0x4000>;
++			ranges = <0 0x008f8000 0x4000>;
++			#address-cells = <1>;
++			#size-cells = <1>;
+ 			clocks = <&clks IMX6SX_CLK_OCRAM_S>;
+ 		};
+ 
+ 		ocram: sram@900000 {
+ 			compatible = "mmio-sram";
+ 			reg = <0x00900000 0x20000>;
++			ranges = <0 0x00900000 0x20000>;
++			#address-cells = <1>;
++			#size-cells = <1>;
+ 			clocks = <&clks IMX6SX_CLK_OCRAM>;
+ 		};
+ 
+diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
+index 78f4224a9bf4e..e93b9cd9c27b2 100644
+--- a/arch/arm/boot/dts/imx7d-sdb.dts
++++ b/arch/arm/boot/dts/imx7d-sdb.dts
+@@ -206,12 +206,7 @@
+ 		interrupt-parent = <&gpio2>;
+ 		interrupts = <29 0>;
+ 		pendown-gpio = <&gpio2 29 GPIO_ACTIVE_HIGH>;
+-		ti,x-min = /bits/ 16 <0>;
+-		ti,x-max = /bits/ 16 <0>;
+-		ti,y-min = /bits/ 16 <0>;
+-		ti,y-max = /bits/ 16 <0>;
+-		ti,pressure-max = /bits/ 16 <0>;
+-		ti,x-plate-ohms = /bits/ 16 <400>;
++		touchscreen-max-pressure = <255>;
+ 		wakeup-source;
+ 	};
+ };
+diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi
+index 7b151acb99846..88b70ba1c8fee 100644
+--- a/arch/arm/boot/dts/kirkwood-lsxl.dtsi
++++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi
+@@ -10,6 +10,11 @@
+ 
+ 	ocp@f1000000 {
+ 		pinctrl: pin-controller@10000 {
++			/* Non-default UART pins */
++			pmx_uart0: pmx-uart0 {
++				marvell,pins = "mpp4", "mpp5";
++			};
++
+ 			pmx_power_hdd: pmx-power-hdd {
+ 				marvell,pins = "mpp10";
+ 				marvell,function = "gpo";
+@@ -213,22 +218,11 @@
+ &mdio {
+ 	status = "okay";
+ 
+-	ethphy0: ethernet-phy@0 {
+-		reg = <0>;
+-	};
+-
+ 	ethphy1: ethernet-phy@8 {
+ 		reg = <8>;
+ 	};
+ };
+ 
+-&eth0 {
+-	status = "okay";
+-	ethernet0-port@0 {
+-		phy-handle = <&ethphy0>;
+-	};
+-};
+-
+ &eth1 {
+ 	status = "okay";
+ 	ethernet1-port@0 {
+diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h
+index 3e78f921b8b2d..39be2d1aa27b8 100644
+--- a/arch/arm/include/asm/stacktrace.h
++++ b/arch/arm/include/asm/stacktrace.h
+@@ -21,6 +21,9 @@ struct stackframe {
+ 	struct llist_node *kr_cur;
+ 	struct task_struct *tsk;
+ #endif
++#ifdef CONFIG_UNWINDER_FRAME_POINTER
++	bool ex_frame;
++#endif
+ };
+ 
+ static __always_inline
+@@ -34,6 +37,9 @@ void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame)
+ 		frame->kr_cur = NULL;
+ 		frame->tsk = current;
+ #endif
++#ifdef CONFIG_UNWINDER_FRAME_POINTER
++		frame->ex_frame = in_entry_text(frame->pc);
++#endif
+ }
+ 
+ extern int unwind_frame(struct stackframe *frame);
+diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
+index 8aac1e10b117a..38f1ea9c724d5 100644
+--- a/arch/arm/kernel/return_address.c
++++ b/arch/arm/kernel/return_address.c
+@@ -47,6 +47,7 @@ here:
+ 	frame.kr_cur = NULL;
+ 	frame.tsk = current;
+ #endif
++	frame.ex_frame = false;
+ 
+ 	walk_stackframe(&frame, save_return_addr, &data);
+ 
+diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
+index d0fa2037460ac..85443b5d19221 100644
+--- a/arch/arm/kernel/stacktrace.c
++++ b/arch/arm/kernel/stacktrace.c
+@@ -9,6 +9,8 @@
+ #include <asm/stacktrace.h>
+ #include <asm/traps.h>
+ 
++#include "reboot.h"
++
+ #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
+ /*
+  * Unwind the current stack frame and store the new register values in the
+@@ -39,29 +41,74 @@
+  * Note that with framepointer enabled, even the leaf functions have the same
+  * prologue and epilogue, therefore we can ignore the LR value in this case.
+  */
+-int notrace unwind_frame(struct stackframe *frame)
++
++extern unsigned long call_with_stack_end;
++
++static int frame_pointer_check(struct stackframe *frame)
+ {
+ 	unsigned long high, low;
+ 	unsigned long fp = frame->fp;
++	unsigned long pc = frame->pc;
++
++	/*
++	 * call_with_stack() is the only place we allow SP to jump from one
++	 * stack to another, with FP and SP pointing to different stacks,
++	 * skipping the FP boundary check at this point.
++	 */
++	if (pc >= (unsigned long)&call_with_stack &&
++			pc < (unsigned long)&call_with_stack_end)
++		return 0;
+ 
+ 	/* only go to a higher address on the stack */
+ 	low = frame->sp;
+ 	high = ALIGN(low, THREAD_SIZE);
+ 
+-#ifdef CONFIG_CC_IS_CLANG
+ 	/* check current frame pointer is within bounds */
++#ifdef CONFIG_CC_IS_CLANG
+ 	if (fp < low + 4 || fp > high - 4)
+ 		return -EINVAL;
+-
+-	frame->sp = frame->fp;
+-	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
+-	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 4));
+ #else
+-	/* check current frame pointer is within bounds */
+ 	if (fp < low + 12 || fp > high - 4)
+ 		return -EINVAL;
++#endif
++
++	return 0;
++}
++
++int notrace unwind_frame(struct stackframe *frame)
++{
++	unsigned long fp = frame->fp;
++
++	if (frame_pointer_check(frame))
++		return -EINVAL;
++
++	/*
++	 * When we unwind through an exception stack, include the saved PC
++	 * value into the stack trace.
++	 */
++	if (frame->ex_frame) {
++		struct pt_regs *regs = (struct pt_regs *)frame->sp;
++
++		/*
++		 * We check that 'regs + sizeof(struct pt_regs)' (that is,
++		 * &regs[1]) does not exceed the bottom of the stack to avoid
++		 * accessing data outside the task's stack. This may happen
++		 * when frame->ex_frame is a false positive.
++		 */
++		if ((unsigned long)&regs[1] > ALIGN(frame->sp, THREAD_SIZE))
++			return -EINVAL;
++
++		frame->pc = regs->ARM_pc;
++		frame->ex_frame = false;
++		return 0;
++	}
+ 
+ 	/* restore the registers from the stack frame */
++#ifdef CONFIG_CC_IS_CLANG
++	frame->sp = frame->fp;
++	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
++	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 4));
++#else
+ 	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp - 12));
+ 	frame->sp = READ_ONCE_NOCHECK(*(unsigned long *)(fp - 8));
+ 	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp - 4));
+@@ -72,6 +119,9 @@ int notrace unwind_frame(struct stackframe *frame)
+ 					(void *)frame->fp, &frame->kr_cur);
+ #endif
+ 
++	if (in_entry_text(frame->pc))
++		frame->ex_frame = true;
++
+ 	return 0;
+ }
+ #endif
+@@ -102,7 +152,6 @@ static int save_trace(struct stackframe *frame, void *d)
+ {
+ 	struct stack_trace_data *data = d;
+ 	struct stack_trace *trace = data->trace;
+-	struct pt_regs *regs;
+ 	unsigned long addr = frame->pc;
+ 
+ 	if (data->no_sched_functions && in_sched_functions(addr))
+@@ -113,19 +162,6 @@ static int save_trace(struct stackframe *frame, void *d)
+ 	}
+ 
+ 	trace->entries[trace->nr_entries++] = addr;
+-
+-	if (trace->nr_entries >= trace->max_entries)
+-		return 1;
+-
+-	if (!in_entry_text(frame->pc))
+-		return 0;
+-
+-	regs = (struct pt_regs *)frame->sp;
+-	if ((unsigned long)&regs[1] > ALIGN(frame->sp, THREAD_SIZE))
+-		return 0;
+-
+-	trace->entries[trace->nr_entries++] = regs->ARM_pc;
+-
+ 	return trace->nr_entries >= trace->max_entries;
+ }
+ 
+@@ -167,6 +203,9 @@ here:
+ 	frame.kr_cur = NULL;
+ 	frame.tsk = tsk;
+ #endif
++#ifdef CONFIG_UNWINDER_FRAME_POINTER
++	frame.ex_frame = false;
++#endif
+ 
+ 	walk_stackframe(&frame, save_trace, &data);
+ }
+@@ -188,6 +227,9 @@ void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
+ 	frame.kr_cur = NULL;
+ 	frame.tsk = current;
+ #endif
++#ifdef CONFIG_UNWINDER_FRAME_POINTER
++	frame.ex_frame = in_entry_text(frame.pc);
++#endif
+ 
+ 	walk_stackframe(&frame, save_trace, &data);
+ }
+diff --git a/arch/arm/lib/call_with_stack.S b/arch/arm/lib/call_with_stack.S
+index 0a268a6c513c8..5030d4e8d1267 100644
+--- a/arch/arm/lib/call_with_stack.S
++++ b/arch/arm/lib/call_with_stack.S
+@@ -46,4 +46,6 @@ UNWIND( .setfp	fpreg, sp	)
+ 	pop	{fpreg, pc}
+ UNWIND( .fnend			)
+ #endif
++	.globl call_with_stack_end
++call_with_stack_end:
+ ENDPROC(call_with_stack)
+diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
+index 089c9c644cce2..bfc7476f14114 100644
+--- a/arch/arm/mm/dma-mapping.c
++++ b/arch/arm/mm/dma-mapping.c
+@@ -1769,8 +1769,16 @@ static void arm_teardown_iommu_dma_ops(struct device *dev) { }
+ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ 			const struct iommu_ops *iommu, bool coherent)
+ {
+-	dev->archdata.dma_coherent = coherent;
+-	dev->dma_coherent = coherent;
++	/*
++	 * Due to legacy code that sets the ->dma_coherent flag from a bus
++	 * notifier we can't just assign coherent to the ->dma_coherent flag
++	 * here, but instead have to make sure we only set but never clear it
++	 * for now.
++	 */
++	if (coherent) {
++		dev->archdata.dma_coherent = true;
++		dev->dma_coherent = true;
++	}
+ 
+ 	/*
+ 	 * Don't override the dma_ops if they have already been set. Ideally
+diff --git a/arch/arm/mm/dump.c b/arch/arm/mm/dump.c
+index fb688003d156e..712da6a81b23f 100644
+--- a/arch/arm/mm/dump.c
++++ b/arch/arm/mm/dump.c
+@@ -346,7 +346,7 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
+ 		addr = start + i * PMD_SIZE;
+ 		domain = get_domain_name(pmd);
+ 		if (pmd_none(*pmd) || pmd_large(*pmd) || !pmd_present(*pmd))
+-			note_page(st, addr, 3, pmd_val(*pmd), domain);
++			note_page(st, addr, 4, pmd_val(*pmd), domain);
+ 		else
+ 			walk_pte(st, pmd, addr, domain);
+ 
+diff --git a/arch/arm/mm/kasan_init.c b/arch/arm/mm/kasan_init.c
+index 29caee9c79ce3..46d9f4a622cbc 100644
+--- a/arch/arm/mm/kasan_init.c
++++ b/arch/arm/mm/kasan_init.c
+@@ -268,12 +268,17 @@ void __init kasan_init(void)
+ 
+ 	/*
+ 	 * 1. The module global variables are in MODULES_VADDR ~ MODULES_END,
+-	 *    so we need to map this area.
++	 *    so we need to map this area if CONFIG_KASAN_VMALLOC=n. With
++	 *    VMALLOC support KASAN will manage this region dynamically,
++	 *    refer to kasan_populate_vmalloc() and ARM's implementation of
++	 *    module_alloc().
+ 	 * 2. PKMAP_BASE ~ PKMAP_BASE+PMD_SIZE's shadow and MODULES_VADDR
+ 	 *    ~ MODULES_END's shadow is in the same PMD_SIZE, so we can't
+ 	 *    use kasan_populate_zero_shadow.
+ 	 */
+-	create_mapping((void *)MODULES_VADDR, (void *)(PKMAP_BASE + PMD_SIZE));
++	if (!IS_ENABLED(CONFIG_KASAN_VMALLOC) && IS_ENABLED(CONFIG_MODULES))
++		create_mapping((void *)MODULES_VADDR, (void *)(MODULES_END));
++	create_mapping((void *)PKMAP_BASE, (void *)(PKMAP_BASE + PMD_SIZE));
+ 
+ 	/*
+ 	 * KAsan may reuse the contents of kasan_early_shadow_pte directly, so
+diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
+index a49f0b9c0f752..463fc2a8448f0 100644
+--- a/arch/arm/mm/mmu.c
++++ b/arch/arm/mm/mmu.c
+@@ -300,7 +300,11 @@ static struct mem_type mem_types[] __ro_after_init = {
+ 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ 			     L_PTE_XN | L_PTE_RDONLY,
+ 		.prot_l1   = PMD_TYPE_TABLE,
++#ifdef CONFIG_ARM_LPAE
++		.prot_sect = PMD_TYPE_SECT | L_PMD_SECT_RDONLY | PMD_SECT_AP2,
++#else
+ 		.prot_sect = PMD_TYPE_SECT,
++#endif
+ 		.domain    = DOMAIN_KERNEL,
+ 	},
+ 	[MT_ROM] = {
+diff --git a/arch/arm/plat-orion/Makefile b/arch/arm/plat-orion/Makefile
+index 4e3f25de13c19..830b0be038c6b 100644
+--- a/arch/arm/plat-orion/Makefile
++++ b/arch/arm/plat-orion/Makefile
+@@ -2,7 +2,7 @@
+ #
+ # Makefile for the linux kernel.
+ #
+-ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
++ccflags-y := -I$(srctree)/$(src)/include
+ 
+ orion-gpio-$(CONFIG_GPIOLIB)      += gpio.o
+ obj-$(CONFIG_PLAT_ORION_LEGACY)   += irq.o pcie.o time.o common.o mpp.o
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 1ce7685ad5de1..3795eb5ba1cdd 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -632,6 +632,23 @@ config ARM64_ERRATUM_1530923
+ config ARM64_WORKAROUND_REPEAT_TLBI
+ 	bool
+ 
++config ARM64_ERRATUM_2441007
++	bool "Cortex-A55: Completion of affected memory accesses might not be guaranteed by completion of a TLBI"
++	default y
++	select ARM64_WORKAROUND_REPEAT_TLBI
++	help
++	  This option adds a workaround for ARM Cortex-A55 erratum #2441007.
++
++	  Under very rare circumstances, affected Cortex-A55 CPUs
++	  may not handle a race between a break-before-make sequence on one
++	  CPU, and another CPU accessing the same page. This could allow a
++	  store to a page that has been unmapped.
++
++	  Work around this by adding the affected CPUs to the list that needs
++	  TLB sequences to be done twice.
++
++	  If unsure, say Y.
++
+ config ARM64_ERRATUM_1286807
+ 	bool "Cortex-A76: Modification of the translation table for a virtual address might lead to read-after-read ordering violation"
+ 	default y
+diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
+index 91c9bd1b47ddf..bde6a6bb8dfcf 100644
+--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
++++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
+@@ -795,7 +795,7 @@
+ 		reg = <0x27>;
+ 		interrupt-parent = <&gpa1>;
+ 		interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+-		en-gpios = <&gpf1 4 GPIO_ACTIVE_HIGH>;
++		en-gpios = <&gpf1 4 GPIO_ACTIVE_LOW>;
+ 		wake-gpios = <&gpj0 2 GPIO_ACTIVE_HIGH>;
+ 	};
+ };
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts
+index 23be1ec538ba6..c54536c0a2ba1 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts
+@@ -321,6 +321,7 @@
+ 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d0
+ 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d0
+ 			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x019
++			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0
+ 		>;
+ 	};
+ 
+@@ -333,6 +334,7 @@
+ 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d4
+ 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d4
+ 			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x019
++			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0
+ 		>;
+ 	};
+ 
+@@ -345,6 +347,7 @@
+ 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d6
+ 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d6
+ 			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x019
++			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0
+ 		>;
+ 	};
+ };
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi
+index 8f90eb02550d8..6307af803429e 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-som.dtsi
+@@ -86,7 +86,6 @@
+ 		pinctrl-0 = <&pinctrl_pmic>;
+ 		interrupt-parent = <&gpio1>;
+ 		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+-		sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ 
+ 		regulators {
+ 			reg_vdd_soc: BUCK1 {
+@@ -229,7 +228,6 @@
+ 	pinctrl_pmic: pmicgrp {
+ 		fsl,pins = <
+ 			MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0		0x141
+-			MX8MM_IOMUXC_GPIO1_IO04_GPIO1_IO4		0x141
+ 		>;
+ 	};
+ 
+diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+index fe178b7d063cb..522ab47426c35 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+@@ -1189,7 +1189,7 @@
+ 				interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ 				phys = <&usb3_phy0>, <&usb3_phy0>;
+ 				phy-names = "usb2-phy", "usb3-phy";
+-				snps,dis-u2-freeclk-exists-quirk;
++				snps,gfladj-refclk-lpm-sel-quirk;
+ 			};
+ 
+ 		};
+@@ -1231,7 +1231,7 @@
+ 				interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ 				phys = <&usb3_phy1>, <&usb3_phy1>;
+ 				phy-names = "usb2-phy", "usb3-phy";
+-				snps,dis-u2-freeclk-exists-quirk;
++				snps,gfladj-refclk-lpm-sel-quirk;
+ 			};
+ 		};
+ 
+diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+index 9eec8a7eecfc8..127fc7f904c87 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+@@ -1077,6 +1077,7 @@
+ 		interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+ 		pinctrl-names = "default";
+ 		pinctrl-0 = <&pinctrl_gauge>;
++		power-supplies = <&bq25895>;
+ 		maxim,over-heat-temp = <700>;
+ 		maxim,over-volt = <4500>;
+ 		maxim,rsns-microohm = <5000>;
+diff --git a/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi b/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
+index 80b44c7df56aa..881bf948d1dff 100644
+--- a/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
++++ b/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
+@@ -117,8 +117,8 @@
+ 				pinctrl-names = "default", "gpio";
+ 				pinctrl-0 = <&i2c0_pins>;
+ 				pinctrl-1 = <&i2c0_gpio>;
+-				scl_gpio = <&gpio0 26 GPIO_ACTIVE_HIGH>;
+-				sda_gpio = <&gpio0 27 GPIO_ACTIVE_HIGH>;
++				scl-gpios = <&gpio0 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
++				sda-gpios = <&gpio0 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ 				status = "disabled";
+ 			};
+ 
+@@ -136,8 +136,8 @@
+ 				pinctrl-names = "default", "gpio";
+ 				pinctrl-0 = <&i2c1_pins>;
+ 				pinctrl-1 = <&i2c1_gpio>;
+-				scl_gpio = <&gpio0 20 GPIO_ACTIVE_HIGH>;
+-				sda_gpio = <&gpio0 21 GPIO_ACTIVE_HIGH>;
++				scl-gpios = <&gpio0 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
++				sda-gpios = <&gpio0 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ 				status = "disabled";
+ 			};
+ 
+diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+index d53675fc15959..b9bf43215ada9 100644
+--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
++++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+@@ -199,7 +199,7 @@
+ 
+ 		pcie_qmp0: phy@86000 {
+ 			compatible = "qcom,ipq8074-qmp-pcie-phy";
+-			reg = <0x00086000 0x1000>;
++			reg = <0x00086000 0x1c4>;
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+ 			ranges;
+@@ -227,7 +227,7 @@
+ 
+ 		pcie_qmp1: phy@8e000 {
+ 			compatible = "qcom,ipq8074-qmp-pcie-phy";
+-			reg = <0x0008e000 0x1000>;
++			reg = <0x0008e000 0x1c4>;
+ 			#address-cells = <1>;
+ 			#size-cells = <1>;
+ 			ranges;
+diff --git a/arch/arm64/boot/dts/qcom/pm8350c.dtsi b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
+index e0bbb67717fec..f28e71487d5c7 100644
+--- a/arch/arm64/boot/dts/qcom/pm8350c.dtsi
++++ b/arch/arm64/boot/dts/qcom/pm8350c.dtsi
+@@ -30,9 +30,8 @@
+ 			#interrupt-cells = <2>;
+ 		};
+ 
+-		pm8350c_pwm: pwm@e800 {
++		pm8350c_pwm: pwm {
+ 			compatible = "qcom,pm8350c-pwm";
+-			reg = <0xe800>;
+ 			#pwm-cells = <2>;
+ 			status = "disabled";
+ 		};
+diff --git a/arch/arm64/boot/dts/qcom/sa8295p-adp.dts b/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
+index 9398f0349944e..ca5f5ad32ce5f 100644
+--- a/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
++++ b/arch/arm64/boot/dts/qcom/sa8295p-adp.dts
+@@ -35,7 +35,6 @@
+ 			regulator-min-microvolt = <1200000>;
+ 			regulator-max-microvolt = <1208000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l5a: ldo5 {
+@@ -43,7 +42,6 @@
+ 			regulator-min-microvolt = <912000>;
+ 			regulator-max-microvolt = <912000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l7a: ldo7 {
+@@ -51,7 +49,6 @@
+ 			regulator-min-microvolt = <1800000>;
+ 			regulator-max-microvolt = <1800000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l13a: ldo13 {
+@@ -59,7 +56,6 @@
+ 			regulator-min-microvolt = <3072000>;
+ 			regulator-max-microvolt = <3072000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 	};
+ 
+@@ -72,7 +68,6 @@
+ 			regulator-min-microvolt = <912000>;
+ 			regulator-max-microvolt = <912000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l2c: ldo2 {
+@@ -80,7 +75,6 @@
+ 			regulator-min-microvolt = <3072000>;
+ 			regulator-max-microvolt = <3072000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l3c: ldo3 {
+@@ -96,7 +90,6 @@
+ 			regulator-min-microvolt = <1200000>;
+ 			regulator-max-microvolt = <1208000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l6c: ldo6 {
+@@ -112,7 +105,6 @@
+ 			regulator-min-microvolt = <1800000>;
+ 			regulator-max-microvolt = <1800000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l10c: ldo10 {
+@@ -141,7 +133,6 @@
+ 			regulator-min-microvolt = <1200000>;
+ 			regulator-max-microvolt = <1200000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l7g: ldo7 {
+@@ -149,7 +140,6 @@
+ 			regulator-min-microvolt = <1800000>;
+ 			regulator-max-microvolt = <1800000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l8g: ldo8 {
+@@ -157,7 +147,6 @@
+ 			regulator-min-microvolt = <880000>;
+ 			regulator-max-microvolt = <880000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 	};
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz-r1.dts
+index 8290d036044a1..edfcd47e1a00f 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz-r1.dts
++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz-r1.dts
+@@ -24,8 +24,6 @@
+ };
+ 
+ &pm6150_adc {
+-	status = "disabled";
+-
+ 	/delete-node/ skin-temp-thermistor@4e;
+ 	/delete-node/ charger-thermistor@4f;
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
+index 2cf7d5212c61c..002663d752da3 100644
+--- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi
+@@ -55,8 +55,6 @@ ap_ts_pen_1v8: &i2c4 {
+ };
+ 
+ &pm6150_adc {
+-	status = "disabled";
+-
+ 	/delete-node/ charger-thermistor@4f;
+ };
+ 
+diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dts b/arch/arm64/boot/dts/qcom/sc7280-idp.dts
+index 6d3ff80582ae9..e2e37a0292ad6 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280-idp.dts
++++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dts
+@@ -78,7 +78,7 @@
+ };
+ 
+ &pmk8350_vadc {
+-	pmr735a_die_temp {
++	pmr735a-die-temp@403 {
+ 		reg = <PMR735A_ADC7_DIE_TEMP>;
+ 		label = "pmr735a_die_temp";
+ 		qcom,pre-scaling = <1 1>;
+diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
+index a74e0b730db61..27c47ddbdf02d 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
+@@ -264,7 +264,7 @@
+ };
+ 
+ &pmk8350_vadc {
+-	pmk8350_die_temp {
++	pmk8350-die-temp@3 {
+ 		reg = <PMK8350_ADC7_DIE_TEMP>;
+ 		label = "pmk8350_die_temp";
+ 		qcom,pre-scaling = <1 1>;
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+index dac3b69e314f1..51ed691075ad3 100644
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
+@@ -2168,9 +2168,8 @@
+ 		lpasscc: lpasscc@3000000 {
+ 			compatible = "qcom,sc7280-lpasscc";
+ 			reg = <0 0x03000000 0 0x40>,
+-			      <0 0x03c04000 0 0x4>,
+-			      <0 0x03389000 0 0x24>;
+-			reg-names = "qdsp6ss", "top_cc", "cc";
++			      <0 0x03c04000 0 0x4>;
++			reg-names = "qdsp6ss", "top_cc";
+ 			clocks = <&gcc GCC_CFG_NOC_LPASS_CLK>;
+ 			clock-names = "iface";
+ 			#clock-cells = <1>;
+@@ -2192,13 +2191,13 @@
+ 			reg = <0 0x03380000 0 0x30000>;
+ 			clocks = <&rpmhcc RPMH_CXO_CLK>,
+ 			       <&rpmhcc RPMH_CXO_CLK_A>,
+-			       <&lpasscore LPASS_CORE_CC_CORE_CLK>;
++			       <&lpass_core LPASS_CORE_CC_CORE_CLK>;
+ 			clock-names = "bi_tcxo", "bi_tcxo_ao", "iface";
+ 			#clock-cells = <1>;
+ 			#power-domain-cells = <1>;
+ 		};
+ 
+-		lpasscore: clock-controller@3900000 {
++		lpass_core: clock-controller@3900000 {
+ 			compatible = "qcom,sc7280-lpasscorecc";
+ 			reg = <0 0x03900000 0 0x50000>;
+ 			clocks = <&rpmhcc RPMH_CXO_CLK>;
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
+index 45058ad0a1c8a..6792e88b2c6c5 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
++++ b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
+@@ -87,7 +87,6 @@
+ 			regulator-min-microvolt = <1200000>;
+ 			regulator-max-microvolt = <1200000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 			regulator-boot-on;
+ 			regulator-always-on;
+ 		};
+@@ -97,7 +96,6 @@
+ 			regulator-min-microvolt = <912000>;
+ 			regulator-max-microvolt = <912000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l6b: ldo6 {
+@@ -105,7 +103,6 @@
+ 			regulator-min-microvolt = <880000>;
+ 			regulator-max-microvolt = <880000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 			regulator-boot-on;
+ 		};
+ 	};
+@@ -119,7 +116,6 @@
+ 			regulator-min-microvolt = <1800000>;
+ 			regulator-max-microvolt = <1800000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l7c: ldo7 {
+@@ -135,7 +131,6 @@
+ 			regulator-min-microvolt = <3072000>;
+ 			regulator-max-microvolt = <3072000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 	};
+ 
+@@ -158,7 +153,6 @@
+ 			regulator-min-microvolt = <1200000>;
+ 			regulator-max-microvolt = <1200000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l6d: ldo6 {
+@@ -166,7 +160,6 @@
+ 			regulator-min-microvolt = <880000>;
+ 			regulator-max-microvolt = <880000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l7d: ldo7 {
+@@ -174,7 +167,6 @@
+ 			regulator-min-microvolt = <3072000>;
+ 			regulator-max-microvolt = <3072000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l9d: ldo9 {
+@@ -182,7 +174,6 @@
+ 			regulator-min-microvolt = <912000>;
+ 			regulator-max-microvolt = <912000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 	};
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
+index 4c404e2eafbac..f0ab207cc8e9e 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
++++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
+@@ -79,7 +79,6 @@
+ 			regulator-min-microvolt = <1200000>;
+ 			regulator-max-microvolt = <1200000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 			regulator-boot-on;
+ 		};
+ 
+@@ -88,7 +87,6 @@
+ 			regulator-min-microvolt = <912000>;
+ 			regulator-max-microvolt = <912000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l6b: ldo6 {
+@@ -96,7 +94,6 @@
+ 			regulator-min-microvolt = <880000>;
+ 			regulator-max-microvolt = <880000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 			regulator-boot-on;
+ 			regulator-always-on;	// FIXME: VDD_A_EDP_0_0P9
+ 		};
+@@ -111,7 +108,6 @@
+ 			regulator-min-microvolt = <1800000>;
+ 			regulator-max-microvolt = <1800000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l12c: ldo12 {
+@@ -119,7 +115,6 @@
+ 			regulator-min-microvolt = <1800000>;
+ 			regulator-max-microvolt = <1800000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l13c: ldo13 {
+@@ -127,7 +122,6 @@
+ 			regulator-min-microvolt = <3072000>;
+ 			regulator-max-microvolt = <3072000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 	};
+ 
+@@ -142,7 +136,6 @@
+ 			regulator-min-microvolt = <1200000>;
+ 			regulator-max-microvolt = <1200000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l4d: ldo4 {
+@@ -150,7 +143,6 @@
+ 			regulator-min-microvolt = <1200000>;
+ 			regulator-max-microvolt = <1200000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l7d: ldo7 {
+@@ -158,7 +150,6 @@
+ 			regulator-min-microvolt = <3072000>;
+ 			regulator-max-microvolt = <3072000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 
+ 		vreg_l9d: ldo9 {
+@@ -166,7 +157,6 @@
+ 			regulator-min-microvolt = <912000>;
+ 			regulator-max-microvolt = <912000>;
+ 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+-			regulator-allow-set-load;
+ 		};
+ 	};
+ };
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
+index ae90b97aecb8e..24836b6b9bbc9 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
+@@ -60,9 +60,8 @@
+ 			#interrupt-cells = <2>;
+ 		};
+ 
+-		pmc8280c_lpg: lpg@e800 {
++		pmc8280c_lpg: pwm {
+ 			compatible = "qcom,pm8350c-pwm";
+-			reg = <0xe800>;
+ 
+ 			#address-cells = <1>;
+ 			#size-cells = <0>;
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+index 7713e8060c5b6..de2d10e0315af 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
+@@ -536,42 +536,42 @@
+ 		reg = <ADC5_XO_THERM_100K_PU>;
+ 		label = "xo_therm";
+ 		qcom,ratiometric;
+-		qcom,hw-settle-time-us = <200>;
++		qcom,hw-settle-time = <200>;
+ 	};
+ 
+ 	adc-chan@4d {
+ 		reg = <ADC5_AMUX_THM1_100K_PU>;
+ 		label = "msm_therm";
+ 		qcom,ratiometric;
+-		qcom,hw-settle-time-us = <200>;
++		qcom,hw-settle-time = <200>;
+ 	};
+ 
+ 	adc-chan@4f {
+ 		reg = <ADC5_AMUX_THM3_100K_PU>;
+ 		label = "pa_therm1";
+ 		qcom,ratiometric;
+-		qcom,hw-settle-time-us = <200>;
++		qcom,hw-settle-time = <200>;
+ 	};
+ 
+ 	adc-chan@51 {
+ 		reg = <ADC5_AMUX_THM5_100K_PU>;
+ 		label = "quiet_therm";
+ 		qcom,ratiometric;
+-		qcom,hw-settle-time-us = <200>;
++		qcom,hw-settle-time = <200>;
+ 	};
+ 
+ 	adc-chan@83 {
+ 		reg = <ADC5_VPH_PWR>;
+ 		label = "vph_pwr";
+ 		qcom,ratiometric;
+-		qcom,hw-settle-time-us = <200>;
++		qcom,hw-settle-time = <200>;
+ 	};
+ 
+ 	adc-chan@85 {
+ 		reg = <ADC5_VCOIN>;
+ 		label = "vcoin";
+ 		qcom,ratiometric;
+-		qcom,hw-settle-time-us = <200>;
++		qcom,hw-settle-time = <200>;
+ 	};
+ };
+ 
+diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+index 7747081b98875..dba7c2693ff50 100644
+--- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
++++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
+@@ -617,7 +617,7 @@
+ 		pins = "gpio6", "gpio10";
+ 		function = "gpio";
+ 		drive-strength = <8>;
+-		bias-disable = <0>;
++		bias-disable;
+ 	};
+ 
+ 	sde_dsi_suspend: sde-dsi-suspend {
+diff --git a/arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi b/arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi
+index cb9bbd234b7bc..b702ab1605bb0 100644
+--- a/arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi
+@@ -223,7 +223,7 @@
+ 	gpio-reserved-ranges = <44 4>;
+ 
+ 	ts_int_default: ts-int-default {
+-		pin = "gpio23";
++		pins = "gpio23";
+ 		function = "gpio";
+ 		drive-strength = <2>;
+ 		bias-disable;
+diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+index 4978c5ba5dd08..8a6c0f3e7bb70 100644
+--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
+@@ -3117,7 +3117,7 @@
+ 
+ 		ufs_mem_phy: phy@1d87000 {
+ 			compatible = "qcom,sm8450-qmp-ufs-phy";
+-			reg = <0 0x01d87000 0 0xe10>;
++			reg = <0 0x01d87000 0 0x1c4>;
+ 			#address-cells = <2>;
+ 			#size-cells = <2>;
+ 			ranges;
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
+index 40201a16d653c..af84d4797972e 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g043.dtsi
+@@ -334,8 +334,8 @@
+ 			compatible = "renesas,r9a07g043-sci", "renesas,sci";
+ 			reg = <0 0x1004d000 0 0x400>;
+ 			interrupts = <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+-				     <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+-				     <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
++				     <GIC_SPI 406 IRQ_TYPE_EDGE_RISING>,
++				     <GIC_SPI 407 IRQ_TYPE_EDGE_RISING>,
+ 				     <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ 			interrupt-names = "eri", "rxi", "txi", "tei";
+ 			clocks = <&cpg CPG_MOD R9A07G043_SCI0_CLKP>;
+@@ -349,8 +349,8 @@
+ 			compatible = "renesas,r9a07g043-sci", "renesas,sci";
+ 			reg = <0 0x1004d400 0 0x400>;
+ 			interrupts = <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+-				     <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+-				     <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
++				     <GIC_SPI 410 IRQ_TYPE_EDGE_RISING>,
++				     <GIC_SPI 411 IRQ_TYPE_EDGE_RISING>,
+ 				     <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>;
+ 			interrupt-names = "eri", "rxi", "txi", "tei";
+ 			clocks = <&cpg CPG_MOD R9A07G043_SCI1_CLKP>;
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+index 3652e511160fb..265140b20dadd 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+@@ -394,8 +394,8 @@
+ 			compatible = "renesas,r9a07g044-sci", "renesas,sci";
+ 			reg = <0 0x1004d000 0 0x400>;
+ 			interrupts = <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+-				     <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+-				     <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
++				     <GIC_SPI 406 IRQ_TYPE_EDGE_RISING>,
++				     <GIC_SPI 407 IRQ_TYPE_EDGE_RISING>,
+ 				     <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ 			interrupt-names = "eri", "rxi", "txi", "tei";
+ 			clocks = <&cpg CPG_MOD R9A07G044_SCI0_CLKP>;
+@@ -409,8 +409,8 @@
+ 			compatible = "renesas,r9a07g044-sci", "renesas,sci";
+ 			reg = <0 0x1004d400 0 0x400>;
+ 			interrupts = <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+-				     <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+-				     <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
++				     <GIC_SPI 410 IRQ_TYPE_EDGE_RISING>,
++				     <GIC_SPI 411 IRQ_TYPE_EDGE_RISING>,
+ 				     <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>;
+ 			interrupt-names = "eri", "rxi", "txi", "tei";
+ 			clocks = <&cpg CPG_MOD R9A07G044_SCI1_CLKP>;
+diff --git a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
+index 4d6b9d7684c94..d0eeca4f6aa1b 100644
+--- a/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
++++ b/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
+@@ -399,8 +399,8 @@
+ 			compatible = "renesas,r9a07g054-sci", "renesas,sci";
+ 			reg = <0 0x1004d000 0 0x400>;
+ 			interrupts = <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+-				     <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+-				     <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
++				     <GIC_SPI 406 IRQ_TYPE_EDGE_RISING>,
++				     <GIC_SPI 407 IRQ_TYPE_EDGE_RISING>,
+ 				     <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+ 			interrupt-names = "eri", "rxi", "txi", "tei";
+ 			clocks = <&cpg CPG_MOD R9A07G054_SCI0_CLKP>;
+@@ -414,8 +414,8 @@
+ 			compatible = "renesas,r9a07g054-sci", "renesas,sci";
+ 			reg = <0 0x1004d400 0 0x400>;
+ 			interrupts = <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+-				     <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+-				     <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
++				     <GIC_SPI 410 IRQ_TYPE_EDGE_RISING>,
++				     <GIC_SPI 411 IRQ_TYPE_EDGE_RISING>,
+ 				     <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>;
+ 			interrupt-names = "eri", "rxi", "txi", "tei";
+ 			clocks = <&cpg CPG_MOD R9A07G054_SCI1_CLKP>;
+diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+index 121975dc82397..7e8552fd2b6ae 100644
+--- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
++++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+@@ -134,15 +134,17 @@
+ 		>;
+ 	};
+ 
+-	main_usbss0_pins_default: main-usbss0-pins-default {
++	vdd_sd_dv_pins_default: vdd-sd-dv-pins-default {
+ 		pinctrl-single,pins = <
+-			J721E_IOPAD(0x120, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */
++			J721E_IOPAD(0xd0, PIN_OUTPUT, 7) /* (T5) SPI0_D1.GPIO0_55 */
+ 		>;
+ 	};
++};
+ 
+-	vdd_sd_dv_pins_default: vdd-sd-dv-pins-default {
++&main_pmx1 {
++	main_usbss0_pins_default: main-usbss0-pins-default {
+ 		pinctrl-single,pins = <
+-			J721E_IOPAD(0xd0, PIN_OUTPUT, 7) /* (T5) SPI0_D1.GPIO0_55 */
++			J721E_IOPAD(0x04, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */
+ 		>;
+ 	};
+ };
+diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+index 16684a2f054d9..e12a53f1857f8 100644
+--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+@@ -295,7 +295,16 @@
+ 	main_pmx0: pinctrl@11c000 {
+ 		compatible = "pinctrl-single";
+ 		/* Proxy 0 addressing */
+-		reg = <0x00 0x11c000 0x00 0x2b4>;
++		reg = <0x00 0x11c000 0x00 0x10c>;
++		#pinctrl-cells = <1>;
++		pinctrl-single,register-width = <32>;
++		pinctrl-single,function-mask = <0xffffffff>;
++	};
++
++	main_pmx1: pinctrl@11c11c {
++		compatible = "pinctrl-single";
++		/* Proxy 0 addressing */
++		reg = <0x00 0x11c11c 0x00 0xc>;
+ 		#pinctrl-cells = <1>;
+ 		pinctrl-single,register-width = <32>;
+ 		pinctrl-single,function-mask = <0xffffffff>;
+diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h
+index aa523591a44e5..760c62f8e22f8 100644
+--- a/arch/arm64/include/asm/mte.h
++++ b/arch/arm64/include/asm/mte.h
+@@ -42,7 +42,9 @@ void mte_sync_tags(pte_t old_pte, pte_t pte);
+ void mte_copy_page_tags(void *kto, const void *kfrom);
+ void mte_thread_init_user(void);
+ void mte_thread_switch(struct task_struct *next);
++void mte_cpu_setup(void);
+ void mte_suspend_enter(void);
++void mte_suspend_exit(void);
+ long set_mte_ctrl(struct task_struct *task, unsigned long arg);
+ long get_mte_ctrl(struct task_struct *task);
+ int mte_ptrace_copy_tags(struct task_struct *child, long request,
+@@ -72,6 +74,9 @@ static inline void mte_thread_switch(struct task_struct *next)
+ static inline void mte_suspend_enter(void)
+ {
+ }
++static inline void mte_suspend_exit(void)
++{
++}
+ static inline long set_mte_ctrl(struct task_struct *task, unsigned long arg)
+ {
+ 	return 0;
+diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
+index 53b973b6059f7..bc857d19acd43 100644
+--- a/arch/arm64/kernel/cpu_errata.c
++++ b/arch/arm64/kernel/cpu_errata.c
+@@ -214,6 +214,11 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
+ 		ERRATA_MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xe),
+ 	},
+ #endif
++#ifdef CONFIG_ARM64_ERRATUM_2441007
++	{
++		ERRATA_MIDR_ALL_VERSIONS(MIDR_CORTEX_A55),
++	},
++#endif
+ #ifdef CONFIG_ARM64_ERRATUM_2441009
+ 	{
+ 		/* Cortex-A510 r0p0 -> r1p1. Fixed in r1p2 */
+diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
+index af4de817d7123..d7a077b5ccd1c 100644
+--- a/arch/arm64/kernel/cpufeature.c
++++ b/arch/arm64/kernel/cpufeature.c
+@@ -2034,7 +2034,8 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused)
+ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
+ {
+ 	sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0);
+-	isb();
++
++	mte_cpu_setup();
+ 
+ 	/*
+ 	 * Clear the tags in the zero page. This needs to be done via the
+diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c
+index ea5dc7c90f465..b49ba9a24bcc8 100644
+--- a/arch/arm64/kernel/ftrace.c
++++ b/arch/arm64/kernel/ftrace.c
+@@ -217,11 +217,26 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
+ 	unsigned long pc = rec->ip;
+ 	u32 old = 0, new;
+ 
++	new = aarch64_insn_gen_nop();
++
++	/*
++	 * When using mcount, callsites in modules may have been initalized to
++	 * call an arbitrary module PLT (which redirects to the _mcount stub)
++	 * rather than the ftrace PLT we'll use at runtime (which redirects to
++	 * the ftrace trampoline). We can ignore the old PLT when initializing
++	 * the callsite.
++	 *
++	 * Note: 'mod' is only set at module load time.
++	 */
++	if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS) &&
++	    IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) && mod) {
++		return aarch64_insn_patch_text_nosync((void *)pc, new);
++	}
++
+ 	if (!ftrace_find_callable_addr(rec, mod, &addr))
+ 		return -EINVAL;
+ 
+ 	old = aarch64_insn_gen_branch_imm(pc, addr, AARCH64_INSN_BRANCH_LINK);
+-	new = aarch64_insn_gen_nop();
+ 
+ 	return ftrace_modify_code(pc, old, new, true);
+ }
+diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
+index b2b730233274b..7467217c1eaf3 100644
+--- a/arch/arm64/kernel/mte.c
++++ b/arch/arm64/kernel/mte.c
+@@ -48,7 +48,12 @@ static void mte_sync_page_tags(struct page *page, pte_t old_pte,
+ 	if (!pte_is_tagged)
+ 		return;
+ 
+-	mte_clear_page_tags(page_address(page));
++	/*
++	 * Test PG_mte_tagged again in case it was racing with another
++	 * set_pte_at().
++	 */
++	if (!test_and_set_bit(PG_mte_tagged, &page->flags))
++		mte_clear_page_tags(page_address(page));
+ }
+ 
+ void mte_sync_tags(pte_t old_pte, pte_t pte)
+@@ -64,7 +69,7 @@ void mte_sync_tags(pte_t old_pte, pte_t pte)
+ 
+ 	/* if PG_mte_tagged is set, tags have already been initialised */
+ 	for (i = 0; i < nr_pages; i++, page++) {
+-		if (!test_and_set_bit(PG_mte_tagged, &page->flags))
++		if (!test_bit(PG_mte_tagged, &page->flags))
+ 			mte_sync_page_tags(page, old_pte, check_swap,
+ 					   pte_is_tagged);
+ 	}
+@@ -285,6 +290,49 @@ void mte_thread_switch(struct task_struct *next)
+ 	mte_check_tfsr_el1();
+ }
+ 
++void mte_cpu_setup(void)
++{
++	u64 rgsr;
++
++	/*
++	 * CnP must be enabled only after the MAIR_EL1 register has been set
++	 * up. Inconsistent MAIR_EL1 between CPUs sharing the same TLB may
++	 * lead to the wrong memory type being used for a brief window during
++	 * CPU power-up.
++	 *
++	 * CnP is not a boot feature so MTE gets enabled before CnP, but let's
++	 * make sure that is the case.
++	 */
++	BUG_ON(read_sysreg(ttbr0_el1) & TTBR_CNP_BIT);
++	BUG_ON(read_sysreg(ttbr1_el1) & TTBR_CNP_BIT);
++
++	/* Normal Tagged memory type at the corresponding MAIR index */
++	sysreg_clear_set(mair_el1,
++			 MAIR_ATTRIDX(MAIR_ATTR_MASK, MT_NORMAL_TAGGED),
++			 MAIR_ATTRIDX(MAIR_ATTR_NORMAL_TAGGED,
++				      MT_NORMAL_TAGGED));
++
++	write_sysreg_s(KERNEL_GCR_EL1, SYS_GCR_EL1);
++
++	/*
++	 * If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then
++	 * RGSR_EL1.SEED must be non-zero for IRG to produce
++	 * pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we
++	 * must initialize it.
++	 */
++	rgsr = (read_sysreg(CNTVCT_EL0) & SYS_RGSR_EL1_SEED_MASK) <<
++	       SYS_RGSR_EL1_SEED_SHIFT;
++	if (rgsr == 0)
++		rgsr = 1 << SYS_RGSR_EL1_SEED_SHIFT;
++	write_sysreg_s(rgsr, SYS_RGSR_EL1);
++
++	/* clear any pending tag check faults in TFSR*_EL1 */
++	write_sysreg_s(0, SYS_TFSR_EL1);
++	write_sysreg_s(0, SYS_TFSRE0_EL1);
++
++	local_flush_tlb_all();
++}
++
+ void mte_suspend_enter(void)
+ {
+ 	if (!system_supports_mte())
+@@ -301,6 +349,14 @@ void mte_suspend_enter(void)
+ 	mte_check_tfsr_el1();
+ }
+ 
++void mte_suspend_exit(void)
++{
++	if (!system_supports_mte())
++		return;
++
++	mte_cpu_setup();
++}
++
+ long set_mte_ctrl(struct task_struct *task, unsigned long arg)
+ {
+ 	u64 mte_ctrl = (~((arg & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT) &
+diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
+index 9135fe0f3df53..8b02d310838f9 100644
+--- a/arch/arm64/kernel/suspend.c
++++ b/arch/arm64/kernel/suspend.c
+@@ -43,6 +43,8 @@ void notrace __cpu_suspend_exit(void)
+ {
+ 	unsigned int cpu = smp_processor_id();
+ 
++	mte_suspend_exit();
++
+ 	/*
+ 	 * We are resuming from reset with the idmap active in TTBR0_EL1.
+ 	 * We must uninstall the idmap and restore the expected MMU
+diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
+index 44ebf5b2fc4b7..817d788cd8666 100644
+--- a/arch/arm64/kernel/topology.c
++++ b/arch/arm64/kernel/topology.c
+@@ -22,46 +22,6 @@
+ #include <asm/cputype.h>
+ #include <asm/topology.h>
+ 
+-void store_cpu_topology(unsigned int cpuid)
+-{
+-	struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
+-	u64 mpidr;
+-
+-	if (cpuid_topo->package_id != -1)
+-		goto topology_populated;
+-
+-	mpidr = read_cpuid_mpidr();
+-
+-	/* Uniprocessor systems can rely on default topology values */
+-	if (mpidr & MPIDR_UP_BITMASK)
+-		return;
+-
+-	/*
+-	 * This would be the place to create cpu topology based on MPIDR.
+-	 *
+-	 * However, it cannot be trusted to depict the actual topology; some
+-	 * pieces of the architecture enforce an artificial cap on Aff0 values
+-	 * (e.g. GICv3's ICC_SGI1R_EL1 limits it to 15), leading to an
+-	 * artificial cycling of Aff1, Aff2 and Aff3 values. IOW, these end up
+-	 * having absolutely no relationship to the actual underlying system
+-	 * topology, and cannot be reasonably used as core / package ID.
+-	 *
+-	 * If the MT bit is set, Aff0 *could* be used to define a thread ID, but
+-	 * we still wouldn't be able to obtain a sane core ID. This means we
+-	 * need to entirely ignore MPIDR for any topology deduction.
+-	 */
+-	cpuid_topo->thread_id  = -1;
+-	cpuid_topo->core_id    = cpuid;
+-	cpuid_topo->package_id = cpu_to_node(cpuid);
+-
+-	pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n",
+-		 cpuid, cpuid_topo->package_id, cpuid_topo->core_id,
+-		 cpuid_topo->thread_id, mpidr);
+-
+-topology_populated:
+-	update_siblings_masks(cpuid);
+-}
+-
+ #ifdef CONFIG_ACPI
+ static bool __init acpi_cpu_is_threaded(int cpu)
+ {
+diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c
+index 4334dec93bd44..bed803d8e1585 100644
+--- a/arch/arm64/mm/mteswap.c
++++ b/arch/arm64/mm/mteswap.c
+@@ -53,7 +53,12 @@ bool mte_restore_tags(swp_entry_t entry, struct page *page)
+ 	if (!tags)
+ 		return false;
+ 
+-	mte_restore_page_tags(page_address(page), tags);
++	/*
++	 * Test PG_mte_tagged again in case it was racing with another
++	 * set_pte_at().
++	 */
++	if (!test_and_set_bit(PG_mte_tagged, &page->flags))
++		mte_restore_page_tags(page_address(page), tags);
+ 
+ 	return true;
+ }
+diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
+index 7837a69524c53..f38bccdd374a5 100644
+--- a/arch/arm64/mm/proc.S
++++ b/arch/arm64/mm/proc.S
+@@ -48,17 +48,19 @@
+ 
+ #ifdef CONFIG_KASAN_HW_TAGS
+ #define TCR_MTE_FLAGS TCR_TCMA1 | TCR_TBI1 | TCR_TBID1
+-#else
++#elif defined(CONFIG_ARM64_MTE)
+ /*
+  * The mte_zero_clear_page_tags() implementation uses DC GZVA, which relies on
+  * TBI being enabled at EL1.
+  */
+ #define TCR_MTE_FLAGS TCR_TBI1 | TCR_TBID1
++#else
++#define TCR_MTE_FLAGS 0
+ #endif
+ 
+ /*
+  * Default MAIR_EL1. MT_NORMAL_TAGGED is initially mapped as Normal memory and
+- * changed during __cpu_setup to Normal Tagged if the system supports MTE.
++ * changed during mte_cpu_setup to Normal Tagged if the system supports MTE.
+  */
+ #define MAIR_EL1_SET							\
+ 	(MAIR_ATTRIDX(MAIR_ATTR_DEVICE_nGnRnE, MT_DEVICE_nGnRnE) |	\
+@@ -426,46 +428,8 @@ SYM_FUNC_START(__cpu_setup)
+ 	mov_q	mair, MAIR_EL1_SET
+ 	mov_q	tcr, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
+ 			TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
+-			TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS
+-
+-#ifdef CONFIG_ARM64_MTE
+-	/*
+-	 * Update MAIR_EL1, GCR_EL1 and TFSR*_EL1 if MTE is supported
+-	 * (ID_AA64PFR1_EL1[11:8] > 1).
+-	 */
+-	mrs	x10, ID_AA64PFR1_EL1
+-	ubfx	x10, x10, #ID_AA64PFR1_MTE_SHIFT, #4
+-	cmp	x10, #ID_AA64PFR1_MTE
+-	b.lt	1f
+-
+-	/* Normal Tagged memory type at the corresponding MAIR index */
+-	mov	x10, #MAIR_ATTR_NORMAL_TAGGED
+-	bfi	mair, x10, #(8 *  MT_NORMAL_TAGGED), #8
++			TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS
+ 
+-	mov	x10, #KERNEL_GCR_EL1
+-	msr_s	SYS_GCR_EL1, x10
+-
+-	/*
+-	 * If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then
+-	 * RGSR_EL1.SEED must be non-zero for IRG to produce
+-	 * pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we
+-	 * must initialize it.
+-	 */
+-	mrs	x10, CNTVCT_EL0
+-	ands	x10, x10, #SYS_RGSR_EL1_SEED_MASK
+-	csinc	x10, x10, xzr, ne
+-	lsl	x10, x10, #SYS_RGSR_EL1_SEED_SHIFT
+-	msr_s	SYS_RGSR_EL1, x10
+-
+-	/* clear any pending tag check faults in TFSR*_EL1 */
+-	msr_s	SYS_TFSR_EL1, xzr
+-	msr_s	SYS_TFSRE0_EL1, xzr
+-
+-	/* set the TCR_EL1 bits */
+-	mov_q	x10, TCR_MTE_FLAGS
+-	orr	tcr, tcr, x10
+-1:
+-#endif
+ 	tcr_clear_errata_bits tcr, x9, x5
+ 
+ #ifdef CONFIG_ARM64_VA_BITS_52
+diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c
+index d6579ec3ea324..4c7b1f50e3b7d 100644
+--- a/arch/ia64/mm/numa.c
++++ b/arch/ia64/mm/numa.c
+@@ -75,5 +75,6 @@ int memory_add_physaddr_to_nid(u64 addr)
+ 		return 0;
+ 	return nid;
+ }
++EXPORT_SYMBOL(memory_add_physaddr_to_nid);
+ #endif
+ #endif
+diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
+index e62fa8f2149b3..7e7ef67cff8b2 100644
+--- a/arch/m68k/kernel/setup_mm.c
++++ b/arch/m68k/kernel/setup_mm.c
+@@ -109,10 +109,9 @@ extern void paging_init(void);
+ 
+ static void __init m68k_parse_bootinfo(const struct bi_record *record)
+ {
++	const struct bi_record *first_record = record;
+ 	uint16_t tag;
+ 
+-	save_bootinfo(record);
+-
+ 	while ((tag = be16_to_cpu(record->tag)) != BI_LAST) {
+ 		int unknown = 0;
+ 		const void *data = record->data;
+@@ -182,6 +181,8 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
+ 		record = (struct bi_record *)((unsigned long)record + size);
+ 	}
+ 
++	save_bootinfo(first_record);
++
+ 	m68k_realnum_memory = m68k_num_memory;
+ #ifdef CONFIG_SINGLE_MEMORY_CHUNK
+ 	if (m68k_num_memory > 1) {
+diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
+index ab203e66ba0dd..a9bea411d9282 100644
+--- a/arch/mips/bcm47xx/prom.c
++++ b/arch/mips/bcm47xx/prom.c
+@@ -86,7 +86,7 @@ static __init void prom_init_mem(void)
+ 			pr_debug("Assume 128MB RAM\n");
+ 			break;
+ 		}
+-		if (!memcmp(prom_init, prom_init + mem, 32))
++		if (!memcmp((void *)prom_init, (void *)prom_init + mem, 32))
+ 			break;
+ 	}
+ 	lowmem = mem;
+@@ -159,7 +159,7 @@ void __init bcm47xx_prom_highmem_init(void)
+ 
+ 	off = EXTVBASE + __pa(off);
+ 	for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) {
+-		if (!memcmp(prom_init, (void *)(off + extmem), 16))
++		if (!memcmp((void *)prom_init, (void *)(off + extmem), 16))
+ 			break;
+ 	}
+ 	extmem -= lowmem;
+diff --git a/arch/mips/boot/dts/ralink/mt7621-gnubee-gb-pc2.dts b/arch/mips/boot/dts/ralink/mt7621-gnubee-gb-pc2.dts
+index 34006e6677806..0d01e542a0a6e 100644
+--- a/arch/mips/boot/dts/ralink/mt7621-gnubee-gb-pc2.dts
++++ b/arch/mips/boot/dts/ralink/mt7621-gnubee-gb-pc2.dts
+@@ -83,12 +83,12 @@
+ 
+ &gmac1 {
+ 	status = "okay";
+-	phy-handle = <&ethphy7>;
++	phy-handle = <&ethphy5>;
+ };
+ 
+ &mdio {
+-	ethphy7: ethernet-phy@7 {
+-		reg = <7>;
++	ethphy5: ethernet-phy@5 {
++		reg = <5>;
+ 		phy-mode = "rgmii-rxid";
+ 	};
+ };
+diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c
+index e762886d1dda9..5143d1cf8984c 100644
+--- a/arch/mips/sgi-ip27/ip27-xtalk.c
++++ b/arch/mips/sgi-ip27/ip27-xtalk.c
+@@ -27,15 +27,18 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
+ {
+ 	struct xtalk_bridge_platform_data *bd;
+ 	struct sgi_w1_platform_data *wd;
+-	struct platform_device *pdev;
++	struct platform_device *pdev_wd;
++	struct platform_device *pdev_bd;
+ 	struct resource w1_res;
+ 	unsigned long offset;
+ 
+ 	offset = NODE_OFFSET(nasid);
+ 
+ 	wd = kzalloc(sizeof(*wd), GFP_KERNEL);
+-	if (!wd)
+-		goto no_mem;
++	if (!wd) {
++		pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
++		return;
++	}
+ 
+ 	snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx",
+ 		 offset + (widget << SWIN_SIZE_BITS));
+@@ -46,24 +49,35 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
+ 	w1_res.end = w1_res.start + 3;
+ 	w1_res.flags = IORESOURCE_MEM;
+ 
+-	pdev = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
+-	if (!pdev) {
+-		kfree(wd);
+-		goto no_mem;
++	pdev_wd = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
++	if (!pdev_wd) {
++		pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
++		goto err_kfree_wd;
++	}
++	if (platform_device_add_resources(pdev_wd, &w1_res, 1)) {
++		pr_warn("xtalk:n%d/%x bridge failed to add platform resources.\n", nasid, widget);
++		goto err_put_pdev_wd;
++	}
++	if (platform_device_add_data(pdev_wd, wd, sizeof(*wd))) {
++		pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget);
++		goto err_put_pdev_wd;
++	}
++	if (platform_device_add(pdev_wd)) {
++		pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget);
++		goto err_put_pdev_wd;
+ 	}
+-	platform_device_add_resources(pdev, &w1_res, 1);
+-	platform_device_add_data(pdev, wd, sizeof(*wd));
+ 	/* platform_device_add_data() duplicates the data */
+ 	kfree(wd);
+-	platform_device_add(pdev);
+ 
+ 	bd = kzalloc(sizeof(*bd), GFP_KERNEL);
+-	if (!bd)
+-		goto no_mem;
+-	pdev = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
+-	if (!pdev) {
+-		kfree(bd);
+-		goto no_mem;
++	if (!bd) {
++		pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
++		goto err_unregister_pdev_wd;
++	}
++	pdev_bd = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
++	if (!pdev_bd) {
++		pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
++		goto err_kfree_bd;
+ 	}
+ 
+ 
+@@ -84,15 +98,31 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
+ 	bd->io.flags	= IORESOURCE_IO;
+ 	bd->io_offset	= offset;
+ 
+-	platform_device_add_data(pdev, bd, sizeof(*bd));
++	if (platform_device_add_data(pdev_bd, bd, sizeof(*bd))) {
++		pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget);
++		goto err_put_pdev_bd;
++	}
++	if (platform_device_add(pdev_bd)) {
++		pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget);
++		goto err_put_pdev_bd;
++	}
+ 	/* platform_device_add_data() duplicates the data */
+ 	kfree(bd);
+-	platform_device_add(pdev);
+ 	pr_info("xtalk:n%d/%x bridge widget\n", nasid, widget);
+ 	return;
+ 
+-no_mem:
+-	pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
++err_put_pdev_bd:
++	platform_device_put(pdev_bd);
++err_kfree_bd:
++	kfree(bd);
++err_unregister_pdev_wd:
++	platform_device_unregister(pdev_wd);
++	return;
++err_put_pdev_wd:
++	platform_device_put(pdev_wd);
++err_kfree_wd:
++	kfree(wd);
++	return;
+ }
+ 
+ static int probe_one_port(nasid_t nasid, int widget, int masterwid)
+diff --git a/arch/mips/sgi-ip30/ip30-xtalk.c b/arch/mips/sgi-ip30/ip30-xtalk.c
+index 8129524421cb0..7ceb2b23ea1cf 100644
+--- a/arch/mips/sgi-ip30/ip30-xtalk.c
++++ b/arch/mips/sgi-ip30/ip30-xtalk.c
+@@ -40,12 +40,15 @@ static void bridge_platform_create(int widget, int masterwid)
+ {
+ 	struct xtalk_bridge_platform_data *bd;
+ 	struct sgi_w1_platform_data *wd;
+-	struct platform_device *pdev;
++	struct platform_device *pdev_wd;
++	struct platform_device *pdev_bd;
+ 	struct resource w1_res;
+ 
+ 	wd = kzalloc(sizeof(*wd), GFP_KERNEL);
+-	if (!wd)
+-		goto no_mem;
++	if (!wd) {
++		pr_warn("xtalk:%x bridge create out of memory\n", widget);
++		return;
++	}
+ 
+ 	snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx",
+ 		 IP30_SWIN_BASE(widget));
+@@ -56,24 +59,35 @@ static void bridge_platform_create(int widget, int masterwid)
+ 	w1_res.end = w1_res.start + 3;
+ 	w1_res.flags = IORESOURCE_MEM;
+ 
+-	pdev = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
+-	if (!pdev) {
+-		kfree(wd);
+-		goto no_mem;
++	pdev_wd = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
++	if (!pdev_wd) {
++		pr_warn("xtalk:%x bridge create out of memory\n", widget);
++		goto err_kfree_wd;
++	}
++	if (platform_device_add_resources(pdev_wd, &w1_res, 1)) {
++		pr_warn("xtalk:%x bridge failed to add platform resources.\n", widget);
++		goto err_put_pdev_wd;
++	}
++	if (platform_device_add_data(pdev_wd, wd, sizeof(*wd))) {
++		pr_warn("xtalk:%x bridge failed to add platform data.\n", widget);
++		goto err_put_pdev_wd;
++	}
++	if (platform_device_add(pdev_wd)) {
++		pr_warn("xtalk:%x bridge failed to add platform device.\n", widget);
++		goto err_put_pdev_wd;
+ 	}
+-	platform_device_add_resources(pdev, &w1_res, 1);
+-	platform_device_add_data(pdev, wd, sizeof(*wd));
+ 	/* platform_device_add_data() duplicates the data */
+ 	kfree(wd);
+-	platform_device_add(pdev);
+ 
+ 	bd = kzalloc(sizeof(*bd), GFP_KERNEL);
+-	if (!bd)
+-		goto no_mem;
+-	pdev = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
+-	if (!pdev) {
+-		kfree(bd);
+-		goto no_mem;
++	if (!bd) {
++		pr_warn("xtalk:%x bridge create out of memory\n", widget);
++		goto err_unregister_pdev_wd;
++	}
++	pdev_bd = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
++	if (!pdev_bd) {
++		pr_warn("xtalk:%x bridge create out of memory\n", widget);
++		goto err_kfree_bd;
+ 	}
+ 
+ 	bd->bridge_addr	= IP30_RAW_SWIN_BASE(widget);
+@@ -93,15 +107,31 @@ static void bridge_platform_create(int widget, int masterwid)
+ 	bd->io.flags	= IORESOURCE_IO;
+ 	bd->io_offset	= IP30_SWIN_BASE(widget);
+ 
+-	platform_device_add_data(pdev, bd, sizeof(*bd));
++	if (platform_device_add_data(pdev_bd, bd, sizeof(*bd))) {
++		pr_warn("xtalk:%x bridge failed to add platform data.\n", widget);
++		goto err_put_pdev_bd;
++	}
++	if (platform_device_add(pdev_bd)) {
++		pr_warn("xtalk:%x bridge failed to add platform device.\n", widget);
++		goto err_put_pdev_bd;
++	}
+ 	/* platform_device_add_data() duplicates the data */
+ 	kfree(bd);
+-	platform_device_add(pdev);
+ 	pr_info("xtalk:%x bridge widget\n", widget);
+ 	return;
+ 
+-no_mem:
+-	pr_warn("xtalk:%x bridge create out of memory\n", widget);
++err_put_pdev_bd:
++	platform_device_put(pdev_bd);
++err_kfree_bd:
++	kfree(bd);
++err_unregister_pdev_wd:
++	platform_device_unregister(pdev_wd);
++	return;
++err_put_pdev_wd:
++	platform_device_put(pdev_wd);
++err_kfree_wd:
++	kfree(wd);
++	return;
+ }
+ 
+ static unsigned int __init xbow_widget_active(s8 wid)
+diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
+index df7b931865d22..ecd0288544698 100644
+--- a/arch/parisc/include/asm/pgtable.h
++++ b/arch/parisc/include/asm/pgtable.h
+@@ -192,6 +192,11 @@ extern void __update_cache(pte_t pte);
+ #define _PAGE_PRESENT_BIT  22   /* (0x200) Software: translation valid */
+ #define _PAGE_HPAGE_BIT    21   /* (0x400) Software: Huge Page */
+ #define _PAGE_USER_BIT     20   /* (0x800) Software: User accessible page */
++#ifdef CONFIG_HUGETLB_PAGE
++#define _PAGE_SPECIAL_BIT  _PAGE_DMB_BIT  /* DMB feature is currently unused */
++#else
++#define _PAGE_SPECIAL_BIT  _PAGE_HPAGE_BIT /* use unused HUGE PAGE bit */
++#endif
+ 
+ /* N.B. The bits are defined in terms of a 32 bit word above, so the */
+ /*      following macro is ok for both 32 and 64 bit.                */
+@@ -219,7 +224,7 @@ extern void __update_cache(pte_t pte);
+ #define _PAGE_PRESENT  (1 << xlate_pabit(_PAGE_PRESENT_BIT))
+ #define _PAGE_HUGE     (1 << xlate_pabit(_PAGE_HPAGE_BIT))
+ #define _PAGE_USER     (1 << xlate_pabit(_PAGE_USER_BIT))
+-#define _PAGE_SPECIAL  (_PAGE_DMB)
++#define _PAGE_SPECIAL  (1 << xlate_pabit(_PAGE_SPECIAL_BIT))
+ 
+ #define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED)
+ #define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_SPECIAL)
+diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
+index df8102fb435fc..0e5ebfe8d9d29 100644
+--- a/arch/parisc/kernel/entry.S
++++ b/arch/parisc/kernel/entry.S
+@@ -499,6 +499,10 @@
+ 	 * Finally, _PAGE_READ goes in the top bit of PL1 (so we
+ 	 * trigger an access rights trap in user space if the user
+ 	 * tries to read an unreadable page */
++#if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT
++	/* need to drop DMB bit, as it's used as SPECIAL flag */
++	depi		0,_PAGE_SPECIAL_BIT,1,\pte
++#endif
+ 	depd            \pte,8,7,\prot
+ 
+ 	/* PAGE_USER indicates the page can be read with user privileges,
+@@ -529,6 +533,10 @@
+ 	 * makes the tlb entry for the differently formatted pa11
+ 	 * insertion instructions */
+ 	.macro		make_insert_tlb_11	spc,pte,prot
++#if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT
++	/* need to drop DMB bit, as it's used as SPECIAL flag */
++	depi		0,_PAGE_SPECIAL_BIT,1,\pte
++#endif
+ 	zdep		\spc,30,15,\prot
+ 	dep		\pte,8,7,\prot
+ 	extru,=		\pte,_PAGE_NO_CACHE_BIT,1,%r0
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index 4c466acdc70d4..cbe7bb029aec8 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -828,7 +828,7 @@ config DATA_SHIFT
+ 	default 24 if STRICT_KERNEL_RWX && PPC64
+ 	range 17 28 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && PPC_BOOK3S_32
+ 	range 19 23 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && PPC_8xx
+-	range 20 24 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && PPC_FSL_BOOKE
++	range 20 24 if (STRICT_KERNEL_RWX || DEBUG_PAGEALLOC || KFENCE) && FSL_BOOKE
+ 	default 22 if STRICT_KERNEL_RWX && PPC_BOOK3S_32
+ 	default 18 if (DEBUG_PAGEALLOC || KFENCE) && PPC_BOOK3S_32
+ 	default 23 if STRICT_KERNEL_RWX && PPC_8xx
+diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
+index 02742facf8951..140a5e6471fef 100644
+--- a/arch/powerpc/Makefile
++++ b/arch/powerpc/Makefile
+@@ -152,7 +152,7 @@ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power8
+ CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power9,-mtune=power8)
+ else
+ CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power7,$(call cc-option,-mtune=power5))
+-CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mcpu=power5,-mcpu=power4)
++CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power4
+ endif
+ else ifdef CONFIG_PPC_BOOK3E_64
+ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64
+diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
+index a9cd2ea4a8617..d32d95aea5d6f 100644
+--- a/arch/powerpc/boot/Makefile
++++ b/arch/powerpc/boot/Makefile
+@@ -34,6 +34,7 @@ endif
+ 
+ BOOTCFLAGS    := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
+ 		 -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \
++		 $(call cc-option,-mno-spe) $(call cc-option,-mspe=no) \
+ 		 -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
+ 		 $(LINUXINCLUDE)
+ 
+diff --git a/arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi b/arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi
+new file mode 100644
+index 0000000000000..7e2a90cde72e5
+--- /dev/null
++++ b/arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi
+@@ -0,0 +1,51 @@
++/*
++ * e500v1 Power ISA Device Tree Source (include)
++ *
++ * Copyright 2012 Freescale Semiconductor Inc.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ *     * Redistributions of source code must retain the above copyright
++ *       notice, this list of conditions and the following disclaimer.
++ *     * Redistributions in binary form must reproduce the above copyright
++ *       notice, this list of conditions and the following disclaimer in the
++ *       documentation and/or other materials provided with the distribution.
++ *     * Neither the name of Freescale Semiconductor nor the
++ *       names of its contributors may be used to endorse or promote products
++ *       derived from this software without specific prior written permission.
++ *
++ *
++ * ALTERNATIVELY, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL") as published by the Free Software
++ * Foundation, either version 2 of that License or (at your option) any
++ * later version.
++ *
++ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
++ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
++ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
++ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/ {
++	cpus {
++		power-isa-version = "2.03";
++		power-isa-b;		// Base
++		power-isa-e;		// Embedded
++		power-isa-atb;		// Alternate Time Base
++		power-isa-cs;		// Cache Specification
++		power-isa-e.le;		// Embedded.Little-Endian
++		power-isa-e.pm;		// Embedded.Performance Monitor
++		power-isa-ecl;		// Embedded Cache Locking
++		power-isa-mmc;		// Memory Coherence
++		power-isa-sp;		// Signal Processing Engine
++		power-isa-sp.fs;	// SPE.Embedded Float Scalar Single
++		power-isa-sp.fv;	// SPE.Embedded Float Vector
++		mmu-type = "power-embedded";
++	};
++};
+diff --git a/arch/powerpc/boot/dts/fsl/mpc8540ads.dts b/arch/powerpc/boot/dts/fsl/mpc8540ads.dts
+index 18a885130538a..e03ae130162ba 100644
+--- a/arch/powerpc/boot/dts/fsl/mpc8540ads.dts
++++ b/arch/powerpc/boot/dts/fsl/mpc8540ads.dts
+@@ -7,7 +7,7 @@
+ 
+ /dts-v1/;
+ 
+-/include/ "e500v2_power_isa.dtsi"
++/include/ "e500v1_power_isa.dtsi"
+ 
+ / {
+ 	model = "MPC8540ADS";
+diff --git a/arch/powerpc/boot/dts/fsl/mpc8541cds.dts b/arch/powerpc/boot/dts/fsl/mpc8541cds.dts
+index ac381e7b1c60e..a2a6c5cf852e9 100644
+--- a/arch/powerpc/boot/dts/fsl/mpc8541cds.dts
++++ b/arch/powerpc/boot/dts/fsl/mpc8541cds.dts
+@@ -7,7 +7,7 @@
+ 
+ /dts-v1/;
+ 
+-/include/ "e500v2_power_isa.dtsi"
++/include/ "e500v1_power_isa.dtsi"
+ 
+ / {
+ 	model = "MPC8541CDS";
+diff --git a/arch/powerpc/boot/dts/fsl/mpc8555cds.dts b/arch/powerpc/boot/dts/fsl/mpc8555cds.dts
+index 9f58db2a7e661..901b6ff06dfbb 100644
+--- a/arch/powerpc/boot/dts/fsl/mpc8555cds.dts
++++ b/arch/powerpc/boot/dts/fsl/mpc8555cds.dts
+@@ -7,7 +7,7 @@
+ 
+ /dts-v1/;
+ 
+-/include/ "e500v2_power_isa.dtsi"
++/include/ "e500v1_power_isa.dtsi"
+ 
+ / {
+ 	model = "MPC8555CDS";
+diff --git a/arch/powerpc/boot/dts/fsl/mpc8560ads.dts b/arch/powerpc/boot/dts/fsl/mpc8560ads.dts
+index a24722ccaebf1..c2f9aea78b29f 100644
+--- a/arch/powerpc/boot/dts/fsl/mpc8560ads.dts
++++ b/arch/powerpc/boot/dts/fsl/mpc8560ads.dts
+@@ -7,7 +7,7 @@
+ 
+ /dts-v1/;
+ 
+-/include/ "e500v2_power_isa.dtsi"
++/include/ "e500v1_power_isa.dtsi"
+ 
+ / {
+ 	model = "MPC8560ADS";
+diff --git a/arch/powerpc/boot/dts/turris1x.dts b/arch/powerpc/boot/dts/turris1x.dts
+index 12e08271e61f0..045af668e9284 100644
+--- a/arch/powerpc/boot/dts/turris1x.dts
++++ b/arch/powerpc/boot/dts/turris1x.dts
+@@ -147,7 +147,7 @@
+ 
+ 					port@0 {
+ 						reg = <0>;
+-						label = "cpu1";
++						label = "cpu";
+ 						ethernet = <&enet1>;
+ 						phy-mode = "rgmii-id";
+ 
+@@ -184,7 +184,7 @@
+ 
+ 					port@6 {
+ 						reg = <6>;
+-						label = "cpu0";
++						label = "cpu";
+ 						ethernet = <&enet0>;
+ 						phy-mode = "rgmii-id";
+ 
+@@ -263,21 +263,21 @@
+ 				};
+ 
+ 				partition@20000 {
+-					/* 1.7 MB for Rescue Linux Kernel Image */
++					/* 1.7 MB for Linux Kernel Image */
+ 					reg = <0x00020000 0x001a0000>;
+-					label = "rescue-kernel";
++					label = "kernel";
+ 				};
+ 
+ 				partition@1c0000 {
+ 					/* 1.5 MB for Rescue JFFS2 Root File System */
+ 					reg = <0x001c0000 0x00180000>;
+-					label = "rescue-rootfs";
++					label = "rescue";
+ 				};
+ 
+ 				partition@340000 {
+-					/* 11 MB for TAR.XZ Backup with content of NAND Root File System */
++					/* 11 MB for TAR.XZ Archive with Factory content of NAND Root File System */
+ 					reg = <0x00340000 0x00b00000>;
+-					label = "backup-rootfs";
++					label = "factory";
+ 				};
+ 
+ 				partition@e40000 {
+diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
+index b571d084c148b..c05e37af9f1e8 100644
+--- a/arch/powerpc/configs/pseries_defconfig
++++ b/arch/powerpc/configs/pseries_defconfig
+@@ -40,6 +40,7 @@ CONFIG_PPC_SPLPAR=y
+ CONFIG_DTL=y
+ CONFIG_PPC_SMLPAR=y
+ CONFIG_IBMEBUS=y
++CONFIG_LIBNVDIMM=m
+ CONFIG_PAPR_SCM=m
+ CONFIG_PPC_SVM=y
+ # CONFIG_PPC_PMAC is not set
+diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h
+index 8069dbc4b8d18..b61555e30c7c8 100644
+--- a/arch/powerpc/include/asm/interrupt.h
++++ b/arch/powerpc/include/asm/interrupt.h
+@@ -195,7 +195,8 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs)
+ 		 * so avoid recursion.
+ 		 */
+ 		if (TRAP(regs) != INTERRUPT_PROGRAM) {
+-			CT_WARN_ON(ct_state() != CONTEXT_KERNEL);
++			CT_WARN_ON(ct_state() != CONTEXT_KERNEL &&
++				   ct_state() != CONTEXT_IDLE);
+ 			if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG))
+ 				BUG_ON(is_implicit_soft_masked(regs));
+ 		}
+diff --git a/arch/powerpc/include/asm/syscalls.h b/arch/powerpc/include/asm/syscalls.h
+index a2b13e55254fb..da40219b303a6 100644
+--- a/arch/powerpc/include/asm/syscalls.h
++++ b/arch/powerpc/include/asm/syscalls.h
+@@ -8,6 +8,18 @@
+ #include <linux/types.h>
+ #include <linux/compat.h>
+ 
++/*
++ * long long munging:
++ * The 32 bit ABI passes long longs in an odd even register pair.
++ * High and low parts are swapped depending on endian mode,
++ * so define a macro (similar to mips linux32) to handle that.
++ */
++#ifdef __LITTLE_ENDIAN__
++#define merge_64(low, high) (((u64)high << 32) | low)
++#else
++#define merge_64(high, low) (((u64)high << 32) | low)
++#endif
++
+ struct rtas_args;
+ 
+ asmlinkage long sys_mmap(unsigned long addr, size_t len,
+diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
+index 0e75cb03244ad..f9db0a172401a 100644
+--- a/arch/powerpc/kernel/interrupt.c
++++ b/arch/powerpc/kernel/interrupt.c
+@@ -431,16 +431,6 @@ again:
+ 
+ 		if (unlikely(stack_store))
+ 			__hard_EE_RI_disable();
+-		/*
+-		 * Returning to a kernel context with local irqs disabled.
+-		 * Here, if EE was enabled in the interrupted context, enable
+-		 * it on return as well. A problem exists here where a soft
+-		 * masked interrupt may have cleared MSR[EE] and set HARD_DIS
+-		 * here, and it will still exist on return to the caller. This
+-		 * will be resolved by the masked interrupt firing again.
+-		 */
+-		if (regs->msr & MSR_EE)
+-			local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS;
+ #endif /* CONFIG_PPC64 */
+ 	}
+ 
+diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S
+index ce25b28cf418e..2ca1c037ea258 100644
+--- a/arch/powerpc/kernel/interrupt_64.S
++++ b/arch/powerpc/kernel/interrupt_64.S
+@@ -559,15 +559,54 @@ _ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
+ 	ld	r11,SOFTE(r1)
+ 	cmpwi	r11,IRQS_ENABLED
+ 	stb	r11,PACAIRQSOFTMASK(r13)
+-	bne	1f
++	beq	.Linterrupt_return_\srr\()_soft_enabled
++
++	/*
++	 * Returning to soft-disabled context.
++	 * Check if a MUST_HARD_MASK interrupt has become pending, in which
++	 * case we need to disable MSR[EE] in the return context.
++	 */
++	ld	r12,_MSR(r1)
++	andi.	r10,r12,MSR_EE
++	beq	.Lfast_kernel_interrupt_return_\srr\() // EE already disabled
++	lbz	r11,PACAIRQHAPPENED(r13)
++	andi.	r10,r11,PACA_IRQ_MUST_HARD_MASK
++	beq	.Lfast_kernel_interrupt_return_\srr\() // No HARD_MASK pending
++
++	/* Must clear MSR_EE from _MSR */
++#ifdef CONFIG_PPC_BOOK3S
++	li	r10,0
++	/* Clear valid before changing _MSR */
++	.ifc \srr,srr
++	stb	r10,PACASRR_VALID(r13)
++	.else
++	stb	r10,PACAHSRR_VALID(r13)
++	.endif
++#endif
++	xori	r12,r12,MSR_EE
++	std	r12,_MSR(r1)
++	b	.Lfast_kernel_interrupt_return_\srr\()
++
++.Linterrupt_return_\srr\()_soft_enabled:
++	/*
++	 * In the soft-enabled case, need to double-check that we have no
++	 * pending interrupts that might have come in before we reached the
++	 * restart section of code, and restart the exit so those can be
++	 * handled.
++	 *
++	 * If there are none, it is be possible that the interrupt still
++	 * has PACA_IRQ_HARD_DIS set, which needs to be cleared for the
++	 * interrupted context. This clear will not clobber a new pending
++	 * interrupt coming in, because we're in the restart section, so
++	 * such would return to the restart location.
++	 */
+ #ifdef CONFIG_PPC_BOOK3S
+ 	lbz	r11,PACAIRQHAPPENED(r13)
+ 	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
+ 	bne-	interrupt_return_\srr\()_kernel_restart
+ #endif
+ 	li	r11,0
+-	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
+-1:
++	stb	r11,PACAIRQHAPPENED(r13) // clear the possible HARD_DIS
+ 
+ .Lfast_kernel_interrupt_return_\srr\():
+ 	cmpdi	cr1,r3,0
+diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
+index 912d4f8a13beb..bd7b1a0354594 100644
+--- a/arch/powerpc/kernel/kprobes.c
++++ b/arch/powerpc/kernel/kprobes.c
+@@ -161,7 +161,13 @@ int arch_prepare_kprobe(struct kprobe *p)
+ 	preempt_disable();
+ 	prev = get_kprobe(p->addr - 1);
+ 	preempt_enable_no_resched();
+-	if (prev && ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) {
++
++	/*
++	 * When prev is a ftrace-based kprobe, we don't have an insn, and it
++	 * doesn't probe for prefixed instruction.
++	 */
++	if (prev && !kprobe_ftrace(prev) &&
++	    ppc_inst_prefixed(ppc_inst_read(prev->ainsn.insn))) {
+ 		printk("Cannot register a kprobe on the second word of prefixed instruction\n");
+ 		ret = -EINVAL;
+ 	}
+diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
+index 7a35fc25a3046..38561d6a20792 100644
+--- a/arch/powerpc/kernel/pci_dn.c
++++ b/arch/powerpc/kernel/pci_dn.c
+@@ -330,6 +330,7 @@ struct pci_dn *pci_add_device_node_info(struct pci_controller *hose,
+ 	INIT_LIST_HEAD(&pdn->list);
+ 	parent = of_get_parent(dn);
+ 	pdn->parent = parent ? PCI_DN(parent) : NULL;
++	of_node_put(parent);
+ 	if (pdn->parent)
+ 		list_add_tail(&pdn->list, &pdn->parent->child_list);
+ 
+diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
+index 2b2d0b0fbb30d..ce8fc6575eaa2 100644
+--- a/arch/powerpc/kernel/setup_64.c
++++ b/arch/powerpc/kernel/setup_64.c
+@@ -182,8 +182,10 @@ static void __init fixup_boot_paca(void)
+ 	get_paca()->cpu_start = 1;
+ 	/* Allow percpu accesses to work until we setup percpu data */
+ 	get_paca()->data_offset = 0;
+-	/* Mark interrupts disabled in PACA */
++	/* Mark interrupts soft and hard disabled in PACA */
+ 	irq_soft_mask_set(IRQS_DISABLED);
++	get_paca()->irq_happened = PACA_IRQ_HARD_DIS;
++	WARN_ON(mfmsr() & MSR_EE);
+ }
+ 
+ static void __init configure_exceptions(void)
+diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
+index 16ff0399a2574..719bfc6d1e3f5 100644
+--- a/arch/powerpc/kernel/sys_ppc32.c
++++ b/arch/powerpc/kernel/sys_ppc32.c
+@@ -56,18 +56,6 @@ unsigned long compat_sys_mmap2(unsigned long addr, size_t len,
+ 	return sys_mmap(addr, len, prot, flags, fd, pgoff << 12);
+ }
+ 
+-/* 
+- * long long munging:
+- * The 32 bit ABI passes long longs in an odd even register pair.
+- * High and low parts are swapped depending on endian mode,
+- * so define a macro (similar to mips linux32) to handle that.
+- */
+-#ifdef __LITTLE_ENDIAN__
+-#define merge_64(low, high) ((u64)high << 32) | low
+-#else
+-#define merge_64(high, low) ((u64)high << 32) | low
+-#endif
+-
+ compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count,
+ 			     u32 reg6, u32 pos1, u32 pos2)
+ {
+@@ -94,7 +82,7 @@ asmlinkage int compat_sys_truncate64(const char __user * path, u32 reg4,
+ asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offset1, u32 offset2,
+ 				     u32 len1, u32 len2)
+ {
+-	return ksys_fallocate(fd, mode, ((loff_t)offset1 << 32) | offset2,
++	return ksys_fallocate(fd, mode, merge_64(offset1, offset2),
+ 			     merge_64(len1, len2));
+ }
+ 
+diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
+index fc999140bc27e..abc3fbb3c4902 100644
+--- a/arch/powerpc/kernel/syscalls.c
++++ b/arch/powerpc/kernel/syscalls.c
+@@ -98,8 +98,8 @@ long ppc64_personality(unsigned long personality)
+ long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low,
+ 		      u32 len_high, u32 len_low)
+ {
+-	return ksys_fadvise64_64(fd, (u64)offset_high << 32 | offset_low,
+-				 (u64)len_high << 32 | len_low, advice);
++	return ksys_fadvise64_64(fd, merge_64(offset_high, offset_low),
++				 merge_64(len_high, len_low), advice);
+ }
+ 
+ SYSCALL_DEFINE0(switch_endian)
+diff --git a/arch/powerpc/math-emu/math_efp.c b/arch/powerpc/math-emu/math_efp.c
+index 39b84e7452e1b..aa3bb8da1cb9b 100644
+--- a/arch/powerpc/math-emu/math_efp.c
++++ b/arch/powerpc/math-emu/math_efp.c
+@@ -17,6 +17,7 @@
+ 
+ #include <linux/types.h>
+ #include <linux/prctl.h>
++#include <linux/module.h>
+ 
+ #include <linux/uaccess.h>
+ #include <asm/reg.h>
+diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
+index 55a8fbfdb5b28..3510b55b36f8c 100644
+--- a/arch/powerpc/platforms/powernv/opal.c
++++ b/arch/powerpc/platforms/powernv/opal.c
+@@ -892,6 +892,7 @@ static void opal_export_attrs(void)
+ 	kobj = kobject_create_and_add("exports", opal_kobj);
+ 	if (!kobj) {
+ 		pr_warn("kobject_create_and_add() of exports failed\n");
++		of_node_put(np);
+ 		return;
+ 	}
+ 
+diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c
+index 7e6e6dd2e33e9..1a2cbc156e8f3 100644
+--- a/arch/powerpc/platforms/pseries/vas.c
++++ b/arch/powerpc/platforms/pseries/vas.c
+@@ -333,7 +333,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
+ 		 * So no unpacking needs to be done.
+ 		 */
+ 		rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, domain,
+-				  VPHN_FLAG_VCPU, smp_processor_id());
++				  VPHN_FLAG_VCPU, hard_smp_processor_id());
+ 		if (rc != H_SUCCESS) {
+ 			pr_err("H_HOME_NODE_ASSOCIATIVITY error: %d\n", rc);
+ 			goto out;
+diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
+index ef9a5999fa93d..73c2d70706c0a 100644
+--- a/arch/powerpc/sysdev/fsl_msi.c
++++ b/arch/powerpc/sysdev/fsl_msi.c
+@@ -209,8 +209,10 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+ 			dev_err(&pdev->dev,
+ 				"node %pOF has an invalid fsl,msi phandle %u\n",
+ 				hose->dn, np->phandle);
++			of_node_put(np);
+ 			return -EINVAL;
+ 		}
++		of_node_put(np);
+ 	}
+ 
+ 	msi_for_each_desc(entry, &pdev->dev, MSI_DESC_NOTASSOCIATED) {
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index 59d18881f35be..cea22ccb57cb9 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -52,7 +52,7 @@ config RISCV
+ 	select COMMON_CLK
+ 	select CPU_PM if CPU_IDLE
+ 	select EDAC_SUPPORT
+-	select GENERIC_ARCH_TOPOLOGY if SMP
++	select GENERIC_ARCH_TOPOLOGY
+ 	select GENERIC_ATOMIC64 if !64BIT
+ 	select GENERIC_CLOCKEVENTS_BROADCAST if SMP
+ 	select GENERIC_EARLY_IOREMAP
+diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
+index 3fa8ef3368224..e7d52a2301e26 100644
+--- a/arch/riscv/Makefile
++++ b/arch/riscv/Makefile
+@@ -37,6 +37,7 @@ else
+ endif
+ 
+ ifeq ($(CONFIG_LD_IS_LLD),y)
++ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 150000; echo $$?),0)
+ 	KBUILD_CFLAGS += -mno-relax
+ 	KBUILD_AFLAGS += -mno-relax
+ ifndef CONFIG_AS_IS_LLVM
+@@ -44,6 +45,7 @@ ifndef CONFIG_AS_IS_LLVM
+ 	KBUILD_AFLAGS += -Wa,-mno-relax
+ endif
+ endif
++endif
+ 
+ # ISA string setting
+ riscv-march-$(CONFIG_ARCH_RV32I)	:= rv32ima
+diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
+index 69605a4742706..92080a2279372 100644
+--- a/arch/riscv/include/asm/io.h
++++ b/arch/riscv/include/asm/io.h
+@@ -101,9 +101,9 @@ __io_reads_ins(reads, u32, l, __io_br(), __io_ar(addr))
+ __io_reads_ins(ins,  u8, b, __io_pbr(), __io_par(addr))
+ __io_reads_ins(ins, u16, w, __io_pbr(), __io_par(addr))
+ __io_reads_ins(ins, u32, l, __io_pbr(), __io_par(addr))
+-#define insb(addr, buffer, count) __insb((void __iomem *)(long)addr, buffer, count)
+-#define insw(addr, buffer, count) __insw((void __iomem *)(long)addr, buffer, count)
+-#define insl(addr, buffer, count) __insl((void __iomem *)(long)addr, buffer, count)
++#define insb(addr, buffer, count) __insb(PCI_IOBASE + (addr), buffer, count)
++#define insw(addr, buffer, count) __insw(PCI_IOBASE + (addr), buffer, count)
++#define insl(addr, buffer, count) __insl(PCI_IOBASE + (addr), buffer, count)
+ 
+ __io_writes_outs(writes,  u8, b, __io_bw(), __io_aw())
+ __io_writes_outs(writes, u16, w, __io_bw(), __io_aw())
+@@ -115,22 +115,22 @@ __io_writes_outs(writes, u32, l, __io_bw(), __io_aw())
+ __io_writes_outs(outs,  u8, b, __io_pbw(), __io_paw())
+ __io_writes_outs(outs, u16, w, __io_pbw(), __io_paw())
+ __io_writes_outs(outs, u32, l, __io_pbw(), __io_paw())
+-#define outsb(addr, buffer, count) __outsb((void __iomem *)(long)addr, buffer, count)
+-#define outsw(addr, buffer, count) __outsw((void __iomem *)(long)addr, buffer, count)
+-#define outsl(addr, buffer, count) __outsl((void __iomem *)(long)addr, buffer, count)
++#define outsb(addr, buffer, count) __outsb(PCI_IOBASE + (addr), buffer, count)
++#define outsw(addr, buffer, count) __outsw(PCI_IOBASE + (addr), buffer, count)
++#define outsl(addr, buffer, count) __outsl(PCI_IOBASE + (addr), buffer, count)
+ 
+ #ifdef CONFIG_64BIT
+ __io_reads_ins(reads, u64, q, __io_br(), __io_ar(addr))
+ #define readsq(addr, buffer, count) __readsq(addr, buffer, count)
+ 
+ __io_reads_ins(ins, u64, q, __io_pbr(), __io_par(addr))
+-#define insq(addr, buffer, count) __insq((void __iomem *)addr, buffer, count)
++#define insq(addr, buffer, count) __insq(PCI_IOBASE + (addr), buffer, count)
+ 
+ __io_writes_outs(writes, u64, q, __io_bw(), __io_aw())
+ #define writesq(addr, buffer, count) __writesq(addr, buffer, count)
+ 
+ __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw())
+-#define outsq(addr, buffer, count) __outsq((void __iomem *)addr, buffer, count)
++#define outsq(addr, buffer, count) __outsq(PCI_IOBASE + (addr), buffer, count)
+ #endif
+ 
+ #include <asm-generic/io.h>
+diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
+index cedcf8ea3c766..0099dc1161683 100644
+--- a/arch/riscv/include/asm/mmu.h
++++ b/arch/riscv/include/asm/mmu.h
+@@ -16,7 +16,6 @@ typedef struct {
+ 	atomic_long_t id;
+ #endif
+ 	void *vdso;
+-	void *vdso_info;
+ #ifdef CONFIG_SMP
+ 	/* A local icache flush is needed before user execution can resume. */
+ 	cpumask_t icache_stale_mask;
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
+index 2dfc463b86bb3..ad76bb59b0590 100644
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -252,10 +252,10 @@ static void __init parse_dtb(void)
+ 			pr_info("Machine model: %s\n", name);
+ 			dump_stack_set_arch_desc("%s (DT)", name);
+ 		}
+-		return;
++	} else {
++		pr_err("No DTB passed to the kernel\n");
+ 	}
+ 
+-	pr_err("No DTB passed to the kernel\n");
+ #ifdef CONFIG_CMDLINE_FORCE
+ 	strscpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
+ 	pr_info("Forcing kernel command line to: %s\n", boot_command_line);
+diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
+index a752c7b416838..3373df413c882 100644
+--- a/arch/riscv/kernel/smpboot.c
++++ b/arch/riscv/kernel/smpboot.c
+@@ -49,6 +49,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
+ 	unsigned int curr_cpuid;
+ 
+ 	curr_cpuid = smp_processor_id();
++	store_cpu_topology(curr_cpuid);
+ 	numa_store_cpu_info(curr_cpuid);
+ 	numa_add_cpu(curr_cpuid);
+ 
+@@ -162,9 +163,9 @@ asmlinkage __visible void smp_callin(void)
+ 	mmgrab(mm);
+ 	current->active_mm = mm;
+ 
++	store_cpu_topology(curr_cpuid);
+ 	notify_cpu_starting(curr_cpuid);
+ 	numa_add_cpu(curr_cpuid);
+-	update_siblings_masks(curr_cpuid);
+ 	set_cpu_online(curr_cpuid, 1);
+ 
+ 	/*
+diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c
+index 571556bb9261a..5d3f2fbeb33c7 100644
+--- a/arch/riscv/kernel/sys_riscv.c
++++ b/arch/riscv/kernel/sys_riscv.c
+@@ -18,9 +18,6 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len,
+ 	if (unlikely(offset & (~PAGE_MASK >> page_shift_offset)))
+ 		return -EINVAL;
+ 
+-	if (unlikely((prot & PROT_WRITE) && !(prot & PROT_READ)))
+-		return -EINVAL;
+-
+ 	return ksys_mmap_pgoff(addr, len, prot, flags, fd,
+ 			       offset >> (PAGE_SHIFT - page_shift_offset));
+ }
+diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
+index 69b05b6c181b6..4abc9aebdfae2 100644
+--- a/arch/riscv/kernel/vdso.c
++++ b/arch/riscv/kernel/vdso.c
+@@ -60,6 +60,11 @@ struct __vdso_info {
+ 	struct vm_special_mapping *cm;
+ };
+ 
++static struct __vdso_info vdso_info;
++#ifdef CONFIG_COMPAT
++static struct __vdso_info compat_vdso_info;
++#endif
++
+ static int vdso_mremap(const struct vm_special_mapping *sm,
+ 		       struct vm_area_struct *new_vma)
+ {
+@@ -114,15 +119,18 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
+ {
+ 	struct mm_struct *mm = task->mm;
+ 	struct vm_area_struct *vma;
+-	struct __vdso_info *vdso_info = mm->context.vdso_info;
+ 
+ 	mmap_read_lock(mm);
+ 
+ 	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+ 		unsigned long size = vma->vm_end - vma->vm_start;
+ 
+-		if (vma_is_special_mapping(vma, vdso_info->dm))
++		if (vma_is_special_mapping(vma, vdso_info.dm))
+ 			zap_page_range(vma, vma->vm_start, size);
++#ifdef CONFIG_COMPAT
++		if (vma_is_special_mapping(vma, compat_vdso_info.dm))
++			zap_page_range(vma, vma->vm_start, size);
++#endif
+ 	}
+ 
+ 	mmap_read_unlock(mm);
+@@ -264,7 +272,6 @@ static int __setup_additional_pages(struct mm_struct *mm,
+ 
+ 	vdso_base += VVAR_SIZE;
+ 	mm->context.vdso = (void *)vdso_base;
+-	mm->context.vdso_info = (void *)vdso_info;
+ 
+ 	ret =
+ 	   _install_special_mapping(mm, vdso_base, vdso_text_len,
+diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
+index f2fbd1400b7c9..d86f7cebd4a7e 100644
+--- a/arch/riscv/mm/fault.c
++++ b/arch/riscv/mm/fault.c
+@@ -184,7 +184,8 @@ static inline bool access_error(unsigned long cause, struct vm_area_struct *vma)
+ 		}
+ 		break;
+ 	case EXC_LOAD_PAGE_FAULT:
+-		if (!(vma->vm_flags & VM_READ)) {
++		/* Write implies read */
++		if (!(vma->vm_flags & (VM_READ | VM_WRITE))) {
+ 			return true;
+ 		}
+ 		break;
+diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h
+index 8edb824049b9e..0cb0ca149ac34 100644
+--- a/arch/sh/include/asm/sections.h
++++ b/arch/sh/include/asm/sections.h
+@@ -4,7 +4,7 @@
+ 
+ #include <asm-generic/sections.h>
+ 
+-extern long __machvec_start, __machvec_end;
++extern char __machvec_start[], __machvec_end[];
+ extern char __uncached_start, __uncached_end;
+ extern char __start_eh_frame[], __stop_eh_frame[];
+ 
+diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
+index d606679a211e1..57efaf5b82ae0 100644
+--- a/arch/sh/kernel/machvec.c
++++ b/arch/sh/kernel/machvec.c
+@@ -20,8 +20,8 @@
+ #define MV_NAME_SIZE 32
+ 
+ #define for_each_mv(mv) \
+-	for ((mv) = (struct sh_machine_vector *)&__machvec_start; \
+-	     (mv) && (unsigned long)(mv) < (unsigned long)&__machvec_end; \
++	for ((mv) = (struct sh_machine_vector *)__machvec_start; \
++	     (mv) && (unsigned long)(mv) < (unsigned long)__machvec_end; \
+ 	     (mv)++)
+ 
+ static struct sh_machine_vector * __init get_mv_byname(const char *name)
+@@ -87,8 +87,8 @@ void __init sh_mv_setup(void)
+ 	if (!machvec_selected) {
+ 		unsigned long machvec_size;
+ 
+-		machvec_size = ((unsigned long)&__machvec_end -
+-				(unsigned long)&__machvec_start);
++		machvec_size = ((unsigned long)__machvec_end -
++				(unsigned long)__machvec_start);
+ 
+ 		/*
+ 		 * Sanity check for machvec section alignment. Ensure
+@@ -102,7 +102,7 @@ void __init sh_mv_setup(void)
+ 		 * vector (usually the only one) from .machvec.init.
+ 		 */
+ 		if (machvec_size >= sizeof(struct sh_machine_vector))
+-			sh_mv = *(struct sh_machine_vector *)&__machvec_start;
++			sh_mv = *(struct sh_machine_vector *)__machvec_start;
+ 	}
+ 
+ 	pr_notice("Booting machvec: %s\n", get_system_type());
+diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
+index d9e023c78f568..f6f126ac34804 100644
+--- a/arch/um/kernel/um_arch.c
++++ b/arch/um/kernel/um_arch.c
+@@ -96,7 +96,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
+ 
+ static void *c_start(struct seq_file *m, loff_t *pos)
+ {
+-	return *pos < NR_CPUS ? cpu_data + *pos : NULL;
++	return *pos < nr_cpu_ids ? cpu_data + *pos : NULL;
+ }
+ 
+ static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index f9920f1341c8d..159c025ebb03e 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -448,6 +448,11 @@ config X86_X2APIC
+ 	  This allows 32-bit apic IDs (so it can support very large systems),
+ 	  and accesses the local apic via MSRs not via mmio.
+ 
++	  Some Intel systems circa 2022 and later are locked into x2APIC mode
++	  and can not fall back to the legacy APIC modes if SGX or TDX are
++	  enabled in the BIOS.  They will be unable to boot without enabling
++	  this option.
++
+ 	  If you don't know what to do here, say N.
+ 
+ config X86_MPPARSE
+@@ -1919,7 +1924,7 @@ endchoice
+ 
+ config X86_SGX
+ 	bool "Software Guard eXtensions (SGX)"
+-	depends on X86_64 && CPU_SUP_INTEL
++	depends on X86_64 && CPU_SUP_INTEL && X86_X2APIC
+ 	depends on CRYPTO=y
+ 	depends on CRYPTO_SHA256=y
+ 	select SRCU
+diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
+index 8cbf623f0ecfb..b472ef76826ad 100644
+--- a/arch/x86/include/asm/cpu.h
++++ b/arch/x86/include/asm/cpu.h
+@@ -94,4 +94,6 @@ static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1,
+ 	return p1 & p2;
+ }
+ 
++extern u64 x86_read_arch_cap_msr(void);
++
+ #endif /* _ASM_X86_CPU_H */
+diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
+index 0a9407dc08598..6f0acc45e67a7 100644
+--- a/arch/x86/include/asm/hyperv-tlfs.h
++++ b/arch/x86/include/asm/hyperv-tlfs.h
+@@ -546,7 +546,7 @@ struct hv_enlightened_vmcs {
+ 	u64 guest_rip;
+ 
+ 	u32 hv_clean_fields;
+-	u32 hv_padding_32;
++	u32 padding32_1;
+ 	u32 hv_synthetic_controls;
+ 	struct {
+ 		u32 nested_flush_hypercall:1;
+@@ -554,7 +554,7 @@ struct hv_enlightened_vmcs {
+ 		u32 reserved:30;
+ 	}  __packed hv_enlightenments_control;
+ 	u32 hv_vp_id;
+-
++	u32 padding32_2;
+ 	u64 hv_vm_id;
+ 	u64 partition_assist_page;
+ 	u64 padding64_4[4];
+diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
+index 0c3d3440fe278..aa675783412f8 100644
+--- a/arch/x86/include/asm/microcode.h
++++ b/arch/x86/include/asm/microcode.h
+@@ -9,6 +9,7 @@
+ struct ucode_patch {
+ 	struct list_head plist;
+ 	void *data;		/* Intel uses only this one */
++	unsigned int size;
+ 	u32 patch_id;
+ 	u16 equiv_cpu;
+ };
+diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
+index 6674bdb096f34..1e086b37a3071 100644
+--- a/arch/x86/include/asm/msr-index.h
++++ b/arch/x86/include/asm/msr-index.h
+@@ -155,6 +155,11 @@
+ 						 * Return Stack Buffer Predictions.
+ 						 */
+ 
++#define ARCH_CAP_XAPIC_DISABLE		BIT(21)	/*
++						 * IA32_XAPIC_DISABLE_STATUS MSR
++						 * supported
++						 */
++
+ #define MSR_IA32_FLUSH_CMD		0x0000010b
+ #define L1D_FLUSH			BIT(0)	/*
+ 						 * Writeback and invalidate the
+@@ -1054,4 +1059,12 @@
+ #define MSR_IA32_HW_FEEDBACK_PTR        0x17d0
+ #define MSR_IA32_HW_FEEDBACK_CONFIG     0x17d1
+ 
++/* x2APIC locked status */
++#define MSR_IA32_XAPIC_DISABLE_STATUS	0xBD
++#define LEGACY_XAPIC_DISABLED		BIT(0) /*
++						* x2APIC mode is locked and
++						* disabling x2APIC will cause
++						* a #GP
++						*/
++
+ #endif /* _ASM_X86_MSR_INDEX_H */
+diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
+index 89df6c6617f50..bc2e1b67319d3 100644
+--- a/arch/x86/include/asm/paravirt_types.h
++++ b/arch/x86/include/asm/paravirt_types.h
+@@ -414,8 +414,17 @@ int paravirt_disable_iospace(void);
+ 				"=c" (__ecx)
+ #define PVOP_CALL_CLOBBERS	PVOP_VCALL_CLOBBERS, "=a" (__eax)
+ 
+-/* void functions are still allowed [re]ax for scratch */
++/*
++ * void functions are still allowed [re]ax for scratch.
++ *
++ * The ZERO_CALL_USED REGS feature may end up zeroing out callee-saved
++ * registers. Make sure we model this with the appropriate clobbers.
++ */
++#ifdef CONFIG_ZERO_CALL_USED_REGS
++#define PVOP_VCALLEE_CLOBBERS	"=a" (__eax), PVOP_VCALL_CLOBBERS
++#else
+ #define PVOP_VCALLEE_CLOBBERS	"=a" (__eax)
++#endif
+ #define PVOP_CALLEE_CLOBBERS	PVOP_VCALLEE_CLOBBERS
+ 
+ #define EXTRA_CLOBBERS	 , "r8", "r9", "r10", "r11"
+diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
+index 6d303d1d276c3..c6876d3ea4b17 100644
+--- a/arch/x86/kernel/apic/apic.c
++++ b/arch/x86/kernel/apic/apic.c
+@@ -61,6 +61,7 @@
+ #include <asm/cpu_device_id.h>
+ #include <asm/intel-family.h>
+ #include <asm/irq_regs.h>
++#include <asm/cpu.h>
+ 
+ unsigned int num_processors;
+ 
+@@ -1751,11 +1752,26 @@ EXPORT_SYMBOL_GPL(x2apic_mode);
+ 
+ enum {
+ 	X2APIC_OFF,
+-	X2APIC_ON,
+ 	X2APIC_DISABLED,
++	/* All states below here have X2APIC enabled */
++	X2APIC_ON,
++	X2APIC_ON_LOCKED
+ };
+ static int x2apic_state;
+ 
++static bool x2apic_hw_locked(void)
++{
++	u64 ia32_cap;
++	u64 msr;
++
++	ia32_cap = x86_read_arch_cap_msr();
++	if (ia32_cap & ARCH_CAP_XAPIC_DISABLE) {
++		rdmsrl(MSR_IA32_XAPIC_DISABLE_STATUS, msr);
++		return (msr & LEGACY_XAPIC_DISABLED);
++	}
++	return false;
++}
++
+ static void __x2apic_disable(void)
+ {
+ 	u64 msr;
+@@ -1793,6 +1809,10 @@ static int __init setup_nox2apic(char *str)
+ 				apicid);
+ 			return 0;
+ 		}
++		if (x2apic_hw_locked()) {
++			pr_warn("APIC locked in x2apic mode, can't disable\n");
++			return 0;
++		}
+ 		pr_warn("x2apic already enabled.\n");
+ 		__x2apic_disable();
+ 	}
+@@ -1807,10 +1827,18 @@ early_param("nox2apic", setup_nox2apic);
+ void x2apic_setup(void)
+ {
+ 	/*
+-	 * If x2apic is not in ON state, disable it if already enabled
++	 * Try to make the AP's APIC state match that of the BSP,  but if the
++	 * BSP is unlocked and the AP is locked then there is a state mismatch.
++	 * Warn about the mismatch in case a GP fault occurs due to a locked AP
++	 * trying to be turned off.
++	 */
++	if (x2apic_state != X2APIC_ON_LOCKED && x2apic_hw_locked())
++		pr_warn("x2apic lock mismatch between BSP and AP.\n");
++	/*
++	 * If x2apic is not in ON or LOCKED state, disable it if already enabled
+ 	 * from BIOS.
+ 	 */
+-	if (x2apic_state != X2APIC_ON) {
++	if (x2apic_state < X2APIC_ON) {
+ 		__x2apic_disable();
+ 		return;
+ 	}
+@@ -1831,6 +1859,11 @@ static __init void x2apic_disable(void)
+ 	if (x2apic_id >= 255)
+ 		panic("Cannot disable x2apic, id: %08x\n", x2apic_id);
+ 
++	if (x2apic_hw_locked()) {
++		pr_warn("Cannot disable locked x2apic, id: %08x\n", x2apic_id);
++		return;
++	}
++
+ 	__x2apic_disable();
+ 	register_lapic_address(mp_lapic_addr);
+ }
+@@ -1889,7 +1922,10 @@ void __init check_x2apic(void)
+ 	if (x2apic_enabled()) {
+ 		pr_info("x2apic: enabled by BIOS, switching to x2apic ops\n");
+ 		x2apic_mode = 1;
+-		x2apic_state = X2APIC_ON;
++		if (x2apic_hw_locked())
++			x2apic_state = X2APIC_ON_LOCKED;
++		else
++			x2apic_state = X2APIC_ON;
+ 	} else if (!boot_cpu_has(X86_FEATURE_X2APIC)) {
+ 		x2apic_state = X2APIC_DISABLED;
+ 	}
+diff --git a/arch/x86/kernel/cpu/feat_ctl.c b/arch/x86/kernel/cpu/feat_ctl.c
+index 993697e71854c..03851240c3e36 100644
+--- a/arch/x86/kernel/cpu/feat_ctl.c
++++ b/arch/x86/kernel/cpu/feat_ctl.c
+@@ -1,11 +1,11 @@
+ // SPDX-License-Identifier: GPL-2.0
+ #include <linux/tboot.h>
+ 
++#include <asm/cpu.h>
+ #include <asm/cpufeature.h>
+ #include <asm/msr-index.h>
+ #include <asm/processor.h>
+ #include <asm/vmx.h>
+-#include "cpu.h"
+ 
+ #undef pr_fmt
+ #define pr_fmt(fmt)	"x86/cpu: " fmt
+diff --git a/arch/x86/kernel/cpu/mce/apei.c b/arch/x86/kernel/cpu/mce/apei.c
+index 717192915f28a..8ed341714686a 100644
+--- a/arch/x86/kernel/cpu/mce/apei.c
++++ b/arch/x86/kernel/cpu/mce/apei.c
+@@ -29,15 +29,26 @@
+ void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err)
+ {
+ 	struct mce m;
++	int lsb;
+ 
+ 	if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
+ 		return;
+ 
++	/*
++	 * Even if the ->validation_bits are set for address mask,
++	 * to be extra safe, check and reject an error radius '0',
++	 * and fall back to the default page size.
++	 */
++	if (mem_err->validation_bits & CPER_MEM_VALID_PA_MASK)
++		lsb = find_first_bit((void *)&mem_err->physical_addr_mask, PAGE_SHIFT);
++	else
++		lsb = PAGE_SHIFT;
++
+ 	mce_setup(&m);
+ 	m.bank = -1;
+ 	/* Fake a memory read error with unknown channel */
+ 	m.status = MCI_STATUS_VAL | MCI_STATUS_EN | MCI_STATUS_ADDRV | MCI_STATUS_MISCV | 0x9f;
+-	m.misc = (MCI_MISC_ADDR_PHYS << 6) | PAGE_SHIFT;
++	m.misc = (MCI_MISC_ADDR_PHYS << 6) | lsb;
+ 
+ 	if (severity >= GHES_SEV_RECOVERABLE)
+ 		m.status |= MCI_STATUS_UC;
+diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
+index 8b2fcdfa6d316..615bc6efa1dd4 100644
+--- a/arch/x86/kernel/cpu/microcode/amd.c
++++ b/arch/x86/kernel/cpu/microcode/amd.c
+@@ -788,6 +788,7 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover,
+ 		kfree(patch);
+ 		return -EINVAL;
+ 	}
++	patch->size = *patch_size;
+ 
+ 	mc_hdr      = (struct microcode_header_amd *)(fw + SECTION_HDR_SIZE);
+ 	proc_id     = mc_hdr->processor_rev_id;
+@@ -869,7 +870,7 @@ load_microcode_amd(bool save, u8 family, const u8 *data, size_t size)
+ 		return ret;
+ 
+ 	memset(amd_ucode_patch, 0, PATCH_MAX_SIZE);
+-	memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), PATCH_MAX_SIZE));
++	memcpy(amd_ucode_patch, p->data, min_t(u32, p->size, PATCH_MAX_SIZE));
+ 
+ 	return ret;
+ }
+diff --git a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
+index db813f819ad6c..4d8398986f784 100644
+--- a/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
++++ b/arch/x86/kernel/cpu/resctrl/pseudo_lock.c
+@@ -420,6 +420,7 @@ static int pseudo_lock_fn(void *_rdtgrp)
+ 	struct pseudo_lock_region *plr = rdtgrp->plr;
+ 	u32 rmid_p, closid_p;
+ 	unsigned long i;
++	u64 saved_msr;
+ #ifdef CONFIG_KASAN
+ 	/*
+ 	 * The registers used for local register variables are also used
+@@ -463,6 +464,7 @@ static int pseudo_lock_fn(void *_rdtgrp)
+ 	 * the buffer and evict pseudo-locked memory read earlier from the
+ 	 * cache.
+ 	 */
++	saved_msr = __rdmsr(MSR_MISC_FEATURE_CONTROL);
+ 	__wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0);
+ 	closid_p = this_cpu_read(pqr_state.cur_closid);
+ 	rmid_p = this_cpu_read(pqr_state.cur_rmid);
+@@ -514,7 +516,7 @@ static int pseudo_lock_fn(void *_rdtgrp)
+ 	__wrmsr(IA32_PQR_ASSOC, rmid_p, closid_p);
+ 
+ 	/* Re-enable the hardware prefetcher(s) */
+-	wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0);
++	wrmsrl(MSR_MISC_FEATURE_CONTROL, saved_msr);
+ 	local_irq_enable();
+ 
+ 	plr->thread_done = 1;
+@@ -871,6 +873,7 @@ bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_domain *d)
+ static int measure_cycles_lat_fn(void *_plr)
+ {
+ 	struct pseudo_lock_region *plr = _plr;
++	u32 saved_low, saved_high;
+ 	unsigned long i;
+ 	u64 start, end;
+ 	void *mem_r;
+@@ -879,6 +882,7 @@ static int measure_cycles_lat_fn(void *_plr)
+ 	/*
+ 	 * Disable hardware prefetchers.
+ 	 */
++	rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
+ 	wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0);
+ 	mem_r = READ_ONCE(plr->kmem);
+ 	/*
+@@ -895,7 +899,7 @@ static int measure_cycles_lat_fn(void *_plr)
+ 		end = rdtsc_ordered();
+ 		trace_pseudo_lock_mem_latency((u32)(end - start));
+ 	}
+-	wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0);
++	wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
+ 	local_irq_enable();
+ 	plr->thread_done = 1;
+ 	wake_up_interruptible(&plr->lock_thread_wq);
+@@ -940,6 +944,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,
+ 	u64 hits_before = 0, hits_after = 0, miss_before = 0, miss_after = 0;
+ 	struct perf_event *miss_event, *hit_event;
+ 	int hit_pmcnum, miss_pmcnum;
++	u32 saved_low, saved_high;
+ 	unsigned int line_size;
+ 	unsigned int size;
+ 	unsigned long i;
+@@ -973,6 +978,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,
+ 	/*
+ 	 * Disable hardware prefetchers.
+ 	 */
++	rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
+ 	wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0);
+ 
+ 	/* Initialize rest of local variables */
+@@ -1031,7 +1037,7 @@ static int measure_residency_fn(struct perf_event_attr *miss_attr,
+ 	 */
+ 	rmb();
+ 	/* Re-enable hardware prefetchers */
+-	wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0);
++	wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high);
+ 	local_irq_enable();
+ out_hit:
+ 	perf_event_release_kernel(hit_event);
+diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
+index aacb28c83e437..883e380e5801d 100644
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -1953,7 +1953,7 @@ static int em_pop_sreg(struct x86_emulate_ctxt *ctxt)
+ 	if (rc != X86EMUL_CONTINUE)
+ 		return rc;
+ 
+-	if (ctxt->modrm_reg == VCPU_SREG_SS)
++	if (seg == VCPU_SREG_SS)
+ 		ctxt->interruptibility = KVM_X86_SHADOW_INT_MOV_SS;
+ 	if (ctxt->op_bytes > 2)
+ 		rsp_increment(ctxt, ctxt->op_bytes - 2);
+diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
+index ddd4367d48265..03d348fa6485a 100644
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -2328,9 +2328,14 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
+ 	 * are emulated by vmx_set_efer() in prepare_vmcs02(), but speculate
+ 	 * on the related bits (if supported by the CPU) in the hope that
+ 	 * we can avoid VMWrites during vmx_set_efer().
++	 *
++	 * Similarly, take vmcs01's PERF_GLOBAL_CTRL in the hope that if KVM is
++	 * loading PERF_GLOBAL_CTRL via the VMCS for L1, then KVM will want to
++	 * do the same for L2.
+ 	 */
+ 	exec_control = __vm_entry_controls_get(vmcs01);
+-	exec_control |= vmcs12->vm_entry_controls;
++	exec_control |= (vmcs12->vm_entry_controls &
++			 ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL);
+ 	exec_control &= ~(VM_ENTRY_IA32E_MODE | VM_ENTRY_LOAD_IA32_EFER);
+ 	if (cpu_has_load_ia32_efer()) {
+ 		if (guest_efer & EFER_LMA)
+@@ -3827,7 +3832,16 @@ static void nested_vmx_inject_exception_vmexit(struct kvm_vcpu *vcpu,
+ 	u32 intr_info = nr | INTR_INFO_VALID_MASK;
+ 
+ 	if (vcpu->arch.exception.has_error_code) {
+-		vmcs12->vm_exit_intr_error_code = vcpu->arch.exception.error_code;
++		/*
++		 * Intel CPUs do not generate error codes with bits 31:16 set,
++		 * and more importantly VMX disallows setting bits 31:16 in the
++		 * injected error code for VM-Entry.  Drop the bits to mimic
++		 * hardware and avoid inducing failure on nested VM-Entry if L1
++		 * chooses to inject the exception back to L2.  AMD CPUs _do_
++		 * generate "full" 32-bit error codes, so KVM allows userspace
++		 * to inject exception error codes with bits 31:16 set.
++		 */
++		vmcs12->vm_exit_intr_error_code = (u16)vcpu->arch.exception.error_code;
+ 		intr_info |= INTR_INFO_DELIVER_CODE_MASK;
+ 	}
+ 
+@@ -4255,14 +4269,6 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
+ 			nested_vmx_abort(vcpu,
+ 					 VMX_ABORT_SAVE_GUEST_MSR_FAIL);
+ 	}
+-
+-	/*
+-	 * Drop what we picked up for L2 via vmx_complete_interrupts. It is
+-	 * preserved above and would only end up incorrectly in L1.
+-	 */
+-	vcpu->arch.nmi_injected = false;
+-	kvm_clear_exception_queue(vcpu);
+-	kvm_clear_interrupt_queue(vcpu);
+ }
+ 
+ /*
+@@ -4602,6 +4608,17 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason,
+ 		WARN_ON_ONCE(nested_early_check);
+ 	}
+ 
++	/*
++	 * Drop events/exceptions that were queued for re-injection to L2
++	 * (picked up via vmx_complete_interrupts()), as well as exceptions
++	 * that were pending for L2.  Note, this must NOT be hoisted above
++	 * prepare_vmcs12(), events/exceptions queued for re-injection need to
++	 * be captured in vmcs12 (see vmcs12_save_pending_event()).
++	 */
++	vcpu->arch.nmi_injected = false;
++	kvm_clear_exception_queue(vcpu);
++	kvm_clear_interrupt_queue(vcpu);
++
+ 	vmx_switch_vmcs(vcpu, &vmx->vmcs01);
+ 
+ 	/* Update any VMCS fields that might have changed while L2 ran */
+diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
+index c9b49a09e6b53..7f3581960eb5d 100644
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -1695,7 +1695,17 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu)
+ 	kvm_deliver_exception_payload(vcpu);
+ 
+ 	if (has_error_code) {
+-		vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
++		/*
++		 * Despite the error code being architecturally defined as 32
++		 * bits, and the VMCS field being 32 bits, Intel CPUs and thus
++		 * VMX don't actually supporting setting bits 31:16.  Hardware
++		 * will (should) never provide a bogus error code, but AMD CPUs
++		 * do generate error codes with bits 31:16 set, and so KVM's
++		 * ABI lets userspace shove in arbitrary 32-bit values.  Drop
++		 * the upper bits to avoid VM-Fail, losing information that
++		 * does't really exist is preferable to killing the VM.
++		 */
++		vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, (u16)error_code);
+ 		intr_info |= INTR_INFO_DELIVER_CODE_MASK;
+ 	}
+ 
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index b0c47b41c2649..e2435090f2258 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -528,6 +528,7 @@ static int exception_class(int vector)
+ #define EXCPT_TRAP		1
+ #define EXCPT_ABORT		2
+ #define EXCPT_INTERRUPT		3
++#define EXCPT_DB		4
+ 
+ static int exception_type(int vector)
+ {
+@@ -538,8 +539,14 @@ static int exception_type(int vector)
+ 
+ 	mask = 1 << vector;
+ 
+-	/* #DB is trap, as instruction watchpoints are handled elsewhere */
+-	if (mask & ((1 << DB_VECTOR) | (1 << BP_VECTOR) | (1 << OF_VECTOR)))
++	/*
++	 * #DBs can be trap-like or fault-like, the caller must check other CPU
++	 * state, e.g. DR6, to determine whether a #DB is a trap or fault.
++	 */
++	if (mask & (1 << DB_VECTOR))
++		return EXCPT_DB;
++
++	if (mask & ((1 << BP_VECTOR) | (1 << OF_VECTOR)))
+ 		return EXCPT_TRAP;
+ 
+ 	if (mask & ((1 << DF_VECTOR) | (1 << MC_VECTOR)))
+@@ -8801,6 +8808,12 @@ writeback:
+ 		unsigned long rflags = static_call(kvm_x86_get_rflags)(vcpu);
+ 		toggle_interruptibility(vcpu, ctxt->interruptibility);
+ 		vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
++
++		/*
++		 * Note, EXCPT_DB is assumed to be fault-like as the emulator
++		 * only supports code breakpoints and general detect #DB, both
++		 * of which are fault-like.
++		 */
+ 		if (!ctxt->have_exception ||
+ 		    exception_type(ctxt->exception.vector) == EXCPT_TRAP) {
+ 			kvm_pmu_trigger_event(vcpu, PERF_COUNT_HW_INSTRUCTIONS);
+@@ -9724,6 +9737,16 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit)
+ 
+ 	/* try to inject new event if pending */
+ 	if (vcpu->arch.exception.pending) {
++		/*
++		 * Fault-class exceptions, except #DBs, set RF=1 in the RFLAGS
++		 * value pushed on the stack.  Trap-like exception and all #DBs
++		 * leave RF as-is (KVM follows Intel's behavior in this regard;
++		 * AMD states that code breakpoint #DBs excplitly clear RF=0).
++		 *
++		 * Note, most versions of Intel's SDM and AMD's APM incorrectly
++		 * describe the behavior of General Detect #DBs, which are
++		 * fault-like.  They do _not_ set RF, a la code breakpoints.
++		 */
+ 		if (exception_type(vcpu->arch.exception.nr) == EXCPT_FAULT)
+ 			__kvm_set_rflags(vcpu, kvm_get_rflags(vcpu) |
+ 					     X86_EFLAGS_RF);
+diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
+index c1f6c1c51d998..362562c832e65 100644
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -2209,7 +2209,7 @@ cleanup:
+ 	return ret;
+ }
+ 
+-static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
++static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs, u8 *image, u8 *buf)
+ {
+ 	u8 *jg_reloc, *prog = *pprog;
+ 	int pivot, err, jg_bytes = 1;
+@@ -2225,12 +2225,12 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
+ 		EMIT2_off32(0x81, add_1reg(0xF8, BPF_REG_3),
+ 			    progs[a]);
+ 		err = emit_cond_near_jump(&prog,	/* je func */
+-					  (void *)progs[a], prog,
++					  (void *)progs[a], image + (prog - buf),
+ 					  X86_JE);
+ 		if (err)
+ 			return err;
+ 
+-		emit_indirect_jump(&prog, 2 /* rdx */, prog);
++		emit_indirect_jump(&prog, 2 /* rdx */, image + (prog - buf));
+ 
+ 		*pprog = prog;
+ 		return 0;
+@@ -2255,7 +2255,7 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
+ 	jg_reloc = prog;
+ 
+ 	err = emit_bpf_dispatcher(&prog, a, a + pivot,	/* emit lower_part */
+-				  progs);
++				  progs, image, buf);
+ 	if (err)
+ 		return err;
+ 
+@@ -2269,7 +2269,7 @@ static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
+ 	emit_code(jg_reloc - jg_bytes, jg_offset, jg_bytes);
+ 
+ 	err = emit_bpf_dispatcher(&prog, a + pivot + 1,	/* emit upper_part */
+-				  b, progs);
++				  b, progs, image, buf);
+ 	if (err)
+ 		return err;
+ 
+@@ -2289,12 +2289,12 @@ static int cmp_ips(const void *a, const void *b)
+ 	return 0;
+ }
+ 
+-int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
++int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs)
+ {
+-	u8 *prog = image;
++	u8 *prog = buf;
+ 
+ 	sort(funcs, num_funcs, sizeof(funcs[0]), cmp_ips, NULL);
+-	return emit_bpf_dispatcher(&prog, 0, num_funcs - 1, funcs);
++	return emit_bpf_dispatcher(&prog, 0, num_funcs - 1, funcs, image, buf);
+ }
+ 
+ struct x64_jit_data {
+diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
+index 0ed2e487a693f..9b1a58dda935b 100644
+--- a/arch/x86/xen/enlighten_pv.c
++++ b/arch/x86/xen/enlighten_pv.c
+@@ -765,6 +765,7 @@ static void xen_load_idt(const struct desc_ptr *desc)
+ {
+ 	static DEFINE_SPINLOCK(lock);
+ 	static struct trap_info traps[257];
++	static const struct trap_info zero = { };
+ 	unsigned out;
+ 
+ 	trace_xen_cpu_load_idt(desc);
+@@ -774,7 +775,7 @@ static void xen_load_idt(const struct desc_ptr *desc)
+ 	memcpy(this_cpu_ptr(&idt_desc), desc, sizeof(idt_desc));
+ 
+ 	out = xen_convert_trap_info(desc, traps, false);
+-	memset(&traps[out], 0, sizeof(traps[0]));
++	traps[out] = zero;
+ 
+ 	xen_mc_flush();
+ 	if (HYPERVISOR_set_trap_table(traps))
+diff --git a/block/bio.c b/block/bio.c
+index 3d3a2678fea25..77e3b764a0784 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -760,8 +760,6 @@ EXPORT_SYMBOL(bio_put);
+ static int __bio_clone(struct bio *bio, struct bio *bio_src, gfp_t gfp)
+ {
+ 	bio_set_flag(bio, BIO_CLONED);
+-	if (bio_flagged(bio_src, BIO_THROTTLED))
+-		bio_set_flag(bio, BIO_THROTTLED);
+ 	bio->bi_ioprio = bio_src->bi_ioprio;
+ 	bio->bi_iter = bio_src->bi_iter;
+ 
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index c96c8c4f751b3..887b8682eb690 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -4473,14 +4473,14 @@ static bool blk_mq_elv_switch_none(struct list_head *head,
+ 	list_add(&qe->node, head);
+ 
+ 	/*
+-	 * After elevator_switch_mq, the previous elevator_queue will be
++	 * After elevator_switch, the previous elevator_queue will be
+ 	 * released by elevator_release. The reference of the io scheduler
+ 	 * module get by elevator_get will also be put. So we need to get
+ 	 * a reference of the io scheduler module here to prevent it to be
+ 	 * removed.
+ 	 */
+ 	__module_get(qe->type->elevator_owner);
+-	elevator_switch_mq(q, NULL);
++	elevator_switch(q, NULL);
+ 	mutex_unlock(&q->sysfs_lock);
+ 
+ 	return true;
+@@ -4512,7 +4512,7 @@ static void blk_mq_elv_switch_back(struct list_head *head,
+ 	kfree(qe);
+ 
+ 	mutex_lock(&q->sysfs_lock);
+-	elevator_switch_mq(q, t);
++	elevator_switch(q, t);
+ 	mutex_unlock(&q->sysfs_lock);
+ }
+ 
+diff --git a/block/blk-throttle.c b/block/blk-throttle.c
+index 9f5fe62afff92..35cf744ea9d11 100644
+--- a/block/blk-throttle.c
++++ b/block/blk-throttle.c
+@@ -806,12 +806,12 @@ static bool tg_with_in_bps_limit(struct throtl_grp *tg, struct bio *bio,
+ 				 u64 bps_limit, unsigned long *wait)
+ {
+ 	bool rw = bio_data_dir(bio);
+-	u64 bytes_allowed, extra_bytes, tmp;
++	u64 bytes_allowed, extra_bytes;
+ 	unsigned long jiffy_elapsed, jiffy_wait, jiffy_elapsed_rnd;
+ 	unsigned int bio_size = throtl_bio_data_size(bio);
+ 
+ 	/* no need to throttle if this bio's bytes have been accounted */
+-	if (bps_limit == U64_MAX || bio_flagged(bio, BIO_THROTTLED)) {
++	if (bps_limit == U64_MAX || bio_flagged(bio, BIO_BPS_THROTTLED)) {
+ 		if (wait)
+ 			*wait = 0;
+ 		return true;
+@@ -824,10 +824,8 @@ static bool tg_with_in_bps_limit(struct throtl_grp *tg, struct bio *bio,
+ 		jiffy_elapsed_rnd = tg->td->throtl_slice;
+ 
+ 	jiffy_elapsed_rnd = roundup(jiffy_elapsed_rnd, tg->td->throtl_slice);
+-
+-	tmp = bps_limit * jiffy_elapsed_rnd;
+-	do_div(tmp, HZ);
+-	bytes_allowed = tmp;
++	bytes_allowed = mul_u64_u64_div_u64(bps_limit, (u64)jiffy_elapsed_rnd,
++					    (u64)HZ);
+ 
+ 	if (tg->bytes_disp[rw] + bio_size <= bytes_allowed) {
+ 		if (wait)
+@@ -921,22 +919,13 @@ static void throtl_charge_bio(struct throtl_grp *tg, struct bio *bio)
+ 	unsigned int bio_size = throtl_bio_data_size(bio);
+ 
+ 	/* Charge the bio to the group */
+-	if (!bio_flagged(bio, BIO_THROTTLED)) {
++	if (!bio_flagged(bio, BIO_BPS_THROTTLED)) {
+ 		tg->bytes_disp[rw] += bio_size;
+ 		tg->last_bytes_disp[rw] += bio_size;
+ 	}
+ 
+ 	tg->io_disp[rw]++;
+ 	tg->last_io_disp[rw]++;
+-
+-	/*
+-	 * BIO_THROTTLED is used to prevent the same bio to be throttled
+-	 * more than once as a throttled bio will go through blk-throtl the
+-	 * second time when it eventually gets issued.  Set it when a bio
+-	 * is being charged to a tg.
+-	 */
+-	if (!bio_flagged(bio, BIO_THROTTLED))
+-		bio_set_flag(bio, BIO_THROTTLED);
+ }
+ 
+ /**
+@@ -1026,6 +1015,7 @@ static void tg_dispatch_one_bio(struct throtl_grp *tg, bool rw)
+ 	sq->nr_queued[rw]--;
+ 
+ 	throtl_charge_bio(tg, bio);
++	bio_set_flag(bio, BIO_BPS_THROTTLED);
+ 
+ 	/*
+ 	 * If our parent is another tg, we just need to transfer @bio to
+@@ -2159,8 +2149,10 @@ again:
+ 		qn = &tg->qnode_on_parent[rw];
+ 		sq = sq->parent_sq;
+ 		tg = sq_to_tg(sq);
+-		if (!tg)
++		if (!tg) {
++			bio_set_flag(bio, BIO_BPS_THROTTLED);
+ 			goto out_unlock;
++		}
+ 	}
+ 
+ 	/* out-of-limit, queue to @tg */
+@@ -2189,8 +2181,6 @@ again:
+ 	}
+ 
+ out_unlock:
+-	bio_set_flag(bio, BIO_THROTTLED);
+-
+ #ifdef CONFIG_BLK_DEV_THROTTLING_LOW
+ 	if (throttled || !td->track_bio_latency)
+ 		bio->bi_issue.value |= BIO_ISSUE_THROTL_SKIP_LATENCY;
+diff --git a/block/blk-throttle.h b/block/blk-throttle.h
+index c1b6029961272..ee7299e6dea91 100644
+--- a/block/blk-throttle.h
++++ b/block/blk-throttle.h
+@@ -175,7 +175,7 @@ static inline bool blk_throtl_bio(struct bio *bio)
+ 	struct throtl_grp *tg = blkg_to_tg(bio->bi_blkg);
+ 
+ 	/* no need to throttle bps any more if the bio has been throttled */
+-	if (bio_flagged(bio, BIO_THROTTLED) &&
++	if (bio_flagged(bio, BIO_BPS_THROTTLED) &&
+ 	    !(tg->flags & THROTL_TG_HAS_IOPS_LIMIT))
+ 		return false;
+ 
+diff --git a/block/blk-wbt.c b/block/blk-wbt.c
+index a9982000b667e..c293e08b301ff 100644
+--- a/block/blk-wbt.c
++++ b/block/blk-wbt.c
+@@ -841,8 +841,11 @@ int wbt_init(struct request_queue *q)
+ 	rwb->last_comp = rwb->last_issue = jiffies;
+ 	rwb->win_nsec = RWB_WINDOW_NSEC;
+ 	rwb->enable_state = WBT_STATE_ON_DEFAULT;
+-	rwb->wc = 1;
++	rwb->wc = test_bit(QUEUE_FLAG_WC, &q->queue_flags);
+ 	rwb->rq_depth.default_depth = RWB_DEF_DEPTH;
++	rwb->min_lat_nsec = wbt_default_latency_nsec(q);
++
++	wbt_queue_depth_changed(&rwb->rqos);
+ 
+ 	/*
+ 	 * Assign rwb and add the stats callback.
+@@ -853,11 +856,6 @@ int wbt_init(struct request_queue *q)
+ 
+ 	blk_stat_add_callback(q, rwb->cb);
+ 
+-	rwb->min_lat_nsec = wbt_default_latency_nsec(q);
+-
+-	wbt_queue_depth_changed(&rwb->rqos);
+-	wbt_set_write_cache(q, test_bit(QUEUE_FLAG_WC, &q->queue_flags));
+-
+ 	return 0;
+ 
+ err_free:
+diff --git a/block/blk.h b/block/blk.h
+index d7142c4d2fefb..52432eab621e5 100644
+--- a/block/blk.h
++++ b/block/blk.h
+@@ -270,8 +270,7 @@ bool blk_bio_list_merge(struct request_queue *q, struct list_head *list,
+ 
+ void blk_insert_flush(struct request *rq);
+ 
+-int elevator_switch_mq(struct request_queue *q,
+-			      struct elevator_type *new_e);
++int elevator_switch(struct request_queue *q, struct elevator_type *new_e);
+ void elevator_exit(struct request_queue *q);
+ int elv_register_queue(struct request_queue *q, bool uevent);
+ void elv_unregister_queue(struct request_queue *q);
+diff --git a/block/elevator.c b/block/elevator.c
+index c319765892bb9..bd71f0fc4e4b6 100644
+--- a/block/elevator.c
++++ b/block/elevator.c
+@@ -588,7 +588,7 @@ void elv_unregister(struct elevator_type *e)
+ }
+ EXPORT_SYMBOL_GPL(elv_unregister);
+ 
+-int elevator_switch_mq(struct request_queue *q,
++static int elevator_switch_mq(struct request_queue *q,
+ 			      struct elevator_type *new_e)
+ {
+ 	int ret;
+@@ -723,7 +723,7 @@ void elevator_init_mq(struct request_queue *q)
+  * need for the new one. this way we have a chance of going back to the old
+  * one, if the new one fails init for some reason.
+  */
+-static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
++int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
+ {
+ 	int err;
+ 
+diff --git a/crypto/akcipher.c b/crypto/akcipher.c
+index f866085c8a4a3..ab975a420e1e9 100644
+--- a/crypto/akcipher.c
++++ b/crypto/akcipher.c
+@@ -120,6 +120,12 @@ static int akcipher_default_op(struct akcipher_request *req)
+ 	return -ENOSYS;
+ }
+ 
++static int akcipher_default_set_key(struct crypto_akcipher *tfm,
++				     const void *key, unsigned int keylen)
++{
++	return -ENOSYS;
++}
++
+ int crypto_register_akcipher(struct akcipher_alg *alg)
+ {
+ 	struct crypto_alg *base = &alg->base;
+@@ -132,6 +138,8 @@ int crypto_register_akcipher(struct akcipher_alg *alg)
+ 		alg->encrypt = akcipher_default_op;
+ 	if (!alg->decrypt)
+ 		alg->decrypt = akcipher_default_op;
++	if (!alg->set_priv_key)
++		alg->set_priv_key = akcipher_default_set_key;
+ 
+ 	akcipher_prepare_alg(alg);
+ 	return crypto_register_alg(base);
+diff --git a/drivers/acpi/acpi_fpdt.c b/drivers/acpi/acpi_fpdt.c
+index 6922a44b3ce70..a2056c4c8cb70 100644
+--- a/drivers/acpi/acpi_fpdt.c
++++ b/drivers/acpi/acpi_fpdt.c
+@@ -143,6 +143,23 @@ static const struct attribute_group boot_attr_group = {
+ 
+ static struct kobject *fpdt_kobj;
+ 
++#if defined CONFIG_X86 && defined CONFIG_PHYS_ADDR_T_64BIT
++#include <linux/processor.h>
++static bool fpdt_address_valid(u64 address)
++{
++	/*
++	 * On some systems the table contains invalid addresses
++	 * with unsuppored high address bits set, check for this.
++	 */
++	return !(address >> boot_cpu_data.x86_phys_bits);
++}
++#else
++static bool fpdt_address_valid(u64 address)
++{
++	return true;
++}
++#endif
++
+ static int fpdt_process_subtable(u64 address, u32 subtable_type)
+ {
+ 	struct fpdt_subtable_header *subtable_header;
+@@ -151,6 +168,11 @@ static int fpdt_process_subtable(u64 address, u32 subtable_type)
+ 	u32 length, offset;
+ 	int result;
+ 
++	if (!fpdt_address_valid(address)) {
++		pr_info(FW_BUG "invalid physical address: 0x%llx!\n", address);
++		return -EINVAL;
++	}
++
+ 	subtable_header = acpi_os_map_memory(address, sizeof(*subtable_header));
+ 	if (!subtable_header)
+ 		return -ENOMEM;
+diff --git a/drivers/acpi/acpi_pcc.c b/drivers/acpi/acpi_pcc.c
+index a12b55d812096..ee4ce5ba1fb24 100644
+--- a/drivers/acpi/acpi_pcc.c
++++ b/drivers/acpi/acpi_pcc.c
+@@ -23,6 +23,12 @@
+ 
+ #include <acpi/pcc.h>
+ 
++/*
++ * Arbitrary retries in case the remote processor is slow to respond
++ * to PCC commands
++ */
++#define PCC_CMD_WAIT_RETRIES_NUM	500
++
+ struct pcc_data {
+ 	struct pcc_mbox_chan *pcc_chan;
+ 	void __iomem *pcc_comm_addr;
+@@ -63,6 +69,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
+ 	if (IS_ERR(data->pcc_chan)) {
+ 		pr_err("Failed to find PCC channel for subspace %d\n",
+ 		       ctx->subspace_id);
++		kfree(data);
+ 		return AE_NOT_FOUND;
+ 	}
+ 
+@@ -72,6 +79,8 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function,
+ 	if (!data->pcc_comm_addr) {
+ 		pr_err("Failed to ioremap PCC comm region mem for %d\n",
+ 		       ctx->subspace_id);
++		pcc_mbox_free_channel(data->pcc_chan);
++		kfree(data);
+ 		return AE_NO_MEMORY;
+ 	}
+ 
+@@ -86,6 +95,7 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
+ {
+ 	int ret;
+ 	struct pcc_data *data = region_context;
++	u64 usecs_lat;
+ 
+ 	reinit_completion(&data->done);
+ 
+@@ -96,10 +106,22 @@ acpi_pcc_address_space_handler(u32 function, acpi_physical_address addr,
+ 	if (ret < 0)
+ 		return AE_ERROR;
+ 
+-	if (data->pcc_chan->mchan->mbox->txdone_irq)
+-		wait_for_completion(&data->done);
++	if (data->pcc_chan->mchan->mbox->txdone_irq) {
++		/*
++		 * pcc_chan->latency is just a Nominal value. In reality the remote
++		 * processor could be much slower to reply. So add an arbitrary
++		 * amount of wait on top of Nominal.
++		 */
++		usecs_lat = PCC_CMD_WAIT_RETRIES_NUM * data->pcc_chan->latency;
++		ret = wait_for_completion_timeout(&data->done,
++						  usecs_to_jiffies(usecs_lat));
++		if (ret == 0) {
++			pr_err("PCC command executed timeout!\n");
++			return AE_TIME;
++		}
++	}
+ 
+-	mbox_client_txdone(data->pcc_chan->mchan, ret);
++	mbox_chan_txdone(data->pcc_chan->mchan, ret);
+ 
+ 	memcpy_fromio(value, data->pcc_comm_addr, data->ctx.length);
+ 
+diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
+index 5cbe2196176db..2a4990733cf02 100644
+--- a/drivers/acpi/acpi_video.c
++++ b/drivers/acpi/acpi_video.c
+@@ -496,6 +496,22 @@ static const struct dmi_system_id video_dmi_table[] = {
+ 		DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"),
+ 		},
+ 	},
++	{
++	 .callback = video_disable_backlight_sysfs_if,
++	 .ident = "Toshiba Satellite Z830",
++	 .matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
++		DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Z830"),
++		},
++	},
++	{
++	 .callback = video_disable_backlight_sysfs_if,
++	 .ident = "Toshiba Portege Z830",
++	 .matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
++		DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE Z830"),
++		},
++	},
+ 	/*
+ 	 * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set
+ 	 * but the IDs actually follow the Device ID Scheme.
+diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
+index d91ad378c00d6..80ad530583c9c 100644
+--- a/drivers/acpi/apei/ghes.c
++++ b/drivers/acpi/apei/ghes.c
+@@ -985,7 +985,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
+ 				ghes_estatus_cache_add(generic, estatus);
+ 		}
+ 
+-		if (task_work_pending && current->mm != &init_mm) {
++		if (task_work_pending && current->mm) {
+ 			estatus_node->task_work.func = ghes_kick_task_work;
+ 			estatus_node->task_work_cpu = smp_processor_id();
+ 			ret = task_work_add(current, &estatus_node->task_work,
+diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c
+index 664070fc83498..d7cdd8406c84f 100644
+--- a/drivers/acpi/x86/utils.c
++++ b/drivers/acpi/x86/utils.c
+@@ -207,9 +207,26 @@ static const struct x86_cpu_id storage_d3_cpu_ids[] = {
+ 	{}
+ };
+ 
++static const struct dmi_system_id force_storage_d3_dmi[] = {
++	{
++		/*
++		 * _ADR is ambiguous between GPP1.DEV0 and GPP1.NVME
++		 * but .NVME is needed to get StorageD3Enable node
++		 * https://bugzilla.kernel.org/show_bug.cgi?id=216440
++		 */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 14 7425 2-in-1"),
++		}
++	},
++	{}
++};
++
+ bool force_storage_d3(void)
+ {
+-	return x86_match_cpu(storage_d3_cpu_ids);
++	const struct dmi_system_id *dmi_id = dmi_first_match(force_storage_d3_dmi);
++
++	return dmi_id || x86_match_cpu(storage_d3_cpu_ids);
+ }
+ 
+ /*
+diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
+index 32495ae96567a..986f1923a76da 100644
+--- a/drivers/ata/libahci_platform.c
++++ b/drivers/ata/libahci_platform.c
+@@ -451,14 +451,24 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
+ 		}
+ 	}
+ 
+-	hpriv->nports = child_nodes = of_get_child_count(dev->of_node);
++	/*
++	 * Too many sub-nodes most likely means having something wrong with
++	 * the firmware.
++	 */
++	child_nodes = of_get_child_count(dev->of_node);
++	if (child_nodes > AHCI_MAX_PORTS) {
++		rc = -EINVAL;
++		goto err_out;
++	}
+ 
+ 	/*
+ 	 * If no sub-node was found, we still need to set nports to
+ 	 * one in order to be able to use the
+ 	 * ahci_platform_[en|dis]able_[phys|regulators] functions.
+ 	 */
+-	if (!child_nodes)
++	if (child_nodes)
++		hpriv->nports = child_nodes;
++	else
+ 		hpriv->nports = 1;
+ 
+ 	hpriv->phys = devm_kcalloc(dev, hpriv->nports, sizeof(*hpriv->phys), GFP_KERNEL);
+diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
+index 46cbe4471e785..d07a7cfa389a1 100644
+--- a/drivers/base/arch_topology.c
++++ b/drivers/base/arch_topology.c
+@@ -841,4 +841,23 @@ void __init init_cpu_topology(void)
+ 		return;
+ 	}
+ }
++
++void store_cpu_topology(unsigned int cpuid)
++{
++	struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
++
++	if (cpuid_topo->package_id != -1)
++		goto topology_populated;
++
++	cpuid_topo->thread_id = -1;
++	cpuid_topo->core_id = cpuid;
++	cpuid_topo->package_id = cpu_to_node(cpuid);
++
++	pr_debug("CPU%u: package %d core %d thread %d\n",
++		 cpuid, cpuid_topo->package_id, cpuid_topo->core_id,
++		 cpuid_topo->thread_id);
++
++topology_populated:
++	update_siblings_masks(cpuid);
++}
+ #endif
+diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
+index 2a709daefbc46..2a2a1d996a57a 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -1413,10 +1413,12 @@ static int nbd_start_device_ioctl(struct nbd_device *nbd)
+ 	mutex_unlock(&nbd->config_lock);
+ 	ret = wait_event_interruptible(config->recv_wq,
+ 					 atomic_read(&config->recv_threads) == 0);
+-	if (ret)
++	if (ret) {
+ 		sock_shutdown(nbd);
+-	flush_workqueue(nbd->recv_workq);
++		nbd_clear_que(nbd);
++	}
+ 
++	flush_workqueue(nbd->recv_workq);
+ 	mutex_lock(&nbd->config_lock);
+ 	nbd_bdev_reset(nbd);
+ 	/* user requested, ignore socket errors */
+diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
+index 818681c89db8b..d44a966675179 100644
+--- a/drivers/bluetooth/btintel.c
++++ b/drivers/bluetooth/btintel.c
+@@ -2439,15 +2439,20 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ 					       INTEL_ROM_LEGACY_NO_WBS_SUPPORT))
+ 				set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
+ 					&hdev->quirks);
++			if (ver.hw_variant == 0x08 && ver.fw_variant == 0x22)
++				set_bit(HCI_QUIRK_VALID_LE_STATES,
++					&hdev->quirks);
+ 
+ 			err = btintel_legacy_rom_setup(hdev, &ver);
+ 			break;
+ 		case 0x0b:      /* SfP */
+-		case 0x0c:      /* WsP */
+ 		case 0x11:      /* JfP */
+ 		case 0x12:      /* ThP */
+ 		case 0x13:      /* HrP */
+ 		case 0x14:      /* CcP */
++			set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
++			fallthrough;
++		case 0x0c:	/* WsP */
+ 			/* Apply the device specific HCI quirks
+ 			 *
+ 			 * All Legacy bootloader devices support WBS
+@@ -2455,11 +2460,6 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ 			set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
+ 				&hdev->quirks);
+ 
+-			/* Valid LE States quirk for JfP/ThP familiy */
+-			if (ver.hw_variant == 0x11 || ver.hw_variant == 0x12)
+-				set_bit(HCI_QUIRK_VALID_LE_STATES,
+-					&hdev->quirks);
+-
+ 			/* Setup MSFT Extension support */
+ 			btintel_set_msft_opcode(hdev, ver.hw_variant);
+ 
+@@ -2530,9 +2530,8 @@ static int btintel_setup_combined(struct hci_dev *hdev)
+ 		 */
+ 		set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
+ 
+-		/* Valid LE States quirk for JfP/ThP familiy */
+-		if (ver.hw_variant == 0x11 || ver.hw_variant == 0x12)
+-			set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
++		/* Set Valid LE States quirk */
++		set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
+ 
+ 		/* Setup MSFT Extension support */
+ 		btintel_set_msft_opcode(hdev, ver.hw_variant);
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 15caa64695389..1bb46cbff0fac 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -2477,15 +2477,29 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
+ 
+ 	set_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags);
+ 
++	/* WMT cmd/event doesn't follow up the generic HCI cmd/event handling,
++	 * it needs constantly polling control pipe until the host received the
++	 * WMT event, thus, we should require to specifically acquire PM counter
++	 * on the USB to prevent the interface from entering auto suspended
++	 * while WMT cmd/event in progress.
++	 */
++	err = usb_autopm_get_interface(data->intf);
++	if (err < 0)
++		goto err_free_wc;
++
+ 	err = __hci_cmd_send(hdev, 0xfc6f, hlen, wc);
+ 
+ 	if (err < 0) {
+ 		clear_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags);
++		usb_autopm_put_interface(data->intf);
+ 		goto err_free_wc;
+ 	}
+ 
+ 	/* Submit control IN URB on demand to process the WMT event */
+ 	err = btusb_mtk_submit_wmt_recv_urb(hdev);
++
++	usb_autopm_put_interface(data->intf);
++
+ 	if (err < 0)
+ 		goto err_free_wc;
+ 
+diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
+index f537673ede174..865112e96ff9f 100644
+--- a/drivers/bluetooth/hci_ldisc.c
++++ b/drivers/bluetooth/hci_ldisc.c
+@@ -493,6 +493,11 @@ static int hci_uart_tty_open(struct tty_struct *tty)
+ 		BT_ERR("Can't allocate control structure");
+ 		return -ENFILE;
+ 	}
++	if (percpu_init_rwsem(&hu->proto_lock)) {
++		BT_ERR("Can't allocate semaphore structure");
++		kfree(hu);
++		return -ENOMEM;
++	}
+ 
+ 	tty->disc_data = hu;
+ 	hu->tty = tty;
+@@ -505,8 +510,6 @@ static int hci_uart_tty_open(struct tty_struct *tty)
+ 	INIT_WORK(&hu->init_ready, hci_uart_init_work);
+ 	INIT_WORK(&hu->write_work, hci_uart_write_work);
+ 
+-	percpu_init_rwsem(&hu->proto_lock);
+-
+ 	/* Flush any pending characters in the driver */
+ 	tty_driver_flush_buffer(tty);
+ 
+diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c
+index c0e5f42ec6b7d..f16fd79bc02b8 100644
+--- a/drivers/bluetooth/hci_serdev.c
++++ b/drivers/bluetooth/hci_serdev.c
+@@ -310,11 +310,12 @@ int hci_uart_register_device(struct hci_uart *hu,
+ 
+ 	serdev_device_set_client_ops(hu->serdev, &hci_serdev_client_ops);
+ 
++	if (percpu_init_rwsem(&hu->proto_lock))
++		return -ENOMEM;
++
+ 	err = serdev_device_open(hu->serdev);
+ 	if (err)
+-		return err;
+-
+-	percpu_init_rwsem(&hu->proto_lock);
++		goto err_rwsem;
+ 
+ 	err = p->open(hu);
+ 	if (err)
+@@ -389,6 +390,8 @@ err_alloc:
+ 	p->close(hu);
+ err_open:
+ 	serdev_device_close(hu->serdev);
++err_rwsem:
++	percpu_free_rwsem(&hu->proto_lock);
+ 	return err;
+ }
+ EXPORT_SYMBOL_GPL(hci_uart_register_device);
+@@ -410,5 +413,6 @@ void hci_uart_unregister_device(struct hci_uart *hu)
+ 		clear_bit(HCI_UART_PROTO_READY, &hu->flags);
+ 		serdev_device_close(hu->serdev);
+ 	}
++	percpu_free_rwsem(&hu->proto_lock);
+ }
+ EXPORT_SYMBOL_GPL(hci_uart_unregister_device);
+diff --git a/drivers/char/hw_random/arm_smccc_trng.c b/drivers/char/hw_random/arm_smccc_trng.c
+index b24ac39a903b3..e34c3ea692b6c 100644
+--- a/drivers/char/hw_random/arm_smccc_trng.c
++++ b/drivers/char/hw_random/arm_smccc_trng.c
+@@ -71,8 +71,6 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+ 				  MAX_BITS_PER_CALL);
+ 
+ 		arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND, bits, &res);
+-		if ((int)res.a0 < 0)
+-			return (int)res.a0;
+ 
+ 		switch ((int)res.a0) {
+ 		case SMCCC_RET_SUCCESS:
+@@ -88,6 +86,8 @@ static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+ 				return copied;
+ 			cond_resched();
+ 			break;
++		default:
++			return -EIO;
+ 		}
+ 	}
+ 
+diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
+index 16f227b995e8a..d7045dfaf16cf 100644
+--- a/drivers/char/hw_random/core.c
++++ b/drivers/char/hw_random/core.c
+@@ -507,16 +507,17 @@ static int hwrng_fillfn(void *unused)
+ 			rng->quality = current_quality; /* obsolete */
+ 		quality = rng->quality;
+ 		mutex_unlock(&reading_mutex);
++
++		if (rc <= 0)
++			hwrng_msleep(rng, 10000);
++
+ 		put_rng(rng);
+ 
+ 		if (!quality)
+ 			break;
+ 
+-		if (rc <= 0) {
+-			pr_warn("hwrng: no data available\n");
+-			msleep_interruptible(10000);
++		if (rc <= 0)
+ 			continue;
+-		}
+ 
+ 		/* If we cannot credit at least one bit of entropy,
+ 		 * keep track of the remainder for the next iteration
+@@ -570,6 +571,7 @@ int hwrng_register(struct hwrng *rng)
+ 
+ 	init_completion(&rng->cleanup_done);
+ 	complete(&rng->cleanup_done);
++	init_completion(&rng->dying);
+ 
+ 	if (!current_rng ||
+ 	    (!cur_rng_set_by_user && rng->quality > current_rng->quality)) {
+@@ -617,6 +619,7 @@ void hwrng_unregister(struct hwrng *rng)
+ 
+ 	old_rng = current_rng;
+ 	list_del(&rng->list);
++	complete_all(&rng->dying);
+ 	if (current_rng == rng) {
+ 		err = enable_best_rng();
+ 		if (err) {
+@@ -685,6 +688,14 @@ void devm_hwrng_unregister(struct device *dev, struct hwrng *rng)
+ }
+ EXPORT_SYMBOL_GPL(devm_hwrng_unregister);
+ 
++long hwrng_msleep(struct hwrng *rng, unsigned int msecs)
++{
++	unsigned long timeout = msecs_to_jiffies(msecs) + 1;
++
++	return wait_for_completion_interruptible_timeout(&rng->dying, timeout);
++}
++EXPORT_SYMBOL_GPL(hwrng_msleep);
++
+ static int __init hwrng_modinit(void)
+ {
+ 	int ret;
+diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c
+index b05d676ca814c..1d7ce7443586e 100644
+--- a/drivers/char/hw_random/imx-rngc.c
++++ b/drivers/char/hw_random/imx-rngc.c
+@@ -245,7 +245,7 @@ static int imx_rngc_probe(struct platform_device *pdev)
+ 	if (IS_ERR(rngc->base))
+ 		return PTR_ERR(rngc->base);
+ 
+-	rngc->clk = devm_clk_get(&pdev->dev, NULL);
++	rngc->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ 	if (IS_ERR(rngc->clk)) {
+ 		dev_err(&pdev->dev, "Can not get rng_clk\n");
+ 		return PTR_ERR(rngc->clk);
+@@ -255,27 +255,14 @@ static int imx_rngc_probe(struct platform_device *pdev)
+ 	if (irq < 0)
+ 		return irq;
+ 
+-	ret = clk_prepare_enable(rngc->clk);
+-	if (ret)
+-		return ret;
+-
+ 	ver_id = readl(rngc->base + RNGC_VER_ID);
+ 	rng_type = ver_id >> RNGC_TYPE_SHIFT;
+ 	/*
+ 	 * This driver supports only RNGC and RNGB. (There's a different
+ 	 * driver for RNGA.)
+ 	 */
+-	if (rng_type != RNGC_TYPE_RNGC && rng_type != RNGC_TYPE_RNGB) {
+-		ret = -ENODEV;
+-		goto err;
+-	}
+-
+-	ret = devm_request_irq(&pdev->dev,
+-			irq, imx_rngc_irq, 0, pdev->name, (void *)rngc);
+-	if (ret) {
+-		dev_err(rngc->dev, "Can't get interrupt working.\n");
+-		goto err;
+-	}
++	if (rng_type != RNGC_TYPE_RNGC && rng_type != RNGC_TYPE_RNGB)
++		return -ENODEV;
+ 
+ 	init_completion(&rngc->rng_op_done);
+ 
+@@ -290,18 +277,25 @@ static int imx_rngc_probe(struct platform_device *pdev)
+ 
+ 	imx_rngc_irq_mask_clear(rngc);
+ 
++	ret = devm_request_irq(&pdev->dev,
++			irq, imx_rngc_irq, 0, pdev->name, (void *)rngc);
++	if (ret) {
++		dev_err(rngc->dev, "Can't get interrupt working.\n");
++		return ret;
++	}
++
+ 	if (self_test) {
+ 		ret = imx_rngc_self_test(rngc);
+ 		if (ret) {
+ 			dev_err(rngc->dev, "self test failed\n");
+-			goto err;
++			return ret;
+ 		}
+ 	}
+ 
+ 	ret = hwrng_register(&rngc->rng);
+ 	if (ret) {
+ 		dev_err(&pdev->dev, "hwrng registration failed\n");
+-		goto err;
++		return ret;
+ 	}
+ 
+ 	dev_info(&pdev->dev,
+@@ -309,11 +303,6 @@ static int imx_rngc_probe(struct platform_device *pdev)
+ 		rng_type == RNGC_TYPE_RNGB ? 'B' : 'C',
+ 		(ver_id >> RNGC_VER_MAJ_SHIFT) & 0xff, ver_id & 0xff);
+ 	return 0;
+-
+-err:
+-	clk_disable_unprepare(rngc->clk);
+-
+-	return ret;
+ }
+ 
+ static int __exit imx_rngc_remove(struct platform_device *pdev)
+@@ -322,8 +311,6 @@ static int __exit imx_rngc_remove(struct platform_device *pdev)
+ 
+ 	hwrng_unregister(&rngc->rng);
+ 
+-	clk_disable_unprepare(rngc->clk);
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index 060f999dcffb3..46d6100fa3a7f 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -1195,7 +1195,7 @@ static void __cold entropy_timer(struct timer_list *timer)
+  */
+ static void __cold try_to_generate_entropy(void)
+ {
+-	enum { NUM_TRIAL_SAMPLES = 8192, MAX_SAMPLES_PER_BIT = HZ / 30 };
++	enum { NUM_TRIAL_SAMPLES = 8192, MAX_SAMPLES_PER_BIT = HZ / 15 };
+ 	struct entropy_timer_state stack;
+ 	unsigned int i, num_different = 0;
+ 	unsigned long last = random_get_entropy();
+@@ -1214,7 +1214,7 @@ static void __cold try_to_generate_entropy(void)
+ 	timer_setup_on_stack(&stack.timer, entropy_timer, 0);
+ 	while (!crng_ready() && !signal_pending(current)) {
+ 		if (!timer_pending(&stack.timer))
+-			mod_timer(&stack.timer, jiffies + 1);
++			mod_timer(&stack.timer, jiffies);
+ 		mix_pool_bytes(&stack.entropy, sizeof(stack.entropy));
+ 		schedule();
+ 		stack.entropy = random_get_entropy();
+diff --git a/drivers/clk/baikal-t1/ccu-div.c b/drivers/clk/baikal-t1/ccu-div.c
+index 4062092d67f90..a6642f3d33d44 100644
+--- a/drivers/clk/baikal-t1/ccu-div.c
++++ b/drivers/clk/baikal-t1/ccu-div.c
+@@ -34,6 +34,7 @@
+ #define CCU_DIV_CTL_CLKDIV_MASK(_width) \
+ 	GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD)
+ #define CCU_DIV_CTL_LOCK_SHIFTED	BIT(27)
++#define CCU_DIV_CTL_GATE_REF_BUF	BIT(28)
+ #define CCU_DIV_CTL_LOCK_NORMAL		BIT(31)
+ 
+ #define CCU_DIV_RST_DELAY_US		1
+@@ -170,6 +171,40 @@ static int ccu_div_gate_is_enabled(struct clk_hw *hw)
+ 	return !!(val & CCU_DIV_CTL_EN);
+ }
+ 
++static int ccu_div_buf_enable(struct clk_hw *hw)
++{
++	struct ccu_div *div = to_ccu_div(hw);
++	unsigned long flags;
++
++	spin_lock_irqsave(&div->lock, flags);
++	regmap_update_bits(div->sys_regs, div->reg_ctl,
++			   CCU_DIV_CTL_GATE_REF_BUF, 0);
++	spin_unlock_irqrestore(&div->lock, flags);
++
++	return 0;
++}
++
++static void ccu_div_buf_disable(struct clk_hw *hw)
++{
++	struct ccu_div *div = to_ccu_div(hw);
++	unsigned long flags;
++
++	spin_lock_irqsave(&div->lock, flags);
++	regmap_update_bits(div->sys_regs, div->reg_ctl,
++			   CCU_DIV_CTL_GATE_REF_BUF, CCU_DIV_CTL_GATE_REF_BUF);
++	spin_unlock_irqrestore(&div->lock, flags);
++}
++
++static int ccu_div_buf_is_enabled(struct clk_hw *hw)
++{
++	struct ccu_div *div = to_ccu_div(hw);
++	u32 val = 0;
++
++	regmap_read(div->sys_regs, div->reg_ctl, &val);
++
++	return !(val & CCU_DIV_CTL_GATE_REF_BUF);
++}
++
+ static unsigned long ccu_div_var_recalc_rate(struct clk_hw *hw,
+ 					     unsigned long parent_rate)
+ {
+@@ -323,6 +358,7 @@ static const struct ccu_div_dbgfs_bit ccu_div_bits[] = {
+ 	CCU_DIV_DBGFS_BIT_ATTR("div_en", CCU_DIV_CTL_EN),
+ 	CCU_DIV_DBGFS_BIT_ATTR("div_rst", CCU_DIV_CTL_RST),
+ 	CCU_DIV_DBGFS_BIT_ATTR("div_bypass", CCU_DIV_CTL_SET_CLKDIV),
++	CCU_DIV_DBGFS_BIT_ATTR("div_buf", CCU_DIV_CTL_GATE_REF_BUF),
+ 	CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL)
+ };
+ 
+@@ -441,6 +477,9 @@ static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry)
+ 			continue;
+ 		}
+ 
++		if (!strcmp("div_buf", name))
++			continue;
++
+ 		bits[didx] = ccu_div_bits[bidx];
+ 		bits[didx].div = div;
+ 
+@@ -477,6 +516,21 @@ static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry)
+ 				   &ccu_div_dbgfs_fixed_clkdiv_fops);
+ }
+ 
++static void ccu_div_buf_debug_init(struct clk_hw *hw, struct dentry *dentry)
++{
++	struct ccu_div *div = to_ccu_div(hw);
++	struct ccu_div_dbgfs_bit *bit;
++
++	bit = kmalloc(sizeof(*bit), GFP_KERNEL);
++	if (!bit)
++		return;
++
++	*bit = ccu_div_bits[3];
++	bit->div = div;
++	debugfs_create_file_unsafe(bit->name, ccu_div_dbgfs_mode, dentry, bit,
++				   &ccu_div_dbgfs_bit_fops);
++}
++
+ static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)
+ {
+ 	struct ccu_div *div = to_ccu_div(hw);
+@@ -489,6 +543,7 @@ static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)
+ 
+ #define ccu_div_var_debug_init NULL
+ #define ccu_div_gate_debug_init NULL
++#define ccu_div_buf_debug_init NULL
+ #define ccu_div_fixed_debug_init NULL
+ 
+ #endif /* !CONFIG_DEBUG_FS */
+@@ -520,6 +575,13 @@ static const struct clk_ops ccu_div_gate_ops = {
+ 	.debug_init = ccu_div_gate_debug_init
+ };
+ 
++static const struct clk_ops ccu_div_buf_ops = {
++	.enable = ccu_div_buf_enable,
++	.disable = ccu_div_buf_disable,
++	.is_enabled = ccu_div_buf_is_enabled,
++	.debug_init = ccu_div_buf_debug_init
++};
++
+ static const struct clk_ops ccu_div_fixed_ops = {
+ 	.recalc_rate = ccu_div_fixed_recalc_rate,
+ 	.round_rate = ccu_div_fixed_round_rate,
+@@ -566,6 +628,8 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init)
+ 	} else if (div_init->type == CCU_DIV_GATE) {
+ 		hw_init.ops = &ccu_div_gate_ops;
+ 		div->divider = div_init->divider;
++	} else if (div_init->type == CCU_DIV_BUF) {
++		hw_init.ops = &ccu_div_buf_ops;
+ 	} else if (div_init->type == CCU_DIV_FIXED) {
+ 		hw_init.ops = &ccu_div_fixed_ops;
+ 		div->divider = div_init->divider;
+@@ -579,6 +643,7 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init)
+ 		goto err_free_div;
+ 	}
+ 	parent_data.fw_name = div_init->parent_name;
++	parent_data.name = div_init->parent_name;
+ 	hw_init.parent_data = &parent_data;
+ 	hw_init.num_parents = 1;
+ 
+diff --git a/drivers/clk/baikal-t1/ccu-div.h b/drivers/clk/baikal-t1/ccu-div.h
+index 795665caefbdc..4eb49ff4803c6 100644
+--- a/drivers/clk/baikal-t1/ccu-div.h
++++ b/drivers/clk/baikal-t1/ccu-div.h
+@@ -13,6 +13,14 @@
+ #include <linux/bits.h>
+ #include <linux/of.h>
+ 
++/*
++ * CCU Divider private clock IDs
++ * @CCU_SYS_SATA_CLK: CCU SATA internal clock
++ * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock
++ */
++#define CCU_SYS_SATA_CLK		-1
++#define CCU_SYS_XGMAC_CLK		-2
++
+ /*
+  * CCU Divider private flags
+  * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
+@@ -31,11 +39,13 @@
+  * enum ccu_div_type - CCU Divider types
+  * @CCU_DIV_VAR: Clocks gate with variable divider.
+  * @CCU_DIV_GATE: Clocks gate with fixed divider.
++ * @CCU_DIV_BUF: Clock gate with no divider.
+  * @CCU_DIV_FIXED: Ungateable clock with fixed divider.
+  */
+ enum ccu_div_type {
+ 	CCU_DIV_VAR,
+ 	CCU_DIV_GATE,
++	CCU_DIV_BUF,
+ 	CCU_DIV_FIXED
+ };
+ 
+diff --git a/drivers/clk/baikal-t1/clk-ccu-div.c b/drivers/clk/baikal-t1/clk-ccu-div.c
+index f141fda12b09a..90f4fda406ee6 100644
+--- a/drivers/clk/baikal-t1/clk-ccu-div.c
++++ b/drivers/clk/baikal-t1/clk-ccu-div.c
+@@ -76,6 +76,16 @@
+ 		.divider = _divider				\
+ 	}
+ 
++#define CCU_DIV_BUF_INFO(_id, _name, _pname, _base, _flags)	\
++	{							\
++		.id = _id,					\
++		.name = _name,					\
++		.parent_name = _pname,				\
++		.base = _base,					\
++		.type = CCU_DIV_BUF,				\
++		.flags = _flags					\
++	}
++
+ #define CCU_DIV_FIXED_INFO(_id, _name, _pname, _divider)	\
+ 	{							\
+ 		.id = _id,					\
+@@ -188,11 +198,14 @@ static const struct ccu_div_rst_map axi_rst_map[] = {
+  * for the SoC devices registers IO-operations.
+  */
+ static const struct ccu_div_info sys_info[] = {
+-	CCU_DIV_VAR_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk",
++	CCU_DIV_VAR_INFO(CCU_SYS_SATA_CLK, "sys_sata_clk",
+ 			 "sata_clk", CCU_SYS_SATA_REF_BASE, 4,
+ 			 CLK_SET_RATE_GATE,
+ 			 CCU_DIV_SKIP_ONE | CCU_DIV_LOCK_SHIFTED |
+ 			 CCU_DIV_RESET_DOMAIN),
++	CCU_DIV_BUF_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk",
++			 "sys_sata_clk", CCU_SYS_SATA_REF_BASE,
++			 CLK_SET_RATE_PARENT),
+ 	CCU_DIV_VAR_INFO(CCU_SYS_APB_CLK, "sys_apb_clk",
+ 			 "pcie_clk", CCU_SYS_APB_BASE, 5,
+ 			 CLK_IS_CRITICAL, CCU_DIV_RESET_DOMAIN),
+@@ -204,10 +217,12 @@ static const struct ccu_div_info sys_info[] = {
+ 			  "eth_clk", CCU_SYS_GMAC1_BASE, 5),
+ 	CCU_DIV_FIXED_INFO(CCU_SYS_GMAC1_PTP_CLK, "sys_gmac1_ptp_clk",
+ 			   "eth_clk", 10),
+-	CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk",
+-			  "eth_clk", CCU_SYS_XGMAC_BASE, 8),
++	CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_CLK, "sys_xgmac_clk",
++			  "eth_clk", CCU_SYS_XGMAC_BASE, 1),
++	CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk",
++			   "sys_xgmac_clk", 8),
+ 	CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_PTP_CLK, "sys_xgmac_ptp_clk",
+-			   "eth_clk", 10),
++			   "sys_xgmac_clk", 8),
+ 	CCU_DIV_GATE_INFO(CCU_SYS_USB_CLK, "sys_usb_clk",
+ 			  "eth_clk", CCU_SYS_USB_BASE, 10),
+ 	CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
+@@ -396,6 +411,9 @@ static int ccu_div_clk_register(struct ccu_div_data *data)
+ 			init.base = info->base;
+ 			init.sys_regs = data->sys_regs;
+ 			init.divider = info->divider;
++		} else if (init.type == CCU_DIV_BUF) {
++			init.base = info->base;
++			init.sys_regs = data->sys_regs;
+ 		} else {
+ 			init.divider = info->divider;
+ 		}
+diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
+index 48a1eb9f2d551..e74fe6219d14e 100644
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -30,6 +30,7 @@
+ #include <linux/debugfs.h>
+ #include <linux/delay.h>
+ #include <linux/io.h>
++#include <linux/math.h>
+ #include <linux/module.h>
+ #include <linux/of_device.h>
+ #include <linux/platform_device.h>
+@@ -502,6 +503,8 @@ struct bcm2835_clock_data {
+ 	bool low_jitter;
+ 
+ 	u32 tcnt_mux;
++
++	bool round_up;
+ };
+ 
+ struct bcm2835_gate_data {
+@@ -966,9 +969,9 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
+ 	return div;
+ }
+ 
+-static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock,
+-					    unsigned long parent_rate,
+-					    u32 div)
++static unsigned long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock,
++						     unsigned long parent_rate,
++						     u32 div)
+ {
+ 	const struct bcm2835_clock_data *data = clock->data;
+ 	u64 temp;
+@@ -993,12 +996,34 @@ static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock,
+ 	return temp;
+ }
+ 
++static unsigned long bcm2835_round_rate(unsigned long rate)
++{
++	unsigned long scaler;
++	unsigned long limit;
++
++	limit = rate / 100000;
++
++	scaler = 1;
++	while (scaler < limit)
++		scaler *= 10;
++
++	/*
++	 * If increasing a clock by less than 0.1% changes it
++	 * from ..999.. to ..000.., round up.
++	 */
++	if ((rate + scaler - 1) / scaler % 1000 == 0)
++		rate = roundup(rate, scaler);
++
++	return rate;
++}
++
+ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw,
+ 					    unsigned long parent_rate)
+ {
+ 	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+ 	struct bcm2835_cprman *cprman = clock->cprman;
+ 	const struct bcm2835_clock_data *data = clock->data;
++	unsigned long rate;
+ 	u32 div;
+ 
+ 	if (data->int_bits == 0 && data->frac_bits == 0)
+@@ -1006,7 +1031,12 @@ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw,
+ 
+ 	div = cprman_read(cprman, data->div_reg);
+ 
+-	return bcm2835_clock_rate_from_divisor(clock, parent_rate, div);
++	rate = bcm2835_clock_rate_from_divisor(clock, parent_rate, div);
++
++	if (data->round_up)
++		rate = bcm2835_round_rate(rate);
++
++	return rate;
+ }
+ 
+ static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock)
+@@ -1784,7 +1814,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
+ 		.load_mask = CM_PLLC_LOADPER,
+ 		.hold_mask = CM_PLLC_HOLDPER,
+ 		.fixed_divider = 1,
+-		.flags = CLK_SET_RATE_PARENT),
++		.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
+ 
+ 	/*
+ 	 * PLLD is the display PLL, used to drive DSI display panels.
+@@ -2143,7 +2173,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
+ 		.div_reg = CM_UARTDIV,
+ 		.int_bits = 10,
+ 		.frac_bits = 12,
+-		.tcnt_mux = 28),
++		.tcnt_mux = 28,
++		.round_up = true),
+ 
+ 	/* TV encoder clock.  Only operating frequency is 108Mhz.  */
+ 	[BCM2835_CLOCK_VEC]	= REGISTER_PER_CLK(
+diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c
+index bccdfa00fd373..67a9edbba29c4 100644
+--- a/drivers/clk/berlin/bg2.c
++++ b/drivers/clk/berlin/bg2.c
+@@ -500,12 +500,15 @@ static void __init berlin2_clock_setup(struct device_node *np)
+ 	int n, ret;
+ 
+ 	clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
+-	if (!clk_data)
++	if (!clk_data) {
++		of_node_put(parent_np);
+ 		return;
++	}
+ 	clk_data->num = MAX_CLKS;
+ 	hws = clk_data->hws;
+ 
+ 	gbase = of_iomap(parent_np, 0);
++	of_node_put(parent_np);
+ 	if (!gbase)
+ 		return;
+ 
+diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c
+index e9518d35f262e..dd2784bb75b64 100644
+--- a/drivers/clk/berlin/bg2q.c
++++ b/drivers/clk/berlin/bg2q.c
+@@ -286,19 +286,23 @@ static void __init berlin2q_clock_setup(struct device_node *np)
+ 	int n, ret;
+ 
+ 	clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
+-	if (!clk_data)
++	if (!clk_data) {
++		of_node_put(parent_np);
+ 		return;
++	}
+ 	clk_data->num = MAX_CLKS;
+ 	hws = clk_data->hws;
+ 
+ 	gbase = of_iomap(parent_np, 0);
+ 	if (!gbase) {
++		of_node_put(parent_np);
+ 		pr_err("%pOF: Unable to map global base\n", np);
+ 		return;
+ 	}
+ 
+ 	/* BG2Q CPU PLL is not part of global registers */
+ 	cpupll_base = of_iomap(parent_np, 1);
++	of_node_put(parent_np);
+ 	if (!cpupll_base) {
+ 		pr_err("%pOF: Unable to map cpupll base\n", np);
+ 		iounmap(gbase);
+diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c
+index 24dab2312bc6f..9c3305bcb27ae 100644
+--- a/drivers/clk/clk-ast2600.c
++++ b/drivers/clk/clk-ast2600.c
+@@ -622,7 +622,7 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev)
+ 	regmap_write(map, 0x308, 0x12000); /* 3x3 = 9 */
+ 
+ 	/* P-Bus (BCLK) clock divider */
+-	hw = clk_hw_register_divider_table(dev, "bclk", "hpll", 0,
++	hw = clk_hw_register_divider_table(dev, "bclk", "epll", 0,
+ 			scu_g6_base + ASPEED_G6_CLK_SELECTION1, 20, 3, 0,
+ 			ast2600_div_table,
+ 			&aspeed_g6_clk_lock);
+diff --git a/drivers/clk/clk-oxnas.c b/drivers/clk/clk-oxnas.c
+index cda5e258355bc..584e293156ad6 100644
+--- a/drivers/clk/clk-oxnas.c
++++ b/drivers/clk/clk-oxnas.c
+@@ -207,7 +207,7 @@ static const struct of_device_id oxnas_stdclk_dt_ids[] = {
+ 
+ static int oxnas_stdclk_probe(struct platform_device *pdev)
+ {
+-	struct device_node *np = pdev->dev.of_node;
++	struct device_node *np = pdev->dev.of_node, *parent_np;
+ 	const struct oxnas_stdclk_data *data;
+ 	struct regmap *regmap;
+ 	int ret;
+@@ -215,7 +215,9 @@ static int oxnas_stdclk_probe(struct platform_device *pdev)
+ 
+ 	data = of_device_get_match_data(&pdev->dev);
+ 
+-	regmap = syscon_node_to_regmap(of_get_parent(np));
++	parent_np = of_get_parent(np);
++	regmap = syscon_node_to_regmap(parent_np);
++	of_node_put(parent_np);
+ 	if (IS_ERR(regmap)) {
+ 		dev_err(&pdev->dev, "failed to have parent regmap\n");
+ 		return PTR_ERR(regmap);
+diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
+index 88898b97a4431..5eddb9f0d6bdb 100644
+--- a/drivers/clk/clk-qoriq.c
++++ b/drivers/clk/clk-qoriq.c
+@@ -1063,8 +1063,13 @@ static void __init _clockgen_init(struct device_node *np, bool legacy);
+  */
+ static void __init legacy_init_clockgen(struct device_node *np)
+ {
+-	if (!clockgen.node)
+-		_clockgen_init(of_get_parent(np), true);
++	if (!clockgen.node) {
++		struct device_node *parent_np;
++
++		parent_np = of_get_parent(np);
++		_clockgen_init(parent_np, true);
++		of_node_put(parent_np);
++	}
+ }
+ 
+ /* Legacy node */
+@@ -1159,6 +1164,7 @@ static struct clk * __init create_sysclk(const char *name)
+ 	sysclk = of_get_child_by_name(clockgen.node, "sysclk");
+ 	if (sysclk) {
+ 		clk = sysclk_from_fixed(sysclk, name);
++		of_node_put(sysclk);
+ 		if (!IS_ERR(clk))
+ 			return clk;
+ 	}
+diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c
+index e7be3e54b9be4..03cfef494b49b 100644
+--- a/drivers/clk/clk-versaclock5.c
++++ b/drivers/clk/clk-versaclock5.c
+@@ -1204,7 +1204,7 @@ static const struct vc5_chip_info idt_5p49v6901_info = {
+ 	.model = IDT_VC6_5P49V6901,
+ 	.clk_fod_cnt = 4,
+ 	.clk_out_cnt = 5,
+-	.flags = VC5_HAS_PFD_FREQ_DBL,
++	.flags = VC5_HAS_PFD_FREQ_DBL | VC5_HAS_BYPASS_SYNC_BIT,
+ };
+ 
+ static const struct vc5_chip_info idt_5p49v6965_info = {
+diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
+index e89db568f5a89..652ae58c2735f 100644
+--- a/drivers/clk/imx/clk-imx8mp.c
++++ b/drivers/clk/imx/clk-imx8mp.c
+@@ -665,8 +665,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
+ 	hws[IMX8MP_CLK_CAN1_ROOT] = imx_clk_hw_gate2("can1_root_clk", "can1", ccm_base + 0x4350, 0);
+ 	hws[IMX8MP_CLK_CAN2_ROOT] = imx_clk_hw_gate2("can2_root_clk", "can2", ccm_base + 0x4360, 0);
+ 	hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0);
+-	hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
+ 	hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
++	hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "sim_enet_root_clk", ccm_base + 0x43b0, 0);
+ 	hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0);
+ 	hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0);
+ 	hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);
+diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
+index c56e406138dbe..1e6870f3671f6 100644
+--- a/drivers/clk/imx/clk-scu.c
++++ b/drivers/clk/imx/clk-scu.c
+@@ -695,7 +695,11 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
+ 		pr_warn("%s: failed to attached the power domain %d\n",
+ 			name, ret);
+ 
+-	platform_device_add(pdev);
++	ret = platform_device_add(pdev);
++	if (ret) {
++		platform_device_put(pdev);
++		return ERR_PTR(ret);
++	}
+ 
+ 	/* For API backwards compatiblilty, simply return NULL for success */
+ 	return NULL;
+diff --git a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
+index d774edaf760be..230299728859c 100644
+--- a/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
++++ b/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
+@@ -18,9 +18,9 @@ static const struct mtk_gate_regs mfg_cg_regs = {
+ 	.sta_ofs = 0x0,
+ };
+ 
+-#define GATE_MFG(_id, _name, _parent, _shift)			\
+-	GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift,	\
+-		&mtk_clk_gate_ops_setclr)
++#define GATE_MFG(_id, _name, _parent, _shift)				\
++	GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, _shift,	\
++		       &mtk_clk_gate_ops_setclr, CLK_SET_RATE_PARENT)
+ 
+ static const struct mtk_gate mfg_clks[] = {
+ 	GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0)
+diff --git a/drivers/clk/mediatek/clk-mt8195-infra_ao.c b/drivers/clk/mediatek/clk-mt8195-infra_ao.c
+index 97657f255618c..832160c929961 100644
+--- a/drivers/clk/mediatek/clk-mt8195-infra_ao.c
++++ b/drivers/clk/mediatek/clk-mt8195-infra_ao.c
+@@ -55,8 +55,12 @@ static const struct mtk_gate_regs infra_ao4_cg_regs = {
+ #define GATE_INFRA_AO1(_id, _name, _parent, _shift)	\
+ 	GATE_INFRA_AO1_FLAGS(_id, _name, _parent, _shift, 0)
+ 
++#define GATE_INFRA_AO2_FLAGS(_id, _name, _parent, _shift, _flag)	\
++	GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao2_cg_regs, _shift,	\
++		       &mtk_clk_gate_ops_setclr, _flag)
++
+ #define GATE_INFRA_AO2(_id, _name, _parent, _shift)			\
+-	GATE_MTK(_id, _name, _parent, &infra_ao2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
++	GATE_INFRA_AO2_FLAGS(_id, _name, _parent, _shift, 0)
+ 
+ #define GATE_INFRA_AO3_FLAGS(_id, _name, _parent, _shift, _flag)		\
+ 	GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao3_cg_regs, _shift,	\
+@@ -136,8 +140,11 @@ static const struct mtk_gate infra_ao_clks[] = {
+ 	GATE_INFRA_AO2(CLK_INFRA_AO_UNIPRO_SYS, "infra_ao_unipro_sys", "top_ufs", 11),
+ 	GATE_INFRA_AO2(CLK_INFRA_AO_UNIPRO_TICK, "infra_ao_unipro_tick", "top_ufs_tick1us", 12),
+ 	GATE_INFRA_AO2(CLK_INFRA_AO_UFS_MP_SAP_B, "infra_ao_ufs_mp_sap_b", "top_ufs_mp_sap_cfg", 13),
+-	GATE_INFRA_AO2(CLK_INFRA_AO_PWRMCU, "infra_ao_pwrmcu", "top_pwrmcu", 15),
+-	GATE_INFRA_AO2(CLK_INFRA_AO_PWRMCU_BUS_H, "infra_ao_pwrmcu_bus_h", "top_axi", 17),
++	/* pwrmcu is used by ATF for platform PM: clocks must never be disabled by the kernel */
++	GATE_INFRA_AO2_FLAGS(CLK_INFRA_AO_PWRMCU, "infra_ao_pwrmcu", "top_pwrmcu", 15,
++			     CLK_IS_CRITICAL),
++	GATE_INFRA_AO2_FLAGS(CLK_INFRA_AO_PWRMCU_BUS_H, "infra_ao_pwrmcu_bus_h", "top_axi", 17,
++			     CLK_IS_CRITICAL),
+ 	GATE_INFRA_AO2(CLK_INFRA_AO_APDMA_B, "infra_ao_apdma_b", "top_axi", 18),
+ 	GATE_INFRA_AO2(CLK_INFRA_AO_SPI4, "infra_ao_spi4", "top_spi", 25),
+ 	GATE_INFRA_AO2(CLK_INFRA_AO_SPI5, "infra_ao_spi5", "top_spi", 26),
+diff --git a/drivers/clk/mediatek/clk-mt8195-mfg.c b/drivers/clk/mediatek/clk-mt8195-mfg.c
+index 9411c556a5a97..c94cb71bd9b94 100644
+--- a/drivers/clk/mediatek/clk-mt8195-mfg.c
++++ b/drivers/clk/mediatek/clk-mt8195-mfg.c
+@@ -17,10 +17,12 @@ static const struct mtk_gate_regs mfg_cg_regs = {
+ };
+ 
+ #define GATE_MFG(_id, _name, _parent, _shift)			\
+-	GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
++	GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs,	\
++		       _shift, &mtk_clk_gate_ops_setclr,	\
++		       CLK_SET_RATE_PARENT)
+ 
+ static const struct mtk_gate mfg_clks[] = {
+-	GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "top_mfg_core_tmp", 0),
++	GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_ck_fast_ref", 0),
+ };
+ 
+ static const struct mtk_clk_desc mfg_desc = {
+diff --git a/drivers/clk/mediatek/clk-mt8195-vdo0.c b/drivers/clk/mediatek/clk-mt8195-vdo0.c
+index 261a7f76dd3cc..07b46bfd50406 100644
+--- a/drivers/clk/mediatek/clk-mt8195-vdo0.c
++++ b/drivers/clk/mediatek/clk-mt8195-vdo0.c
+@@ -37,6 +37,10 @@ static const struct mtk_gate_regs vdo0_2_cg_regs = {
+ #define GATE_VDO0_2(_id, _name, _parent, _shift)			\
+ 	GATE_MTK(_id, _name, _parent, &vdo0_2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+ 
++#define GATE_VDO0_2_FLAGS(_id, _name, _parent, _shift, _flags)		\
++	GATE_MTK_FLAGS(_id, _name, _parent, &vdo0_2_cg_regs, _shift,	\
++		       &mtk_clk_gate_ops_setclr, _flags)
++
+ static const struct mtk_gate vdo0_clks[] = {
+ 	/* VDO0_0 */
+ 	GATE_VDO0_0(CLK_VDO0_DISP_OVL0, "vdo0_disp_ovl0", "top_vpp", 0),
+@@ -85,7 +89,8 @@ static const struct mtk_gate vdo0_clks[] = {
+ 	/* VDO0_2 */
+ 	GATE_VDO0_2(CLK_VDO0_DSI0_DSI, "vdo0_dsi0_dsi", "top_dsi_occ", 0),
+ 	GATE_VDO0_2(CLK_VDO0_DSI1_DSI, "vdo0_dsi1_dsi", "top_dsi_occ", 8),
+-	GATE_VDO0_2(CLK_VDO0_DP_INTF0_DP_INTF, "vdo0_dp_intf0_dp_intf", "top_edp", 16),
++	GATE_VDO0_2_FLAGS(CLK_VDO0_DP_INTF0_DP_INTF, "vdo0_dp_intf0_dp_intf",
++			  "top_edp", 16, CLK_SET_RATE_PARENT),
+ };
+ 
+ static int clk_mt8195_vdo0_probe(struct platform_device *pdev)
+diff --git a/drivers/clk/mediatek/clk-mt8195-vdo1.c b/drivers/clk/mediatek/clk-mt8195-vdo1.c
+index 3378487d2c904..d54d7726d1866 100644
+--- a/drivers/clk/mediatek/clk-mt8195-vdo1.c
++++ b/drivers/clk/mediatek/clk-mt8195-vdo1.c
+@@ -43,6 +43,10 @@ static const struct mtk_gate_regs vdo1_3_cg_regs = {
+ #define GATE_VDO1_2(_id, _name, _parent, _shift)			\
+ 	GATE_MTK(_id, _name, _parent, &vdo1_2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+ 
++#define GATE_VDO1_2_FLAGS(_id, _name, _parent, _shift, _flags)		\
++	GATE_MTK_FLAGS(_id, _name, _parent, &vdo1_2_cg_regs, _shift,	\
++		       &mtk_clk_gate_ops_setclr, _flags)
++
+ #define GATE_VDO1_3(_id, _name, _parent, _shift)			\
+ 	GATE_MTK(_id, _name, _parent, &vdo1_3_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+ 
+@@ -99,7 +103,7 @@ static const struct mtk_gate vdo1_clks[] = {
+ 	GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPI0, "vdo1_disp_monitor_dpi0", "top_vpp", 1),
+ 	GATE_VDO1_2(CLK_VDO1_DPI1, "vdo1_dpi1", "top_vpp", 8),
+ 	GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPI1, "vdo1_disp_monitor_dpi1", "top_vpp", 9),
+-	GATE_VDO1_2(CLK_VDO1_DPINTF, "vdo1_dpintf", "top_vpp", 16),
++	GATE_VDO1_2_FLAGS(CLK_VDO1_DPINTF, "vdo1_dpintf", "top_dp", 16, CLK_SET_RATE_PARENT),
+ 	GATE_VDO1_2(CLK_VDO1_DISP_MONITOR_DPINTF, "vdo1_disp_monitor_dpintf", "top_vpp", 17),
+ 	/* VDO1_3 */
+ 	GATE_VDO1_3(CLK_VDO1_26M_SLOW, "vdo1_26m_slow", "clk26m", 8),
+diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
+index 05a188c621191..e1b445f2c5c54 100644
+--- a/drivers/clk/mediatek/clk-mtk.c
++++ b/drivers/clk/mediatek/clk-mtk.c
+@@ -80,7 +80,7 @@ err:
+ 		if (IS_ERR_OR_NULL(clk_data->hws[rc->id]))
+ 			continue;
+ 
+-		clk_unregister_fixed_rate(clk_data->hws[rc->id]->clk);
++		clk_hw_unregister_fixed_rate(clk_data->hws[rc->id]);
+ 		clk_data->hws[rc->id] = ERR_PTR(-ENOENT);
+ 	}
+ 
+@@ -102,7 +102,7 @@ void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
+ 		if (IS_ERR_OR_NULL(clk_data->hws[rc->id]))
+ 			continue;
+ 
+-		clk_unregister_fixed_rate(clk_data->hws[rc->id]->clk);
++		clk_hw_unregister_fixed_rate(clk_data->hws[rc->id]);
+ 		clk_data->hws[rc->id] = ERR_PTR(-ENOENT);
+ 	}
+ }
+@@ -146,7 +146,7 @@ err:
+ 		if (IS_ERR_OR_NULL(clk_data->hws[ff->id]))
+ 			continue;
+ 
+-		clk_unregister_fixed_factor(clk_data->hws[ff->id]->clk);
++		clk_hw_unregister_fixed_factor(clk_data->hws[ff->id]);
+ 		clk_data->hws[ff->id] = ERR_PTR(-ENOENT);
+ 	}
+ 
+@@ -168,7 +168,7 @@ void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,
+ 		if (IS_ERR_OR_NULL(clk_data->hws[ff->id]))
+ 			continue;
+ 
+-		clk_unregister_fixed_factor(clk_data->hws[ff->id]->clk);
++		clk_hw_unregister_fixed_factor(clk_data->hws[ff->id]);
+ 		clk_data->hws[ff->id] = ERR_PTR(-ENOENT);
+ 	}
+ }
+@@ -393,7 +393,7 @@ err:
+ 		if (IS_ERR_OR_NULL(clk_data->hws[mcd->id]))
+ 			continue;
+ 
+-		mtk_clk_unregister_composite(clk_data->hws[mcd->id]);
++		clk_hw_unregister_divider(clk_data->hws[mcd->id]);
+ 		clk_data->hws[mcd->id] = ERR_PTR(-ENOENT);
+ 	}
+ 
+@@ -414,7 +414,7 @@ void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
+ 		if (IS_ERR_OR_NULL(clk_data->hws[mcd->id]))
+ 			continue;
+ 
+-		clk_unregister_divider(clk_data->hws[mcd->id]->clk);
++		clk_hw_unregister_divider(clk_data->hws[mcd->id]);
+ 		clk_data->hws[mcd->id] = ERR_PTR(-ENOENT);
+ 	}
+ }
+diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c
+index 27cd2c1f3f612..434cd8f9de826 100644
+--- a/drivers/clk/meson/meson-aoclk.c
++++ b/drivers/clk/meson/meson-aoclk.c
+@@ -38,6 +38,7 @@ int meson_aoclkc_probe(struct platform_device *pdev)
+ 	struct meson_aoclk_reset_controller *rstc;
+ 	struct meson_aoclk_data *data;
+ 	struct device *dev = &pdev->dev;
++	struct device_node *np;
+ 	struct regmap *regmap;
+ 	int ret, clkid;
+ 
+@@ -49,7 +50,9 @@ int meson_aoclkc_probe(struct platform_device *pdev)
+ 	if (!rstc)
+ 		return -ENOMEM;
+ 
+-	regmap = syscon_node_to_regmap(of_get_parent(dev->of_node));
++	np = of_get_parent(dev->of_node);
++	regmap = syscon_node_to_regmap(np);
++	of_node_put(np);
+ 	if (IS_ERR(regmap)) {
+ 		dev_err(dev, "failed to get regmap\n");
+ 		return PTR_ERR(regmap);
+diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c
+index 8d5a5dab955a8..0e5e6b57eb20e 100644
+--- a/drivers/clk/meson/meson-eeclk.c
++++ b/drivers/clk/meson/meson-eeclk.c
+@@ -18,6 +18,7 @@ int meson_eeclkc_probe(struct platform_device *pdev)
+ {
+ 	const struct meson_eeclkc_data *data;
+ 	struct device *dev = &pdev->dev;
++	struct device_node *np;
+ 	struct regmap *map;
+ 	int ret, i;
+ 
+@@ -26,7 +27,9 @@ int meson_eeclkc_probe(struct platform_device *pdev)
+ 		return -EINVAL;
+ 
+ 	/* Get the hhi system controller node */
+-	map = syscon_node_to_regmap(of_get_parent(dev->of_node));
++	np = of_get_parent(dev->of_node);
++	map = syscon_node_to_regmap(np);
++	of_node_put(np);
+ 	if (IS_ERR(map)) {
+ 		dev_err(dev,
+ 			"failed to get HHI regmap\n");
+diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
+index 8f3b7a94a6677..827e78fb16a84 100644
+--- a/drivers/clk/meson/meson8b.c
++++ b/drivers/clk/meson/meson8b.c
+@@ -3792,12 +3792,15 @@ static void __init meson8b_clkc_init_common(struct device_node *np,
+ 			struct clk_hw_onecell_data *clk_hw_onecell_data)
+ {
+ 	struct meson8b_clk_reset *rstc;
++	struct device_node *parent_np;
+ 	const char *notifier_clk_name;
+ 	struct clk *notifier_clk;
+ 	struct regmap *map;
+ 	int i, ret;
+ 
+-	map = syscon_node_to_regmap(of_get_parent(np));
++	parent_np = of_get_parent(np);
++	map = syscon_node_to_regmap(parent_np);
++	of_node_put(parent_np);
+ 	if (IS_ERR(map)) {
+ 		pr_err("failed to get HHI regmap - Trying obsolete regs\n");
+ 		return;
+diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
+index 1cf1ef70e3478..d566fbdebdf93 100644
+--- a/drivers/clk/qcom/Kconfig
++++ b/drivers/clk/qcom/Kconfig
+@@ -645,6 +645,7 @@ config SM_DISPCC_6350
+ 
+ config SM_GCC_6115
+ 	tristate "SM6115 and SM4250 Global Clock Controller"
++	select QCOM_GDSC
+ 	help
+ 	  Support for the global clock controller on SM6115 and SM4250 devices.
+ 	  Say Y if you want to use peripheral devices such as UART, SPI,
+diff --git a/drivers/clk/qcom/apss-ipq6018.c b/drivers/clk/qcom/apss-ipq6018.c
+index d78ff2f310bfa..b5d93657e1ee3 100644
+--- a/drivers/clk/qcom/apss-ipq6018.c
++++ b/drivers/clk/qcom/apss-ipq6018.c
+@@ -57,7 +57,7 @@ static struct clk_branch apcs_alias0_core_clk = {
+ 			.parent_hws = (const struct clk_hw *[]){
+ 				&apcs_alias0_clk_src.clkr.hw },
+ 			.num_parents = 1,
+-			.flags = CLK_SET_RATE_PARENT,
++			.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+ 			.ops = &clk_branch2_ops,
+ 		},
+ 	},
+diff --git a/drivers/clk/qcom/gcc-sdm660.c b/drivers/clk/qcom/gcc-sdm660.c
+index 9b97425008ce1..db918c92a522c 100644
+--- a/drivers/clk/qcom/gcc-sdm660.c
++++ b/drivers/clk/qcom/gcc-sdm660.c
+@@ -757,7 +757,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
+ 		.name = "sdcc1_apps_clk_src",
+ 		.parent_data = gcc_parent_data_xo_gpll0_gpll4_gpll0_early_div,
+ 		.num_parents = ARRAY_SIZE(gcc_parent_data_xo_gpll0_gpll4_gpll0_early_div),
+-		.ops = &clk_rcg2_ops,
++		.ops = &clk_rcg2_floor_ops,
+ 	},
+ };
+ 
+diff --git a/drivers/clk/qcom/gcc-sm6115.c b/drivers/clk/qcom/gcc-sm6115.c
+index 68fe9f6f0d2f3..e24a977c25806 100644
+--- a/drivers/clk/qcom/gcc-sm6115.c
++++ b/drivers/clk/qcom/gcc-sm6115.c
+@@ -53,11 +53,25 @@ static struct pll_vco gpll10_vco[] = {
+ 	{ 750000000, 1500000000, 1 },
+ };
+ 
++static const u8 clk_alpha_pll_regs_offset[][PLL_OFF_MAX_REGS] = {
++	[CLK_ALPHA_PLL_TYPE_DEFAULT] =  {
++		[PLL_OFF_L_VAL] = 0x04,
++		[PLL_OFF_ALPHA_VAL] = 0x08,
++		[PLL_OFF_ALPHA_VAL_U] = 0x0c,
++		[PLL_OFF_TEST_CTL] = 0x10,
++		[PLL_OFF_TEST_CTL_U] = 0x14,
++		[PLL_OFF_USER_CTL] = 0x18,
++		[PLL_OFF_USER_CTL_U] = 0x1c,
++		[PLL_OFF_CONFIG_CTL] = 0x20,
++		[PLL_OFF_STATUS] = 0x24,
++	},
++};
++
+ static struct clk_alpha_pll gpll0 = {
+ 	.offset = 0x0,
+ 	.vco_table = default_vco,
+ 	.num_vco = ARRAY_SIZE(default_vco),
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr = {
+ 		.enable_reg = 0x79000,
+ 		.enable_mask = BIT(0),
+@@ -83,7 +97,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_aux2 = {
+ 	.post_div_table = post_div_table_gpll0_out_aux2,
+ 	.num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_aux2),
+ 	.width = 4,
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr.hw.init = &(struct clk_init_data){
+ 		.name = "gpll0_out_aux2",
+ 		.parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
+@@ -115,7 +129,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_main = {
+ 	.post_div_table = post_div_table_gpll0_out_main,
+ 	.num_post_div = ARRAY_SIZE(post_div_table_gpll0_out_main),
+ 	.width = 4,
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr.hw.init = &(struct clk_init_data){
+ 		.name = "gpll0_out_main",
+ 		.parent_hws = (const struct clk_hw *[]){ &gpll0.clkr.hw },
+@@ -137,7 +151,7 @@ static struct clk_alpha_pll gpll10 = {
+ 	.offset = 0xa000,
+ 	.vco_table = gpll10_vco,
+ 	.num_vco = ARRAY_SIZE(gpll10_vco),
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr = {
+ 		.enable_reg = 0x79000,
+ 		.enable_mask = BIT(10),
+@@ -163,7 +177,7 @@ static struct clk_alpha_pll_postdiv gpll10_out_main = {
+ 	.post_div_table = post_div_table_gpll10_out_main,
+ 	.num_post_div = ARRAY_SIZE(post_div_table_gpll10_out_main),
+ 	.width = 4,
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr.hw.init = &(struct clk_init_data){
+ 		.name = "gpll10_out_main",
+ 		.parent_hws = (const struct clk_hw *[]){ &gpll10.clkr.hw },
+@@ -189,7 +203,7 @@ static struct clk_alpha_pll gpll11 = {
+ 	.vco_table = default_vco,
+ 	.num_vco = ARRAY_SIZE(default_vco),
+ 	.flags = SUPPORTS_DYNAMIC_UPDATE,
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr = {
+ 		.enable_reg = 0x79000,
+ 		.enable_mask = BIT(11),
+@@ -215,7 +229,7 @@ static struct clk_alpha_pll_postdiv gpll11_out_main = {
+ 	.post_div_table = post_div_table_gpll11_out_main,
+ 	.num_post_div = ARRAY_SIZE(post_div_table_gpll11_out_main),
+ 	.width = 4,
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr.hw.init = &(struct clk_init_data){
+ 		.name = "gpll11_out_main",
+ 		.parent_hws = (const struct clk_hw *[]){ &gpll11.clkr.hw },
+@@ -229,7 +243,7 @@ static struct clk_alpha_pll gpll3 = {
+ 	.offset = 0x3000,
+ 	.vco_table = default_vco,
+ 	.num_vco = ARRAY_SIZE(default_vco),
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr = {
+ 		.enable_reg = 0x79000,
+ 		.enable_mask = BIT(3),
+@@ -248,7 +262,7 @@ static struct clk_alpha_pll gpll4 = {
+ 	.offset = 0x4000,
+ 	.vco_table = default_vco,
+ 	.num_vco = ARRAY_SIZE(default_vco),
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr = {
+ 		.enable_reg = 0x79000,
+ 		.enable_mask = BIT(4),
+@@ -274,7 +288,7 @@ static struct clk_alpha_pll_postdiv gpll4_out_main = {
+ 	.post_div_table = post_div_table_gpll4_out_main,
+ 	.num_post_div = ARRAY_SIZE(post_div_table_gpll4_out_main),
+ 	.width = 4,
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr.hw.init = &(struct clk_init_data){
+ 		.name = "gpll4_out_main",
+ 		.parent_hws = (const struct clk_hw *[]){ &gpll4.clkr.hw },
+@@ -287,7 +301,7 @@ static struct clk_alpha_pll gpll6 = {
+ 	.offset = 0x6000,
+ 	.vco_table = default_vco,
+ 	.num_vco = ARRAY_SIZE(default_vco),
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr = {
+ 		.enable_reg = 0x79000,
+ 		.enable_mask = BIT(6),
+@@ -313,7 +327,7 @@ static struct clk_alpha_pll_postdiv gpll6_out_main = {
+ 	.post_div_table = post_div_table_gpll6_out_main,
+ 	.num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main),
+ 	.width = 4,
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr.hw.init = &(struct clk_init_data){
+ 		.name = "gpll6_out_main",
+ 		.parent_hws = (const struct clk_hw *[]){ &gpll6.clkr.hw },
+@@ -326,7 +340,7 @@ static struct clk_alpha_pll gpll7 = {
+ 	.offset = 0x7000,
+ 	.vco_table = default_vco,
+ 	.num_vco = ARRAY_SIZE(default_vco),
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr = {
+ 		.enable_reg = 0x79000,
+ 		.enable_mask = BIT(7),
+@@ -352,7 +366,7 @@ static struct clk_alpha_pll_postdiv gpll7_out_main = {
+ 	.post_div_table = post_div_table_gpll7_out_main,
+ 	.num_post_div = ARRAY_SIZE(post_div_table_gpll7_out_main),
+ 	.width = 4,
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr.hw.init = &(struct clk_init_data){
+ 		.name = "gpll7_out_main",
+ 		.parent_hws = (const struct clk_hw *[]){ &gpll7.clkr.hw },
+@@ -380,7 +394,7 @@ static struct clk_alpha_pll gpll8 = {
+ 	.offset = 0x8000,
+ 	.vco_table = default_vco,
+ 	.num_vco = ARRAY_SIZE(default_vco),
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.flags = SUPPORTS_DYNAMIC_UPDATE,
+ 	.clkr = {
+ 		.enable_reg = 0x79000,
+@@ -407,7 +421,7 @@ static struct clk_alpha_pll_postdiv gpll8_out_main = {
+ 	.post_div_table = post_div_table_gpll8_out_main,
+ 	.num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main),
+ 	.width = 4,
+-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
++	.regs = clk_alpha_pll_regs_offset[CLK_ALPHA_PLL_TYPE_DEFAULT],
+ 	.clkr.hw.init = &(struct clk_init_data){
+ 		.name = "gpll8_out_main",
+ 		.parent_hws = (const struct clk_hw *[]){ &gpll8.clkr.hw },
+diff --git a/drivers/clk/samsung/clk-exynosautov9.c b/drivers/clk/samsung/clk-exynosautov9.c
+index d9e1f8e4a7b45..487a71b32a009 100644
+--- a/drivers/clk/samsung/clk-exynosautov9.c
++++ b/drivers/clk/samsung/clk-exynosautov9.c
+@@ -1170,9 +1170,9 @@ static const struct samsung_cmu_info fsys2_cmu_info __initconst = {
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_2	0x2058
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_3	0x205c
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_4	0x2060
+-#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_7	0x206c
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_5	0x2064
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_6	0x2068
++#define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_7	0x206c
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_8	0x2070
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_9	0x2074
+ #define CLK_CON_GAT_GOUT_BLK_PERIC0_UID_PERIC0_TOP0_IPCLKPORT_PCLK_10	0x204c
+@@ -1418,14 +1418,14 @@ static const struct samsung_cmu_info peric0_cmu_info __initconst = {
+ #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_IPCLK_11	0x2020
+ #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_0	0x2044
+ #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_1	0x2048
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2	0x2058
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_3	0x205c
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4	0x2060
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_7	0x206c
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_5	0x2064
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_6	0x2068
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_8	0x2070
+-#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_9	0x2074
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2	0x2054
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_3	0x2058
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4	0x205c
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_5	0x2060
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_6	0x2064
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_7	0x2068
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_8	0x206c
++#define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_9	0x2070
+ #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_10	0x204c
+ #define CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_11	0x2050
+ 
+@@ -1463,9 +1463,9 @@ static const unsigned long peric1_clk_regs[] __initconst = {
+ 	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_2,
+ 	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_3,
+ 	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_4,
+-	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_7,
+ 	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_5,
+ 	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_6,
++	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_7,
+ 	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_8,
+ 	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_9,
+ 	CLK_CON_GAT_GOUT_BLK_PERIC1_UID_PERIC1_TOP0_IPCLKPORT_PCLK_10,
+diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c
+index d620bbbcdfc88..ce81e4087a8fc 100644
+--- a/drivers/clk/sprd/common.c
++++ b/drivers/clk/sprd/common.c
+@@ -41,7 +41,7 @@ int sprd_clk_regmap_init(struct platform_device *pdev,
+ {
+ 	void __iomem *base;
+ 	struct device *dev = &pdev->dev;
+-	struct device_node *node = dev->of_node;
++	struct device_node *node = dev->of_node, *np;
+ 	struct regmap *regmap;
+ 
+ 	if (of_find_property(node, "sprd,syscon", NULL)) {
+@@ -50,9 +50,10 @@ int sprd_clk_regmap_init(struct platform_device *pdev,
+ 			pr_err("%s: failed to get syscon regmap\n", __func__);
+ 			return PTR_ERR(regmap);
+ 		}
+-	} else if (of_device_is_compatible(of_get_parent(dev->of_node),
+-			   "syscon")) {
+-		regmap = device_node_to_regmap(of_get_parent(dev->of_node));
++	} else if (of_device_is_compatible(np =	of_get_parent(node), "syscon") ||
++		   (of_node_put(np), 0)) {
++		regmap = device_node_to_regmap(np);
++		of_node_put(np);
+ 		if (IS_ERR(regmap)) {
+ 			dev_err(dev, "failed to get regmap from its parent.\n");
+ 			return PTR_ERR(regmap);
+diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c
+index 582a22c049194..d820292a381d0 100644
+--- a/drivers/clk/st/clkgen-fsyn.c
++++ b/drivers/clk/st/clkgen-fsyn.c
+@@ -987,6 +987,7 @@ static void __init st_of_quadfs_setup(struct device_node *np,
+ 	const char *pll_name, *clk_parent_name;
+ 	void __iomem *reg;
+ 	spinlock_t *lock;
++	struct device_node *parent_np;
+ 
+ 	/*
+ 	 * First check for reg property within the node to keep backward
+@@ -994,7 +995,9 @@ static void __init st_of_quadfs_setup(struct device_node *np,
+ 	 */
+ 	reg = of_iomap(np, 0);
+ 	if (!reg) {
+-		reg = of_iomap(of_get_parent(np), 0);
++		parent_np = of_get_parent(np);
++		reg = of_iomap(parent_np, 0);
++		of_node_put(parent_np);
+ 		if (!reg) {
+ 			pr_err("%s: Failed to get base address\n", __func__);
+ 			return;
+diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c
+index ee39af7a0b721..596e939ad905e 100644
+--- a/drivers/clk/st/clkgen-mux.c
++++ b/drivers/clk/st/clkgen-mux.c
+@@ -56,6 +56,7 @@ static void __init st_of_clkgen_mux_setup(struct device_node *np,
+ 	void __iomem *reg;
+ 	const char **parents;
+ 	int num_parents = 0;
++	struct device_node *parent_np;
+ 
+ 	/*
+ 	 * First check for reg property within the node to keep backward
+@@ -63,7 +64,9 @@ static void __init st_of_clkgen_mux_setup(struct device_node *np,
+ 	 */
+ 	reg = of_iomap(np, 0);
+ 	if (!reg) {
+-		reg = of_iomap(of_get_parent(np), 0);
++		parent_np = of_get_parent(np);
++		reg = of_iomap(parent_np, 0);
++		of_node_put(parent_np);
+ 		if (!reg) {
+ 			pr_err("%s: Failed to get base address\n", __func__);
+ 			return;
+diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
+index ef718c4b38267..f7405a58877e2 100644
+--- a/drivers/clk/tegra/clk-tegra114.c
++++ b/drivers/clk/tegra/clk-tegra114.c
+@@ -1317,6 +1317,7 @@ static void __init tegra114_clock_init(struct device_node *np)
+ 	}
+ 
+ 	pmc_base = of_iomap(node, 0);
++	of_node_put(node);
+ 	if (!pmc_base) {
+ 		pr_err("Can't map pmc registers\n");
+ 		WARN_ON(1);
+diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
+index be3c33441cfc4..8a4514f6d5033 100644
+--- a/drivers/clk/tegra/clk-tegra20.c
++++ b/drivers/clk/tegra/clk-tegra20.c
+@@ -1131,6 +1131,7 @@ static void __init tegra20_clock_init(struct device_node *np)
+ 	}
+ 
+ 	pmc_base = of_iomap(node, 0);
++	of_node_put(node);
+ 	if (!pmc_base) {
+ 		pr_err("Can't map pmc registers\n");
+ 		BUG();
+diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
+index b9099012dc7b1..499f999e91e13 100644
+--- a/drivers/clk/tegra/clk-tegra210.c
++++ b/drivers/clk/tegra/clk-tegra210.c
+@@ -3748,6 +3748,7 @@ static void __init tegra210_clock_init(struct device_node *np)
+ 	}
+ 
+ 	pmc_base = of_iomap(node, 0);
++	of_node_put(node);
+ 	if (!pmc_base) {
+ 		pr_err("Can't map pmc registers\n");
+ 		WARN_ON(1);
+diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
+index f0f5bf68b6d23..ff4d6a9516813 100644
+--- a/drivers/clk/ti/clk-dra7-atl.c
++++ b/drivers/clk/ti/clk-dra7-atl.c
+@@ -245,14 +245,16 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
+ 		if (rc) {
+ 			pr_err("%s: failed to lookup atl clock %d\n", __func__,
+ 			       i);
+-			return -EINVAL;
++			ret = -EINVAL;
++			goto pm_put;
+ 		}
+ 
+ 		clk = of_clk_get_from_provider(&clkspec);
+ 		if (IS_ERR(clk)) {
+ 			pr_err("%s: failed to get atl clock %d from provider\n",
+ 			       __func__, i);
+-			return PTR_ERR(clk);
++			ret = PTR_ERR(clk);
++			goto pm_put;
+ 		}
+ 
+ 		cdesc = to_atl_desc(__clk_get_hw(clk));
+@@ -285,8 +287,9 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
+ 		if (cdesc->enabled)
+ 			atl_clk_enable(__clk_get_hw(clk));
+ 	}
+-	pm_runtime_put_sync(cinfo->dev);
+ 
++pm_put:
++	pm_runtime_put_sync(cinfo->dev);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c
+index 373e9438b57a3..1dc2f15fb75b2 100644
+--- a/drivers/clk/ti/clk.c
++++ b/drivers/clk/ti/clk.c
+@@ -140,11 +140,12 @@ static struct device_node *ti_find_clock_provider(struct device_node *from,
+ 			break;
+ 		}
+ 	}
+-	of_node_put(from);
+ 	kfree(tmp);
+ 
+-	if (found)
++	if (found) {
++		of_node_put(from);
+ 		return np;
++	}
+ 
+ 	/* Fall back to using old node name base provider name */
+ 	return of_find_node_by_name(from, name);
+diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c
+index eb25303eefed4..2c9da6623b84e 100644
+--- a/drivers/clk/zynqmp/clkc.c
++++ b/drivers/clk/zynqmp/clkc.c
+@@ -710,6 +710,13 @@ static void zynqmp_get_clock_info(void)
+ 				  FIELD_PREP(CLK_ATTR_NODE_INDEX, i);
+ 
+ 		zynqmp_pm_clock_get_name(clock[i].clk_id, &name);
++
++		/*
++		 * Terminate with NULL character in case name provided by firmware
++		 * is longer and truncated due to size limit.
++		 */
++		name.name[sizeof(name.name) - 1] = '\0';
++
+ 		if (!strcmp(name.name, RESERVED_CLK_NAME))
+ 			continue;
+ 		strncpy(clock[i].clk_name, name.name, MAX_NAME_LEN);
+diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c
+index 91a6b4cc910eb..0d3e1377b092c 100644
+--- a/drivers/clk/zynqmp/pll.c
++++ b/drivers/clk/zynqmp/pll.c
+@@ -102,26 +102,25 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+ 				  unsigned long *prate)
+ {
+ 	u32 fbdiv;
+-	long rate_div, f;
++	u32 mult, div;
+ 
+-	/* Enable the fractional mode if needed */
+-	rate_div = (rate * FRAC_DIV) / *prate;
+-	f = rate_div % FRAC_DIV;
+-	if (f) {
+-		if (rate > PS_PLL_VCO_MAX) {
+-			fbdiv = rate / PS_PLL_VCO_MAX;
+-			rate = rate / (fbdiv + 1);
+-		}
+-		if (rate < PS_PLL_VCO_MIN) {
+-			fbdiv = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate);
+-			rate = rate * fbdiv;
+-		}
+-		return rate;
++	/* Let rate fall inside the range PS_PLL_VCO_MIN ~ PS_PLL_VCO_MAX */
++	if (rate > PS_PLL_VCO_MAX) {
++		div = DIV_ROUND_UP(rate, PS_PLL_VCO_MAX);
++		rate = rate / div;
++	}
++	if (rate < PS_PLL_VCO_MIN) {
++		mult = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate);
++		rate = rate * mult;
+ 	}
+ 
+ 	fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
+-	fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
+-	return *prate * fbdiv;
++	if (fbdiv < PLL_FBDIV_MIN || fbdiv > PLL_FBDIV_MAX) {
++		fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
++		rate = *prate * fbdiv;
++	}
++
++	return rate;
+ }
+ 
+ /**
+diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
+index 9ab8221ee3c65..a7ff77550e173 100644
+--- a/drivers/clocksource/arm_arch_timer.c
++++ b/drivers/clocksource/arm_arch_timer.c
+@@ -44,8 +44,8 @@
+ #define CNTACR_RWVT	BIT(4)
+ #define CNTACR_RWPT	BIT(5)
+ 
+-#define CNTVCT_LO	0x00
+-#define CNTPCT_LO	0x08
++#define CNTPCT_LO	0x00
++#define CNTVCT_LO	0x08
+ #define CNTFRQ		0x10
+ #define CNTP_CVAL_LO	0x20
+ #define CNTP_CTL	0x2c
+@@ -473,6 +473,8 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
+ 		.desc = "ARM erratum 858921",
+ 		.read_cntpct_el0 = arm64_858921_read_cntpct_el0,
+ 		.read_cntvct_el0 = arm64_858921_read_cntvct_el0,
++		.set_next_event_phys = erratum_set_next_event_phys,
++		.set_next_event_virt = erratum_set_next_event_virt,
+ 	},
+ #endif
+ #ifdef CONFIG_SUN50I_ERRATUM_UNKNOWN1
+diff --git a/drivers/clocksource/timer-gxp.c b/drivers/clocksource/timer-gxp.c
+index 8b38b32123880..fe4fa8d7b3f13 100644
+--- a/drivers/clocksource/timer-gxp.c
++++ b/drivers/clocksource/timer-gxp.c
+@@ -171,6 +171,7 @@ static int gxp_timer_probe(struct platform_device *pdev)
+ {
+ 	struct platform_device *gxp_watchdog_device;
+ 	struct device *dev = &pdev->dev;
++	int ret;
+ 
+ 	if (!gxp_timer) {
+ 		pr_err("Gxp Timer not initialized, cannot create watchdog");
+@@ -187,7 +188,11 @@ static int gxp_timer_probe(struct platform_device *pdev)
+ 	gxp_watchdog_device->dev.platform_data = gxp_timer->counter;
+ 	gxp_watchdog_device->dev.parent = dev;
+ 
+-	return platform_device_add(gxp_watchdog_device);
++	ret = platform_device_add(gxp_watchdog_device);
++	if (ret)
++		platform_device_put(gxp_watchdog_device);
++
++	return ret;
+ }
+ 
+ static const struct of_device_id gxp_timer_of_match[] = {
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index 9ac75c1cde9c2..d63a28c5f95a9 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -152,6 +152,7 @@ static inline int amd_pstate_enable(bool enable)
+ static int pstate_init_perf(struct amd_cpudata *cpudata)
+ {
+ 	u64 cap1;
++	u32 highest_perf;
+ 
+ 	int ret = rdmsrl_safe_on_cpu(cpudata->cpu, MSR_AMD_CPPC_CAP1,
+ 				     &cap1);
+@@ -163,7 +164,11 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
+ 	 *
+ 	 * CPPC entry doesn't indicate the highest performance in some ASICs.
+ 	 */
+-	WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf());
++	highest_perf = amd_get_highest_perf();
++	if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1))
++		highest_perf = AMD_CPPC_HIGHEST_PERF(cap1);
++
++	WRITE_ONCE(cpudata->highest_perf, highest_perf);
+ 
+ 	WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1));
+ 	WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1));
+@@ -175,12 +180,17 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
+ static int cppc_init_perf(struct amd_cpudata *cpudata)
+ {
+ 	struct cppc_perf_caps cppc_perf;
++	u32 highest_perf;
+ 
+ 	int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
+ 	if (ret)
+ 		return ret;
+ 
+-	WRITE_ONCE(cpudata->highest_perf, amd_get_highest_perf());
++	highest_perf = amd_get_highest_perf();
++	if (highest_perf > cppc_perf.highest_perf)
++		highest_perf = cppc_perf.highest_perf;
++
++	WRITE_ONCE(cpudata->highest_perf, highest_perf);
+ 
+ 	WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf);
+ 	WRITE_ONCE(cpudata->lowest_nonlinear_perf,
+@@ -312,7 +322,7 @@ static int amd_pstate_target(struct cpufreq_policy *policy,
+ 		return -ENODEV;
+ 
+ 	cap_perf = READ_ONCE(cpudata->highest_perf);
+-	min_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
++	min_perf = READ_ONCE(cpudata->lowest_perf);
+ 	max_perf = cap_perf;
+ 
+ 	freqs.old = policy->cur;
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index 57cdb36798854..fc3ebeb0bbe59 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -2416,6 +2416,7 @@ static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
+ 	X86_MATCH(SKYLAKE_X,		core_funcs),
+ 	X86_MATCH(COMETLAKE,		core_funcs),
+ 	X86_MATCH(ICELAKE_X,		core_funcs),
++	X86_MATCH(TIGERLAKE,		core_funcs),
+ 	{}
+ };
+ MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
+diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
+index d5ef3c66c7625..bb32659820ceb 100644
+--- a/drivers/cpufreq/qcom-cpufreq-hw.c
++++ b/drivers/cpufreq/qcom-cpufreq-hw.c
+@@ -316,14 +316,14 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data)
+ 	if (IS_ERR(opp)) {
+ 		dev_warn(dev, "Can't find the OPP for throttling: %pe!\n", opp);
+ 	} else {
+-		throttled_freq = freq_hz / HZ_PER_KHZ;
+-
+-		/* Update thermal pressure (the boost frequencies are accepted) */
+-		arch_update_thermal_pressure(policy->related_cpus, throttled_freq);
+-
+ 		dev_pm_opp_put(opp);
+ 	}
+ 
++	throttled_freq = freq_hz / HZ_PER_KHZ;
++
++	/* Update thermal pressure (the boost frequencies are accepted) */
++	arch_update_thermal_pressure(policy->related_cpus, throttled_freq);
++
+ 	/*
+ 	 * In the unlikely case policy is unregistered do not enable
+ 	 * polling or h/w interrupt
+diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c
+index 862a2876f1c9d..05fe2902df9a7 100644
+--- a/drivers/cpuidle/cpuidle-riscv-sbi.c
++++ b/drivers/cpuidle/cpuidle-riscv-sbi.c
+@@ -97,8 +97,13 @@ static int sbi_cpuidle_enter_state(struct cpuidle_device *dev,
+ 				   struct cpuidle_driver *drv, int idx)
+ {
+ 	u32 *states = __this_cpu_read(sbi_cpuidle_data.states);
++	u32 state = states[idx];
+ 
+-	return CPU_PM_CPU_IDLE_ENTER_PARAM(sbi_suspend, idx, states[idx]);
++	if (state & SBI_HSM_SUSP_NON_RET_BIT)
++		return CPU_PM_CPU_IDLE_ENTER_PARAM(sbi_suspend, idx, state);
++	else
++		return CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(sbi_suspend,
++							     idx, state);
+ }
+ 
+ static int __sbi_enter_domain_idle_state(struct cpuidle_device *dev,
+diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c
+index 8c32d0eb8fcf2..6872ac3440010 100644
+--- a/drivers/crypto/cavium/cpt/cptpf_main.c
++++ b/drivers/crypto/cavium/cpt/cptpf_main.c
+@@ -253,6 +253,7 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae)
+ 	const struct firmware *fw_entry;
+ 	struct device *dev = &cpt->pdev->dev;
+ 	struct ucode_header *ucode;
++	unsigned int code_length;
+ 	struct microcode *mcode;
+ 	int j, ret = 0;
+ 
+@@ -263,11 +264,12 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae)
+ 	ucode = (struct ucode_header *)fw_entry->data;
+ 	mcode = &cpt->mcode[cpt->next_mc_idx];
+ 	memcpy(mcode->version, (u8 *)fw_entry->data, CPT_UCODE_VERSION_SZ);
+-	mcode->code_size = ntohl(ucode->code_length) * 2;
+-	if (!mcode->code_size) {
++	code_length = ntohl(ucode->code_length);
++	if (code_length == 0 || code_length >= INT_MAX / 2) {
+ 		ret = -EINVAL;
+ 		goto fw_release;
+ 	}
++	mcode->code_size = code_length * 2;
+ 
+ 	mcode->is_ae = is_ae;
+ 	mcode->core_mask = 0ULL;
+diff --git a/drivers/crypto/ccp/ccp-dmaengine.c b/drivers/crypto/ccp/ccp-dmaengine.c
+index 7d4b4ad1db1f3..9f753cb4f5f18 100644
+--- a/drivers/crypto/ccp/ccp-dmaengine.c
++++ b/drivers/crypto/ccp/ccp-dmaengine.c
+@@ -641,6 +641,10 @@ static void ccp_dma_release(struct ccp_device *ccp)
+ 	for (i = 0; i < ccp->cmd_q_count; i++) {
+ 		chan = ccp->ccp_dma_chan + i;
+ 		dma_chan = &chan->dma_chan;
++
++		if (dma_chan->client_count)
++			dma_release_channel(dma_chan);
++
+ 		tasklet_kill(&chan->cleanup_tasklet);
+ 		list_del_rcu(&dma_chan->device_node);
+ 	}
+@@ -766,8 +770,8 @@ void ccp_dmaengine_unregister(struct ccp_device *ccp)
+ 	if (!dmaengine)
+ 		return;
+ 
+-	dma_async_device_unregister(dma_dev);
+ 	ccp_dma_release(ccp);
++	dma_async_device_unregister(dma_dev);
+ 
+ 	kmem_cache_destroy(ccp->dma_desc_cache);
+ 	kmem_cache_destroy(ccp->dma_cmd_cache);
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
+index 9f588c9728f8b..6c49e6d06114f 100644
+--- a/drivers/crypto/ccp/sev-dev.c
++++ b/drivers/crypto/ccp/sev-dev.c
+@@ -231,7 +231,7 @@ static int sev_read_init_ex_file(void)
+ 	return 0;
+ }
+ 
+-static void sev_write_init_ex_file(void)
++static int sev_write_init_ex_file(void)
+ {
+ 	struct sev_device *sev = psp_master->sev_data;
+ 	struct file *fp;
+@@ -241,14 +241,16 @@ static void sev_write_init_ex_file(void)
+ 	lockdep_assert_held(&sev_cmd_mutex);
+ 
+ 	if (!sev_init_ex_buffer)
+-		return;
++		return 0;
+ 
+ 	fp = open_file_as_root(init_ex_path, O_CREAT | O_WRONLY, 0600);
+ 	if (IS_ERR(fp)) {
++		int ret = PTR_ERR(fp);
++
+ 		dev_err(sev->dev,
+-			"SEV: could not open file for write, error %ld\n",
+-			PTR_ERR(fp));
+-		return;
++			"SEV: could not open file for write, error %d\n",
++			ret);
++		return ret;
+ 	}
+ 
+ 	nwrite = kernel_write(fp, sev_init_ex_buffer, NV_LENGTH, &offset);
+@@ -259,18 +261,20 @@ static void sev_write_init_ex_file(void)
+ 		dev_err(sev->dev,
+ 			"SEV: failed to write %u bytes to non volatile memory area, ret %ld\n",
+ 			NV_LENGTH, nwrite);
+-		return;
++		return -EIO;
+ 	}
+ 
+ 	dev_dbg(sev->dev, "SEV: write successful to NV file\n");
++
++	return 0;
+ }
+ 
+-static void sev_write_init_ex_file_if_required(int cmd_id)
++static int sev_write_init_ex_file_if_required(int cmd_id)
+ {
+ 	lockdep_assert_held(&sev_cmd_mutex);
+ 
+ 	if (!sev_init_ex_buffer)
+-		return;
++		return 0;
+ 
+ 	/*
+ 	 * Only a few platform commands modify the SPI/NV area, but none of the
+@@ -285,10 +289,10 @@ static void sev_write_init_ex_file_if_required(int cmd_id)
+ 	case SEV_CMD_PEK_GEN:
+ 		break;
+ 	default:
+-		return;
++		return 0;
+ 	}
+ 
+-	sev_write_init_ex_file();
++	return sev_write_init_ex_file();
+ }
+ 
+ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
+@@ -361,7 +365,7 @@ static int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
+ 			cmd, reg & PSP_CMDRESP_ERR_MASK);
+ 		ret = -EIO;
+ 	} else {
+-		sev_write_init_ex_file_if_required(cmd);
++		ret = sev_write_init_ex_file_if_required(cmd);
+ 	}
+ 
+ 	print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data,
+diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
+index ad83c194d6648..9fa2efe601537 100644
+--- a/drivers/crypto/hisilicon/qm.c
++++ b/drivers/crypto/hisilicon/qm.c
+@@ -2245,8 +2245,10 @@ static ssize_t qm_cmd_write(struct file *filp, const char __user *buffer,
+ 		return ret;
+ 
+ 	/* Judge if the instance is being reset. */
+-	if (unlikely(atomic_read(&qm->status.flags) == QM_STOP))
+-		return 0;
++	if (unlikely(atomic_read(&qm->status.flags) == QM_STOP)) {
++		ret = 0;
++		goto put_dfx_access;
++	}
+ 
+ 	if (count > QM_DBG_WRITE_LEN) {
+ 		ret = -ENOSPC;
+diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c
+index ad35434a3fdb7..06a2d6e81ae93 100644
+--- a/drivers/crypto/hisilicon/zip/zip_crypto.c
++++ b/drivers/crypto/hisilicon/zip/zip_crypto.c
+@@ -123,12 +123,12 @@ static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp)
+ 	if (ret || n == 0 || n > HISI_ACC_SGL_SGE_NR_MAX)
+ 		return -EINVAL;
+ 
+-	return param_set_int(val, kp);
++	return param_set_ushort(val, kp);
+ }
+ 
+ static const struct kernel_param_ops sgl_sge_nr_ops = {
+ 	.set = sgl_sge_nr_set,
+-	.get = param_get_int,
++	.get = param_get_ushort,
+ };
+ 
+ static u16 sgl_sge_nr = HZIP_SGL_SGE_NR;
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index bc60b58022564..2124416742f84 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -383,7 +383,7 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+ 					u32 x;
+ 
+ 					x = ipad[i] ^ ipad[i + 4];
+-					cache[i] ^= swab(x);
++					cache[i] ^= swab32(x);
+ 				}
+ 			}
+ 			cache_len = AES_BLOCK_SIZE;
+@@ -821,7 +821,7 @@ static int safexcel_ahash_final(struct ahash_request *areq)
+ 			u32 *result = (void *)areq->result;
+ 
+ 			/* K3 */
+-			result[i] = swab(ctx->base.ipad.word[i + 4]);
++			result[i] = swab32(ctx->base.ipad.word[i + 4]);
+ 		}
+ 		areq->result[0] ^= 0x80;			// 10- padding
+ 		crypto_cipher_encrypt_one(ctx->kaes, areq->result, areq->result);
+@@ -2106,7 +2106,7 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key,
+ 	crypto_cipher_encrypt_one(ctx->kaes, (u8 *)key_tmp + AES_BLOCK_SIZE,
+ 		"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3");
+ 	for (i = 0; i < 3 * AES_BLOCK_SIZE / sizeof(u32); i++)
+-		ctx->base.ipad.word[i] = swab(key_tmp[i]);
++		ctx->base.ipad.word[i] = swab32(key_tmp[i]);
+ 
+ 	crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK);
+ 	crypto_cipher_set_flags(ctx->kaes, crypto_ahash_get_flags(tfm) &
+@@ -2189,7 +2189,7 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,
+ 		return ret;
+ 
+ 	for (i = 0; i < len / sizeof(u32); i++)
+-		ctx->base.ipad.word[i + 8] = swab(aes.key_enc[i]);
++		ctx->base.ipad.word[i + 8] = swab32(aes.key_enc[i]);
+ 
+ 	/* precompute the CMAC key material */
+ 	crypto_cipher_clear_flags(ctx->kaes, CRYPTO_TFM_REQ_MASK);
+diff --git a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
+index 40b482198ebc5..a765eefb18c2f 100644
+--- a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
++++ b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
+@@ -286,6 +286,7 @@ static int process_tar_file(struct device *dev,
+ 	struct tar_ucode_info_t *tar_info;
+ 	struct otx_cpt_ucode_hdr *ucode_hdr;
+ 	int ucode_type, ucode_size;
++	unsigned int code_length;
+ 
+ 	/*
+ 	 * If size is less than microcode header size then don't report
+@@ -303,7 +304,13 @@ static int process_tar_file(struct device *dev,
+ 	if (get_ucode_type(ucode_hdr, &ucode_type))
+ 		return 0;
+ 
+-	ucode_size = ntohl(ucode_hdr->code_length) * 2;
++	code_length = ntohl(ucode_hdr->code_length);
++	if (code_length >= INT_MAX / 2) {
++		dev_err(dev, "Invalid code_length %u\n", code_length);
++		return -EINVAL;
++	}
++
++	ucode_size = code_length * 2;
+ 	if (!ucode_size || (size < round_up(ucode_size, 16) +
+ 	    sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) {
+ 		dev_err(dev, "Ucode %s invalid size\n", filename);
+@@ -886,6 +893,7 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode,
+ {
+ 	struct otx_cpt_ucode_hdr *ucode_hdr;
+ 	const struct firmware *fw;
++	unsigned int code_length;
+ 	int ret;
+ 
+ 	set_ucode_filename(ucode, ucode_filename);
+@@ -896,7 +904,13 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode,
+ 	ucode_hdr = (struct otx_cpt_ucode_hdr *) fw->data;
+ 	memcpy(ucode->ver_str, ucode_hdr->ver_str, OTX_CPT_UCODE_VER_STR_SZ);
+ 	ucode->ver_num = ucode_hdr->ver_num;
+-	ucode->size = ntohl(ucode_hdr->code_length) * 2;
++	code_length = ntohl(ucode_hdr->code_length);
++	if (code_length >= INT_MAX / 2) {
++		dev_err(dev, "Ucode invalid code_length %u\n", code_length);
++		ret = -EINVAL;
++		goto release_fw;
++	}
++	ucode->size = code_length * 2;
+ 	if (!ucode->size || (fw->size < round_up(ucode->size, 16)
+ 	    + sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) {
+ 		dev_err(dev, "Ucode %s invalid size\n", ucode_filename);
+diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
+index 43b8f864806bd..4fb4b3df5a188 100644
+--- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
++++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
+@@ -107,7 +107,7 @@ do { \
+  * Timeout is in cycles. Clock speed may vary across products but this
+  * value should be a few milli-seconds.
+  */
+-#define ADF_SSM_WDT_DEFAULT_VALUE	0x200000
++#define ADF_SSM_WDT_DEFAULT_VALUE	0x7000000ULL
+ #define ADF_SSM_WDT_PKE_DEFAULT_VALUE	0x8000000
+ #define ADF_SSMWDTL_OFFSET		0x54
+ #define ADF_SSMWDTH_OFFSET		0x5C
+diff --git a/drivers/crypto/qat/qat_common/qat_algs.c b/drivers/crypto/qat/qat_common/qat_algs.c
+index fb45fa83841c5..cad9c58caab13 100644
+--- a/drivers/crypto/qat/qat_common/qat_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_algs.c
+@@ -673,11 +673,14 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,
+ 	dma_addr_t blpout = qat_req->buf.bloutp;
+ 	size_t sz = qat_req->buf.sz;
+ 	size_t sz_out = qat_req->buf.sz_out;
++	int bl_dma_dir;
+ 	int i;
+ 
++	bl_dma_dir = blp != blpout ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
++
+ 	for (i = 0; i < bl->num_bufs; i++)
+ 		dma_unmap_single(dev, bl->bufers[i].addr,
+-				 bl->bufers[i].len, DMA_BIDIRECTIONAL);
++				 bl->bufers[i].len, bl_dma_dir);
+ 
+ 	dma_unmap_single(dev, blp, sz, DMA_TO_DEVICE);
+ 
+@@ -691,7 +694,7 @@ static void qat_alg_free_bufl(struct qat_crypto_instance *inst,
+ 		for (i = bufless; i < blout->num_bufs; i++) {
+ 			dma_unmap_single(dev, blout->bufers[i].addr,
+ 					 blout->bufers[i].len,
+-					 DMA_BIDIRECTIONAL);
++					 DMA_FROM_DEVICE);
+ 		}
+ 		dma_unmap_single(dev, blpout, sz_out, DMA_TO_DEVICE);
+ 
+@@ -716,6 +719,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+ 	struct scatterlist *sg;
+ 	size_t sz_out, sz = struct_size(bufl, bufers, n);
+ 	int node = dev_to_node(&GET_DEV(inst->accel_dev));
++	int bufl_dma_dir;
+ 
+ 	if (unlikely(!n))
+ 		return -EINVAL;
+@@ -733,6 +737,8 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+ 		qat_req->buf.sgl_src_valid = true;
+ 	}
+ 
++	bufl_dma_dir = sgl != sglout ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
++
+ 	for_each_sg(sgl, sg, n, i)
+ 		bufl->bufers[i].addr = DMA_MAPPING_ERROR;
+ 
+@@ -744,7 +750,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+ 
+ 		bufl->bufers[y].addr = dma_map_single(dev, sg_virt(sg),
+ 						      sg->length,
+-						      DMA_BIDIRECTIONAL);
++						      bufl_dma_dir);
+ 		bufl->bufers[y].len = sg->length;
+ 		if (unlikely(dma_mapping_error(dev, bufl->bufers[y].addr)))
+ 			goto err_in;
+@@ -787,7 +793,7 @@ static int qat_alg_sgl_to_bufl(struct qat_crypto_instance *inst,
+ 
+ 			bufers[y].addr = dma_map_single(dev, sg_virt(sg),
+ 							sg->length,
+-							DMA_BIDIRECTIONAL);
++							DMA_FROM_DEVICE);
+ 			if (unlikely(dma_mapping_error(dev, bufers[y].addr)))
+ 				goto err_out;
+ 			bufers[y].len = sg->length;
+@@ -817,7 +823,7 @@ err_out:
+ 		if (!dma_mapping_error(dev, buflout->bufers[i].addr))
+ 			dma_unmap_single(dev, buflout->bufers[i].addr,
+ 					 buflout->bufers[i].len,
+-					 DMA_BIDIRECTIONAL);
++					 DMA_FROM_DEVICE);
+ 
+ 	if (!qat_req->buf.sgl_dst_valid)
+ 		kfree(buflout);
+@@ -831,7 +837,7 @@ err_in:
+ 		if (!dma_mapping_error(dev, bufl->bufers[i].addr))
+ 			dma_unmap_single(dev, bufl->bufers[i].addr,
+ 					 bufl->bufers[i].len,
+-					 DMA_BIDIRECTIONAL);
++					 bufl_dma_dir);
+ 
+ 	if (!qat_req->buf.sgl_src_valid)
+ 		kfree(bufl);
+diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c
+index 457084b344c17..b07ae4ba165e7 100644
+--- a/drivers/crypto/sahara.c
++++ b/drivers/crypto/sahara.c
+@@ -26,10 +26,10 @@
+ #include <linux/kernel.h>
+ #include <linux/kthread.h>
+ #include <linux/module.h>
+-#include <linux/mutex.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+ #include <linux/platform_device.h>
++#include <linux/spinlock.h>
+ 
+ #define SHA_BUFFER_LEN		PAGE_SIZE
+ #define SAHARA_MAX_SHA_BLOCK_SIZE	SHA256_BLOCK_SIZE
+@@ -196,7 +196,7 @@ struct sahara_dev {
+ 	void __iomem		*regs_base;
+ 	struct clk		*clk_ipg;
+ 	struct clk		*clk_ahb;
+-	struct mutex		queue_mutex;
++	spinlock_t		queue_spinlock;
+ 	struct task_struct	*kthread;
+ 	struct completion	dma_completion;
+ 
+@@ -642,9 +642,9 @@ static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode)
+ 
+ 	rctx->mode = mode;
+ 
+-	mutex_lock(&dev->queue_mutex);
++	spin_lock_bh(&dev->queue_spinlock);
+ 	err = crypto_enqueue_request(&dev->queue, &req->base);
+-	mutex_unlock(&dev->queue_mutex);
++	spin_unlock_bh(&dev->queue_spinlock);
+ 
+ 	wake_up_process(dev->kthread);
+ 
+@@ -1043,10 +1043,10 @@ static int sahara_queue_manage(void *data)
+ 	do {
+ 		__set_current_state(TASK_INTERRUPTIBLE);
+ 
+-		mutex_lock(&dev->queue_mutex);
++		spin_lock_bh(&dev->queue_spinlock);
+ 		backlog = crypto_get_backlog(&dev->queue);
+ 		async_req = crypto_dequeue_request(&dev->queue);
+-		mutex_unlock(&dev->queue_mutex);
++		spin_unlock_bh(&dev->queue_spinlock);
+ 
+ 		if (backlog)
+ 			backlog->complete(backlog, -EINPROGRESS);
+@@ -1092,9 +1092,9 @@ static int sahara_sha_enqueue(struct ahash_request *req, int last)
+ 		rctx->first = 1;
+ 	}
+ 
+-	mutex_lock(&dev->queue_mutex);
++	spin_lock_bh(&dev->queue_spinlock);
+ 	ret = crypto_enqueue_request(&dev->queue, &req->base);
+-	mutex_unlock(&dev->queue_mutex);
++	spin_unlock_bh(&dev->queue_spinlock);
+ 
+ 	wake_up_process(dev->kthread);
+ 
+@@ -1449,7 +1449,7 @@ static int sahara_probe(struct platform_device *pdev)
+ 
+ 	crypto_init_queue(&dev->queue, SAHARA_QUEUE_LENGTH);
+ 
+-	mutex_init(&dev->queue_mutex);
++	spin_lock_init(&dev->queue_spinlock);
+ 
+ 	dev_ptr = dev;
+ 
+diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
+index 38e8767ec3715..bf11d32205f38 100644
+--- a/drivers/dma-buf/udmabuf.c
++++ b/drivers/dma-buf/udmabuf.c
+@@ -124,17 +124,20 @@ static int begin_cpu_udmabuf(struct dma_buf *buf,
+ {
+ 	struct udmabuf *ubuf = buf->priv;
+ 	struct device *dev = ubuf->device->this_device;
++	int ret = 0;
+ 
+ 	if (!ubuf->sg) {
+ 		ubuf->sg = get_sg_table(dev, buf, direction);
+-		if (IS_ERR(ubuf->sg))
+-			return PTR_ERR(ubuf->sg);
++		if (IS_ERR(ubuf->sg)) {
++			ret = PTR_ERR(ubuf->sg);
++			ubuf->sg = NULL;
++		}
+ 	} else {
+ 		dma_sync_sg_for_cpu(dev, ubuf->sg->sgl, ubuf->sg->nents,
+ 				    direction);
+ 	}
+ 
+-	return 0;
++	return ret;
+ }
+ 
+ static int end_cpu_udmabuf(struct dma_buf *buf,
+diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
+index 07f7564796637..c54b24ff5206a 100644
+--- a/drivers/dma/dw-edma/dw-edma-core.c
++++ b/drivers/dma/dw-edma/dw-edma-core.c
+@@ -9,7 +9,6 @@
+ #include <linux/module.h>
+ #include <linux/device.h>
+ #include <linux/kernel.h>
+-#include <linux/pm_runtime.h>
+ #include <linux/dmaengine.h>
+ #include <linux/err.h>
+ #include <linux/interrupt.h>
+@@ -682,15 +681,12 @@ static int dw_edma_alloc_chan_resources(struct dma_chan *dchan)
+ 	if (chan->status != EDMA_ST_IDLE)
+ 		return -EBUSY;
+ 
+-	pm_runtime_get(chan->dw->chip->dev);
+-
+ 	return 0;
+ }
+ 
+ static void dw_edma_free_chan_resources(struct dma_chan *dchan)
+ {
+ 	unsigned long timeout = jiffies + msecs_to_jiffies(5000);
+-	struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan);
+ 	int ret;
+ 
+ 	while (time_before(jiffies, timeout)) {
+@@ -703,8 +699,6 @@ static void dw_edma_free_chan_resources(struct dma_chan *dchan)
+ 
+ 		cpu_relax();
+ 	}
+-
+-	pm_runtime_put(chan->dw->chip->dev);
+ }
+ 
+ static int dw_edma_channel_setup(struct dw_edma *dw, bool write,
+@@ -977,9 +971,6 @@ int dw_edma_probe(struct dw_edma_chip *chip)
+ 	if (err)
+ 		goto err_irq_free;
+ 
+-	/* Power management */
+-	pm_runtime_enable(dev);
+-
+ 	/* Turn debugfs on */
+ 	dw_edma_v0_core_debugfs_on(dw);
+ 
+@@ -1009,9 +1000,6 @@ int dw_edma_remove(struct dw_edma_chip *chip)
+ 	for (i = (dw->nr_irqs - 1); i >= 0; i--)
+ 		free_irq(chip->ops->irq_vector(dev, i), &dw->irq[i]);
+ 
+-	/* Power management */
+-	pm_runtime_disable(dev);
+-
+ 	/* Deregister eDMA device */
+ 	dma_async_device_unregister(&dw->wr_edma);
+ 	list_for_each_entry_safe(chan, _chan, &dw->wr_edma.channels,
+diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c
+index 43817ced3a3e1..0233b42143c77 100644
+--- a/drivers/dma/hisi_dma.c
++++ b/drivers/dma/hisi_dma.c
+@@ -180,7 +180,8 @@ static void hisi_dma_reset_qp_point(struct hisi_dma_dev *hdma_dev, u32 index)
+ 	hisi_dma_chan_write(hdma_dev->base, HISI_DMA_CQ_HEAD_PTR, index, 0);
+ }
+ 
+-static void hisi_dma_reset_hw_chan(struct hisi_dma_chan *chan)
++static void hisi_dma_reset_or_disable_hw_chan(struct hisi_dma_chan *chan,
++					      bool disable)
+ {
+ 	struct hisi_dma_dev *hdma_dev = chan->hdma_dev;
+ 	u32 index = chan->qp_num, tmp;
+@@ -201,8 +202,11 @@ static void hisi_dma_reset_hw_chan(struct hisi_dma_chan *chan)
+ 	hisi_dma_do_reset(hdma_dev, index);
+ 	hisi_dma_reset_qp_point(hdma_dev, index);
+ 	hisi_dma_pause_dma(hdma_dev, index, false);
+-	hisi_dma_enable_dma(hdma_dev, index, true);
+-	hisi_dma_unmask_irq(hdma_dev, index);
++
++	if (!disable) {
++		hisi_dma_enable_dma(hdma_dev, index, true);
++		hisi_dma_unmask_irq(hdma_dev, index);
++	}
+ 
+ 	ret = readl_relaxed_poll_timeout(hdma_dev->base +
+ 		HISI_DMA_Q_FSM_STS + index * HISI_DMA_OFFSET, tmp,
+@@ -218,7 +222,7 @@ static void hisi_dma_free_chan_resources(struct dma_chan *c)
+ 	struct hisi_dma_chan *chan = to_hisi_dma_chan(c);
+ 	struct hisi_dma_dev *hdma_dev = chan->hdma_dev;
+ 
+-	hisi_dma_reset_hw_chan(chan);
++	hisi_dma_reset_or_disable_hw_chan(chan, false);
+ 	vchan_free_chan_resources(&chan->vc);
+ 
+ 	memset(chan->sq, 0, sizeof(struct hisi_dma_sqe) * hdma_dev->chan_depth);
+@@ -267,7 +271,6 @@ static void hisi_dma_start_transfer(struct hisi_dma_chan *chan)
+ 
+ 	vd = vchan_next_desc(&chan->vc);
+ 	if (!vd) {
+-		dev_err(&hdma_dev->pdev->dev, "no issued task!\n");
+ 		chan->desc = NULL;
+ 		return;
+ 	}
+@@ -299,7 +302,7 @@ static void hisi_dma_issue_pending(struct dma_chan *c)
+ 
+ 	spin_lock_irqsave(&chan->vc.lock, flags);
+ 
+-	if (vchan_issue_pending(&chan->vc))
++	if (vchan_issue_pending(&chan->vc) && !chan->desc)
+ 		hisi_dma_start_transfer(chan);
+ 
+ 	spin_unlock_irqrestore(&chan->vc.lock, flags);
+@@ -394,7 +397,7 @@ static void hisi_dma_enable_qp(struct hisi_dma_dev *hdma_dev, u32 qp_index)
+ 
+ static void hisi_dma_disable_qp(struct hisi_dma_dev *hdma_dev, u32 qp_index)
+ {
+-	hisi_dma_reset_hw_chan(&hdma_dev->chan[qp_index]);
++	hisi_dma_reset_or_disable_hw_chan(&hdma_dev->chan[qp_index], true);
+ }
+ 
+ static void hisi_dma_enable_qps(struct hisi_dma_dev *hdma_dev)
+@@ -432,18 +435,15 @@ static irqreturn_t hisi_dma_irq(int irq, void *data)
+ 	desc = chan->desc;
+ 	cqe = chan->cq + chan->cq_head;
+ 	if (desc) {
++		chan->cq_head = (chan->cq_head + 1) % hdma_dev->chan_depth;
++		hisi_dma_chan_write(hdma_dev->base, HISI_DMA_CQ_HEAD_PTR,
++				    chan->qp_num, chan->cq_head);
+ 		if (FIELD_GET(STATUS_MASK, cqe->w0) == STATUS_SUCC) {
+-			chan->cq_head = (chan->cq_head + 1) %
+-					hdma_dev->chan_depth;
+-			hisi_dma_chan_write(hdma_dev->base,
+-					    HISI_DMA_CQ_HEAD_PTR, chan->qp_num,
+-					    chan->cq_head);
+ 			vchan_cookie_complete(&desc->vd);
++			hisi_dma_start_transfer(chan);
+ 		} else {
+ 			dev_err(&hdma_dev->pdev->dev, "task error!\n");
+ 		}
+-
+-		chan->desc = NULL;
+ 	}
+ 
+ 	spin_unlock(&chan->vc.lock);
+diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c
+index 743ead5ebc579..5b9921475be6c 100644
+--- a/drivers/dma/idxd/irq.c
++++ b/drivers/dma/idxd/irq.c
+@@ -324,13 +324,11 @@ halt:
+ 			idxd->state = IDXD_DEV_HALTED;
+ 			idxd_wqs_quiesce(idxd);
+ 			idxd_wqs_unmap_portal(idxd);
+-			spin_lock(&idxd->dev_lock);
+ 			idxd_device_clear_state(idxd);
+ 			dev_err(&idxd->pdev->dev,
+ 				"idxd halted, need %s.\n",
+ 				gensts.reset_type == IDXD_DEVICE_RESET_FLR ?
+ 				"FLR" : "system reset");
+-			spin_unlock(&idxd->dev_lock);
+ 			return -ENXIO;
+ 		}
+ 	}
+diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c
+index 37ff4ec7db76f..e2070df6cad28 100644
+--- a/drivers/dma/ioat/dma.c
++++ b/drivers/dma/ioat/dma.c
+@@ -656,7 +656,7 @@ static void __cleanup(struct ioatdma_chan *ioat_chan, dma_addr_t phys_complete)
+ 	if (active - i == 0) {
+ 		dev_dbg(to_dev(ioat_chan), "%s: cancel completion timeout\n",
+ 			__func__);
+-		mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
++		mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
+ 	}
+ 
+ 	/* microsecond delay by sysfs variable  per pending descriptor */
+@@ -682,7 +682,7 @@ static void ioat_cleanup(struct ioatdma_chan *ioat_chan)
+ 
+ 		if (chanerr &
+ 		    (IOAT_CHANERR_HANDLE_MASK | IOAT_CHANERR_RECOVER_MASK)) {
+-			mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
++			mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
+ 			ioat_eh(ioat_chan);
+ 		}
+ 	}
+@@ -879,7 +879,7 @@ static void check_active(struct ioatdma_chan *ioat_chan)
+ 	}
+ 
+ 	if (test_and_clear_bit(IOAT_CHAN_ACTIVE, &ioat_chan->state))
+-		mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
++		mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT);
+ }
+ 
+ static void ioat_reboot_chan(struct ioatdma_chan *ioat_chan)
+diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
+index 994fc4d2aca42..dc147cc2436e9 100644
+--- a/drivers/dma/mxs-dma.c
++++ b/drivers/dma/mxs-dma.c
+@@ -670,7 +670,7 @@ static enum dma_status mxs_dma_tx_status(struct dma_chan *chan,
+ 	return mxs_chan->status;
+ }
+ 
+-static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma)
++static int mxs_dma_init(struct mxs_dma_engine *mxs_dma)
+ {
+ 	int ret;
+ 
+@@ -741,7 +741,7 @@ static struct dma_chan *mxs_dma_xlate(struct of_phandle_args *dma_spec,
+ 				     ofdma->of_node);
+ }
+ 
+-static int __init mxs_dma_probe(struct platform_device *pdev)
++static int mxs_dma_probe(struct platform_device *pdev)
+ {
+ 	struct device_node *np = pdev->dev.of_node;
+ 	const struct mxs_dma_type *dma_type;
+@@ -839,10 +839,7 @@ static struct platform_driver mxs_dma_driver = {
+ 		.name	= "mxs-dma",
+ 		.of_match_table = mxs_dma_dt_ids,
+ 	},
++	.probe = mxs_dma_probe,
+ };
+ 
+-static int __init mxs_dma_module_init(void)
+-{
+-	return platform_driver_probe(&mxs_dma_driver, mxs_dma_probe);
+-}
+-subsys_initcall(mxs_dma_module_init);
++builtin_platform_driver(mxs_dma_driver);
+diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c
+index facdacf8aede6..d56caf1681ffb 100644
+--- a/drivers/dma/qcom/qcom_adm.c
++++ b/drivers/dma/qcom/qcom_adm.c
+@@ -379,13 +379,13 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
+ 		if (blk_size < 0) {
+ 			dev_err(adev->dev, "invalid burst value: %d\n",
+ 				burst);
+-			return ERR_PTR(-EINVAL);
++			return NULL;
+ 		}
+ 
+ 		crci = achan->crci & 0xf;
+ 		if (!crci || achan->crci > 0x1f) {
+ 			dev_err(adev->dev, "invalid crci value\n");
+-			return ERR_PTR(-EINVAL);
++			return NULL;
+ 		}
+ 	}
+ 
+@@ -403,8 +403,10 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
+ 	}
+ 
+ 	async_desc = kzalloc(sizeof(*async_desc), GFP_NOWAIT);
+-	if (!async_desc)
+-		return ERR_PTR(-ENOMEM);
++	if (!async_desc) {
++		dev_err(adev->dev, "not enough memory for async_desc struct\n");
++		return NULL;
++	}
+ 
+ 	async_desc->mux = achan->mux ? ADM_CRCI_CTL_MUX_SEL : 0;
+ 	async_desc->crci = crci;
+@@ -414,8 +416,10 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
+ 				sizeof(*cple) + 2 * ADM_DESC_ALIGN;
+ 
+ 	async_desc->cpl = kzalloc(async_desc->dma_len, GFP_NOWAIT);
+-	if (!async_desc->cpl)
++	if (!async_desc->cpl) {
++		dev_err(adev->dev, "not enough memory for cpl struct\n");
+ 		goto free;
++	}
+ 
+ 	async_desc->adev = adev;
+ 
+@@ -437,8 +441,10 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
+ 	async_desc->dma_addr = dma_map_single(adev->dev, async_desc->cpl,
+ 					      async_desc->dma_len,
+ 					      DMA_TO_DEVICE);
+-	if (dma_mapping_error(adev->dev, async_desc->dma_addr))
++	if (dma_mapping_error(adev->dev, async_desc->dma_addr)) {
++		dev_err(adev->dev, "dma mapping error for cpl\n");
+ 		goto free;
++	}
+ 
+ 	cple_addr = async_desc->dma_addr + ((void *)cple - async_desc->cpl);
+ 
+@@ -454,7 +460,7 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,
+ 
+ free:
+ 	kfree(async_desc);
+-	return ERR_PTR(-ENOMEM);
++	return NULL;
+ }
+ 
+ /**
+@@ -494,7 +500,7 @@ static int adm_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg)
+ 
+ 	spin_lock_irqsave(&achan->vc.lock, flag);
+ 	memcpy(&achan->slave, cfg, sizeof(struct dma_slave_config));
+-	if (cfg->peripheral_size == sizeof(config))
++	if (cfg->peripheral_size == sizeof(*config))
+ 		achan->crci = config->crci;
+ 	spin_unlock_irqrestore(&achan->vc.lock, flag);
+ 
+diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c
+index 2f0d2c68c93c6..fcfcde947b307 100644
+--- a/drivers/dma/ti/k3-udma.c
++++ b/drivers/dma/ti/k3-udma.c
+@@ -300,8 +300,6 @@ struct udma_chan {
+ 
+ 	struct udma_tx_drain tx_drain;
+ 
+-	u32 bcnt; /* number of bytes completed since the start of the channel */
+-
+ 	/* Channel configuration parameters */
+ 	struct udma_chan_config config;
+ 
+@@ -757,6 +755,20 @@ static void udma_reset_rings(struct udma_chan *uc)
+ 	}
+ }
+ 
++static void udma_decrement_byte_counters(struct udma_chan *uc, u32 val)
++{
++	if (uc->desc->dir == DMA_DEV_TO_MEM) {
++		udma_rchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val);
++		udma_rchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val);
++		udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val);
++	} else {
++		udma_tchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val);
++		udma_tchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val);
++		if (!uc->bchan)
++			udma_tchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val);
++	}
++}
++
+ static void udma_reset_counters(struct udma_chan *uc)
+ {
+ 	u32 val;
+@@ -790,8 +802,6 @@ static void udma_reset_counters(struct udma_chan *uc)
+ 		val = udma_rchanrt_read(uc, UDMA_CHAN_RT_PEER_BCNT_REG);
+ 		udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val);
+ 	}
+-
+-	uc->bcnt = 0;
+ }
+ 
+ static int udma_reset_chan(struct udma_chan *uc, bool hard)
+@@ -1115,7 +1125,7 @@ static void udma_check_tx_completion(struct work_struct *work)
+ 		if (uc->desc) {
+ 			struct udma_desc *d = uc->desc;
+ 
+-			uc->bcnt += d->residue;
++			udma_decrement_byte_counters(uc, d->residue);
+ 			udma_start(uc);
+ 			vchan_cookie_complete(&d->vd);
+ 			break;
+@@ -1168,7 +1178,7 @@ static irqreturn_t udma_ring_irq_handler(int irq, void *data)
+ 				vchan_cyclic_callback(&d->vd);
+ 			} else {
+ 				if (udma_is_desc_really_done(uc, d)) {
+-					uc->bcnt += d->residue;
++					udma_decrement_byte_counters(uc, d->residue);
+ 					udma_start(uc);
+ 					vchan_cookie_complete(&d->vd);
+ 				} else {
+@@ -1204,7 +1214,7 @@ static irqreturn_t udma_udma_irq_handler(int irq, void *data)
+ 			vchan_cyclic_callback(&d->vd);
+ 		} else {
+ 			/* TODO: figure out the real amount of data */
+-			uc->bcnt += d->residue;
++			udma_decrement_byte_counters(uc, d->residue);
+ 			udma_start(uc);
+ 			vchan_cookie_complete(&d->vd);
+ 		}
+@@ -3809,7 +3819,6 @@ static enum dma_status udma_tx_status(struct dma_chan *chan,
+ 			bcnt = udma_tchanrt_read(uc, UDMA_CHAN_RT_BCNT_REG);
+ 		}
+ 
+-		bcnt -= uc->bcnt;
+ 		if (bcnt && !(bcnt % uc->desc->residue))
+ 			residue = 0;
+ 		else
+diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
+index fe567be0f118b..804f542be3f28 100644
+--- a/drivers/firmware/efi/libstub/fdt.c
++++ b/drivers/firmware/efi/libstub/fdt.c
+@@ -280,14 +280,6 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
+ 		goto fail;
+ 	}
+ 
+-	/*
+-	 * Now that we have done our final memory allocation (and free)
+-	 * we can get the memory map key needed for exit_boot_services().
+-	 */
+-	status = efi_get_memory_map(&map);
+-	if (status != EFI_SUCCESS)
+-		goto fail_free_new_fdt;
+-
+ 	status = update_fdt((void *)fdt_addr, fdt_size,
+ 			    (void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr,
+ 			    initrd_addr, initrd_size);
+diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c
+index adaa492c3d2df..4e2575dfeb908 100644
+--- a/drivers/firmware/google/gsmi.c
++++ b/drivers/firmware/google/gsmi.c
+@@ -681,6 +681,15 @@ static struct notifier_block gsmi_die_notifier = {
+ static int gsmi_panic_callback(struct notifier_block *nb,
+ 			       unsigned long reason, void *arg)
+ {
++
++	/*
++	 * Panic callbacks are executed with all other CPUs stopped,
++	 * so we must not attempt to spin waiting for gsmi_dev.lock
++	 * to be released.
++	 */
++	if (spin_is_locked(&gsmi_dev.lock))
++		return NOTIFY_DONE;
++
+ 	gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC);
+ 	return NOTIFY_DONE;
+ }
+diff --git a/drivers/fpga/dfl-pci.c b/drivers/fpga/dfl-pci.c
+index fd1fa55c91130..0914e7328b1a5 100644
+--- a/drivers/fpga/dfl-pci.c
++++ b/drivers/fpga/dfl-pci.c
+@@ -77,12 +77,18 @@ static void cci_pci_free_irq(struct pci_dev *pcidev)
+ #define PCIE_DEVICE_ID_INTEL_PAC_D5005		0x0B2B
+ #define PCIE_DEVICE_ID_SILICOM_PAC_N5010	0x1000
+ #define PCIE_DEVICE_ID_SILICOM_PAC_N5011	0x1001
++#define PCIE_DEVICE_ID_INTEL_DFL		0xbcce
++/* PCI Subdevice ID for PCIE_DEVICE_ID_INTEL_DFL */
++#define PCIE_SUBDEVICE_ID_INTEL_N6000		0x1770
++#define PCIE_SUBDEVICE_ID_INTEL_N6001		0x1771
++#define PCIE_SUBDEVICE_ID_INTEL_C6100		0x17d4
+ 
+ /* VF Device */
+ #define PCIE_DEVICE_ID_VF_INT_5_X		0xBCBF
+ #define PCIE_DEVICE_ID_VF_INT_6_X		0xBCC1
+ #define PCIE_DEVICE_ID_VF_DSC_1_X		0x09C5
+ #define PCIE_DEVICE_ID_INTEL_PAC_D5005_VF	0x0B2C
++#define PCIE_DEVICE_ID_INTEL_DFL_VF		0xbccf
+ 
+ static struct pci_device_id cci_pcie_id_tbl[] = {
+ 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X),},
+@@ -96,6 +102,18 @@ static struct pci_device_id cci_pcie_id_tbl[] = {
+ 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF),},
+ 	{PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5010),},
+ 	{PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5011),},
++	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
++			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6000),},
++	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL_VF,
++			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6000),},
++	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
++			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6001),},
++	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL_VF,
++			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6001),},
++	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
++			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_C6100),},
++	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL_VF,
++			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_C6100),},
+ 	{0,}
+ };
+ MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
+diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c
+index 5498bc337f8b2..b9aae85ba9308 100644
+--- a/drivers/fpga/dfl.c
++++ b/drivers/fpga/dfl.c
+@@ -1866,7 +1866,7 @@ long dfl_feature_ioctl_set_irq(struct platform_device *pdev,
+ 		return -EINVAL;
+ 
+ 	fds = memdup_user((void __user *)(arg + sizeof(hdr)),
+-			  hdr.count * sizeof(s32));
++			  array_size(hdr.count, sizeof(s32)));
+ 	if (IS_ERR(fds))
+ 		return PTR_ERR(fds);
+ 
+diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
+index 3a7b78e367011..5858e6339a10b 100644
+--- a/drivers/fsi/fsi-core.c
++++ b/drivers/fsi/fsi-core.c
+@@ -1314,6 +1314,9 @@ int fsi_master_register(struct fsi_master *master)
+ 
+ 	mutex_init(&master->scan_lock);
+ 	master->idx = ida_simple_get(&master_ida, 0, INT_MAX, GFP_KERNEL);
++	if (master->idx < 0)
++		return master->idx;
++
+ 	dev_set_name(&master->dev, "fsi%d", master->idx);
+ 	master->dev.class = &fsi_master_class;
+ 
+diff --git a/drivers/fsi/fsi-master-ast-cf.c b/drivers/fsi/fsi-master-ast-cf.c
+index 24292acdbaf84..5f608ef8b53ca 100644
+--- a/drivers/fsi/fsi-master-ast-cf.c
++++ b/drivers/fsi/fsi-master-ast-cf.c
+@@ -1324,12 +1324,14 @@ static int fsi_master_acf_probe(struct platform_device *pdev)
+ 		}
+ 		master->cvic = devm_of_iomap(&pdev->dev, np, 0, NULL);
+ 		if (IS_ERR(master->cvic)) {
++			of_node_put(np);
+ 			rc = PTR_ERR(master->cvic);
+ 			dev_err(&pdev->dev, "Error %d mapping CVIC\n", rc);
+ 			goto err_free;
+ 		}
+ 		rc = of_property_read_u32(np, "copro-sw-interrupts",
+ 					  &master->cvic_sw_irq);
++		of_node_put(np);
+ 		if (rc) {
+ 			dev_err(&pdev->dev, "Can't find coprocessor SW interrupt\n");
+ 			goto err_free;
+diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c
+index c9cc75fbdfb9d..28c176d038a26 100644
+--- a/drivers/fsi/fsi-occ.c
++++ b/drivers/fsi/fsi-occ.c
+@@ -94,6 +94,7 @@ static int occ_open(struct inode *inode, struct file *file)
+ 	client->occ = occ;
+ 	mutex_init(&client->lock);
+ 	file->private_data = client;
++	get_device(occ->dev);
+ 
+ 	/* We allocate a 1-page buffer, make sure it all fits */
+ 	BUILD_BUG_ON((OCC_CMD_DATA_BYTES + 3) > PAGE_SIZE);
+@@ -197,6 +198,7 @@ static int occ_release(struct inode *inode, struct file *file)
+ {
+ 	struct occ_client *client = file->private_data;
+ 
++	put_device(client->occ->dev);
+ 	free_page((unsigned long)client->buffer);
+ 	kfree(client);
+ 
+@@ -493,12 +495,19 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len,
+ 	for (i = 1; i < req_len - 2; ++i)
+ 		checksum += byte_request[i];
+ 
+-	mutex_lock(&occ->occ_lock);
++	rc = mutex_lock_interruptible(&occ->occ_lock);
++	if (rc)
++		return rc;
+ 
+ 	occ->client_buffer = response;
+ 	occ->client_buffer_size = user_resp_len;
+ 	occ->client_response_size = 0;
+ 
++	if (!occ->buffer) {
++		rc = -ENOENT;
++		goto done;
++	}
++
+ 	/*
+ 	 * Get a sequence number and update the counter. Avoid a sequence
+ 	 * number of 0 which would pass the response check below even if the
+@@ -671,10 +680,13 @@ static int occ_remove(struct platform_device *pdev)
+ {
+ 	struct occ *occ = platform_get_drvdata(pdev);
+ 
+-	kvfree(occ->buffer);
+-
+ 	misc_deregister(&occ->mdev);
+ 
++	mutex_lock(&occ->occ_lock);
++	kvfree(occ->buffer);
++	occ->buffer = NULL;
++	mutex_unlock(&occ->occ_lock);
++
+ 	device_for_each_child(&pdev->dev, NULL, occ_unregister_child);
+ 
+ 	ida_simple_remove(&occ_ida, occ->idx);
+diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
+index bb50335239ac8..9c976ad7208ef 100644
+--- a/drivers/gpio/gpio-rockchip.c
++++ b/drivers/gpio/gpio-rockchip.c
+@@ -19,6 +19,7 @@
+ #include <linux/of_address.h>
+ #include <linux/of_device.h>
+ #include <linux/of_irq.h>
++#include <linux/pinctrl/consumer.h>
+ #include <linux/pinctrl/pinconf-generic.h>
+ #include <linux/regmap.h>
+ 
+@@ -156,6 +157,12 @@ static int rockchip_gpio_set_direction(struct gpio_chip *chip,
+ 	unsigned long flags;
+ 	u32 data = input ? 0 : 1;
+ 
++
++	if (input)
++		pinctrl_gpio_direction_input(bank->pin_base + offset);
++	else
++		pinctrl_gpio_direction_output(bank->pin_base + offset);
++
+ 	raw_spin_lock_irqsave(&bank->slock, flags);
+ 	rockchip_gpio_writel_bit(bank, offset, data, bank->gpio_regs->port_ddr);
+ 	raw_spin_unlock_irqrestore(&bank->slock, flags);
+diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
+index 6c2256e8474be..679ad054ea4b0 100644
+--- a/drivers/gpu/drm/Kconfig
++++ b/drivers/gpu/drm/Kconfig
+@@ -31,6 +31,7 @@ menuconfig DRM
+ config DRM_MIPI_DBI
+ 	tristate
+ 	depends on DRM
++	select DRM_KMS_HELPER
+ 
+ config DRM_MIPI_DSI
+ 	bool
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+index b7933c2ce765c..491d4846fc02c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+@@ -1674,10 +1674,12 @@ amdgpu_connector_add(struct amdgpu_device *adev,
+ 						   adev->mode_info.dither_property,
+ 						   AMDGPU_FMT_DITHER_DISABLE);
+ 
+-			if (amdgpu_audio != 0)
++			if (amdgpu_audio != 0) {
+ 				drm_object_attach_property(&amdgpu_connector->base.base,
+ 							   adev->mode_info.audio_property,
+ 							   AMDGPU_AUDIO_AUTO);
++				amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
++			}
+ 
+ 			subpixel_order = SubPixelHorizontalRGB;
+ 			connector->interlace_allowed = true;
+@@ -1799,6 +1801,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
+ 				drm_object_attach_property(&amdgpu_connector->base.base,
+ 							   adev->mode_info.audio_property,
+ 							   AMDGPU_AUDIO_AUTO);
++				amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
+ 			}
+ 			drm_object_attach_property(&amdgpu_connector->base.base,
+ 						   adev->mode_info.dither_property,
+@@ -1852,6 +1855,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
+ 				drm_object_attach_property(&amdgpu_connector->base.base,
+ 							   adev->mode_info.audio_property,
+ 							   AMDGPU_AUDIO_AUTO);
++				amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
+ 			}
+ 			drm_object_attach_property(&amdgpu_connector->base.base,
+ 						   adev->mode_info.dither_property,
+@@ -1902,6 +1906,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
+ 				drm_object_attach_property(&amdgpu_connector->base.base,
+ 							   adev->mode_info.audio_property,
+ 							   AMDGPU_AUDIO_AUTO);
++				amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;
+ 			}
+ 			drm_object_attach_property(&amdgpu_connector->base.base,
+ 						   adev->mode_info.dither_property,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+index 23998f727c7f9..1a06b8d724f39 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+@@ -38,8 +38,6 @@
+ #include <linux/pci.h>
+ #include <linux/pm_runtime.h>
+ #include <drm/drm_crtc_helper.h>
+-#include <drm/drm_damage_helper.h>
+-#include <drm/drm_drv.h>
+ #include <drm/drm_edid.h>
+ #include <drm/drm_gem_framebuffer_helper.h>
+ #include <drm/drm_fb_helper.h>
+@@ -500,12 +498,6 @@ static const struct drm_framebuffer_funcs amdgpu_fb_funcs = {
+ 	.create_handle = drm_gem_fb_create_handle,
+ };
+ 
+-static const struct drm_framebuffer_funcs amdgpu_fb_funcs_atomic = {
+-	.destroy = drm_gem_fb_destroy,
+-	.create_handle = drm_gem_fb_create_handle,
+-	.dirty = drm_atomic_helper_dirtyfb,
+-};
+-
+ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
+ 					  uint64_t bo_flags)
+ {
+@@ -1108,10 +1100,8 @@ static int amdgpu_display_gem_fb_verify_and_init(struct drm_device *dev,
+ 	if (ret)
+ 		goto err;
+ 
+-	if (drm_drv_uses_atomic_modeset(dev))
+-		ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs_atomic);
+-	else
+-		ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
++	ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
++
+ 	if (ret)
+ 		goto err;
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index 429fcdf28836e..de7144b06e933 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -2563,8 +2563,11 @@ static int amdgpu_pmops_runtime_resume(struct device *dev)
+ 		amdgpu_device_baco_exit(drm_dev);
+ 	}
+ 	ret = amdgpu_device_resume(drm_dev, false);
+-	if (ret)
++	if (ret) {
++		if (amdgpu_device_supports_px(drm_dev))
++			pci_disable_device(pdev);
+ 		return ret;
++	}
+ 
+ 	if (amdgpu_device_supports_px(drm_dev))
+ 		drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+index 1fd3cbca20a29..718db7d98e5a3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+@@ -211,12 +211,15 @@ static int amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p,
+ 	int r;
+ 
+ 	/* Wait for PD/PT moves to be completed */
+-	dma_resv_for_each_fence(&cursor, bo->tbo.base.resv,
+-				DMA_RESV_USAGE_KERNEL, fence) {
++	dma_resv_iter_begin(&cursor, bo->tbo.base.resv, DMA_RESV_USAGE_KERNEL);
++	dma_resv_for_each_fence_unlocked(&cursor, fence) {
+ 		r = amdgpu_sync_fence(&p->job->sync, fence);
+-		if (r)
++		if (r) {
++			dma_resv_iter_end(&cursor);
+ 			return r;
++		}
+ 	}
++	dma_resv_iter_end(&cursor);
+ 
+ 	do {
+ 		ndw = p->num_dw_left;
+diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c
+index bc11b2de37aeb..a1d26c4d80b8c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v3_0.c
+@@ -169,17 +169,17 @@ static void mmhub_v3_0_init_system_aperture_regs(struct amdgpu_device *adev)
+ 	uint64_t value;
+ 	uint32_t tmp;
+ 
+-	/* Disable AGP. */
+-	WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0);
+-	WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0);
+-	WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF);
+-
+ 	if (!amdgpu_sriov_vf(adev)) {
+ 		/*
+ 		 * the new L1 policy will block SRIOV guest from writing
+ 		 * these regs, and they will be programed at host.
+ 		 * so skip programing these regs.
+ 		 */
++		/* Disable AGP. */
++		WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BASE, 0);
++		WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_TOP, 0);
++		WREG32_SOC15(MMHUB, 0, regMMMC_VM_AGP_BOT, 0x00FFFFFF);
++
+ 		/* Program the system aperture low logical page number. */
+ 		WREG32_SOC15(MMHUB, 0, regMMMC_VM_SYSTEM_APERTURE_LOW_ADDR,
+ 			     adev->gmc.vram_start >> 18);
+diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+index 0200cb3a31a49..6a4f3ba14b1d2 100644
+--- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c
+@@ -910,7 +910,8 @@ static int sdma_v6_0_mqd_init(struct amdgpu_device *adev, void *mqd,
+ 	m->sdmax_rlcx_rb_cntl =
+ 		order_base_2(prop->queue_size / 4) << SDMA0_QUEUE0_RB_CNTL__RB_SIZE__SHIFT |
+ 		1 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_ENABLE__SHIFT |
+-		4 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT;
++		4 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT |
++		1 << SDMA0_QUEUE0_RB_CNTL__F32_WPTR_POLL_ENABLE__SHIFT;
+ 
+ 	m->sdmax_rlcx_rb_base = lower_32_bits(prop->hqd_base_gpu_addr >> 8);
+ 	m->sdmax_rlcx_rb_base_hi = upper_32_bits(prop->hqd_base_gpu_addr >> 8);
+diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c
+index 6e564b549b9ff..9c3463b481396 100644
+--- a/drivers/gpu/drm/amd/amdgpu/soc21.c
++++ b/drivers/gpu/drm/amd/amdgpu/soc21.c
+@@ -583,6 +583,10 @@ static int soc21_common_early_init(void *handle)
+ 			AMD_PG_SUPPORT_JPEG |
+ 			AMD_PG_SUPPORT_ATHUB |
+ 			AMD_PG_SUPPORT_MMHUB;
++		if (amdgpu_sriov_vf(adev)) {
++			adev->cg_flags = 0;
++			adev->pg_flags = 0;
++		}
+ 		adev->external_rev_id = adev->rev_id + 0x1; // TODO: need update
+ 		break;
+ 	case IP_VERSION(11, 0, 2):
+@@ -625,6 +629,7 @@ static int soc21_common_early_init(void *handle)
+ 			AMD_CG_SUPPORT_JPEG_MGCG;
+ 		adev->pg_flags =
+ 			AMD_PG_SUPPORT_GFX_PG |
++			AMD_PG_SUPPORT_VCN |
+ 			AMD_PG_SUPPORT_VCN_DPG |
+ 			AMD_PG_SUPPORT_JPEG;
+ 		adev->external_rev_id = adev->rev_id + 0x1;
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+index 007a3db69df13..ecb4c3abc6297 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+@@ -1242,6 +1242,24 @@ static void init_interrupts(struct device_queue_manager *dqm)
+ 			dqm->dev->kfd2kgd->init_interrupts(dqm->dev->adev, i);
+ }
+ 
++static void init_sdma_bitmaps(struct device_queue_manager *dqm)
++{
++	unsigned int num_sdma_queues =
++		min_t(unsigned int, sizeof(dqm->sdma_bitmap)*8,
++		      get_num_sdma_queues(dqm));
++	unsigned int num_xgmi_sdma_queues =
++		min_t(unsigned int, sizeof(dqm->xgmi_sdma_bitmap)*8,
++		      get_num_xgmi_sdma_queues(dqm));
++
++	if (num_sdma_queues)
++		dqm->sdma_bitmap = GENMASK_ULL(num_sdma_queues-1, 0);
++	if (num_xgmi_sdma_queues)
++		dqm->xgmi_sdma_bitmap = GENMASK_ULL(num_xgmi_sdma_queues-1, 0);
++
++	dqm->sdma_bitmap &= ~get_reserved_sdma_queues_bitmap(dqm);
++	pr_info("sdma_bitmap: %llx\n", dqm->sdma_bitmap);
++}
++
+ static int initialize_nocpsch(struct device_queue_manager *dqm)
+ {
+ 	int pipe, queue;
+@@ -1270,11 +1288,7 @@ static int initialize_nocpsch(struct device_queue_manager *dqm)
+ 
+ 	memset(dqm->vmid_pasid, 0, sizeof(dqm->vmid_pasid));
+ 
+-	dqm->sdma_bitmap = ~0ULL >> (64 - get_num_sdma_queues(dqm));
+-	dqm->sdma_bitmap &= ~(get_reserved_sdma_queues_bitmap(dqm));
+-	pr_info("sdma_bitmap: %llx\n", dqm->sdma_bitmap);
+-
+-	dqm->xgmi_sdma_bitmap = ~0ULL >> (64 - get_num_xgmi_sdma_queues(dqm));
++	init_sdma_bitmaps(dqm);
+ 
+ 	return 0;
+ }
+@@ -1452,9 +1466,6 @@ static int set_sched_resources(struct device_queue_manager *dqm)
+ 
+ static int initialize_cpsch(struct device_queue_manager *dqm)
+ {
+-	uint64_t num_sdma_queues;
+-	uint64_t num_xgmi_sdma_queues;
+-
+ 	pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm));
+ 
+ 	mutex_init(&dqm->lock_hidden);
+@@ -1463,24 +1474,10 @@ static int initialize_cpsch(struct device_queue_manager *dqm)
+ 	dqm->active_cp_queue_count = 0;
+ 	dqm->gws_queue_count = 0;
+ 	dqm->active_runlist = false;
+-
+-	num_sdma_queues = get_num_sdma_queues(dqm);
+-	if (num_sdma_queues >= BITS_PER_TYPE(dqm->sdma_bitmap))
+-		dqm->sdma_bitmap = ULLONG_MAX;
+-	else
+-		dqm->sdma_bitmap = (BIT_ULL(num_sdma_queues) - 1);
+-
+-	dqm->sdma_bitmap &= ~(get_reserved_sdma_queues_bitmap(dqm));
+-	pr_info("sdma_bitmap: %llx\n", dqm->sdma_bitmap);
+-
+-	num_xgmi_sdma_queues = get_num_xgmi_sdma_queues(dqm);
+-	if (num_xgmi_sdma_queues >= BITS_PER_TYPE(dqm->xgmi_sdma_bitmap))
+-		dqm->xgmi_sdma_bitmap = ULLONG_MAX;
+-	else
+-		dqm->xgmi_sdma_bitmap = (BIT_ULL(num_xgmi_sdma_queues) - 1);
+-
+ 	INIT_WORK(&dqm->hw_exception_work, kfd_process_hw_exception);
+ 
++	init_sdma_bitmaps(dqm);
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
+index 3ae350220d42e..5c3d216a26633 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
+@@ -375,7 +375,8 @@ static void update_mqd_sdma(struct mqd_manager *mm, void *mqd,
+ 		<< SDMA0_QUEUE0_RB_CNTL__RB_SIZE__SHIFT |
+ 		q->vmid << SDMA0_QUEUE0_RB_CNTL__RB_VMID__SHIFT |
+ 		1 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_ENABLE__SHIFT |
+-		6 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT;
++		6 << SDMA0_QUEUE0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT |
++		1 << SDMA0_QUEUE0_RB_CNTL__F32_WPTR_POLL_ENABLE__SHIFT;
+ 
+ 	m->sdmax_rlcx_rb_base = lower_32_bits(q->queue_address >> 8);
+ 	m->sdmax_rlcx_rb_base_hi = upper_32_bits(q->queue_address >> 8);
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+index 1efe7fa5bc589..3be70848b2020 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1109,7 +1109,8 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev)
+ 		hw_params.fb[i] = &fb_info->fb[i];
+ 
+ 	switch (adev->ip_versions[DCE_HWIP][0]) {
+-	case IP_VERSION(3, 1, 3): /* Only for this asic hw internal rev B0 */
++	case IP_VERSION(3, 1, 3):
++	case IP_VERSION(3, 1, 4):
+ 		hw_params.dpia_supported = true;
+ 		hw_params.disable_dpia = adev->dm.dc->debug.dpia_debug.bits.disable_dpia;
+ 		break;
+@@ -1295,13 +1296,21 @@ static struct hpd_rx_irq_offload_work_queue *hpd_rx_irq_create_workqueue(struct
+ 
+ 		if (hpd_rx_offload_wq[i].wq == NULL) {
+ 			DRM_ERROR("create amdgpu_dm_hpd_rx_offload_wq fail!");
+-			return NULL;
++			goto out_err;
+ 		}
+ 
+ 		spin_lock_init(&hpd_rx_offload_wq[i].offload_lock);
+ 	}
+ 
+ 	return hpd_rx_offload_wq;
++
++out_err:
++	for (i = 0; i < max_caps; i++) {
++		if (hpd_rx_offload_wq[i].wq)
++			destroy_workqueue(hpd_rx_offload_wq[i].wq);
++	}
++	kfree(hpd_rx_offload_wq);
++	return NULL;
+ }
+ 
+ struct amdgpu_stutter_quirk {
+@@ -7490,15 +7499,15 @@ static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state,
+ 		 * We also need vupdate irq for the actual core vblank handling
+ 		 * at end of vblank.
+ 		 */
+-		dm_set_vupdate_irq(new_state->base.crtc, true);
+-		drm_crtc_vblank_get(new_state->base.crtc);
++		WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, true) != 0);
++		WARN_ON(drm_crtc_vblank_get(new_state->base.crtc) != 0);
+ 		DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n",
+ 				 __func__, new_state->base.crtc->base.id);
+ 	} else if (old_vrr_active && !new_vrr_active) {
+ 		/* Transition VRR active -> inactive:
+ 		 * Allow vblank irq disable again for fixed refresh rate.
+ 		 */
+-		dm_set_vupdate_irq(new_state->base.crtc, false);
++		WARN_ON(dm_set_vupdate_irq(new_state->base.crtc, false) != 0);
+ 		drm_crtc_vblank_put(new_state->base.crtc);
+ 		DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n",
+ 				 __func__, new_state->base.crtc->base.id);
+@@ -8253,23 +8262,6 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ 		mutex_unlock(&dm->dc_lock);
+ 	}
+ 
+-	/* Count number of newly disabled CRTCs for dropping PM refs later. */
+-	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
+-				      new_crtc_state, i) {
+-		if (old_crtc_state->active && !new_crtc_state->active)
+-			crtc_disable_count++;
+-
+-		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+-		dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
+-
+-		/* For freesync config update on crtc state and params for irq */
+-		update_stream_irq_parameters(dm, dm_new_crtc_state);
+-
+-		/* Handle vrr on->off / off->on transitions */
+-		amdgpu_dm_handle_vrr_transition(dm_old_crtc_state,
+-						dm_new_crtc_state);
+-	}
+-
+ 	/**
+ 	 * Enable interrupts for CRTCs that are newly enabled or went through
+ 	 * a modeset. It was intentionally deferred until after the front end
+@@ -8279,16 +8271,29 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ 	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+ 		struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
+ #ifdef CONFIG_DEBUG_FS
+-		bool configure_crc = false;
+ 		enum amdgpu_dm_pipe_crc_source cur_crc_src;
+ #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+-		struct crc_rd_work *crc_rd_wrk = dm->crc_rd_wrk;
++		struct crc_rd_work *crc_rd_wrk;
++#endif
++#endif
++		/* Count number of newly disabled CRTCs for dropping PM refs later. */
++		if (old_crtc_state->active && !new_crtc_state->active)
++			crtc_disable_count++;
++
++		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
++		dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
++
++		/* For freesync config update on crtc state and params for irq */
++		update_stream_irq_parameters(dm, dm_new_crtc_state);
++
++#ifdef CONFIG_DEBUG_FS
++#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
++		crc_rd_wrk = dm->crc_rd_wrk;
+ #endif
+ 		spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
+ 		cur_crc_src = acrtc->dm_irq_params.crc_src;
+ 		spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
+ #endif
+-		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+ 
+ 		if (new_crtc_state->active &&
+ 		    (!old_crtc_state->active ||
+@@ -8296,16 +8301,19 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ 			dc_stream_retain(dm_new_crtc_state->stream);
+ 			acrtc->dm_irq_params.stream = dm_new_crtc_state->stream;
+ 			manage_dm_interrupts(adev, acrtc, true);
++		}
++		/* Handle vrr on->off / off->on transitions */
++		amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, dm_new_crtc_state);
+ 
+ #ifdef CONFIG_DEBUG_FS
++		if (new_crtc_state->active &&
++		    (!old_crtc_state->active ||
++		     drm_atomic_crtc_needs_modeset(new_crtc_state))) {
+ 			/**
+ 			 * Frontend may have changed so reapply the CRC capture
+ 			 * settings for the stream.
+ 			 */
+-			dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+-
+ 			if (amdgpu_dm_is_valid_crc_source(cur_crc_src)) {
+-				configure_crc = true;
+ #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+ 				if (amdgpu_dm_crc_window_is_activated(crtc)) {
+ 					spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags);
+@@ -8317,14 +8325,12 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
+ 					spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags);
+ 				}
+ #endif
+-			}
+-
+-			if (configure_crc)
+ 				if (amdgpu_dm_crtc_configure_crc_source(
+ 					crtc, dm_new_crtc_state, cur_crc_src))
+ 					DRM_DEBUG_DRIVER("Failed to configure crc source");
+-#endif
++			}
+ 		}
++#endif
+ 	}
+ 
+ 	for_each_new_crtc_in_state(state, crtc, new_crtc_state, j)
+@@ -9408,10 +9414,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
+ 				}
+ 			}
+ 		}
+-		if (!pre_validate_dsc(state, &dm_state, vars)) {
+-			ret = -EINVAL;
+-			goto fail;
+-		}
+ 	}
+ #endif
+ 	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+@@ -9545,6 +9547,15 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
+ 		}
+ 	}
+ 
++#if defined(CONFIG_DRM_AMD_DC_DCN)
++	if (dc_resource_is_dsc_encoding_supported(dc)) {
++		if (!pre_validate_dsc(state, &dm_state, vars)) {
++			ret = -EINVAL;
++			goto fail;
++		}
++	}
++#endif
++
+ 	/* Run this here since we want to validate the streams we created */
+ 	ret = drm_atomic_helper_check_planes(dev, state);
+ 	if (ret) {
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+index 8ca10ab3dfc12..26291db0a3cf6 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+@@ -60,11 +60,15 @@ static bool link_supports_psrsu(struct dc_link *link)
+  */
+ void amdgpu_dm_set_psr_caps(struct dc_link *link)
+ {
+-	if (!(link->connector_signal & SIGNAL_TYPE_EDP))
++	if (!(link->connector_signal & SIGNAL_TYPE_EDP)) {
++		link->psr_settings.psr_feature_enabled = false;
+ 		return;
++	}
+ 
+-	if (link->type == dc_connection_none)
++	if (link->type == dc_connection_none) {
++		link->psr_settings.psr_feature_enabled = false;
+ 		return;
++	}
+ 
+ 	if (link->dpcd_caps.psr_info.psr_version == 0) {
+ 		link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED;
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_smu.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_smu.c
+index 897105d1c111e..ef0795b14a1fd 100644
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_smu.c
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_smu.c
+@@ -339,29 +339,24 @@ void dcn314_smu_set_zstate_support(struct clk_mgr_internal *clk_mgr, enum dcn_zs
+ 	if (!clk_mgr->smu_present)
+ 		return;
+ 
+-	if (!clk_mgr->base.ctx->dc->debug.enable_z9_disable_interface &&
+-			(support == DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY))
+-		support = DCN_ZSTATE_SUPPORT_DISALLOW;
+-
+-
+ 	// Arg[15:0] = 8/9/0 for Z8/Z9/disallow -> existing bits
+ 	// Arg[16] = Disallow Z9 -> new bit
+ 	switch (support) {
+ 
+ 	case DCN_ZSTATE_SUPPORT_ALLOW:
+ 		msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
+-		param = 9;
++		param = (1 << 10) | (1 << 9) | (1 << 8);
+ 		break;
+ 
+ 	case DCN_ZSTATE_SUPPORT_DISALLOW:
+ 		msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
+-		param = 8;
++		param = 0;
+ 		break;
+ 
+ 
+ 	case DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY:
+ 		msg_id = VBIOSSMC_MSG_AllowZstatesEntry;
+-		param = 0x00010008;
++		param = (1 << 10);
+ 		break;
+ 
+ 	default: //DCN_ZSTATE_SUPPORT_UNKNOWN
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index fb22c3d70528e..18d6ee666297b 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -2753,11 +2753,8 @@ static void copy_stream_update_to_stream(struct dc *dc,
+ 	if (update->abm_level)
+ 		stream->abm_level = *update->abm_level;
+ 
+-	if (update->periodic_interrupt0)
+-		stream->periodic_interrupt0 = *update->periodic_interrupt0;
+-
+-	if (update->periodic_interrupt1)
+-		stream->periodic_interrupt1 = *update->periodic_interrupt1;
++	if (update->periodic_interrupt)
++		stream->periodic_interrupt = *update->periodic_interrupt;
+ 
+ 	if (update->gamut_remap)
+ 		stream->gamut_remap_matrix = *update->gamut_remap;
+@@ -2987,13 +2984,8 @@ static void commit_planes_do_stream_update(struct dc *dc,
+ 
+ 		if (!pipe_ctx->top_pipe &&  !pipe_ctx->prev_odm_pipe && pipe_ctx->stream == stream) {
+ 
+-			if (stream_update->periodic_interrupt0 &&
+-					dc->hwss.setup_periodic_interrupt)
+-				dc->hwss.setup_periodic_interrupt(dc, pipe_ctx, VLINE0);
+-
+-			if (stream_update->periodic_interrupt1 &&
+-					dc->hwss.setup_periodic_interrupt)
+-				dc->hwss.setup_periodic_interrupt(dc, pipe_ctx, VLINE1);
++			if (stream_update->periodic_interrupt && dc->hwss.setup_periodic_interrupt)
++				dc->hwss.setup_periodic_interrupt(dc, pipe_ctx);
+ 
+ 			if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
+ 					stream_update->vrr_infopacket ||
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+index 52a61b3e5a8b0..755c4f9de6da0 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
++++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+@@ -323,11 +323,13 @@ bool dc_dmub_srv_p_state_delegate(struct dc *dc, bool should_manage_pstate, stru
+ 	struct dmub_cmd_fw_assisted_mclk_switch_config *config_data = &cmd.fw_assisted_mclk_switch.config_data;
+ 	int i = 0;
+ 	int ramp_up_num_steps = 1; // TODO: Ramp is currently disabled. Reenable it.
+-	uint8_t visual_confirm_enabled = dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS;
++	uint8_t visual_confirm_enabled;
+ 
+ 	if (dc == NULL)
+ 		return false;
+ 
++	visual_confirm_enabled = dc->debug.visual_confirm == VISUAL_CONFIRM_FAMS;
++
+ 	// Format command.
+ 	cmd.fw_assisted_mclk_switch.header.type = DMUB_CMD__FW_ASSISTED_MCLK_SWITCH;
+ 	cmd.fw_assisted_mclk_switch.header.sub_type = DMUB_CMD__FAMS_SETUP_FW_CTRL;
+@@ -719,7 +721,7 @@ void dc_dmub_setup_subvp_dmub_command(struct dc *dc,
+ 		// Store the original watermark value for this SubVP config so we can lower it when the
+ 		// MCLK switch starts
+ 		wm_val_refclk = context->bw_ctx.bw.dcn.watermarks.a.cstate_pstate.pstate_change_ns *
+-				dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 / 1000;
++				(dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000) / 1000;
+ 
+ 		cmd.fw_assisted_mclk_switch_v2.config_data.watermark_a_cache = wm_val_refclk < 0xFFFF ? wm_val_refclk : 0xFFFF;
+ 	}
+diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
+index f87f852d48298..ae0922e98ef77 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
++++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
+@@ -212,8 +212,7 @@ struct dc_stream_state {
+ 	/* DMCU info */
+ 	unsigned int abm_level;
+ 
+-	struct periodic_interrupt_config periodic_interrupt0;
+-	struct periodic_interrupt_config periodic_interrupt1;
++	struct periodic_interrupt_config periodic_interrupt;
+ 
+ 	/* from core_stream struct */
+ 	struct dc_context *ctx;
+@@ -283,8 +282,7 @@ struct dc_stream_update {
+ 	struct dc_info_packet *hdr_static_metadata;
+ 	unsigned int *abm_level;
+ 
+-	struct periodic_interrupt_config *periodic_interrupt0;
+-	struct periodic_interrupt_config *periodic_interrupt1;
++	struct periodic_interrupt_config *periodic_interrupt;
+ 
+ 	struct dc_info_packet *vrr_infopacket;
+ 	struct dc_info_packet *vsc_infopacket;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+index 5b5d952b2b8cd..bc9b92838ea9f 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+@@ -3768,7 +3768,7 @@ void dcn10_calc_vupdate_position(
+ {
+ 	const struct dc_crtc_timing *dc_crtc_timing = &pipe_ctx->stream->timing;
+ 	int vline_int_offset_from_vupdate =
+-			pipe_ctx->stream->periodic_interrupt0.lines_offset;
++			pipe_ctx->stream->periodic_interrupt.lines_offset;
+ 	int vupdate_offset_from_vsync = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
+ 	int start_position;
+ 
+@@ -3793,18 +3793,10 @@ void dcn10_calc_vupdate_position(
+ static void dcn10_cal_vline_position(
+ 		struct dc *dc,
+ 		struct pipe_ctx *pipe_ctx,
+-		enum vline_select vline,
+ 		uint32_t *start_line,
+ 		uint32_t *end_line)
+ {
+-	enum vertical_interrupt_ref_point ref_point = INVALID_POINT;
+-
+-	if (vline == VLINE0)
+-		ref_point = pipe_ctx->stream->periodic_interrupt0.ref_point;
+-	else if (vline == VLINE1)
+-		ref_point = pipe_ctx->stream->periodic_interrupt1.ref_point;
+-
+-	switch (ref_point) {
++	switch (pipe_ctx->stream->periodic_interrupt.ref_point) {
+ 	case START_V_UPDATE:
+ 		dcn10_calc_vupdate_position(
+ 				dc,
+@@ -3813,7 +3805,9 @@ static void dcn10_cal_vline_position(
+ 				end_line);
+ 		break;
+ 	case START_V_SYNC:
+-		// Suppose to do nothing because vsync is 0;
++		// vsync is line 0 so start_line is just the requested line offset
++		*start_line = pipe_ctx->stream->periodic_interrupt.lines_offset;
++		*end_line = *start_line + 2;
+ 		break;
+ 	default:
+ 		ASSERT(0);
+@@ -3823,24 +3817,15 @@ static void dcn10_cal_vline_position(
+ 
+ void dcn10_setup_periodic_interrupt(
+ 		struct dc *dc,
+-		struct pipe_ctx *pipe_ctx,
+-		enum vline_select vline)
++		struct pipe_ctx *pipe_ctx)
+ {
+ 	struct timing_generator *tg = pipe_ctx->stream_res.tg;
++	uint32_t start_line = 0;
++	uint32_t end_line = 0;
+ 
+-	if (vline == VLINE0) {
+-		uint32_t start_line = 0;
+-		uint32_t end_line = 0;
++	dcn10_cal_vline_position(dc, pipe_ctx, &start_line, &end_line);
+ 
+-		dcn10_cal_vline_position(dc, pipe_ctx, vline, &start_line, &end_line);
+-
+-		tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line);
+-
+-	} else if (vline == VLINE1) {
+-		pipe_ctx->stream_res.tg->funcs->setup_vertical_interrupt1(
+-				tg,
+-				pipe_ctx->stream->periodic_interrupt1.lines_offset);
+-	}
++	tg->funcs->setup_vertical_interrupt0(tg, start_line, end_line);
+ }
+ 
+ void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx)
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
+index 9ae07c77fdc01..0ef7bf7ddb75e 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h
+@@ -175,8 +175,7 @@ void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx);
+ void dcn10_set_cursor_sdr_white_level(struct pipe_ctx *pipe_ctx);
+ void dcn10_setup_periodic_interrupt(
+ 		struct dc *dc,
+-		struct pipe_ctx *pipe_ctx,
+-		enum vline_select vline);
++		struct pipe_ctx *pipe_ctx);
+ enum dc_status dcn10_set_clock(struct dc *dc,
+ 		enum dc_clock_type clock_type,
+ 		uint32_t clk_khz,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
+index 23621ff08c905..52fb2bf3d5781 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_stream_encoder.c
+@@ -150,9 +150,9 @@ static void dcn31_hpo_dp_stream_enc_dp_blank(
+ 	 * 10us*5000=50ms. This covers 41.7ms of minimum 24 Hz mode +
+ 	 * a little more because we may not trust delay accuracy.
+ 	 */
+-	//REG_WAIT(DP_SYM32_ENC_VID_STREAM_CONTROL,
+-	//		VID_STREAM_STATUS, 0,
+-	//		10, 5000);
++	REG_WAIT(DP_SYM32_ENC_VID_STREAM_CONTROL,
++			VID_STREAM_STATUS, 0,
++			10, 5000);
+ 
+ 	/* Disable SDP tranmission */
+ 	REG_UPDATE(DP_SYM32_ENC_SDP_CONTROL,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+index 44ac1c2aabf5e..6d721fadcbee6 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_resource.c
+@@ -881,7 +881,8 @@ static const struct dc_plane_cap plane_cap = {
+ };
+ 
+ static const struct dc_debug_options debug_defaults_drv = {
+-	.disable_z10 = true, /*hw not support it*/
++	.disable_z10 = false,
++	.enable_z9_disable_interface = true,
+ 	.disable_dmcu = true,
+ 	.force_abm_enable = false,
+ 	.timing_trace = false,
+@@ -1719,6 +1720,7 @@ static struct clock_source *dcn30_clock_source_create(
+ 	}
+ 
+ 	BREAK_TO_DEBUGGER();
++	kfree(clk_src);
+ 	return NULL;
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c
+index 2038cbda33f74..1fbb9fbf84549 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c
+@@ -179,6 +179,7 @@ static struct hubp_funcs dcn32_hubp_funcs = {
+ 	.hubp_init = hubp3_init,
+ 	.set_unbounded_requesting = hubp31_set_unbounded_requesting,
+ 	.hubp_soft_reset = hubp31_soft_reset,
++	.hubp_set_flip_int = hubp1_set_flip_int,
+ 	.hubp_in_blank = hubp1_in_blank,
+ 	.hubp_update_force_pstate_disallow = hubp32_update_force_pstate_disallow,
+ 	.phantom_hubp_post_enable = hubp32_phantom_hubp_post_enable,
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+index 344fe7535df5b..c72166e096bad 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -1001,6 +1001,10 @@ void dcn32_init_hw(struct dc *dc)
+ 		dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv->dmub);
+ 		dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
+ 	}
++
++	/* Enable support for ODM and windowed MPO if policy flag is set */
++	if (dc->debug.enable_single_display_2to1_odm_policy)
++		dc->config.enable_windowed_mpo_odm = true;
+ }
+ 
+ static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
+index 6ca288fb5fb9e..2d46bc527b218 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
+@@ -26,12 +26,12 @@
+ #include "bw_fixed.h"
+ 
+ 
+-#define MIN_I64 \
+-	(int64_t)(-(1LL << 63))
+-
+ #define MAX_I64 \
+ 	(int64_t)((1ULL << 63) - 1)
+ 
++#define MIN_I64 \
++	(-MAX_I64 - 1)
++
+ #define FRACTIONAL_PART_MASK \
+ 	((1ULL << BW_FIXED_BITS_PER_FRACTIONAL_PART) - 1)
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+index e573e706430df..b9d3a4000c3d4 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+@@ -2199,6 +2199,7 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa
+ 		if ((int)(dcn3_2_soc.urgent_latency_us * 1000) != dc->bb_overrides.urgent_latency_ns
+ 			&& dc->bb_overrides.urgent_latency_ns) {
+ 			dcn3_2_soc.urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
++			dcn3_2_soc.urgent_latency_pixel_data_only_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
+ 		}
+ 
+ 		if ((int)(dcn3_2_soc.dram_clock_change_latency_us * 1000)
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+index 6980f698eb23a..52525833a99b9 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+@@ -733,6 +733,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
+ 				mode_lib->vba.FCLKChangeLatency, v->UrgentLatency,
+ 				mode_lib->vba.SREnterPlusExitTime);
+ 
++			memset(&v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe, 0, sizeof(DmlPipe));
++
+ 			v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe.Dppclk = mode_lib->vba.DPPCLK[k];
+ 			v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe.Dispclk = mode_lib->vba.DISPCLK;
+ 			v->dummy_vars.DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation.myPipe.PixelClock = mode_lib->vba.PixelClock[k];
+diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+index c87091683b5dc..b6369758b4912 100644
+--- a/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
++++ b/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+@@ -489,6 +489,7 @@ void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_p
+ 		if ((int)(dcn3_21_soc.urgent_latency_us * 1000) != dc->bb_overrides.urgent_latency_ns
+ 			&& dc->bb_overrides.urgent_latency_ns) {
+ 			dcn3_21_soc.urgent_latency_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
++			dcn3_21_soc.urgent_latency_pixel_data_only_us = dc->bb_overrides.urgent_latency_ns / 1000.0;
+ 		}
+ 
+ 		if ((int)(dcn3_21_soc.dram_clock_change_latency_us * 1000)
+diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+index ccb3c719fc4de..ac94dba72c18b 100644
+--- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
++++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
+@@ -32,11 +32,6 @@
+ #include "inc/hw/link_encoder.h"
+ #include "core_status.h"
+ 
+-enum vline_select {
+-	VLINE0,
+-	VLINE1
+-};
+-
+ struct pipe_ctx;
+ struct dc_state;
+ struct dc_stream_status;
+@@ -116,8 +111,7 @@ struct hw_sequencer_funcs {
+ 			int group_index, int group_size,
+ 			struct pipe_ctx *grouped_pipes[]);
+ 	void (*setup_periodic_interrupt)(struct dc *dc,
+-			struct pipe_ctx *pipe_ctx,
+-			enum vline_select vline);
++			struct pipe_ctx *pipe_ctx);
+ 	void (*set_drr)(struct pipe_ctx **pipe_ctx, int num_pipes,
+ 			struct dc_crtc_timing_adjust adjust);
+ 	void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx,
+diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+index 59172acb97380..292f533d8cf0d 100644
+--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
++++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+@@ -235,7 +235,7 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
+ 			crtc->state->event = NULL;
+ 			drm_crtc_send_vblank_event(crtc, event);
+ 		} else {
+-			DRM_WARN("CRTC[%d]: FLIP happen but no pending commit.\n",
++			DRM_WARN("CRTC[%d]: FLIP happened but no pending commit.\n",
+ 				 drm_crtc_index(&kcrtc->base));
+ 		}
+ 		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+@@ -286,7 +286,7 @@ komeda_crtc_atomic_enable(struct drm_crtc *crtc,
+ 	komeda_crtc_do_flush(crtc, old);
+ }
+ 
+-static void
++void
+ komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
+ 					 struct completion *input_flip_done)
+ {
+diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+index 93b7f09b96ca9..327051bba5b68 100644
+--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
++++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+@@ -69,6 +69,25 @@ static const struct drm_driver komeda_kms_driver = {
+ 	.minor = 1,
+ };
+ 
++static void komeda_kms_atomic_commit_hw_done(struct drm_atomic_state *state)
++{
++	struct drm_device *dev = state->dev;
++	struct komeda_kms_dev *kms = to_kdev(dev);
++	int i;
++
++	for (i = 0; i < kms->n_crtcs; i++) {
++		struct komeda_crtc *kcrtc = &kms->crtcs[i];
++
++		if (kcrtc->base.state->active) {
++			struct completion *flip_done = NULL;
++			if (kcrtc->base.state->event)
++				flip_done = kcrtc->base.state->event->base.completion;
++			komeda_crtc_flush_and_wait_for_flip_done(kcrtc, flip_done);
++		}
++	}
++	drm_atomic_helper_commit_hw_done(state);
++}
++
+ static void komeda_kms_commit_tail(struct drm_atomic_state *old_state)
+ {
+ 	struct drm_device *dev = old_state->dev;
+@@ -81,7 +100,7 @@ static void komeda_kms_commit_tail(struct drm_atomic_state *old_state)
+ 
+ 	drm_atomic_helper_commit_modeset_enables(dev, old_state);
+ 
+-	drm_atomic_helper_commit_hw_done(old_state);
++	komeda_kms_atomic_commit_hw_done(old_state);
+ 
+ 	drm_atomic_helper_wait_for_flip_done(dev, old_state);
+ 
+diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+index 7889e380ab23c..7339339ef6b87 100644
+--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
++++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+@@ -183,6 +183,8 @@ void komeda_kms_cleanup_private_objs(struct komeda_kms_dev *kms);
+ 
+ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
+ 			      struct komeda_events *evts);
++void komeda_crtc_flush_and_wait_for_flip_done(struct komeda_crtc *kcrtc,
++					      struct completion *input_flip_done);
+ 
+ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev);
+ void komeda_kms_detach(struct komeda_kms_dev *kms);
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+index a031a0cd1f181..94de73cbeb2dd 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
+@@ -394,10 +394,7 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1);
+ #else
+ static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
+ {
+-	unsigned int offset = adv7511->type == ADV7533 ?
+-						ADV7533_REG_CEC_OFFSET : 0;
+-
+-	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
++	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL,
+ 		     ADV7511_CEC_CTRL_POWER_DOWN);
+ 	return 0;
+ }
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
+index 0b266f28f150f..99964f5a5457b 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c
+@@ -359,7 +359,7 @@ int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
+ 		goto err_cec_alloc;
+ 	}
+ 
+-	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0);
++	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, 0);
+ 	/* cec soft reset */
+ 	regmap_write(adv7511->regmap_cec,
+ 		     ADV7511_REG_CEC_SOFT_RESET + offset, 0x01);
+@@ -386,7 +386,7 @@ err_cec_alloc:
+ 	dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n",
+ 		 ret);
+ err_cec_parse_dt:
+-	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
++	regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL,
+ 		     ADV7511_CEC_CTRL_POWER_DOWN);
+ 	return ret == -EPROBE_DEFER ? ret : 0;
+ }
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index 38bf28720f3a2..6031bdd923420 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -1340,9 +1340,6 @@ static int adv7511_remove(struct i2c_client *i2c)
+ {
+ 	struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
+ 
+-	i2c_unregister_device(adv7511->i2c_cec);
+-	clk_disable_unprepare(adv7511->cec_clk);
+-
+ 	adv7511_uninit_regulators(adv7511);
+ 
+ 	drm_bridge_remove(&adv7511->bridge);
+@@ -1350,6 +1347,8 @@ static int adv7511_remove(struct i2c_client *i2c)
+ 	adv7511_audio_exit(adv7511);
+ 
+ 	cec_unregister_adapter(adv7511->cec_adap);
++	i2c_unregister_device(adv7511->i2c_cec);
++	clk_disable_unprepare(adv7511->cec_clk);
+ 
+ 	i2c_unregister_device(adv7511->i2c_packet);
+ 	i2c_unregister_device(adv7511->i2c_edid);
+diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
+index d1f1d525aeb6d..79fc7a50b4976 100644
+--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
++++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
+@@ -1642,6 +1642,7 @@ static int anx7625_parse_dt(struct device *dev,
+ 	anx7625_get_swing_setting(dev, pdata);
+ 
+ 	pdata->is_dpi = 0; /* default dsi mode */
++	of_node_put(pdata->mipi_host_node);
+ 	pdata->mipi_host_node = of_graph_get_remote_node(np, 0, 0);
+ 	if (!pdata->mipi_host_node) {
+ 		DRM_DEV_ERROR(dev, "fail to get internal panel.\n");
+diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
+index 4b673c4792d77..a09d1a39ab0ae 100644
+--- a/drivers/gpu/drm/bridge/ite-it6505.c
++++ b/drivers/gpu/drm/bridge/ite-it6505.c
+@@ -2954,6 +2954,9 @@ static void it6505_bridge_atomic_enable(struct drm_bridge *bridge,
+ 
+ 	it6505_int_mask_enable(it6505);
+ 	it6505_video_reset(it6505);
++
++	it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
++				     DP_SET_POWER_D0);
+ }
+ 
+ static void it6505_bridge_atomic_disable(struct drm_bridge *bridge,
+@@ -2965,9 +2968,9 @@ static void it6505_bridge_atomic_disable(struct drm_bridge *bridge,
+ 	DRM_DEV_DEBUG_DRIVER(dev, "start");
+ 
+ 	if (it6505->powered) {
+-		it6505_video_disable(it6505);
+ 		it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
+ 					     DP_SET_POWER_D3);
++		it6505_video_disable(it6505);
+ 	}
+ }
+ 
+diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c
+index 8a60e83482a04..5fccacc159f00 100644
+--- a/drivers/gpu/drm/bridge/lontium-lt9611.c
++++ b/drivers/gpu/drm/bridge/lontium-lt9611.c
+@@ -813,13 +813,14 @@ static int lt9611_connector_init(struct drm_bridge *bridge, struct lt9611 *lt961
+ 
+ 	drm_connector_helper_add(&lt9611->connector,
+ 				 &lt9611_bridge_connector_helper_funcs);
+-	drm_connector_attach_encoder(&lt9611->connector, bridge->encoder);
+ 
+ 	if (!bridge->encoder) {
+ 		DRM_ERROR("Parent encoder object not found");
+ 		return -ENODEV;
+ 	}
+ 
++	drm_connector_attach_encoder(&lt9611->connector, bridge->encoder);
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+index cce98bf2a4e73..72248a565579e 100644
+--- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
++++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+@@ -296,7 +296,9 @@ static void ge_b850v3_lvds_remove(void)
+ 	 * This check is to avoid both the drivers
+ 	 * removing the bridge in their remove() function
+ 	 */
+-	if (!ge_b850v3_lvds_ptr)
++	if (!ge_b850v3_lvds_ptr ||
++	    !ge_b850v3_lvds_ptr->stdp2690_i2c ||
++		!ge_b850v3_lvds_ptr->stdp4028_i2c)
+ 		goto out;
+ 
+ 	drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge);
+diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c b/drivers/gpu/drm/bridge/parade-ps8640.c
+index 31e88cb39f8a0..49107a6cdac18 100644
+--- a/drivers/gpu/drm/bridge/parade-ps8640.c
++++ b/drivers/gpu/drm/bridge/parade-ps8640.c
+@@ -631,8 +631,8 @@ static int ps8640_probe(struct i2c_client *client)
+ 	if (!ps_bridge)
+ 		return -ENOMEM;
+ 
+-	ps_bridge->supplies[0].supply = "vdd33";
+-	ps_bridge->supplies[1].supply = "vdd12";
++	ps_bridge->supplies[0].supply = "vdd12";
++	ps_bridge->supplies[1].supply = "vdd33";
+ 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies),
+ 				      ps_bridge->supplies);
+ 	if (ret)
+diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+index 25a60eb4d67c7..40d8ca37f5bc8 100644
+--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+@@ -3096,6 +3096,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
+ {
+ 	struct dw_hdmi *hdmi = dev_id;
+ 	u8 intr_stat, phy_int_pol, phy_pol_mask, phy_stat;
++	enum drm_connector_status status = connector_status_unknown;
+ 
+ 	intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
+ 	phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);
+@@ -3134,13 +3135,15 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
+ 			cec_notifier_phys_addr_invalidate(hdmi->cec_notifier);
+ 			mutex_unlock(&hdmi->cec_notifier_mutex);
+ 		}
+-	}
+ 
+-	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
+-		enum drm_connector_status status = phy_int_pol & HDMI_PHY_HPD
+-						 ? connector_status_connected
+-						 : connector_status_disconnected;
++		if (phy_stat & HDMI_PHY_HPD)
++			status = connector_status_connected;
++
++		if (!(phy_stat & (HDMI_PHY_HPD | HDMI_PHY_RX_SENSE)))
++			status = connector_status_disconnected;
++	}
+ 
++	if (status != connector_status_unknown) {
+ 		dev_dbg(hdmi->dev, "EVENT=%s\n",
+ 			status == connector_status_connected ?
+ 			"plugin" : "plugout");
+diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
+index 02bd757a89874..1dc107f13645b 100644
+--- a/drivers/gpu/drm/bridge/tc358767.c
++++ b/drivers/gpu/drm/bridge/tc358767.c
+@@ -2010,9 +2010,10 @@ static int tc_probe_bridge_endpoint(struct tc_data *tc)
+ 
+ 	for_each_endpoint_of_node(dev->of_node, node) {
+ 		of_graph_parse_endpoint(node, &endpoint);
+-		if (endpoint.port > 2)
++		if (endpoint.port > 2) {
++			of_node_put(node);
+ 			return -EINVAL;
+-
++		}
+ 		mode |= BIT(endpoint.port);
+ 	}
+ 
+diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
+index e5bab236b3ae5..4c0c4e3d1e206 100644
+--- a/drivers/gpu/drm/display/drm_dp_helper.c
++++ b/drivers/gpu/drm/display/drm_dp_helper.c
+@@ -2638,17 +2638,8 @@ int drm_dp_set_phy_test_pattern(struct drm_dp_aux *aux,
+ 				struct drm_dp_phy_test_params *data, u8 dp_rev)
+ {
+ 	int err, i;
+-	u8 link_config[2];
+ 	u8 test_pattern;
+ 
+-	link_config[0] = drm_dp_link_rate_to_bw_code(data->link_rate);
+-	link_config[1] = data->num_lanes;
+-	if (data->enhanced_frame_cap)
+-		link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+-	err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, link_config, 2);
+-	if (err < 0)
+-		return err;
+-
+ 	test_pattern = data->phy_pattern;
+ 	if (dp_rev < 0x12) {
+ 		test_pattern = (test_pattern << 2) &
+diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c
+index 57e65423e50d2..7a94a5288e8d7 100644
+--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
++++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
+@@ -4907,14 +4907,14 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
+ 		seq_printf(m, "dpcd: %*ph\n", DP_RECEIVER_CAP_SIZE, buf);
+ 
+ 		ret = drm_dp_dpcd_read(mgr->aux, DP_FAUX_CAP, buf, 2);
+-		if (ret) {
++		if (ret != 2) {
+ 			seq_printf(m, "faux/mst read failed\n");
+ 			goto out;
+ 		}
+ 		seq_printf(m, "faux/mst: %*ph\n", 2, buf);
+ 
+ 		ret = drm_dp_dpcd_read(mgr->aux, DP_MSTM_CTRL, buf, 1);
+-		if (ret) {
++		if (ret != 1) {
+ 			seq_printf(m, "mst ctrl read failed\n");
+ 			goto out;
+ 		}
+@@ -4922,7 +4922,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
+ 
+ 		/* dump the standard OUI branch header */
+ 		ret = drm_dp_dpcd_read(mgr->aux, DP_BRANCH_OUI, buf, DP_BRANCH_OUI_HEADER_SIZE);
+-		if (ret) {
++		if (ret != DP_BRANCH_OUI_HEADER_SIZE) {
+ 			seq_printf(m, "branch oui read failed\n");
+ 			goto out;
+ 		}
+diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
+index 6abf7a2407e93..1545c50fd1c8f 100644
+--- a/drivers/gpu/drm/drm_bridge.c
++++ b/drivers/gpu/drm/drm_bridge.c
+@@ -847,8 +847,8 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
+ 				    struct drm_connector_state *conn_state,
+ 				    u32 out_bus_fmt)
+ {
++	unsigned int i, num_in_bus_fmts = 0;
+ 	struct drm_bridge_state *cur_state;
+-	unsigned int num_in_bus_fmts, i;
+ 	struct drm_bridge *prev_bridge;
+ 	u32 *in_bus_fmts;
+ 	int ret;
+@@ -969,7 +969,7 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
+ 	struct drm_connector *conn = conn_state->connector;
+ 	struct drm_encoder *encoder = bridge->encoder;
+ 	struct drm_bridge_state *last_bridge_state;
+-	unsigned int i, num_out_bus_fmts;
++	unsigned int i, num_out_bus_fmts = 0;
+ 	struct drm_bridge *last_bridge;
+ 	u32 *out_bus_fmts;
+ 	int ret = 0;
+diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
+index 8faad23dc1d81..ca2a6e6101dc8 100644
+--- a/drivers/gpu/drm/drm_ioctl.c
++++ b/drivers/gpu/drm/drm_ioctl.c
+@@ -472,7 +472,13 @@ EXPORT_SYMBOL(drm_invalid_op);
+  */
+ static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value)
+ {
+-	int len;
++	size_t len;
++
++	/* don't attempt to copy a NULL pointer */
++	if (WARN_ONCE(!value, "BUG: the value to copy was not set!")) {
++		*buf_len = 0;
++		return 0;
++	}
+ 
+ 	/* don't overflow userbuf */
+ 	len = strlen(value);
+diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
+index c40bde96cfdf0..c317ee9fa4458 100644
+--- a/drivers/gpu/drm/drm_mipi_dsi.c
++++ b/drivers/gpu/drm/drm_mipi_dsi.c
+@@ -346,6 +346,7 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv)
+ {
+ 	struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
+ 
++	mipi_dsi_detach(dsi);
+ 	mipi_dsi_device_unregister(dsi);
+ 
+ 	return 0;
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+index fc1728d46ac2a..8a0c0e0bb5bd2 100644
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c
+@@ -103,6 +103,12 @@ static const struct drm_dmi_panel_orientation_data lcd800x1280_rightside_up = {
+ 	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+ };
+ 
++static const struct drm_dmi_panel_orientation_data lcd1080x1920_leftside_up = {
++	.width = 1080,
++	.height = 1920,
++	.orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
++};
++
+ static const struct drm_dmi_panel_orientation_data lcd1200x1920_rightside_up = {
+ 	.width = 1200,
+ 	.height = 1920,
+@@ -128,6 +134,12 @@ static const struct dmi_system_id orientation_data[] = {
+ 		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
+ 		},
+ 		.driver_data = (void *)&lcd800x1280_rightside_up,
++	}, {	/* Anbernic Win600 */
++		.matches = {
++		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"),
++		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Win600"),
++		},
++		.driver_data = (void *)&lcd720x1280_rightside_up,
+ 	}, {	/* Asus T100HA */
+ 		.matches = {
+ 		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+@@ -152,6 +164,12 @@ static const struct dmi_system_id orientation_data[] = {
+ 		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYA NEO 2021"),
+ 		},
+ 		.driver_data = (void *)&lcd800x1280_rightside_up,
++	}, {	/* AYA NEO AIR */
++		.matches = {
++		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"),
++		  DMI_MATCH(DMI_BOARD_NAME, "AIR"),
++		},
++		.driver_data = (void *)&lcd1080x1920_leftside_up,
+ 	}, {	/* AYA NEO NEXT */
+ 		.matches = {
+ 		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
+diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
+index 6e80162632ddf..86a22c3766e52 100644
+--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
++++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
+@@ -2300,7 +2300,7 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
+ 		min_cdclk = max(min_cdclk, (int)crtc_state->pixel_rate);
+ 
+ 	/*
+-	 * HACK. Currently for TGL platforms we calculate
++	 * HACK. Currently for TGL/DG2 platforms we calculate
+ 	 * min_cdclk initially based on pixel_rate divided
+ 	 * by 2, accounting for also plane requirements,
+ 	 * however in some cases the lowest possible CDCLK
+@@ -2308,7 +2308,7 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
+ 	 * Explicitly stating here that this seems to be currently
+ 	 * rather a Hack, than final solution.
+ 	 */
+-	if (IS_TIGERLAKE(dev_priv)) {
++	if (IS_TIGERLAKE(dev_priv) || IS_DG2(dev_priv)) {
+ 		/*
+ 		 * Clamp to max_cdclk_freq in case pixel rate is higher,
+ 		 * in order not to break an 8K, but still leave W/A at place.
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
+index 0bcde53c50c61..1e29b1e6d1868 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
+@@ -1387,14 +1387,8 @@ kill_engines(struct i915_gem_engines *engines, bool exit, bool persistent)
+ 	 */
+ 	for_each_gem_engine(ce, engines, it) {
+ 		struct intel_engine_cs *engine;
+-		bool skip = false;
+ 
+-		if (exit)
+-			skip = intel_context_set_exiting(ce);
+-		else if (!persistent)
+-			skip = intel_context_exit_nonpersistent(ce, NULL);
+-
+-		if (skip)
++		if ((exit || !persistent) && intel_context_revoke(ce))
+ 			continue; /* Already marked. */
+ 
+ 		/*
+diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+index 1bb766c79dcbe..5aaacc53fa4ca 100644
+--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
++++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+@@ -247,6 +247,7 @@ err_scratch1:
+ 	i915_gem_object_put(vm->scratch[1]);
+ err_scratch0:
+ 	i915_gem_object_put(vm->scratch[0]);
++	vm->scratch[0] = NULL;
+ 	return ret;
+ }
+ 
+@@ -268,9 +269,10 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
+ 	gen6_ppgtt_free_pd(ppgtt);
+ 	free_scratch(vm);
+ 
+-	mutex_destroy(&ppgtt->flush);
++	if (ppgtt->base.pd)
++		free_pd(&ppgtt->base.vm, ppgtt->base.pd);
+ 
+-	free_pd(&ppgtt->base.vm, ppgtt->base.pd);
++	mutex_destroy(&ppgtt->flush);
+ }
+ 
+ static void pd_vma_bind(struct i915_address_space *vm,
+@@ -449,19 +451,17 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt)
+ 
+ 	err = gen6_ppgtt_init_scratch(ppgtt);
+ 	if (err)
+-		goto err_free;
++		goto err_put;
+ 
+ 	ppgtt->base.pd = gen6_alloc_top_pd(ppgtt);
+ 	if (IS_ERR(ppgtt->base.pd)) {
+ 		err = PTR_ERR(ppgtt->base.pd);
+-		goto err_scratch;
++		goto err_put;
+ 	}
+ 
+ 	return &ppgtt->base;
+ 
+-err_scratch:
+-	free_scratch(&ppgtt->base.vm);
+-err_free:
+-	kfree(ppgtt);
++err_put:
++	i915_vm_put(&ppgtt->base.vm);
+ 	return ERR_PTR(err);
+ }
+diff --git a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
+index c7bd5d71b03e5..2128b7a72a257 100644
+--- a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
++++ b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
+@@ -196,7 +196,10 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
+ 	if (intel_vgpu_active(vm->i915))
+ 		gen8_ppgtt_notify_vgt(ppgtt, false);
+ 
+-	__gen8_ppgtt_cleanup(vm, ppgtt->pd, gen8_pd_top_count(vm), vm->top);
++	if (ppgtt->pd)
++		__gen8_ppgtt_cleanup(vm, ppgtt->pd,
++				     gen8_pd_top_count(vm), vm->top);
++
+ 	free_scratch(vm);
+ }
+ 
+@@ -803,8 +806,10 @@ static int gen8_init_scratch(struct i915_address_space *vm)
+ 		struct drm_i915_gem_object *obj;
+ 
+ 		obj = vm->alloc_pt_dma(vm, I915_GTT_PAGE_SIZE_4K);
+-		if (IS_ERR(obj))
++		if (IS_ERR(obj)) {
++			ret = PTR_ERR(obj);
+ 			goto free_scratch;
++		}
+ 
+ 		ret = map_pt_dma(vm, obj);
+ 		if (ret) {
+@@ -823,7 +828,8 @@ static int gen8_init_scratch(struct i915_address_space *vm)
+ free_scratch:
+ 	while (i--)
+ 		i915_gem_object_put(vm->scratch[i]);
+-	return -ENOMEM;
++	vm->scratch[0] = NULL;
++	return ret;
+ }
+ 
+ static int gen8_preallocate_top_level_pdp(struct i915_ppgtt *ppgtt)
+@@ -901,6 +907,7 @@ err_pd:
+ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt,
+ 				     unsigned long lmem_pt_obj_flags)
+ {
++	struct i915_page_directory *pd;
+ 	struct i915_ppgtt *ppgtt;
+ 	int err;
+ 
+@@ -946,21 +953,7 @@ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt,
+ 		ppgtt->vm.alloc_scratch_dma = alloc_pt_dma;
+ 	}
+ 
+-	err = gen8_init_scratch(&ppgtt->vm);
+-	if (err)
+-		goto err_free;
+-
+-	ppgtt->pd = gen8_alloc_top_pd(&ppgtt->vm);
+-	if (IS_ERR(ppgtt->pd)) {
+-		err = PTR_ERR(ppgtt->pd);
+-		goto err_free_scratch;
+-	}
+-
+-	if (!i915_vm_is_4lvl(&ppgtt->vm)) {
+-		err = gen8_preallocate_top_level_pdp(ppgtt);
+-		if (err)
+-			goto err_free_pd;
+-	}
++	ppgtt->vm.pte_encode = gen8_pte_encode;
+ 
+ 	ppgtt->vm.bind_async_flags = I915_VMA_LOCAL_BIND;
+ 	ppgtt->vm.insert_entries = gen8_ppgtt_insert;
+@@ -971,22 +964,31 @@ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt,
+ 	ppgtt->vm.allocate_va_range = gen8_ppgtt_alloc;
+ 	ppgtt->vm.clear_range = gen8_ppgtt_clear;
+ 	ppgtt->vm.foreach = gen8_ppgtt_foreach;
++	ppgtt->vm.cleanup = gen8_ppgtt_cleanup;
+ 
+-	ppgtt->vm.pte_encode = gen8_pte_encode;
++	err = gen8_init_scratch(&ppgtt->vm);
++	if (err)
++		goto err_put;
++
++	pd = gen8_alloc_top_pd(&ppgtt->vm);
++	if (IS_ERR(pd)) {
++		err = PTR_ERR(pd);
++		goto err_put;
++	}
++	ppgtt->pd = pd;
++
++	if (!i915_vm_is_4lvl(&ppgtt->vm)) {
++		err = gen8_preallocate_top_level_pdp(ppgtt);
++		if (err)
++			goto err_put;
++	}
+ 
+ 	if (intel_vgpu_active(gt->i915))
+ 		gen8_ppgtt_notify_vgt(ppgtt, true);
+ 
+-	ppgtt->vm.cleanup = gen8_ppgtt_cleanup;
+-
+ 	return ppgtt;
+ 
+-err_free_pd:
+-	__gen8_ppgtt_cleanup(&ppgtt->vm, ppgtt->pd,
+-			     gen8_pd_top_count(&ppgtt->vm), ppgtt->vm.top);
+-err_free_scratch:
+-	free_scratch(&ppgtt->vm);
+-err_free:
+-	kfree(ppgtt);
++err_put:
++	i915_vm_put(&ppgtt->vm);
+ 	return ERR_PTR(err);
+ }
+diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c
+index 654a092ed3d69..e94365b08f1ef 100644
+--- a/drivers/gpu/drm/i915/gt/intel_context.c
++++ b/drivers/gpu/drm/i915/gt/intel_context.c
+@@ -614,13 +614,12 @@ bool intel_context_ban(struct intel_context *ce, struct i915_request *rq)
+ 	return ret;
+ }
+ 
+-bool intel_context_exit_nonpersistent(struct intel_context *ce,
+-				      struct i915_request *rq)
++bool intel_context_revoke(struct intel_context *ce)
+ {
+ 	bool ret = intel_context_set_exiting(ce);
+ 
+ 	if (ce->ops->revoke)
+-		ce->ops->revoke(ce, rq, ce->engine->props.preempt_timeout_ms);
++		ce->ops->revoke(ce, NULL, ce->engine->props.preempt_timeout_ms);
+ 
+ 	return ret;
+ }
+diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h
+index 8e2d70630c49e..be09fb2e883a5 100644
+--- a/drivers/gpu/drm/i915/gt/intel_context.h
++++ b/drivers/gpu/drm/i915/gt/intel_context.h
+@@ -329,8 +329,7 @@ static inline bool intel_context_set_exiting(struct intel_context *ce)
+ 	return test_and_set_bit(CONTEXT_EXITING, &ce->flags);
+ }
+ 
+-bool intel_context_exit_nonpersistent(struct intel_context *ce,
+-				      struct i915_request *rq);
++bool intel_context_revoke(struct intel_context *ce);
+ 
+ static inline bool
+ intel_context_force_single_submission(const struct intel_context *ce)
+diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
+index 15a915bb4088e..e717160135d7d 100644
+--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
++++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
+@@ -1267,10 +1267,16 @@ bool i915_ggtt_resume_vm(struct i915_address_space *vm)
+ 			atomic_read(&vma->flags) & I915_VMA_BIND_MASK;
+ 
+ 		GEM_BUG_ON(!was_bound);
+-		if (!retained_ptes)
++		if (!retained_ptes) {
++			/*
++			 * Clear the bound flags of the vma resource to allow
++			 * ptes to be repopulated.
++			 */
++			vma->resource->bound_flags = 0;
+ 			vma->ops->bind_vma(vm, NULL, vma->resource,
+ 					   obj ? obj->cache_level : 0,
+ 					   was_bound);
++		}
+ 		if (obj) { /* only used during resume => exclusive access */
+ 			write_domain_objs |= fetch_and_zero(&obj->write_domain);
+ 			obj->read_domains |= I915_GEM_DOMAIN_GTT;
+diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c
+index b67831833c9a3..2eaeba14319e9 100644
+--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
++++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
+@@ -405,6 +405,9 @@ void free_scratch(struct i915_address_space *vm)
+ {
+ 	int i;
+ 
++	if (!vm->scratch[0])
++		return;
++
+ 	for (i = 0; i <= vm->top; i++)
+ 		i915_gem_object_put(vm->scratch[i]);
+ }
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+index 3e91f44829e92..fe179146d51b9 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+@@ -684,7 +684,7 @@ static int __guc_add_request(struct intel_guc *guc, struct i915_request *rq)
+ 	 * Corner case where requests were sitting in the priority list or a
+ 	 * request resubmitted after the context was banned.
+ 	 */
+-	if (unlikely(intel_context_is_banned(ce))) {
++	if (unlikely(!intel_context_is_schedulable(ce))) {
+ 		i915_request_put(i915_request_mark_eio(rq));
+ 		intel_engine_signal_breadcrumbs(ce->engine);
+ 		return 0;
+@@ -870,15 +870,15 @@ static int guc_wq_item_append(struct intel_guc *guc,
+ 			      struct i915_request *rq)
+ {
+ 	struct intel_context *ce = request_to_scheduling_context(rq);
+-	int ret = 0;
++	int ret;
+ 
+-	if (likely(!intel_context_is_banned(ce))) {
+-		ret = __guc_wq_item_append(rq);
++	if (unlikely(!intel_context_is_schedulable(ce)))
++		return 0;
+ 
+-		if (unlikely(ret == -EBUSY)) {
+-			guc->stalled_request = rq;
+-			guc->submission_stall_reason = STALL_MOVE_LRC_TAIL;
+-		}
++	ret = __guc_wq_item_append(rq);
++	if (unlikely(ret == -EBUSY)) {
++		guc->stalled_request = rq;
++		guc->submission_stall_reason = STALL_MOVE_LRC_TAIL;
+ 	}
+ 
+ 	return ret;
+@@ -897,7 +897,7 @@ static bool multi_lrc_submit(struct i915_request *rq)
+ 	 * submitting all the requests generated in parallel.
+ 	 */
+ 	return test_bit(I915_FENCE_FLAG_SUBMIT_PARALLEL, &rq->fence.flags) ||
+-		intel_context_is_banned(ce);
++	       !intel_context_is_schedulable(ce);
+ }
+ 
+ static int guc_dequeue_one_context(struct intel_guc *guc)
+@@ -966,7 +966,7 @@ register_context:
+ 		struct intel_context *ce = request_to_scheduling_context(last);
+ 
+ 		if (unlikely(!ctx_id_mapped(guc, ce->guc_id.id) &&
+-			     !intel_context_is_banned(ce))) {
++			     intel_context_is_schedulable(ce))) {
+ 			ret = try_context_registration(ce, false);
+ 			if (unlikely(ret == -EPIPE)) {
+ 				goto deadlk;
+@@ -1576,7 +1576,7 @@ static void guc_reset_state(struct intel_context *ce, u32 head, bool scrub)
+ {
+ 	struct intel_engine_cs *engine = __context_to_physical_engine(ce);
+ 
+-	if (intel_context_is_banned(ce))
++	if (!intel_context_is_schedulable(ce))
+ 		return;
+ 
+ 	GEM_BUG_ON(!intel_context_is_pinned(ce));
+@@ -4434,12 +4434,12 @@ static void guc_handle_context_reset(struct intel_guc *guc,
+ {
+ 	trace_intel_context_reset(ce);
+ 
+-	if (likely(!intel_context_is_banned(ce))) {
++	if (likely(intel_context_is_schedulable(ce))) {
+ 		capture_error_state(guc, ce);
+ 		guc_context_replay(ce);
+ 	} else {
+ 		drm_info(&guc_to_gt(guc)->i915->drm,
+-			 "Ignoring context reset notification of banned context 0x%04X on %s",
++			 "Ignoring context reset notification of exiting context 0x%04X on %s",
+ 			 ce->guc_id.id, ce->engine->name);
+ 	}
+ }
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 9fe4b583cc28a..bf01e0191e542 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -5308,10 +5308,22 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
+ 		      modifier == I915_FORMAT_MOD_4_TILED ||
+ 		      modifier == I915_FORMAT_MOD_Yf_TILED ||
+ 		      modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+-		      modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
++		      modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
++		      modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
++		      modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
++		      modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
++		      modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
++		      modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
++		      modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
+ 	wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED;
+ 	wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
+-			 modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
++			 modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
++			 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
++			 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
++			 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
++			 modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
++			 modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
++			 modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
+ 	wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
+ 
+ 	wp->width = width;
+diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
+index bd4ca11d3ff53..86b90d0f5780a 100644
+--- a/drivers/gpu/drm/meson/meson_drv.c
++++ b/drivers/gpu/drm/meson/meson_drv.c
+@@ -388,10 +388,14 @@ static void meson_drv_unbind(struct device *dev)
+ 	drm_dev_unregister(drm);
+ 	drm_kms_helper_poll_fini(drm);
+ 	drm_atomic_helper_shutdown(drm);
+-	component_unbind_all(dev, drm);
+ 	free_irq(priv->vsync_irq, drm);
+ 	drm_dev_put(drm);
+ 
++	meson_encoder_hdmi_remove(priv);
++	meson_encoder_cvbs_remove(priv);
++
++	component_unbind_all(dev, drm);
++
+ 	if (priv->afbcd.ops)
+ 		priv->afbcd.ops->exit(priv);
+ }
+@@ -493,6 +497,13 @@ static int meson_drv_probe(struct platform_device *pdev)
+ 	return 0;
+ };
+ 
++static int meson_drv_remove(struct platform_device *pdev)
++{
++	component_master_del(&pdev->dev, &meson_drv_master_ops);
++
++	return 0;
++}
++
+ static struct meson_drm_match_data meson_drm_gxbb_data = {
+ 	.compat = VPU_COMPATIBLE_GXBB,
+ };
+@@ -530,6 +541,7 @@ static const struct dev_pm_ops meson_drv_pm_ops = {
+ 
+ static struct platform_driver meson_drm_platform_driver = {
+ 	.probe      = meson_drv_probe,
++	.remove     = meson_drv_remove,
+ 	.shutdown   = meson_drv_shutdown,
+ 	.driver     = {
+ 		.name	= "meson-drm",
+diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
+index 177dac3ca3bea..c62ee358456fa 100644
+--- a/drivers/gpu/drm/meson/meson_drv.h
++++ b/drivers/gpu/drm/meson/meson_drv.h
+@@ -25,6 +25,12 @@ enum vpu_compatible {
+ 	VPU_COMPATIBLE_G12A = 3,
+ };
+ 
++enum {
++	MESON_ENC_CVBS = 0,
++	MESON_ENC_HDMI,
++	MESON_ENC_LAST,
++};
++
+ struct meson_drm_match_data {
+ 	enum vpu_compatible compat;
+ 	struct meson_afbcd_ops *afbcd_ops;
+@@ -51,6 +57,7 @@ struct meson_drm {
+ 	struct drm_crtc *crtc;
+ 	struct drm_plane *primary_plane;
+ 	struct drm_plane *overlay_plane;
++	void *encoders[MESON_ENC_LAST];
+ 
+ 	const struct meson_drm_soc_limits *limits;
+ 
+diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+index 8110a6e39320f..5675bc2a92cf8 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
++++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+@@ -281,5 +281,18 @@ int meson_encoder_cvbs_init(struct meson_drm *priv)
+ 	}
+ 	drm_connector_attach_encoder(connector, &meson_encoder_cvbs->encoder);
+ 
++	priv->encoders[MESON_ENC_CVBS] = meson_encoder_cvbs;
++
+ 	return 0;
+ }
++
++void meson_encoder_cvbs_remove(struct meson_drm *priv)
++{
++	struct meson_encoder_cvbs *meson_encoder_cvbs;
++
++	if (priv->encoders[MESON_ENC_CVBS]) {
++		meson_encoder_cvbs = priv->encoders[MESON_ENC_CVBS];
++		drm_bridge_remove(&meson_encoder_cvbs->bridge);
++		drm_bridge_remove(meson_encoder_cvbs->next_bridge);
++	}
++}
+diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.h b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
+index 61d9d183ce7fb..09710fec3c660 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.h
++++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
+@@ -25,5 +25,6 @@ struct meson_cvbs_mode {
+ extern struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT];
+ 
+ int meson_encoder_cvbs_init(struct meson_drm *priv);
++void meson_encoder_cvbs_remove(struct meson_drm *priv);
+ 
+ #endif /* __MESON_VENC_CVBS_H */
+diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+index 2f616c55c2718..53231bfdf7e24 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c
++++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c
+@@ -452,6 +452,8 @@ int meson_encoder_hdmi_init(struct meson_drm *priv)
+ 		meson_encoder_hdmi->cec_notifier = notifier;
+ 	}
+ 
++	priv->encoders[MESON_ENC_HDMI] = meson_encoder_hdmi;
++
+ 	dev_dbg(priv->dev, "HDMI encoder initialized\n");
+ 
+ 	return 0;
+@@ -460,3 +462,14 @@ err_put_node:
+ 	of_node_put(remote);
+ 	return ret;
+ }
++
++void meson_encoder_hdmi_remove(struct meson_drm *priv)
++{
++	struct meson_encoder_hdmi *meson_encoder_hdmi;
++
++	if (priv->encoders[MESON_ENC_HDMI]) {
++		meson_encoder_hdmi = priv->encoders[MESON_ENC_HDMI];
++		drm_bridge_remove(&meson_encoder_hdmi->bridge);
++		drm_bridge_remove(meson_encoder_hdmi->next_bridge);
++	}
++}
+diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.h b/drivers/gpu/drm/meson/meson_encoder_hdmi.h
+index ed19494f09563..a6cd38eb5f71c 100644
+--- a/drivers/gpu/drm/meson/meson_encoder_hdmi.h
++++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.h
+@@ -8,5 +8,6 @@
+ #define __MESON_ENCODER_HDMI_H
+ 
+ int meson_encoder_hdmi_init(struct meson_drm *priv);
++void meson_encoder_hdmi_remove(struct meson_drm *priv);
+ 
+ #endif /* __MESON_ENCODER_HDMI_H */
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+index 008e1420e6e55..c99c7a218ddb3 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+@@ -384,12 +384,9 @@ static int dpu_kms_parse_data_bus_icc_path(struct dpu_kms *dpu_kms)
+ 	struct icc_path *path1;
+ 	struct drm_device *dev = dpu_kms->dev;
+ 	struct device *dpu_dev = dev->dev;
+-	struct device *mdss_dev = dpu_dev->parent;
+ 
+-	/* Interconnects are a part of MDSS device tree binding, not the
+-	 * MDP/DPU device. */
+-	path0 = of_icc_get(mdss_dev, "mdp0-mem");
+-	path1 = of_icc_get(mdss_dev, "mdp1-mem");
++	path0 = msm_icc_get(dpu_dev, "mdp0-mem");
++	path1 = msm_icc_get(dpu_dev, "mdp1-mem");
+ 
+ 	if (IS_ERR_OR_NULL(path0))
+ 		return PTR_ERR_OR_ZERO(path0);
+@@ -826,12 +823,10 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
+ 	_dpu_kms_mmu_destroy(dpu_kms);
+ 
+ 	if (dpu_kms->catalog) {
+-		for (i = 0; i < dpu_kms->catalog->vbif_count; i++) {
+-			u32 vbif_idx = dpu_kms->catalog->vbif[i].id;
+-
+-			if ((vbif_idx < VBIF_MAX) && dpu_kms->hw_vbif[vbif_idx]) {
+-				dpu_hw_vbif_destroy(dpu_kms->hw_vbif[vbif_idx]);
+-				dpu_kms->hw_vbif[vbif_idx] = NULL;
++		for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
++			if (dpu_kms->hw_vbif[i]) {
++				dpu_hw_vbif_destroy(dpu_kms->hw_vbif[i]);
++				dpu_kms->hw_vbif[i] = NULL;
+ 			}
+ 		}
+ 	}
+@@ -1113,7 +1108,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
+ 	for (i = 0; i < dpu_kms->catalog->vbif_count; i++) {
+ 		u32 vbif_idx = dpu_kms->catalog->vbif[i].id;
+ 
+-		dpu_kms->hw_vbif[i] = dpu_hw_vbif_init(vbif_idx,
++		dpu_kms->hw_vbif[vbif_idx] = dpu_hw_vbif_init(vbif_idx,
+ 				dpu_kms->vbif[vbif_idx], dpu_kms->catalog);
+ 		if (IS_ERR_OR_NULL(dpu_kms->hw_vbif[vbif_idx])) {
+ 			rc = PTR_ERR(dpu_kms->hw_vbif[vbif_idx]);
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+index 21d20373eb8b3..a18fb649301c9 100644
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+@@ -11,6 +11,14 @@
+ #include "dpu_hw_vbif.h"
+ #include "dpu_trace.h"
+ 
++static struct dpu_hw_vbif *dpu_get_vbif(struct dpu_kms *dpu_kms, enum dpu_vbif vbif_idx)
++{
++	if (vbif_idx < ARRAY_SIZE(dpu_kms->hw_vbif))
++		return dpu_kms->hw_vbif[vbif_idx];
++
++	return NULL;
++}
++
+ /**
+  * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt
+  * @vbif:	Pointer to hardware vbif driver
+@@ -148,20 +156,15 @@ exit:
+ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,
+ 		struct dpu_vbif_set_ot_params *params)
+ {
+-	struct dpu_hw_vbif *vbif = NULL;
++	struct dpu_hw_vbif *vbif;
+ 	struct dpu_hw_mdp *mdp;
+ 	bool forced_on = false;
+ 	u32 ot_lim;
+-	int ret, i;
++	int ret;
+ 
+ 	mdp = dpu_kms->hw_mdp;
+ 
+-	for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
+-		if (dpu_kms->hw_vbif[i] &&
+-				dpu_kms->hw_vbif[i]->idx == params->vbif_idx)
+-			vbif = dpu_kms->hw_vbif[i];
+-	}
+-
++	vbif = dpu_get_vbif(dpu_kms, params->vbif_idx);
+ 	if (!vbif || !mdp) {
+ 		DRM_DEBUG_ATOMIC("invalid arguments vbif %d mdp %d\n",
+ 				vbif != NULL, mdp != NULL);
+@@ -204,7 +207,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,
+ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
+ 		struct dpu_vbif_set_qos_params *params)
+ {
+-	struct dpu_hw_vbif *vbif = NULL;
++	struct dpu_hw_vbif *vbif;
+ 	struct dpu_hw_mdp *mdp;
+ 	bool forced_on = false;
+ 	const struct dpu_vbif_qos_tbl *qos_tbl;
+@@ -216,13 +219,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
+ 	}
+ 	mdp = dpu_kms->hw_mdp;
+ 
+-	for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
+-		if (dpu_kms->hw_vbif[i] &&
+-				dpu_kms->hw_vbif[i]->idx == params->vbif_idx) {
+-			vbif = dpu_kms->hw_vbif[i];
+-			break;
+-		}
+-	}
++	vbif = dpu_get_vbif(dpu_kms, params->vbif_idx);
+ 
+ 	if (!vbif || !vbif->cap) {
+ 		DPU_ERROR("invalid vbif %d\n", params->vbif_idx);
+diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+index d2a48caf9d27e..b0d21838a1343 100644
+--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+@@ -902,12 +902,9 @@ fail:
+ 
+ static int mdp5_setup_interconnect(struct platform_device *pdev)
+ {
+-	/* Interconnects are a part of MDSS device tree binding, not the
+-	 * MDP5 device. */
+-	struct device *mdss_dev = pdev->dev.parent;
+-	struct icc_path *path0 = of_icc_get(mdss_dev, "mdp0-mem");
+-	struct icc_path *path1 = of_icc_get(mdss_dev, "mdp1-mem");
+-	struct icc_path *path_rot = of_icc_get(mdss_dev, "rotator-mem");
++	struct icc_path *path0 = msm_icc_get(&pdev->dev, "mdp0-mem");
++	struct icc_path *path1 = msm_icc_get(&pdev->dev, "mdp1-mem");
++	struct icc_path *path_rot = msm_icc_get(&pdev->dev, "rotator-mem");
+ 
+ 	if (IS_ERR(path0))
+ 		return PTR_ERR(path0);
+diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c
+index 7257515871a9f..676279d0ca8d9 100644
+--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
++++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
+@@ -431,7 +431,7 @@ void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog,
+ 
+ 	if (rate == link_rate_hbr3)
+ 		pixel_div = 6;
+-	else if (rate == 1620000 || rate == 270000)
++	else if (rate == 162000 || rate == 270000)
+ 		pixel_div = 2;
+ 	else if (rate == link_rate_hbr2)
+ 		pixel_div = 4;
+diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
+index 16884db272deb..0759e2d99f59c 100644
+--- a/drivers/gpu/drm/msm/msm_drv.c
++++ b/drivers/gpu/drm/msm/msm_drv.c
+@@ -1244,10 +1244,15 @@ void msm_drv_shutdown(struct platform_device *pdev)
+ 	struct msm_drm_private *priv = platform_get_drvdata(pdev);
+ 	struct drm_device *drm = priv ? priv->dev : NULL;
+ 
+-	if (!priv || !priv->kms)
+-		return;
+-
+-	drm_atomic_helper_shutdown(drm);
++	/*
++	 * Shutdown the hw if we're far enough along where things might be on.
++	 * If we run this too early, we'll end up panicking in any variety of
++	 * places. Since we don't register the drm device until late in
++	 * msm_drm_init, drm_dev->registered is used as an indicator that the
++	 * shutdown will be successful.
++	 */
++	if (drm && drm->registered)
++		drm_atomic_helper_shutdown(drm);
+ }
+ 
+ static struct platform_driver msm_platform_driver = {
+diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
+index b3689a2d27d72..80da0d3cfdc13 100644
+--- a/drivers/gpu/drm/msm/msm_drv.h
++++ b/drivers/gpu/drm/msm/msm_drv.h
+@@ -433,6 +433,8 @@ void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name,
+ 		phys_addr_t *size);
+ void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name);
+ 
++struct icc_path *msm_icc_get(struct device *dev, const char *name);
++
+ #define msm_writel(data, addr) writel((data), (addr))
+ #define msm_readl(addr) readl((addr))
+ 
+diff --git a/drivers/gpu/drm/msm/msm_io_utils.c b/drivers/gpu/drm/msm/msm_io_utils.c
+index 7b504617833ad..d02cd29ce8299 100644
+--- a/drivers/gpu/drm/msm/msm_io_utils.c
++++ b/drivers/gpu/drm/msm/msm_io_utils.c
+@@ -5,6 +5,8 @@
+  * Author: Rob Clark <robdclark@gmail.com>
+  */
+ 
++#include <linux/interconnect.h>
++
+ #include "msm_drv.h"
+ 
+ /*
+@@ -124,3 +126,23 @@ void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
+ 	work->worker = worker;
+ 	kthread_init_work(&work->work, fn);
+ }
++
++struct icc_path *msm_icc_get(struct device *dev, const char *name)
++{
++	struct device *mdss_dev = dev->parent;
++	struct icc_path *path;
++
++	path = of_icc_get(dev, name);
++	if (path)
++		return path;
++
++	/*
++	 * If there are no interconnects attached to the corresponding device
++	 * node, of_icc_get() will return NULL.
++	 *
++	 * If the MDP5/DPU device node doesn't have interconnects, lookup the
++	 * path in the parent (MDSS) device.
++	 */
++	return of_icc_get(mdss_dev, name);
++
++}
+diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
+index e29175e4b44ce..07a327ad5e2a8 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
+@@ -281,8 +281,10 @@ nouveau_bo_alloc(struct nouveau_cli *cli, u64 *size, int *align, u32 domain,
+ 			break;
+ 	}
+ 
+-	if (WARN_ON(pi < 0))
++	if (WARN_ON(pi < 0)) {
++		kfree(nvbo);
+ 		return ERR_PTR(-EINVAL);
++	}
+ 
+ 	/* Disable compression if suitable settings couldn't be found. */
+ 	if (nvbo->comp && !vmm->page[pi].comp) {
+diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
+index 43a9d1e1cf719..8100c75ee7319 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
++++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
+@@ -504,7 +504,8 @@ nouveau_connector_set_encoder(struct drm_connector *connector,
+ 			connector->interlace_allowed =
+ 				nv_encoder->caps.dp_interlace;
+ 		else
+-			connector->interlace_allowed = true;
++			connector->interlace_allowed =
++				drm->client.device.info.family < NV_DEVICE_INFO_V0_VOLTA;
+ 		connector->doublescan_allowed = true;
+ 	} else
+ 	if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS ||
+diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c
+index 347488685f745..9608121e49b7e 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
++++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
+@@ -71,7 +71,6 @@ struct drm_gem_object *nouveau_gem_prime_import_sg_table(struct drm_device *dev,
+ 	ret = nouveau_bo_init(nvbo, size, align, NOUVEAU_GEM_DOMAIN_GART,
+ 			      sg, robj);
+ 	if (ret) {
+-		nouveau_bo_ref(NULL, &nvbo);
+ 		obj = ERR_PTR(ret);
+ 		goto unlock;
+ 	}
+diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
+index 0399f3390a0ad..c4febb8619103 100644
+--- a/drivers/gpu/drm/omapdrm/dss/dss.c
++++ b/drivers/gpu/drm/omapdrm/dss/dss.c
+@@ -1176,6 +1176,7 @@ static void __dss_uninit_ports(struct dss_device *dss, unsigned int num_ports)
+ 		default:
+ 			break;
+ 		}
++		of_node_put(port);
+ 	}
+ }
+ 
+@@ -1208,11 +1209,13 @@ static int dss_init_ports(struct dss_device *dss)
+ 		default:
+ 			break;
+ 		}
++		of_node_put(port);
+ 	}
+ 
+ 	return 0;
+ 
+ error:
++	of_node_put(port);
+ 	__dss_uninit_ports(dss, i);
+ 	return r;
+ }
+diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
+index a9043eacce97c..a582ddd583c24 100644
+--- a/drivers/gpu/drm/panel/Kconfig
++++ b/drivers/gpu/drm/panel/Kconfig
+@@ -165,8 +165,8 @@ config DRM_PANEL_ILITEK_IL9322
+ config DRM_PANEL_ILITEK_ILI9341
+ 	tristate "Ilitek ILI9341 240x320 QVGA panels"
+ 	depends on OF && SPI
+-	depends on DRM_KMS_HELPER
+-	depends on DRM_GEM_CMA_HELPER
++	select DRM_KMS_HELPER
++	select DRM_GEM_DMA_HELPER
+ 	depends on BACKLIGHT_CLASS_DEVICE
+ 	select DRM_MIPI_DBI
+ 	help
+diff --git a/drivers/gpu/drm/pl111/pl111_versatile.c b/drivers/gpu/drm/pl111/pl111_versatile.c
+index efb01a5545740..1b436b75fd396 100644
+--- a/drivers/gpu/drm/pl111/pl111_versatile.c
++++ b/drivers/gpu/drm/pl111/pl111_versatile.c
+@@ -404,6 +404,7 @@ static int pl111_vexpress_clcd_init(struct device *dev, struct device_node *np,
+ 		if (of_device_is_compatible(child, "arm,pl111")) {
+ 			has_coretile_clcd = true;
+ 			ct_clcd = child;
++			of_node_put(child);
+ 			break;
+ 		}
+ 		if (of_device_is_compatible(child, "arm,hdlcd")) {
+diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c b/drivers/gpu/drm/tests/drm_format_helper_test.c
+index 98583bf56044b..eefaba3aaea20 100644
+--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
++++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
+@@ -111,6 +111,21 @@ static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
+ 	return dst_pitch * drm_rect_height(clip);
+ }
+ 
++static u32 *le32buf_to_cpu(struct kunit *test, const u32 *buf, size_t buf_size)
++{
++	u32 *dst = NULL;
++	int n;
++
++	dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
++	if (!dst)
++		return NULL;
++
++	for (n = 0; n < buf_size; n++)
++		dst[n] = le32_to_cpu((__force __le32)buf[n]);
++
++	return dst;
++}
++
+ static void xrgb8888_to_rgb332_case_desc(struct xrgb8888_to_rgb332_case *t,
+ 					 char *desc)
+ {
+@@ -125,6 +140,7 @@ static void xrgb8888_to_rgb332_test(struct kunit *test)
+ 	const struct xrgb8888_to_rgb332_case *params = test->param_value;
+ 	size_t dst_size;
+ 	__u8 *dst = NULL;
++	__u32 *src = NULL;
+ 
+ 	struct drm_framebuffer fb = {
+ 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
+@@ -138,8 +154,11 @@ static void xrgb8888_to_rgb332_test(struct kunit *test)
+ 	dst = kunit_kzalloc(test, dst_size, GFP_KERNEL);
+ 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dst);
+ 
+-	drm_fb_xrgb8888_to_rgb332(dst, params->dst_pitch, params->xrgb8888,
+-				  &fb, &params->clip);
++	src = le32buf_to_cpu(test, params->xrgb8888, TEST_BUF_SIZE);
++	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, src);
++
++	drm_fb_xrgb8888_to_rgb332(dst, params->dst_pitch, src, &fb,
++				  &params->clip);
+ 	KUNIT_EXPECT_EQ(test, memcmp(dst, params->expected, dst_size), 0);
+ }
+ 
+diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c
+index 82364a0a7b180..490fa92a4dce3 100644
+--- a/drivers/gpu/drm/tiny/bochs.c
++++ b/drivers/gpu/drm/tiny/bochs.c
+@@ -309,6 +309,8 @@ static void bochs_hw_fini(struct drm_device *dev)
+ static void bochs_hw_blank(struct bochs_device *bochs, bool blank)
+ {
+ 	DRM_DEBUG_DRIVER("hw_blank %d\n", blank);
++	/* enable color bit (so VGA_IS1_RC access works) */
++	bochs_vga_writeb(bochs, VGA_MIS_W, VGA_MIS_COLOR);
+ 	/* discard ar_flip_flop */
+ 	(void)bochs_vga_readb(bochs, VGA_IS1_RC);
+ 	/* blank or unblank; we need only update index and set 0x20 */
+diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
+index e67c40a48fb46..b43e6ff06310f 100644
+--- a/drivers/gpu/drm/udl/udl_modeset.c
++++ b/drivers/gpu/drm/udl/udl_modeset.c
+@@ -382,9 +382,6 @@ udl_simple_display_pipe_enable(struct drm_simple_display_pipe *pipe,
+ 
+ 	udl_handle_damage(fb, &shadow_plane_state->data[0], 0, 0, fb->width, fb->height);
+ 
+-	if (!crtc_state->mode_changed)
+-		return;
+-
+ 	/* enable display */
+ 	udl_crtc_write_mode_to_hw(crtc);
+ }
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
+index 292d1b6a01b6f..6b8dfa1e7650d 100644
+--- a/drivers/gpu/drm/vc4/vc4_drv.c
++++ b/drivers/gpu/drm/vc4/vc4_drv.c
+@@ -267,6 +267,13 @@ static void vc4_match_add_drivers(struct device *dev,
+ 	}
+ }
+ 
++static void vc4_component_unbind_all(void *ptr)
++{
++	struct vc4_dev *vc4 = ptr;
++
++	component_unbind_all(vc4->dev, &vc4->base);
++}
++
+ static const struct of_device_id vc4_dma_range_matches[] = {
+ 	{ .compatible = "brcm,bcm2711-hvs" },
+ 	{ .compatible = "brcm,bcm2835-hvs" },
+@@ -310,6 +317,7 @@ static int vc4_drm_bind(struct device *dev)
+ 	if (IS_ERR(vc4))
+ 		return PTR_ERR(vc4);
+ 	vc4->is_vc5 = is_vc5;
++	vc4->dev = dev;
+ 
+ 	drm = &vc4->base;
+ 	platform_set_drvdata(pdev, drm);
+@@ -360,6 +368,10 @@ static int vc4_drm_bind(struct device *dev)
+ 	if (ret)
+ 		return ret;
+ 
++	ret = devm_add_action_or_reset(dev, vc4_component_unbind_all, vc4);
++	if (ret)
++		return ret;
++
+ 	ret = vc4_plane_create_additional_planes(drm);
+ 	if (ret)
+ 		goto unbind_all;
+@@ -380,8 +392,6 @@ static int vc4_drm_bind(struct device *dev)
+ 	return 0;
+ 
+ unbind_all:
+-	component_unbind_all(dev, drm);
+-
+ 	return ret;
+ }
+ 
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
+index 1beb96b77b8c6..950056b83843b 100644
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -76,6 +76,7 @@ struct vc4_perfmon {
+ 
+ struct vc4_dev {
+ 	struct drm_device base;
++	struct device *dev;
+ 
+ 	bool is_vc5;
+ 
+diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
+index 11fc3d6f66b1e..4e2250b8fa23e 100644
+--- a/drivers/gpu/drm/vc4/vc4_vec.c
++++ b/drivers/gpu/drm/vc4/vc4_vec.c
+@@ -256,7 +256,7 @@ static void vc4_vec_ntsc_j_mode_set(struct vc4_vec *vec)
+ static const struct drm_display_mode ntsc_mode = {
+ 	DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
+ 		 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
+-		 480, 480 + 3, 480 + 3 + 3, 480 + 3 + 3 + 16, 0,
++		 480, 480 + 7, 480 + 7 + 6, 525, 0,
+ 		 DRM_MODE_FLAG_INTERLACE)
+ };
+ 
+@@ -278,7 +278,7 @@ static void vc4_vec_pal_m_mode_set(struct vc4_vec *vec)
+ static const struct drm_display_mode pal_mode = {
+ 	DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
+ 		 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
+-		 576, 576 + 2, 576 + 2 + 3, 576 + 2 + 3 + 20, 0,
++		 576, 576 + 4, 576 + 4 + 6, 625, 0,
+ 		 DRM_MODE_FLAG_INTERLACE)
+ };
+ 
+diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
+index 5c7f198c07120..9ea7611a9e0fc 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_display.c
++++ b/drivers/gpu/drm/virtio/virtgpu_display.c
+@@ -349,6 +349,8 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev)
+ 	vgdev->ddev->mode_config.max_width = XRES_MAX;
+ 	vgdev->ddev->mode_config.max_height = YRES_MAX;
+ 
++	vgdev->ddev->mode_config.fb_modifiers_not_supported = true;
++
+ 	for (i = 0 ; i < vgdev->num_scanouts; ++i)
+ 		vgdev_output_init(vgdev, i);
+ 
+diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
+index 580a788098361..7db48d17ee3a8 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
++++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
+@@ -228,8 +228,10 @@ int virtio_gpu_array_lock_resv(struct virtio_gpu_object_array *objs)
+ 
+ 	for (i = 0; i < objs->nents; ++i) {
+ 		ret = dma_resv_reserve_fences(objs->objs[i]->resv, 1);
+-		if (ret)
++		if (ret) {
++			virtio_gpu_array_unlock_resv(objs);
+ 			return ret;
++		}
+ 	}
+ 	return ret;
+ }
+diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+index 9b2702116f93e..5d05093014ac3 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
++++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+@@ -47,7 +47,7 @@ static int virtio_gpu_fence_event_create(struct drm_device *dev,
+ 	struct virtio_gpu_fence_event *e = NULL;
+ 	int ret;
+ 
+-	if (!(vfpriv->ring_idx_mask & (1 << ring_idx)))
++	if (!(vfpriv->ring_idx_mask & BIT_ULL(ring_idx)))
+ 		return 0;
+ 
+ 	e = kzalloc(sizeof(*e), GFP_KERNEL);
+@@ -168,7 +168,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data,
+ 		 * array contains any fence from a foreign context.
+ 		 */
+ 		ret = 0;
+-		if (!dma_fence_match_context(in_fence, vgdev->fence_drv.context))
++		if (!dma_fence_match_context(in_fence, fence_ctx + ring_idx))
+ 			ret = dma_fence_wait(in_fence, true);
+ 
+ 		dma_fence_put(in_fence);
+diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
+index 1cc8f3fc8e4ba..75a159df0af66 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_object.c
++++ b/drivers/gpu/drm/virtio/virtgpu_object.c
+@@ -170,6 +170,7 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
+ 	shmem->pages = drm_gem_shmem_get_sg_table(&bo->base);
+ 	if (IS_ERR(shmem->pages)) {
+ 		drm_gem_shmem_unpin(&bo->base);
++		shmem->pages = NULL;
+ 		return PTR_ERR(shmem->pages);
+ 	}
+ 
+@@ -248,6 +249,8 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev,
+ 
+ 	ret = virtio_gpu_object_shmem_init(vgdev, bo, &ents, &nents);
+ 	if (ret != 0) {
++		if (fence)
++			virtio_gpu_array_unlock_resv(objs);
+ 		virtio_gpu_array_put_free(objs);
+ 		virtio_gpu_free_object(&shmem_obj->base);
+ 		return ret;
+diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
+index 6d3cc9e238a4a..7148f3813d8bd 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
++++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
+@@ -266,14 +266,14 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane,
+ }
+ 
+ static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane,
+-					struct drm_plane_state *old_state)
++					struct drm_plane_state *state)
+ {
+ 	struct virtio_gpu_framebuffer *vgfb;
+ 
+-	if (!plane->state->fb)
++	if (!state->fb)
+ 		return;
+ 
+-	vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
++	vgfb = to_virtio_gpu_framebuffer(state->fb);
+ 	if (vgfb->fence) {
+ 		dma_fence_put(&vgfb->fence->f);
+ 		vgfb->fence = NULL;
+diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
+index b7529b2b98832..1262fd0b3bef3 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
++++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
+@@ -597,7 +597,7 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
+ 	bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
+ 	struct virtio_gpu_object_shmem *shmem = to_virtio_gpu_shmem(bo);
+ 
+-	if (use_dma_api)
++	if (virtio_gpu_is_shmem(bo) && use_dma_api)
+ 		dma_sync_sgtable_for_device(vgdev->vdev->dev.parent,
+ 					    shmem->pages, DMA_TO_DEVICE);
+ 
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+index 2aceac7856e21..089046fa21bea 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+@@ -1076,6 +1076,7 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data,
+ 
+ 	if (desc_len < 0) {
+ 		atomic_set(&dev_priv->mksstat_user_pids[slot], 0);
++		__free_page(page);
+ 		return -EFAULT;
+ 	}
+ 
+diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
+index 6ce92830b5d1f..c4308d4988dc0 100644
+--- a/drivers/hid/Kconfig
++++ b/drivers/hid/Kconfig
+@@ -1141,6 +1141,12 @@ config HID_TOPSEED
+ 	Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic
+ 	CLLRCMCE remote control.
+ 
++config HID_TOPRE
++	tristate "Topre REALFORCE keyboards"
++	depends on HID
++	help
++	  Say Y for N-key rollover support on Topre REALFORCE R2 108 key keyboards.
++
+ config HID_THINGM
+ 	tristate "ThingM blink(1) USB RGB LED"
+ 	depends on HID
+diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
+index b0bef80981394..bccaec0d77d36 100644
+--- a/drivers/hid/Makefile
++++ b/drivers/hid/Makefile
+@@ -123,6 +123,7 @@ obj-$(CONFIG_HID_GREENASIA)	+= hid-gaff.o
+ obj-$(CONFIG_HID_THRUSTMASTER)	+= hid-tmff.o hid-thrustmaster.o
+ obj-$(CONFIG_HID_TIVO)		+= hid-tivo.o
+ obj-$(CONFIG_HID_TOPSEED)	+= hid-topseed.o
++obj-$(CONFIG_HID_TOPRE)	+= hid-topre.o
+ obj-$(CONFIG_HID_TWINHAN)	+= hid-twinhan.o
+ obj-$(CONFIG_HID_U2FZERO)	+= hid-u2fzero.o
+ hid-uclogic-objs		:= hid-uclogic-core.o \
+diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
+index 70436f9fad2f2..33e039e1e01d4 100644
+--- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
++++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
+@@ -110,6 +110,8 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata)
+ 	amd_sfh1_1_set_desc_ops(mp2_ops);
+ 
+ 	cl_data->num_hid_devices = amd_sfh_get_sensor_num(privdata, &cl_data->sensor_idx[0]);
++	if (cl_data->num_hid_devices == 0)
++		return -ENODEV;
+ 
+ 	INIT_DELAYED_WORK(&cl_data->work, amd_sfh_work);
+ 	INIT_DELAYED_WORK(&cl_data->work_buffer, amd_sfh_work_buffer);
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index f80d6193fca6e..50bab12d9476f 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -1231,6 +1231,9 @@
+ #define USB_DEVICE_ID_TIVO_SLIDE	0x1201
+ #define USB_DEVICE_ID_TIVO_SLIDE_PRO	0x1203
+ 
++#define USB_VENDOR_ID_TOPRE			0x0853
++#define USB_DEVICE_ID_TOPRE_REALFORCE_R2_108			0x0148
++
+ #define USB_VENDOR_ID_TOPSEED		0x0766
+ #define USB_DEVICE_ID_TOPSEED_CYBERLINK	0x0204
+ 
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index 2e72922e36f56..91a4d3fc30e08 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -1186,7 +1186,7 @@ static void mt_touch_report(struct hid_device *hid,
+ 	int contact_count = -1;
+ 
+ 	/* sticky fingers release in progress, abort */
+-	if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
++	if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
+ 		return;
+ 
+ 	scantime = *app->scantime;
+@@ -1267,7 +1267,7 @@ static void mt_touch_report(struct hid_device *hid,
+ 			del_timer(&td->release_timer);
+ 	}
+ 
+-	clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
++	clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
+ }
+ 
+ static int mt_touch_input_configured(struct hid_device *hdev,
+@@ -1699,11 +1699,11 @@ static void mt_expired_timeout(struct timer_list *t)
+ 	 * An input report came in just before we release the sticky fingers,
+ 	 * it will take care of the sticky fingers.
+ 	 */
+-	if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
++	if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
+ 		return;
+ 	if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags))
+ 		mt_release_contacts(hdev);
+-	clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
++	clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
+ }
+ 
+ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
+diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c
+index 6028af3c3aae5..c3774a468b229 100644
+--- a/drivers/hid/hid-nintendo.c
++++ b/drivers/hid/hid-nintendo.c
+@@ -760,12 +760,31 @@ static int joycon_read_stick_calibration(struct joycon_ctlr *ctlr, u16 cal_addr,
+ 	cal_y->max = cal_y->center + y_max_above;
+ 	cal_y->min = cal_y->center - y_min_below;
+ 
+-	return 0;
++	/* check if calibration values are plausible */
++	if (cal_x->min >= cal_x->center || cal_x->center >= cal_x->max ||
++	    cal_y->min >= cal_y->center || cal_y->center >= cal_y->max)
++		ret = -EINVAL;
++
++	return ret;
+ }
+ 
+ static const u16 DFLT_STICK_CAL_CEN = 2000;
+ static const u16 DFLT_STICK_CAL_MAX = 3500;
+ static const u16 DFLT_STICK_CAL_MIN = 500;
++static void joycon_use_default_calibration(struct hid_device *hdev,
++					   struct joycon_stick_cal *cal_x,
++					   struct joycon_stick_cal *cal_y,
++					   const char *stick, int ret)
++{
++	hid_warn(hdev,
++		 "Failed to read %s stick cal, using defaults; e=%d\n",
++		 stick, ret);
++
++	cal_x->center = cal_y->center = DFLT_STICK_CAL_CEN;
++	cal_x->max = cal_y->max = DFLT_STICK_CAL_MAX;
++	cal_x->min = cal_y->min = DFLT_STICK_CAL_MIN;
++}
++
+ static int joycon_request_calibration(struct joycon_ctlr *ctlr)
+ {
+ 	u16 left_stick_addr = JC_CAL_FCT_DATA_LEFT_ADDR;
+@@ -793,38 +812,24 @@ static int joycon_request_calibration(struct joycon_ctlr *ctlr)
+ 					    &ctlr->left_stick_cal_x,
+ 					    &ctlr->left_stick_cal_y,
+ 					    true);
+-	if (ret) {
+-		hid_warn(ctlr->hdev,
+-			 "Failed to read left stick cal, using dflts; e=%d\n",
+-			 ret);
+-
+-		ctlr->left_stick_cal_x.center = DFLT_STICK_CAL_CEN;
+-		ctlr->left_stick_cal_x.max = DFLT_STICK_CAL_MAX;
+-		ctlr->left_stick_cal_x.min = DFLT_STICK_CAL_MIN;
+ 
+-		ctlr->left_stick_cal_y.center = DFLT_STICK_CAL_CEN;
+-		ctlr->left_stick_cal_y.max = DFLT_STICK_CAL_MAX;
+-		ctlr->left_stick_cal_y.min = DFLT_STICK_CAL_MIN;
+-	}
++	if (ret)
++		joycon_use_default_calibration(ctlr->hdev,
++					       &ctlr->left_stick_cal_x,
++					       &ctlr->left_stick_cal_y,
++					       "left", ret);
+ 
+ 	/* read the right stick calibration data */
+ 	ret = joycon_read_stick_calibration(ctlr, right_stick_addr,
+ 					    &ctlr->right_stick_cal_x,
+ 					    &ctlr->right_stick_cal_y,
+ 					    false);
+-	if (ret) {
+-		hid_warn(ctlr->hdev,
+-			 "Failed to read right stick cal, using dflts; e=%d\n",
+-			 ret);
+-
+-		ctlr->right_stick_cal_x.center = DFLT_STICK_CAL_CEN;
+-		ctlr->right_stick_cal_x.max = DFLT_STICK_CAL_MAX;
+-		ctlr->right_stick_cal_x.min = DFLT_STICK_CAL_MIN;
+ 
+-		ctlr->right_stick_cal_y.center = DFLT_STICK_CAL_CEN;
+-		ctlr->right_stick_cal_y.max = DFLT_STICK_CAL_MAX;
+-		ctlr->right_stick_cal_y.min = DFLT_STICK_CAL_MIN;
+-	}
++	if (ret)
++		joycon_use_default_calibration(ctlr->hdev,
++					       &ctlr->right_stick_cal_x,
++					       &ctlr->right_stick_cal_y,
++					       "right", ret);
+ 
+ 	hid_dbg(ctlr->hdev, "calibration:\n"
+ 			    "l_x_c=%d l_x_max=%d l_x_min=%d\n"
+diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c
+index 26373b82fe812..6da80e442fdd1 100644
+--- a/drivers/hid/hid-roccat.c
++++ b/drivers/hid/hid-roccat.c
+@@ -257,6 +257,8 @@ int roccat_report_event(int minor, u8 const *data)
+ 	if (!new_value)
+ 		return -ENOMEM;
+ 
++	mutex_lock(&device->cbuf_lock);
++
+ 	report = &device->cbuf[device->cbuf_end];
+ 
+ 	/* passing NULL is safe */
+@@ -276,6 +278,8 @@ int roccat_report_event(int minor, u8 const *data)
+ 			reader->cbuf_start = (reader->cbuf_start + 1) % ROCCAT_CBUF_SIZE;
+ 	}
+ 
++	mutex_unlock(&device->cbuf_lock);
++
+ 	wake_up_interruptible(&device->wait);
+ 	return 0;
+ }
+diff --git a/drivers/hid/hid-topre.c b/drivers/hid/hid-topre.c
+new file mode 100644
+index 0000000000000..88a91cdad5f80
+--- /dev/null
++++ b/drivers/hid/hid-topre.c
+@@ -0,0 +1,49 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ *  HID driver for Topre REALFORCE Keyboards
++ *
++ *  Copyright (c) 2022 Harry Stern <harry@harrystern.net>
++ *
++ *  Based on the hid-macally driver
++ */
++
++#include <linux/hid.h>
++#include <linux/module.h>
++
++#include "hid-ids.h"
++
++MODULE_AUTHOR("Harry Stern <harry@harrystern.net>");
++MODULE_DESCRIPTION("REALFORCE R2 Keyboard driver");
++MODULE_LICENSE("GPL");
++
++/*
++ * Fix the REALFORCE R2's non-boot interface's report descriptor to match the
++ * events it's actually sending. It claims to send array events but is instead
++ * sending variable events.
++ */
++static __u8 *topre_report_fixup(struct hid_device *hdev, __u8 *rdesc,
++				 unsigned int *rsize)
++{
++	if (*rsize >= 119 && rdesc[69] == 0x29 && rdesc[70] == 0xe7 &&
++						 rdesc[71] == 0x81 && rdesc[72] == 0x00) {
++		hid_info(hdev,
++			"fixing up Topre REALFORCE keyboard report descriptor\n");
++		rdesc[72] = 0x02;
++	}
++	return rdesc;
++}
++
++static const struct hid_device_id topre_id_table[] = {
++	{ HID_USB_DEVICE(USB_VENDOR_ID_TOPRE,
++			 USB_DEVICE_ID_TOPRE_REALFORCE_R2_108) },
++	{ }
++};
++MODULE_DEVICE_TABLE(hid, topre_id_table);
++
++static struct hid_driver topre_driver = {
++	.name			= "topre",
++	.id_table		= topre_id_table,
++	.report_fixup		= topre_report_fixup,
++};
++
++module_hid_driver(topre_driver);
+diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c
+index 47a17375c7fce..ff46604ef1d8c 100644
+--- a/drivers/hid/hid-uclogic-core.c
++++ b/drivers/hid/hid-uclogic-core.c
+@@ -153,6 +153,7 @@ static int uclogic_input_configured(struct hid_device *hdev,
+ 			suffix = "Pad";
+ 			break;
+ 		case HID_DG_PEN:
++		case HID_DG_DIGITIZER:
+ 			suffix = "Pen";
+ 			break;
+ 		case HID_CP_CONSUMER_CONTROL:
+diff --git a/drivers/hid/hid-uclogic-rdesc.c b/drivers/hid/hid-uclogic-rdesc.c
+index 3d68e8b0784d0..81ca22398ed55 100644
+--- a/drivers/hid/hid-uclogic-rdesc.c
++++ b/drivers/hid/hid-uclogic-rdesc.c
+@@ -1113,7 +1113,7 @@ __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
+ 		    memcmp(p, pen_head, sizeof(pen_head)) == 0 &&
+ 		    p[sizeof(pen_head)] < param_num) {
+ 			v = param_list[p[sizeof(pen_head)]];
+-			put_unaligned(cpu_to_le32(v), (s32 *)p);
++			put_unaligned((__force u32)cpu_to_le32(v), (s32 *)p);
+ 			p += sizeof(pen_head) + 1;
+ 		} else if (memcmp(p, btn_head, sizeof(btn_head)) == 0 &&
+ 			   p[sizeof(btn_head)] < param_num) {
+diff --git a/drivers/hsi/clients/ssi_protocol.c b/drivers/hsi/clients/ssi_protocol.c
+index 21f11a5b965b1..49ffd808d17ff 100644
+--- a/drivers/hsi/clients/ssi_protocol.c
++++ b/drivers/hsi/clients/ssi_protocol.c
+@@ -931,6 +931,7 @@ static int ssip_pn_open(struct net_device *dev)
+ 	if (err < 0) {
+ 		dev_err(&cl->device, "Register HSI port event failed (%d)\n",
+ 			err);
++		hsi_release_port(cl);
+ 		return err;
+ 	}
+ 	dev_dbg(&cl->device, "Configuring SSI port\n");
+diff --git a/drivers/hsi/controllers/omap_ssi_core.c b/drivers/hsi/controllers/omap_ssi_core.c
+index 44a3f5660c109..eb98201583185 100644
+--- a/drivers/hsi/controllers/omap_ssi_core.c
++++ b/drivers/hsi/controllers/omap_ssi_core.c
+@@ -524,6 +524,7 @@ static int ssi_probe(struct platform_device *pd)
+ 		if (!childpdev) {
+ 			err = -ENODEV;
+ 			dev_err(&pd->dev, "failed to create ssi controller port\n");
++			of_node_put(child);
+ 			goto out3;
+ 		}
+ 	}
+diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c
+index a0cb5be246e1c..b9495b720f1bd 100644
+--- a/drivers/hsi/controllers/omap_ssi_port.c
++++ b/drivers/hsi/controllers/omap_ssi_port.c
+@@ -230,10 +230,10 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch)
+ 	if (msg->ttype == HSI_MSG_READ) {
+ 		err = dma_map_sg(&ssi->device, msg->sgt.sgl, msg->sgt.nents,
+ 							DMA_FROM_DEVICE);
+-		if (err < 0) {
++		if (!err) {
+ 			dev_dbg(&ssi->device, "DMA map SG failed !\n");
+ 			pm_runtime_put_autosuspend(omap_port->pdev);
+-			return err;
++			return -EIO;
+ 		}
+ 		csdp = SSI_DST_BURST_4x32_BIT | SSI_DST_MEMORY_PORT |
+ 			SSI_SRC_SINGLE_ACCESS0 | SSI_SRC_PERIPHERAL_PORT |
+@@ -247,10 +247,10 @@ static int ssi_start_dma(struct hsi_msg *msg, int lch)
+ 	} else {
+ 		err = dma_map_sg(&ssi->device, msg->sgt.sgl, msg->sgt.nents,
+ 							DMA_TO_DEVICE);
+-		if (err < 0) {
++		if (!err) {
+ 			dev_dbg(&ssi->device, "DMA map SG failed !\n");
+ 			pm_runtime_put_autosuspend(omap_port->pdev);
+-			return err;
++			return -EIO;
+ 		}
+ 		csdp = SSI_SRC_BURST_4x32_BIT | SSI_SRC_MEMORY_PORT |
+ 			SSI_DST_SINGLE_ACCESS0 | SSI_DST_PERIPHERAL_PORT |
+diff --git a/drivers/hwmon/gsc-hwmon.c b/drivers/hwmon/gsc-hwmon.c
+index d64be48f1ef6c..b60ec95b5edbf 100644
+--- a/drivers/hwmon/gsc-hwmon.c
++++ b/drivers/hwmon/gsc-hwmon.c
+@@ -267,6 +267,7 @@ gsc_hwmon_get_devtree_pdata(struct device *dev)
+ 	pdata->nchannels = nchannels;
+ 
+ 	/* fan controller base address */
++	of_node_get(dev->parent->of_node);
+ 	fan = of_find_compatible_node(dev->parent->of_node, NULL, "gw,gsc-fan");
+ 	if (fan && of_property_read_u32(fan, "reg", &pdata->fan_base)) {
+ 		of_node_put(fan);
+diff --git a/drivers/hwmon/occ/p9_sbe.c b/drivers/hwmon/occ/p9_sbe.c
+index c1e0a1d96cd47..f3791a589b01b 100644
+--- a/drivers/hwmon/occ/p9_sbe.c
++++ b/drivers/hwmon/occ/p9_sbe.c
+@@ -14,6 +14,8 @@
+ 
+ #include "common.h"
+ 
++#define OCC_CHECKSUM_RETRIES	3
++
+ struct p9_sbe_occ {
+ 	struct occ occ;
+ 	bool sbe_error;
+@@ -80,18 +82,23 @@ done:
+ static int p9_sbe_occ_send_cmd(struct occ *occ, u8 *cmd, size_t len,
+ 			       void *resp, size_t resp_len)
+ {
++	size_t original_resp_len = resp_len;
+ 	struct p9_sbe_occ *ctx = to_p9_sbe_occ(occ);
+-	int rc;
++	int rc, i;
+ 
+-	rc = fsi_occ_submit(ctx->sbe, cmd, len, resp, &resp_len);
+-	if (rc < 0) {
++	for (i = 0; i < OCC_CHECKSUM_RETRIES; ++i) {
++		rc = fsi_occ_submit(ctx->sbe, cmd, len, resp, &resp_len);
++		if (rc >= 0)
++			break;
+ 		if (resp_len) {
+ 			if (p9_sbe_occ_save_ffdc(ctx, resp, resp_len))
+ 				sysfs_notify(&occ->bus_dev->kobj, NULL,
+ 					     bin_attr_ffdc.attr.name);
++			return rc;
+ 		}
+-
+-		return rc;
++		if (rc != -EBADE)
++			return rc;
++		resp_len = original_resp_len;
+ 	}
+ 
+ 	switch (((struct occ_response *)resp)->return_status) {
+diff --git a/drivers/hwmon/pmbus/mp2888.c b/drivers/hwmon/pmbus/mp2888.c
+index 8ecd4adfef40e..24e5194706cf6 100644
+--- a/drivers/hwmon/pmbus/mp2888.c
++++ b/drivers/hwmon/pmbus/mp2888.c
+@@ -34,7 +34,7 @@ struct mp2888_data {
+ 	int curr_sense_gain;
+ };
+ 
+-#define to_mp2888_data(x)  container_of(x, struct mp2888_data, info)
++#define to_mp2888_data(x)	container_of(x, struct mp2888_data, info)
+ 
+ static int mp2888_read_byte_data(struct i2c_client *client, int page, int reg)
+ {
+@@ -109,7 +109,7 @@ mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page,
+ 	 * - Kcs is the DrMOS current sense gain of power stage, which is obtained from the
+ 	 *   register MP2888_MFR_VR_CONFIG1, bits 13-12 with the following selection of DrMOS
+ 	 *   (data->curr_sense_gain):
+-	 *   00b - 5µA/A, 01b - 8.5µA/A, 10b - 9.7µA/A, 11b - 10µA/A.
++	 *   00b - 8.5µA/A, 01b - 9.7µA/A, 1b - 10µA/A, 11b - 5µA/A.
+ 	 * - Rcs is the internal phase current sense resistor. This parameter depends on hardware
+ 	 *   assembly. By default it is set to 1kΩ. In case of different assembly, user should
+ 	 *   scale this parameter by dividing it by Rcs.
+@@ -118,10 +118,9 @@ mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page,
+ 	 * because sampling of current occurrence of bit weight has a big deviation, especially for
+ 	 * light load.
+ 	 */
+-	ret = DIV_ROUND_CLOSEST(ret * 100 - 9800, data->curr_sense_gain);
+-	ret = (data->phase_curr_resolution) ? ret * 2 : ret;
++	ret = DIV_ROUND_CLOSEST(ret * 200 - 19600, data->curr_sense_gain);
+ 	/* Scale according to total current resolution. */
+-	ret = (data->total_curr_resolution) ? ret * 8 : ret * 4;
++	ret = (data->total_curr_resolution) ? ret * 2 : ret;
+ 	return ret;
+ }
+ 
+@@ -212,7 +211,7 @@ static int mp2888_read_word_data(struct i2c_client *client, int page, int phase,
+ 		ret = pmbus_read_word_data(client, page, phase, reg);
+ 		if (ret < 0)
+ 			return ret;
+-		ret = data->total_curr_resolution ? ret * 2 : ret;
++		ret = data->total_curr_resolution ? ret : DIV_ROUND_CLOSEST(ret, 2);
+ 		break;
+ 	case PMBUS_POUT_OP_WARN_LIMIT:
+ 		ret = pmbus_read_word_data(client, page, phase, reg);
+@@ -223,7 +222,7 @@ static int mp2888_read_word_data(struct i2c_client *client, int page, int phase,
+ 		 * set 1. Actual power is reported with 0.5W or 1W respectively resolution. Scaling
+ 		 * is needed to match both.
+ 		 */
+-		ret = data->total_curr_resolution ? ret * 4 : ret * 2;
++		ret = data->total_curr_resolution ? ret * 2 : ret;
+ 		break;
+ 	/*
+ 	 * The below registers are not implemented by device or implemented not according to the
+diff --git a/drivers/hwmon/sht4x.c b/drivers/hwmon/sht4x.c
+index c19df3ade48e3..13ac2d8f22c79 100644
+--- a/drivers/hwmon/sht4x.c
++++ b/drivers/hwmon/sht4x.c
+@@ -129,7 +129,7 @@ unlock:
+ 
+ static ssize_t sht4x_interval_write(struct sht4x_data *data, long val)
+ {
+-	data->update_interval = clamp_val(val, SHT4X_MIN_POLL_INTERVAL, UINT_MAX);
++	data->update_interval = clamp_val(val, SHT4X_MIN_POLL_INTERVAL, INT_MAX);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
+index 70b80e7109905..4d3a3b464ecd8 100644
+--- a/drivers/i2c/busses/i2c-designware-core.h
++++ b/drivers/i2c/busses/i2c-designware-core.h
+@@ -126,8 +126,9 @@
+  * status codes
+  */
+ #define STATUS_IDLE			0x0
+-#define STATUS_WRITE_IN_PROGRESS	0x1
+-#define STATUS_READ_IN_PROGRESS		0x2
++#define STATUS_ACTIVE			0x1
++#define STATUS_WRITE_IN_PROGRESS	0x2
++#define STATUS_READ_IN_PROGRESS		0x4
+ 
+ /*
+  * operation modes
+@@ -334,12 +335,14 @@ void i2c_dw_disable_int(struct dw_i2c_dev *dev);
+ 
+ static inline void __i2c_dw_enable(struct dw_i2c_dev *dev)
+ {
++	dev->status |= STATUS_ACTIVE;
+ 	regmap_write(dev->map, DW_IC_ENABLE, 1);
+ }
+ 
+ static inline void __i2c_dw_disable_nowait(struct dw_i2c_dev *dev)
+ {
+ 	regmap_write(dev->map, DW_IC_ENABLE, 0);
++	dev->status &= ~STATUS_ACTIVE;
+ }
+ 
+ void __i2c_dw_disable(struct dw_i2c_dev *dev);
+diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
+index 44a94b225ed82..dc3c5a15a95b9 100644
+--- a/drivers/i2c/busses/i2c-designware-master.c
++++ b/drivers/i2c/busses/i2c-designware-master.c
+@@ -716,6 +716,19 @@ static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev)
+ 	u32 stat;
+ 
+ 	stat = i2c_dw_read_clear_intrbits(dev);
++
++	if (!(dev->status & STATUS_ACTIVE)) {
++		/*
++		 * Unexpected interrupt in driver point of view. State
++		 * variables are either unset or stale so acknowledge and
++		 * disable interrupts for suppressing further interrupts if
++		 * interrupt really came from this HW (E.g. firmware has left
++		 * the HW active).
++		 */
++		regmap_write(dev->map, DW_IC_INTR_MASK, 0);
++		return 0;
++	}
++
+ 	if (stat & DW_IC_INTR_TX_ABRT) {
+ 		dev->cmd_err |= DW_IC_ERR_TX_ABRT;
+ 		dev->status = STATUS_IDLE;
+diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
+index 608e612094556..ca368482b2464 100644
+--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
++++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
+@@ -27,7 +27,6 @@
+ #include "i2c-ccgx-ucsi.h"
+ 
+ #define DRIVER_NAME "i2c-designware-pci"
+-#define AMD_CLK_RATE_HZ	100000
+ 
+ enum dw_pci_ctl_id_t {
+ 	medfield,
+@@ -100,11 +99,6 @@ static u32 mfld_get_clk_rate_khz(struct dw_i2c_dev *dev)
+ 	return 25000;
+ }
+ 
+-static u32 navi_amd_get_clk_rate_khz(struct dw_i2c_dev *dev)
+-{
+-	return AMD_CLK_RATE_HZ;
+-}
+-
+ static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
+ {
+ 	struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev);
+@@ -126,15 +120,6 @@ static int mfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
+ 	return -ENODEV;
+ }
+ 
+-static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
+-{
+-	struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev);
+-
+-	dev->flags |= MODEL_AMD_NAVI_GPU;
+-	dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
+-	return 0;
+-}
+-
+ static int mrfld_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
+ {
+ 	/*
+@@ -159,6 +144,20 @@ static u32 ehl_get_clk_rate_khz(struct dw_i2c_dev *dev)
+ 	return 100000;
+ }
+ 
++static u32 navi_amd_get_clk_rate_khz(struct dw_i2c_dev *dev)
++{
++	return 100000;
++}
++
++static int navi_amd_setup(struct pci_dev *pdev, struct dw_pci_controller *c)
++{
++	struct dw_i2c_dev *dev = dev_get_drvdata(&pdev->dev);
++
++	dev->flags |= MODEL_AMD_NAVI_GPU;
++	dev->timings.bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
++	return 0;
++}
++
+ static struct dw_pci_controller dw_pci_controllers[] = {
+ 	[medfield] = {
+ 		.bus_num = -1,
+@@ -389,6 +388,7 @@ static const struct pci_device_id i2_designware_pci_ids[] = {
+ 	{ PCI_VDEVICE(INTEL, 0x4bbe), elkhartlake },
+ 	{ PCI_VDEVICE(INTEL, 0x4bbf), elkhartlake },
+ 	{ PCI_VDEVICE(INTEL, 0x4bc0), elkhartlake },
++	/* AMD NAVI */
+ 	{ PCI_VDEVICE(ATI,  0x7314), navi_amd },
+ 	{ PCI_VDEVICE(ATI,  0x73a4), navi_amd },
+ 	{ PCI_VDEVICE(ATI,  0x73e4), navi_amd },
+diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c
+index ad5efd7497d1c..0e840eba4fd64 100644
+--- a/drivers/i2c/busses/i2c-mlxbf.c
++++ b/drivers/i2c/busses/i2c-mlxbf.c
+@@ -306,6 +306,7 @@ static u64 mlxbf_i2c_corepll_frequency;
+  * exact.
+  */
+ #define MLXBF_I2C_SMBUS_TIMEOUT   (300 * 1000) /* 300ms */
++#define MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT (300 * 1000) /* 300ms */
+ 
+ /* Encapsulates timing parameters. */
+ struct mlxbf_i2c_timings {
+@@ -514,6 +515,25 @@ static bool mlxbf_smbus_master_wait_for_idle(struct mlxbf_i2c_priv *priv)
+ 	return false;
+ }
+ 
++/*
++ * wait for the lock to be released before acquiring it.
++ */
++static bool mlxbf_i2c_smbus_master_lock(struct mlxbf_i2c_priv *priv)
++{
++	if (mlxbf_smbus_poll(priv->smbus->io, MLXBF_I2C_SMBUS_MASTER_GW,
++			   MLXBF_I2C_MASTER_LOCK_BIT, true,
++			   MLXBF_I2C_SMBUS_LOCK_POLL_TIMEOUT))
++		return true;
++
++	return false;
++}
++
++static void mlxbf_i2c_smbus_master_unlock(struct mlxbf_i2c_priv *priv)
++{
++	/* Clear the gw to clear the lock */
++	writel(0, priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_GW);
++}
++
+ static bool mlxbf_i2c_smbus_transaction_success(u32 master_status,
+ 						u32 cause_status)
+ {
+@@ -705,10 +725,19 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
+ 	slave = request->slave & GENMASK(6, 0);
+ 	addr = slave << 1;
+ 
+-	/* First of all, check whether the HW is idle. */
+-	if (WARN_ON(!mlxbf_smbus_master_wait_for_idle(priv)))
++	/*
++	 * Try to acquire the smbus gw lock before any reads of the GW register since
++	 * a read sets the lock.
++	 */
++	if (WARN_ON(!mlxbf_i2c_smbus_master_lock(priv)))
+ 		return -EBUSY;
+ 
++	/* Check whether the HW is idle */
++	if (WARN_ON(!mlxbf_smbus_master_wait_for_idle(priv))) {
++		ret = -EBUSY;
++		goto out_unlock;
++	}
++
+ 	/* Set first byte. */
+ 	data_desc[data_idx++] = addr;
+ 
+@@ -732,8 +761,10 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
+ 			write_en = 1;
+ 			write_len += operation->length;
+ 			if (data_idx + operation->length >
+-					MLXBF_I2C_MASTER_DATA_DESC_SIZE)
+-				return -ENOBUFS;
++					MLXBF_I2C_MASTER_DATA_DESC_SIZE) {
++				ret = -ENOBUFS;
++				goto out_unlock;
++			}
+ 			memcpy(data_desc + data_idx,
+ 			       operation->buffer, operation->length);
+ 			data_idx += operation->length;
+@@ -765,7 +796,7 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
+ 		ret = mlxbf_i2c_smbus_enable(priv, slave, write_len, block_en,
+ 					 pec_en, 0);
+ 		if (ret)
+-			return ret;
++			goto out_unlock;
+ 	}
+ 
+ 	if (read_en) {
+@@ -792,6 +823,9 @@ mlxbf_i2c_smbus_start_transaction(struct mlxbf_i2c_priv *priv,
+ 			priv->smbus->io + MLXBF_I2C_SMBUS_MASTER_FSM);
+ 	}
+ 
++out_unlock:
++	mlxbf_i2c_smbus_master_unlock(priv);
++
+ 	return ret;
+ }
+ 
+diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c
+index edad1f30121dd..502253f53d966 100644
+--- a/drivers/iio/adc/ad7923.c
++++ b/drivers/iio/adc/ad7923.c
+@@ -93,6 +93,7 @@ enum ad7923_id {
+ 			.sign = 'u',					\
+ 			.realbits = (bits),				\
+ 			.storagebits = 16,				\
++			.shift = 12 - (bits),				\
+ 			.endianness = IIO_BE,				\
+ 		},							\
+ 	}
+@@ -268,7 +269,8 @@ static int ad7923_read_raw(struct iio_dev *indio_dev,
+ 			return ret;
+ 
+ 		if (chan->address == EXTRACT(ret, 12, 4))
+-			*val = EXTRACT(ret, 0, 12);
++			*val = EXTRACT(ret, chan->scan_type.shift,
++				       chan->scan_type.realbits);
+ 		else
+ 			return -EIO;
+ 
+diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
+index 279430c1d88c3..e2c82c5a2fac0 100644
+--- a/drivers/iio/adc/at91-sama5d2_adc.c
++++ b/drivers/iio/adc/at91-sama5d2_adc.c
+@@ -77,7 +77,7 @@ struct at91_adc_reg_layout {
+ #define	AT91_SAMA5D2_MR_ANACH		BIT(23)
+ /* Tracking Time */
+ #define	AT91_SAMA5D2_MR_TRACKTIM(v)	((v) << 24)
+-#define	AT91_SAMA5D2_MR_TRACKTIM_MAX	0xff
++#define	AT91_SAMA5D2_MR_TRACKTIM_MAX	0xf
+ /* Transfer Time */
+ #define	AT91_SAMA5D2_MR_TRANSFER(v)	((v) << 28)
+ #define	AT91_SAMA5D2_MR_TRANSFER_MAX	0x3
+@@ -1542,10 +1542,12 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
+ 		ret = at91_adc_read_position(st, chan->channel,
+ 					     &tmp_val);
+ 		*val = tmp_val;
++		if (ret > 0)
++			ret = at91_adc_adjust_val_osr(st, val);
+ 		mutex_unlock(&st->lock);
+ 		iio_device_release_direct_mode(indio_dev);
+ 
+-		return at91_adc_adjust_val_osr(st, val);
++		return ret;
+ 	}
+ 	if (chan->type == IIO_PRESSURE) {
+ 		ret = iio_device_claim_direct_mode(indio_dev);
+@@ -1556,10 +1558,12 @@ static int at91_adc_read_info_raw(struct iio_dev *indio_dev,
+ 		ret = at91_adc_read_pressure(st, chan->channel,
+ 					     &tmp_val);
+ 		*val = tmp_val;
++		if (ret > 0)
++			ret = at91_adc_adjust_val_osr(st, val);
+ 		mutex_unlock(&st->lock);
+ 		iio_device_release_direct_mode(indio_dev);
+ 
+-		return at91_adc_adjust_val_osr(st, val);
++		return ret;
+ 	}
+ 
+ 	/* in this case we have a voltage channel */
+@@ -1646,16 +1650,20 @@ static int at91_adc_write_raw(struct iio_dev *indio_dev,
+ 		/* if no change, optimize out */
+ 		if (val == st->oversampling_ratio)
+ 			return 0;
++		mutex_lock(&st->lock);
+ 		st->oversampling_ratio = val;
+ 		/* update ratio */
+ 		at91_adc_config_emr(st);
++		mutex_unlock(&st->lock);
+ 		return 0;
+ 	case IIO_CHAN_INFO_SAMP_FREQ:
+ 		if (val < st->soc_info.min_sample_rate ||
+ 		    val > st->soc_info.max_sample_rate)
+ 			return -EINVAL;
+ 
++		mutex_lock(&st->lock);
+ 		at91_adc_setup_samp_freq(indio_dev, val);
++		mutex_unlock(&st->lock);
+ 		return 0;
+ 	default:
+ 		return -EINVAL;
+@@ -2108,6 +2116,9 @@ static int at91_adc_suspend(struct device *dev)
+ 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ 	struct at91_adc_state *st = iio_priv(indio_dev);
+ 
++	if (iio_buffer_enabled(indio_dev))
++		at91_adc_buffer_postdisable(indio_dev);
++
+ 	/*
+ 	 * Do a sofware reset of the ADC before we go to suspend.
+ 	 * this will ensure that all pins are free from being muxed by the ADC
+@@ -2151,14 +2162,11 @@ static int at91_adc_resume(struct device *dev)
+ 	if (!iio_buffer_enabled(indio_dev))
+ 		return 0;
+ 
+-	/* check if we are enabling triggered buffer or the touchscreen */
+-	if (at91_adc_current_chan_is_touch(indio_dev))
+-		return at91_adc_configure_touch(st, true);
+-	else
+-		return at91_adc_configure_trigger(st->trig, true);
++	ret = at91_adc_buffer_prepare(indio_dev);
++	if (ret)
++		goto vref_disable_resume;
+ 
+-	/* not needed but more explicit */
+-	return 0;
++	return at91_adc_configure_trigger(st->trig, true);
+ 
+ vref_disable_resume:
+ 	regulator_disable(st->vref);
+diff --git a/drivers/iio/adc/ltc2497.c b/drivers/iio/adc/ltc2497.c
+index f7c786f37ceb1..78b93c99cc47c 100644
+--- a/drivers/iio/adc/ltc2497.c
++++ b/drivers/iio/adc/ltc2497.c
+@@ -41,6 +41,19 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
+ 		}
+ 
+ 		*val = (be32_to_cpu(st->buf) >> 14) - (1 << 17);
++
++		/*
++		 * The part started a new conversion at the end of the above i2c
++		 * transfer, so if the address didn't change since the last call
++		 * everything is fine and we can return early.
++		 * If not (which should only happen when some sort of bulk
++		 * conversion is implemented) we have to program the new
++		 * address. Note that this probably fails as the conversion that
++		 * was triggered above is like not complete yet and the two
++		 * operations have to be done in a single transfer.
++		 */
++		if (ddata->addr_prev == address)
++			return 0;
+ 	}
+ 
+ 	ret = i2c_smbus_write_byte(st->client,
+diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c
+index 34e1319a97126..356dc0bab1153 100644
+--- a/drivers/iio/dac/ad5593r.c
++++ b/drivers/iio/dac/ad5593r.c
+@@ -13,6 +13,8 @@
+ #include <linux/module.h>
+ #include <linux/mod_devicetable.h>
+ 
++#include <asm/unaligned.h>
++
+ #define AD5593R_MODE_CONF		(0 << 4)
+ #define AD5593R_MODE_DAC_WRITE		(1 << 4)
+ #define AD5593R_MODE_ADC_READBACK	(4 << 4)
+@@ -20,6 +22,24 @@
+ #define AD5593R_MODE_GPIO_READBACK	(6 << 4)
+ #define AD5593R_MODE_REG_READBACK	(7 << 4)
+ 
++static int ad5593r_read_word(struct i2c_client *i2c, u8 reg, u16 *value)
++{
++	int ret;
++	u8 buf[2];
++
++	ret = i2c_smbus_write_byte(i2c, reg);
++	if (ret < 0)
++		return ret;
++
++	ret = i2c_master_recv(i2c, buf, sizeof(buf));
++	if (ret < 0)
++		return ret;
++
++	*value = get_unaligned_be16(buf);
++
++	return 0;
++}
++
+ static int ad5593r_write_dac(struct ad5592r_state *st, unsigned chan, u16 value)
+ {
+ 	struct i2c_client *i2c = to_i2c_client(st->dev);
+@@ -38,13 +58,7 @@ static int ad5593r_read_adc(struct ad5592r_state *st, unsigned chan, u16 *value)
+ 	if (val < 0)
+ 		return (int) val;
+ 
+-	val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_ADC_READBACK);
+-	if (val < 0)
+-		return (int) val;
+-
+-	*value = (u16) val;
+-
+-	return 0;
++	return ad5593r_read_word(i2c, AD5593R_MODE_ADC_READBACK, value);
+ }
+ 
+ static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value)
+@@ -58,25 +72,19 @@ static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value)
+ static int ad5593r_reg_read(struct ad5592r_state *st, u8 reg, u16 *value)
+ {
+ 	struct i2c_client *i2c = to_i2c_client(st->dev);
+-	s32 val;
+-
+-	val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_REG_READBACK | reg);
+-	if (val < 0)
+-		return (int) val;
+ 
+-	*value = (u16) val;
+-
+-	return 0;
++	return ad5593r_read_word(i2c, AD5593R_MODE_REG_READBACK | reg, value);
+ }
+ 
+ static int ad5593r_gpio_read(struct ad5592r_state *st, u8 *value)
+ {
+ 	struct i2c_client *i2c = to_i2c_client(st->dev);
+-	s32 val;
++	u16 val;
++	int ret;
+ 
+-	val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_GPIO_READBACK);
+-	if (val < 0)
+-		return (int) val;
++	ret = ad5593r_read_word(i2c, AD5593R_MODE_GPIO_READBACK, &val);
++	if (ret)
++		return ret;
+ 
+ 	*value = (u8) val;
+ 
+diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
+index 0f4dbda3b9d36..921d8e8643a26 100644
+--- a/drivers/iio/industrialio-core.c
++++ b/drivers/iio/industrialio-core.c
+@@ -1621,6 +1621,8 @@ static void iio_dev_release(struct device *device)
+ 
+ 	iio_device_detach_buffers(indio_dev);
+ 
++	lockdep_unregister_key(&iio_dev_opaque->mlock_key);
++
+ 	ida_free(&iio_ida, iio_dev_opaque->id);
+ 	kfree(iio_dev_opaque);
+ }
+@@ -1680,6 +1682,9 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv)
+ 	INIT_LIST_HEAD(&iio_dev_opaque->buffer_list);
+ 	INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers);
+ 
++	lockdep_register_key(&iio_dev_opaque->mlock_key);
++	lockdep_set_class(&indio_dev->mlock, &iio_dev_opaque->mlock_key);
++
+ 	return indio_dev;
+ }
+ EXPORT_SYMBOL(iio_device_alloc);
+diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
+index df74765d33dcb..87fd2a0d44f2a 100644
+--- a/drivers/iio/inkern.c
++++ b/drivers/iio/inkern.c
+@@ -165,9 +165,10 @@ static int __of_iio_channel_get(struct iio_channel *channel,
+ 
+ 	idev = bus_find_device(&iio_bus_type, NULL, iiospec.np,
+ 			       iio_dev_node_match);
+-	of_node_put(iiospec.np);
+-	if (idev == NULL)
++	if (idev == NULL) {
++		of_node_put(iiospec.np);
+ 		return -EPROBE_DEFER;
++	}
+ 
+ 	indio_dev = dev_to_iio_dev(idev);
+ 	channel->indio_dev = indio_dev;
+@@ -175,6 +176,7 @@ static int __of_iio_channel_get(struct iio_channel *channel,
+ 		index = indio_dev->info->of_xlate(indio_dev, &iiospec);
+ 	else
+ 		index = __of_iio_simple_xlate(indio_dev, &iiospec);
++	of_node_put(iiospec.np);
+ 	if (index < 0)
+ 		goto err_put;
+ 	channel->channel = &indio_dev->channels[index];
+@@ -410,6 +412,8 @@ struct iio_channel *devm_of_iio_channel_get_by_name(struct device *dev,
+ 	channel = of_iio_channel_get_by_name(np, channel_name);
+ 	if (IS_ERR(channel))
+ 		return channel;
++	if (!channel)
++		return ERR_PTR(-ENODEV);
+ 
+ 	ret = devm_add_action_or_reset(dev, devm_iio_channel_free, channel);
+ 	if (ret)
+diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c
+index aeaa4da6923b4..d1f16729c60ed 100644
+--- a/drivers/iio/magnetometer/yamaha-yas530.c
++++ b/drivers/iio/magnetometer/yamaha-yas530.c
+@@ -132,7 +132,7 @@ struct yas5xx {
+ 	unsigned int version;
+ 	char name[16];
+ 	struct yas5xx_calibration calibration;
+-	u8 hard_offsets[3];
++	s8 hard_offsets[3];
+ 	struct iio_mount_matrix orientation;
+ 	struct regmap *map;
+ 	struct regulator_bulk_data regs[2];
+diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c
+index 36fb7ae0d0a9d..984a3f511a1ae 100644
+--- a/drivers/iio/pressure/dps310.c
++++ b/drivers/iio/pressure/dps310.c
+@@ -89,6 +89,7 @@ struct dps310_data {
+ 	s32 c00, c10, c20, c30, c01, c11, c21;
+ 	s32 pressure_raw;
+ 	s32 temp_raw;
++	bool timeout_recovery_failed;
+ };
+ 
+ static const struct iio_chan_spec dps310_channels[] = {
+@@ -159,6 +160,102 @@ static int dps310_get_coefs(struct dps310_data *data)
+ 	return 0;
+ }
+ 
++/*
++ * Some versions of the chip will read temperatures in the ~60C range when
++ * it's actually ~20C. This is the manufacturer recommended workaround
++ * to correct the issue. The registers used below are undocumented.
++ */
++static int dps310_temp_workaround(struct dps310_data *data)
++{
++	int rc;
++	int reg;
++
++	rc = regmap_read(data->regmap, 0x32, &reg);
++	if (rc)
++		return rc;
++
++	/*
++	 * If bit 1 is set then the device is okay, and the workaround does not
++	 * need to be applied
++	 */
++	if (reg & BIT(1))
++		return 0;
++
++	rc = regmap_write(data->regmap, 0x0e, 0xA5);
++	if (rc)
++		return rc;
++
++	rc = regmap_write(data->regmap, 0x0f, 0x96);
++	if (rc)
++		return rc;
++
++	rc = regmap_write(data->regmap, 0x62, 0x02);
++	if (rc)
++		return rc;
++
++	rc = regmap_write(data->regmap, 0x0e, 0x00);
++	if (rc)
++		return rc;
++
++	return regmap_write(data->regmap, 0x0f, 0x00);
++}
++
++static int dps310_startup(struct dps310_data *data)
++{
++	int rc;
++	int ready;
++
++	/*
++	 * Set up pressure sensor in single sample, one measurement per second
++	 * mode
++	 */
++	rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0);
++	if (rc)
++		return rc;
++
++	/*
++	 * Set up external (MEMS) temperature sensor in single sample, one
++	 * measurement per second mode
++	 */
++	rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT);
++	if (rc)
++		return rc;
++
++	/* Temp and pressure shifts are disabled when PRC <= 8 */
++	rc = regmap_write_bits(data->regmap, DPS310_CFG_REG,
++			       DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0);
++	if (rc)
++		return rc;
++
++	/* MEAS_CFG doesn't update correctly unless first written with 0 */
++	rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG,
++			       DPS310_MEAS_CTRL_BITS, 0);
++	if (rc)
++		return rc;
++
++	/* Turn on temperature and pressure measurement in the background */
++	rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG,
++			       DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN |
++			       DPS310_TEMP_EN | DPS310_BACKGROUND);
++	if (rc)
++		return rc;
++
++	/*
++	 * Calibration coefficients required for reporting temperature.
++	 * They are available 40ms after the device has started
++	 */
++	rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready,
++				      ready & DPS310_COEF_RDY, 10000, 40000);
++	if (rc)
++		return rc;
++
++	rc = dps310_get_coefs(data);
++	if (rc)
++		return rc;
++
++	return dps310_temp_workaround(data);
++}
++
+ static int dps310_get_pres_precision(struct dps310_data *data)
+ {
+ 	int rc;
+@@ -297,11 +394,69 @@ static int dps310_get_temp_k(struct dps310_data *data)
+ 	return scale_factors[ilog2(rc)];
+ }
+ 
++static int dps310_reset_wait(struct dps310_data *data)
++{
++	int rc;
++
++	rc = regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC);
++	if (rc)
++		return rc;
++
++	/* Wait for device chip access: 2.5ms in specification */
++	usleep_range(2500, 12000);
++	return 0;
++}
++
++static int dps310_reset_reinit(struct dps310_data *data)
++{
++	int rc;
++
++	rc = dps310_reset_wait(data);
++	if (rc)
++		return rc;
++
++	return dps310_startup(data);
++}
++
++static int dps310_ready_status(struct dps310_data *data, int ready_bit, int timeout)
++{
++	int sleep = DPS310_POLL_SLEEP_US(timeout);
++	int ready;
++
++	return regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, ready & ready_bit,
++					sleep, timeout);
++}
++
++static int dps310_ready(struct dps310_data *data, int ready_bit, int timeout)
++{
++	int rc;
++
++	rc = dps310_ready_status(data, ready_bit, timeout);
++	if (rc) {
++		if (rc == -ETIMEDOUT && !data->timeout_recovery_failed) {
++			/* Reset and reinitialize the chip. */
++			if (dps310_reset_reinit(data)) {
++				data->timeout_recovery_failed = true;
++			} else {
++				/* Try again to get sensor ready status. */
++				if (dps310_ready_status(data, ready_bit, timeout))
++					data->timeout_recovery_failed = true;
++				else
++					return 0;
++			}
++		}
++
++		return rc;
++	}
++
++	data->timeout_recovery_failed = false;
++	return 0;
++}
++
+ static int dps310_read_pres_raw(struct dps310_data *data)
+ {
+ 	int rc;
+ 	int rate;
+-	int ready;
+ 	int timeout;
+ 	s32 raw;
+ 	u8 val[3];
+@@ -313,9 +468,7 @@ static int dps310_read_pres_raw(struct dps310_data *data)
+ 	timeout = DPS310_POLL_TIMEOUT_US(rate);
+ 
+ 	/* Poll for sensor readiness; base the timeout upon the sample rate. */
+-	rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready,
+-				      ready & DPS310_PRS_RDY,
+-				      DPS310_POLL_SLEEP_US(timeout), timeout);
++	rc = dps310_ready(data, DPS310_PRS_RDY, timeout);
+ 	if (rc)
+ 		goto done;
+ 
+@@ -352,7 +505,6 @@ static int dps310_read_temp_raw(struct dps310_data *data)
+ {
+ 	int rc;
+ 	int rate;
+-	int ready;
+ 	int timeout;
+ 
+ 	if (mutex_lock_interruptible(&data->lock))
+@@ -362,10 +514,8 @@ static int dps310_read_temp_raw(struct dps310_data *data)
+ 	timeout = DPS310_POLL_TIMEOUT_US(rate);
+ 
+ 	/* Poll for sensor readiness; base the timeout upon the sample rate. */
+-	rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready,
+-				      ready & DPS310_TMP_RDY,
+-				      DPS310_POLL_SLEEP_US(timeout), timeout);
+-	if (rc < 0)
++	rc = dps310_ready(data, DPS310_TMP_RDY, timeout);
++	if (rc)
+ 		goto done;
+ 
+ 	rc = dps310_read_temp_ready(data);
+@@ -660,7 +810,7 @@ static void dps310_reset(void *action_data)
+ {
+ 	struct dps310_data *data = action_data;
+ 
+-	regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC);
++	dps310_reset_wait(data);
+ }
+ 
+ static const struct regmap_config dps310_regmap_config = {
+@@ -677,52 +827,12 @@ static const struct iio_info dps310_info = {
+ 	.write_raw = dps310_write_raw,
+ };
+ 
+-/*
+- * Some verions of chip will read temperatures in the ~60C range when
+- * its actually ~20C. This is the manufacturer recommended workaround
+- * to correct the issue. The registers used below are undocumented.
+- */
+-static int dps310_temp_workaround(struct dps310_data *data)
+-{
+-	int rc;
+-	int reg;
+-
+-	rc = regmap_read(data->regmap, 0x32, &reg);
+-	if (rc < 0)
+-		return rc;
+-
+-	/*
+-	 * If bit 1 is set then the device is okay, and the workaround does not
+-	 * need to be applied
+-	 */
+-	if (reg & BIT(1))
+-		return 0;
+-
+-	rc = regmap_write(data->regmap, 0x0e, 0xA5);
+-	if (rc < 0)
+-		return rc;
+-
+-	rc = regmap_write(data->regmap, 0x0f, 0x96);
+-	if (rc < 0)
+-		return rc;
+-
+-	rc = regmap_write(data->regmap, 0x62, 0x02);
+-	if (rc < 0)
+-		return rc;
+-
+-	rc = regmap_write(data->regmap, 0x0e, 0x00);
+-	if (rc < 0)
+-		return rc;
+-
+-	return regmap_write(data->regmap, 0x0f, 0x00);
+-}
+-
+ static int dps310_probe(struct i2c_client *client,
+ 			const struct i2c_device_id *id)
+ {
+ 	struct dps310_data *data;
+ 	struct iio_dev *iio;
+-	int rc, ready;
++	int rc;
+ 
+ 	iio = devm_iio_device_alloc(&client->dev,  sizeof(*data));
+ 	if (!iio)
+@@ -747,54 +857,8 @@ static int dps310_probe(struct i2c_client *client,
+ 	if (rc)
+ 		return rc;
+ 
+-	/*
+-	 * Set up pressure sensor in single sample, one measurement per second
+-	 * mode
+-	 */
+-	rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0);
+-
+-	/*
+-	 * Set up external (MEMS) temperature sensor in single sample, one
+-	 * measurement per second mode
+-	 */
+-	rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT);
+-	if (rc < 0)
+-		return rc;
+-
+-	/* Temp and pressure shifts are disabled when PRC <= 8 */
+-	rc = regmap_write_bits(data->regmap, DPS310_CFG_REG,
+-			       DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0);
+-	if (rc < 0)
+-		return rc;
+-
+-	/* MEAS_CFG doesn't update correctly unless first written with 0 */
+-	rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG,
+-			       DPS310_MEAS_CTRL_BITS, 0);
+-	if (rc < 0)
+-		return rc;
+-
+-	/* Turn on temperature and pressure measurement in the background */
+-	rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG,
+-			       DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN |
+-			       DPS310_TEMP_EN | DPS310_BACKGROUND);
+-	if (rc < 0)
+-		return rc;
+-
+-	/*
+-	 * Calibration coefficients required for reporting temperature.
+-	 * They are available 40ms after the device has started
+-	 */
+-	rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready,
+-				      ready & DPS310_COEF_RDY, 10000, 40000);
+-	if (rc < 0)
+-		return rc;
+-
+-	rc = dps310_get_coefs(data);
+-	if (rc < 0)
+-		return rc;
+-
+-	rc = dps310_temp_workaround(data);
+-	if (rc < 0)
++	rc = dps310_startup(data);
++	if (rc)
+ 		return rc;
+ 
+ 	rc = devm_iio_device_register(&client->dev, iio);
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+index b985e0d9bc05e..5c910f5c01b35 100644
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -1632,14 +1632,13 @@ static void cm_path_set_rec_type(struct ib_device *ib_device, u32 port_num,
+ 
+ static void cm_format_path_lid_from_req(struct cm_req_msg *req_msg,
+ 					struct sa_path_rec *primary_path,
+-					struct sa_path_rec *alt_path)
++					struct sa_path_rec *alt_path,
++					struct ib_wc *wc)
+ {
+ 	u32 lid;
+ 
+ 	if (primary_path->rec_type != SA_PATH_REC_TYPE_OPA) {
+-		sa_path_set_dlid(primary_path,
+-				 IBA_GET(CM_REQ_PRIMARY_LOCAL_PORT_LID,
+-					 req_msg));
++		sa_path_set_dlid(primary_path, wc->slid);
+ 		sa_path_set_slid(primary_path,
+ 				 IBA_GET(CM_REQ_PRIMARY_REMOTE_PORT_LID,
+ 					 req_msg));
+@@ -1676,7 +1675,8 @@ static void cm_format_path_lid_from_req(struct cm_req_msg *req_msg,
+ 
+ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
+ 				     struct sa_path_rec *primary_path,
+-				     struct sa_path_rec *alt_path)
++				     struct sa_path_rec *alt_path,
++				     struct ib_wc *wc)
+ {
+ 	primary_path->dgid =
+ 		*IBA_GET_MEM_PTR(CM_REQ_PRIMARY_LOCAL_PORT_GID, req_msg);
+@@ -1734,7 +1734,7 @@ static void cm_format_paths_from_req(struct cm_req_msg *req_msg,
+ 		if (sa_path_is_roce(alt_path))
+ 			alt_path->roce.route_resolved = false;
+ 	}
+-	cm_format_path_lid_from_req(req_msg, primary_path, alt_path);
++	cm_format_path_lid_from_req(req_msg, primary_path, alt_path, wc);
+ }
+ 
+ static u16 cm_get_bth_pkey(struct cm_work *work)
+@@ -2148,7 +2148,7 @@ static int cm_req_handler(struct cm_work *work)
+ 	if (cm_req_has_alt_path(req_msg))
+ 		work->path[1].rec_type = work->path[0].rec_type;
+ 	cm_format_paths_from_req(req_msg, &work->path[0],
+-				 &work->path[1]);
++				 &work->path[1], work->mad_recv_wc->wc);
+ 	if (cm_id_priv->av.ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE)
+ 		sa_path_set_dmac(&work->path[0],
+ 				 cm_id_priv->av.ah_attr.roce.dmac);
+diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
+index 046376bd68e27..4796f6a8828ca 100644
+--- a/drivers/infiniband/core/uverbs_cmd.c
++++ b/drivers/infiniband/core/uverbs_cmd.c
+@@ -739,6 +739,7 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)
+ 	mr->uobject = uobj;
+ 	atomic_inc(&pd->usecnt);
+ 	mr->iova = cmd.hca_va;
++	mr->length = cmd.length;
+ 
+ 	rdma_restrack_new(&mr->res, RDMA_RESTRACK_MR);
+ 	rdma_restrack_set_name(&mr->res, NULL);
+@@ -861,8 +862,10 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs)
+ 			mr->pd = new_pd;
+ 			atomic_inc(&new_pd->usecnt);
+ 		}
+-		if (cmd.flags & IB_MR_REREG_TRANS)
++		if (cmd.flags & IB_MR_REREG_TRANS) {
+ 			mr->iova = cmd.hca_va;
++			mr->length = cmd.length;
++		}
+ 	}
+ 
+ 	memset(&resp, 0, sizeof(resp));
+diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
+index e54b3f1b730e0..f8964c8cf0ade 100644
+--- a/drivers/infiniband/core/verbs.c
++++ b/drivers/infiniband/core/verbs.c
+@@ -2149,6 +2149,8 @@ struct ib_mr *ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+ 	mr->pd = pd;
+ 	mr->dm = NULL;
+ 	atomic_inc(&pd->usecnt);
++	mr->iova =  virt_addr;
++	mr->length = length;
+ 
+ 	rdma_restrack_new(&mr->res, RDMA_RESTRACK_MR);
+ 	rdma_restrack_parent_name(&mr->res, &pd->res);
+diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
+index 867972c2a894d..dedfa56f57731 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
++++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
+@@ -249,7 +249,6 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+ 		goto err_alloc_pbl;
+ 
+ 	mr->ibmr.rkey = mr->ibmr.lkey = mr->key;
+-	mr->ibmr.length = length;
+ 
+ 	return &mr->ibmr;
+ 
+diff --git a/drivers/infiniband/hw/irdma/defs.h b/drivers/infiniband/hw/irdma/defs.h
+index e03e03082a5fb..c1906cab5c8ad 100644
+--- a/drivers/infiniband/hw/irdma/defs.h
++++ b/drivers/infiniband/hw/irdma/defs.h
+@@ -314,6 +314,7 @@ enum irdma_cqp_op_type {
+ #define IRDMA_AE_IB_REMOTE_ACCESS_ERROR					0x020d
+ #define IRDMA_AE_IB_REMOTE_OP_ERROR					0x020e
+ #define IRDMA_AE_WQE_LSMM_TOO_LONG					0x0220
++#define IRDMA_AE_INVALID_REQUEST					0x0223
+ #define IRDMA_AE_DDP_INVALID_MSN_GAP_IN_MSN				0x0301
+ #define IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER	0x0303
+ #define IRDMA_AE_DDP_UBE_INVALID_DDP_VERSION				0x0304
+diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c
+index 4f132c6fb653b..ab246447520bd 100644
+--- a/drivers/infiniband/hw/irdma/hw.c
++++ b/drivers/infiniband/hw/irdma/hw.c
+@@ -138,59 +138,68 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp,
+ 	qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
+ 
+ 	switch (info->ae_id) {
+-	case IRDMA_AE_AMP_UNALLOCATED_STAG:
+ 	case IRDMA_AE_AMP_BOUNDS_VIOLATION:
+ 	case IRDMA_AE_AMP_INVALID_STAG:
+-		qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
+-		fallthrough;
++	case IRDMA_AE_AMP_RIGHTS_VIOLATION:
++	case IRDMA_AE_AMP_UNALLOCATED_STAG:
+ 	case IRDMA_AE_AMP_BAD_PD:
+-	case IRDMA_AE_UDA_XMIT_BAD_PD:
++	case IRDMA_AE_AMP_BAD_QP:
++	case IRDMA_AE_AMP_BAD_STAG_KEY:
++	case IRDMA_AE_AMP_BAD_STAG_INDEX:
++	case IRDMA_AE_AMP_TO_WRAP:
++	case IRDMA_AE_PRIV_OPERATION_DENIED:
+ 		qp->flush_code = FLUSH_PROT_ERR;
++		qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
+ 		break;
+-	case IRDMA_AE_AMP_BAD_QP:
++	case IRDMA_AE_UDA_XMIT_BAD_PD:
+ 	case IRDMA_AE_WQE_UNEXPECTED_OPCODE:
+ 		qp->flush_code = FLUSH_LOC_QP_OP_ERR;
++		qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
++		break;
++	case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG:
++	case IRDMA_AE_UDA_XMIT_DGRAM_TOO_SHORT:
++	case IRDMA_AE_UDA_L4LEN_INVALID:
++	case IRDMA_AE_DDP_UBE_INVALID_MO:
++	case IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
++		qp->flush_code = FLUSH_LOC_LEN_ERR;
++		qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
+ 		break;
+-	case IRDMA_AE_AMP_BAD_STAG_KEY:
+-	case IRDMA_AE_AMP_BAD_STAG_INDEX:
+-	case IRDMA_AE_AMP_TO_WRAP:
+-	case IRDMA_AE_AMP_RIGHTS_VIOLATION:
+ 	case IRDMA_AE_AMP_INVALIDATE_NO_REMOTE_ACCESS_RIGHTS:
+-	case IRDMA_AE_PRIV_OPERATION_DENIED:
+-	case IRDMA_AE_IB_INVALID_REQUEST:
+ 	case IRDMA_AE_IB_REMOTE_ACCESS_ERROR:
+ 		qp->flush_code = FLUSH_REM_ACCESS_ERR;
+ 		qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
+ 		break;
+ 	case IRDMA_AE_LLP_SEGMENT_TOO_SMALL:
+-	case IRDMA_AE_DDP_UBE_DDP_MESSAGE_TOO_LONG_FOR_AVAILABLE_BUFFER:
+-	case IRDMA_AE_UDA_XMIT_DGRAM_TOO_LONG:
+-	case IRDMA_AE_UDA_XMIT_DGRAM_TOO_SHORT:
+-	case IRDMA_AE_UDA_L4LEN_INVALID:
++	case IRDMA_AE_LLP_RECEIVED_MPA_CRC_ERROR:
+ 	case IRDMA_AE_ROCE_RSP_LENGTH_ERROR:
+-		qp->flush_code = FLUSH_LOC_LEN_ERR;
++	case IRDMA_AE_IB_REMOTE_OP_ERROR:
++		qp->flush_code = FLUSH_REM_OP_ERR;
++		qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
+ 		break;
+ 	case IRDMA_AE_LCE_QP_CATASTROPHIC:
+ 		qp->flush_code = FLUSH_FATAL_ERR;
++		qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
+ 		break;
+-	case IRDMA_AE_DDP_UBE_INVALID_MO:
+ 	case IRDMA_AE_IB_RREQ_AND_Q1_FULL:
+-	case IRDMA_AE_LLP_RECEIVED_MPA_CRC_ERROR:
+ 		qp->flush_code = FLUSH_GENERAL_ERR;
+ 		break;
+ 	case IRDMA_AE_LLP_TOO_MANY_RETRIES:
+ 		qp->flush_code = FLUSH_RETRY_EXC_ERR;
++		qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
+ 		break;
+ 	case IRDMA_AE_AMP_MWBIND_INVALID_RIGHTS:
+ 	case IRDMA_AE_AMP_MWBIND_BIND_DISABLED:
+ 	case IRDMA_AE_AMP_MWBIND_INVALID_BOUNDS:
+ 		qp->flush_code = FLUSH_MW_BIND_ERR;
++		qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR;
+ 		break;
+-	case IRDMA_AE_IB_REMOTE_OP_ERROR:
+-		qp->flush_code = FLUSH_REM_OP_ERR;
++	case IRDMA_AE_IB_INVALID_REQUEST:
++		qp->flush_code = FLUSH_REM_INV_REQ_ERR;
++		qp->event_type = IRDMA_QP_EVENT_REQ_ERR;
+ 		break;
+ 	default:
+-		qp->flush_code = FLUSH_FATAL_ERR;
++		qp->flush_code = FLUSH_GENERAL_ERR;
++		qp->event_type = IRDMA_QP_EVENT_CATASTROPHIC;
+ 		break;
+ 	}
+ }
+diff --git a/drivers/infiniband/hw/irdma/type.h b/drivers/infiniband/hw/irdma/type.h
+index 9e7b8ecb137ab..517d41a1c2894 100644
+--- a/drivers/infiniband/hw/irdma/type.h
++++ b/drivers/infiniband/hw/irdma/type.h
+@@ -98,6 +98,7 @@ enum irdma_term_mpa_errors {
+ enum irdma_qp_event_type {
+ 	IRDMA_QP_EVENT_CATASTROPHIC,
+ 	IRDMA_QP_EVENT_ACCESS_ERR,
++	IRDMA_QP_EVENT_REQ_ERR,
+ };
+ 
+ enum irdma_hw_stats_index_32b {
+diff --git a/drivers/infiniband/hw/irdma/user.h b/drivers/infiniband/hw/irdma/user.h
+index ddd0ebbdd7d54..2ef61923c9268 100644
+--- a/drivers/infiniband/hw/irdma/user.h
++++ b/drivers/infiniband/hw/irdma/user.h
+@@ -103,6 +103,7 @@ enum irdma_flush_opcode {
+ 	FLUSH_FATAL_ERR,
+ 	FLUSH_RETRY_EXC_ERR,
+ 	FLUSH_MW_BIND_ERR,
++	FLUSH_REM_INV_REQ_ERR,
+ };
+ 
+ enum irdma_cmpl_status {
+diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c
+index 075defaabee53..8dfc9e154d733 100644
+--- a/drivers/infiniband/hw/irdma/utils.c
++++ b/drivers/infiniband/hw/irdma/utils.c
+@@ -2479,6 +2479,9 @@ void irdma_ib_qp_event(struct irdma_qp *iwqp, enum irdma_qp_event_type event)
+ 	case IRDMA_QP_EVENT_ACCESS_ERR:
+ 		ibevent.event = IB_EVENT_QP_ACCESS_ERR;
+ 		break;
++	case IRDMA_QP_EVENT_REQ_ERR:
++		ibevent.event = IB_EVENT_QP_REQ_ERR;
++		break;
+ 	}
+ 	ibevent.device = iwqp->ibqp.device;
+ 	ibevent.element.qp = &iwqp->ibqp;
+diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
+index 9b207f5084eb7..a22afbb25bc58 100644
+--- a/drivers/infiniband/hw/irdma/verbs.c
++++ b/drivers/infiniband/hw/irdma/verbs.c
+@@ -299,13 +299,19 @@ static void irdma_alloc_push_page(struct irdma_qp *iwqp)
+ static int irdma_alloc_ucontext(struct ib_ucontext *uctx,
+ 				struct ib_udata *udata)
+ {
++#define IRDMA_ALLOC_UCTX_MIN_REQ_LEN offsetofend(struct irdma_alloc_ucontext_req, rsvd8)
++#define IRDMA_ALLOC_UCTX_MIN_RESP_LEN offsetofend(struct irdma_alloc_ucontext_resp, rsvd)
+ 	struct ib_device *ibdev = uctx->device;
+ 	struct irdma_device *iwdev = to_iwdev(ibdev);
+-	struct irdma_alloc_ucontext_req req;
++	struct irdma_alloc_ucontext_req req = {};
+ 	struct irdma_alloc_ucontext_resp uresp = {};
+ 	struct irdma_ucontext *ucontext = to_ucontext(uctx);
+ 	struct irdma_uk_attrs *uk_attrs;
+ 
++	if (udata->inlen < IRDMA_ALLOC_UCTX_MIN_REQ_LEN ||
++	    udata->outlen < IRDMA_ALLOC_UCTX_MIN_RESP_LEN)
++		return -EINVAL;
++
+ 	if (ib_copy_from_udata(&req, udata, min(sizeof(req), udata->inlen)))
+ 		return -EINVAL;
+ 
+@@ -317,7 +323,7 @@ static int irdma_alloc_ucontext(struct ib_ucontext *uctx,
+ 
+ 	uk_attrs = &iwdev->rf->sc_dev.hw_attrs.uk_attrs;
+ 	/* GEN_1 legacy support with libi40iw */
+-	if (udata->outlen < sizeof(uresp)) {
++	if (udata->outlen == IRDMA_ALLOC_UCTX_MIN_RESP_LEN) {
+ 		if (uk_attrs->hw_rev != IRDMA_GEN_1)
+ 			return -EOPNOTSUPP;
+ 
+@@ -389,6 +395,7 @@ static void irdma_dealloc_ucontext(struct ib_ucontext *context)
+  */
+ static int irdma_alloc_pd(struct ib_pd *pd, struct ib_udata *udata)
+ {
++#define IRDMA_ALLOC_PD_MIN_RESP_LEN offsetofend(struct irdma_alloc_pd_resp, rsvd)
+ 	struct irdma_pd *iwpd = to_iwpd(pd);
+ 	struct irdma_device *iwdev = to_iwdev(pd->device);
+ 	struct irdma_sc_dev *dev = &iwdev->rf->sc_dev;
+@@ -398,6 +405,9 @@ static int irdma_alloc_pd(struct ib_pd *pd, struct ib_udata *udata)
+ 	u32 pd_id = 0;
+ 	int err;
+ 
++	if (udata && udata->outlen < IRDMA_ALLOC_PD_MIN_RESP_LEN)
++		return -EINVAL;
++
+ 	err = irdma_alloc_rsrc(rf, rf->allocated_pds, rf->max_pd, &pd_id,
+ 			       &rf->next_pd);
+ 	if (err)
+@@ -814,12 +824,14 @@ static int irdma_create_qp(struct ib_qp *ibqp,
+ 			   struct ib_qp_init_attr *init_attr,
+ 			   struct ib_udata *udata)
+ {
++#define IRDMA_CREATE_QP_MIN_REQ_LEN offsetofend(struct irdma_create_qp_req, user_compl_ctx)
++#define IRDMA_CREATE_QP_MIN_RESP_LEN offsetofend(struct irdma_create_qp_resp, rsvd)
+ 	struct ib_pd *ibpd = ibqp->pd;
+ 	struct irdma_pd *iwpd = to_iwpd(ibpd);
+ 	struct irdma_device *iwdev = to_iwdev(ibpd->device);
+ 	struct irdma_pci_f *rf = iwdev->rf;
+ 	struct irdma_qp *iwqp = to_iwqp(ibqp);
+-	struct irdma_create_qp_req req;
++	struct irdma_create_qp_req req = {};
+ 	struct irdma_create_qp_resp uresp = {};
+ 	u32 qp_num = 0;
+ 	int err_code;
+@@ -836,6 +848,10 @@ static int irdma_create_qp(struct ib_qp *ibqp,
+ 	if (err_code)
+ 		return err_code;
+ 
++	if (udata && (udata->inlen < IRDMA_CREATE_QP_MIN_REQ_LEN ||
++		      udata->outlen < IRDMA_CREATE_QP_MIN_RESP_LEN))
++		return -EINVAL;
++
+ 	sq_size = init_attr->cap.max_send_wr;
+ 	rq_size = init_attr->cap.max_recv_wr;
+ 
+@@ -1120,6 +1136,8 @@ static int irdma_query_pkey(struct ib_device *ibdev, u32 port, u16 index,
+ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 			 int attr_mask, struct ib_udata *udata)
+ {
++#define IRDMA_MODIFY_QP_MIN_REQ_LEN offsetofend(struct irdma_modify_qp_req, rq_flush)
++#define IRDMA_MODIFY_QP_MIN_RESP_LEN offsetofend(struct irdma_modify_qp_resp, push_valid)
+ 	struct irdma_pd *iwpd = to_iwpd(ibqp->pd);
+ 	struct irdma_qp *iwqp = to_iwqp(ibqp);
+ 	struct irdma_device *iwdev = iwqp->iwdev;
+@@ -1138,6 +1156,13 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 	roce_info = &iwqp->roce_info;
+ 	udp_info = &iwqp->udp_info;
+ 
++	if (udata) {
++		/* udata inlen/outlen can be 0 when supporting legacy libi40iw */
++		if ((udata->inlen && udata->inlen < IRDMA_MODIFY_QP_MIN_REQ_LEN) ||
++		    (udata->outlen && udata->outlen < IRDMA_MODIFY_QP_MIN_RESP_LEN))
++			return -EINVAL;
++	}
++
+ 	if (attr_mask & ~IB_QP_ATTR_STANDARD_BITS)
+ 		return -EOPNOTSUPP;
+ 
+@@ -1374,7 +1399,7 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 
+ 			if (iwqp->iwarp_state == IRDMA_QP_STATE_ERROR) {
+ 				spin_unlock_irqrestore(&iwqp->lock, flags);
+-				if (udata) {
++				if (udata && udata->inlen) {
+ 					if (ib_copy_from_udata(&ureq, udata,
+ 					    min(sizeof(ureq), udata->inlen)))
+ 						return -EINVAL;
+@@ -1426,7 +1451,7 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ 		} else {
+ 			iwqp->ibqp_state = attr->qp_state;
+ 		}
+-		if (udata && dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) {
++		if (udata && udata->outlen && dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) {
+ 			struct irdma_ucontext *ucontext;
+ 
+ 			ucontext = rdma_udata_to_drv_context(udata,
+@@ -1466,6 +1491,8 @@ exit:
+ int irdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
+ 		    struct ib_udata *udata)
+ {
++#define IRDMA_MODIFY_QP_MIN_REQ_LEN offsetofend(struct irdma_modify_qp_req, rq_flush)
++#define IRDMA_MODIFY_QP_MIN_RESP_LEN offsetofend(struct irdma_modify_qp_resp, push_valid)
+ 	struct irdma_qp *iwqp = to_iwqp(ibqp);
+ 	struct irdma_device *iwdev = iwqp->iwdev;
+ 	struct irdma_sc_dev *dev = &iwdev->rf->sc_dev;
+@@ -1480,6 +1507,13 @@ int irdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
+ 	int err;
+ 	unsigned long flags;
+ 
++	if (udata) {
++		/* udata inlen/outlen can be 0 when supporting legacy libi40iw */
++		if ((udata->inlen && udata->inlen < IRDMA_MODIFY_QP_MIN_REQ_LEN) ||
++		    (udata->outlen && udata->outlen < IRDMA_MODIFY_QP_MIN_RESP_LEN))
++			return -EINVAL;
++	}
++
+ 	if (attr_mask & ~IB_QP_ATTR_STANDARD_BITS)
+ 		return -EOPNOTSUPP;
+ 
+@@ -1565,7 +1599,7 @@ int irdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
+ 		case IB_QPS_RESET:
+ 			if (iwqp->iwarp_state == IRDMA_QP_STATE_ERROR) {
+ 				spin_unlock_irqrestore(&iwqp->lock, flags);
+-				if (udata) {
++				if (udata && udata->inlen) {
+ 					if (ib_copy_from_udata(&ureq, udata,
+ 					    min(sizeof(ureq), udata->inlen)))
+ 						return -EINVAL;
+@@ -1662,7 +1696,7 @@ int irdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
+ 			}
+ 		}
+ 	}
+-	if (attr_mask & IB_QP_STATE && udata &&
++	if (attr_mask & IB_QP_STATE && udata && udata->outlen &&
+ 	    dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) {
+ 		struct irdma_ucontext *ucontext;
+ 
+@@ -1797,6 +1831,7 @@ static int irdma_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
+ static int irdma_resize_cq(struct ib_cq *ibcq, int entries,
+ 			   struct ib_udata *udata)
+ {
++#define IRDMA_RESIZE_CQ_MIN_REQ_LEN offsetofend(struct irdma_resize_cq_req, user_cq_buffer)
+ 	struct irdma_cq *iwcq = to_iwcq(ibcq);
+ 	struct irdma_sc_dev *dev = iwcq->sc_cq.dev;
+ 	struct irdma_cqp_request *cqp_request;
+@@ -1819,6 +1854,9 @@ static int irdma_resize_cq(struct ib_cq *ibcq, int entries,
+ 	    IRDMA_FEATURE_CQ_RESIZE))
+ 		return -EOPNOTSUPP;
+ 
++	if (udata && udata->inlen < IRDMA_RESIZE_CQ_MIN_REQ_LEN)
++		return -EINVAL;
++
+ 	if (entries > rf->max_cqe)
+ 		return -EINVAL;
+ 
+@@ -1951,6 +1989,8 @@ static int irdma_create_cq(struct ib_cq *ibcq,
+ 			   const struct ib_cq_init_attr *attr,
+ 			   struct ib_udata *udata)
+ {
++#define IRDMA_CREATE_CQ_MIN_REQ_LEN offsetofend(struct irdma_create_cq_req, user_cq_buf)
++#define IRDMA_CREATE_CQ_MIN_RESP_LEN offsetofend(struct irdma_create_cq_resp, cq_size)
+ 	struct ib_device *ibdev = ibcq->device;
+ 	struct irdma_device *iwdev = to_iwdev(ibdev);
+ 	struct irdma_pci_f *rf = iwdev->rf;
+@@ -1969,6 +2009,11 @@ static int irdma_create_cq(struct ib_cq *ibcq,
+ 	err_code = cq_validate_flags(attr->flags, dev->hw_attrs.uk_attrs.hw_rev);
+ 	if (err_code)
+ 		return err_code;
++
++	if (udata && (udata->inlen < IRDMA_CREATE_CQ_MIN_REQ_LEN ||
++		      udata->outlen < IRDMA_CREATE_CQ_MIN_RESP_LEN))
++		return -EINVAL;
++
+ 	err_code = irdma_alloc_rsrc(rf, rf->allocated_cqs, rf->max_cq, &cq_num,
+ 				    &rf->next_cq);
+ 	if (err_code)
+@@ -2746,6 +2791,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
+ 				       u64 virt, int access,
+ 				       struct ib_udata *udata)
+ {
++#define IRDMA_MEM_REG_MIN_REQ_LEN offsetofend(struct irdma_mem_reg_req, sq_pages)
+ 	struct irdma_device *iwdev = to_iwdev(pd->device);
+ 	struct irdma_ucontext *ucontext;
+ 	struct irdma_pble_alloc *palloc;
+@@ -2763,6 +2809,9 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
+ 	if (len > iwdev->rf->sc_dev.hw_attrs.max_mr_size)
+ 		return ERR_PTR(-EINVAL);
+ 
++	if (udata->inlen < IRDMA_MEM_REG_MIN_REQ_LEN)
++		return ERR_PTR(-EINVAL);
++
+ 	region = ib_umem_get(pd->device, start, len, access);
+ 
+ 	if (IS_ERR(region)) {
+@@ -3315,6 +3364,8 @@ static enum ib_wc_status irdma_flush_err_to_ib_wc_status(enum irdma_flush_opcode
+ 		return IB_WC_RETRY_EXC_ERR;
+ 	case FLUSH_MW_BIND_ERR:
+ 		return IB_WC_MW_BIND_ERR;
++	case FLUSH_REM_INV_REQ_ERR:
++		return IB_WC_REM_INV_REQ_ERR;
+ 	case FLUSH_FATAL_ERR:
+ 	default:
+ 		return IB_WC_FATAL_ERR;
+@@ -4296,12 +4347,16 @@ static int irdma_create_user_ah(struct ib_ah *ibah,
+ 				struct rdma_ah_init_attr *attr,
+ 				struct ib_udata *udata)
+ {
++#define IRDMA_CREATE_AH_MIN_RESP_LEN offsetofend(struct irdma_create_ah_resp, rsvd)
+ 	struct irdma_ah *ah = container_of(ibah, struct irdma_ah, ibah);
+ 	struct irdma_device *iwdev = to_iwdev(ibah->pd->device);
+ 	struct irdma_create_ah_resp uresp;
+ 	struct irdma_ah *parent_ah;
+ 	int err;
+ 
++	if (udata && udata->outlen < IRDMA_CREATE_AH_MIN_RESP_LEN)
++		return -EINVAL;
++
+ 	err = irdma_setup_ah(ibah, attr);
+ 	if (err)
+ 		return err;
+diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
+index 04a67b4816086..a40bf58bcdd3a 100644
+--- a/drivers/infiniband/hw/mlx4/mr.c
++++ b/drivers/infiniband/hw/mlx4/mr.c
+@@ -439,7 +439,6 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
+ 		goto err_mr;
+ 
+ 	mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key;
+-	mr->ibmr.length = length;
+ 	mr->ibmr.page_size = 1U << shift;
+ 
+ 	return &mr->ibmr;
+diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
+index 883d7c60143e8..1aa0c772b44d9 100644
+--- a/drivers/infiniband/hw/mlx5/main.c
++++ b/drivers/infiniband/hw/mlx5/main.c
+@@ -1826,6 +1826,9 @@ static int set_ucontext_resp(struct ib_ucontext *uctx,
+ 	if (MLX5_CAP_GEN(dev->mdev, drain_sigerr))
+ 		resp->comp_mask |= MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_SQD2RTS;
+ 
++	resp->comp_mask |=
++		MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_MKEY_UPDATE_TAG;
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c
+index e305bf1dc6c22..901a8b0302360 100644
+--- a/drivers/infiniband/hw/mlx5/odp.c
++++ b/drivers/infiniband/hw/mlx5/odp.c
+@@ -795,7 +795,8 @@ static bool mkey_is_eq(struct mlx5_ib_mkey *mmkey, u32 key)
+ {
+ 	if (!mmkey)
+ 		return false;
+-	if (mmkey->type == MLX5_MKEY_MW)
++	if (mmkey->type == MLX5_MKEY_MW ||
++	    mmkey->type == MLX5_MKEY_INDIRECT_DEVX)
+ 		return mlx5_base_mkey(mmkey->key) == mlx5_base_mkey(key);
+ 	return mmkey->key == key;
+ }
+diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h
+index 22f6cc31d1d63..c2a5c8814a48b 100644
+--- a/drivers/infiniband/sw/rxe/rxe_loc.h
++++ b/drivers/infiniband/sw/rxe/rxe_loc.h
+@@ -64,10 +64,10 @@ int rxe_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
+ 
+ /* rxe_mr.c */
+ u8 rxe_get_next_key(u32 last_key);
+-void rxe_mr_init_dma(struct rxe_pd *pd, int access, struct rxe_mr *mr);
+-int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
++void rxe_mr_init_dma(int access, struct rxe_mr *mr);
++int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
+ 		     int access, struct rxe_mr *mr);
+-int rxe_mr_init_fast(struct rxe_pd *pd, int max_pages, struct rxe_mr *mr);
++int rxe_mr_init_fast(int max_pages, struct rxe_mr *mr);
+ int rxe_mr_copy(struct rxe_mr *mr, u64 iova, void *addr, int length,
+ 		enum rxe_mr_copy_dir dir);
+ int copy_data(struct rxe_pd *pd, int access, struct rxe_dma_info *dma,
+diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
+index 850b80f5ad8bd..af34f198e6456 100644
+--- a/drivers/infiniband/sw/rxe/rxe_mr.c
++++ b/drivers/infiniband/sw/rxe/rxe_mr.c
+@@ -103,17 +103,16 @@ err1:
+ 	return -ENOMEM;
+ }
+ 
+-void rxe_mr_init_dma(struct rxe_pd *pd, int access, struct rxe_mr *mr)
++void rxe_mr_init_dma(int access, struct rxe_mr *mr)
+ {
+ 	rxe_mr_init(access, mr);
+ 
+-	mr->ibmr.pd = &pd->ibpd;
+ 	mr->access = access;
+ 	mr->state = RXE_MR_STATE_VALID;
+ 	mr->type = IB_MR_TYPE_DMA;
+ }
+ 
+-int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
++int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length, u64 iova,
+ 		     int access, struct rxe_mr *mr)
+ {
+ 	struct rxe_map		**map;
+@@ -125,7 +124,7 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
+ 	int err;
+ 	int i;
+ 
+-	umem = ib_umem_get(pd->ibpd.device, start, length, access);
++	umem = ib_umem_get(&rxe->ib_dev, start, length, access);
+ 	if (IS_ERR(umem)) {
+ 		pr_warn("%s: Unable to pin memory region err = %d\n",
+ 			__func__, (int)PTR_ERR(umem));
+@@ -175,7 +174,6 @@ int rxe_mr_init_user(struct rxe_pd *pd, u64 start, u64 length, u64 iova,
+ 		}
+ 	}
+ 
+-	mr->ibmr.pd = &pd->ibpd;
+ 	mr->umem = umem;
+ 	mr->access = access;
+ 	mr->length = length;
+@@ -197,7 +195,7 @@ err_out:
+ 	return err;
+ }
+ 
+-int rxe_mr_init_fast(struct rxe_pd *pd, int max_pages, struct rxe_mr *mr)
++int rxe_mr_init_fast(int max_pages, struct rxe_mr *mr)
+ {
+ 	int err;
+ 
+@@ -208,7 +206,6 @@ int rxe_mr_init_fast(struct rxe_pd *pd, int max_pages, struct rxe_mr *mr)
+ 	if (err)
+ 		goto err1;
+ 
+-	mr->ibmr.pd = &pd->ibpd;
+ 	mr->max_buf = max_pages;
+ 	mr->state = RXE_MR_STATE_FREE;
+ 	mr->type = IB_MR_TYPE_MEM_REG;
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index 516bf9b95e489..d776dfda43b16 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -797,7 +797,9 @@ static void rxe_qp_do_cleanup(struct work_struct *work)
+ 	rxe_cleanup_task(&qp->comp.task);
+ 
+ 	/* flush out any receive wr's or pending requests */
+-	__rxe_do_task(&qp->req.task);
++	if (qp->req.task.func)
++		__rxe_do_task(&qp->req.task);
++
+ 	if (qp->sq.queue) {
+ 		__rxe_do_task(&qp->comp.task);
+ 		__rxe_do_task(&qp->req.task);
+@@ -833,8 +835,10 @@ static void rxe_qp_do_cleanup(struct work_struct *work)
+ 
+ 	free_rd_atomic_resources(qp);
+ 
+-	kernel_sock_shutdown(qp->sk, SHUT_RDWR);
+-	sock_release(qp->sk);
++	if (qp->sk) {
++		kernel_sock_shutdown(qp->sk, SHUT_RDWR);
++		sock_release(qp->sk);
++	}
+ }
+ 
+ /* called when the last reference to the qp is dropped */
+diff --git a/drivers/infiniband/sw/rxe/rxe_queue.c b/drivers/infiniband/sw/rxe/rxe_queue.c
+index dbd4971039c0c..d6dbf5a0058dc 100644
+--- a/drivers/infiniband/sw/rxe/rxe_queue.c
++++ b/drivers/infiniband/sw/rxe/rxe_queue.c
+@@ -112,23 +112,25 @@ static int resize_finish(struct rxe_queue *q, struct rxe_queue *new_q,
+ 			 unsigned int num_elem)
+ {
+ 	enum queue_type type = q->type;
++	u32 new_prod;
+ 	u32 prod;
+ 	u32 cons;
+ 
+ 	if (!queue_empty(q, q->type) && (num_elem < queue_count(q, type)))
+ 		return -EINVAL;
+ 
+-	prod = queue_get_producer(new_q, type);
++	new_prod = queue_get_producer(new_q, type);
++	prod = queue_get_producer(q, type);
+ 	cons = queue_get_consumer(q, type);
+ 
+-	while (!queue_empty(q, type)) {
+-		memcpy(queue_addr_from_index(new_q, prod),
++	while ((prod - cons) & q->index_mask) {
++		memcpy(queue_addr_from_index(new_q, new_prod),
+ 		       queue_addr_from_index(q, cons), new_q->elem_size);
+-		prod = queue_next_index(new_q, prod);
++		new_prod = queue_next_index(new_q, new_prod);
+ 		cons = queue_next_index(q, cons);
+ 	}
+ 
+-	new_q->buf->producer_index = prod;
++	new_q->buf->producer_index = new_prod;
+ 	q->buf->consumer_index = cons;
+ 
+ 	/* update private index copies */
+diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
+index b36ec5c4d5e07..7c336db5cb547 100644
+--- a/drivers/infiniband/sw/rxe/rxe_resp.c
++++ b/drivers/infiniband/sw/rxe/rxe_resp.c
+@@ -809,10 +809,8 @@ static enum resp_states read_reply(struct rxe_qp *qp,
+ 	if (!skb)
+ 		return RESPST_ERR_RNR;
+ 
+-	err = rxe_mr_copy(mr, res->read.va, payload_addr(&ack_pkt),
+-			  payload, RXE_FROM_MR_OBJ);
+-	if (err)
+-		pr_err("Failed copying memory\n");
++	rxe_mr_copy(mr, res->read.va, payload_addr(&ack_pkt),
++		    payload, RXE_FROM_MR_OBJ);
+ 	if (mr)
+ 		rxe_put(mr);
+ 
+@@ -823,10 +821,8 @@ static enum resp_states read_reply(struct rxe_qp *qp,
+ 	}
+ 
+ 	err = rxe_xmit_packet(qp, &ack_pkt, skb);
+-	if (err) {
+-		pr_err("Failed sending RDMA reply.\n");
++	if (err)
+ 		return RESPST_ERR_RNR;
+-	}
+ 
+ 	res->read.va += payload;
+ 	res->read.resid -= payload;
+diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
+index e264cf69bf558..f54a3eba652f2 100644
+--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
++++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
+@@ -903,7 +903,9 @@ static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access)
+ 		return ERR_PTR(-ENOMEM);
+ 
+ 	rxe_get(pd);
+-	rxe_mr_init_dma(pd, access, mr);
++	mr->ibmr.pd = ibpd;
++
++	rxe_mr_init_dma(access, mr);
+ 	rxe_finalize(mr);
+ 
+ 	return &mr->ibmr;
+@@ -928,8 +930,9 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,
+ 
+ 
+ 	rxe_get(pd);
++	mr->ibmr.pd = ibpd;
+ 
+-	err = rxe_mr_init_user(pd, start, length, iova, access, mr);
++	err = rxe_mr_init_user(rxe, start, length, iova, access, mr);
+ 	if (err)
+ 		goto err3;
+ 
+@@ -938,7 +941,6 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,
+ 	return &mr->ibmr;
+ 
+ err3:
+-	rxe_put(pd);
+ 	rxe_cleanup(mr);
+ err2:
+ 	return ERR_PTR(err);
+@@ -962,8 +964,9 @@ static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
+ 	}
+ 
+ 	rxe_get(pd);
++	mr->ibmr.pd = ibpd;
+ 
+-	err = rxe_mr_init_fast(pd, max_num_sg, mr);
++	err = rxe_mr_init_fast(max_num_sg, mr);
+ 	if (err)
+ 		goto err2;
+ 
+@@ -972,7 +975,6 @@ static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
+ 	return &mr->ibmr;
+ 
+ err2:
+-	rxe_put(pd);
+ 	rxe_cleanup(mr);
+ err1:
+ 	return ERR_PTR(err);
+diff --git a/drivers/infiniband/sw/siw/siw.h b/drivers/infiniband/sw/siw/siw.h
+index df03d84c6868a..2f3a9cda3850f 100644
+--- a/drivers/infiniband/sw/siw/siw.h
++++ b/drivers/infiniband/sw/siw/siw.h
+@@ -418,6 +418,7 @@ struct siw_qp {
+ 	struct ib_qp base_qp;
+ 	struct siw_device *sdev;
+ 	struct kref ref;
++	struct completion qp_free;
+ 	struct list_head devq;
+ 	int tx_cpu;
+ 	struct siw_qp_attrs attrs;
+diff --git a/drivers/infiniband/sw/siw/siw_qp.c b/drivers/infiniband/sw/siw/siw_qp.c
+index 7e01f2438afc5..e6f634971228e 100644
+--- a/drivers/infiniband/sw/siw/siw_qp.c
++++ b/drivers/infiniband/sw/siw/siw_qp.c
+@@ -1342,6 +1342,6 @@ void siw_free_qp(struct kref *ref)
+ 	vfree(qp->orq);
+ 
+ 	siw_put_tx_cpu(qp->tx_cpu);
+-
++	complete(&qp->qp_free);
+ 	atomic_dec(&sdev->num_qp);
+ }
+diff --git a/drivers/infiniband/sw/siw/siw_qp_rx.c b/drivers/infiniband/sw/siw/siw_qp_rx.c
+index 875ea6f1b04a2..fd721cc19682e 100644
+--- a/drivers/infiniband/sw/siw/siw_qp_rx.c
++++ b/drivers/infiniband/sw/siw/siw_qp_rx.c
+@@ -961,27 +961,28 @@ out:
+ static int siw_get_trailer(struct siw_qp *qp, struct siw_rx_stream *srx)
+ {
+ 	struct sk_buff *skb = srx->skb;
++	int avail = min(srx->skb_new, srx->fpdu_part_rem);
+ 	u8 *tbuf = (u8 *)&srx->trailer.crc - srx->pad;
+ 	__wsum crc_in, crc_own = 0;
+ 
+ 	siw_dbg_qp(qp, "expected %d, available %d, pad %u\n",
+ 		   srx->fpdu_part_rem, srx->skb_new, srx->pad);
+ 
+-	if (srx->skb_new < srx->fpdu_part_rem)
+-		return -EAGAIN;
+-
+-	skb_copy_bits(skb, srx->skb_offset, tbuf, srx->fpdu_part_rem);
++	skb_copy_bits(skb, srx->skb_offset, tbuf, avail);
+ 
+-	if (srx->mpa_crc_hd && srx->pad)
+-		crypto_shash_update(srx->mpa_crc_hd, tbuf, srx->pad);
++	srx->skb_new -= avail;
++	srx->skb_offset += avail;
++	srx->skb_copied += avail;
++	srx->fpdu_part_rem -= avail;
+ 
+-	srx->skb_new -= srx->fpdu_part_rem;
+-	srx->skb_offset += srx->fpdu_part_rem;
+-	srx->skb_copied += srx->fpdu_part_rem;
++	if (srx->fpdu_part_rem)
++		return -EAGAIN;
+ 
+ 	if (!srx->mpa_crc_hd)
+ 		return 0;
+ 
++	if (srx->pad)
++		crypto_shash_update(srx->mpa_crc_hd, tbuf, srx->pad);
+ 	/*
+ 	 * CRC32 is computed, transmitted and received directly in NBO,
+ 	 * so there's never a reason to convert byte order.
+@@ -1083,10 +1084,9 @@ static int siw_get_hdr(struct siw_rx_stream *srx)
+ 	 * completely received.
+ 	 */
+ 	if (iwarp_pktinfo[opcode].hdr_len > sizeof(struct iwarp_ctrl_tagged)) {
+-		bytes = iwarp_pktinfo[opcode].hdr_len - MIN_DDP_HDR;
++		int hdrlen = iwarp_pktinfo[opcode].hdr_len;
+ 
+-		if (srx->skb_new < bytes)
+-			return -EAGAIN;
++		bytes = min_t(int, hdrlen - MIN_DDP_HDR, srx->skb_new);
+ 
+ 		skb_copy_bits(skb, srx->skb_offset,
+ 			      (char *)c_hdr + srx->fpdu_part_rcvd, bytes);
+@@ -1096,6 +1096,9 @@ static int siw_get_hdr(struct siw_rx_stream *srx)
+ 		srx->skb_new -= bytes;
+ 		srx->skb_offset += bytes;
+ 		srx->skb_copied += bytes;
++
++		if (srx->fpdu_part_rcvd < hdrlen)
++			return -EAGAIN;
+ 	}
+ 
+ 	/*
+diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c
+index 8dedae7ae79e6..3e814cfb298cf 100644
+--- a/drivers/infiniband/sw/siw/siw_verbs.c
++++ b/drivers/infiniband/sw/siw/siw_verbs.c
+@@ -480,6 +480,8 @@ int siw_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,
+ 	list_add_tail(&qp->devq, &sdev->qp_list);
+ 	spin_unlock_irqrestore(&sdev->lock, flags);
+ 
++	init_completion(&qp->qp_free);
++
+ 	return 0;
+ 
+ err_out_xa:
+@@ -624,6 +626,7 @@ int siw_destroy_qp(struct ib_qp *base_qp, struct ib_udata *udata)
+ 	qp->scq = qp->rcq = NULL;
+ 
+ 	siw_qp_put(qp);
++	wait_for_completion(&qp->qp_free);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index d7f69e593a63f..9c9872868aeea 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -2789,7 +2789,7 @@ static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun,
+ static int srp_abort(struct scsi_cmnd *scmnd)
+ {
+ 	struct srp_target_port *target = host_to_target(scmnd->device->host);
+-	struct srp_request *req = (struct srp_request *) scmnd->host_scribble;
++	struct srp_request *req = scsi_cmd_priv(scmnd);
+ 	u32 tag;
+ 	u16 ch_idx;
+ 	struct srp_rdma_ch *ch;
+@@ -2797,8 +2797,6 @@ static int srp_abort(struct scsi_cmnd *scmnd)
+ 
+ 	shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n");
+ 
+-	if (!req)
+-		return SUCCESS;
+ 	tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmnd));
+ 	ch_idx = blk_mq_unique_tag_to_hwq(tag);
+ 	if (WARN_ON_ONCE(ch_idx >= target->ch_count))
+diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+index d32b02336411d..71f7edded9cf2 100644
+--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+@@ -2817,6 +2817,26 @@ static int arm_smmu_dev_disable_feature(struct device *dev,
+ 	}
+ }
+ 
++/*
++ * HiSilicon PCIe tune and trace device can be used to trace TLP headers on the
++ * PCIe link and save the data to memory by DMA. The hardware is restricted to
++ * use identity mapping only.
++ */
++#define IS_HISI_PTT_DEVICE(pdev)	((pdev)->vendor == PCI_VENDOR_ID_HUAWEI && \
++					 (pdev)->device == 0xa12e)
++
++static int arm_smmu_def_domain_type(struct device *dev)
++{
++	if (dev_is_pci(dev)) {
++		struct pci_dev *pdev = to_pci_dev(dev);
++
++		if (IS_HISI_PTT_DEVICE(pdev))
++			return IOMMU_DOMAIN_IDENTITY;
++	}
++
++	return 0;
++}
++
+ static struct iommu_ops arm_smmu_ops = {
+ 	.capable		= arm_smmu_capable,
+ 	.domain_alloc		= arm_smmu_domain_alloc,
+@@ -2831,6 +2851,7 @@ static struct iommu_ops arm_smmu_ops = {
+ 	.sva_unbind		= arm_smmu_sva_unbind,
+ 	.sva_get_pasid		= arm_smmu_sva_get_pasid,
+ 	.page_response		= arm_smmu_page_response,
++	.def_domain_type	= arm_smmu_def_domain_type,
+ 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
+ 	.owner			= THIS_MODULE,
+ 	.default_domain_ops = &(const struct iommu_domain_ops) {
+diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c
+index a99afb5d9011c..259f65291d909 100644
+--- a/drivers/iommu/omap-iommu-debug.c
++++ b/drivers/iommu/omap-iommu-debug.c
+@@ -32,12 +32,12 @@ static inline bool is_omap_iommu_detached(struct omap_iommu *obj)
+ 		ssize_t bytes;						\
+ 		const char *str = "%20s: %08x\n";			\
+ 		const int maxcol = 32;					\
+-		bytes = snprintf(p, maxcol, str, __stringify(name),	\
++		if (len < maxcol)					\
++			goto out;					\
++		bytes = scnprintf(p, maxcol, str, __stringify(name),	\
+ 				 iommu_read_reg(obj, MMU_##name));	\
+ 		p += bytes;						\
+ 		len -= bytes;						\
+-		if (len < maxcol)					\
+-			goto out;					\
+ 	} while (0)
+ 
+ static ssize_t
+diff --git a/drivers/isdn/mISDN/l1oip.h b/drivers/isdn/mISDN/l1oip.h
+index 7ea10db20e3a6..48133d0228120 100644
+--- a/drivers/isdn/mISDN/l1oip.h
++++ b/drivers/isdn/mISDN/l1oip.h
+@@ -59,6 +59,7 @@ struct l1oip {
+ 	int			bundle;		/* bundle channels in one frm */
+ 	int			codec;		/* codec to use for transmis. */
+ 	int			limit;		/* limit number of bchannels */
++	bool			shutdown;	/* if card is released */
+ 
+ 	/* timer */
+ 	struct timer_list	keep_tl;
+diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
+index 2c40412466e6f..a77195e378b7b 100644
+--- a/drivers/isdn/mISDN/l1oip_core.c
++++ b/drivers/isdn/mISDN/l1oip_core.c
+@@ -275,7 +275,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
+ 	p = frame;
+ 
+ 	/* restart timer */
+-	if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ))
++	if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ) && !hc->shutdown)
+ 		mod_timer(&hc->keep_tl, jiffies + L1OIP_KEEPALIVE * HZ);
+ 	else
+ 		hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ;
+@@ -601,7 +601,9 @@ multiframe:
+ 		goto multiframe;
+ 
+ 	/* restart timer */
+-	if (time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || !hc->timeout_on) {
++	if ((time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) ||
++	     !hc->timeout_on) &&
++	    !hc->shutdown) {
+ 		hc->timeout_on = 1;
+ 		mod_timer(&hc->timeout_tl, jiffies + L1OIP_TIMEOUT * HZ);
+ 	} else /* only adjust timer */
+@@ -1232,11 +1234,10 @@ release_card(struct l1oip *hc)
+ {
+ 	int	ch;
+ 
+-	if (timer_pending(&hc->keep_tl))
+-		del_timer(&hc->keep_tl);
++	hc->shutdown = true;
+ 
+-	if (timer_pending(&hc->timeout_tl))
+-		del_timer(&hc->timeout_tl);
++	del_timer_sync(&hc->keep_tl);
++	del_timer_sync(&hc->timeout_tl);
+ 
+ 	cancel_work_sync(&hc->workq);
+ 
+diff --git a/drivers/leds/flash/leds-lm3601x.c b/drivers/leds/flash/leds-lm3601x.c
+index d0e1d4814042e..3d12727482017 100644
+--- a/drivers/leds/flash/leds-lm3601x.c
++++ b/drivers/leds/flash/leds-lm3601x.c
+@@ -444,8 +444,6 @@ static int lm3601x_remove(struct i2c_client *client)
+ {
+ 	struct lm3601x_led *led = i2c_get_clientdata(client);
+ 
+-	mutex_destroy(&led->lock);
+-
+ 	return regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
+ 			   LM3601X_ENABLE_MASK,
+ 			   LM3601X_MODE_STANDBY);
+diff --git a/drivers/mailbox/bcm-flexrm-mailbox.c b/drivers/mailbox/bcm-flexrm-mailbox.c
+index fda16f76401e0..bf6e86b0ed09c 100644
+--- a/drivers/mailbox/bcm-flexrm-mailbox.c
++++ b/drivers/mailbox/bcm-flexrm-mailbox.c
+@@ -622,15 +622,15 @@ static int flexrm_spu_dma_map(struct device *dev, struct brcm_message *msg)
+ 
+ 	rc = dma_map_sg(dev, msg->spu.src, sg_nents(msg->spu.src),
+ 			DMA_TO_DEVICE);
+-	if (rc < 0)
+-		return rc;
++	if (!rc)
++		return -EIO;
+ 
+ 	rc = dma_map_sg(dev, msg->spu.dst, sg_nents(msg->spu.dst),
+ 			DMA_FROM_DEVICE);
+-	if (rc < 0) {
++	if (!rc) {
+ 		dma_unmap_sg(dev, msg->spu.src, sg_nents(msg->spu.src),
+ 			     DMA_TO_DEVICE);
+-		return rc;
++		return -EIO;
+ 	}
+ 
+ 	return 0;
+diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
+index 02922073c9efd..20f2ec880ad69 100644
+--- a/drivers/mailbox/imx-mailbox.c
++++ b/drivers/mailbox/imx-mailbox.c
+@@ -904,7 +904,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = {
+ 	.xTR	= 0x20,
+ 	.xRR	= 0x40,
+ 	.xSR	= {0x60, 0x60, 0x60, 0x60},
+-	.xCR	= {0x64, 0x64, 0x64, 0x64},
++	.xCR	= {0x64, 0x64, 0x64, 0x64, 0x64},
+ };
+ 
+ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = {
+@@ -927,7 +927,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp_s4 = {
+ 	.xTR	= 0x200,
+ 	.xRR	= 0x280,
+ 	.xSR	= {0xC, 0x118, 0x124, 0x12C},
+-	.xCR	= {0x110, 0x114, 0x120, 0x128},
++	.xCR	= {0x8, 0x110, 0x114, 0x120, 0x128},
+ };
+ 
+ static const struct imx_mu_dcfg imx_mu_cfg_imx93_s4 = {
+@@ -938,7 +938,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx93_s4 = {
+ 	.xTR	= 0x200,
+ 	.xRR	= 0x280,
+ 	.xSR	= {0xC, 0x118, 0x124, 0x12C},
+-	.xCR	= {0x110, 0x114, 0x120, 0x128},
++	.xCR	= {0x8, 0x110, 0x114, 0x120, 0x128},
+ };
+ 
+ static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = {
+@@ -949,7 +949,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = {
+ 	.xTR	= 0x0,
+ 	.xRR	= 0x10,
+ 	.xSR	= {0x20, 0x20, 0x20, 0x20},
+-	.xCR	= {0x24, 0x24, 0x24, 0x24},
++	.xCR	= {0x24, 0x24, 0x24, 0x24, 0x24},
+ };
+ 
+ static const struct imx_mu_dcfg imx_mu_cfg_imx8_seco = {
+@@ -960,7 +960,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8_seco = {
+ 	.xTR	= 0x0,
+ 	.xRR	= 0x10,
+ 	.xSR	= {0x20, 0x20, 0x20, 0x20},
+-	.xCR	= {0x24, 0x24, 0x24, 0x24},
++	.xCR	= {0x24, 0x24, 0x24, 0x24, 0x24},
+ };
+ 
+ static const struct of_device_id imx_mu_dt_ids[] = {
+diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c
+index 4e34854d12389..cfacb3f320a64 100644
+--- a/drivers/mailbox/mailbox-mpfs.c
++++ b/drivers/mailbox/mailbox-mpfs.c
+@@ -62,6 +62,7 @@ struct mpfs_mbox {
+ 	struct mbox_controller controller;
+ 	struct device *dev;
+ 	int irq;
++	void __iomem *ctrl_base;
+ 	void __iomem *mbox_base;
+ 	void __iomem *int_reg;
+ 	struct mbox_chan chans[1];
+@@ -73,7 +74,7 @@ static bool mpfs_mbox_busy(struct mpfs_mbox *mbox)
+ {
+ 	u32 status;
+ 
+-	status = readl_relaxed(mbox->mbox_base + SERVICES_SR_OFFSET);
++	status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET);
+ 
+ 	return status & SCB_STATUS_BUSY_MASK;
+ }
+@@ -99,29 +100,27 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)
+ 
+ 		for (index = 0; index < (msg->cmd_data_size / 4); index++)
+ 			writel_relaxed(word_buf[index],
+-				       mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4);
++				       mbox->mbox_base + msg->mbox_offset + index * 0x4);
+ 		if (extra_bits) {
+ 			u8 i;
+ 			u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4);
+ 			u8 *byte_buf = msg->cmd_data + byte_off;
+ 
+-			val = readl_relaxed(mbox->mbox_base +
+-					    MAILBOX_REG_OFFSET + index * 0x4);
++			val = readl_relaxed(mbox->mbox_base + msg->mbox_offset + index * 0x4);
+ 
+ 			for (i = 0u; i < extra_bits; i++) {
+ 				val &= ~(0xffu << (i * 8u));
+ 				val |= (byte_buf[i] << (i * 8u));
+ 			}
+ 
+-			writel_relaxed(val,
+-				       mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4);
++			writel_relaxed(val, mbox->mbox_base + msg->mbox_offset + index * 0x4);
+ 		}
+ 	}
+ 
+ 	opt_sel = ((msg->mbox_offset << 7u) | (msg->cmd_opcode & 0x7fu));
+ 	tx_trigger = (opt_sel << SCB_CTRL_POS) & SCB_CTRL_MASK;
+ 	tx_trigger |= SCB_CTRL_REQ_MASK | SCB_STATUS_NOTIFY_MASK;
+-	writel_relaxed(tx_trigger, mbox->mbox_base + SERVICES_CR_OFFSET);
++	writel_relaxed(tx_trigger, mbox->ctrl_base + SERVICES_CR_OFFSET);
+ 
+ 	return 0;
+ }
+@@ -141,7 +140,7 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan)
+ 	if (!mpfs_mbox_busy(mbox)) {
+ 		for (i = 0; i < num_words; i++) {
+ 			response->resp_msg[i] =
+-				readl_relaxed(mbox->mbox_base + MAILBOX_REG_OFFSET
++				readl_relaxed(mbox->mbox_base
+ 					      + mbox->resp_offset + i * 0x4);
+ 		}
+ 	}
+@@ -200,14 +199,18 @@ static int mpfs_mbox_probe(struct platform_device *pdev)
+ 	if (!mbox)
+ 		return -ENOMEM;
+ 
+-	mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 0, &regs);
+-	if (IS_ERR(mbox->mbox_base))
+-		return PTR_ERR(mbox->mbox_base);
++	mbox->ctrl_base = devm_platform_get_and_ioremap_resource(pdev, 0, &regs);
++	if (IS_ERR(mbox->ctrl_base))
++		return PTR_ERR(mbox->ctrl_base);
+ 
+ 	mbox->int_reg = devm_platform_get_and_ioremap_resource(pdev, 1, &regs);
+ 	if (IS_ERR(mbox->int_reg))
+ 		return PTR_ERR(mbox->int_reg);
+ 
++	mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 2, &regs);
++	if (IS_ERR(mbox->mbox_base)) // account for the old dt-binding w/ 2 regs
++		mbox->mbox_base = mbox->ctrl_base + MAILBOX_REG_OFFSET;
++
+ 	mbox->irq = platform_get_irq(pdev, 0);
+ 	if (mbox->irq < 0)
+ 		return mbox->irq;
+diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
+index 3f0ff3aab6f23..9c227e4a84654 100644
+--- a/drivers/md/bcache/writeback.c
++++ b/drivers/md/bcache/writeback.c
+@@ -157,6 +157,53 @@ static void __update_writeback_rate(struct cached_dev *dc)
+ 	dc->writeback_rate_target = target;
+ }
+ 
++static bool idle_counter_exceeded(struct cache_set *c)
++{
++	int counter, dev_nr;
++
++	/*
++	 * If c->idle_counter is overflow (idel for really long time),
++	 * reset as 0 and not set maximum rate this time for code
++	 * simplicity.
++	 */
++	counter = atomic_inc_return(&c->idle_counter);
++	if (counter <= 0) {
++		atomic_set(&c->idle_counter, 0);
++		return false;
++	}
++
++	dev_nr = atomic_read(&c->attached_dev_nr);
++	if (dev_nr == 0)
++		return false;
++
++	/*
++	 * c->idle_counter is increased by writeback thread of all
++	 * attached backing devices, in order to represent a rough
++	 * time period, counter should be divided by dev_nr.
++	 * Otherwise the idle time cannot be larger with more backing
++	 * device attached.
++	 * The following calculation equals to checking
++	 *	(counter / dev_nr) < (dev_nr * 6)
++	 */
++	if (counter < (dev_nr * dev_nr * 6))
++		return false;
++
++	return true;
++}
++
++/*
++ * Idle_counter is increased every time when update_writeback_rate() is
++ * called. If all backing devices attached to the same cache set have
++ * identical dc->writeback_rate_update_seconds values, it is about 6
++ * rounds of update_writeback_rate() on each backing device before
++ * c->at_max_writeback_rate is set to 1, and then max wrteback rate set
++ * to each dc->writeback_rate.rate.
++ * In order to avoid extra locking cost for counting exact dirty cached
++ * devices number, c->attached_dev_nr is used to calculate the idle
++ * throushold. It might be bigger if not all cached device are in write-
++ * back mode, but it still works well with limited extra rounds of
++ * update_writeback_rate().
++ */
+ static bool set_at_max_writeback_rate(struct cache_set *c,
+ 				       struct cached_dev *dc)
+ {
+@@ -167,21 +214,8 @@ static bool set_at_max_writeback_rate(struct cache_set *c,
+ 	/* Don't set max writeback rate if gc is running */
+ 	if (!c->gc_mark_valid)
+ 		return false;
+-	/*
+-	 * Idle_counter is increased everytime when update_writeback_rate() is
+-	 * called. If all backing devices attached to the same cache set have
+-	 * identical dc->writeback_rate_update_seconds values, it is about 6
+-	 * rounds of update_writeback_rate() on each backing device before
+-	 * c->at_max_writeback_rate is set to 1, and then max wrteback rate set
+-	 * to each dc->writeback_rate.rate.
+-	 * In order to avoid extra locking cost for counting exact dirty cached
+-	 * devices number, c->attached_dev_nr is used to calculate the idle
+-	 * throushold. It might be bigger if not all cached device are in write-
+-	 * back mode, but it still works well with limited extra rounds of
+-	 * update_writeback_rate().
+-	 */
+-	if (atomic_inc_return(&c->idle_counter) <
+-	    atomic_read(&c->attached_dev_nr) * 6)
++
++	if (!idle_counter_exceeded(c))
+ 		return false;
+ 
+ 	if (atomic_read(&c->at_max_writeback_rate) != 1)
+@@ -195,13 +229,10 @@ static bool set_at_max_writeback_rate(struct cache_set *c,
+ 	dc->writeback_rate_change = 0;
+ 
+ 	/*
+-	 * Check c->idle_counter and c->at_max_writeback_rate agagain in case
+-	 * new I/O arrives during before set_at_max_writeback_rate() returns.
+-	 * Then the writeback rate is set to 1, and its new value should be
+-	 * decided via __update_writeback_rate().
++	 * In case new I/O arrives during before
++	 * set_at_max_writeback_rate() returns.
+ 	 */
+-	if ((atomic_read(&c->idle_counter) <
+-	     atomic_read(&c->attached_dev_nr) * 6) ||
++	if (!idle_counter_exceeded(c) ||
+ 	    !atomic_read(&c->at_max_writeback_rate))
+ 		return false;
+ 
+diff --git a/drivers/md/dm-verity-loadpin.c b/drivers/md/dm-verity-loadpin.c
+index 387ec43aef728..4f78cc55c2514 100644
+--- a/drivers/md/dm-verity-loadpin.c
++++ b/drivers/md/dm-verity-loadpin.c
+@@ -14,6 +14,7 @@ LIST_HEAD(dm_verity_loadpin_trusted_root_digests);
+ 
+ static bool is_trusted_verity_target(struct dm_target *ti)
+ {
++	int verity_mode;
+ 	u8 *root_digest;
+ 	unsigned int digest_size;
+ 	struct dm_verity_loadpin_trusted_root_digest *trd;
+@@ -22,6 +23,13 @@ static bool is_trusted_verity_target(struct dm_target *ti)
+ 	if (!dm_is_verity_target(ti))
+ 		return false;
+ 
++	verity_mode = dm_verity_get_mode(ti);
++
++	if ((verity_mode != DM_VERITY_MODE_EIO) &&
++	    (verity_mode != DM_VERITY_MODE_RESTART) &&
++	    (verity_mode != DM_VERITY_MODE_PANIC))
++		return false;
++
+ 	if (dm_verity_get_root_digest(ti, &root_digest, &digest_size))
+ 		return false;
+ 
+diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
+index 94b6cb599db4f..8a00cc42e4985 100644
+--- a/drivers/md/dm-verity-target.c
++++ b/drivers/md/dm-verity-target.c
+@@ -1446,6 +1446,22 @@ bool dm_is_verity_target(struct dm_target *ti)
+ 	return ti->type->module == THIS_MODULE;
+ }
+ 
++/*
++ * Get the verity mode (error behavior) of a verity target.
++ *
++ * Returns the verity mode of the target, or -EINVAL if 'ti' is not a verity
++ * target.
++ */
++int dm_verity_get_mode(struct dm_target *ti)
++{
++	struct dm_verity *v = ti->private;
++
++	if (!dm_is_verity_target(ti))
++		return -EINVAL;
++
++	return v->mode;
++}
++
+ /*
+  * Get the root digest of a verity target.
+  *
+diff --git a/drivers/md/dm-verity.h b/drivers/md/dm-verity.h
+index 45455de1b4bc5..98f306ec6a33d 100644
+--- a/drivers/md/dm-verity.h
++++ b/drivers/md/dm-verity.h
+@@ -134,6 +134,7 @@ extern int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io,
+ 				 sector_t block, u8 *digest, bool *is_zero);
+ 
+ extern bool dm_is_verity_target(struct dm_target *ti);
++extern int dm_verity_get_mode(struct dm_target *ti);
+ extern int dm_verity_get_root_digest(struct dm_target *ti, u8 **root_digest,
+ 				     unsigned int *digest_size);
+ 
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 729be2c5296c6..470a975e4be9b 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -8156,7 +8156,6 @@ static void *md_seq_start(struct seq_file *seq, loff_t *pos)
+ 	list_for_each(tmp,&all_mddevs)
+ 		if (!l--) {
+ 			mddev = list_entry(tmp, struct mddev, all_mddevs);
+-			mddev_get(mddev);
+ 			if (!mddev_get(mddev))
+ 				continue;
+ 			spin_unlock(&all_mddevs_lock);
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
+index 78addfe4a0c92..857c49399c28e 100644
+--- a/drivers/md/raid0.c
++++ b/drivers/md/raid0.c
+@@ -47,7 +47,7 @@ static void dump_zones(struct mddev *mddev)
+ 		int len = 0;
+ 
+ 		for (k = 0; k < conf->strip_zone[j].nb_dev; k++)
+-			len += snprintf(line+len, 200-len, "%s%pg", k?"/":"",
++			len += scnprintf(line+len, 200-len, "%s%pg", k?"/":"",
+ 				conf->devlist[j * raid_disks + k]->bdev);
+ 		pr_debug("md: zone%d=[%s]\n", j, line);
+ 
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
+index 31a0cbf63384d..caaae10e33f81 100644
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -36,6 +36,7 @@
+  */
+ 
+ #include <linux/blkdev.h>
++#include <linux/delay.h>
+ #include <linux/kthread.h>
+ #include <linux/raid/pq.h>
+ #include <linux/async_tx.h>
+@@ -4047,7 +4048,7 @@ static void handle_stripe_fill(struct stripe_head *sh,
+ 		 * back cache (prexor with orig_page, and then xor with
+ 		 * page) in the read path
+ 		 */
+-		if (s->injournal && s->failed) {
++		if (s->to_read && s->injournal && s->failed) {
+ 			if (test_bit(STRIPE_R5C_CACHING, &sh->state))
+ 				r5c_make_stripe_write_out(sh);
+ 			goto out;
+@@ -5542,7 +5543,6 @@ static int raid5_read_one_chunk(struct mddev *mddev, struct bio *raid_bio)
+ 
+ 	if (is_badblock(rdev, sector, bio_sectors(raid_bio), &first_bad,
+ 			&bad_sectors)) {
+-		bio_put(raid_bio);
+ 		rdev_dec_pending(rdev, mddev);
+ 		return 0;
+ 	}
+@@ -6781,7 +6781,18 @@ static void raid5d(struct md_thread *thread)
+ 			spin_unlock_irq(&conf->device_lock);
+ 			md_check_recovery(mddev);
+ 			spin_lock_irq(&conf->device_lock);
++
++			/*
++			 * Waiting on MD_SB_CHANGE_PENDING below may deadlock
++			 * seeing md_check_recovery() is needed to clear
++			 * the flag when using mdmon.
++			 */
++			continue;
+ 		}
++
++		wait_event_lock_irq(mddev->sb_wait,
++			!test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags),
++			conf->device_lock);
+ 	}
+ 	pr_debug("%d stripes handled\n", handled);
+ 
+diff --git a/drivers/media/pci/cx88/cx88-vbi.c b/drivers/media/pci/cx88/cx88-vbi.c
+index a075788c64d45..469aeaa725ad9 100644
+--- a/drivers/media/pci/cx88/cx88-vbi.c
++++ b/drivers/media/pci/cx88/cx88-vbi.c
+@@ -144,11 +144,10 @@ static int buffer_prepare(struct vb2_buffer *vb)
+ 		return -EINVAL;
+ 	vb2_set_plane_payload(vb, 0, size);
+ 
+-	cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl,
+-			 0, VBI_LINE_LENGTH * lines,
+-			 VBI_LINE_LENGTH, 0,
+-			 lines);
+-	return 0;
++	return cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl,
++				0, VBI_LINE_LENGTH * lines,
++				VBI_LINE_LENGTH, 0,
++				lines);
+ }
+ 
+ static void buffer_finish(struct vb2_buffer *vb)
+diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
+index d3729be892529..b509c2a03852b 100644
+--- a/drivers/media/pci/cx88/cx88-video.c
++++ b/drivers/media/pci/cx88/cx88-video.c
+@@ -431,6 +431,7 @@ static int queue_setup(struct vb2_queue *q,
+ 
+ static int buffer_prepare(struct vb2_buffer *vb)
+ {
++	int ret;
+ 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ 	struct cx8800_dev *dev = vb->vb2_queue->drv_priv;
+ 	struct cx88_core *core = dev->core;
+@@ -445,35 +446,35 @@ static int buffer_prepare(struct vb2_buffer *vb)
+ 
+ 	switch (core->field) {
+ 	case V4L2_FIELD_TOP:
+-		cx88_risc_buffer(dev->pci, &buf->risc,
+-				 sgt->sgl, 0, UNSET,
+-				 buf->bpl, 0, core->height);
++		ret = cx88_risc_buffer(dev->pci, &buf->risc,
++				       sgt->sgl, 0, UNSET,
++				       buf->bpl, 0, core->height);
+ 		break;
+ 	case V4L2_FIELD_BOTTOM:
+-		cx88_risc_buffer(dev->pci, &buf->risc,
+-				 sgt->sgl, UNSET, 0,
+-				 buf->bpl, 0, core->height);
++		ret = cx88_risc_buffer(dev->pci, &buf->risc,
++				       sgt->sgl, UNSET, 0,
++				       buf->bpl, 0, core->height);
+ 		break;
+ 	case V4L2_FIELD_SEQ_TB:
+-		cx88_risc_buffer(dev->pci, &buf->risc,
+-				 sgt->sgl,
+-				 0, buf->bpl * (core->height >> 1),
+-				 buf->bpl, 0,
+-				 core->height >> 1);
++		ret = cx88_risc_buffer(dev->pci, &buf->risc,
++				       sgt->sgl,
++				       0, buf->bpl * (core->height >> 1),
++				       buf->bpl, 0,
++				       core->height >> 1);
+ 		break;
+ 	case V4L2_FIELD_SEQ_BT:
+-		cx88_risc_buffer(dev->pci, &buf->risc,
+-				 sgt->sgl,
+-				 buf->bpl * (core->height >> 1), 0,
+-				 buf->bpl, 0,
+-				 core->height >> 1);
++		ret = cx88_risc_buffer(dev->pci, &buf->risc,
++				       sgt->sgl,
++				       buf->bpl * (core->height >> 1), 0,
++				       buf->bpl, 0,
++				       core->height >> 1);
+ 		break;
+ 	case V4L2_FIELD_INTERLACED:
+ 	default:
+-		cx88_risc_buffer(dev->pci, &buf->risc,
+-				 sgt->sgl, 0, buf->bpl,
+-				 buf->bpl, buf->bpl,
+-				 core->height >> 1);
++		ret = cx88_risc_buffer(dev->pci, &buf->risc,
++				       sgt->sgl, 0, buf->bpl,
++				       buf->bpl, buf->bpl,
++				       core->height >> 1);
+ 		break;
+ 	}
+ 	dprintk(2,
+@@ -481,7 +482,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
+ 		buf, buf->vb.vb2_buf.index, __func__,
+ 		core->width, core->height, dev->fmt->depth, dev->fmt->fourcc,
+ 		(unsigned long)buf->risc.dma);
+-	return 0;
++	return ret;
+ }
+ 
+ static void buffer_finish(struct vb2_buffer *vb)
+diff --git a/drivers/media/platform/amlogic/meson-ge2d/ge2d.c b/drivers/media/platform/amlogic/meson-ge2d/ge2d.c
+index 5e7b319f300df..142d421a8d769 100644
+--- a/drivers/media/platform/amlogic/meson-ge2d/ge2d.c
++++ b/drivers/media/platform/amlogic/meson-ge2d/ge2d.c
+@@ -1030,7 +1030,6 @@ static int ge2d_remove(struct platform_device *pdev)
+ 
+ 	video_unregister_device(ge2d->vfd);
+ 	v4l2_m2m_release(ge2d->m2m_dev);
+-	video_device_release(ge2d->vfd);
+ 	v4l2_device_unregister(&ge2d->v4l2_dev);
+ 	clk_disable_unprepare(ge2d->clk);
+ 
+diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
+index 9e64041cc1c1d..feb75dc204de8 100644
+--- a/drivers/media/platform/amphion/vdec.c
++++ b/drivers/media/platform/amphion/vdec.c
+@@ -808,14 +808,6 @@ static void vdec_init_fmt(struct vpu_inst *inst)
+ 		inst->cap_format.field = V4L2_FIELD_NONE;
+ 	else
+ 		inst->cap_format.field = V4L2_FIELD_SEQ_TB;
+-	if (vdec->codec_info.color_primaries == V4L2_COLORSPACE_DEFAULT)
+-		vdec->codec_info.color_primaries = V4L2_COLORSPACE_REC709;
+-	if (vdec->codec_info.transfer_chars == V4L2_XFER_FUNC_DEFAULT)
+-		vdec->codec_info.transfer_chars = V4L2_XFER_FUNC_709;
+-	if (vdec->codec_info.matrix_coeffs == V4L2_YCBCR_ENC_DEFAULT)
+-		vdec->codec_info.matrix_coeffs = V4L2_YCBCR_ENC_709;
+-	if (vdec->codec_info.full_range == V4L2_QUANTIZATION_DEFAULT)
+-		vdec->codec_info.full_range = V4L2_QUANTIZATION_LIM_RANGE;
+ }
+ 
+ static void vdec_init_crop(struct vpu_inst *inst)
+@@ -1555,6 +1547,14 @@ static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i
+ 				vdec->codec_info.frame_rate.numerator,
+ 				vdec->codec_info.frame_rate.denominator);
+ 		break;
++	case 9:
++		num = scnprintf(str, size, "colorspace: %d, %d, %d, %d (%d)\n",
++				vdec->codec_info.color_primaries,
++				vdec->codec_info.transfer_chars,
++				vdec->codec_info.matrix_coeffs,
++				vdec->codec_info.full_range,
++				vdec->codec_info.vui_present);
++		break;
+ 	default:
+ 		break;
+ 	}
+diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c
+index 461524dd1e441..37212f087fdd9 100644
+--- a/drivers/media/platform/amphion/venc.c
++++ b/drivers/media/platform/amphion/venc.c
+@@ -644,7 +644,7 @@ static int venc_ctrl_init(struct vpu_inst *inst)
+ 			  BITRATE_DEFAULT_PEAK);
+ 
+ 	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+-			  V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30);
++			  V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 8000, 1, 30);
+ 
+ 	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+ 			  V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);
+diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h
+index f914de6ed81e9..beac0309ca8d9 100644
+--- a/drivers/media/platform/amphion/vpu.h
++++ b/drivers/media/platform/amphion/vpu.h
+@@ -119,7 +119,6 @@ struct vpu_mbox {
+ enum vpu_core_state {
+ 	VPU_CORE_DEINIT = 0,
+ 	VPU_CORE_ACTIVE,
+-	VPU_CORE_SNAPSHOT,
+ 	VPU_CORE_HANG
+ };
+ 
+diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c
+index 73faa50d28653..f9ec1753f7c86 100644
+--- a/drivers/media/platform/amphion/vpu_core.c
++++ b/drivers/media/platform/amphion/vpu_core.c
+@@ -89,7 +89,7 @@ static int vpu_core_boot_done(struct vpu_core *core)
+ 		core->supported_instance_count = min(core->supported_instance_count, count);
+ 	}
+ 	core->fw_version = fw_version;
+-	core->state = VPU_CORE_ACTIVE;
++	vpu_core_set_state(core, VPU_CORE_ACTIVE);
+ 
+ 	return 0;
+ }
+@@ -172,10 +172,26 @@ int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf)
+ 	return __vpu_alloc_dma(core->dev, buf);
+ }
+ 
+-static void vpu_core_check_hang(struct vpu_core *core)
++void vpu_core_set_state(struct vpu_core *core, enum vpu_core_state state)
+ {
+-	if (core->hang_mask)
+-		core->state = VPU_CORE_HANG;
++	if (state != core->state)
++		vpu_trace(core->dev, "vpu core state change from %d to %d\n", core->state, state);
++	core->state = state;
++	if (core->state == VPU_CORE_DEINIT)
++		core->hang_mask = 0;
++}
++
++static void vpu_core_update_state(struct vpu_core *core)
++{
++	if (!vpu_iface_get_power_state(core)) {
++		if (core->request_count)
++			vpu_core_set_state(core, VPU_CORE_HANG);
++		else
++			vpu_core_set_state(core, VPU_CORE_DEINIT);
++
++	} else if (core->state == VPU_CORE_ACTIVE && core->hang_mask) {
++		vpu_core_set_state(core, VPU_CORE_HANG);
++	}
+ }
+ 
+ static struct vpu_core *vpu_core_find_proper_by_type(struct vpu_dev *vpu, u32 type)
+@@ -188,11 +204,13 @@ static struct vpu_core *vpu_core_find_proper_by_type(struct vpu_dev *vpu, u32 ty
+ 		dev_dbg(c->dev, "instance_mask = 0x%lx, state = %d\n", c->instance_mask, c->state);
+ 		if (c->type != type)
+ 			continue;
++		mutex_lock(&c->lock);
++		vpu_core_update_state(c);
++		mutex_unlock(&c->lock);
+ 		if (c->state == VPU_CORE_DEINIT) {
+ 			core = c;
+ 			break;
+ 		}
+-		vpu_core_check_hang(c);
+ 		if (c->state != VPU_CORE_ACTIVE)
+ 			continue;
+ 		if (c->request_count < request_count) {
+@@ -409,6 +427,12 @@ int vpu_inst_register(struct vpu_inst *inst)
+ 	}
+ 
+ 	mutex_lock(&core->lock);
++	if (core->state != VPU_CORE_ACTIVE) {
++		dev_err(core->dev, "vpu core is not active, state = %d\n", core->state);
++		ret = -EINVAL;
++		goto exit;
++	}
++
+ 	if (inst->id >= 0 && inst->id < core->supported_instance_count)
+ 		goto exit;
+ 
+@@ -450,7 +474,7 @@ int vpu_inst_unregister(struct vpu_inst *inst)
+ 		vpu_core_release_instance(core, inst->id);
+ 		inst->id = VPU_INST_NULL_ID;
+ 	}
+-	vpu_core_check_hang(core);
++	vpu_core_update_state(core);
+ 	if (core->state == VPU_CORE_HANG && !core->instance_mask) {
+ 		int err;
+ 
+@@ -459,7 +483,7 @@ int vpu_inst_unregister(struct vpu_inst *inst)
+ 		err = vpu_core_sw_reset(core);
+ 		mutex_lock(&core->lock);
+ 		if (!err) {
+-			core->state = VPU_CORE_ACTIVE;
++			vpu_core_set_state(core, VPU_CORE_ACTIVE);
+ 			core->hang_mask = 0;
+ 		}
+ 	}
+@@ -609,7 +633,7 @@ static int vpu_core_probe(struct platform_device *pdev)
+ 	mutex_init(&core->cmd_lock);
+ 	init_completion(&core->cmp);
+ 	init_waitqueue_head(&core->ack_wq);
+-	core->state = VPU_CORE_DEINIT;
++	vpu_core_set_state(core, VPU_CORE_DEINIT);
+ 
+ 	core->res = of_device_get_match_data(dev);
+ 	if (!core->res)
+@@ -758,33 +782,18 @@ static int __maybe_unused vpu_core_resume(struct device *dev)
+ 	mutex_lock(&core->lock);
+ 	pm_runtime_resume_and_get(dev);
+ 	vpu_core_get_vpu(core);
+-	if (core->state != VPU_CORE_SNAPSHOT)
+-		goto exit;
+ 
+-	if (!vpu_iface_get_power_state(core)) {
+-		if (!list_empty(&core->instances)) {
++	if (core->request_count) {
++		if (!vpu_iface_get_power_state(core))
+ 			ret = vpu_core_boot(core, false);
+-			if (ret) {
+-				dev_err(core->dev, "%s boot fail\n", __func__);
+-				core->state = VPU_CORE_DEINIT;
+-				goto exit;
+-			}
+-		} else {
+-			core->state = VPU_CORE_DEINIT;
+-		}
+-	} else {
+-		if (!list_empty(&core->instances)) {
++		else
+ 			ret = vpu_core_sw_reset(core);
+-			if (ret) {
+-				dev_err(core->dev, "%s sw_reset fail\n", __func__);
+-				core->state = VPU_CORE_HANG;
+-				goto exit;
+-			}
++		if (ret) {
++			dev_err(core->dev, "resume fail\n");
++			vpu_core_set_state(core, VPU_CORE_HANG);
+ 		}
+-		core->state = VPU_CORE_ACTIVE;
+ 	}
+-
+-exit:
++	vpu_core_update_state(core);
+ 	pm_runtime_put_sync(dev);
+ 	mutex_unlock(&core->lock);
+ 
+@@ -798,18 +807,11 @@ static int __maybe_unused vpu_core_suspend(struct device *dev)
+ 	int ret = 0;
+ 
+ 	mutex_lock(&core->lock);
+-	if (core->state == VPU_CORE_ACTIVE) {
+-		if (!list_empty(&core->instances)) {
+-			ret = vpu_core_snapshot(core);
+-			if (ret) {
+-				mutex_unlock(&core->lock);
+-				return ret;
+-			}
+-		}
+-
+-		core->state = VPU_CORE_SNAPSHOT;
+-	}
++	if (core->request_count)
++		ret = vpu_core_snapshot(core);
+ 	mutex_unlock(&core->lock);
++	if (ret)
++		return ret;
+ 
+ 	vpu_core_cancel_work(core);
+ 
+diff --git a/drivers/media/platform/amphion/vpu_core.h b/drivers/media/platform/amphion/vpu_core.h
+index 00a662997da4f..65b562642603a 100644
+--- a/drivers/media/platform/amphion/vpu_core.h
++++ b/drivers/media/platform/amphion/vpu_core.h
+@@ -11,5 +11,6 @@ u32 csr_readl(struct vpu_core *core, u32 reg);
+ int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf);
+ void vpu_free_dma(struct vpu_buffer *buf);
+ struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index);
++void vpu_core_set_state(struct vpu_core *core, enum vpu_core_state state);
+ 
+ #endif
+diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c
+index f72c8a506b220..260f1c4b8f8dc 100644
+--- a/drivers/media/platform/amphion/vpu_dbg.c
++++ b/drivers/media/platform/amphion/vpu_dbg.c
+@@ -15,6 +15,7 @@
+ #include <linux/debugfs.h>
+ #include "vpu.h"
+ #include "vpu_defs.h"
++#include "vpu_core.h"
+ #include "vpu_helpers.h"
+ #include "vpu_cmds.h"
+ #include "vpu_rpc.h"
+@@ -233,6 +234,10 @@ static int vpu_dbg_core(struct seq_file *s, void *data)
+ 	if (seq_write(s, str, num))
+ 		return 0;
+ 
++	num = scnprintf(str, sizeof(str), "power %s\n",
++			vpu_iface_get_power_state(core) ? "on" : "off");
++	if (seq_write(s, str, num))
++		return 0;
+ 	num = scnprintf(str, sizeof(str), "state = %d\n", core->state);
+ 	if (seq_write(s, str, num))
+ 		return 0;
+@@ -346,10 +351,10 @@ static ssize_t vpu_dbg_core_write(struct file *file,
+ 
+ 	pm_runtime_resume_and_get(core->dev);
+ 	mutex_lock(&core->lock);
+-	if (core->state != VPU_CORE_DEINIT && !core->instance_mask) {
++	if (vpu_iface_get_power_state(core) && !core->request_count) {
+ 		dev_info(core->dev, "reset\n");
+ 		if (!vpu_core_sw_reset(core)) {
+-			core->state = VPU_CORE_ACTIVE;
++			vpu_core_set_state(core, VPU_CORE_ACTIVE);
+ 			core->hang_mask = 0;
+ 		}
+ 	}
+diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
+index f4a488bf98801..51e0702f9ae17 100644
+--- a/drivers/media/platform/amphion/vpu_malone.c
++++ b/drivers/media/platform/amphion/vpu_malone.c
+@@ -1293,7 +1293,7 @@ static int vpu_malone_insert_scode_vc1_g_pic(struct malone_scode_t *scode)
+ 	vbuf = to_vb2_v4l2_buffer(scode->vb);
+ 	data = vb2_plane_vaddr(scode->vb, 0);
+ 
+-	if (vbuf->sequence == 0 || vpu_vb_is_codecconfig(vbuf))
++	if (scode->inst->total_input_count == 0 || vpu_vb_is_codecconfig(vbuf))
+ 		return 0;
+ 	if (MALONE_VC1_CONTAIN_NAL(*data))
+ 		return 0;
+diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+index 87685a62a5c23..3071b61946c3b 100644
+--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
++++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+@@ -1414,7 +1414,6 @@ static int mtk_jpeg_remove(struct platform_device *pdev)
+ 
+ 	pm_runtime_disable(&pdev->dev);
+ 	video_unregister_device(jpeg->vdev);
+-	video_device_release(jpeg->vdev);
+ 	v4l2_m2m_release(jpeg->m2m_dev);
+ 	v4l2_device_unregister(&jpeg->v4l2_dev);
+ 
+diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c
+index 25e8168635975..27c5fdaabed45 100644
+--- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c
++++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_enc.c
+@@ -1403,7 +1403,8 @@ int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx)
+ 			       V4L2_MPEG_VIDEO_VP8_PROFILE_0, 0, V4L2_MPEG_VIDEO_VP8_PROFILE_0);
+ 	v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+ 			       V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+-			       0, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
++			       ~(1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR),
++			       V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
+ 
+ 
+ 	if (handler->error) {
+diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is.c b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
+index e3072d69c49fa..a7704ff069d6c 100644
+--- a/drivers/media/platform/samsung/exynos4-is/fimc-is.c
++++ b/drivers/media/platform/samsung/exynos4-is/fimc-is.c
+@@ -213,6 +213,7 @@ static int fimc_is_register_subdevs(struct fimc_is *is)
+ 
+ 			if (ret < 0 || index >= FIMC_IS_SENSORS_NUM) {
+ 				of_node_put(child);
++				of_node_put(i2c_bus);
+ 				return ret;
+ 			}
+ 			index++;
+diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+index 761341934925e..f85d1eebaface 100644
+--- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
++++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c
+@@ -1399,6 +1399,7 @@ static int s5p_mfc_probe(struct platform_device *pdev)
+ /* Deinit MFC if probe had failed */
+ err_enc_reg:
+ 	video_unregister_device(dev->vfd_dec);
++	dev->vfd_dec = NULL;
+ err_dec_reg:
+ 	video_device_release(dev->vfd_enc);
+ err_enc_alloc:
+@@ -1444,8 +1445,6 @@ static int s5p_mfc_remove(struct platform_device *pdev)
+ 
+ 	video_unregister_device(dev->vfd_enc);
+ 	video_unregister_device(dev->vfd_dec);
+-	video_device_release(dev->vfd_enc);
+-	video_device_release(dev->vfd_dec);
+ 	v4l2_device_unregister(&dev->v4l2_dev);
+ 	s5p_mfc_unconfigure_dma_memory(dev);
+ 
+diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
+index f34f8b077e03c..0a16c218a50a7 100644
+--- a/drivers/media/platform/xilinx/xilinx-vipp.c
++++ b/drivers/media/platform/xilinx/xilinx-vipp.c
+@@ -471,7 +471,7 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev)
+ {
+ 	struct device_node *ports;
+ 	struct device_node *port;
+-	int ret;
++	int ret = 0;
+ 
+ 	ports = of_get_child_by_name(xdev->dev->of_node, "ports");
+ 	if (ports == NULL) {
+@@ -481,13 +481,14 @@ static int xvip_graph_dma_init(struct xvip_composite_device *xdev)
+ 
+ 	for_each_child_of_node(ports, port) {
+ 		ret = xvip_graph_dma_init_one(xdev, port);
+-		if (ret < 0) {
++		if (ret) {
+ 			of_node_put(port);
+-			return ret;
++			break;
+ 		}
+ 	}
+ 
+-	return 0;
++	of_node_put(ports);
++	return ret;
+ }
+ 
+ static void xvip_graph_cleanup(struct xvip_composite_device *xdev)
+diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c
+index 240a7cc56777d..7b1c40132555b 100644
+--- a/drivers/media/usb/airspy/airspy.c
++++ b/drivers/media/usb/airspy/airspy.c
+@@ -1070,6 +1070,10 @@ static int airspy_probe(struct usb_interface *intf,
+ 				ret);
+ 		goto err_free_controls;
+ 	}
++
++	/* Free buf if success*/
++	kfree(buf);
++
+ 	dev_info(s->dev, "Registered as %s\n",
+ 			video_device_node_name(&s->vdev));
+ 	dev_notice(s->dev, "SDR API is still slightly experimental and functionality changes may follow\n");
+diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
+index 8c208db9600b4..53250ea75dfb7 100644
+--- a/drivers/media/usb/uvc/uvc_ctrl.c
++++ b/drivers/media/usb/uvc/uvc_ctrl.c
+@@ -985,36 +985,56 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,
+ 	return value;
+ }
+ 
+-static int __uvc_ctrl_get(struct uvc_video_chain *chain,
+-	struct uvc_control *ctrl, struct uvc_control_mapping *mapping,
+-	s32 *value)
++static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain,
++			       struct uvc_control *ctrl)
+ {
++	u8 *data;
+ 	int ret;
+ 
+-	if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
+-		return -EACCES;
++	if (ctrl->loaded)
++		return 0;
+ 
+-	if (!ctrl->loaded) {
+-		if (ctrl->entity->get_cur) {
+-			ret = ctrl->entity->get_cur(chain->dev,
+-				ctrl->entity,
+-				ctrl->info.selector,
+-				uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+-				ctrl->info.size);
+-		} else {
+-			ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
+-				ctrl->entity->id,
+-				chain->dev->intfnum,
+-				ctrl->info.selector,
+-				uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+-				ctrl->info.size);
+-		}
+-		if (ret < 0)
+-			return ret;
++	data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT);
+ 
++	if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
++		memset(data, 0, ctrl->info.size);
+ 		ctrl->loaded = 1;
++
++		return 0;
+ 	}
+ 
++	if (ctrl->entity->get_cur)
++		ret = ctrl->entity->get_cur(chain->dev, ctrl->entity,
++					    ctrl->info.selector, data,
++					    ctrl->info.size);
++	else
++		ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
++				     ctrl->entity->id, chain->dev->intfnum,
++				     ctrl->info.selector, data,
++				     ctrl->info.size);
++
++	if (ret < 0)
++		return ret;
++
++	ctrl->loaded = 1;
++
++	return ret;
++}
++
++static int __uvc_ctrl_get(struct uvc_video_chain *chain,
++			  struct uvc_control *ctrl,
++			  struct uvc_control_mapping *mapping,
++			  s32 *value)
++{
++	int ret;
++
++	if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
++		return -EACCES;
++
++	ret = __uvc_ctrl_load_cur(chain, ctrl);
++	if (ret < 0)
++		return ret;
++
+ 	*value = __uvc_ctrl_get_value(mapping,
+ 				uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
+ 
+@@ -1810,21 +1830,10 @@ int uvc_ctrl_set(struct uvc_fh *handle,
+ 	 * needs to be loaded from the device to perform the read-modify-write
+ 	 * operation.
+ 	 */
+-	if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) {
+-		if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
+-			memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+-				0, ctrl->info.size);
+-		} else {
+-			ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
+-				ctrl->entity->id, chain->dev->intfnum,
+-				ctrl->info.selector,
+-				uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
+-				ctrl->info.size);
+-			if (ret < 0)
+-				return ret;
+-		}
+-
+-		ctrl->loaded = 1;
++	if ((ctrl->info.size * 8) != mapping->size) {
++		ret = __uvc_ctrl_load_cur(chain, ctrl);
++		if (ret < 0)
++			return ret;
+ 	}
+ 
+ 	/* Backup the current value in case we need to rollback later. */
+diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
+index d509a4a2f08e9..822e9694f0926 100644
+--- a/drivers/media/usb/uvc/uvc_driver.c
++++ b/drivers/media/usb/uvc/uvc_driver.c
+@@ -1553,10 +1553,6 @@ static int uvc_gpio_parse(struct uvc_device *dev)
+ 	if (IS_ERR_OR_NULL(gpio_privacy))
+ 		return PTR_ERR_OR_ZERO(gpio_privacy);
+ 
+-	unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
+-	if (!unit)
+-		return -ENOMEM;
+-
+ 	irq = gpiod_to_irq(gpio_privacy);
+ 	if (irq < 0) {
+ 		if (irq != EPROBE_DEFER)
+@@ -1565,6 +1561,10 @@ static int uvc_gpio_parse(struct uvc_device *dev)
+ 		return irq;
+ 	}
+ 
++	unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
++	if (!unit)
++		return -ENOMEM;
++
+ 	unit->gpio.gpio_privacy = gpio_privacy;
+ 	unit->gpio.irq = irq;
+ 	unit->gpio.bControlSize = 1;
+diff --git a/drivers/memory/of_memory.c b/drivers/memory/of_memory.c
+index dbdf87bc0b78e..fcd20d85d3857 100644
+--- a/drivers/memory/of_memory.c
++++ b/drivers/memory/of_memory.c
+@@ -134,6 +134,7 @@ const struct lpddr2_timings *of_get_ddr_timings(struct device_node *np_ddr,
+ 	for_each_child_of_node(np_ddr, np_tim) {
+ 		if (of_device_is_compatible(np_tim, tim_compat)) {
+ 			if (of_do_get_timings(np_tim, &timings[i])) {
++				of_node_put(np_tim);
+ 				devm_kfree(dev, timings);
+ 				goto default_timings;
+ 			}
+@@ -284,6 +285,7 @@ const struct lpddr3_timings
+ 		if (of_device_is_compatible(np_tim, tim_compat)) {
+ 			if (of_lpddr3_do_get_timings(np_tim, &timings[i])) {
+ 				devm_kfree(dev, timings);
++				of_node_put(np_tim);
+ 				goto default_timings;
+ 			}
+ 			i++;
+diff --git a/drivers/memory/pl353-smc.c b/drivers/memory/pl353-smc.c
+index f84b98278745c..d39ee7d06665b 100644
+--- a/drivers/memory/pl353-smc.c
++++ b/drivers/memory/pl353-smc.c
+@@ -122,6 +122,7 @@ static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id)
+ 	}
+ 
+ 	of_platform_device_create(child, NULL, &adev->dev);
++	of_node_put(child);
+ 
+ 	return 0;
+ 
+diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c
+index 2774b2cbaea6d..c2acdbcd5d6b6 100644
+--- a/drivers/mfd/da9062-core.c
++++ b/drivers/mfd/da9062-core.c
+@@ -453,6 +453,7 @@ static const struct regmap_range da9061_aa_writeable_ranges[] = {
+ 	regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B),
+ 	regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
+ 	regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
++	regmap_reg_range(DA9062AA_CONFIG_J, DA9062AA_CONFIG_J),
+ 	regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19),
+ };
+ 
+diff --git a/drivers/mfd/fsl-imx25-tsadc.c b/drivers/mfd/fsl-imx25-tsadc.c
+index 37e5e02a1d059..823595bcc9b7c 100644
+--- a/drivers/mfd/fsl-imx25-tsadc.c
++++ b/drivers/mfd/fsl-imx25-tsadc.c
+@@ -69,7 +69,7 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev,
+ 	int irq;
+ 
+ 	irq = platform_get_irq(pdev, 0);
+-	if (irq <= 0)
++	if (irq < 0)
+ 		return irq;
+ 
+ 	tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops,
+@@ -84,6 +84,19 @@ static int mx25_tsadc_setup_irq(struct platform_device *pdev,
+ 	return 0;
+ }
+ 
++static int mx25_tsadc_unset_irq(struct platform_device *pdev)
++{
++	struct mx25_tsadc *tsadc = platform_get_drvdata(pdev);
++	int irq = platform_get_irq(pdev, 0);
++
++	if (irq >= 0) {
++		irq_set_chained_handler_and_data(irq, NULL, NULL);
++		irq_domain_remove(tsadc->domain);
++	}
++
++	return 0;
++}
++
+ static void mx25_tsadc_setup_clk(struct platform_device *pdev,
+ 				 struct mx25_tsadc *tsadc)
+ {
+@@ -171,18 +184,21 @@ static int mx25_tsadc_probe(struct platform_device *pdev)
+ 
+ 	platform_set_drvdata(pdev, tsadc);
+ 
+-	return devm_of_platform_populate(dev);
++	ret = devm_of_platform_populate(dev);
++	if (ret)
++		goto err_irq;
++
++	return 0;
++
++err_irq:
++	mx25_tsadc_unset_irq(pdev);
++
++	return ret;
+ }
+ 
+ static int mx25_tsadc_remove(struct platform_device *pdev)
+ {
+-	struct mx25_tsadc *tsadc = platform_get_drvdata(pdev);
+-	int irq = platform_get_irq(pdev, 0);
+-
+-	if (irq) {
+-		irq_set_chained_handler_and_data(irq, NULL, NULL);
+-		irq_domain_remove(tsadc->domain);
+-	}
++	mx25_tsadc_unset_irq(pdev);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c
+index 5e8c94e008ed1..85d070bce0e2b 100644
+--- a/drivers/mfd/intel_soc_pmic_core.c
++++ b/drivers/mfd/intel_soc_pmic_core.c
+@@ -77,6 +77,7 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c,
+ 	return 0;
+ 
+ err_del_irq_chip:
++	pwm_remove_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup));
+ 	regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data);
+ 	return ret;
+ }
+diff --git a/drivers/mfd/lp8788-irq.c b/drivers/mfd/lp8788-irq.c
+index 348439a3fbbd4..39006297f3d27 100644
+--- a/drivers/mfd/lp8788-irq.c
++++ b/drivers/mfd/lp8788-irq.c
+@@ -175,6 +175,7 @@ int lp8788_irq_init(struct lp8788 *lp, int irq)
+ 				IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ 				"lp8788-irq", irqd);
+ 	if (ret) {
++		irq_domain_remove(lp->irqdm);
+ 		dev_err(lp->dev, "failed to create a thread for IRQ_N\n");
+ 		return ret;
+ 	}
+@@ -188,4 +189,6 @@ void lp8788_irq_exit(struct lp8788 *lp)
+ {
+ 	if (lp->irq)
+ 		free_irq(lp->irq, lp->irqdm);
++	if (lp->irqdm)
++		irq_domain_remove(lp->irqdm);
+ }
+diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c
+index c223d2c6a3635..998e8cc408a0e 100644
+--- a/drivers/mfd/lp8788.c
++++ b/drivers/mfd/lp8788.c
+@@ -195,8 +195,16 @@ static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+ 	if (ret)
+ 		return ret;
+ 
+-	return mfd_add_devices(lp->dev, -1, lp8788_devs,
+-			       ARRAY_SIZE(lp8788_devs), NULL, 0, NULL);
++	ret = mfd_add_devices(lp->dev, -1, lp8788_devs,
++			      ARRAY_SIZE(lp8788_devs), NULL, 0, NULL);
++	if (ret)
++		goto err_exit_irq;
++
++	return 0;
++
++err_exit_irq:
++	lp8788_irq_exit(lp);
++	return ret;
+ }
+ 
+ static int lp8788_remove(struct i2c_client *cl)
+diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
+index bc0a2c38653e5..3ac4508a6742a 100644
+--- a/drivers/mfd/sm501.c
++++ b/drivers/mfd/sm501.c
+@@ -1720,7 +1720,12 @@ static struct platform_driver sm501_plat_driver = {
+ 
+ static int __init sm501_base_init(void)
+ {
+-	platform_driver_register(&sm501_plat_driver);
++	int ret;
++
++	ret = platform_driver_register(&sm501_plat_driver);
++	if (ret < 0)
++		return ret;
++
+ 	return pci_register_driver(&sm501_pci_driver);
+ }
+ 
+diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c
+index 6777c419a8da2..d46dba2df5a10 100644
+--- a/drivers/misc/ocxl/file.c
++++ b/drivers/misc/ocxl/file.c
+@@ -257,6 +257,8 @@ static long afu_ioctl(struct file *file, unsigned int cmd,
+ 		if (IS_ERR(ev_ctx))
+ 			return PTR_ERR(ev_ctx);
+ 		rc = ocxl_irq_set_handler(ctx, irq_id, irq_handler, irq_free, ev_ctx);
++		if (rc)
++			eventfd_ctx_put(ev_ctx);
+ 		break;
+ 
+ 	case OCXL_IOCTL_GET_METADATA:
+diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
+index ce89611a136e9..54cd009aee50e 100644
+--- a/drivers/mmc/core/block.c
++++ b/drivers/mmc/core/block.c
+@@ -1140,8 +1140,12 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
+ {
+ 	struct mmc_blk_data *md = mq->blkdata;
+ 	struct mmc_card *card = md->queue.card;
++	unsigned int arg = card->erase_arg;
+ 
+-	mmc_blk_issue_erase_rq(mq, req, MMC_BLK_DISCARD, card->erase_arg);
++	if (mmc_card_broken_sd_discard(card))
++		arg = SD_ERASE_ARG;
++
++	mmc_blk_issue_erase_rq(mq, req, MMC_BLK_DISCARD, arg);
+ }
+ 
+ static void mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
+diff --git a/drivers/mmc/core/card.h b/drivers/mmc/core/card.h
+index 99045e138ba48..cfdd1ff40b865 100644
+--- a/drivers/mmc/core/card.h
++++ b/drivers/mmc/core/card.h
+@@ -73,6 +73,7 @@ struct mmc_fixup {
+ #define EXT_CSD_REV_ANY (-1u)
+ 
+ #define CID_MANFID_SANDISK      0x2
++#define CID_MANFID_SANDISK_SD   0x3
+ #define CID_MANFID_ATP          0x9
+ #define CID_MANFID_TOSHIBA      0x11
+ #define CID_MANFID_MICRON       0x13
+@@ -258,4 +259,9 @@ static inline int mmc_card_broken_hpi(const struct mmc_card *c)
+ 	return c->quirks & MMC_QUIRK_BROKEN_HPI;
+ }
+ 
++static inline int mmc_card_broken_sd_discard(const struct mmc_card *c)
++{
++	return c->quirks & MMC_QUIRK_BROKEN_SD_DISCARD;
++}
++
+ #endif
+diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
+index be43939880868..29b9497936df9 100644
+--- a/drivers/mmc/core/quirks.h
++++ b/drivers/mmc/core/quirks.h
+@@ -100,6 +100,12 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = {
+ 	MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
+ 		  MMC_QUIRK_TRIM_BROKEN),
+ 
++	/*
++	 * Some SD cards reports discard support while they don't
++	 */
++	MMC_FIXUP(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, add_quirk_sd,
++		  MMC_QUIRK_BROKEN_SD_DISCARD),
++
+ 	END_FIXUP
+ };
+ 
+diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
+index a9a0837153d87..c88b039dc9fbd 100644
+--- a/drivers/mmc/host/au1xmmc.c
++++ b/drivers/mmc/host/au1xmmc.c
+@@ -1097,8 +1097,9 @@ out5:
+ 	if (host->platdata && host->platdata->cd_setup &&
+ 	    !(mmc->caps & MMC_CAP_NEEDS_POLL))
+ 		host->platdata->cd_setup(mmc, 0);
+-out_clk:
++
+ 	clk_disable_unprepare(host->clk);
++out_clk:
+ 	clk_put(host->clk);
+ out_irq:
+ 	free_irq(host->irq, host);
+diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
+index 6edbf5c161ab9..b970699743e0a 100644
+--- a/drivers/mmc/host/renesas_sdhi_core.c
++++ b/drivers/mmc/host/renesas_sdhi_core.c
+@@ -128,6 +128,7 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
+ 	struct clk *ref_clk = priv->clk;
+ 	unsigned int freq, diff, best_freq = 0, diff_min = ~0;
+ 	unsigned int new_clock, clkh_shift = 0;
++	unsigned int new_upper_limit;
+ 	int i;
+ 
+ 	/*
+@@ -153,13 +154,20 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
+ 	 * greater than, new_clock.  As we can divide by 1 << i for
+ 	 * any i in [0, 9] we want the input clock to be as close as
+ 	 * possible, but no greater than, new_clock << i.
++	 *
++	 * Add an upper limit of 1/1024 rate higher to the clock rate to fix
++	 * clk rate jumping to lower rate due to rounding error (eg: RZ/G2L has
++	 * 3 clk sources 533.333333 MHz, 400 MHz and 266.666666 MHz. The request
++	 * for 533.333333 MHz will selects a slower 400 MHz due to rounding
++	 * error (533333333 Hz / 4 * 4 = 533333332 Hz < 533333333 Hz)).
+ 	 */
+ 	for (i = min(9, ilog2(UINT_MAX / new_clock)); i >= 0; i--) {
+ 		freq = clk_round_rate(ref_clk, new_clock << i);
+-		if (freq > (new_clock << i)) {
++		new_upper_limit = (new_clock << i) + ((new_clock << i) >> 10);
++		if (freq > new_upper_limit) {
+ 			/* Too fast; look for a slightly slower option */
+ 			freq = clk_round_rate(ref_clk, (new_clock << i) / 4 * 3);
+-			if (freq > (new_clock << i))
++			if (freq > new_upper_limit)
+ 				continue;
+ 		}
+ 
+@@ -181,6 +189,7 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
+ static void renesas_sdhi_set_clock(struct tmio_mmc_host *host,
+ 				   unsigned int new_clock)
+ {
++	unsigned int clk_margin;
+ 	u32 clk = 0, clock;
+ 
+ 	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
+@@ -194,7 +203,13 @@ static void renesas_sdhi_set_clock(struct tmio_mmc_host *host,
+ 	host->mmc->actual_clock = renesas_sdhi_clk_update(host, new_clock);
+ 	clock = host->mmc->actual_clock / 512;
+ 
+-	for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1)
++	/*
++	 * Add a margin of 1/1024 rate higher to the clock rate in order
++	 * to avoid clk variable setting a value of 0 due to the margin
++	 * provided for actual_clock in renesas_sdhi_clk_update().
++	 */
++	clk_margin = new_clock >> 10;
++	for (clk = 0x80000080; new_clock + clk_margin >= (clock << 1); clk >>= 1)
+ 		clock <<= 1;
+ 
+ 	/* 1/1 clock is option */
+diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
+index dc2991422a873..3a091a387ecbc 100644
+--- a/drivers/mmc/host/sdhci-msm.c
++++ b/drivers/mmc/host/sdhci-msm.c
+@@ -2441,6 +2441,7 @@ static const struct of_device_id sdhci_msm_dt_match[] = {
+ 	 */
+ 	{.compatible = "qcom,sdhci-msm-v4", .data = &sdhci_msm_mci_var},
+ 	{.compatible = "qcom,sdhci-msm-v5", .data = &sdhci_msm_v5_var},
++	{.compatible = "qcom,sdm670-sdhci", .data = &sdm845_sdhci_var},
+ 	{.compatible = "qcom,sdm845-sdhci", .data = &sdm845_sdhci_var},
+ 	{.compatible = "qcom,sc7180-sdhci", .data = &sdm845_sdhci_var},
+ 	{},
+diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c
+index f33e9349e4e62..3b88c9d3ddf90 100644
+--- a/drivers/mmc/host/sdhci-sprd.c
++++ b/drivers/mmc/host/sdhci-sprd.c
+@@ -309,7 +309,7 @@ static unsigned int sdhci_sprd_get_max_clock(struct sdhci_host *host)
+ 
+ static unsigned int sdhci_sprd_get_min_clock(struct sdhci_host *host)
+ {
+-	return 400000;
++	return 100000;
+ }
+ 
+ static void sdhci_sprd_set_uhs_signaling(struct sdhci_host *host,
+diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
+index 2d2d8260c6814..413925bce0ca8 100644
+--- a/drivers/mmc/host/sdhci-tegra.c
++++ b/drivers/mmc/host/sdhci-tegra.c
+@@ -773,7 +773,7 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
+ 		dev_err(dev, "failed to set clk rate to %luHz: %d\n",
+ 			host_clk, err);
+ 
+-	tegra_host->curr_clk_rate = host_clk;
++	tegra_host->curr_clk_rate = clk_get_rate(pltfm_host->clk);
+ 	if (tegra_host->ddr_signaling)
+ 		host->max_clk = host_clk;
+ 	else
+diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c
+index 163ac9df8cca0..9b5c503e3a3fc 100644
+--- a/drivers/mmc/host/wmt-sdmmc.c
++++ b/drivers/mmc/host/wmt-sdmmc.c
+@@ -846,7 +846,7 @@ static int wmt_mci_probe(struct platform_device *pdev)
+ 	if (IS_ERR(priv->clk_sdmmc)) {
+ 		dev_err(&pdev->dev, "Error getting clock\n");
+ 		ret = PTR_ERR(priv->clk_sdmmc);
+-		goto fail5;
++		goto fail5_and_a_half;
+ 	}
+ 
+ 	ret = clk_prepare_enable(priv->clk_sdmmc);
+@@ -863,6 +863,9 @@ static int wmt_mci_probe(struct platform_device *pdev)
+ 	return 0;
+ fail6:
+ 	clk_put(priv->clk_sdmmc);
++fail5_and_a_half:
++	dma_free_coherent(&pdev->dev, mmc->max_blk_count * 16,
++			  priv->dma_desc_buffer, priv->dma_desc_device_addr);
+ fail5:
+ 	free_irq(dma_irq, priv);
+ fail4:
+diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
+index 5b0ae5ddad745..27c08f22dec8c 100644
+--- a/drivers/mtd/devices/docg3.c
++++ b/drivers/mtd/devices/docg3.c
+@@ -1974,9 +1974,14 @@ static int __init docg3_probe(struct platform_device *pdev)
+ 		dev_err(dev, "No I/O memory resource defined\n");
+ 		return ret;
+ 	}
+-	base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE);
+ 
+ 	ret = -ENOMEM;
++	base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE);
++	if (!base) {
++		dev_err(dev, "devm_ioremap dev failed\n");
++		return ret;
++	}
++
+ 	cascade = devm_kcalloc(dev, DOC_MAX_NBFLOORS, sizeof(*cascade),
+ 			       GFP_KERNEL);
+ 	if (!cascade)
+diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
+index c9ac3baf68c02..41c6bd6e2d72c 100644
+--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
++++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
+@@ -405,6 +405,7 @@ static int atmel_nand_dma_transfer(struct atmel_nand_controller *nc,
+ 
+ 	dma_async_issue_pending(nc->dmac);
+ 	wait_for_completion(&finished);
++	dma_unmap_single(nc->dev, buf_dma, len, dir);
+ 
+ 	return 0;
+ 
+diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
+index aab93b9e6052d..a18d121396aa5 100644
+--- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
++++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
+@@ -726,36 +726,40 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)
+ 	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
+ 	unsigned int al;
+ 
+-	switch (chip->ecc.engine_type) {
+ 	/*
+ 	 * if ECC was not chosen in DT, decide whether to use HW or SW ECC from
+ 	 * CS Base Register
+ 	 */
+-	case NAND_ECC_ENGINE_TYPE_NONE:
++	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID) {
+ 		/* If CS Base Register selects full hardware ECC then use it */
+ 		if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) ==
+ 		    BR_DECC_CHK_GEN) {
+-			chip->ecc.read_page = fsl_elbc_read_page;
+-			chip->ecc.write_page = fsl_elbc_write_page;
+-			chip->ecc.write_subpage = fsl_elbc_write_subpage;
+-
+ 			chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
+-			mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops);
+-			chip->ecc.size = 512;
+-			chip->ecc.bytes = 3;
+-			chip->ecc.strength = 1;
+ 		} else {
+ 			/* otherwise fall back to default software ECC */
+ 			chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+ 			chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
+ 		}
++	}
++
++	switch (chip->ecc.engine_type) {
++	/* if HW ECC was chosen, setup ecc and oob layout */
++	case NAND_ECC_ENGINE_TYPE_ON_HOST:
++		chip->ecc.read_page = fsl_elbc_read_page;
++		chip->ecc.write_page = fsl_elbc_write_page;
++		chip->ecc.write_subpage = fsl_elbc_write_subpage;
++		mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops);
++		chip->ecc.size = 512;
++		chip->ecc.bytes = 3;
++		chip->ecc.strength = 1;
+ 		break;
+ 
+-	/* if SW ECC was chosen in DT, we do not need to set anything here */
++	/* if none or SW ECC was chosen, we do not need to set anything here */
++	case NAND_ECC_ENGINE_TYPE_NONE:
+ 	case NAND_ECC_ENGINE_TYPE_SOFT:
++	case NAND_ECC_ENGINE_TYPE_ON_DIE:
+ 		break;
+ 
+-	/* should we also implement *_ECC_ENGINE_CONTROLLER to do as above? */
+ 	default:
+ 		return -EINVAL;
+ 	}
+diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c
+index e91b879b32bdb..056835fd45622 100644
+--- a/drivers/mtd/nand/raw/intel-nand-controller.c
++++ b/drivers/mtd/nand/raw/intel-nand-controller.c
+@@ -16,6 +16,7 @@
+ #include <linux/mtd/rawnand.h>
+ #include <linux/mtd/nand.h>
+ 
++#include <linux/of.h>
+ #include <linux/platform_device.h>
+ #include <linux/sched.h>
+ #include <linux/slab.h>
+@@ -580,6 +581,7 @@ static int ebu_nand_probe(struct platform_device *pdev)
+ {
+ 	struct device *dev = &pdev->dev;
+ 	struct ebu_nand_controller *ebu_host;
++	struct device_node *chip_np;
+ 	struct nand_chip *nand;
+ 	struct mtd_info *mtd;
+ 	struct resource *res;
+@@ -604,7 +606,12 @@ static int ebu_nand_probe(struct platform_device *pdev)
+ 	if (IS_ERR(ebu_host->hsnand))
+ 		return PTR_ERR(ebu_host->hsnand);
+ 
+-	ret = device_property_read_u32(dev, "reg", &cs);
++	chip_np = of_get_next_child(dev->of_node, NULL);
++	if (!chip_np)
++		return dev_err_probe(dev, -EINVAL,
++				     "Could not find child node for the NAND chip\n");
++
++	ret = of_property_read_u32(chip_np, "reg", &cs);
+ 	if (ret) {
+ 		dev_err(dev, "failed to get chip select: %d\n", ret);
+ 		return ret;
+@@ -660,7 +667,7 @@ static int ebu_nand_probe(struct platform_device *pdev)
+ 	writel(ebu_host->cs[cs].addr_sel | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN,
+ 	       ebu_host->ebu + EBU_ADDR_SEL(cs));
+ 
+-	nand_set_flash_node(&ebu_host->chip, dev->of_node);
++	nand_set_flash_node(&ebu_host->chip, chip_np);
+ 
+ 	mtd = nand_to_mtd(&ebu_host->chip);
+ 	if (!mtd->name) {
+@@ -716,7 +723,6 @@ static int ebu_nand_remove(struct platform_device *pdev)
+ }
+ 
+ static const struct of_device_id ebu_nand_match[] = {
+-	{ .compatible = "intel,nand-controller" },
+ 	{ .compatible = "intel,lgm-ebunand" },
+ 	{}
+ };
+diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
+index 829b76b303aae..ad2ffd0ca8006 100644
+--- a/drivers/mtd/nand/raw/meson_nand.c
++++ b/drivers/mtd/nand/raw/meson_nand.c
+@@ -454,7 +454,7 @@ static int meson_nfc_ecc_correct(struct nand_chip *nand, u32 *bitflips,
+ 		if (ECC_ERR_CNT(*info) != ECC_UNCORRECTABLE) {
+ 			mtd->ecc_stats.corrected += ECC_ERR_CNT(*info);
+ 			*bitflips = max_t(u32, *bitflips, ECC_ERR_CNT(*info));
+-			*correct_bitmap |= 1 >> i;
++			*correct_bitmap |= BIT_ULL(i);
+ 			continue;
+ 		}
+ 		if ((nand->options & NAND_NEED_SCRAMBLING) &&
+@@ -800,7 +800,7 @@ static int meson_nfc_read_page_hwecc(struct nand_chip *nand, u8 *buf,
+ 			u8 *data = buf + i * ecc->size;
+ 			u8 *oob = nand->oob_poi + i * (ecc->bytes + 2);
+ 
+-			if (correct_bitmap & (1 << i))
++			if (correct_bitmap & BIT_ULL(i))
+ 				continue;
+ 			ret = nand_check_erased_ecc_chunk(data,	ecc->size,
+ 							  oob, ecc->bytes + 2,
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+index 841da29cef939..f6c0938027ece 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h
+@@ -178,6 +178,8 @@ struct kvaser_usb_dev_cfg {
+ extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops;
+ extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops;
+ 
++void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv);
++
+ int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len,
+ 			int *actual_len);
+ 
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+index 824cab80aa02f..e91648ed73862 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+@@ -477,7 +477,7 @@ static void kvaser_usb_reset_tx_urb_contexts(struct kvaser_usb_net_priv *priv)
+ /* This method might sleep. Do not call it in the atomic context
+  * of URB completions.
+  */
+-static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv)
++void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv)
+ {
+ 	usb_kill_anchored_urbs(&priv->tx_submitted);
+ 	kvaser_usb_reset_tx_urb_contexts(priv);
+@@ -729,6 +729,7 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
+ 	init_usb_anchor(&priv->tx_submitted);
+ 	init_completion(&priv->start_comp);
+ 	init_completion(&priv->stop_comp);
++	init_completion(&priv->flush_comp);
+ 	priv->can.ctrlmode_supported = 0;
+ 
+ 	priv->dev = dev;
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+index dd65c101bfb8e..3dcd35979e6fd 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+@@ -1916,7 +1916,7 @@ static int kvaser_usb_hydra_flush_queue(struct kvaser_usb_net_priv *priv)
+ {
+ 	int err;
+ 
+-	init_completion(&priv->flush_comp);
++	reinit_completion(&priv->flush_comp);
+ 
+ 	err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_FLUSH_QUEUE,
+ 					       priv->channel);
+diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+index 07f687f29b341..50f2ac8319ff8 100644
+--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
++++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+@@ -310,6 +310,38 @@ struct kvaser_cmd {
+ 	} u;
+ } __packed;
+ 
++#define CMD_SIZE_ANY 0xff
++#define kvaser_fsize(field) sizeof_field(struct kvaser_cmd, field)
++
++static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = {
++	[CMD_START_CHIP_REPLY]		= kvaser_fsize(u.simple),
++	[CMD_STOP_CHIP_REPLY]		= kvaser_fsize(u.simple),
++	[CMD_GET_CARD_INFO_REPLY]	= kvaser_fsize(u.cardinfo),
++	[CMD_TX_ACKNOWLEDGE]		= kvaser_fsize(u.tx_acknowledge_header),
++	[CMD_GET_SOFTWARE_INFO_REPLY]	= kvaser_fsize(u.leaf.softinfo),
++	[CMD_RX_STD_MESSAGE]		= kvaser_fsize(u.leaf.rx_can),
++	[CMD_RX_EXT_MESSAGE]		= kvaser_fsize(u.leaf.rx_can),
++	[CMD_LEAF_LOG_MESSAGE]		= kvaser_fsize(u.leaf.log_message),
++	[CMD_CHIP_STATE_EVENT]		= kvaser_fsize(u.leaf.chip_state_event),
++	[CMD_CAN_ERROR_EVENT]		= kvaser_fsize(u.leaf.error_event),
++	/* ignored events: */
++	[CMD_FLUSH_QUEUE_REPLY]		= CMD_SIZE_ANY,
++};
++
++static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = {
++	[CMD_START_CHIP_REPLY]		= kvaser_fsize(u.simple),
++	[CMD_STOP_CHIP_REPLY]		= kvaser_fsize(u.simple),
++	[CMD_GET_CARD_INFO_REPLY]	= kvaser_fsize(u.cardinfo),
++	[CMD_TX_ACKNOWLEDGE]		= kvaser_fsize(u.tx_acknowledge_header),
++	[CMD_GET_SOFTWARE_INFO_REPLY]	= kvaser_fsize(u.usbcan.softinfo),
++	[CMD_RX_STD_MESSAGE]		= kvaser_fsize(u.usbcan.rx_can),
++	[CMD_RX_EXT_MESSAGE]		= kvaser_fsize(u.usbcan.rx_can),
++	[CMD_CHIP_STATE_EVENT]		= kvaser_fsize(u.usbcan.chip_state_event),
++	[CMD_CAN_ERROR_EVENT]		= kvaser_fsize(u.usbcan.error_event),
++	/* ignored events: */
++	[CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY,
++};
++
+ /* Summary of a kvaser error event, for a unified Leaf/Usbcan error
+  * handling. Some discrepancies between the two families exist:
+  *
+@@ -397,6 +429,43 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_32mhz = {
+ 	.bittiming_const = &kvaser_usb_flexc_bittiming_const,
+ };
+ 
++static int kvaser_usb_leaf_verify_size(const struct kvaser_usb *dev,
++				       const struct kvaser_cmd *cmd)
++{
++	/* buffer size >= cmd->len ensured by caller */
++	u8 min_size = 0;
++
++	switch (dev->driver_info->family) {
++	case KVASER_LEAF:
++		if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_leaf))
++			min_size = kvaser_usb_leaf_cmd_sizes_leaf[cmd->id];
++		break;
++	case KVASER_USBCAN:
++		if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_usbcan))
++			min_size = kvaser_usb_leaf_cmd_sizes_usbcan[cmd->id];
++		break;
++	}
++
++	if (min_size == CMD_SIZE_ANY)
++		return 0;
++
++	if (min_size) {
++		min_size += CMD_HEADER_LEN;
++		if (cmd->len >= min_size)
++			return 0;
++
++		dev_err_ratelimited(&dev->intf->dev,
++				    "Received command %u too short (size %u, needed %u)",
++				    cmd->id, cmd->len, min_size);
++		return -EIO;
++	}
++
++	dev_warn_ratelimited(&dev->intf->dev,
++			     "Unhandled command (%d, size %d)\n",
++			     cmd->id, cmd->len);
++	return -EINVAL;
++}
++
+ static void *
+ kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv,
+ 			     const struct sk_buff *skb, int *cmd_len,
+@@ -502,6 +571,9 @@ static int kvaser_usb_leaf_wait_cmd(const struct kvaser_usb *dev, u8 id,
+ end:
+ 	kfree(buf);
+ 
++	if (err == 0)
++		err = kvaser_usb_leaf_verify_size(dev, cmd);
++
+ 	return err;
+ }
+ 
+@@ -1133,6 +1205,9 @@ static void kvaser_usb_leaf_stop_chip_reply(const struct kvaser_usb *dev,
+ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev,
+ 					   const struct kvaser_cmd *cmd)
+ {
++	if (kvaser_usb_leaf_verify_size(dev, cmd) < 0)
++		return;
++
+ 	switch (cmd->id) {
+ 	case CMD_START_CHIP_REPLY:
+ 		kvaser_usb_leaf_start_chip_reply(dev, cmd);
+@@ -1351,9 +1426,13 @@ static int kvaser_usb_leaf_set_mode(struct net_device *netdev,
+ 
+ 	switch (mode) {
+ 	case CAN_MODE_START:
++		kvaser_usb_unlink_tx_urbs(priv);
++
+ 		err = kvaser_usb_leaf_simple_cmd_async(priv, CMD_START_CHIP);
+ 		if (err)
+ 			return err;
++
++		priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ 		break;
+ 	default:
+ 		return -EOPNOTSUPP;
+diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
+index a89b93cb4e26d..d5939586c82ee 100644
+--- a/drivers/net/ethernet/atheros/alx/main.c
++++ b/drivers/net/ethernet/atheros/alx/main.c
+@@ -1912,11 +1912,14 @@ static int alx_suspend(struct device *dev)
+ 
+ 	if (!netif_running(alx->dev))
+ 		return 0;
++
++	rtnl_lock();
+ 	netif_device_detach(alx->dev);
+ 
+ 	mutex_lock(&alx->mtx);
+ 	__alx_stop(alx);
+ 	mutex_unlock(&alx->mtx);
++	rtnl_unlock();
+ 
+ 	return 0;
+ }
+@@ -1927,6 +1930,7 @@ static int alx_resume(struct device *dev)
+ 	struct alx_hw *hw = &alx->hw;
+ 	int err;
+ 
++	rtnl_lock();
+ 	mutex_lock(&alx->mtx);
+ 	alx_reset_phy(hw);
+ 
+@@ -1943,6 +1947,7 @@ static int alx_resume(struct device *dev)
+ 
+ unlock:
+ 	mutex_unlock(&alx->mtx);
++	rtnl_unlock();
+ 	return err;
+ }
+ 
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+index 712b5595bc393..24bfc65e28e10 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+@@ -789,6 +789,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+ 			BNX2X_ERR("skb_put is about to fail...  pad %d  len %d  rx_buf_size %d\n",
+ 				  pad, len, fp->rx_buf_size);
+ 			bnx2x_panic();
++			bnx2x_frag_free(fp, new_data);
+ 			return;
+ 		}
+ #endif
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
+index 8e316367f6ced..2132ce63193ce 100644
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
+@@ -505,9 +505,13 @@ static int bnxt_hwrm_ptp_cfg(struct bnxt *bp)
+ 	ptp->tstamp_filters = flags;
+ 
+ 	if (netif_running(bp->dev)) {
+-		rc = bnxt_close_nic(bp, false, false);
+-		if (!rc)
+-			rc = bnxt_open_nic(bp, false, false);
++		if (ptp->rx_filter == HWTSTAMP_FILTER_ALL) {
++			rc = bnxt_close_nic(bp, false, false);
++			if (!rc)
++				rc = bnxt_open_nic(bp, false, false);
++		} else {
++			bnxt_ptp_cfg_tstamp_filters(bp);
++		}
+ 		if (!rc && !ptp->tstamp_filters)
+ 			rc = -EIO;
+ 	}
+diff --git a/drivers/net/ethernet/engleder/tsnep_hw.h b/drivers/net/ethernet/engleder/tsnep_hw.h
+index 916ceac3ada23..e03aaafab559f 100644
+--- a/drivers/net/ethernet/engleder/tsnep_hw.h
++++ b/drivers/net/ethernet/engleder/tsnep_hw.h
+@@ -92,8 +92,7 @@
+ 
+ /* tsnep register */
+ #define TSNEP_INFO 0x0100
+-#define TSNEP_INFO_RX_ASSIGN 0x00010000
+-#define TSNEP_INFO_TX_TIME 0x00020000
++#define TSNEP_INFO_TX_TIME 0x00010000
+ #define TSNEP_CONTROL 0x0108
+ #define TSNEP_CONTROL_TX_RESET 0x00000001
+ #define TSNEP_CONTROL_TX_ENABLE 0x00000002
+diff --git a/drivers/net/ethernet/faraday/ftmac100.h b/drivers/net/ethernet/faraday/ftmac100.h
+index fe986f1673fc6..8af32f9070f4c 100644
+--- a/drivers/net/ethernet/faraday/ftmac100.h
++++ b/drivers/net/ethernet/faraday/ftmac100.h
+@@ -122,9 +122,9 @@
+  * Transmit descriptor, aligned to 16 bytes
+  */
+ struct ftmac100_txdes {
+-	unsigned int	txdes0;
+-	unsigned int	txdes1;
+-	unsigned int	txdes2;	/* TXBUF_BADR */
++	__le32		txdes0;
++	__le32		txdes1;
++	__le32		txdes2;	/* TXBUF_BADR */
+ 	unsigned int	txdes3;	/* not used by HW */
+ } __attribute__ ((aligned(16)));
+ 
+@@ -143,9 +143,9 @@ struct ftmac100_txdes {
+  * Receive descriptor, aligned to 16 bytes
+  */
+ struct ftmac100_rxdes {
+-	unsigned int	rxdes0;
+-	unsigned int	rxdes1;
+-	unsigned int	rxdes2;	/* RXBUF_BADR */
++	__le32		rxdes0;
++	__le32		rxdes1;
++	__le32		rxdes2;	/* RXBUF_BADR */
+ 	unsigned int	rxdes3;	/* not used by HW */
+ } __attribute__ ((aligned(16)));
+ 
+diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
+index 99fe2c210d0f6..61f4b6e50d29b 100644
+--- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
++++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
+@@ -98,7 +98,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
+ 		return -EINVAL;
+ 
+ 	fep->fec.fecp = of_iomap(ofdev->dev.of_node, 0);
+-	if (!fep->fcc.fccp)
++	if (!fep->fec.fecp)
+ 		return -EINVAL;
+ 
+ 	return 0;
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 0c89f16bf1e23..79fef8c59d652 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -1267,66 +1267,138 @@ static void iavf_up_complete(struct iavf_adapter *adapter)
+ }
+ 
+ /**
+- * iavf_down - Shutdown the connection processing
++ * iavf_clear_mac_vlan_filters - Remove mac and vlan filters not sent to PF
++ * yet and mark other to be removed.
+  * @adapter: board private structure
+- *
+- * Expects to be called while holding the __IAVF_IN_CRITICAL_TASK bit lock.
+  **/
+-void iavf_down(struct iavf_adapter *adapter)
++static void iavf_clear_mac_vlan_filters(struct iavf_adapter *adapter)
+ {
+-	struct net_device *netdev = adapter->netdev;
+-	struct iavf_vlan_filter *vlf;
+-	struct iavf_cloud_filter *cf;
+-	struct iavf_fdir_fltr *fdir;
+-	struct iavf_mac_filter *f;
+-	struct iavf_adv_rss *rss;
+-
+-	if (adapter->state <= __IAVF_DOWN_PENDING)
+-		return;
+-
+-	netif_carrier_off(netdev);
+-	netif_tx_disable(netdev);
+-	adapter->link_up = false;
+-	iavf_napi_disable_all(adapter);
+-	iavf_irq_disable(adapter);
++	struct iavf_vlan_filter *vlf, *vlftmp;
++	struct iavf_mac_filter *f, *ftmp;
+ 
+ 	spin_lock_bh(&adapter->mac_vlan_list_lock);
+-
+ 	/* clear the sync flag on all filters */
+ 	__dev_uc_unsync(adapter->netdev, NULL);
+ 	__dev_mc_unsync(adapter->netdev, NULL);
+ 
+ 	/* remove all MAC filters */
+-	list_for_each_entry(f, &adapter->mac_filter_list, list) {
+-		f->remove = true;
++	list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list,
++				 list) {
++		if (f->add) {
++			list_del(&f->list);
++			kfree(f);
++		} else {
++			f->remove = true;
++		}
+ 	}
+ 
+ 	/* remove all VLAN filters */
+-	list_for_each_entry(vlf, &adapter->vlan_filter_list, list) {
+-		vlf->remove = true;
++	list_for_each_entry_safe(vlf, vlftmp, &adapter->vlan_filter_list,
++				 list) {
++		if (vlf->add) {
++			list_del(&vlf->list);
++			kfree(vlf);
++		} else {
++			vlf->remove = true;
++		}
+ 	}
+-
+ 	spin_unlock_bh(&adapter->mac_vlan_list_lock);
++}
++
++/**
++ * iavf_clear_cloud_filters - Remove cloud filters not sent to PF yet and
++ * mark other to be removed.
++ * @adapter: board private structure
++ **/
++static void iavf_clear_cloud_filters(struct iavf_adapter *adapter)
++{
++	struct iavf_cloud_filter *cf, *cftmp;
+ 
+ 	/* remove all cloud filters */
+ 	spin_lock_bh(&adapter->cloud_filter_list_lock);
+-	list_for_each_entry(cf, &adapter->cloud_filter_list, list) {
+-		cf->del = true;
++	list_for_each_entry_safe(cf, cftmp, &adapter->cloud_filter_list,
++				 list) {
++		if (cf->add) {
++			list_del(&cf->list);
++			kfree(cf);
++			adapter->num_cloud_filters--;
++		} else {
++			cf->del = true;
++		}
+ 	}
+ 	spin_unlock_bh(&adapter->cloud_filter_list_lock);
++}
++
++/**
++ * iavf_clear_fdir_filters - Remove fdir filters not sent to PF yet and mark
++ * other to be removed.
++ * @adapter: board private structure
++ **/
++static void iavf_clear_fdir_filters(struct iavf_adapter *adapter)
++{
++	struct iavf_fdir_fltr *fdir, *fdirtmp;
+ 
+ 	/* remove all Flow Director filters */
+ 	spin_lock_bh(&adapter->fdir_fltr_lock);
+-	list_for_each_entry(fdir, &adapter->fdir_list_head, list) {
+-		fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST;
++	list_for_each_entry_safe(fdir, fdirtmp, &adapter->fdir_list_head,
++				 list) {
++		if (fdir->state == IAVF_FDIR_FLTR_ADD_REQUEST) {
++			list_del(&fdir->list);
++			kfree(fdir);
++			adapter->fdir_active_fltr--;
++		} else {
++			fdir->state = IAVF_FDIR_FLTR_DEL_REQUEST;
++		}
+ 	}
+ 	spin_unlock_bh(&adapter->fdir_fltr_lock);
++}
++
++/**
++ * iavf_clear_adv_rss_conf - Remove adv rss conf not sent to PF yet and mark
++ * other to be removed.
++ * @adapter: board private structure
++ **/
++static void iavf_clear_adv_rss_conf(struct iavf_adapter *adapter)
++{
++	struct iavf_adv_rss *rss, *rsstmp;
+ 
+ 	/* remove all advance RSS configuration */
+ 	spin_lock_bh(&adapter->adv_rss_lock);
+-	list_for_each_entry(rss, &adapter->adv_rss_list_head, list)
+-		rss->state = IAVF_ADV_RSS_DEL_REQUEST;
++	list_for_each_entry_safe(rss, rsstmp, &adapter->adv_rss_list_head,
++				 list) {
++		if (rss->state == IAVF_ADV_RSS_ADD_REQUEST) {
++			list_del(&rss->list);
++			kfree(rss);
++		} else {
++			rss->state = IAVF_ADV_RSS_DEL_REQUEST;
++		}
++	}
+ 	spin_unlock_bh(&adapter->adv_rss_lock);
++}
++
++/**
++ * iavf_down - Shutdown the connection processing
++ * @adapter: board private structure
++ *
++ * Expects to be called while holding the __IAVF_IN_CRITICAL_TASK bit lock.
++ **/
++void iavf_down(struct iavf_adapter *adapter)
++{
++	struct net_device *netdev = adapter->netdev;
++
++	if (adapter->state <= __IAVF_DOWN_PENDING)
++		return;
++
++	netif_carrier_off(netdev);
++	netif_tx_disable(netdev);
++	adapter->link_up = false;
++	iavf_napi_disable_all(adapter);
++	iavf_irq_disable(adapter);
++
++	iavf_clear_mac_vlan_filters(adapter);
++	iavf_clear_cloud_filters(adapter);
++	iavf_clear_fdir_filters(adapter);
++	iavf_clear_adv_rss_conf(adapter);
+ 
+ 	if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)) {
+ 		/* cancel any current operation */
+@@ -1335,11 +1407,16 @@ void iavf_down(struct iavf_adapter *adapter)
+ 		 * here for this to complete. The watchdog is still running
+ 		 * and it will take care of this.
+ 		 */
+-		adapter->aq_required = IAVF_FLAG_AQ_DEL_MAC_FILTER;
+-		adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;
+-		adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
+-		adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER;
+-		adapter->aq_required |= IAVF_FLAG_AQ_DEL_ADV_RSS_CFG;
++		if (!list_empty(&adapter->mac_filter_list))
++			adapter->aq_required |= IAVF_FLAG_AQ_DEL_MAC_FILTER;
++		if (!list_empty(&adapter->vlan_filter_list))
++			adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER;
++		if (!list_empty(&adapter->cloud_filter_list))
++			adapter->aq_required |= IAVF_FLAG_AQ_DEL_CLOUD_FILTER;
++		if (!list_empty(&adapter->fdir_list_head))
++			adapter->aq_required |= IAVF_FLAG_AQ_DEL_FDIR_FILTER;
++		if (!list_empty(&adapter->adv_rss_list_head))
++			adapter->aq_required |= IAVF_FLAG_AQ_DEL_ADV_RSS_CFG;
+ 		adapter->aq_required |= IAVF_FLAG_AQ_DISABLE_QUEUES;
+ 	}
+ 
+@@ -4178,6 +4255,7 @@ err_unlock:
+ static int iavf_close(struct net_device *netdev)
+ {
+ 	struct iavf_adapter *adapter = netdev_priv(netdev);
++	u64 aq_to_restore;
+ 	int status;
+ 
+ 	mutex_lock(&adapter->crit_lock);
+@@ -4190,6 +4268,29 @@ static int iavf_close(struct net_device *netdev)
+ 	set_bit(__IAVF_VSI_DOWN, adapter->vsi.state);
+ 	if (CLIENT_ENABLED(adapter))
+ 		adapter->flags |= IAVF_FLAG_CLIENT_NEEDS_CLOSE;
++	/* We cannot send IAVF_FLAG_AQ_GET_OFFLOAD_VLAN_V2_CAPS before
++	 * IAVF_FLAG_AQ_DISABLE_QUEUES because in such case there is rtnl
++	 * deadlock with adminq_task() until iavf_close timeouts. We must send
++	 * IAVF_FLAG_AQ_GET_CONFIG before IAVF_FLAG_AQ_DISABLE_QUEUES to make
++	 * disable queues possible for vf. Give only necessary flags to
++	 * iavf_down and save other to set them right before iavf_close()
++	 * returns, when IAVF_FLAG_AQ_DISABLE_QUEUES will be already sent and
++	 * iavf will be in DOWN state.
++	 */
++	aq_to_restore = adapter->aq_required;
++	adapter->aq_required &= IAVF_FLAG_AQ_GET_CONFIG;
++
++	/* Remove flags which we do not want to send after close or we want to
++	 * send before disable queues.
++	 */
++	aq_to_restore &= ~(IAVF_FLAG_AQ_GET_CONFIG		|
++			   IAVF_FLAG_AQ_ENABLE_QUEUES		|
++			   IAVF_FLAG_AQ_CONFIGURE_QUEUES	|
++			   IAVF_FLAG_AQ_ADD_VLAN_FILTER		|
++			   IAVF_FLAG_AQ_ADD_MAC_FILTER		|
++			   IAVF_FLAG_AQ_ADD_CLOUD_FILTER	|
++			   IAVF_FLAG_AQ_ADD_FDIR_FILTER		|
++			   IAVF_FLAG_AQ_ADD_ADV_RSS_CFG);
+ 
+ 	iavf_down(adapter);
+ 	iavf_change_state(adapter, __IAVF_DOWN_PENDING);
+@@ -4213,6 +4314,10 @@ static int iavf_close(struct net_device *netdev)
+ 				    msecs_to_jiffies(500));
+ 	if (!status)
+ 		netdev_warn(netdev, "Device resources not yet released\n");
++
++	mutex_lock(&adapter->crit_lock);
++	adapter->aq_required |= aq_to_restore;
++	mutex_unlock(&adapter->crit_lock);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
+index a6fff8ebaf9d9..bbf6a300078e5 100644
+--- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
++++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
+@@ -2826,6 +2826,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring,
+ 		tx_rings[i].count = new_tx_cnt;
+ 		tx_rings[i].desc = NULL;
+ 		tx_rings[i].tx_buf = NULL;
++		tx_rings[i].tx_tstamps = &pf->ptp.port.tx;
+ 		err = ice_setup_tx_ring(&tx_rings[i]);
+ 		if (err) {
+ 			while (i--)
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+index ad73a488fc5fb..11e603686a276 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+@@ -1530,6 +1530,7 @@ u32 mvpp2_read(struct mvpp2 *priv, u32 offset);
+ void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name);
+ 
+ void mvpp2_dbgfs_cleanup(struct mvpp2 *priv);
++void mvpp2_dbgfs_exit(void);
+ 
+ void mvpp23_rx_fifo_fc_en(struct mvpp2 *priv, int port, bool en);
+ 
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c
+index 4a3baa7e01424..75e83ea2a926e 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c
+@@ -691,6 +691,13 @@ static int mvpp2_dbgfs_port_init(struct dentry *parent,
+ 	return 0;
+ }
+ 
++static struct dentry *mvpp2_root;
++
++void mvpp2_dbgfs_exit(void)
++{
++	debugfs_remove(mvpp2_root);
++}
++
+ void mvpp2_dbgfs_cleanup(struct mvpp2 *priv)
+ {
+ 	debugfs_remove_recursive(priv->dbgfs_dir);
+@@ -700,10 +707,9 @@ void mvpp2_dbgfs_cleanup(struct mvpp2 *priv)
+ 
+ void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name)
+ {
+-	struct dentry *mvpp2_dir, *mvpp2_root;
++	struct dentry *mvpp2_dir;
+ 	int ret, i;
+ 
+-	mvpp2_root = debugfs_lookup(MVPP2_DRIVER_NAME, NULL);
+ 	if (!mvpp2_root)
+ 		mvpp2_root = debugfs_create_dir(MVPP2_DRIVER_NAME, NULL);
+ 
+diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+index b84128b549b44..eaa51cd7456b6 100644
+--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+@@ -7706,7 +7706,18 @@ static struct platform_driver mvpp2_driver = {
+ 	},
+ };
+ 
+-module_platform_driver(mvpp2_driver);
++static int __init mvpp2_driver_init(void)
++{
++	return platform_driver_register(&mvpp2_driver);
++}
++module_init(mvpp2_driver_init);
++
++static void __exit mvpp2_driver_exit(void)
++{
++	platform_driver_unregister(&mvpp2_driver);
++	mvpp2_dbgfs_exit();
++}
++module_exit(mvpp2_driver_exit);
+ 
+ MODULE_DESCRIPTION("Marvell PPv2 Ethernet Driver - www.marvell.com");
+ MODULE_AUTHOR("Marcin Wojtas <mw@semihalf.com>");
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_acl.c b/drivers/net/ethernet/marvell/prestera/prestera_acl.c
+index 3d4b85f2d5414..f6b2933859d00 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_acl.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_acl.c
+@@ -178,10 +178,14 @@ err_rhashtable_init:
+ 	return ERR_PTR(err);
+ }
+ 
+-void prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset,
+-				      void *keymask)
++int prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset,
++				     void *keymask)
+ {
+ 	ruleset->keymask = kmemdup(keymask, ACL_KEYMASK_SIZE, GFP_KERNEL);
++	if (!ruleset->keymask)
++		return -ENOMEM;
++
++	return 0;
+ }
+ 
+ int prestera_acl_ruleset_offload(struct prestera_acl_ruleset *ruleset)
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_acl.h b/drivers/net/ethernet/marvell/prestera/prestera_acl.h
+index 03fc5b9dc9258..131bfbc87cd75 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_acl.h
++++ b/drivers/net/ethernet/marvell/prestera/prestera_acl.h
+@@ -185,8 +185,8 @@ struct prestera_acl_ruleset *
+ prestera_acl_ruleset_lookup(struct prestera_acl *acl,
+ 			    struct prestera_flow_block *block,
+ 			    u32 chain_index);
+-void prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset,
+-				      void *keymask);
++int prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset,
++				     void *keymask);
+ bool prestera_acl_ruleset_is_offload(struct prestera_acl_ruleset *ruleset);
+ int prestera_acl_ruleset_offload(struct prestera_acl_ruleset *ruleset);
+ void prestera_acl_ruleset_put(struct prestera_acl_ruleset *ruleset);
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flower.c b/drivers/net/ethernet/marvell/prestera/prestera_flower.c
+index 19d3b55c578ee..cf551a8379aca 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_flower.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_flower.c
+@@ -452,7 +452,9 @@ int prestera_flower_tmplt_create(struct prestera_flow_block *block,
+ 	}
+ 
+ 	/* preserve keymask/template to this ruleset */
+-	prestera_acl_ruleset_keymask_set(ruleset, rule.re_key.match.mask);
++	err = prestera_acl_ruleset_keymask_set(ruleset, rule.re_key.match.mask);
++	if (err)
++		goto err_ruleset_keymask_set;
+ 
+ 	/* skip error, as it is not possible to reject template operation,
+ 	 * so, keep the reference to the ruleset for rules to be added
+@@ -468,6 +470,8 @@ int prestera_flower_tmplt_create(struct prestera_flow_block *block,
+ 	list_add_rcu(&template->list, &block->template_list);
+ 	return 0;
+ 
++err_ruleset_keymask_set:
++	prestera_acl_ruleset_put(ruleset);
+ err_ruleset_get:
+ 	kfree(template);
+ err_malloc:
+diff --git a/drivers/net/ethernet/marvell/prestera/prestera_main.c b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+index a895862b48212..a0ad0bcbf89f4 100644
+--- a/drivers/net/ethernet/marvell/prestera/prestera_main.c
++++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c
+@@ -799,32 +799,30 @@ static void prestera_port_handle_event(struct prestera_switch *sw,
+ 
+ 		caching_dw = &port->cached_hw_stats.caching_dw;
+ 
+-		if (port->phy_link) {
+-			memset(&smac, 0, sizeof(smac));
+-			smac.valid = true;
+-			smac.oper = pevt->data.mac.oper;
+-			if (smac.oper) {
+-				smac.mode = pevt->data.mac.mode;
+-				smac.speed = pevt->data.mac.speed;
+-				smac.duplex = pevt->data.mac.duplex;
+-				smac.fc = pevt->data.mac.fc;
+-				smac.fec = pevt->data.mac.fec;
+-				phylink_mac_change(port->phy_link, true);
+-			} else {
+-				phylink_mac_change(port->phy_link, false);
+-			}
+-			prestera_port_mac_state_cache_write(port, &smac);
++		memset(&smac, 0, sizeof(smac));
++		smac.valid = true;
++		smac.oper = pevt->data.mac.oper;
++		if (smac.oper) {
++			smac.mode = pevt->data.mac.mode;
++			smac.speed = pevt->data.mac.speed;
++			smac.duplex = pevt->data.mac.duplex;
++			smac.fc = pevt->data.mac.fc;
++			smac.fec = pevt->data.mac.fec;
+ 		}
++		prestera_port_mac_state_cache_write(port, &smac);
+ 
+ 		if (port->state_mac.oper) {
+-			if (!port->phy_link)
++			if (port->phy_link)
++				phylink_mac_change(port->phy_link, true);
++			else
+ 				netif_carrier_on(port->dev);
+ 
+ 			if (!delayed_work_pending(caching_dw))
+ 				queue_delayed_work(prestera_wq, caching_dw, 0);
+-		} else if (netif_running(port->dev) &&
+-			   netif_carrier_ok(port->dev)) {
+-			if (!port->phy_link)
++		} else {
++			if (port->phy_link)
++				phylink_mac_change(port->phy_link, false);
++			else if (netif_running(port->dev) && netif_carrier_ok(port->dev))
+ 				netif_carrier_off(port->dev);
+ 
+ 			if (delayed_work_pending(caching_dw))
+diff --git a/drivers/net/ethernet/micrel/ks8851_spi.c b/drivers/net/ethernet/micrel/ks8851_spi.c
+index 82d55fc27edc6..70bc7253454f6 100644
+--- a/drivers/net/ethernet/micrel/ks8851_spi.c
++++ b/drivers/net/ethernet/micrel/ks8851_spi.c
+@@ -413,7 +413,8 @@ static int ks8851_probe_spi(struct spi_device *spi)
+ 
+ 	spi->bits_per_word = 8;
+ 
+-	ks = netdev_priv(netdev);
++	kss = netdev_priv(netdev);
++	ks = &kss->ks8851;
+ 
+ 	ks->lock = ks8851_lock_spi;
+ 	ks->unlock = ks8851_unlock_spi;
+@@ -433,8 +434,6 @@ static int ks8851_probe_spi(struct spi_device *spi)
+ 		 IRQ_RXPSI)	/* RX process stop */
+ 	ks->rc_ier = STD_IRQ;
+ 
+-	kss = to_ks8851_spi(ks);
+-
+ 	kss->spidev = spi;
+ 	mutex_init(&kss->lock);
+ 	INIT_WORK(&kss->tx_work, ks8851_tx_work);
+diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.c b/drivers/net/ethernet/microchip/lan743x_ptp.c
+index 6a11e2ceb013b..da3ea905adbb8 100644
+--- a/drivers/net/ethernet/microchip/lan743x_ptp.c
++++ b/drivers/net/ethernet/microchip/lan743x_ptp.c
+@@ -1049,6 +1049,10 @@ static int lan743x_ptpci_verify_pin_config(struct ptp_clock_info *ptp,
+ 					   enum ptp_pin_function func,
+ 					   unsigned int chan)
+ {
++	struct lan743x_ptp *lan_ptp =
++		container_of(ptp, struct lan743x_ptp, ptp_clock_info);
++	struct lan743x_adapter *adapter =
++		container_of(lan_ptp, struct lan743x_adapter, ptp);
+ 	int result = 0;
+ 
+ 	/* Confirm the requested function is supported. Parameter
+@@ -1057,7 +1061,10 @@ static int lan743x_ptpci_verify_pin_config(struct ptp_clock_info *ptp,
+ 	switch (func) {
+ 	case PTP_PF_NONE:
+ 	case PTP_PF_PEROUT:
++		break;
+ 	case PTP_PF_EXTTS:
++		if (!adapter->is_pci11x1x)
++			result = -1;
+ 		break;
+ 	case PTP_PF_PHYSYNC:
+ 	default:
+diff --git a/drivers/net/ethernet/sunplus/spl2sw_driver.c b/drivers/net/ethernet/sunplus/spl2sw_driver.c
+index 546206640492b..61d1d07dc0704 100644
+--- a/drivers/net/ethernet/sunplus/spl2sw_driver.c
++++ b/drivers/net/ethernet/sunplus/spl2sw_driver.c
+@@ -248,8 +248,8 @@ static int spl2sw_nvmem_get_mac_address(struct device *dev, struct device_node *
+ 
+ 	/* Check if mac address is valid */
+ 	if (!is_valid_ether_addr(mac)) {
+-		kfree(mac);
+ 		dev_info(dev, "Invalid mac address in nvmem (%pM)!\n", mac);
++		kfree(mac);
+ 		return -EINVAL;
+ 	}
+ 
+diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
+index fb30bc5d56cb7..fce06663e1e11 100644
+--- a/drivers/net/ethernet/ti/Kconfig
++++ b/drivers/net/ethernet/ti/Kconfig
+@@ -33,6 +33,7 @@ config TI_DAVINCI_MDIO
+ 	tristate "TI DaVinci MDIO Support"
+ 	depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
+ 	select PHYLIB
++	select MDIO_BITBANG
+ 	help
+ 	  This driver supports TI's DaVinci MDIO module.
+ 
+diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
+index ea37726180431..946b9753ccfb3 100644
+--- a/drivers/net/ethernet/ti/davinci_mdio.c
++++ b/drivers/net/ethernet/ti/davinci_mdio.c
+@@ -26,6 +26,8 @@
+ #include <linux/of_device.h>
+ #include <linux/of_mdio.h>
+ #include <linux/pinctrl/consumer.h>
++#include <linux/mdio-bitbang.h>
++#include <linux/sys_soc.h>
+ 
+ /*
+  * This timeout definition is a worst-case ultra defensive measure against
+@@ -41,6 +43,7 @@
+ 
+ struct davinci_mdio_of_param {
+ 	int autosuspend_delay_ms;
++	bool manual_mode;
+ };
+ 
+ struct davinci_mdio_regs {
+@@ -49,6 +52,15 @@ struct davinci_mdio_regs {
+ #define CONTROL_IDLE		BIT(31)
+ #define CONTROL_ENABLE		BIT(30)
+ #define CONTROL_MAX_DIV		(0xffff)
++#define CONTROL_CLKDIV		GENMASK(15, 0)
++
++#define MDIO_MAN_MDCLK_O	BIT(2)
++#define MDIO_MAN_OE		BIT(1)
++#define MDIO_MAN_PIN		BIT(0)
++#define MDIO_MANUALMODE		BIT(31)
++
++#define MDIO_PIN               0
++
+ 
+ 	u32	alive;
+ 	u32	link;
+@@ -59,7 +71,9 @@ struct davinci_mdio_regs {
+ 	u32	userintmasked;
+ 	u32	userintmaskset;
+ 	u32	userintmaskclr;
+-	u32	__reserved_1[20];
++	u32	manualif;
++	u32	poll;
++	u32	__reserved_1[18];
+ 
+ 	struct {
+ 		u32	access;
+@@ -79,6 +93,7 @@ static const struct mdio_platform_data default_pdata = {
+ 
+ struct davinci_mdio_data {
+ 	struct mdio_platform_data pdata;
++	struct mdiobb_ctrl bb_ctrl;
+ 	struct davinci_mdio_regs __iomem *regs;
+ 	struct clk	*clk;
+ 	struct device	*dev;
+@@ -90,6 +105,7 @@ struct davinci_mdio_data {
+ 	 */
+ 	bool		skip_scan;
+ 	u32		clk_div;
++	bool		manual_mode;
+ };
+ 
+ static void davinci_mdio_init_clk(struct davinci_mdio_data *data)
+@@ -128,9 +144,122 @@ static void davinci_mdio_enable(struct davinci_mdio_data *data)
+ 	writel(data->clk_div | CONTROL_ENABLE, &data->regs->control);
+ }
+ 
+-static int davinci_mdio_reset(struct mii_bus *bus)
++static void davinci_mdio_disable(struct davinci_mdio_data *data)
++{
++	u32 reg;
++
++	/* Disable MDIO state machine */
++	reg = readl(&data->regs->control);
++
++	reg &= ~CONTROL_CLKDIV;
++	reg |= data->clk_div;
++
++	reg &= ~CONTROL_ENABLE;
++	writel(reg, &data->regs->control);
++}
++
++static void davinci_mdio_enable_manual_mode(struct davinci_mdio_data *data)
++{
++	u32 reg;
++	/* set manual mode */
++	reg = readl(&data->regs->poll);
++	reg |= MDIO_MANUALMODE;
++	writel(reg, &data->regs->poll);
++}
++
++static void davinci_set_mdc(struct mdiobb_ctrl *ctrl, int level)
++{
++	struct davinci_mdio_data *data;
++	u32 reg;
++
++	data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
++	reg = readl(&data->regs->manualif);
++
++	if (level)
++		reg |= MDIO_MAN_MDCLK_O;
++	else
++		reg &= ~MDIO_MAN_MDCLK_O;
++
++	writel(reg, &data->regs->manualif);
++}
++
++static void davinci_set_mdio_dir(struct mdiobb_ctrl *ctrl, int output)
++{
++	struct davinci_mdio_data *data;
++	u32 reg;
++
++	data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
++	reg = readl(&data->regs->manualif);
++
++	if (output)
++		reg |= MDIO_MAN_OE;
++	else
++		reg &= ~MDIO_MAN_OE;
++
++	writel(reg, &data->regs->manualif);
++}
++
++static void  davinci_set_mdio_data(struct mdiobb_ctrl *ctrl, int value)
++{
++	struct davinci_mdio_data *data;
++	u32 reg;
++
++	data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
++	reg = readl(&data->regs->manualif);
++
++	if (value)
++		reg |= MDIO_MAN_PIN;
++	else
++		reg &= ~MDIO_MAN_PIN;
++
++	writel(reg, &data->regs->manualif);
++}
++
++static int davinci_get_mdio_data(struct mdiobb_ctrl *ctrl)
++{
++	struct davinci_mdio_data *data;
++	unsigned long reg;
++
++	data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
++	reg = readl(&data->regs->manualif);
++	return test_bit(MDIO_PIN, &reg);
++}
++
++static int davinci_mdiobb_read(struct mii_bus *bus, int phy, int reg)
++{
++	int ret;
++
++	ret = pm_runtime_resume_and_get(bus->parent);
++	if (ret < 0)
++		return ret;
++
++	ret = mdiobb_read(bus, phy, reg);
++
++	pm_runtime_mark_last_busy(bus->parent);
++	pm_runtime_put_autosuspend(bus->parent);
++
++	return ret;
++}
++
++static int davinci_mdiobb_write(struct mii_bus *bus, int phy, int reg,
++				u16 val)
++{
++	int ret;
++
++	ret = pm_runtime_resume_and_get(bus->parent);
++	if (ret < 0)
++		return ret;
++
++	ret = mdiobb_write(bus, phy, reg, val);
++
++	pm_runtime_mark_last_busy(bus->parent);
++	pm_runtime_put_autosuspend(bus->parent);
++
++	return ret;
++}
++
++static int davinci_mdio_common_reset(struct davinci_mdio_data *data)
+ {
+-	struct davinci_mdio_data *data = bus->priv;
+ 	u32 phy_mask, ver;
+ 	int ret;
+ 
+@@ -138,6 +267,11 @@ static int davinci_mdio_reset(struct mii_bus *bus)
+ 	if (ret < 0)
+ 		return ret;
+ 
++	if (data->manual_mode) {
++		davinci_mdio_disable(data);
++		davinci_mdio_enable_manual_mode(data);
++	}
++
+ 	/* wait for scan logic to settle */
+ 	msleep(PHY_MAX_ADDR * data->access_time);
+ 
+@@ -171,6 +305,23 @@ done:
+ 	return 0;
+ }
+ 
++static int davinci_mdio_reset(struct mii_bus *bus)
++{
++	struct davinci_mdio_data *data = bus->priv;
++
++	return davinci_mdio_common_reset(data);
++}
++
++static int davinci_mdiobb_reset(struct mii_bus *bus)
++{
++	struct mdiobb_ctrl *ctrl = bus->priv;
++	struct davinci_mdio_data *data;
++
++	data = container_of(ctrl, struct davinci_mdio_data, bb_ctrl);
++
++	return davinci_mdio_common_reset(data);
++}
++
+ /* wait until hardware is ready for another user access */
+ static inline int wait_for_user_access(struct davinci_mdio_data *data)
+ {
+@@ -318,6 +469,28 @@ static int davinci_mdio_probe_dt(struct mdio_platform_data *data,
+ 	return 0;
+ }
+ 
++struct k3_mdio_soc_data {
++	bool manual_mode;
++};
++
++static const struct k3_mdio_soc_data am65_mdio_soc_data = {
++	.manual_mode = true,
++};
++
++static const struct soc_device_attribute k3_mdio_socinfo[] = {
++	{ .family = "AM62X", .revision = "SR1.0", .data = &am65_mdio_soc_data },
++	{ .family = "AM64X", .revision = "SR1.0", .data = &am65_mdio_soc_data },
++	{ .family = "AM64X", .revision = "SR2.0", .data = &am65_mdio_soc_data },
++	{ .family = "AM65X", .revision = "SR1.0", .data = &am65_mdio_soc_data },
++	{ .family = "AM65X", .revision = "SR2.0", .data = &am65_mdio_soc_data },
++	{ .family = "J7200", .revision = "SR1.0", .data = &am65_mdio_soc_data },
++	{ .family = "J7200", .revision = "SR2.0", .data = &am65_mdio_soc_data },
++	{ .family = "J721E", .revision = "SR1.0", .data = &am65_mdio_soc_data },
++	{ .family = "J721E", .revision = "SR2.0", .data = &am65_mdio_soc_data },
++	{ .family = "J721S2", .revision = "SR1.0", .data = &am65_mdio_soc_data},
++	{ /* sentinel */ },
++};
++
+ #if IS_ENABLED(CONFIG_OF)
+ static const struct davinci_mdio_of_param of_cpsw_mdio_data = {
+ 	.autosuspend_delay_ms = 100,
+@@ -331,6 +504,14 @@ static const struct of_device_id davinci_mdio_of_mtable[] = {
+ MODULE_DEVICE_TABLE(of, davinci_mdio_of_mtable);
+ #endif
+ 
++static const struct mdiobb_ops davinci_mdiobb_ops = {
++	.owner = THIS_MODULE,
++	.set_mdc = davinci_set_mdc,
++	.set_mdio_dir = davinci_set_mdio_dir,
++	.set_mdio_data = davinci_set_mdio_data,
++	.get_mdio_data = davinci_get_mdio_data,
++};
++
+ static int davinci_mdio_probe(struct platform_device *pdev)
+ {
+ 	struct mdio_platform_data *pdata = dev_get_platdata(&pdev->dev);
+@@ -345,7 +526,26 @@ static int davinci_mdio_probe(struct platform_device *pdev)
+ 	if (!data)
+ 		return -ENOMEM;
+ 
+-	data->bus = devm_mdiobus_alloc(dev);
++	data->manual_mode = false;
++	data->bb_ctrl.ops = &davinci_mdiobb_ops;
++
++	if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
++		const struct soc_device_attribute *soc_match_data;
++
++		soc_match_data = soc_device_match(k3_mdio_socinfo);
++		if (soc_match_data && soc_match_data->data) {
++			const struct k3_mdio_soc_data *socdata =
++						soc_match_data->data;
++
++			data->manual_mode = socdata->manual_mode;
++		}
++	}
++
++	if (data->manual_mode)
++		data->bus = alloc_mdio_bitbang(&data->bb_ctrl);
++	else
++		data->bus = devm_mdiobus_alloc(dev);
++
+ 	if (!data->bus) {
+ 		dev_err(dev, "failed to alloc mii bus\n");
+ 		return -ENOMEM;
+@@ -371,11 +571,20 @@ static int davinci_mdio_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	data->bus->name		= dev_name(dev);
+-	data->bus->read		= davinci_mdio_read;
+-	data->bus->write	= davinci_mdio_write;
+-	data->bus->reset	= davinci_mdio_reset;
++
++	if (data->manual_mode) {
++		data->bus->read		= davinci_mdiobb_read;
++		data->bus->write	= davinci_mdiobb_write;
++		data->bus->reset	= davinci_mdiobb_reset;
++
++		dev_info(dev, "Configuring MDIO in manual mode\n");
++	} else {
++		data->bus->read		= davinci_mdio_read;
++		data->bus->write	= davinci_mdio_write;
++		data->bus->reset	= davinci_mdio_reset;
++		data->bus->priv		= data;
++	}
+ 	data->bus->parent	= dev;
+-	data->bus->priv		= data;
+ 
+ 	data->clk = devm_clk_get(dev, "fck");
+ 	if (IS_ERR(data->clk)) {
+@@ -433,9 +642,13 @@ static int davinci_mdio_remove(struct platform_device *pdev)
+ {
+ 	struct davinci_mdio_data *data = platform_get_drvdata(pdev);
+ 
+-	if (data->bus)
++	if (data->bus) {
+ 		mdiobus_unregister(data->bus);
+ 
++		if (data->manual_mode)
++			free_mdio_bitbang(data->bus);
++	}
++
+ 	pm_runtime_dont_use_autosuspend(&pdev->dev);
+ 	pm_runtime_disable(&pdev->dev);
+ 
+@@ -452,7 +665,9 @@ static int davinci_mdio_runtime_suspend(struct device *dev)
+ 	ctrl = readl(&data->regs->control);
+ 	ctrl &= ~CONTROL_ENABLE;
+ 	writel(ctrl, &data->regs->control);
+-	wait_for_idle(data);
++
++	if (!data->manual_mode)
++		wait_for_idle(data);
+ 
+ 	return 0;
+ }
+@@ -461,7 +676,12 @@ static int davinci_mdio_runtime_resume(struct device *dev)
+ {
+ 	struct davinci_mdio_data *data = dev_get_drvdata(dev);
+ 
+-	davinci_mdio_enable(data);
++	if (data->manual_mode) {
++		davinci_mdio_disable(data);
++		davinci_mdio_enable_manual_mode(data);
++	} else {
++		davinci_mdio_enable(data);
++	}
+ 	return 0;
+ }
+ #endif
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+index f2e2261b4b7d9..8ff4333de2ad9 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
+@@ -402,6 +402,9 @@ struct axidma_bd {
+  * @rx_bd_num:	Size of RX buffer descriptor ring
+  * @rx_bd_ci:	Stores the index of the Rx buffer descriptor in the ring being
+  *		accessed currently.
++ * @rx_packets: RX packet count for statistics
++ * @rx_bytes:	RX byte count for statistics
++ * @rx_stat_sync: Synchronization object for RX stats
+  * @napi_tx:	NAPI TX control structure
+  * @tx_dma_cr:  Nominal content of TX DMA control register
+  * @tx_bd_v:	Virtual address of the TX buffer descriptor ring
+@@ -411,6 +414,9 @@ struct axidma_bd {
+  *		complete. Only updated at runtime by TX NAPI poll.
+  * @tx_bd_tail:	Stores the index of the next Tx buffer descriptor in the ring
+  *              to be populated.
++ * @tx_packets: TX packet count for statistics
++ * @tx_bytes:	TX byte count for statistics
++ * @tx_stat_sync: Synchronization object for TX stats
+  * @dma_err_task: Work structure to process Axi DMA errors
+  * @tx_irq:	Axidma TX IRQ number
+  * @rx_irq:	Axidma RX IRQ number
+@@ -458,6 +464,9 @@ struct axienet_local {
+ 	dma_addr_t rx_bd_p;
+ 	u32 rx_bd_num;
+ 	u32 rx_bd_ci;
++	u64_stats_t rx_packets;
++	u64_stats_t rx_bytes;
++	struct u64_stats_sync rx_stat_sync;
+ 
+ 	struct napi_struct napi_tx;
+ 	u32 tx_dma_cr;
+@@ -466,6 +475,9 @@ struct axienet_local {
+ 	u32 tx_bd_num;
+ 	u32 tx_bd_ci;
+ 	u32 tx_bd_tail;
++	u64_stats_t tx_packets;
++	u64_stats_t tx_bytes;
++	struct u64_stats_sync tx_stat_sync;
+ 
+ 	struct work_struct dma_err_task;
+ 
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+index 1760930ec0c49..9262988d26a32 100644
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+@@ -752,8 +752,10 @@ static int axienet_tx_poll(struct napi_struct *napi, int budget)
+ 		if (lp->tx_bd_ci >= lp->tx_bd_num)
+ 			lp->tx_bd_ci %= lp->tx_bd_num;
+ 
+-		ndev->stats.tx_packets += packets;
+-		ndev->stats.tx_bytes += size;
++		u64_stats_update_begin(&lp->tx_stat_sync);
++		u64_stats_add(&lp->tx_packets, packets);
++		u64_stats_add(&lp->tx_bytes, size);
++		u64_stats_update_end(&lp->tx_stat_sync);
+ 
+ 		/* Matches barrier in axienet_start_xmit */
+ 		smp_mb();
+@@ -984,8 +986,10 @@ static int axienet_rx_poll(struct napi_struct *napi, int budget)
+ 		cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+ 	}
+ 
+-	lp->ndev->stats.rx_packets += packets;
+-	lp->ndev->stats.rx_bytes += size;
++	u64_stats_update_begin(&lp->rx_stat_sync);
++	u64_stats_add(&lp->rx_packets, packets);
++	u64_stats_add(&lp->rx_bytes, size);
++	u64_stats_update_end(&lp->rx_stat_sync);
+ 
+ 	if (tail_p)
+ 		axienet_dma_out_addr(lp, XAXIDMA_RX_TDESC_OFFSET, tail_p);
+@@ -1292,10 +1296,32 @@ static int axienet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ 	return phylink_mii_ioctl(lp->phylink, rq, cmd);
+ }
+ 
++static void
++axienet_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
++{
++	struct axienet_local *lp = netdev_priv(dev);
++	unsigned int start;
++
++	netdev_stats_to_stats64(stats, &dev->stats);
++
++	do {
++		start = u64_stats_fetch_begin_irq(&lp->rx_stat_sync);
++		stats->rx_packets = u64_stats_read(&lp->rx_packets);
++		stats->rx_bytes = u64_stats_read(&lp->rx_bytes);
++	} while (u64_stats_fetch_retry_irq(&lp->rx_stat_sync, start));
++
++	do {
++		start = u64_stats_fetch_begin_irq(&lp->tx_stat_sync);
++		stats->tx_packets = u64_stats_read(&lp->tx_packets);
++		stats->tx_bytes = u64_stats_read(&lp->tx_bytes);
++	} while (u64_stats_fetch_retry_irq(&lp->tx_stat_sync, start));
++}
++
+ static const struct net_device_ops axienet_netdev_ops = {
+ 	.ndo_open = axienet_open,
+ 	.ndo_stop = axienet_stop,
+ 	.ndo_start_xmit = axienet_start_xmit,
++	.ndo_get_stats64 = axienet_get_stats64,
+ 	.ndo_change_mtu	= axienet_change_mtu,
+ 	.ndo_set_mac_address = netdev_set_mac_address,
+ 	.ndo_validate_addr = eth_validate_addr,
+@@ -1850,6 +1876,9 @@ static int axienet_probe(struct platform_device *pdev)
+ 	lp->rx_bd_num = RX_BD_NUM_DEFAULT;
+ 	lp->tx_bd_num = TX_BD_NUM_DEFAULT;
+ 
++	u64_stats_init(&lp->rx_stat_sync);
++	u64_stats_init(&lp->tx_stat_sync);
++
+ 	netif_napi_add(ndev, &lp->napi_rx, axienet_rx_poll, NAPI_POLL_WEIGHT);
+ 	netif_napi_add(ndev, &lp->napi_tx, axienet_tx_poll, NAPI_POLL_WEIGHT);
+ 
+diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
+index 25b38a374e3c3..dd5919ec408bf 100644
+--- a/drivers/net/hyperv/hyperv_net.h
++++ b/drivers/net/hyperv/hyperv_net.h
+@@ -1051,7 +1051,8 @@ struct net_device_context {
+ 	u32 vf_alloc;
+ 	/* Serial number of the VF to team with */
+ 	u32 vf_serial;
+-
++	/* completion variable to confirm vf association */
++	struct completion vf_add;
+ 	/* Is the current data path through the VF NIC? */
+ 	bool  data_path_is_vf;
+ 
+diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
+index 6e42cb03e226a..456db7c28a34c 100644
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -1580,6 +1580,10 @@ static void netvsc_send_vf(struct net_device *ndev,
+ 
+ 	net_device_ctx->vf_alloc = nvmsg->msg.v4_msg.vf_assoc.allocated;
+ 	net_device_ctx->vf_serial = nvmsg->msg.v4_msg.vf_assoc.serial;
++
++	if (net_device_ctx->vf_alloc)
++		complete(&net_device_ctx->vf_add);
++
+ 	netdev_info(ndev, "VF slot %u %s\n",
+ 		    net_device_ctx->vf_serial,
+ 		    net_device_ctx->vf_alloc ? "added" : "removed");
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+index 15ebd54266049..8113ac17ab70a 100644
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -2313,6 +2313,18 @@ static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
+ 
+ 	}
+ 
++	/* Fallback path to check synthetic vf with
++	 * help of mac addr
++	 */
++	list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) {
++		ndev = hv_get_drvdata(ndev_ctx->device_ctx);
++		if (ether_addr_equal(vf_netdev->perm_addr, ndev->perm_addr)) {
++			netdev_notice(vf_netdev,
++				      "falling back to mac addr based matching\n");
++			return ndev;
++		}
++	}
++
+ 	netdev_notice(vf_netdev,
+ 		      "no netdev found for vf serial:%u\n", serial);
+ 	return NULL;
+@@ -2409,6 +2421,11 @@ static int netvsc_vf_changed(struct net_device *vf_netdev, unsigned long event)
+ 	if (net_device_ctx->data_path_is_vf == vf_is_up)
+ 		return NOTIFY_OK;
+ 
++	if (vf_is_up && !net_device_ctx->vf_alloc) {
++		netdev_info(ndev, "Waiting for the VF association from host\n");
++		wait_for_completion(&net_device_ctx->vf_add);
++	}
++
+ 	ret = netvsc_switch_datapath(ndev, vf_is_up);
+ 
+ 	if (ret) {
+@@ -2440,6 +2457,7 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev)
+ 
+ 	netvsc_vf_setxdp(vf_netdev, NULL);
+ 
++	reinit_completion(&net_device_ctx->vf_add);
+ 	netdev_rx_handler_unregister(vf_netdev);
+ 	netdev_upper_dev_unlink(vf_netdev, ndev);
+ 	RCU_INIT_POINTER(net_device_ctx->vf_netdev, NULL);
+@@ -2479,6 +2497,7 @@ static int netvsc_probe(struct hv_device *dev,
+ 
+ 	INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change);
+ 
++	init_completion(&net_device_ctx->vf_add);
+ 	spin_lock_init(&net_device_ctx->lock);
+ 	INIT_LIST_HEAD(&net_device_ctx->reconfig_events);
+ 	INIT_DELAYED_WORK(&net_device_ctx->vf_takeover, netvsc_vf_setup);
+diff --git a/drivers/net/thunderbolt.c b/drivers/net/thunderbolt.c
+index ff5d0e98a0881..ab3f045629802 100644
+--- a/drivers/net/thunderbolt.c
++++ b/drivers/net/thunderbolt.c
+@@ -612,18 +612,13 @@ static void tbnet_connected_work(struct work_struct *work)
+ 		return;
+ 	}
+ 
+-	/* Both logins successful so enable the high-speed DMA paths and
+-	 * start the network device queue.
++	/* Both logins successful so enable the rings, high-speed DMA
++	 * paths and start the network device queue.
++	 *
++	 * Note we enable the DMA paths last to make sure we have primed
++	 * the Rx ring before any incoming packets are allowed to
++	 * arrive.
+ 	 */
+-	ret = tb_xdomain_enable_paths(net->xd, net->local_transmit_path,
+-				      net->rx_ring.ring->hop,
+-				      net->remote_transmit_path,
+-				      net->tx_ring.ring->hop);
+-	if (ret) {
+-		netdev_err(net->dev, "failed to enable DMA paths\n");
+-		return;
+-	}
+-
+ 	tb_ring_start(net->tx_ring.ring);
+ 	tb_ring_start(net->rx_ring.ring);
+ 
+@@ -635,10 +630,21 @@ static void tbnet_connected_work(struct work_struct *work)
+ 	if (ret)
+ 		goto err_free_rx_buffers;
+ 
++	ret = tb_xdomain_enable_paths(net->xd, net->local_transmit_path,
++				      net->rx_ring.ring->hop,
++				      net->remote_transmit_path,
++				      net->tx_ring.ring->hop);
++	if (ret) {
++		netdev_err(net->dev, "failed to enable DMA paths\n");
++		goto err_free_tx_buffers;
++	}
++
+ 	netif_carrier_on(net->dev);
+ 	netif_start_queue(net->dev);
+ 	return;
+ 
++err_free_tx_buffers:
++	tbnet_free_buffers(&net->tx_ring);
+ err_free_rx_buffers:
+ 	tbnet_free_buffers(&net->rx_ring);
+ err_stop_rings:
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index 688905ea0a6d3..e7b0b59e2bc8c 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -1874,7 +1874,9 @@ static void intr_callback(struct urb *urb)
+ 			   "Stop submitting intr, status %d\n", status);
+ 		return;
+ 	case -EOVERFLOW:
+-		netif_info(tp, intr, tp->netdev, "intr status -EOVERFLOW\n");
++		if (net_ratelimit())
++			netif_info(tp, intr, tp->netdev,
++				   "intr status -EOVERFLOW\n");
+ 		goto resubmit;
+ 	/* -EPIPE:  should clear the halt */
+ 	default:
+diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
+index 276954b70d630..d1ac64026cb31 100644
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -98,6 +98,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = true,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA988X_HW_2_0_VERSION,
+@@ -136,6 +137,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = true,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA9887_HW_1_0_VERSION,
+@@ -175,6 +177,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = false,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA6174_HW_3_2_VERSION,
+@@ -209,6 +212,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.supports_peer_stats_info = true,
+ 		.dynamic_sar_support = true,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA6174_HW_2_1_VERSION,
+@@ -247,6 +251,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = false,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA6174_HW_2_1_VERSION,
+@@ -285,6 +290,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = false,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA6174_HW_3_0_VERSION,
+@@ -323,6 +329,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = false,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA6174_HW_3_2_VERSION,
+@@ -365,6 +372,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.supports_peer_stats_info = true,
+ 		.dynamic_sar_support = true,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA99X0_HW_2_0_DEV_VERSION,
+@@ -409,6 +417,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = false,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA9984_HW_1_0_DEV_VERSION,
+@@ -460,6 +469,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = false,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA9888_HW_2_0_DEV_VERSION,
+@@ -508,6 +518,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = false,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA9377_HW_1_0_DEV_VERSION,
+@@ -546,6 +557,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = false,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA9377_HW_1_1_DEV_VERSION,
+@@ -586,6 +598,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = false,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA9377_HW_1_1_DEV_VERSION,
+@@ -617,6 +630,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.credit_size_workaround = true,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = QCA4019_HW_1_0_DEV_VERSION,
+@@ -662,6 +676,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = false,
+ 		.dynamic_sar_support = false,
+ 		.hw_restart_disconnect = false,
++		.use_fw_tx_credits = true,
+ 	},
+ 	{
+ 		.id = WCN3990_HW_1_0_DEV_VERSION,
+@@ -693,6 +708,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
+ 		.tx_stats_over_pktlog = false,
+ 		.dynamic_sar_support = true,
+ 		.hw_restart_disconnect = true,
++		.use_fw_tx_credits = false,
+ 	},
+ };
+ 
+diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
+index fab398046a3f2..6d1784f74bea4 100644
+--- a/drivers/net/wireless/ath/ath10k/htc.c
++++ b/drivers/net/wireless/ath/ath10k/htc.c
+@@ -947,13 +947,18 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
+ 		return -ECOMM;
+ 	}
+ 
+-	htc->total_transmit_credits = __le16_to_cpu(msg->ready.credit_count);
++	if (ar->hw_params.use_fw_tx_credits)
++		htc->total_transmit_credits = __le16_to_cpu(msg->ready.credit_count);
++	else
++		htc->total_transmit_credits = 1;
++
+ 	htc->target_credit_size = __le16_to_cpu(msg->ready.credit_size);
+ 
+ 	ath10k_dbg(ar, ATH10K_DBG_HTC,
+-		   "Target ready! transmit resources: %d size:%d\n",
++		   "Target ready! transmit resources: %d size:%d actual credits:%d\n",
+ 		   htc->total_transmit_credits,
+-		   htc->target_credit_size);
++		   htc->target_credit_size,
++		   msg->ready.credit_count);
+ 
+ 	if ((htc->total_transmit_credits == 0) ||
+ 	    (htc->target_credit_size == 0)) {
+diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
+index 93acf0dd580a6..1b99f3a39a113 100644
+--- a/drivers/net/wireless/ath/ath10k/hw.h
++++ b/drivers/net/wireless/ath/ath10k/hw.h
+@@ -635,6 +635,8 @@ struct ath10k_hw_params {
+ 	bool dynamic_sar_support;
+ 
+ 	bool hw_restart_disconnect;
++
++	bool use_fw_tx_credits;
+ };
+ 
+ struct htt_resp;
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
+index 9dd3b8fba4b0e..23381a9db6aeb 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -864,11 +864,36 @@ static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr)
+ 	return 0;
+ }
+ 
++static void ath10k_peer_map_cleanup(struct ath10k *ar, struct ath10k_peer *peer)
++{
++	int peer_id, i;
++
++	lockdep_assert_held(&ar->conf_mutex);
++
++	for_each_set_bit(peer_id, peer->peer_ids,
++			 ATH10K_MAX_NUM_PEER_IDS) {
++		ar->peer_map[peer_id] = NULL;
++	}
++
++	/* Double check that peer is properly un-referenced from
++	 * the peer_map
++	 */
++	for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
++		if (ar->peer_map[i] == peer) {
++			ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
++				    peer->addr, peer, i);
++			ar->peer_map[i] = NULL;
++		}
++	}
++
++	list_del(&peer->list);
++	kfree(peer);
++	ar->num_peers--;
++}
++
+ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
+ {
+ 	struct ath10k_peer *peer, *tmp;
+-	int peer_id;
+-	int i;
+ 
+ 	lockdep_assert_held(&ar->conf_mutex);
+ 
+@@ -880,25 +905,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
+ 		ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
+ 			    peer->addr, vdev_id);
+ 
+-		for_each_set_bit(peer_id, peer->peer_ids,
+-				 ATH10K_MAX_NUM_PEER_IDS) {
+-			ar->peer_map[peer_id] = NULL;
+-		}
+-
+-		/* Double check that peer is properly un-referenced from
+-		 * the peer_map
+-		 */
+-		for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) {
+-			if (ar->peer_map[i] == peer) {
+-				ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n",
+-					    peer->addr, peer, i);
+-				ar->peer_map[i] = NULL;
+-			}
+-		}
+-
+-		list_del(&peer->list);
+-		kfree(peer);
+-		ar->num_peers--;
++		ath10k_peer_map_cleanup(ar, peer);
+ 	}
+ 	spin_unlock_bh(&ar->data_lock);
+ }
+@@ -7621,10 +7628,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
+ 				/* Clean up the peer object as well since we
+ 				 * must have failed to do this above.
+ 				 */
+-				list_del(&peer->list);
+-				ar->peer_map[i] = NULL;
+-				kfree(peer);
+-				ar->num_peers--;
++				ath10k_peer_map_cleanup(ar, peer);
+ 			}
+ 		}
+ 		spin_unlock_bh(&ar->data_lock);
+diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c
+index c474147101382..911eee9646a45 100644
+--- a/drivers/net/wireless/ath/ath11k/ahb.c
++++ b/drivers/net/wireless/ath/ath11k/ahb.c
+@@ -1088,20 +1088,10 @@ err_core_free:
+ 	return ret;
+ }
+ 
+-static int ath11k_ahb_remove(struct platform_device *pdev)
++static void ath11k_ahb_remove_prepare(struct ath11k_base *ab)
+ {
+-	struct ath11k_base *ab = platform_get_drvdata(pdev);
+ 	unsigned long left;
+ 
+-	if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
+-		ath11k_ahb_power_down(ab);
+-		ath11k_debugfs_soc_destroy(ab);
+-		ath11k_qmi_deinit_service(ab);
+-		goto qmi_fail;
+-	}
+-
+-	reinit_completion(&ab->driver_recovery);
+-
+ 	if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags)) {
+ 		left = wait_for_completion_timeout(&ab->driver_recovery,
+ 						   ATH11K_AHB_RECOVERY_TIMEOUT);
+@@ -1111,19 +1101,60 @@ static int ath11k_ahb_remove(struct platform_device *pdev)
+ 
+ 	set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
+ 	cancel_work_sync(&ab->restart_work);
++	cancel_work_sync(&ab->qmi.event_work);
++}
++
++static void ath11k_ahb_free_resources(struct ath11k_base *ab)
++{
++	struct platform_device *pdev = ab->pdev;
+ 
+-	ath11k_core_deinit(ab);
+-qmi_fail:
+ 	ath11k_ahb_free_irq(ab);
+ 	ath11k_hal_srng_deinit(ab);
+ 	ath11k_ahb_fw_resource_deinit(ab);
+ 	ath11k_ce_free_pipes(ab);
+ 	ath11k_core_free(ab);
+ 	platform_set_drvdata(pdev, NULL);
++}
++
++static int ath11k_ahb_remove(struct platform_device *pdev)
++{
++	struct ath11k_base *ab = platform_get_drvdata(pdev);
++
++	if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
++		ath11k_ahb_power_down(ab);
++		ath11k_debugfs_soc_destroy(ab);
++		ath11k_qmi_deinit_service(ab);
++		goto qmi_fail;
++	}
++
++	ath11k_ahb_remove_prepare(ab);
++	ath11k_core_deinit(ab);
++
++qmi_fail:
++	ath11k_ahb_free_resources(ab);
+ 
+ 	return 0;
+ }
+ 
++static void ath11k_ahb_shutdown(struct platform_device *pdev)
++{
++	struct ath11k_base *ab = platform_get_drvdata(pdev);
++
++	/* platform shutdown() & remove() are mutually exclusive.
++	 * remove() is invoked during rmmod & shutdown() during
++	 * system reboot/shutdown.
++	 */
++	ath11k_ahb_remove_prepare(ab);
++
++	if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)))
++		goto free_resources;
++
++	ath11k_core_deinit(ab);
++
++free_resources:
++	ath11k_ahb_free_resources(ab);
++}
++
+ static struct platform_driver ath11k_ahb_driver = {
+ 	.driver         = {
+ 		.name   = "ath11k",
+@@ -1131,6 +1162,7 @@ static struct platform_driver ath11k_ahb_driver = {
+ 	},
+ 	.probe  = ath11k_ahb_probe,
+ 	.remove = ath11k_ahb_remove,
++	.shutdown = ath11k_ahb_shutdown,
+ };
+ 
+ static int ath11k_ahb_init(void)
+diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c
+index c3e9e4f7bc24e..9df6aaae8a443 100644
+--- a/drivers/net/wireless/ath/ath11k/core.c
++++ b/drivers/net/wireless/ath/ath11k/core.c
+@@ -1563,6 +1563,8 @@ static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab)
+ 
+ 	wake_up(&ab->wmi_ab.tx_credits_wq);
+ 	wake_up(&ab->peer_mapping_wq);
++
++	reinit_completion(&ab->driver_recovery);
+ }
+ 
+ static void ath11k_core_post_reconfigure_recovery(struct ath11k_base *ab)
+diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
+index 2148acf37071e..e9c56ad1ec9d3 100644
+--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
++++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
+@@ -5197,7 +5197,8 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
+ 		if (log_type != ATH11K_PKTLOG_TYPE_INVALID)
+ 			trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz);
+ 
+-		memset(ppdu_info, 0, sizeof(struct hal_rx_mon_ppdu_info));
++		memset(ppdu_info, 0, sizeof(*ppdu_info));
++		ppdu_info->peer_id = HAL_INVALID_PEERID;
+ 		hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb);
+ 
+ 		if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags) &&
+diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
+index 7e91e347c9ff2..7f6521314b2d4 100644
+--- a/drivers/net/wireless/ath/ath11k/mac.c
++++ b/drivers/net/wireless/ath/ath11k/mac.c
+@@ -4954,6 +4954,8 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif)
+ 	if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) {
+ 		nsts = vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
+ 		nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
++		if (nsts > (ar->num_rx_chains - 1))
++			nsts = ar->num_rx_chains - 1;
+ 		value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
+ 	}
+ 
+@@ -4994,7 +4996,7 @@ static int ath11k_mac_set_txbf_conf(struct ath11k_vif *arvif)
+ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap)
+ {
+ 	bool subfer, subfee;
+-	int sound_dim = 0;
++	int sound_dim = 0, nsts = 0;
+ 
+ 	subfer = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE));
+ 	subfee = !!(*vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE));
+@@ -5004,6 +5006,11 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap)
+ 		subfer = false;
+ 	}
+ 
++	if (ar->num_rx_chains < 2) {
++		*vht_cap &= ~(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE);
++		subfee = false;
++	}
++
+ 	/* If SU Beaformer is not set, then disable MU Beamformer Capability */
+ 	if (!subfer)
+ 		*vht_cap &= ~(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE);
+@@ -5016,7 +5023,9 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap)
+ 	sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT;
+ 	*vht_cap &= ~IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK;
+ 
+-	/* TODO: Need to check invalid STS and Sound_dim values set by FW? */
++	nsts = (*vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK);
++	nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
++	*vht_cap &= ~IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
+ 
+ 	/* Enable Sounding Dimension Field only if SU BF is enabled */
+ 	if (subfer) {
+@@ -5028,9 +5037,15 @@ static void ath11k_set_vht_txbf_cap(struct ath11k *ar, u32 *vht_cap)
+ 		*vht_cap |= sound_dim;
+ 	}
+ 
+-	/* Use the STS advertised by FW unless SU Beamformee is not supported*/
+-	if (!subfee)
+-		*vht_cap &= ~(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK);
++	/* Enable Beamformee STS Field only if SU BF is enabled */
++	if (subfee) {
++		if (nsts > (ar->num_rx_chains - 1))
++			nsts = ar->num_rx_chains - 1;
++
++		nsts <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
++		nsts &=  IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
++		*vht_cap |= nsts;
++	}
+ }
+ 
+ static struct ieee80211_sta_vht_cap
+diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c
+index c44df17719f64..86995e8dc9135 100644
+--- a/drivers/net/wireless/ath/ath11k/mhi.c
++++ b/drivers/net/wireless/ath/ath11k/mhi.c
+@@ -402,8 +402,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
+ 	ret = ath11k_mhi_get_msi(ab_pci);
+ 	if (ret) {
+ 		ath11k_err(ab, "failed to get msi for mhi\n");
+-		mhi_free_controller(mhi_ctrl);
+-		return ret;
++		goto free_controller;
+ 	}
+ 
+ 	if (!test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags))
+@@ -412,7 +411,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
+ 	if (test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) {
+ 		ret = ath11k_mhi_read_addr_from_dt(mhi_ctrl);
+ 		if (ret < 0)
+-			return ret;
++			goto free_controller;
+ 	} else {
+ 		mhi_ctrl->iova_start = 0;
+ 		mhi_ctrl->iova_stop = 0xFFFFFFFF;
+@@ -440,18 +439,22 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
+ 	default:
+ 		ath11k_err(ab, "failed assign mhi_config for unknown hw rev %d\n",
+ 			   ab->hw_rev);
+-		mhi_free_controller(mhi_ctrl);
+-		return -EINVAL;
++		ret = -EINVAL;
++		goto free_controller;
+ 	}
+ 
+ 	ret = mhi_register_controller(mhi_ctrl, ath11k_mhi_config);
+ 	if (ret) {
+ 		ath11k_err(ab, "failed to register to mhi bus, err = %d\n", ret);
+-		mhi_free_controller(mhi_ctrl);
+-		return ret;
++		goto free_controller;
+ 	}
+ 
+ 	return 0;
++
++free_controller:
++	mhi_free_controller(mhi_ctrl);
++	ab_pci->mhi_ctrl = NULL;
++	return ret;
+ }
+ 
+ void ath11k_mhi_unregister(struct ath11k_pci *ab_pci)
+diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c
+index 9e22aaf34b88c..1ae7af02c364e 100644
+--- a/drivers/net/wireless/ath/ath11k/peer.c
++++ b/drivers/net/wireless/ath/ath11k/peer.c
+@@ -302,6 +302,21 @@ static int __ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, const u8 *addr)
+ 	spin_lock_bh(&ab->base_lock);
+ 
+ 	peer = ath11k_peer_find_by_addr(ab, addr);
++	/* Check if the found peer is what we want to remove.
++	 * While the sta is transitioning to another band we may
++	 * have 2 peer with the same addr assigned to different
++	 * vdev_id. Make sure we are deleting the correct peer.
++	 */
++	if (peer && peer->vdev_id == vdev_id)
++		ath11k_peer_rhash_delete(ab, peer);
++
++	/* Fallback to peer list search if the correct peer can't be found.
++	 * Skip the deletion of the peer from the rhash since it has already
++	 * been deleted in peer add.
++	 */
++	if (!peer)
++		peer = ath11k_peer_find(ab, vdev_id, addr);
++
+ 	if (!peer) {
+ 		spin_unlock_bh(&ab->base_lock);
+ 		mutex_unlock(&ab->tbl_mtx_lock);
+@@ -312,8 +327,6 @@ static int __ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, const u8 *addr)
+ 		return -EINVAL;
+ 	}
+ 
+-	ath11k_peer_rhash_delete(ab, peer);
+-
+ 	spin_unlock_bh(&ab->base_lock);
+ 	mutex_unlock(&ab->tbl_mtx_lock);
+ 
+@@ -372,8 +385,17 @@ int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
+ 	spin_lock_bh(&ar->ab->base_lock);
+ 	peer = ath11k_peer_find_by_addr(ar->ab, param->peer_addr);
+ 	if (peer) {
+-		spin_unlock_bh(&ar->ab->base_lock);
+-		return -EINVAL;
++		if (peer->vdev_id == param->vdev_id) {
++			spin_unlock_bh(&ar->ab->base_lock);
++			return -EINVAL;
++		}
++
++		/* Assume sta is transitioning to another band.
++		 * Remove here the peer from rhash.
++		 */
++		mutex_lock(&ar->ab->tbl_mtx_lock);
++		ath11k_peer_rhash_delete(ar->ab, peer);
++		mutex_unlock(&ar->ab->tbl_mtx_lock);
+ 	}
+ 	spin_unlock_bh(&ar->ab->base_lock);
+ 
+diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c
+index 00136601cb7db..e6ced8597e1d6 100644
+--- a/drivers/net/wireless/ath/ath11k/qmi.c
++++ b/drivers/net/wireless/ath/ath11k/qmi.c
+@@ -1696,6 +1696,13 @@ static struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = {
+ 	},
+ };
+ 
++static struct qmi_elem_info qmi_wlfw_fw_init_done_ind_msg_v01_ei[] = {
++	{
++		.data_type = QMI_EOTI,
++		.array_type = NO_ARRAY,
++	},
++};
++
+ static int ath11k_qmi_host_cap_send(struct ath11k_base *ab)
+ {
+ 	struct qmi_wlanfw_host_cap_req_msg_v01 req;
+@@ -3006,6 +3013,10 @@ static void ath11k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,
+ 	struct ath11k_base *ab = qmi->ab;
+ 
+ 	ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware ready\n");
++
++	ab->qmi.cal_done = 1;
++	wake_up(&ab->qmi.cold_boot_waitq);
++
+ 	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_READY, NULL);
+ }
+ 
+@@ -3018,11 +3029,22 @@ static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi_hdl,
+ 					      struct ath11k_qmi, handle);
+ 	struct ath11k_base *ab = qmi->ab;
+ 
+-	ab->qmi.cal_done = 1;
+-	wake_up(&ab->qmi.cold_boot_waitq);
+ 	ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi cold boot calibration done\n");
+ }
+ 
++static void ath11k_qmi_msg_fw_init_done_cb(struct qmi_handle *qmi_hdl,
++					   struct sockaddr_qrtr *sq,
++					   struct qmi_txn *txn,
++					   const void *decoded)
++{
++	struct ath11k_qmi *qmi = container_of(qmi_hdl,
++					      struct ath11k_qmi, handle);
++	struct ath11k_base *ab = qmi->ab;
++
++	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_INIT_DONE, NULL);
++	ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware init done\n");
++}
++
+ static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
+ 	{
+ 		.type = QMI_INDICATION,
+@@ -3053,6 +3075,14 @@ static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
+ 			sizeof(struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01),
+ 		.fn = ath11k_qmi_msg_cold_boot_cal_done_cb,
+ 	},
++	{
++		.type = QMI_INDICATION,
++		.msg_id = QMI_WLFW_FW_INIT_DONE_IND_V01,
++		.ei = qmi_wlfw_fw_init_done_ind_msg_v01_ei,
++		.decoded_size =
++			sizeof(struct qmi_wlfw_fw_init_done_ind_msg_v01),
++		.fn = ath11k_qmi_msg_fw_init_done_cb,
++	},
+ };
+ 
+ static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
+@@ -3145,7 +3175,7 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)
+ 			}
+ 
+ 			break;
+-		case ATH11K_QMI_EVENT_FW_READY:
++		case ATH11K_QMI_EVENT_FW_INIT_DONE:
+ 			clear_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
+ 			if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {
+ 				ath11k_hal_dump_srng_stats(ab);
+@@ -3168,6 +3198,8 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)
+ 				set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
+ 			}
+ 
++			break;
++		case ATH11K_QMI_EVENT_FW_READY:
+ 			break;
+ 		case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
+ 			break;
+diff --git a/drivers/net/wireless/ath/ath11k/qmi.h b/drivers/net/wireless/ath/ath11k/qmi.h
+index c83cf822be81a..2ec56a34fa810 100644
+--- a/drivers/net/wireless/ath/ath11k/qmi.h
++++ b/drivers/net/wireless/ath/ath11k/qmi.h
+@@ -31,8 +31,9 @@
+ 
+ #define QMI_WLFW_REQUEST_MEM_IND_V01		0x0035
+ #define QMI_WLFW_FW_MEM_READY_IND_V01		0x0037
+-#define QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01	0x0021
+-#define QMI_WLFW_FW_READY_IND_V01		0x0038
++#define QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01	0x003E
++#define QMI_WLFW_FW_READY_IND_V01		0x0021
++#define QMI_WLFW_FW_INIT_DONE_IND_V01		0x0038
+ 
+ #define QMI_WLANFW_MAX_DATA_SIZE_V01		6144
+ #define ATH11K_FIRMWARE_MODE_OFF		4
+@@ -69,6 +70,7 @@ enum ath11k_qmi_event_type {
+ 	ATH11K_QMI_EVENT_FORCE_FW_ASSERT,
+ 	ATH11K_QMI_EVENT_POWER_UP,
+ 	ATH11K_QMI_EVENT_POWER_DOWN,
++	ATH11K_QMI_EVENT_FW_INIT_DONE,
+ 	ATH11K_QMI_EVENT_MAX,
+ };
+ 
+@@ -291,6 +293,10 @@ struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01 {
+ 	char placeholder;
+ };
+ 
++struct qmi_wlfw_fw_init_done_ind_msg_v01 {
++	char placeholder;
++};
++
+ #define QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN		0
+ #define QMI_WLANFW_CAP_RESP_MSG_V01_MAX_LEN		235
+ #define QMI_WLANFW_CAP_REQ_V01				0x0024
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c
+index 88ee4f9d19da5..b658ea60dcf7d 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.c
++++ b/drivers/net/wireless/ath/ath11k/wmi.c
+@@ -8962,12 +8962,13 @@ int ath11k_wmi_sta_keepalive(struct ath11k *ar,
+ 	cmd->interval = arg->interval;
+ 	cmd->method = arg->method;
+ 
++	arp = (struct wmi_sta_keepalive_arp_resp *)(cmd + 1);
++	arp->tlv_header = FIELD_PREP(WMI_TLV_TAG,
++				     WMI_TAG_STA_KEEPALIVE_ARP_RESPONSE) |
++			 FIELD_PREP(WMI_TLV_LEN, sizeof(*arp) - TLV_HDR_SIZE);
++
+ 	if (arg->method == WMI_STA_KEEPALIVE_METHOD_UNSOLICITED_ARP_RESPONSE ||
+ 	    arg->method == WMI_STA_KEEPALIVE_METHOD_GRATUITOUS_ARP_REQUEST) {
+-		arp = (struct wmi_sta_keepalive_arp_resp *)(cmd + 1);
+-		arp->tlv_header = FIELD_PREP(WMI_TLV_TAG,
+-					     WMI_TAG_STA_KEEPALVE_ARP_RESPONSE) |
+-				 FIELD_PREP(WMI_TLV_LEN, sizeof(*arp) - TLV_HDR_SIZE);
+ 		arp->src_ip4_addr = arg->src_ip4_addr;
+ 		arp->dest_ip4_addr = arg->dest_ip4_addr;
+ 		ether_addr_copy(arp->dest_mac_addr.addr, arg->dest_mac_addr);
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h
+index 4da248ffa3186..ba5343a3411fa 100644
+--- a/drivers/net/wireless/ath/ath11k/wmi.h
++++ b/drivers/net/wireless/ath/ath11k/wmi.h
+@@ -1214,7 +1214,7 @@ enum wmi_tlv_tag {
+ 	WMI_TAG_NS_OFFLOAD_TUPLE,
+ 	WMI_TAG_FTM_INTG_CMD,
+ 	WMI_TAG_STA_KEEPALIVE_CMD,
+-	WMI_TAG_STA_KEEPALVE_ARP_RESPONSE,
++	WMI_TAG_STA_KEEPALIVE_ARP_RESPONSE,
+ 	WMI_TAG_P2P_SET_VENDOR_IE_DATA_CMD,
+ 	WMI_TAG_AP_PS_PEER_CMD,
+ 	WMI_TAG_PEER_RATE_RETRY_SCHED_CMD,
+diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
+index 994ec48b2f669..ca05b07a45e67 100644
+--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
++++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
+@@ -364,33 +364,27 @@ ret:
+ }
+ 
+ static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle,
+-				      struct sk_buff *skb)
++				      struct sk_buff *skb, u32 len)
+ {
+ 	uint32_t *pattern = (uint32_t *)skb->data;
+ 
+-	switch (*pattern) {
+-	case 0x33221199:
+-		{
++	if (*pattern == 0x33221199 && len >= sizeof(struct htc_panic_bad_vaddr)) {
+ 		struct htc_panic_bad_vaddr *htc_panic;
+ 		htc_panic = (struct htc_panic_bad_vaddr *) skb->data;
+ 		dev_err(htc_handle->dev, "ath: firmware panic! "
+ 			"exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n",
+ 			htc_panic->exccause, htc_panic->pc,
+ 			htc_panic->badvaddr);
+-		break;
+-		}
+-	case 0x33221299:
+-		{
++		return;
++	}
++	if (*pattern == 0x33221299) {
+ 		struct htc_panic_bad_epid *htc_panic;
+ 		htc_panic = (struct htc_panic_bad_epid *) skb->data;
+ 		dev_err(htc_handle->dev, "ath: firmware panic! "
+ 			"bad epid: 0x%08x\n", htc_panic->epid);
+-		break;
+-		}
+-	default:
+-		dev_err(htc_handle->dev, "ath: unknown panic pattern!\n");
+-		break;
++		return;
+ 	}
++	dev_err(htc_handle->dev, "ath: unknown panic pattern!\n");
+ }
+ 
+ /*
+@@ -411,16 +405,26 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
+ 	if (!htc_handle || !skb)
+ 		return;
+ 
++	/* A valid message requires len >= 8.
++	 *
++	 *   sizeof(struct htc_frame_hdr) == 8
++	 *   sizeof(struct htc_ready_msg) == 8
++	 *   sizeof(struct htc_panic_bad_vaddr) == 16
++	 *   sizeof(struct htc_panic_bad_epid) == 8
++	 */
++	if (unlikely(len < sizeof(struct htc_frame_hdr)))
++		goto invalid;
+ 	htc_hdr = (struct htc_frame_hdr *) skb->data;
+ 	epid = htc_hdr->endpoint_id;
+ 
+ 	if (epid == 0x99) {
+-		ath9k_htc_fw_panic_report(htc_handle, skb);
++		ath9k_htc_fw_panic_report(htc_handle, skb, len);
+ 		kfree_skb(skb);
+ 		return;
+ 	}
+ 
+ 	if (epid < 0 || epid >= ENDPOINT_MAX) {
++invalid:
+ 		if (pipe_id != USB_REG_IN_PIPE)
+ 			dev_kfree_skb_any(skb);
+ 		else
+@@ -432,21 +436,30 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
+ 
+ 		/* Handle trailer */
+ 		if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) {
+-			if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000)
++			if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000) {
+ 				/* Move past the Watchdog pattern */
+ 				htc_hdr = (struct htc_frame_hdr *)(skb->data + 4);
++				len -= 4;
++			}
+ 		}
+ 
+ 		/* Get the message ID */
++		if (unlikely(len < sizeof(struct htc_frame_hdr) + sizeof(__be16)))
++			goto invalid;
+ 		msg_id = (__be16 *) ((void *) htc_hdr +
+ 				     sizeof(struct htc_frame_hdr));
+ 
+ 		/* Now process HTC messages */
+ 		switch (be16_to_cpu(*msg_id)) {
+ 		case HTC_MSG_READY_ID:
++			if (unlikely(len < sizeof(struct htc_ready_msg)))
++				goto invalid;
+ 			htc_process_target_rdy(htc_handle, htc_hdr);
+ 			break;
+ 		case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID:
++			if (unlikely(len < sizeof(struct htc_frame_hdr) +
++				     sizeof(struct htc_conn_svc_rspmsg)))
++				goto invalid;
+ 			htc_process_conn_rsp(htc_handle, htc_hdr);
+ 			break;
+ 		default:
+diff --git a/drivers/net/wireless/ath/ath9k/rng.c b/drivers/net/wireless/ath/ath9k/rng.c
+index cb5414265a9b5..58c0ab01771b0 100644
+--- a/drivers/net/wireless/ath/ath9k/rng.c
++++ b/drivers/net/wireless/ath/ath9k/rng.c
+@@ -83,7 +83,8 @@ static int ath9k_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+ 		if (!wait || !max || likely(bytes_read) || fail_stats > 110)
+ 			break;
+ 
+-		msleep_interruptible(ath9k_rng_delay_get(++fail_stats));
++		if (hwrng_msleep(rng, ath9k_rng_delay_get(++fail_stats)))
++			break;
+ 	}
+ 
+ 	if (wait && !bytes_read && max)
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+index bd164a0821f9f..ca95b02962eff 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -292,6 +292,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
+ 	struct brcmf_pub *drvr = ifp->drvr;
+ 	struct ethhdr *eh;
+ 	int head_delta;
++	unsigned int tx_bytes = skb->len;
+ 
+ 	brcmf_dbg(DATA, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
+ 
+@@ -366,7 +367,7 @@ done:
+ 		ndev->stats.tx_dropped++;
+ 	} else {
+ 		ndev->stats.tx_packets++;
+-		ndev->stats.tx_bytes += skb->len;
++		ndev->stats.tx_bytes += tx_bytes;
+ 	}
+ 
+ 	/* Return ok: we always eat the packet */
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+index fabfbb0b40b0c..d0a7465be586d 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+@@ -158,12 +158,12 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)
+ 	struct brcmf_pno_macaddr_le pfn_mac;
+ 	u8 *mac_addr = NULL;
+ 	u8 *mac_mask = NULL;
+-	int err, i;
++	int err, i, ri;
+ 
+-	for (i = 0; i < pi->n_reqs; i++)
+-		if (pi->reqs[i]->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
+-			mac_addr = pi->reqs[i]->mac_addr;
+-			mac_mask = pi->reqs[i]->mac_addr_mask;
++	for (ri = 0; ri < pi->n_reqs; ri++)
++		if (pi->reqs[ri]->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
++			mac_addr = pi->reqs[ri]->mac_addr;
++			mac_mask = pi->reqs[ri]->mac_addr_mask;
+ 			break;
+ 		}
+ 
+@@ -185,7 +185,7 @@ static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi)
+ 	pfn_mac.mac[0] |= 0x02;
+ 
+ 	brcmf_dbg(SCAN, "enabling random mac: reqid=%llu mac=%pM\n",
+-		  pi->reqs[i]->reqid, pfn_mac.mac);
++		  pi->reqs[ri]->reqid, pfn_mac.mac);
+ 	err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
+ 				       sizeof(pfn_mac));
+ 	if (err)
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index ee34814bd12b5..a074552bcec3d 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -2995,10 +2995,15 @@ static int mac80211_hwsim_change_vif_links(struct ieee80211_hw *hw,
+ 					   u16 old_links, u16 new_links,
+ 					   struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS])
+ {
+-	unsigned long rem = old_links & ~new_links ?: BIT(0);
++	unsigned long rem = old_links & ~new_links;
+ 	unsigned long add = new_links & ~old_links;
+ 	int i;
+ 
++	if (!old_links)
++		rem |= BIT(0);
++	if (!new_links)
++		add |= BIT(0);
++
+ 	for_each_set_bit(i, &rem, IEEE80211_MLD_MAX_NUM_LINKS)
+ 		mac80211_hwsim_config_mac_nl(hw, old[i]->addr, false);
+ 
+diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c
+index fc77489cc5119..7dddb4b5dea1d 100644
+--- a/drivers/net/wireless/marvell/mwifiex/init.c
++++ b/drivers/net/wireless/marvell/mwifiex/init.c
+@@ -51,9 +51,10 @@ static void wakeup_timer_fn(struct timer_list *t)
+ 		adapter->if_ops.card_reset(adapter);
+ }
+ 
+-static void fw_dump_timer_fn(struct timer_list *t)
++static void fw_dump_work(struct work_struct *work)
+ {
+-	struct mwifiex_adapter *adapter = from_timer(adapter, t, devdump_timer);
++	struct mwifiex_adapter *adapter =
++		container_of(work, struct mwifiex_adapter, devdump_work.work);
+ 
+ 	mwifiex_upload_device_dump(adapter);
+ }
+@@ -309,7 +310,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
+ 	adapter->active_scan_triggered = false;
+ 	timer_setup(&adapter->wakeup_timer, wakeup_timer_fn, 0);
+ 	adapter->devdump_len = 0;
+-	timer_setup(&adapter->devdump_timer, fw_dump_timer_fn, 0);
++	INIT_DELAYED_WORK(&adapter->devdump_work, fw_dump_work);
+ }
+ 
+ /*
+@@ -388,7 +389,7 @@ static void
+ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
+ {
+ 	del_timer(&adapter->wakeup_timer);
+-	del_timer_sync(&adapter->devdump_timer);
++	cancel_delayed_work_sync(&adapter->devdump_work);
+ 	mwifiex_cancel_all_pending_cmd(adapter);
+ 	wake_up_interruptible(&adapter->cmd_wait_q.wait);
+ 	wake_up_interruptible(&adapter->hs_activate_wait_q);
+diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
+index 87729d251fedc..63f861e6b28af 100644
+--- a/drivers/net/wireless/marvell/mwifiex/main.h
++++ b/drivers/net/wireless/marvell/mwifiex/main.h
+@@ -37,6 +37,7 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/slab.h>
+ #include <linux/of_irq.h>
++#include <linux/workqueue.h>
+ 
+ #include "decl.h"
+ #include "ioctl.h"
+@@ -1043,7 +1044,7 @@ struct mwifiex_adapter {
+ 	/* Device dump data/length */
+ 	void *devdump_data;
+ 	int devdump_len;
+-	struct timer_list devdump_timer;
++	struct delayed_work devdump_work;
+ 
+ 	bool ignore_btcoex_events;
+ };
+diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
+index b95e90a7d124a..e80e372cce8c4 100644
+--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
++++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
+@@ -611,8 +611,8 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv,
+ 		 * transmission event get lost, in this cornel case,
+ 		 * user would still get partial of the dump.
+ 		 */
+-		mod_timer(&adapter->devdump_timer,
+-			  jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
++		schedule_delayed_work(&adapter->devdump_work,
++				      msecs_to_jiffies(MWIFIEX_TIMER_10S));
+ 	}
+ 
+ 	/* Overflow check */
+@@ -631,7 +631,7 @@ mwifiex_fw_dump_info_event(struct mwifiex_private *priv,
+ 	return;
+ 
+ upload_dump:
+-	del_timer_sync(&adapter->devdump_timer);
++	cancel_delayed_work_sync(&adapter->devdump_work);
+ 	mwifiex_upload_device_dump(adapter);
+ }
+ 
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+index 9bf8545c8c17c..8d4733f87cda9 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+@@ -1195,12 +1195,16 @@ static void mt7615_sta_set_decap_offload(struct ieee80211_hw *hw,
+ 	struct mt7615_dev *dev = mt7615_hw_dev(hw);
+ 	struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
+ 
++	mt7615_mutex_acquire(dev);
++
+ 	if (enabled)
+ 		set_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);
+ 	else
+ 		clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);
+ 
+ 	mt7615_mcu_set_sta_decap_offload(dev, vif, sta);
++
++	mt7615_mutex_release(dev);
+ }
+ 
+ #ifdef CONFIG_PM
+diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+index 9b17bd97ec094..7cac7b126e590 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+@@ -260,8 +260,10 @@ mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag, int len,
+ 	ntlv = le16_to_cpu(ntlv_hdr->tlv_num);
+ 	ntlv_hdr->tlv_num = cpu_to_le16(ntlv + 1);
+ 
+-	if (sta_hdr)
+-		le16_add_cpu(&sta_hdr->len, len);
++	if (sta_hdr) {
++		len += le16_to_cpu(sta_hdr->len);
++		sta_hdr->len = cpu_to_le16(len);
++	}
+ 
+ 	return ptlv;
+ }
+@@ -2886,6 +2888,10 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
+ 		goto out;
+ 	}
+ 
++	snprintf(dev->hw->wiphy->fw_version,
++		 sizeof(dev->hw->wiphy->fw_version),
++		 "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
++
+ 	release_firmware(fw);
+ 
+ 	if (!fw_wa)
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+index fd76db8f5269c..6ef3431cad648 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+@@ -23,9 +23,9 @@ mt7915_implicit_txbf_set(void *data, u64 val)
+ {
+ 	struct mt7915_dev *dev = data;
+ 
+-	if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))
+-		return -EBUSY;
+-
++	/* The existing connected stations shall reconnect to apply
++	 * new implicit txbf configuration.
++	 */
+ 	dev->ibf = !!val;
+ 
+ 	return mt7915_mcu_set_txbf(dev, MT_BF_TYPE_UPDATE);
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+index 60ae834d95a6d..49aa5c056063e 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+@@ -232,7 +232,7 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
+ 	bool unicast, insert_ccmp_hdr = false;
+ 	u8 remove_pad, amsdu_info;
+ 	u8 mode = 0, qos_ctl = 0;
+-	struct mt7915_sta *msta;
++	struct mt7915_sta *msta = NULL;
+ 	bool hdr_trans;
+ 	u16 hdr_gap;
+ 	u16 seq_ctrl = 0;
+@@ -2071,8 +2071,9 @@ void mt7915_mac_add_twt_setup(struct ieee80211_hw *hw,
+ 	}
+ 
+ 	flowid = ffs(~msta->twt.flowid_mask) - 1;
+-	le16p_replace_bits(&twt_agrt->req_type, flowid,
+-			   IEEE80211_TWT_REQTYPE_FLOWID);
++	twt_agrt->req_type &= ~cpu_to_le16(IEEE80211_TWT_REQTYPE_FLOWID);
++	twt_agrt->req_type |= le16_encode_bits(flowid,
++					       IEEE80211_TWT_REQTYPE_FLOWID);
+ 
+ 	table_id = ffs(~dev->twt.table_mask) - 1;
+ 	exp = FIELD_GET(IEEE80211_TWT_REQTYPE_WAKE_INT_EXP, req_type);
+@@ -2122,8 +2123,9 @@ void mt7915_mac_add_twt_setup(struct ieee80211_hw *hw,
+ unlock:
+ 	mutex_unlock(&dev->mt76.mutex);
+ out:
+-	le16p_replace_bits(&twt_agrt->req_type, setup_cmd,
+-			   IEEE80211_TWT_REQTYPE_SETUP_CMD);
++	twt_agrt->req_type &= ~cpu_to_le16(IEEE80211_TWT_REQTYPE_SETUP_CMD);
++	twt_agrt->req_type |=
++		le16_encode_bits(setup_cmd, IEEE80211_TWT_REQTYPE_SETUP_CMD);
+ 	twt->control = (twt->control & IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT) |
+ 		       (twt->control & IEEE80211_TWT_CONTROL_RX_DISABLED);
+ }
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+index f830679619451..e99fdacc11ce1 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+@@ -1360,7 +1360,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+ 	struct sta_phy phy = {};
+ 	int ret, nrates = 0;
+ 
+-#define __sta_phy_bitrate_mask_check(_mcs, _gi, _he)				\
++#define __sta_phy_bitrate_mask_check(_mcs, _gi, _ht, _he)			\
+ 	do {									\
+ 		u8 i, gi = mask->control[band]._gi;				\
+ 		gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI;		\
+@@ -1373,15 +1373,17 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
+ 				continue;					\
+ 			nrates += hweight16(mask->control[band]._mcs[i]);	\
+ 			phy.mcs = ffs(mask->control[band]._mcs[i]) - 1;		\
++			if (_ht)						\
++				phy.mcs += 8 * i;				\
+ 		}								\
+ 	} while (0)
+ 
+ 	if (sta->deflink.he_cap.has_he) {
+-		__sta_phy_bitrate_mask_check(he_mcs, he_gi, 1);
++		__sta_phy_bitrate_mask_check(he_mcs, he_gi, 0, 1);
+ 	} else if (sta->deflink.vht_cap.vht_supported) {
+-		__sta_phy_bitrate_mask_check(vht_mcs, gi, 0);
++		__sta_phy_bitrate_mask_check(vht_mcs, gi, 0, 0);
+ 	} else if (sta->deflink.ht_cap.ht_supported) {
+-		__sta_phy_bitrate_mask_check(ht_mcs, gi, 0);
++		__sta_phy_bitrate_mask_check(ht_mcs, gi, 1, 0);
+ 	} else {
+ 		nrates = hweight32(mask->control[band].legacy);
+ 		phy.mcs = ffs(mask->control[band].legacy) - 1;
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c
+index be4f07ad3af91..47e034a9b0037 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c
+@@ -13,6 +13,7 @@ mt7921_acpi_read(struct mt7921_dev *dev, u8 *method, u8 **tbl, u32 *len)
+ 	acpi_handle root, handle;
+ 	acpi_status status;
+ 	u32 i = 0;
++	int ret;
+ 
+ 	root = ACPI_HANDLE(mdev->dev);
+ 	if (!root)
+@@ -52,9 +53,11 @@ mt7921_acpi_read(struct mt7921_dev *dev, u8 *method, u8 **tbl, u32 *len)
+ 		*(*tbl + i) = (u8)sar_unit->integer.value;
+ 	}
+ free:
++	ret = (i == sar_root->package.count) ? 0 : -EINVAL;
++
+ 	kfree(sar_root);
+ 
+-	return (i == sar_root->package.count) ? 0 : -EINVAL;
++	return ret;
+ }
+ 
+ /* MTCL : Country List Table for 6G band */
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+index 47f0aa81ab028..e8a7a58317822 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+@@ -235,7 +235,7 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
+ 	u32 rxd2 = le32_to_cpu(rxd[2]);
+ 	u32 rxd3 = le32_to_cpu(rxd[3]);
+ 	u32 rxd4 = le32_to_cpu(rxd[4]);
+-	struct mt7921_sta *msta;
++	struct mt7921_sta *msta = NULL;
+ 	u16 seq_ctrl = 0;
+ 	__le16 fc = 0;
+ 	u8 mode = 0;
+@@ -780,6 +780,7 @@ void mt7921_mac_reset_work(struct work_struct *work)
+ void mt7921_reset(struct mt76_dev *mdev)
+ {
+ 	struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
++	struct mt76_connac_pm *pm = &dev->pm;
+ 
+ 	if (!dev->hw_init_done)
+ 		return;
+@@ -787,8 +788,12 @@ void mt7921_reset(struct mt76_dev *mdev)
+ 	if (dev->hw_full_reset)
+ 		return;
+ 
++	if (pm->suspended)
++		return;
++
+ 	queue_work(dev->mt76.wq, &dev->reset_work);
+ }
++EXPORT_SYMBOL_GPL(mt7921_reset);
+ 
+ void mt7921_mac_update_mib_stats(struct mt7921_phy *phy)
+ {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+index 1438a9f8d1fd9..c9e9a533289f0 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+@@ -752,6 +752,7 @@ void mt7921_mac_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ 
+ 	mt7921_mac_wtbl_update(dev, msta->wcid.idx,
+ 			       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
++	memset(msta->airtime_ac, 0, sizeof(msta->airtime_ac));
+ 
+ 	mt7921_mcu_sta_update(dev, sta, vif, true, MT76_STA_INFO_STATE_ASSOC);
+ 
+@@ -1404,6 +1405,8 @@ static void mt7921_sta_set_decap_offload(struct ieee80211_hw *hw,
+ 	struct mt7921_sta *msta = (struct mt7921_sta *)sta->drv_priv;
+ 	struct mt7921_dev *dev = mt7921_hw_dev(hw);
+ 
++	mt7921_mutex_acquire(dev);
++
+ 	if (enabled)
+ 		set_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);
+ 	else
+@@ -1411,6 +1414,8 @@ static void mt7921_sta_set_decap_offload(struct ieee80211_hw *hw,
+ 
+ 	mt76_connac_mcu_sta_update_hdr_trans(&dev->mt76, vif, &msta->wcid,
+ 					     MCU_UNI_CMD(STA_REC_UPDATE));
++
++	mt7921_mutex_release(dev);
+ }
+ 
+ #if IS_ENABLED(CONFIG_IPV6)
+@@ -1526,17 +1531,23 @@ mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 	struct mt7921_dev *dev = mt7921_hw_dev(hw);
+ 	int err;
+ 
++	mt7921_mutex_acquire(dev);
++
+ 	err = mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid,
+ 					  true);
+ 	if (err)
+-		return err;
++		goto out;
+ 
+ 	err = mt7921_mcu_set_bss_pm(dev, vif, true);
+ 	if (err)
+-		return err;
++		goto out;
++
++	err = mt7921_mcu_sta_update(dev, NULL, vif, true,
++				    MT76_STA_INFO_STATE_NONE);
++out:
++	mt7921_mutex_release(dev);
+ 
+-	return mt7921_mcu_sta_update(dev, NULL, vif, true,
+-				     MT76_STA_INFO_STATE_NONE);
++	return err;
+ }
+ 
+ static void
+@@ -1548,11 +1559,16 @@ mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 	struct mt7921_dev *dev = mt7921_hw_dev(hw);
+ 	int err;
+ 
++	mt7921_mutex_acquire(dev);
++
+ 	err = mt7921_mcu_set_bss_pm(dev, vif, false);
+ 	if (err)
+-		return;
++		goto out;
+ 
+ 	mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, false);
++
++out:
++	mt7921_mutex_release(dev);
+ }
+ 
+ const struct ieee80211_ops mt7921_ops = {
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+index ea3069d18c35f..e5b1f6249763a 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+@@ -288,6 +288,8 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
+ 		goto err_free_pci_vec;
+ 	}
+ 
++	pci_set_drvdata(pdev, mdev);
++
+ 	dev = container_of(mdev, struct mt7921_dev, mt76);
+ 	dev->hif_ops = &mt7921_pcie_ops;
+ 
+@@ -367,6 +369,7 @@ static int mt7921_pci_suspend(struct device *device)
+ 	int i, err;
+ 
+ 	pm->suspended = true;
++	flush_work(&dev->reset_work);
+ 	cancel_delayed_work_sync(&pm->ps_work);
+ 	cancel_work_sync(&pm->wake_work);
+ 
+@@ -428,6 +431,9 @@ restore_napi:
+ restore_suspend:
+ 	pm->suspended = false;
+ 
++	if (err < 0)
++		mt7921_reset(&dev->mt76);
++
+ 	return err;
+ }
+ 
+@@ -441,7 +447,7 @@ static int mt7921_pci_resume(struct device *device)
+ 
+ 	err = mt7921_mcu_drv_pmctrl(dev);
+ 	if (err < 0)
+-		return err;
++		goto failed;
+ 
+ 	mt7921_wpdma_reinit_cond(dev);
+ 
+@@ -471,11 +477,12 @@ static int mt7921_pci_resume(struct device *device)
+ 		mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
+ 
+ 	err = mt76_connac_mcu_set_hif_suspend(mdev, false);
+-	if (err)
+-		return err;
+-
++failed:
+ 	pm->suspended = false;
+ 
++	if (err < 0)
++		mt7921_reset(&dev->mt76);
++
+ 	return err;
+ }
+ 
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
+index 487acd6e2be8f..2face849fb4fb 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c
+@@ -206,6 +206,7 @@ static int mt7921s_suspend(struct device *__dev)
+ 	pm->suspended = true;
+ 	set_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
+ 
++	flush_work(&dev->reset_work);
+ 	cancel_delayed_work_sync(&pm->ps_work);
+ 	cancel_work_sync(&pm->wake_work);
+ 
+@@ -261,6 +262,9 @@ restore_suspend:
+ 	clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
+ 	pm->suspended = false;
+ 
++	if (err < 0)
++		mt7921_reset(&dev->mt76);
++
+ 	return err;
+ }
+ 
+@@ -276,7 +280,7 @@ static int mt7921s_resume(struct device *__dev)
+ 
+ 	err = mt7921_mcu_drv_pmctrl(dev);
+ 	if (err < 0)
+-		return err;
++		goto failed;
+ 
+ 	mt76_worker_enable(&mdev->tx_worker);
+ 	mt76_worker_enable(&mdev->sdio.txrx_worker);
+@@ -288,11 +292,12 @@ static int mt7921s_resume(struct device *__dev)
+ 		mt76_connac_mcu_set_deep_sleep(mdev, false);
+ 
+ 	err = mt76_connac_mcu_set_hif_suspend(mdev, false);
+-	if (err)
+-		return err;
+-
++failed:
+ 	pm->suspended = false;
+ 
++	if (err < 0)
++		mt7921_reset(&dev->mt76);
++
+ 	return err;
+ }
+ 
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
+index dd3b8884e1620..613d5cefffc73 100644
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c
+@@ -300,11 +300,15 @@ static void mt7921u_disconnect(struct usb_interface *usb_intf)
+ static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state)
+ {
+ 	struct mt7921_dev *dev = usb_get_intfdata(intf);
++	struct mt76_connac_pm *pm = &dev->pm;
+ 	int err;
+ 
++	pm->suspended = true;
++	flush_work(&dev->reset_work);
++
+ 	err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
+ 	if (err)
+-		return err;
++		goto failed;
+ 
+ 	mt76u_stop_rx(&dev->mt76);
+ 	mt76u_stop_tx(&dev->mt76);
+@@ -312,11 +316,20 @@ static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state)
+ 	set_bit(MT76_STATE_SUSPEND, &dev->mphy.state);
+ 
+ 	return 0;
++
++failed:
++	pm->suspended = false;
++
++	if (err < 0)
++		mt7921_reset(&dev->mt76);
++
++	return err;
+ }
+ 
+ static int mt7921u_resume(struct usb_interface *intf)
+ {
+ 	struct mt7921_dev *dev = usb_get_intfdata(intf);
++	struct mt76_connac_pm *pm = &dev->pm;
+ 	bool reinit = true;
+ 	int err, i;
+ 
+@@ -338,16 +351,23 @@ static int mt7921u_resume(struct usb_interface *intf)
+ 	if (reinit || mt7921_dma_need_reinit(dev)) {
+ 		err = mt7921u_dma_init(dev, true);
+ 		if (err)
+-			return err;
++			goto failed;
+ 	}
+ 
+ 	clear_bit(MT76_STATE_SUSPEND, &dev->mphy.state);
+ 
+ 	err = mt76u_resume_rx(&dev->mt76);
+ 	if (err < 0)
+-		return err;
++		goto failed;
++
++	err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
++failed:
++	pm->suspended = false;
++
++	if (err < 0)
++		mt7921_reset(&dev->mt76);
+ 
+-	return mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
++	return err;
+ }
+ #endif /* CONFIG_PM */
+ 
+diff --git a/drivers/net/wireless/mediatek/mt76/sdio.c b/drivers/net/wireless/mediatek/mt76/sdio.c
+index aba2a98658214..0ec308f99af5a 100644
+--- a/drivers/net/wireless/mediatek/mt76/sdio.c
++++ b/drivers/net/wireless/mediatek/mt76/sdio.c
+@@ -478,14 +478,14 @@ static void mt76s_status_worker(struct mt76_worker *w)
+ 		if (ndata_frames > 0)
+ 			resched = true;
+ 
+-		if (dev->drv->tx_status_data &&
++		if (dev->drv->tx_status_data && ndata_frames > 0 &&
+ 		    !test_and_set_bit(MT76_READING_STATS, &dev->phy.state) &&
+ 		    !test_bit(MT76_STATE_SUSPEND, &dev->phy.state))
+-			queue_work(dev->wq, &dev->sdio.stat_work);
++			ieee80211_queue_work(dev->hw, &dev->sdio.stat_work);
+ 	} while (nframes > 0);
+ 
+ 	if (resched)
+-		mt76_worker_schedule(&dev->sdio.txrx_worker);
++		mt76_worker_schedule(&dev->tx_worker);
+ }
+ 
+ static void mt76s_tx_status_data(struct work_struct *work)
+@@ -508,7 +508,7 @@ static void mt76s_tx_status_data(struct work_struct *work)
+ 	}
+ 
+ 	if (count && test_bit(MT76_STATE_RUNNING, &dev->phy.state))
+-		queue_work(dev->wq, &sdio->stat_work);
++		ieee80211_queue_work(dev->hw, &sdio->stat_work);
+ 	else
+ 		clear_bit(MT76_READING_STATS, &dev->phy.state);
+ }
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+index 18102fbe36d6c..1a9e27a6d6369 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+@@ -4164,7 +4164,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ 		rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+ 		rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+ 		rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+-		rt2800_bbp_write(rt2x00dev, 86, 0);
++		if (rt2x00_rt(rt2x00dev, RT6352))
++			rt2800_bbp_write(rt2x00dev, 86, 0x38);
++		else
++			rt2800_bbp_write(rt2x00dev, 86, 0);
+ 	}
+ 
+ 	if (rf->channel <= 14) {
+@@ -4365,7 +4368,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
+ 		reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain;
+ 		rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
+ 
+-		rt2800_iq_calibrate(rt2x00dev, rf->channel);
++		if (rt2x00_rt(rt2x00dev, RT5592))
++			rt2800_iq_calibrate(rt2x00dev, rf->channel);
+ 	}
+ 
+ 	bbp = rt2800_bbp_read(rt2x00dev, 4);
+@@ -5644,7 +5648,8 @@ static inline void rt2800_set_vgc(struct rt2x00_dev *rt2x00dev,
+ 	if (qual->vgc_level != vgc_level) {
+ 		if (rt2x00_rt(rt2x00dev, RT3572) ||
+ 		    rt2x00_rt(rt2x00dev, RT3593) ||
+-		    rt2x00_rt(rt2x00dev, RT3883)) {
++		    rt2x00_rt(rt2x00dev, RT3883) ||
++		    rt2x00_rt(rt2x00dev, RT6352)) {
+ 			rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
+ 						       vgc_level);
+ 		} else if (rt2x00_rt(rt2x00dev, RT5592)) {
+@@ -5867,7 +5872,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
+ 		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
+ 	} else if (rt2x00_rt(rt2x00dev, RT6352)) {
+ 		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
+-		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
++		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001);
+ 		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+ 		rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000);
+ 		rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
+@@ -6129,6 +6134,27 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
+ 		reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
+ 		rt2x00_set_field32(&reg, US_CYC_CNT_CLOCK_CYCLE, 125);
+ 		rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
++	} else if (rt2x00_is_soc(rt2x00dev)) {
++		struct clk *clk = clk_get_sys("bus", NULL);
++		int rate;
++
++		if (IS_ERR(clk)) {
++			clk = clk_get_sys("cpu", NULL);
++
++			if (IS_ERR(clk)) {
++				rate = 125;
++			} else {
++				rate = clk_get_rate(clk) / 3000000;
++				clk_put(clk);
++			}
++		} else {
++			rate = clk_get_rate(clk) / 1000000;
++			clk_put(clk);
++		}
++
++		reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
++		rt2x00_set_field32(&reg, US_CYC_CNT_CLOCK_CYCLE, rate);
++		rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
+ 	}
+ 
+ 	reg = rt2800_register_read(rt2x00dev, HT_FBK_CFG0);
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+index 7ddce3c3f0c48..782b089a2e1ba 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+@@ -1425,7 +1425,7 @@ struct rtl8xxxu_fileops {
+ 	void (*set_tx_power) (struct rtl8xxxu_priv *priv, int channel,
+ 			      bool ht40);
+ 	void (*update_rate_mask) (struct rtl8xxxu_priv *priv,
+-				  u32 ramask, u8 rateid, int sgi);
++				  u32 ramask, u8 rateid, int sgi, int txbw_40mhz);
+ 	void (*report_connect) (struct rtl8xxxu_priv *priv,
+ 				u8 macid, bool connect);
+ 	void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
+@@ -1511,9 +1511,9 @@ void rtl8xxxu_gen2_config_channel(struct ieee80211_hw *hw);
+ void rtl8xxxu_gen1_usb_quirks(struct rtl8xxxu_priv *priv);
+ void rtl8xxxu_gen2_usb_quirks(struct rtl8xxxu_priv *priv);
+ void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
+-			       u32 ramask, u8 rateid, int sgi);
++			       u32 ramask, u8 rateid, int sgi, int txbw_40mhz);
+ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
+-				    u32 ramask, u8 rateid, int sgi);
++				    u32 ramask, u8 rateid, int sgi, int txbw_40mhz);
+ void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv,
+ 				  u8 macid, bool connect);
+ void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+index c66f0726b2535..08f9d17dce12e 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -1878,13 +1878,6 @@ static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv)
+ 
+ 		/* We have 8 bits to indicate validity */
+ 		map_addr = offset * 8;
+-		if (map_addr >= EFUSE_MAP_LEN) {
+-			dev_warn(dev, "%s: Illegal map_addr (%04x), "
+-				 "efuse corrupt!\n",
+-				 __func__, map_addr);
+-			ret = -EINVAL;
+-			goto exit;
+-		}
+ 		for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+ 			/* Check word enable condition in the section */
+ 			if (word_mask & BIT(i)) {
+@@ -1895,6 +1888,13 @@ static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv)
+ 			ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &val8);
+ 			if (ret)
+ 				goto exit;
++			if (map_addr >= EFUSE_MAP_LEN - 1) {
++				dev_warn(dev, "%s: Illegal map_addr (%04x), "
++					 "efuse corrupt!\n",
++					 __func__, map_addr);
++				ret = -EINVAL;
++				goto exit;
++			}
+ 			priv->efuse_wifi.raw[map_addr++] = val8;
+ 
+ 			ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &val8);
+@@ -2929,12 +2929,12 @@ bool rtl8xxxu_gen2_simularity_compare(struct rtl8xxxu_priv *priv,
+ 		}
+ 
+ 		if (!(simubitmap & 0x30) && priv->tx_paths > 1) {
+-			/* path B RX OK */
++			/* path B TX OK */
+ 			for (i = 4; i < 6; i++)
+ 				result[3][i] = result[c1][i];
+ 		}
+ 
+-		if (!(simubitmap & 0x30) && priv->tx_paths > 1) {
++		if (!(simubitmap & 0xc0) && priv->tx_paths > 1) {
+ 			/* path B RX OK */
+ 			for (i = 6; i < 8; i++)
+ 				result[3][i] = result[c1][i];
+@@ -4320,7 +4320,7 @@ static void rtl8xxxu_sw_scan_complete(struct ieee80211_hw *hw,
+ }
+ 
+ void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
+-			       u32 ramask, u8 rateid, int sgi)
++			       u32 ramask, u8 rateid, int sgi, int txbw_40mhz)
+ {
+ 	struct h2c_cmd h2c;
+ 
+@@ -4340,10 +4340,15 @@ void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
+ }
+ 
+ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
+-				    u32 ramask, u8 rateid, int sgi)
++				    u32 ramask, u8 rateid, int sgi, int txbw_40mhz)
+ {
+ 	struct h2c_cmd h2c;
+-	u8 bw = RTL8XXXU_CHANNEL_WIDTH_20;
++	u8 bw;
++
++	if (txbw_40mhz)
++		bw = RTL8XXXU_CHANNEL_WIDTH_40;
++	else
++		bw = RTL8XXXU_CHANNEL_WIDTH_20;
+ 
+ 	memset(&h2c, 0, sizeof(struct h2c_cmd));
+ 
+@@ -4353,15 +4358,14 @@ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
+ 	h2c.b_macid_cfg.ramask2 = (ramask >> 16) & 0xff;
+ 	h2c.b_macid_cfg.ramask3 = (ramask >> 24) & 0xff;
+ 
+-	h2c.ramask.arg = 0x80;
+ 	h2c.b_macid_cfg.data1 = rateid;
+ 	if (sgi)
+ 		h2c.b_macid_cfg.data1 |= BIT(7);
+ 
+ 	h2c.b_macid_cfg.data2 = bw;
+ 
+-	dev_dbg(&priv->udev->dev, "%s: rate mask %08x, arg %02x, size %zi\n",
+-		__func__, ramask, h2c.ramask.arg, sizeof(h2c.b_macid_cfg));
++	dev_dbg(&priv->udev->dev, "%s: rate mask %08x, rateid %02x, sgi %d, size %zi\n",
++		__func__, ramask, rateid, sgi, sizeof(h2c.b_macid_cfg));
+ 	rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.b_macid_cfg));
+ }
+ 
+@@ -4556,6 +4560,53 @@ rtl8xxxu_wireless_mode(struct ieee80211_hw *hw, struct ieee80211_sta *sta)
+ 	return network_type;
+ }
+ 
++static void rtl8xxxu_set_aifs(struct rtl8xxxu_priv *priv, u8 slot_time)
++{
++	u32 reg_edca_param[IEEE80211_NUM_ACS] = {
++		[IEEE80211_AC_VO] = REG_EDCA_VO_PARAM,
++		[IEEE80211_AC_VI] = REG_EDCA_VI_PARAM,
++		[IEEE80211_AC_BE] = REG_EDCA_BE_PARAM,
++		[IEEE80211_AC_BK] = REG_EDCA_BK_PARAM,
++	};
++	u32 val32;
++	u16 wireless_mode = 0;
++	u8 aifs, aifsn, sifs;
++	int i;
++
++	if (priv->vif) {
++		struct ieee80211_sta *sta;
++
++		rcu_read_lock();
++		sta = ieee80211_find_sta(priv->vif, priv->vif->bss_conf.bssid);
++		if (sta)
++			wireless_mode = rtl8xxxu_wireless_mode(priv->hw, sta);
++		rcu_read_unlock();
++	}
++
++	if (priv->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ ||
++	    (wireless_mode & WIRELESS_MODE_N_24G))
++		sifs = 16;
++	else
++		sifs = 10;
++
++	for (i = 0; i < IEEE80211_NUM_ACS; i++) {
++		val32 = rtl8xxxu_read32(priv, reg_edca_param[i]);
++
++		/* It was set in conf_tx. */
++		aifsn = val32 & 0xff;
++
++		/* aifsn not set yet or already fixed */
++		if (aifsn < 2 || aifsn > 15)
++			continue;
++
++		aifs = aifsn * slot_time + sifs;
++
++		val32 &= ~0xff;
++		val32 |= aifs;
++		rtl8xxxu_write32(priv, reg_edca_param[i], val32);
++	}
++}
++
+ static void
+ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 			  struct ieee80211_bss_conf *bss_conf, u64 changed)
+@@ -4622,7 +4673,11 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 						RATE_INFO_FLAGS_SHORT_GI;
+ 				}
+ 
+-				rarpt->txrate.bw |= RATE_INFO_BW_20;
++				if (rtl8xxxu_ht40_2g &&
++				    (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
++					rarpt->txrate.bw = RATE_INFO_BW_40;
++				else
++					rarpt->txrate.bw = RATE_INFO_BW_20;
+ 			}
+ 			bit_rate = cfg80211_calculate_bitrate(&rarpt->txrate);
+ 			rarpt->bit_rate = bit_rate;
+@@ -4631,7 +4686,7 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 			priv->vif = vif;
+ 			priv->rssi_level = RTL8XXXU_RATR_STA_INIT;
+ 
+-			priv->fops->update_rate_mask(priv, ramask, 0, sgi);
++			priv->fops->update_rate_mask(priv, ramask, 0, sgi, rarpt->txrate.bw == RATE_INFO_BW_40);
+ 
+ 			rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
+ 
+@@ -4671,6 +4726,8 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ 		else
+ 			val8 = 20;
+ 		rtl8xxxu_write8(priv, REG_SLOT, val8);
++
++		rtl8xxxu_set_aifs(priv, val8);
+ 	}
+ 
+ 	if (changed & BSS_CHANGED_BSSID) {
+@@ -5062,6 +5119,8 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
+ 	if (control && control->sta)
+ 		sta = control->sta;
+ 
++	queue = rtl8xxxu_queue_select(hw, skb);
++
+ 	tx_desc = skb_push(skb, tx_desc_size);
+ 
+ 	memset(tx_desc, 0, tx_desc_size);
+@@ -5074,7 +5133,6 @@ static void rtl8xxxu_tx(struct ieee80211_hw *hw,
+ 	    is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
+ 		tx_desc->txdw0 |= TXDESC_BROADMULTICAST;
+ 
+-	queue = rtl8xxxu_queue_select(hw, skb);
+ 	tx_desc->txdw1 = cpu_to_le32(queue << TXDESC_QUEUE_SHIFT);
+ 
+ 	if (tx_info->control.hw_key) {
+@@ -6344,7 +6402,7 @@ static void rtl8xxxu_refresh_rate_mask(struct rtl8xxxu_priv *priv,
+ 		}
+ 
+ 		priv->rssi_level = rssi_level;
+-		priv->fops->update_rate_mask(priv, rate_bitmap, ratr_idx, sgi);
++		priv->fops->update_rate_mask(priv, rate_bitmap, ratr_idx, sgi, txbw_40mhz);
+ 	}
+ }
+ 
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
+index 15e6a6aded319..d18c092b61426 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
+@@ -2386,11 +2386,10 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
+ 			rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD,
+ 				"Just Read IQK Matrix reg for channel:%d....\n",
+ 				channel);
+-			_rtl92d_phy_patha_fill_iqk_matrix(hw, true,
+-					rtlphy->iqk_matrix[
+-					indexforchannel].value,	0,
+-					(rtlphy->iqk_matrix[
+-					indexforchannel].value[0][2] == 0));
++			if (rtlphy->iqk_matrix[indexforchannel].value[0][0] != 0)
++				_rtl92d_phy_patha_fill_iqk_matrix(hw, true,
++					rtlphy->iqk_matrix[indexforchannel].value, 0,
++					rtlphy->iqk_matrix[indexforchannel].value[0][2] == 0);
+ 			if (IS_92D_SINGLEPHY(rtlhal->version)) {
+ 				if ((rtlphy->iqk_matrix[
+ 					indexforchannel].value[0][4] != 0)
+diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
+index 76dc9da88f6c2..3d31c0517a129 100644
+--- a/drivers/net/wireless/realtek/rtw88/main.c
++++ b/drivers/net/wireless/realtek/rtw88/main.c
+@@ -2045,7 +2045,7 @@ int rtw_core_init(struct rtw_dev *rtwdev)
+ 	ret = rtw_load_firmware(rtwdev, RTW_NORMAL_FW);
+ 	if (ret) {
+ 		rtw_warn(rtwdev, "no firmware loaded\n");
+-		return ret;
++		goto out;
+ 	}
+ 
+ 	if (chip->wow_fw_name) {
+@@ -2055,11 +2055,15 @@ int rtw_core_init(struct rtw_dev *rtwdev)
+ 			wait_for_completion(&rtwdev->fw.completion);
+ 			if (rtwdev->fw.firmware)
+ 				release_firmware(rtwdev->fw.firmware);
+-			return ret;
++			goto out;
+ 		}
+ 	}
+ 
+ 	return 0;
++
++out:
++	destroy_workqueue(rtwdev->tx_wq);
++	return ret;
+ }
+ EXPORT_SYMBOL(rtw_core_init);
+ 
+diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
+index a5880a54812e7..8b338e5ce364e 100644
+--- a/drivers/net/wireless/realtek/rtw89/core.c
++++ b/drivers/net/wireless/realtek/rtw89/core.c
+@@ -872,6 +872,7 @@ int rtw89_h2c_tx(struct rtw89_dev *rtwdev,
+ 		rtw89_debug(rtwdev, RTW89_DBG_FW,
+ 			    "ignore h2c due to power is off with firmware state=%d\n",
+ 			    test_bit(RTW89_FLAG_FW_RDY, rtwdev->flags));
++		dev_kfree_skb(skb);
+ 		return 0;
+ 	}
+ 
+diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
+index 6473015a6b2a1..c993fe9cf6b4a 100644
+--- a/drivers/net/wireless/realtek/rtw89/fw.c
++++ b/drivers/net/wireless/realtek/rtw89/fw.c
+@@ -2289,6 +2289,7 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+ {
+ 	struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
+ 	struct cfg80211_scan_request *req = &scan_req->req;
++	u32 rx_fltr = rtwdev->hal.rx_fltr;
+ 	u8 mac_addr[ETH_ALEN];
+ 
+ 	rtwdev->scan_info.scanning_vif = vif;
+@@ -2303,13 +2304,13 @@ void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+ 		ether_addr_copy(mac_addr, vif->addr);
+ 	rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, true);
+ 
+-	rtwdev->hal.rx_fltr &= ~B_AX_A_BCN_CHK_EN;
+-	rtwdev->hal.rx_fltr &= ~B_AX_A_BC;
+-	rtwdev->hal.rx_fltr &= ~B_AX_A_A1_MATCH;
++	rx_fltr &= ~B_AX_A_BCN_CHK_EN;
++	rx_fltr &= ~B_AX_A_BC;
++	rx_fltr &= ~B_AX_A_A1_MATCH;
+ 	rtw89_write32_mask(rtwdev,
+ 			   rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
+ 			   B_AX_RX_FLTR_CFG_MASK,
+-			   rtwdev->hal.rx_fltr);
++			   rx_fltr);
+ }
+ 
+ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+@@ -2323,9 +2324,6 @@ void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
+ 	if (!vif)
+ 		return;
+ 
+-	rtwdev->hal.rx_fltr |= B_AX_A_BCN_CHK_EN;
+-	rtwdev->hal.rx_fltr |= B_AX_A_BC;
+-	rtwdev->hal.rx_fltr |= B_AX_A_A1_MATCH;
+ 	rtw89_write32_mask(rtwdev,
+ 			   rtw89_mac_reg_by_idx(R_AX_RX_FLTR_OPT, RTW89_MAC_0),
+ 			   B_AX_RX_FLTR_CFG_MASK,
+diff --git a/drivers/net/wireless/realtek/rtw89/pci.c b/drivers/net/wireless/realtek/rtw89/pci.c
+index c68fec9eb5a64..7bb1b494c5d15 100644
+--- a/drivers/net/wireless/realtek/rtw89/pci.c
++++ b/drivers/net/wireless/realtek/rtw89/pci.c
+@@ -760,7 +760,8 @@ static irqreturn_t rtw89_pci_interrupt_threadfn(int irq, void *dev)
+ 
+ enable_intr:
+ 	spin_lock_irqsave(&rtwpci->irq_lock, flags);
+-	rtw89_chip_enable_intr(rtwdev, rtwpci);
++	if (likely(rtwpci->running))
++		rtw89_chip_enable_intr(rtwdev, rtwpci);
+ 	spin_unlock_irqrestore(&rtwpci->irq_lock, flags);
+ 	return IRQ_HANDLED;
+ }
+@@ -925,10 +926,12 @@ u32 __rtw89_pci_check_and_reclaim_tx_resource_noio(struct rtw89_dev *rtwdev,
+ {
+ 	struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+ 	struct rtw89_pci_tx_ring *tx_ring = &rtwpci->tx_rings[txch];
++	struct rtw89_pci_tx_wd_ring *wd_ring = &tx_ring->wd_ring;
+ 	u32 cnt;
+ 
+ 	spin_lock_bh(&rtwpci->trx_lock);
+ 	cnt = rtw89_pci_get_avail_txbd_num(tx_ring);
++	cnt = min(cnt, wd_ring->curr_num);
+ 	spin_unlock_bh(&rtwpci->trx_lock);
+ 
+ 	return cnt;
+diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c
+index 726223f25dc69..7240364e8f7df 100644
+--- a/drivers/net/wireless/realtek/rtw89/ser.c
++++ b/drivers/net/wireless/realtek/rtw89/ser.c
+@@ -152,7 +152,10 @@ static void ser_state_run(struct rtw89_ser *ser, u8 evt)
+ 	rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s receive %s\n",
+ 		    ser_st_name(ser), ser_ev_name(ser, evt));
+ 
++	mutex_lock(&rtwdev->mutex);
+ 	rtw89_leave_lps(rtwdev);
++	mutex_unlock(&rtwdev->mutex);
++
+ 	ser->st_tbl[ser->state].st_func(ser, evt);
+ }
+ 
+diff --git a/drivers/net/wireless/silabs/wfx/main.c b/drivers/net/wireless/silabs/wfx/main.c
+index e015bfb8d221f..84d82ddded567 100644
+--- a/drivers/net/wireless/silabs/wfx/main.c
++++ b/drivers/net/wireless/silabs/wfx/main.c
+@@ -181,7 +181,7 @@ int wfx_send_pds(struct wfx_dev *wdev, u8 *buf, size_t len)
+ 	while (len > 0) {
+ 		chunk_type = get_unaligned_le16(buf + 0);
+ 		chunk_len = get_unaligned_le16(buf + 2);
+-		if (chunk_len > len) {
++		if (chunk_len < 4 || chunk_len > len) {
+ 			dev_err(wdev->dev, "PDS:%d: corrupted file\n", chunk_num);
+ 			return -EINVAL;
+ 		}
+diff --git a/drivers/net/wireless/st/cw1200/queue.c b/drivers/net/wireless/st/cw1200/queue.c
+index e06da4b3b0d46..805a3c1bf8fe2 100644
+--- a/drivers/net/wireless/st/cw1200/queue.c
++++ b/drivers/net/wireless/st/cw1200/queue.c
+@@ -91,23 +91,25 @@ static void __cw1200_queue_gc(struct cw1200_queue *queue,
+ 			      bool unlock)
+ {
+ 	struct cw1200_queue_stats *stats = queue->stats;
+-	struct cw1200_queue_item *item = NULL, *tmp;
++	struct cw1200_queue_item *item = NULL, *iter, *tmp;
+ 	bool wakeup_stats = false;
+ 
+-	list_for_each_entry_safe(item, tmp, &queue->queue, head) {
+-		if (time_is_after_jiffies(item->queue_timestamp + queue->ttl))
++	list_for_each_entry_safe(iter, tmp, &queue->queue, head) {
++		if (time_is_after_jiffies(iter->queue_timestamp + queue->ttl)) {
++			item = iter;
+ 			break;
++		}
+ 		--queue->num_queued;
+-		--queue->link_map_cache[item->txpriv.link_id];
++		--queue->link_map_cache[iter->txpriv.link_id];
+ 		spin_lock_bh(&stats->lock);
+ 		--stats->num_queued;
+-		if (!--stats->link_map_cache[item->txpriv.link_id])
++		if (!--stats->link_map_cache[iter->txpriv.link_id])
+ 			wakeup_stats = true;
+ 		spin_unlock_bh(&stats->lock);
+ 		cw1200_debug_tx_ttl(stats->priv);
+-		cw1200_queue_register_post_gc(head, item);
+-		item->skb = NULL;
+-		list_move_tail(&item->head, &queue->free_pool);
++		cw1200_queue_register_post_gc(head, iter);
++		iter->skb = NULL;
++		list_move_tail(&iter->head, &queue->free_pool);
+ 	}
+ 
+ 	if (wakeup_stats)
+diff --git a/drivers/net/wwan/iosm/iosm_ipc_wwan.c b/drivers/net/wwan/iosm/iosm_ipc_wwan.c
+index 27151148c782c..4712f01a7e33e 100644
+--- a/drivers/net/wwan/iosm/iosm_ipc_wwan.c
++++ b/drivers/net/wwan/iosm/iosm_ipc_wwan.c
+@@ -323,15 +323,16 @@ struct iosm_wwan *ipc_wwan_init(struct iosm_imem *ipc_imem, struct device *dev)
+ 	ipc_wwan->dev = dev;
+ 	ipc_wwan->ipc_imem = ipc_imem;
+ 
++	mutex_init(&ipc_wwan->if_mutex);
++
+ 	/* WWAN core will create a netdev for the default IP MUX channel */
+ 	if (wwan_register_ops(ipc_wwan->dev, &iosm_wwan_ops, ipc_wwan,
+ 			      IP_MUX_SESSION_DEFAULT)) {
++		mutex_destroy(&ipc_wwan->if_mutex);
+ 		kfree(ipc_wwan);
+ 		return NULL;
+ 	}
+ 
+-	mutex_init(&ipc_wwan->if_mutex);
+-
+ 	return ipc_wwan;
+ }
+ 
+diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
+index 8d5a7ae198440..59e4b188fc71c 100644
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1111,8 +1111,8 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+ 	return effects;
+ }
+ 
+-static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
+-			      struct nvme_command *cmd, int status)
++void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
++		       struct nvme_command *cmd, int status)
+ {
+ 	if (effects & NVME_CMD_EFFECTS_CSE_MASK) {
+ 		nvme_unfreeze(ctrl);
+@@ -1148,21 +1148,16 @@ static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
+ 		break;
+ 	}
+ }
++EXPORT_SYMBOL_NS_GPL(nvme_passthru_end, NVME_TARGET_PASSTHRU);
+ 
+-int nvme_execute_passthru_rq(struct request *rq)
++int nvme_execute_passthru_rq(struct request *rq, u32 *effects)
+ {
+ 	struct nvme_command *cmd = nvme_req(rq)->cmd;
+ 	struct nvme_ctrl *ctrl = nvme_req(rq)->ctrl;
+ 	struct nvme_ns *ns = rq->q->queuedata;
+-	u32 effects;
+-	int  ret;
+ 
+-	effects = nvme_passthru_start(ctrl, ns, cmd->common.opcode);
+-	ret = nvme_execute_rq(rq, false);
+-	if (effects) /* nothing to be done for zero cmd effects */
+-		nvme_passthru_end(ctrl, effects, cmd, ret);
+-
+-	return ret;
++	*effects = nvme_passthru_start(ctrl, ns, cmd->common.opcode);
++	return nvme_execute_rq(rq, false);
+ }
+ EXPORT_SYMBOL_NS_GPL(nvme_execute_passthru_rq, NVME_TARGET_PASSTHRU);
+ 
+@@ -2894,7 +2889,6 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
+ 	nvme_init_subnqn(subsys, ctrl, id);
+ 	memcpy(subsys->serial, id->sn, sizeof(subsys->serial));
+ 	memcpy(subsys->model, id->mn, sizeof(subsys->model));
+-	memcpy(subsys->firmware_rev, id->fr, sizeof(subsys->firmware_rev));
+ 	subsys->vendor_id = le16_to_cpu(id->vid);
+ 	subsys->cmic = id->cmic;
+ 
+@@ -3113,6 +3107,8 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
+ 				ctrl->quirks |= core_quirks[i].quirks;
+ 		}
+ 	}
++	memcpy(ctrl->subsys->firmware_rev, id->fr,
++	       sizeof(ctrl->subsys->firmware_rev));
+ 
+ 	if (force_apst && (ctrl->quirks & NVME_QUIRK_NO_DEEPEST_PS)) {
+ 		dev_warn(ctrl->device, "forcibly allowing all power states due to nvme_core.force_apst -- use at your own risk\n");
+diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
+index 27614bee73806..d3281f87cd6e4 100644
+--- a/drivers/nvme/host/ioctl.c
++++ b/drivers/nvme/host/ioctl.c
+@@ -136,9 +136,11 @@ static int nvme_submit_user_cmd(struct request_queue *q,
+ 		unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
+ 		u32 meta_seed, u64 *result, unsigned timeout, bool vec)
+ {
++	struct nvme_ctrl *ctrl;
+ 	struct request *req;
+ 	void *meta = NULL;
+ 	struct bio *bio;
++	u32 effects;
+ 	int ret;
+ 
+ 	req = nvme_alloc_user_request(q, cmd, ubuffer, bufflen, meta_buffer,
+@@ -147,8 +149,9 @@ static int nvme_submit_user_cmd(struct request_queue *q,
+ 		return PTR_ERR(req);
+ 
+ 	bio = req->bio;
++	ctrl = nvme_req(req)->ctrl;
+ 
+-	ret = nvme_execute_passthru_rq(req);
++	ret = nvme_execute_passthru_rq(req, &effects);
+ 
+ 	if (result)
+ 		*result = le64_to_cpu(nvme_req(req)->result.u64);
+@@ -158,6 +161,10 @@ static int nvme_submit_user_cmd(struct request_queue *q,
+ 	if (bio)
+ 		blk_rq_unmap_user(bio);
+ 	blk_mq_free_request(req);
++
++	if (effects)
++		nvme_passthru_end(ctrl, effects, cmd, ret);
++
+ 	return ret;
+ }
+ 
+diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
+index 6ef497c75a165..b9cf17cbbbd5d 100644
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -182,6 +182,7 @@ void nvme_mpath_revalidate_paths(struct nvme_ns *ns)
+ 
+ 	for_each_node(node)
+ 		rcu_assign_pointer(head->current_path[node], NULL);
++	kblockd_schedule_work(&head->requeue_work);
+ }
+ 
+ static bool nvme_path_is_disabled(struct nvme_ns *ns)
+diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
+index 1bdf714dcd9e4..a0bf9560cf678 100644
+--- a/drivers/nvme/host/nvme.h
++++ b/drivers/nvme/host/nvme.h
+@@ -1023,7 +1023,9 @@ static inline void nvme_auth_free(struct nvme_ctrl *ctrl) {};
+ 
+ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
+ 			 u8 opcode);
+-int nvme_execute_passthru_rq(struct request *rq);
++int nvme_execute_passthru_rq(struct request *rq, u32 *effects);
++void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
++		       struct nvme_command *cmd, int status);
+ struct nvme_ctrl *nvme_ctrl_from_file(struct file *file);
+ struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid);
+ void nvme_put_ns(struct nvme_ns *ns);
+diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
+index 7f4083cf953a6..14677145bbba0 100644
+--- a/drivers/nvme/target/core.c
++++ b/drivers/nvme/target/core.c
+@@ -832,6 +832,7 @@ int nvmet_sq_init(struct nvmet_sq *sq)
+ 	}
+ 	init_completion(&sq->free_done);
+ 	init_completion(&sq->confirm_done);
++	nvmet_auth_sq_init(sq);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/nvme/target/fabrics-cmd-auth.c b/drivers/nvme/target/fabrics-cmd-auth.c
+index ebdf9aa810419..0c078b6b1447e 100644
+--- a/drivers/nvme/target/fabrics-cmd-auth.c
++++ b/drivers/nvme/target/fabrics-cmd-auth.c
+@@ -23,17 +23,12 @@ static void nvmet_auth_expired_work(struct work_struct *work)
+ 	sq->dhchap_tid = -1;
+ }
+ 
+-void nvmet_init_auth(struct nvmet_ctrl *ctrl, struct nvmet_req *req)
++void nvmet_auth_sq_init(struct nvmet_sq *sq)
+ {
+-	u32 result = le32_to_cpu(req->cqe->result.u32);
+-
+ 	/* Initialize in-band authentication */
+-	INIT_DELAYED_WORK(&req->sq->auth_expired_work,
+-			  nvmet_auth_expired_work);
+-	req->sq->authenticated = false;
+-	req->sq->dhchap_step = NVME_AUTH_DHCHAP_MESSAGE_NEGOTIATE;
+-	result |= (u32)NVME_CONNECT_AUTHREQ_ATR << 16;
+-	req->cqe->result.u32 = cpu_to_le32(result);
++	INIT_DELAYED_WORK(&sq->auth_expired_work, nvmet_auth_expired_work);
++	sq->authenticated = false;
++	sq->dhchap_step = NVME_AUTH_DHCHAP_MESSAGE_NEGOTIATE;
+ }
+ 
+ static u16 nvmet_auth_negotiate(struct nvmet_req *req, void *d)
+diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c
+index f91a56180d3dd..bd739d8b6991b 100644
+--- a/drivers/nvme/target/fabrics-cmd.c
++++ b/drivers/nvme/target/fabrics-cmd.c
+@@ -272,7 +272,8 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req)
+ 	req->cqe->result.u16 = cpu_to_le16(ctrl->cntlid);
+ 
+ 	if (nvmet_has_auth(ctrl))
+-		nvmet_init_auth(ctrl, req);
++		req->cqe->result.u32 |=
++			cpu_to_le32((u32)NVME_CONNECT_AUTHREQ_ATR << 16);
+ out:
+ 	kfree(d);
+ complete:
+@@ -334,7 +335,8 @@ static void nvmet_execute_io_connect(struct nvmet_req *req)
+ 	pr_debug("adding queue %d to ctrl %d.\n", qid, ctrl->cntlid);
+ 	req->cqe->result.u16 = cpu_to_le16(ctrl->cntlid);
+ 	if (nvmet_has_auth(ctrl))
+-		nvmet_init_auth(ctrl, req);
++		req->cqe->result.u32 |=
++			cpu_to_le32((u32)NVME_CONNECT_AUTHREQ_ATR << 16);
+ 
+ out:
+ 	kfree(d);
+diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
+index 6ffeeb0a1c49e..dfe3894205aa7 100644
+--- a/drivers/nvme/target/nvmet.h
++++ b/drivers/nvme/target/nvmet.h
+@@ -704,7 +704,7 @@ int nvmet_auth_set_key(struct nvmet_host *host, const char *secret,
+ 		       bool set_ctrl);
+ int nvmet_auth_set_host_hash(struct nvmet_host *host, const char *hash);
+ int nvmet_setup_auth(struct nvmet_ctrl *ctrl);
+-void nvmet_init_auth(struct nvmet_ctrl *ctrl, struct nvmet_req *req);
++void nvmet_auth_sq_init(struct nvmet_sq *sq);
+ void nvmet_destroy_auth(struct nvmet_ctrl *ctrl);
+ void nvmet_auth_sq_free(struct nvmet_sq *sq);
+ int nvmet_setup_dhgroup(struct nvmet_ctrl *ctrl, u8 dhgroup_id);
+@@ -726,8 +726,9 @@ static inline int nvmet_setup_auth(struct nvmet_ctrl *ctrl)
+ {
+ 	return 0;
+ }
+-static inline void nvmet_init_auth(struct nvmet_ctrl *ctrl,
+-				   struct nvmet_req *req) {};
++static inline void nvmet_auth_sq_init(struct nvmet_sq *sq)
++{
++}
+ static inline void nvmet_destroy_auth(struct nvmet_ctrl *ctrl) {};
+ static inline void nvmet_auth_sq_free(struct nvmet_sq *sq) {};
+ static inline bool nvmet_check_auth_status(struct nvmet_req *req)
+diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c
+index 6f39a29828b12..94d3153bae54d 100644
+--- a/drivers/nvme/target/passthru.c
++++ b/drivers/nvme/target/passthru.c
+@@ -215,9 +215,11 @@ static void nvmet_passthru_execute_cmd_work(struct work_struct *w)
+ {
+ 	struct nvmet_req *req = container_of(w, struct nvmet_req, p.work);
+ 	struct request *rq = req->p.rq;
++	struct nvme_ctrl *ctrl = nvme_req(rq)->ctrl;
++	u32 effects;
+ 	int status;
+ 
+-	status = nvme_execute_passthru_rq(rq);
++	status = nvme_execute_passthru_rq(rq, &effects);
+ 
+ 	if (status == NVME_SC_SUCCESS &&
+ 	    req->cmd->common.opcode == nvme_admin_identify) {
+@@ -238,6 +240,9 @@ static void nvmet_passthru_execute_cmd_work(struct work_struct *w)
+ 	req->cqe->result = nvme_req(rq)->result;
+ 	nvmet_req_complete(req, status);
+ 	blk_mq_free_request(rq);
++
++	if (effects)
++		nvme_passthru_end(ctrl, effects, req->cmd, status);
+ }
+ 
+ static void nvmet_passthru_req_done(struct request *rq,
+diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
+index a3694a32f6d52..7dcf88cde1893 100644
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -935,10 +935,17 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
+ 	struct nvme_tcp_data_pdu *data = &queue->pdu.data;
+ 	struct nvmet_tcp_cmd *cmd;
+ 
+-	if (likely(queue->nr_cmds))
++	if (likely(queue->nr_cmds)) {
++		if (unlikely(data->ttag >= queue->nr_cmds)) {
++			pr_err("queue %d: received out of bound ttag %u, nr_cmds %u\n",
++				queue->idx, data->ttag, queue->nr_cmds);
++			nvmet_tcp_fatal_error(queue);
++			return -EPROTO;
++		}
+ 		cmd = &queue->cmds[data->ttag];
+-	else
++	} else {
+ 		cmd = &queue->connect;
++	}
+ 
+ 	if (le32_to_cpu(data->data_offset) != cmd->rbytes_done) {
+ 		pr_err("ttag %u unexpected data offset %u (expected %u)\n",
+diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
+index 1e3c754efd0d8..2164efd12ba9b 100644
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -829,21 +829,18 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
+ 	nvmem->dev.groups = nvmem_dev_groups;
+ #endif
+ 
+-	if (nvmem->nkeepout) {
+-		rval = nvmem_validate_keepouts(nvmem);
+-		if (rval) {
+-			ida_free(&nvmem_ida, nvmem->id);
+-			kfree(nvmem);
+-			return ERR_PTR(rval);
+-		}
+-	}
+-
+ 	dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
+ 
+ 	rval = device_register(&nvmem->dev);
+ 	if (rval)
+ 		goto err_put_device;
+ 
++	if (nvmem->nkeepout) {
++		rval = nvmem_validate_keepouts(nvmem);
++		if (rval)
++			goto err_device_del;
++	}
++
+ 	if (config->compat) {
+ 		rval = nvmem_sysfs_setup_compat(nvmem, config);
+ 		if (rval)
+diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
+index 439ac5f5907a6..b492e67c3d871 100644
+--- a/drivers/pci/setup-res.c
++++ b/drivers/pci/setup-res.c
+@@ -214,6 +214,17 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
+ 
+ 	root = pci_find_parent_resource(dev, res);
+ 	if (!root) {
++		/*
++		 * If dev is behind a bridge, accesses will only reach it
++		 * if res is inside the relevant bridge window.
++		 */
++		if (pci_upstream_bridge(dev))
++			return -ENXIO;
++
++		/*
++		 * On the root bus, assume the host bridge will forward
++		 * everything.
++		 */
+ 		if (res->flags & IORESOURCE_IO)
+ 			root = &ioport_resource;
+ 		else
+diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
+index 8de4ca2fef210..8e6f217bfb635 100644
+--- a/drivers/perf/riscv_pmu_sbi.c
++++ b/drivers/perf/riscv_pmu_sbi.c
+@@ -645,8 +645,11 @@ static int pmu_sbi_starting_cpu(unsigned int cpu, struct hlist_node *node)
+ 	struct riscv_pmu *pmu = hlist_entry_safe(node, struct riscv_pmu, node);
+ 	struct cpu_hw_events *cpu_hw_evt = this_cpu_ptr(pmu->hw_events);
+ 
+-	/* Enable the access for TIME csr only from the user mode now */
+-	csr_write(CSR_SCOUNTEREN, 0x2);
++	/*
++	 * Enable the access for CYCLE, TIME, and INSTRET CSRs from userspace,
++	 * as is necessary to maintain uABI compatibility.
++	 */
++	csr_write(CSR_SCOUNTEREN, 0x7);
+ 
+ 	/* Stop all the counters so that they can be enabled from perf */
+ 	pmu_sbi_stop_all(pmu);
+diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c
+index 1027ece6ca123..a3e1108b736d6 100644
+--- a/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c
++++ b/drivers/phy/amlogic/phy-meson-axg-mipi-pcie-analog.c
+@@ -197,7 +197,7 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev)
+ 	struct phy_provider *phy;
+ 	struct device *dev = &pdev->dev;
+ 	struct phy_axg_mipi_pcie_analog_priv *priv;
+-	struct device_node *np = dev->of_node;
++	struct device_node *np = dev->of_node, *parent_np;
+ 	struct regmap *map;
+ 	int ret;
+ 
+@@ -206,7 +206,9 @@ static int phy_axg_mipi_pcie_analog_probe(struct platform_device *pdev)
+ 		return -ENOMEM;
+ 
+ 	/* Get the hhi system controller node */
+-	map = syscon_node_to_regmap(of_get_parent(dev->of_node));
++	parent_np = of_get_parent(dev->of_node);
++	map = syscon_node_to_regmap(parent_np);
++	of_node_put(parent_np);
+ 	if (IS_ERR(map)) {
+ 		dev_err(dev,
+ 			"failed to get HHI regmap\n");
+diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
+index 8ee7682b8e93e..bdffc21858f6b 100644
+--- a/drivers/phy/mediatek/phy-mtk-tphy.c
++++ b/drivers/phy/mediatek/phy-mtk-tphy.c
+@@ -906,7 +906,7 @@ static int phy_type_syscon_get(struct mtk_phy_instance *instance,
+ static int phy_type_set(struct mtk_phy_instance *instance)
+ {
+ 	int type;
+-	u32 mask;
++	u32 offset;
+ 
+ 	if (!instance->type_sw)
+ 		return 0;
+@@ -929,8 +929,9 @@ static int phy_type_set(struct mtk_phy_instance *instance)
+ 		return 0;
+ 	}
+ 
+-	mask = RG_PHY_SW_TYPE << (instance->type_sw_index * BITS_PER_BYTE);
+-	regmap_update_bits(instance->type_sw, instance->type_sw_reg, mask, type);
++	offset = instance->type_sw_index * BITS_PER_BYTE;
++	regmap_update_bits(instance->type_sw, instance->type_sw_reg,
++			   RG_PHY_SW_TYPE << offset, type << offset);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+index 1d270356a97f6..1eb4ec576361d 100644
+--- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
++++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c
+@@ -2704,7 +2704,9 @@ static int qcom_qmp_phy_usb_probe(struct platform_device *pdev)
+ 		return -ENOMEM;
+ 
+ 	pm_runtime_set_active(dev);
+-	pm_runtime_enable(dev);
++	ret = devm_pm_runtime_enable(dev);
++	if (ret)
++		return ret;
+ 	/*
+ 	 * Prevent runtime pm from being ON by default. Users can enable
+ 	 * it using power/control in sysfs.
+@@ -2738,13 +2740,10 @@ static int qcom_qmp_phy_usb_probe(struct platform_device *pdev)
+ 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ 	if (!IS_ERR(phy_provider))
+ 		dev_info(dev, "Registered Qcom-QMP phy\n");
+-	else
+-		pm_runtime_disable(dev);
+ 
+ 	return PTR_ERR_OR_ZERO(phy_provider);
+ 
+ err_node_put:
+-	pm_runtime_disable(dev);
+ 	of_node_put(child);
+ 	return ret;
+ }
+diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hsic.c b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c
+index 716a77748ed83..20f6dd37c7c10 100644
+--- a/drivers/phy/qualcomm/phy-qcom-usb-hsic.c
++++ b/drivers/phy/qualcomm/phy-qcom-usb-hsic.c
+@@ -54,8 +54,10 @@ static int qcom_usb_hsic_phy_power_on(struct phy *phy)
+ 
+ 	/* Configure pins for HSIC functionality */
+ 	pins_default = pinctrl_lookup_state(uphy->pctl, PINCTRL_STATE_DEFAULT);
+-	if (IS_ERR(pins_default))
+-		return PTR_ERR(pins_default);
++	if (IS_ERR(pins_default)) {
++		ret = PTR_ERR(pins_default);
++		goto err_ulpi;
++	}
+ 
+ 	ret = pinctrl_select_state(uphy->pctl, pins_default);
+ 	if (ret)
+diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+index 0b1e9337ee8e2..e6ededc515239 100644
+--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+@@ -1124,7 +1124,7 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
+ 					  struct rockchip_usb2phy_port *rport,
+ 					  struct device_node *child_np)
+ {
+-	int ret;
++	int ret, id;
+ 
+ 	rport->port_id = USB2PHY_PORT_OTG;
+ 	rport->port_cfg = &rphy->phy_cfg->port_cfgs[USB2PHY_PORT_OTG];
+@@ -1162,13 +1162,15 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
+ 
+ 		ret = devm_extcon_register_notifier(rphy->dev, rphy->edev,
+ 					EXTCON_USB_HOST, &rport->event_nb);
+-		if (ret)
++		if (ret) {
+ 			dev_err(rphy->dev, "register USB HOST notifier failed\n");
++			goto out;
++		}
+ 
+ 		if (!of_property_read_bool(rphy->dev->of_node, "extcon")) {
+ 			/* do initial sync of usb state */
+-			ret = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
+-			extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !ret);
++			id = property_enabled(rphy->grf, &rport->port_cfg->utmi_id);
++			extcon_set_state_sync(rphy->edev, EXTCON_USB_HOST, !id);
+ 		}
+ 	}
+ 
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
+index 32e41395fc768..c84bd0e1ce5a6 100644
+--- a/drivers/pinctrl/pinctrl-rockchip.c
++++ b/drivers/pinctrl/pinctrl-rockchip.c
+@@ -2393,11 +2393,24 @@ static int rockchip_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
+ 	return 0;
+ }
+ 
++static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
++					   struct pinctrl_gpio_range *range,
++					   unsigned offset,
++					   bool input)
++{
++	struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
++	struct rockchip_pin_bank *bank;
++
++	bank = pin_to_bank(info, offset);
++	return rockchip_set_mux(bank, offset - bank->pin_base, RK_FUNC_GPIO);
++}
++
+ static const struct pinmux_ops rockchip_pmx_ops = {
+ 	.get_functions_count	= rockchip_pmx_get_funcs_count,
+ 	.get_function_name	= rockchip_pmx_get_func_name,
+ 	.get_function_groups	= rockchip_pmx_get_groups,
+ 	.set_mux		= rockchip_pmx_set,
++	.gpio_set_direction	= rockchip_pmx_gpio_set_direction,
+ };
+ 
+ /*
+diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c
+index 4e14b4d6635d7..a2cdbfbaeae6b 100644
+--- a/drivers/platform/chrome/chromeos_laptop.c
++++ b/drivers/platform/chrome/chromeos_laptop.c
+@@ -740,6 +740,7 @@ static int __init
+ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop,
+ 					const struct chromeos_laptop *src)
+ {
++	struct i2c_peripheral *i2c_peripherals;
+ 	struct i2c_peripheral *i2c_dev;
+ 	struct i2c_board_info *info;
+ 	int i;
+@@ -748,17 +749,15 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop,
+ 	if (!src->num_i2c_peripherals)
+ 		return 0;
+ 
+-	cros_laptop->i2c_peripherals = kmemdup(src->i2c_peripherals,
+-					       src->num_i2c_peripherals *
+-						sizeof(*src->i2c_peripherals),
+-					       GFP_KERNEL);
+-	if (!cros_laptop->i2c_peripherals)
++	i2c_peripherals = kmemdup(src->i2c_peripherals,
++					      src->num_i2c_peripherals *
++					  sizeof(*src->i2c_peripherals),
++					  GFP_KERNEL);
++	if (!i2c_peripherals)
+ 		return -ENOMEM;
+ 
+-	cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals;
+-
+-	for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) {
+-		i2c_dev = &cros_laptop->i2c_peripherals[i];
++	for (i = 0; i < src->num_i2c_peripherals; i++) {
++		i2c_dev = &i2c_peripherals[i];
+ 		info = &i2c_dev->board_info;
+ 
+ 		error = chromeos_laptop_setup_irq(i2c_dev);
+@@ -775,16 +774,19 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop,
+ 		}
+ 	}
+ 
++	cros_laptop->i2c_peripherals = i2c_peripherals;
++	cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals;
++
+ 	return 0;
+ 
+ err_out:
+ 	while (--i >= 0) {
+-		i2c_dev = &cros_laptop->i2c_peripherals[i];
++		i2c_dev = &i2c_peripherals[i];
+ 		info = &i2c_dev->board_info;
+ 		if (!IS_ERR_OR_NULL(info->fwnode))
+ 			fwnode_remove_software_node(info->fwnode);
+ 	}
+-	kfree(cros_laptop->i2c_peripherals);
++	kfree(i2c_peripherals);
+ 	return error;
+ }
+ 
+diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c
+index 8aace50d446d6..110df0fd4b003 100644
+--- a/drivers/platform/chrome/cros_ec.c
++++ b/drivers/platform/chrome/cros_ec.c
+@@ -349,10 +349,16 @@ EXPORT_SYMBOL(cros_ec_suspend);
+ 
+ static void cros_ec_report_events_during_suspend(struct cros_ec_device *ec_dev)
+ {
++	bool wake_event;
++
+ 	while (ec_dev->mkbp_event_supported &&
+-	       cros_ec_get_next_event(ec_dev, NULL, NULL) > 0)
++	       cros_ec_get_next_event(ec_dev, &wake_event, NULL) > 0) {
+ 		blocking_notifier_call_chain(&ec_dev->event_notifier,
+ 					     1, ec_dev);
++
++		if (wake_event && device_may_wakeup(ec_dev->dev))
++			pm_wakeup_event(ec_dev->dev, 0);
++	}
+ }
+ 
+ /**
+diff --git a/drivers/platform/chrome/cros_ec_chardev.c b/drivers/platform/chrome/cros_ec_chardev.c
+index fd33de546aee0..0de7c255254e0 100644
+--- a/drivers/platform/chrome/cros_ec_chardev.c
++++ b/drivers/platform/chrome/cros_ec_chardev.c
+@@ -327,6 +327,9 @@ static long cros_ec_chardev_ioctl_readmem(struct cros_ec_dev *ec,
+ 	if (copy_from_user(&s_mem, arg, sizeof(s_mem)))
+ 		return -EFAULT;
+ 
++	if (s_mem.bytes > sizeof(s_mem.buffer))
++		return -EINVAL;
++
+ 	num = ec_dev->cmd_readmem(ec_dev, s_mem.offset, s_mem.bytes,
+ 				  s_mem.buffer);
+ 	if (num <= 0)
+diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c
+index 05d2e8765a66b..475a6dd72db6b 100644
+--- a/drivers/platform/chrome/cros_ec_proto.c
++++ b/drivers/platform/chrome/cros_ec_proto.c
+@@ -773,6 +773,7 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev,
+ 	u8 event_type;
+ 	u32 host_event;
+ 	int ret;
++	u32 ver_mask;
+ 
+ 	/*
+ 	 * Default value for wake_event.
+@@ -794,6 +795,37 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev,
+ 		return get_keyboard_state_event(ec_dev);
+ 
+ 	ret = get_next_event(ec_dev);
++	/*
++	 * -ENOPROTOOPT is returned when EC returns EC_RES_INVALID_VERSION.
++	 * This can occur when EC based device (e.g. Fingerprint MCU) jumps to
++	 * the RO image which doesn't support newer version of the command. In
++	 * this case we will attempt to update maximum supported version of the
++	 * EC_CMD_GET_NEXT_EVENT.
++	 */
++	if (ret == -ENOPROTOOPT) {
++		dev_dbg(ec_dev->dev,
++			"GET_NEXT_EVENT returned invalid version error.\n");
++		ret = cros_ec_get_host_command_version_mask(ec_dev,
++							EC_CMD_GET_NEXT_EVENT,
++							&ver_mask);
++		if (ret < 0 || ver_mask == 0)
++			/*
++			 * Do not change the MKBP supported version if we can't
++			 * obtain supported version correctly. Please note that
++			 * calling EC_CMD_GET_NEXT_EVENT returned
++			 * EC_RES_INVALID_VERSION which means that the command
++			 * is present.
++			 */
++			return -ENOPROTOOPT;
++
++		ec_dev->mkbp_event_supported = fls(ver_mask);
++		dev_dbg(ec_dev->dev, "MKBP support version changed to %u\n",
++			ec_dev->mkbp_event_supported - 1);
++
++		/* Try to get next event with new MKBP support version set. */
++		ret = get_next_event(ec_dev);
++	}
++
+ 	if (ret <= 0)
+ 		return ret;
+ 
+diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
+index de6ee0f926a66..dc5722db20661 100644
+--- a/drivers/platform/chrome/cros_ec_typec.c
++++ b/drivers/platform/chrome/cros_ec_typec.c
+@@ -25,7 +25,8 @@
+ 
+ #define DRV_NAME "cros-ec-typec"
+ 
+-#define DP_PORT_VDO	(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D) | DP_CAP_DFP_D)
++#define DP_PORT_VDO	(DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D)) | \
++				DP_CAP_DFP_D)
+ 
+ /* Supported alt modes. */
+ enum {
+@@ -697,7 +698,7 @@ static int cros_typec_register_altmodes(struct cros_typec_data *typec, int port_
+ 		for (j = 0; j < sop_disc->svids[i].mode_count; j++) {
+ 			memset(&desc, 0, sizeof(desc));
+ 			desc.svid = sop_disc->svids[i].svid;
+-			desc.mode = j;
++			desc.mode = j + 1;
+ 			desc.vdo = sop_disc->svids[i].mode_vdo[j];
+ 
+ 			if (is_partner)
+diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
+index bc7020e9df9e8..fc8dbbd6fc7c2 100644
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -177,7 +177,8 @@ enum hp_thermal_profile_omen_v1 {
+ enum hp_thermal_profile {
+ 	HP_THERMAL_PROFILE_PERFORMANCE	= 0x00,
+ 	HP_THERMAL_PROFILE_DEFAULT		= 0x01,
+-	HP_THERMAL_PROFILE_COOL			= 0x02
++	HP_THERMAL_PROFILE_COOL			= 0x02,
++	HP_THERMAL_PROFILE_QUIET		= 0x03,
+ };
+ 
+ #define IS_HWBLOCKED(x) ((x & HPWMI_POWER_FW_OR_HW) != HPWMI_POWER_FW_OR_HW)
+@@ -1194,6 +1195,9 @@ static int hp_wmi_platform_profile_get(struct platform_profile_handler *pprof,
+ 	case HP_THERMAL_PROFILE_COOL:
+ 		*profile =  PLATFORM_PROFILE_COOL;
+ 		break;
++	case HP_THERMAL_PROFILE_QUIET:
++		*profile = PLATFORM_PROFILE_QUIET;
++		break;
+ 	default:
+ 		return -EINVAL;
+ 	}
+@@ -1216,6 +1220,9 @@ static int hp_wmi_platform_profile_set(struct platform_profile_handler *pprof,
+ 	case PLATFORM_PROFILE_COOL:
+ 		tp =  HP_THERMAL_PROFILE_COOL;
+ 		break;
++	case PLATFORM_PROFILE_QUIET:
++		tp = HP_THERMAL_PROFILE_QUIET;
++		break;
+ 	default:
+ 		return -EOPNOTSUPP;
+ 	}
+@@ -1263,6 +1270,8 @@ static int thermal_profile_setup(void)
+ 
+ 		platform_profile_handler.profile_get = hp_wmi_platform_profile_get;
+ 		platform_profile_handler.profile_set = hp_wmi_platform_profile_set;
++
++		set_bit(PLATFORM_PROFILE_QUIET, platform_profile_handler.choices);
+ 	}
+ 
+ 	set_bit(PLATFORM_PROFILE_COOL, platform_profile_handler.choices);
+diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c
+index 24ffc8e2d2d1e..0e804b6c2d242 100644
+--- a/drivers/platform/x86/msi-laptop.c
++++ b/drivers/platform/x86/msi-laptop.c
+@@ -596,11 +596,10 @@ static const struct dmi_system_id msi_dmi_table[] __initconst = {
+ 	{
+ 		.ident = "MSI S270",
+ 		.matches = {
+-			DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"),
++			DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT"),
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"),
+ 			DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
+-			DMI_MATCH(DMI_CHASSIS_VENDOR,
+-				  "MICRO-STAR INT'L CO.,LTD")
++			DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT")
+ 		},
+ 		.driver_data = &quirk_old_ec_model,
+ 		.callback = dmi_check_cb
+@@ -633,8 +632,7 @@ static const struct dmi_system_id msi_dmi_table[] __initconst = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"),
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"),
+ 			DMI_MATCH(DMI_PRODUCT_VERSION, "0131"),
+-			DMI_MATCH(DMI_CHASSIS_VENDOR,
+-				  "MICRO-STAR INT'L CO.,LTD")
++			DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT")
+ 		},
+ 		.driver_data = &quirk_old_ec_model,
+ 		.callback = dmi_check_cb
+@@ -1048,8 +1046,7 @@ static int __init msi_init(void)
+ 		return -EINVAL;
+ 
+ 	/* Register backlight stuff */
+-
+-	if (quirks->old_ec_model ||
++	if (quirks->old_ec_model &&
+ 	    acpi_video_get_backlight_type() == acpi_backlight_vendor) {
+ 		struct backlight_properties props;
+ 		memset(&props, 0, sizeof(struct backlight_properties));
+@@ -1117,6 +1114,8 @@ fail_create_attr:
+ fail_create_group:
+ 	if (quirks->load_scm_model) {
+ 		i8042_remove_filter(msi_laptop_i8042_filter);
++		cancel_delayed_work_sync(&msi_touchpad_dwork);
++		input_unregister_device(msi_laptop_input_dev);
+ 		cancel_delayed_work_sync(&msi_rfkill_dwork);
+ 		cancel_work_sync(&msi_rfkill_work);
+ 		rfkill_cleanup();
+@@ -1137,6 +1136,7 @@ static void __exit msi_cleanup(void)
+ {
+ 	if (quirks->load_scm_model) {
+ 		i8042_remove_filter(msi_laptop_i8042_filter);
++		cancel_delayed_work_sync(&msi_touchpad_dwork);
+ 		input_unregister_device(msi_laptop_input_dev);
+ 		cancel_delayed_work_sync(&msi_rfkill_dwork);
+ 		cancel_work_sync(&msi_rfkill_work);
+diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
+index 5c757c7f64dee..f4046572a9fe5 100644
+--- a/drivers/platform/x86/pmc_atom.c
++++ b/drivers/platform/x86/pmc_atom.c
+@@ -354,7 +354,7 @@ static bool pmc_clk_is_critical = true;
+ 
+ static int dmi_callback(const struct dmi_system_id *d)
+ {
+-	pr_info("%s critclks quirk enabled\n", d->ident);
++	pr_info("%s: PMC critical clocks quirk enabled\n", d->ident);
+ 
+ 	return 1;
+ }
+diff --git a/drivers/power/supply/adp5061.c b/drivers/power/supply/adp5061.c
+index 003557043ab3a..daee1161c3059 100644
+--- a/drivers/power/supply/adp5061.c
++++ b/drivers/power/supply/adp5061.c
+@@ -427,11 +427,11 @@ static int adp5061_get_chg_type(struct adp5061_state *st,
+ 	if (ret < 0)
+ 		return ret;
+ 
+-	chg_type = adp5061_chg_type[ADP5061_CHG_STATUS_1_CHG_STATUS(status1)];
+-	if (chg_type > ADP5061_CHG_FAST_CV)
++	chg_type = ADP5061_CHG_STATUS_1_CHG_STATUS(status1);
++	if (chg_type >= ARRAY_SIZE(adp5061_chg_type))
+ 		val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+ 	else
+-		val->intval = chg_type;
++		val->intval = adp5061_chg_type[chg_type];
+ 
+ 	return ret;
+ }
+diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c
+index 21d624f9f5fb2..33a3ca35cda07 100644
+--- a/drivers/powercap/intel_rapl_common.c
++++ b/drivers/powercap/intel_rapl_common.c
+@@ -994,6 +994,9 @@ static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value,
+ 		y = value & 0x1f;
+ 		value = (1 << y) * (4 + f) * rp->time_unit / 4;
+ 	} else {
++		if (value < rp->time_unit)
++			return 0;
++
+ 		do_div(value, rp->time_unit);
+ 		y = ilog2(value);
+ 		f = div64_u64(4 * (value - (1 << y)), 1 << y);
+@@ -1035,7 +1038,6 @@ static const struct rapl_defaults rapl_defaults_spr_server = {
+ 	.check_unit = rapl_check_unit_core,
+ 	.set_floor_freq = set_floor_freq_default,
+ 	.compute_time_window = rapl_compute_time_window_core,
+-	.dram_domain_energy_unit = 15300,
+ 	.psys_domain_energy_unit = 1000000000,
+ 	.spr_psys_bits = true,
+ };
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index d3e8dc32832dd..c3871565fd7d2 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -2681,7 +2681,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
+ 	 * return -ETIMEDOUT.
+ 	 */
+ 	if (rdev->desc->poll_enabled_time) {
+-		unsigned int time_remaining = delay;
++		int time_remaining = delay;
+ 
+ 		while (time_remaining > 0) {
+ 			_regulator_delay_helper(rdev->desc->poll_enabled_time);
+diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c
+index 7f9d66ac37ff8..3c41b71a1f529 100644
+--- a/drivers/regulator/qcom_rpm-regulator.c
++++ b/drivers/regulator/qcom_rpm-regulator.c
+@@ -802,6 +802,12 @@ static const struct rpm_regulator_data rpm_pm8018_regulators[] = {
+ };
+ 
+ static const struct rpm_regulator_data rpm_pm8058_regulators[] = {
++	{ "s0",   QCOM_RPM_PM8058_SMPS0,  &pm8058_smps, "vdd_s0" },
++	{ "s1",   QCOM_RPM_PM8058_SMPS1,  &pm8058_smps, "vdd_s1" },
++	{ "s2",   QCOM_RPM_PM8058_SMPS2,  &pm8058_smps, "vdd_s2" },
++	{ "s3",   QCOM_RPM_PM8058_SMPS3,  &pm8058_smps, "vdd_s3" },
++	{ "s4",   QCOM_RPM_PM8058_SMPS4,  &pm8058_smps, "vdd_s4" },
++
+ 	{ "l0",   QCOM_RPM_PM8058_LDO0,   &pm8058_nldo, "vdd_l0_l1_lvs"	},
+ 	{ "l1",   QCOM_RPM_PM8058_LDO1,   &pm8058_nldo, "vdd_l0_l1_lvs" },
+ 	{ "l2",   QCOM_RPM_PM8058_LDO2,   &pm8058_pldo, "vdd_l2_l11_l12" },
+@@ -829,12 +835,6 @@ static const struct rpm_regulator_data rpm_pm8058_regulators[] = {
+ 	{ "l24",  QCOM_RPM_PM8058_LDO24,  &pm8058_nldo, "vdd_l23_l24_l25" },
+ 	{ "l25",  QCOM_RPM_PM8058_LDO25,  &pm8058_nldo, "vdd_l23_l24_l25" },
+ 
+-	{ "s0",   QCOM_RPM_PM8058_SMPS0,  &pm8058_smps, "vdd_s0" },
+-	{ "s1",   QCOM_RPM_PM8058_SMPS1,  &pm8058_smps, "vdd_s1" },
+-	{ "s2",   QCOM_RPM_PM8058_SMPS2,  &pm8058_smps, "vdd_s2" },
+-	{ "s3",   QCOM_RPM_PM8058_SMPS3,  &pm8058_smps, "vdd_s3" },
+-	{ "s4",   QCOM_RPM_PM8058_SMPS4,  &pm8058_smps, "vdd_s4" },
+-
+ 	{ "lvs0", QCOM_RPM_PM8058_LVS0, &pm8058_switch, "vdd_l0_l1_lvs" },
+ 	{ "lvs1", QCOM_RPM_PM8058_LVS1, &pm8058_switch, "vdd_l0_l1_lvs" },
+ 
+@@ -843,6 +843,12 @@ static const struct rpm_regulator_data rpm_pm8058_regulators[] = {
+ };
+ 
+ static const struct rpm_regulator_data rpm_pm8901_regulators[] = {
++	{ "s0",   QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" },
++	{ "s1",   QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" },
++	{ "s2",   QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" },
++	{ "s3",   QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" },
++	{ "s4",   QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" },
++
+ 	{ "l0",   QCOM_RPM_PM8901_LDO0, &pm8901_nldo, "vdd_l0" },
+ 	{ "l1",   QCOM_RPM_PM8901_LDO1, &pm8901_pldo, "vdd_l1" },
+ 	{ "l2",   QCOM_RPM_PM8901_LDO2, &pm8901_pldo, "vdd_l2" },
+@@ -851,12 +857,6 @@ static const struct rpm_regulator_data rpm_pm8901_regulators[] = {
+ 	{ "l5",   QCOM_RPM_PM8901_LDO5, &pm8901_pldo, "vdd_l5" },
+ 	{ "l6",   QCOM_RPM_PM8901_LDO6, &pm8901_pldo, "vdd_l6" },
+ 
+-	{ "s0",   QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" },
+-	{ "s1",   QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" },
+-	{ "s2",   QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" },
+-	{ "s3",   QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" },
+-	{ "s4",   QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" },
+-
+ 	{ "lvs0", QCOM_RPM_PM8901_LVS0, &pm8901_switch, "lvs0_in" },
+ 	{ "lvs1", QCOM_RPM_PM8901_LVS1, &pm8901_switch, "lvs1_in" },
+ 	{ "lvs2", QCOM_RPM_PM8901_LVS2, &pm8901_switch, "lvs2_in" },
+diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
+index e5279ed9a8d7c..4fc5ce2187ac8 100644
+--- a/drivers/remoteproc/remoteproc_core.c
++++ b/drivers/remoteproc/remoteproc_core.c
+@@ -520,12 +520,13 @@ static int rproc_handle_vdev(struct rproc *rproc, void *ptr,
+ 	struct fw_rsc_vdev *rsc = ptr;
+ 	struct device *dev = &rproc->dev;
+ 	struct rproc_vdev *rvdev;
++	size_t rsc_size;
+ 	int i, ret;
+ 	char name[16];
+ 
+ 	/* make sure resource isn't truncated */
+-	if (struct_size(rsc, vring, rsc->num_of_vrings) + rsc->config_len >
+-			avail) {
++	rsc_size = struct_size(rsc, vring, rsc->num_of_vrings);
++	if (size_add(rsc_size, rsc->config_len) > avail) {
+ 		dev_err(dev, "vdev rsc is truncated\n");
+ 		return -EINVAL;
+ 	}
+diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
+index 4f2189111494a..0408ce58183c1 100644
+--- a/drivers/rpmsg/rpmsg_char.c
++++ b/drivers/rpmsg/rpmsg_char.c
+@@ -76,7 +76,9 @@ int rpmsg_chrdev_eptdev_destroy(struct device *dev, void *data)
+ 
+ 	mutex_lock(&eptdev->ept_lock);
+ 	if (eptdev->ept) {
+-		rpmsg_destroy_ept(eptdev->ept);
++		/* The default endpoint is released by the rpmsg core */
++		if (!eptdev->default_ept)
++			rpmsg_destroy_ept(eptdev->ept);
+ 		eptdev->ept = NULL;
+ 	}
+ 	mutex_unlock(&eptdev->ept_lock);
+diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
+index cd823ff5deab2..6cb9cca9565b9 100644
+--- a/drivers/scsi/3w-9xxx.c
++++ b/drivers/scsi/3w-9xxx.c
+@@ -2006,7 +2006,7 @@ static int twa_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
+ 	retval = pci_enable_device(pdev);
+ 	if (retval) {
+ 		TW_PRINTK(host, TW_DRIVER, 0x34, "Failed to enable pci device");
+-		goto out_disable_device;
++		return -ENODEV;
+ 	}
+ 
+ 	pci_set_master(pdev);
+diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
+index 29b1bd755afec..5fb1f364e8155 100644
+--- a/drivers/scsi/iscsi_tcp.c
++++ b/drivers/scsi/iscsi_tcp.c
+@@ -595,6 +595,8 @@ iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session,
+ 	INIT_WORK(&conn->recvwork, iscsi_sw_tcp_recv_data_work);
+ 	tcp_sw_conn->queue_recv = iscsi_recv_from_iscsi_q;
+ 
++	mutex_init(&tcp_sw_conn->sock_lock);
++
+ 	tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC);
+ 	if (IS_ERR(tfm))
+ 		goto free_conn;
+@@ -629,11 +631,15 @@ free_conn:
+ 
+ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)
+ {
+-	struct iscsi_session *session = conn->session;
+ 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ 	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
+ 	struct socket *sock = tcp_sw_conn->sock;
+ 
++	/*
++	 * The iscsi transport class will make sure we are not called in
++	 * parallel with start, stop, bind and destroys. However, this can be
++	 * called twice if userspace does a stop then a destroy.
++	 */
+ 	if (!sock)
+ 		return;
+ 
+@@ -649,9 +655,9 @@ static void iscsi_sw_tcp_release_conn(struct iscsi_conn *conn)
+ 
+ 	iscsi_suspend_rx(conn);
+ 
+-	spin_lock_bh(&session->frwd_lock);
++	mutex_lock(&tcp_sw_conn->sock_lock);
+ 	tcp_sw_conn->sock = NULL;
+-	spin_unlock_bh(&session->frwd_lock);
++	mutex_unlock(&tcp_sw_conn->sock_lock);
+ 	sockfd_put(sock);
+ }
+ 
+@@ -703,7 +709,6 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session,
+ 		       struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
+ 		       int is_leading)
+ {
+-	struct iscsi_session *session = cls_session->dd_data;
+ 	struct iscsi_conn *conn = cls_conn->dd_data;
+ 	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+ 	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
+@@ -723,10 +728,10 @@ iscsi_sw_tcp_conn_bind(struct iscsi_cls_session *cls_session,
+ 	if (err)
+ 		goto free_socket;
+ 
+-	spin_lock_bh(&session->frwd_lock);
++	mutex_lock(&tcp_sw_conn->sock_lock);
+ 	/* bind iSCSI connection and socket */
+ 	tcp_sw_conn->sock = sock;
+-	spin_unlock_bh(&session->frwd_lock);
++	mutex_unlock(&tcp_sw_conn->sock_lock);
+ 
+ 	/* setup Socket parameters */
+ 	sk = sock->sk;
+@@ -763,8 +768,15 @@ static int iscsi_sw_tcp_conn_set_param(struct iscsi_cls_conn *cls_conn,
+ 		break;
+ 	case ISCSI_PARAM_DATADGST_EN:
+ 		iscsi_set_param(cls_conn, param, buf, buflen);
++
++		mutex_lock(&tcp_sw_conn->sock_lock);
++		if (!tcp_sw_conn->sock) {
++			mutex_unlock(&tcp_sw_conn->sock_lock);
++			return -ENOTCONN;
++		}
+ 		tcp_sw_conn->sendpage = conn->datadgst_en ?
+ 			sock_no_sendpage : tcp_sw_conn->sock->ops->sendpage;
++		mutex_unlock(&tcp_sw_conn->sock_lock);
+ 		break;
+ 	case ISCSI_PARAM_MAX_R2T:
+ 		return iscsi_tcp_set_max_r2t(conn, buf);
+@@ -779,8 +791,8 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
+ 				       enum iscsi_param param, char *buf)
+ {
+ 	struct iscsi_conn *conn = cls_conn->dd_data;
+-	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
+-	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
++	struct iscsi_sw_tcp_conn *tcp_sw_conn;
++	struct iscsi_tcp_conn *tcp_conn;
+ 	struct sockaddr_in6 addr;
+ 	struct socket *sock;
+ 	int rc;
+@@ -790,21 +802,36 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
+ 	case ISCSI_PARAM_CONN_ADDRESS:
+ 	case ISCSI_PARAM_LOCAL_PORT:
+ 		spin_lock_bh(&conn->session->frwd_lock);
+-		if (!tcp_sw_conn || !tcp_sw_conn->sock) {
++		if (!conn->session->leadconn) {
+ 			spin_unlock_bh(&conn->session->frwd_lock);
+ 			return -ENOTCONN;
+ 		}
+-		sock = tcp_sw_conn->sock;
+-		sock_hold(sock->sk);
++		/*
++		 * The conn has been setup and bound, so just grab a ref
++		 * incase a destroy runs while we are in the net layer.
++		 */
++		iscsi_get_conn(conn->cls_conn);
+ 		spin_unlock_bh(&conn->session->frwd_lock);
+ 
++		tcp_conn = conn->dd_data;
++		tcp_sw_conn = tcp_conn->dd_data;
++
++		mutex_lock(&tcp_sw_conn->sock_lock);
++		sock = tcp_sw_conn->sock;
++		if (!sock) {
++			rc = -ENOTCONN;
++			goto sock_unlock;
++		}
++
+ 		if (param == ISCSI_PARAM_LOCAL_PORT)
+ 			rc = kernel_getsockname(sock,
+ 						(struct sockaddr *)&addr);
+ 		else
+ 			rc = kernel_getpeername(sock,
+ 						(struct sockaddr *)&addr);
+-		sock_put(sock->sk);
++sock_unlock:
++		mutex_unlock(&tcp_sw_conn->sock_lock);
++		iscsi_put_conn(conn->cls_conn);
+ 		if (rc < 0)
+ 			return rc;
+ 
+@@ -842,17 +869,21 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost,
+ 		}
+ 		tcp_conn = conn->dd_data;
+ 		tcp_sw_conn = tcp_conn->dd_data;
+-		sock = tcp_sw_conn->sock;
+-		if (!sock) {
+-			spin_unlock_bh(&session->frwd_lock);
+-			return -ENOTCONN;
+-		}
+-		sock_hold(sock->sk);
++		/*
++		 * The conn has been setup and bound, so just grab a ref
++		 * incase a destroy runs while we are in the net layer.
++		 */
++		iscsi_get_conn(conn->cls_conn);
+ 		spin_unlock_bh(&session->frwd_lock);
+ 
+-		rc = kernel_getsockname(sock,
+-					(struct sockaddr *)&addr);
+-		sock_put(sock->sk);
++		mutex_lock(&tcp_sw_conn->sock_lock);
++		sock = tcp_sw_conn->sock;
++		if (!sock)
++			rc = -ENOTCONN;
++		else
++			rc = kernel_getsockname(sock, (struct sockaddr *)&addr);
++		mutex_unlock(&tcp_sw_conn->sock_lock);
++		iscsi_put_conn(conn->cls_conn);
+ 		if (rc < 0)
+ 			return rc;
+ 
+diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
+index 850a018aefb9b..68e14a344904f 100644
+--- a/drivers/scsi/iscsi_tcp.h
++++ b/drivers/scsi/iscsi_tcp.h
+@@ -28,6 +28,9 @@ struct iscsi_sw_tcp_send {
+ 
+ struct iscsi_sw_tcp_conn {
+ 	struct socket		*sock;
++	/* Taken when accessing the sock from the netlink/sysfs interface */
++	struct mutex		sock_lock;
++
+ 	struct work_struct	recvwork;
+ 	bool			queue_recv;
+ 
+diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
+index fa2209080cc26..5ce2518301040 100644
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -67,7 +67,7 @@ static int smp_execute_task_sg(struct domain_device *dev,
+ 		res = i->dft->lldd_execute_task(task, GFP_KERNEL);
+ 
+ 		if (res) {
+-			del_timer(&task->slow_task->timer);
++			del_timer_sync(&task->slow_task->timer);
+ 			pr_notice("executing SMP task failed:%d\n", res);
+ 			break;
+ 		}
+diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
+index e6a083d098a1a..11a05f2c88c44 100644
+--- a/drivers/scsi/lpfc/lpfc.h
++++ b/drivers/scsi/lpfc/lpfc.h
+@@ -1570,10 +1570,7 @@ struct lpfc_hba {
+ 	u32 cgn_acqe_cnt;
+ 
+ 	/* RX monitor handling for CMF */
+-	struct rxtable_entry *rxtable;  /* RX_monitor information */
+-	atomic_t rxtable_idx_head;
+-#define LPFC_RXMONITOR_TABLE_IN_USE     (LPFC_MAX_RXMONITOR_ENTRY + 73)
+-	atomic_t rxtable_idx_tail;
++	struct lpfc_rx_info_monitor *rx_monitor;
+ 	atomic_t rx_max_read_cnt;       /* Maximum read bytes */
+ 	uint64_t rx_block_cnt;
+ 
+@@ -1622,7 +1619,7 @@ struct lpfc_hba {
+ 
+ #define LPFC_MAX_RXMONITOR_ENTRY	800
+ #define LPFC_MAX_RXMONITOR_DUMP		32
+-struct rxtable_entry {
++struct rx_info_entry {
+ 	uint64_t cmf_bytes;	/* Total no of read bytes for CMF_SYNC_WQE */
+ 	uint64_t total_bytes;   /* Total no of read bytes requested */
+ 	uint64_t rcv_bytes;     /* Total no of read bytes completed */
+@@ -1637,6 +1634,13 @@ struct rxtable_entry {
+ 	uint32_t timer_interval;
+ };
+ 
++struct lpfc_rx_info_monitor {
++	struct rx_info_entry *ring; /* info organized in a circular buffer */
++	u32 head_idx, tail_idx; /* index to head/tail of ring */
++	spinlock_t lock; /* spinlock for ring */
++	u32 entries; /* storing number entries/size of ring */
++};
++
+ static inline struct Scsi_Host *
+ lpfc_shost_from_vport(struct lpfc_vport *vport)
+ {
+diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
+index bcad912043282..c8cac90240b9b 100644
+--- a/drivers/scsi/lpfc/lpfc_crtn.h
++++ b/drivers/scsi/lpfc/lpfc_crtn.h
+@@ -92,6 +92,14 @@ void lpfc_cgn_dump_rxmonitor(struct lpfc_hba *phba);
+ void lpfc_cgn_update_stat(struct lpfc_hba *phba, uint32_t dtag);
+ void lpfc_unblock_requests(struct lpfc_hba *phba);
+ void lpfc_block_requests(struct lpfc_hba *phba);
++int lpfc_rx_monitor_create_ring(struct lpfc_rx_info_monitor *rx_monitor,
++				u32 entries);
++void lpfc_rx_monitor_destroy_ring(struct lpfc_rx_info_monitor *rx_monitor);
++void lpfc_rx_monitor_record(struct lpfc_rx_info_monitor *rx_monitor,
++			    struct rx_info_entry *entry);
++u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
++			   struct lpfc_rx_info_monitor *rx_monitor, char *buf,
++			   u32 buf_len, u32 max_read_entries);
+ 
+ void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
+ void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
+diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
+index 13dfe285493d1..b555ccb5ae345 100644
+--- a/drivers/scsi/lpfc/lpfc_ct.c
++++ b/drivers/scsi/lpfc/lpfc_ct.c
+@@ -1509,7 +1509,7 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ 	struct lpfc_sli_ct_request *CTrsp;
+ 	int did;
+ 	struct lpfc_nodelist *ndlp = NULL;
+-	struct lpfc_nodelist *ns_ndlp = NULL;
++	struct lpfc_nodelist *ns_ndlp = cmdiocb->ndlp;
+ 	uint32_t fc4_data_0, fc4_data_1;
+ 	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);
+ 	u32 ulp_word4 = get_job_word4(phba, rspiocb);
+@@ -1522,15 +1522,12 @@ lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ 			      ulp_status, ulp_word4, did);
+ 
+ 	/* Ignore response if link flipped after this request was made */
+-	if ((uint32_t) cmdiocb->event_tag != phba->fc_eventTag) {
++	if ((uint32_t)cmdiocb->event_tag != phba->fc_eventTag) {
+ 		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ 				 "9046 Event tag mismatch. Ignoring NS rsp\n");
+ 		goto out;
+ 	}
+ 
+-	/* Preserve the nameserver node to release the reference. */
+-	ns_ndlp = cmdiocb->ndlp;
+-
+ 	if (ulp_status == IOSTAT_SUCCESS) {
+ 		/* Good status, continue checking */
+ 		CTrsp = (struct lpfc_sli_ct_request *)outp->virt;
+diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
+index 5037ea09a8104..f5252e45a48a2 100644
+--- a/drivers/scsi/lpfc/lpfc_debugfs.c
++++ b/drivers/scsi/lpfc/lpfc_debugfs.c
+@@ -5156,7 +5156,7 @@ error_out:
+ static int
+ lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len)
+ {
+-	uint16_t ext_cnt, ext_size;
++	uint16_t ext_cnt = 0, ext_size = 0;
+ 
+ 	len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
+ 			"\nAvailable Extents Information:\n");
+@@ -5531,7 +5531,7 @@ lpfc_rx_monitor_open(struct inode *inode, struct file *file)
+ 	if (!debug)
+ 		goto out;
+ 
+-	debug->buffer = vmalloc(MAX_DEBUGFS_RX_TABLE_SIZE);
++	debug->buffer = vmalloc(MAX_DEBUGFS_RX_INFO_SIZE);
+ 	if (!debug->buffer) {
+ 		kfree(debug);
+ 		goto out;
+@@ -5552,57 +5552,18 @@ lpfc_rx_monitor_read(struct file *file, char __user *buf, size_t nbytes,
+ 	struct lpfc_rx_monitor_debug *debug = file->private_data;
+ 	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
+ 	char *buffer = debug->buffer;
+-	struct rxtable_entry *entry;
+-	int i, len = 0, head, tail, last, start;
+-
+-	head = atomic_read(&phba->rxtable_idx_head);
+-	while (head == LPFC_RXMONITOR_TABLE_IN_USE) {
+-		/* Table is getting updated */
+-		msleep(20);
+-		head = atomic_read(&phba->rxtable_idx_head);
+-	}
+ 
+-	tail = atomic_xchg(&phba->rxtable_idx_tail, head);
+-	if (!phba->rxtable || head == tail) {
+-		len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
+-				"Rxtable is empty\n");
+-		goto out;
+-	}
+-	last = (head > tail) ?  head : LPFC_MAX_RXMONITOR_ENTRY;
+-	start = tail;
+-
+-	len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
+-			"        MaxBPI    Tot_Data_CMF Tot_Data_Cmd "
+-			"Tot_Data_Cmpl  Lat(us)  Avg_IO  Max_IO "
+-			"Bsy IO_cnt Info BWutil(ms)\n");
+-get_table:
+-	for (i = start; i < last; i++) {
+-		entry = &phba->rxtable[i];
+-		len += scnprintf(buffer + len, MAX_DEBUGFS_RX_TABLE_SIZE - len,
+-				"%3d:%12lld %12lld %12lld %12lld "
+-				"%7lldus %8lld %7lld "
+-				"%2d   %4d   %2d   %2d(%2d)\n",
+-				i, entry->max_bytes_per_interval,
+-				entry->cmf_bytes,
+-				entry->total_bytes,
+-				entry->rcv_bytes,
+-				entry->avg_io_latency,
+-				entry->avg_io_size,
+-				entry->max_read_cnt,
+-				entry->cmf_busy,
+-				entry->io_cnt,
+-				entry->cmf_info,
+-				entry->timer_utilization,
+-				entry->timer_interval);
++	if (!phba->rx_monitor) {
++		scnprintf(buffer, MAX_DEBUGFS_RX_INFO_SIZE,
++			  "Rx Monitor Info is empty.\n");
++	} else {
++		lpfc_rx_monitor_report(phba, phba->rx_monitor, buffer,
++				       MAX_DEBUGFS_RX_INFO_SIZE,
++				       LPFC_MAX_RXMONITOR_ENTRY);
+ 	}
+ 
+-	if (head != last) {
+-		start = 0;
+-		last = head;
+-		goto get_table;
+-	}
+-out:
+-	return simple_read_from_buffer(buf, nbytes, ppos, buffer, len);
++	return simple_read_from_buffer(buf, nbytes, ppos, buffer,
++				       strlen(buffer));
+ }
+ 
+ static int
+diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
+index 6dd361c1fd318..f71e5b6311ac0 100644
+--- a/drivers/scsi/lpfc/lpfc_debugfs.h
++++ b/drivers/scsi/lpfc/lpfc_debugfs.h
+@@ -282,7 +282,7 @@ struct lpfc_idiag {
+ 	void *ptr_private;
+ };
+ 
+-#define MAX_DEBUGFS_RX_TABLE_SIZE	(128 * LPFC_MAX_RXMONITOR_ENTRY)
++#define MAX_DEBUGFS_RX_INFO_SIZE	(128 * LPFC_MAX_RXMONITOR_ENTRY)
+ struct lpfc_rx_monitor_debug {
+ 	char *i_private;
+ 	char *buffer;
+diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
+index 2645def612e6d..a488d00894aee 100644
+--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
+@@ -2964,7 +2964,7 @@ lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+ 	uint32_t boot_flag, addr_mode;
+ 	uint16_t next_fcf_index, fcf_index;
+ 	uint16_t current_fcf_index;
+-	uint16_t vlan_id;
++	uint16_t vlan_id = LPFC_FCOE_NULL_VID;
+ 	int rc;
+ 
+ 	/* If link state is not up, stop the roundrobin failover process */
+@@ -3069,7 +3069,7 @@ lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+ 	struct fcf_record *new_fcf_record;
+ 	uint32_t boot_flag, addr_mode;
+ 	uint16_t fcf_index, next_fcf_index;
+-	uint16_t vlan_id;
++	uint16_t vlan_id =  LPFC_FCOE_NULL_VID;
+ 	int rc;
+ 
+ 	/* If link state is not up, no need to proceed */
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
+index 55a1ad6eed034..1a02134438fcc 100644
+--- a/drivers/scsi/lpfc/lpfc_init.c
++++ b/drivers/scsi/lpfc/lpfc_init.c
+@@ -325,8 +325,7 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
+ 	prog_id_word = pmboxq->u.mb.un.varWords[7];
+ 
+ 	/* Decode the Option rom version word to a readable string */
+-	if (prg->dist < 4)
+-		dist = dist_char[prg->dist];
++	dist = dist_char[prg->dist];
+ 
+ 	if ((prg->dist == 3) && (prg->num == 0))
+ 		snprintf(phba->OptionROMVersion, 32, "%d.%d%d",
+@@ -2258,6 +2257,101 @@ lpfc_handle_latt_err_exit:
+ 	return;
+ }
+ 
++static void
++lpfc_fill_vpd(struct lpfc_hba *phba, uint8_t *vpd, int length, int *pindex)
++{
++	int i, j;
++
++	while (length > 0) {
++		/* Look for Serial Number */
++		if ((vpd[*pindex] == 'S') && (vpd[*pindex + 1] == 'N')) {
++			*pindex += 2;
++			i = vpd[*pindex];
++			*pindex += 1;
++			j = 0;
++			length -= (3+i);
++			while (i--) {
++				phba->SerialNumber[j++] = vpd[(*pindex)++];
++				if (j == 31)
++					break;
++			}
++			phba->SerialNumber[j] = 0;
++			continue;
++		} else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '1')) {
++			phba->vpd_flag |= VPD_MODEL_DESC;
++			*pindex += 2;
++			i = vpd[*pindex];
++			*pindex += 1;
++			j = 0;
++			length -= (3+i);
++			while (i--) {
++				phba->ModelDesc[j++] = vpd[(*pindex)++];
++				if (j == 255)
++					break;
++			}
++			phba->ModelDesc[j] = 0;
++			continue;
++		} else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '2')) {
++			phba->vpd_flag |= VPD_MODEL_NAME;
++			*pindex += 2;
++			i = vpd[*pindex];
++			*pindex += 1;
++			j = 0;
++			length -= (3+i);
++			while (i--) {
++				phba->ModelName[j++] = vpd[(*pindex)++];
++				if (j == 79)
++					break;
++			}
++			phba->ModelName[j] = 0;
++			continue;
++		} else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '3')) {
++			phba->vpd_flag |= VPD_PROGRAM_TYPE;
++			*pindex += 2;
++			i = vpd[*pindex];
++			*pindex += 1;
++			j = 0;
++			length -= (3+i);
++			while (i--) {
++				phba->ProgramType[j++] = vpd[(*pindex)++];
++				if (j == 255)
++					break;
++			}
++			phba->ProgramType[j] = 0;
++			continue;
++		} else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '4')) {
++			phba->vpd_flag |= VPD_PORT;
++			*pindex += 2;
++			i = vpd[*pindex];
++			*pindex += 1;
++			j = 0;
++			length -= (3 + i);
++			while (i--) {
++				if ((phba->sli_rev == LPFC_SLI_REV4) &&
++				    (phba->sli4_hba.pport_name_sta ==
++				     LPFC_SLI4_PPNAME_GET)) {
++					j++;
++					(*pindex)++;
++				} else
++					phba->Port[j++] = vpd[(*pindex)++];
++				if (j == 19)
++					break;
++			}
++			if ((phba->sli_rev != LPFC_SLI_REV4) ||
++			    (phba->sli4_hba.pport_name_sta ==
++			     LPFC_SLI4_PPNAME_NON))
++				phba->Port[j] = 0;
++			continue;
++		} else {
++			*pindex += 2;
++			i = vpd[*pindex];
++			*pindex += 1;
++			*pindex += i;
++			length -= (3 + i);
++		}
++	}
++}
++
+ /**
+  * lpfc_parse_vpd - Parse VPD (Vital Product Data)
+  * @phba: pointer to lpfc hba data structure.
+@@ -2277,7 +2371,7 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
+ {
+ 	uint8_t lenlo, lenhi;
+ 	int Length;
+-	int i, j;
++	int i;
+ 	int finished = 0;
+ 	int index = 0;
+ 
+@@ -2310,101 +2404,10 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
+ 			Length = ((((unsigned short)lenhi) << 8) + lenlo);
+ 			if (Length > len - index)
+ 				Length = len - index;
+-			while (Length > 0) {
+-			/* Look for Serial Number */
+-			if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) {
+-				index += 2;
+-				i = vpd[index];
+-				index += 1;
+-				j = 0;
+-				Length -= (3+i);
+-				while(i--) {
+-					phba->SerialNumber[j++] = vpd[index++];
+-					if (j == 31)
+-						break;
+-				}
+-				phba->SerialNumber[j] = 0;
+-				continue;
+-			}
+-			else if ((vpd[index] == 'V') && (vpd[index+1] == '1')) {
+-				phba->vpd_flag |= VPD_MODEL_DESC;
+-				index += 2;
+-				i = vpd[index];
+-				index += 1;
+-				j = 0;
+-				Length -= (3+i);
+-				while(i--) {
+-					phba->ModelDesc[j++] = vpd[index++];
+-					if (j == 255)
+-						break;
+-				}
+-				phba->ModelDesc[j] = 0;
+-				continue;
+-			}
+-			else if ((vpd[index] == 'V') && (vpd[index+1] == '2')) {
+-				phba->vpd_flag |= VPD_MODEL_NAME;
+-				index += 2;
+-				i = vpd[index];
+-				index += 1;
+-				j = 0;
+-				Length -= (3+i);
+-				while(i--) {
+-					phba->ModelName[j++] = vpd[index++];
+-					if (j == 79)
+-						break;
+-				}
+-				phba->ModelName[j] = 0;
+-				continue;
+-			}
+-			else if ((vpd[index] == 'V') && (vpd[index+1] == '3')) {
+-				phba->vpd_flag |= VPD_PROGRAM_TYPE;
+-				index += 2;
+-				i = vpd[index];
+-				index += 1;
+-				j = 0;
+-				Length -= (3+i);
+-				while(i--) {
+-					phba->ProgramType[j++] = vpd[index++];
+-					if (j == 255)
+-						break;
+-				}
+-				phba->ProgramType[j] = 0;
+-				continue;
+-			}
+-			else if ((vpd[index] == 'V') && (vpd[index+1] == '4')) {
+-				phba->vpd_flag |= VPD_PORT;
+-				index += 2;
+-				i = vpd[index];
+-				index += 1;
+-				j = 0;
+-				Length -= (3+i);
+-				while(i--) {
+-					if ((phba->sli_rev == LPFC_SLI_REV4) &&
+-					    (phba->sli4_hba.pport_name_sta ==
+-					     LPFC_SLI4_PPNAME_GET)) {
+-						j++;
+-						index++;
+-					} else
+-						phba->Port[j++] = vpd[index++];
+-					if (j == 19)
+-						break;
+-				}
+-				if ((phba->sli_rev != LPFC_SLI_REV4) ||
+-				    (phba->sli4_hba.pport_name_sta ==
+-				     LPFC_SLI4_PPNAME_NON))
+-					phba->Port[j] = 0;
+-				continue;
+-			}
+-			else {
+-				index += 2;
+-				i = vpd[index];
+-				index += 1;
+-				index += i;
+-				Length -= (3 + i);
+-			}
+-		}
+-		finished = 0;
+-		break;
++
++			lpfc_fill_vpd(phba, vpd, Length, &index);
++			finished = 0;
++			break;
+ 		case 0x78:
+ 			finished = 1;
+ 			break;
+@@ -5569,38 +5572,12 @@ lpfc_async_link_speed_to_read_top(struct lpfc_hba *phba, uint8_t speed_code)
+ void
+ lpfc_cgn_dump_rxmonitor(struct lpfc_hba *phba)
+ {
+-	struct rxtable_entry *entry;
+-	int cnt = 0, head, tail, last, start;
+-
+-	head = atomic_read(&phba->rxtable_idx_head);
+-	tail = atomic_read(&phba->rxtable_idx_tail);
+-	if (!phba->rxtable || head == tail) {
+-		lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT,
+-				"4411 Rxtable is empty\n");
+-		return;
+-	}
+-	last = tail;
+-	start = head;
+-
+-	/* Display the last LPFC_MAX_RXMONITOR_DUMP entries from the rxtable */
+-	while (start != last) {
+-		if (start)
+-			start--;
+-		else
+-			start = LPFC_MAX_RXMONITOR_ENTRY - 1;
+-		entry = &phba->rxtable[start];
++	if (!phba->rx_monitor) {
+ 		lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
+-				"4410 %02d: MBPI %lld Xmit %lld Cmpl %lld "
+-				"Lat %lld ASz %lld Info %02d BWUtil %d "
+-				"Int %d slot %d\n",
+-				cnt, entry->max_bytes_per_interval,
+-				entry->total_bytes, entry->rcv_bytes,
+-				entry->avg_io_latency, entry->avg_io_size,
+-				entry->cmf_info, entry->timer_utilization,
+-				entry->timer_interval, start);
+-		cnt++;
+-		if (cnt >= LPFC_MAX_RXMONITOR_DUMP)
+-			return;
++				"4411 Rx Monitor Info is empty.\n");
++	} else {
++		lpfc_rx_monitor_report(phba, phba->rx_monitor, NULL, 0,
++				       LPFC_MAX_RXMONITOR_DUMP);
+ 	}
+ }
+ 
+@@ -6007,9 +5984,8 @@ lpfc_cmf_timer(struct hrtimer *timer)
+ {
+ 	struct lpfc_hba *phba = container_of(timer, struct lpfc_hba,
+ 					     cmf_timer);
+-	struct rxtable_entry *entry;
++	struct rx_info_entry entry;
+ 	uint32_t io_cnt;
+-	uint32_t head, tail;
+ 	uint32_t busy, max_read;
+ 	uint64_t total, rcv, lat, mbpi, extra, cnt;
+ 	int timer_interval = LPFC_CMF_INTERVAL;
+@@ -6129,40 +6105,30 @@ lpfc_cmf_timer(struct hrtimer *timer)
+ 	}
+ 
+ 	/* Save rxmonitor information for debug */
+-	if (phba->rxtable) {
+-		head = atomic_xchg(&phba->rxtable_idx_head,
+-				   LPFC_RXMONITOR_TABLE_IN_USE);
+-		entry = &phba->rxtable[head];
+-		entry->total_bytes = total;
+-		entry->cmf_bytes = total + extra;
+-		entry->rcv_bytes = rcv;
+-		entry->cmf_busy = busy;
+-		entry->cmf_info = phba->cmf_active_info;
++	if (phba->rx_monitor) {
++		entry.total_bytes = total;
++		entry.cmf_bytes = total + extra;
++		entry.rcv_bytes = rcv;
++		entry.cmf_busy = busy;
++		entry.cmf_info = phba->cmf_active_info;
+ 		if (io_cnt) {
+-			entry->avg_io_latency = div_u64(lat, io_cnt);
+-			entry->avg_io_size = div_u64(rcv, io_cnt);
++			entry.avg_io_latency = div_u64(lat, io_cnt);
++			entry.avg_io_size = div_u64(rcv, io_cnt);
+ 		} else {
+-			entry->avg_io_latency = 0;
+-			entry->avg_io_size = 0;
++			entry.avg_io_latency = 0;
++			entry.avg_io_size = 0;
+ 		}
+-		entry->max_read_cnt = max_read;
+-		entry->io_cnt = io_cnt;
+-		entry->max_bytes_per_interval = mbpi;
++		entry.max_read_cnt = max_read;
++		entry.io_cnt = io_cnt;
++		entry.max_bytes_per_interval = mbpi;
+ 		if (phba->cmf_active_mode == LPFC_CFG_MANAGED)
+-			entry->timer_utilization = phba->cmf_last_ts;
++			entry.timer_utilization = phba->cmf_last_ts;
+ 		else
+-			entry->timer_utilization = ms;
+-		entry->timer_interval = ms;
++			entry.timer_utilization = ms;
++		entry.timer_interval = ms;
+ 		phba->cmf_last_ts = 0;
+ 
+-		/* Increment rxtable index */
+-		head = (head + 1) % LPFC_MAX_RXMONITOR_ENTRY;
+-		tail = atomic_read(&phba->rxtable_idx_tail);
+-		if (head == tail) {
+-			tail = (tail + 1) % LPFC_MAX_RXMONITOR_ENTRY;
+-			atomic_set(&phba->rxtable_idx_tail, tail);
+-		}
+-		atomic_set(&phba->rxtable_idx_head, head);
++		lpfc_rx_monitor_record(phba->rx_monitor, &entry);
+ 	}
+ 
+ 	if (phba->cmf_active_mode == LPFC_CFG_MONITOR) {
+@@ -8315,8 +8281,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
+ 					&phba->pcidev->dev,
+ 					phba->cfg_sg_dma_buf_size,
+ 					i, 0);
+-	if (!phba->lpfc_sg_dma_buf_pool)
++	if (!phba->lpfc_sg_dma_buf_pool) {
++		rc = -ENOMEM;
+ 		goto out_free_bsmbx;
++	}
+ 
+ 	phba->lpfc_cmd_rsp_buf_pool =
+ 			dma_pool_create("lpfc_cmd_rsp_buf_pool",
+@@ -8324,8 +8292,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
+ 					sizeof(struct fcp_cmnd) +
+ 					sizeof(struct fcp_rsp),
+ 					i, 0);
+-	if (!phba->lpfc_cmd_rsp_buf_pool)
++	if (!phba->lpfc_cmd_rsp_buf_pool) {
++		rc = -ENOMEM;
+ 		goto out_free_sg_dma_buf;
++	}
+ 
+ 	mempool_free(mboxq, phba->mbox_mem_pool);
+ 
+@@ -12416,7 +12386,7 @@ lpfc_hba_eq_hdl_array_init(struct lpfc_hba *phba)
+ 
+ 	for (i = 0; i < phba->cfg_irq_chann; i++) {
+ 		eqhdl = lpfc_get_eq_hdl(i);
+-		eqhdl->irq = LPFC_VECTOR_MAP_EMPTY;
++		eqhdl->irq = LPFC_IRQ_EMPTY;
+ 		eqhdl->phba = phba;
+ 	}
+ }
+@@ -12789,7 +12759,7 @@ static void __lpfc_cpuhp_remove(struct lpfc_hba *phba)
+ 
+ static void lpfc_cpuhp_remove(struct lpfc_hba *phba)
+ {
+-	if (phba->pport->fc_flag & FC_OFFLINE_MODE)
++	if (phba->pport && (phba->pport->fc_flag & FC_OFFLINE_MODE))
+ 		return;
+ 
+ 	__lpfc_cpuhp_remove(phba);
+@@ -13053,9 +13023,17 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba)
+ 			 LPFC_DRIVER_HANDLER_NAME"%d", index);
+ 
+ 		eqhdl->idx = index;
+-		rc = request_irq(pci_irq_vector(phba->pcidev, index),
+-			 &lpfc_sli4_hba_intr_handler, 0,
+-			 name, eqhdl);
++		rc = pci_irq_vector(phba->pcidev, index);
++		if (rc < 0) {
++			lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
++					"0489 MSI-X fast-path (%d) "
++					"pci_irq_vec failed (%d)\n", index, rc);
++			goto cfg_fail_out;
++		}
++		eqhdl->irq = rc;
++
++		rc = request_irq(eqhdl->irq, &lpfc_sli4_hba_intr_handler, 0,
++				 name, eqhdl);
+ 		if (rc) {
+ 			lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
+ 					"0486 MSI-X fast-path (%d) "
+@@ -13063,8 +13041,6 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba)
+ 			goto cfg_fail_out;
+ 		}
+ 
+-		eqhdl->irq = pci_irq_vector(phba->pcidev, index);
+-
+ 		if (aff_mask) {
+ 			/* If found a neighboring online cpu, set affinity */
+ 			if (cpu_select < nr_cpu_ids)
+@@ -13181,7 +13157,14 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba)
+ 	}
+ 
+ 	eqhdl = lpfc_get_eq_hdl(0);
+-	eqhdl->irq = pci_irq_vector(phba->pcidev, 0);
++	rc = pci_irq_vector(phba->pcidev, 0);
++	if (rc < 0) {
++		pci_free_irq_vectors(phba->pcidev);
++		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
++				"0496 MSI pci_irq_vec failed (%d)\n", rc);
++		return rc;
++	}
++	eqhdl->irq = rc;
+ 
+ 	cpu = cpumask_first(cpu_present_mask);
+ 	lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ, cpu);
+@@ -13208,8 +13191,8 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba)
+  * MSI-X -> MSI -> IRQ.
+  *
+  * Return codes
+- * 	0 - successful
+- * 	other values - error
++ *	Interrupt mode (2, 1, 0) - successful
++ *	LPFC_INTR_ERROR - error
+  **/
+ static uint32_t
+ lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
+@@ -13254,7 +13237,14 @@ lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
+ 			intr_mode = 0;
+ 
+ 			eqhdl = lpfc_get_eq_hdl(0);
+-			eqhdl->irq = pci_irq_vector(phba->pcidev, 0);
++			retval = pci_irq_vector(phba->pcidev, 0);
++			if (retval < 0) {
++				lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
++					"0502 INTR pci_irq_vec failed (%d)\n",
++					 retval);
++				return LPFC_INTR_ERROR;
++			}
++			eqhdl->irq = retval;
+ 
+ 			cpu = cpumask_first(cpu_present_mask);
+ 			lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ,
+diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
+index 870e53b8f81dd..5d36b35148646 100644
+--- a/drivers/scsi/lpfc/lpfc_mem.c
++++ b/drivers/scsi/lpfc/lpfc_mem.c
+@@ -344,9 +344,12 @@ lpfc_mem_free_all(struct lpfc_hba *phba)
+ 		phba->cgn_i = NULL;
+ 	}
+ 
+-	/* Free RX table */
+-	kfree(phba->rxtable);
+-	phba->rxtable = NULL;
++	/* Free RX Monitor */
++	if (phba->rx_monitor) {
++		lpfc_rx_monitor_destroy_ring(phba->rx_monitor);
++		kfree(phba->rx_monitor);
++		phba->rx_monitor = NULL;
++	}
+ 
+ 	/* Free the iocb lookup array */
+ 	kfree(psli->iocbq_lookup);
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 608016725db99..03c21167fc854 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -6202,6 +6202,9 @@ lpfc_sli4_get_avail_extnt_rsrc(struct lpfc_hba *phba, uint16_t type,
+ 	struct lpfc_mbx_get_rsrc_extent_info *rsrc_info;
+ 	LPFC_MBOXQ_t *mbox;
+ 
++	*extnt_count = 0;
++	*extnt_size = 0;
++
+ 	mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+ 	if (!mbox)
+ 		return -ENOMEM;
+@@ -7959,6 +7962,172 @@ static void lpfc_sli4_dip(struct lpfc_hba *phba)
+ 	}
+ }
+ 
++/**
++ * lpfc_rx_monitor_create_ring - Initialize ring buffer for rx_monitor
++ * @rx_monitor: Pointer to lpfc_rx_info_monitor object
++ * @entries: Number of rx_info_entry objects to allocate in ring
++ *
++ * Return:
++ * 0 - Success
++ * ENOMEM - Failure to kmalloc
++ **/
++int lpfc_rx_monitor_create_ring(struct lpfc_rx_info_monitor *rx_monitor,
++				u32 entries)
++{
++	rx_monitor->ring = kmalloc_array(entries, sizeof(struct rx_info_entry),
++					 GFP_KERNEL);
++	if (!rx_monitor->ring)
++		return -ENOMEM;
++
++	rx_monitor->head_idx = 0;
++	rx_monitor->tail_idx = 0;
++	spin_lock_init(&rx_monitor->lock);
++	rx_monitor->entries = entries;
++
++	return 0;
++}
++
++/**
++ * lpfc_rx_monitor_destroy_ring - Free ring buffer for rx_monitor
++ * @rx_monitor: Pointer to lpfc_rx_info_monitor object
++ **/
++void lpfc_rx_monitor_destroy_ring(struct lpfc_rx_info_monitor *rx_monitor)
++{
++	spin_lock(&rx_monitor->lock);
++	kfree(rx_monitor->ring);
++	rx_monitor->ring = NULL;
++	rx_monitor->entries = 0;
++	rx_monitor->head_idx = 0;
++	rx_monitor->tail_idx = 0;
++	spin_unlock(&rx_monitor->lock);
++}
++
++/**
++ * lpfc_rx_monitor_record - Insert an entry into rx_monitor's ring
++ * @rx_monitor: Pointer to lpfc_rx_info_monitor object
++ * @entry: Pointer to rx_info_entry
++ *
++ * Used to insert an rx_info_entry into rx_monitor's ring.  Note that this is a
++ * deep copy of rx_info_entry not a shallow copy of the rx_info_entry ptr.
++ *
++ * This is called from lpfc_cmf_timer, which is in timer/softirq context.
++ *
++ * In cases of old data overflow, we do a best effort of FIFO order.
++ **/
++void lpfc_rx_monitor_record(struct lpfc_rx_info_monitor *rx_monitor,
++			    struct rx_info_entry *entry)
++{
++	struct rx_info_entry *ring = rx_monitor->ring;
++	u32 *head_idx = &rx_monitor->head_idx;
++	u32 *tail_idx = &rx_monitor->tail_idx;
++	spinlock_t *ring_lock = &rx_monitor->lock;
++	u32 ring_size = rx_monitor->entries;
++
++	spin_lock(ring_lock);
++	memcpy(&ring[*tail_idx], entry, sizeof(*entry));
++	*tail_idx = (*tail_idx + 1) % ring_size;
++
++	/* Best effort of FIFO saved data */
++	if (*tail_idx == *head_idx)
++		*head_idx = (*head_idx + 1) % ring_size;
++
++	spin_unlock(ring_lock);
++}
++
++/**
++ * lpfc_rx_monitor_report - Read out rx_monitor's ring
++ * @phba: Pointer to lpfc_hba object
++ * @rx_monitor: Pointer to lpfc_rx_info_monitor object
++ * @buf: Pointer to char buffer that will contain rx monitor info data
++ * @buf_len: Length buf including null char
++ * @max_read_entries: Maximum number of entries to read out of ring
++ *
++ * Used to dump/read what's in rx_monitor's ring buffer.
++ *
++ * If buf is NULL || buf_len == 0, then it is implied that we want to log the
++ * information to kmsg instead of filling out buf.
++ *
++ * Return:
++ * Number of entries read out of the ring
++ **/
++u32 lpfc_rx_monitor_report(struct lpfc_hba *phba,
++			   struct lpfc_rx_info_monitor *rx_monitor, char *buf,
++			   u32 buf_len, u32 max_read_entries)
++{
++	struct rx_info_entry *ring = rx_monitor->ring;
++	struct rx_info_entry *entry;
++	u32 *head_idx = &rx_monitor->head_idx;
++	u32 *tail_idx = &rx_monitor->tail_idx;
++	spinlock_t *ring_lock = &rx_monitor->lock;
++	u32 ring_size = rx_monitor->entries;
++	u32 cnt = 0;
++	char tmp[DBG_LOG_STR_SZ] = {0};
++	bool log_to_kmsg = (!buf || !buf_len) ? true : false;
++
++	if (!log_to_kmsg) {
++		/* clear the buffer to be sure */
++		memset(buf, 0, buf_len);
++
++		scnprintf(buf, buf_len, "\t%-16s%-16s%-16s%-16s%-8s%-8s%-8s"
++					"%-8s%-8s%-8s%-16s\n",
++					"MaxBPI", "Tot_Data_CMF",
++					"Tot_Data_Cmd", "Tot_Data_Cmpl",
++					"Lat(us)", "Avg_IO", "Max_IO", "Bsy",
++					"IO_cnt", "Info", "BWutil(ms)");
++	}
++
++	/* Needs to be _bh because record is called from timer interrupt
++	 * context
++	 */
++	spin_lock_bh(ring_lock);
++	while (*head_idx != *tail_idx) {
++		entry = &ring[*head_idx];
++
++		/* Read out this entry's data. */
++		if (!log_to_kmsg) {
++			/* If !log_to_kmsg, then store to buf. */
++			scnprintf(tmp, sizeof(tmp),
++				  "%03d:\t%-16llu%-16llu%-16llu%-16llu%-8llu"
++				  "%-8llu%-8llu%-8u%-8u%-8u%u(%u)\n",
++				  *head_idx, entry->max_bytes_per_interval,
++				  entry->cmf_bytes, entry->total_bytes,
++				  entry->rcv_bytes, entry->avg_io_latency,
++				  entry->avg_io_size, entry->max_read_cnt,
++				  entry->cmf_busy, entry->io_cnt,
++				  entry->cmf_info, entry->timer_utilization,
++				  entry->timer_interval);
++
++			/* Check for buffer overflow */
++			if ((strlen(buf) + strlen(tmp)) >= buf_len)
++				break;
++
++			/* Append entry's data to buffer */
++			strlcat(buf, tmp, buf_len);
++		} else {
++			lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
++					"4410 %02u: MBPI %llu Xmit %llu "
++					"Cmpl %llu Lat %llu ASz %llu Info %02u "
++					"BWUtil %u Int %u slot %u\n",
++					cnt, entry->max_bytes_per_interval,
++					entry->total_bytes, entry->rcv_bytes,
++					entry->avg_io_latency,
++					entry->avg_io_size, entry->cmf_info,
++					entry->timer_utilization,
++					entry->timer_interval, *head_idx);
++		}
++
++		*head_idx = (*head_idx + 1) % ring_size;
++
++		/* Don't feed more than max_read_entries */
++		cnt++;
++		if (cnt >= max_read_entries)
++			break;
++	}
++	spin_unlock_bh(ring_lock);
++
++	return cnt;
++}
++
+ /**
+  * lpfc_cmf_setup - Initialize idle_stat tracking
+  * @phba: Pointer to HBA context object.
+@@ -8133,19 +8302,29 @@ no_cmf:
+ 	phba->cmf_interval_rate = LPFC_CMF_INTERVAL;
+ 
+ 	/* Allocate RX Monitor Buffer */
+-	if (!phba->rxtable) {
+-		phba->rxtable = kmalloc_array(LPFC_MAX_RXMONITOR_ENTRY,
+-					      sizeof(struct rxtable_entry),
+-					      GFP_KERNEL);
+-		if (!phba->rxtable) {
++	if (!phba->rx_monitor) {
++		phba->rx_monitor = kzalloc(sizeof(*phba->rx_monitor),
++					   GFP_KERNEL);
++
++		if (!phba->rx_monitor) {
+ 			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ 					"2644 Failed to alloc memory "
+ 					"for RX Monitor Buffer\n");
+ 			return -ENOMEM;
+ 		}
++
++		/* Instruct the rx_monitor object to instantiate its ring */
++		if (lpfc_rx_monitor_create_ring(phba->rx_monitor,
++						LPFC_MAX_RXMONITOR_ENTRY)) {
++			kfree(phba->rx_monitor);
++			phba->rx_monitor = NULL;
++			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
++					"2645 Failed to alloc memory "
++					"for RX Monitor's Ring\n");
++			return -ENOMEM;
++		}
+ 	}
+-	atomic_set(&phba->rxtable_idx_head, 0);
+-	atomic_set(&phba->rxtable_idx_tail, 0);
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
+index 1ddad5b170a60..cbb1aa1cf025b 100644
+--- a/drivers/scsi/lpfc/lpfc_sli4.h
++++ b/drivers/scsi/lpfc/lpfc_sli4.h
+@@ -489,7 +489,7 @@ struct lpfc_hba;
+ #define LPFC_SLI4_HANDLER_NAME_SZ	16
+ struct lpfc_hba_eq_hdl {
+ 	uint32_t idx;
+-	uint16_t irq;
++	int irq;
+ 	char handler_name[LPFC_SLI4_HANDLER_NAME_SZ];
+ 	struct lpfc_hba *phba;
+ 	struct lpfc_queue *eq;
+@@ -611,6 +611,8 @@ struct lpfc_vector_map_info {
+ };
+ #define LPFC_VECTOR_MAP_EMPTY	0xffff
+ 
++#define LPFC_IRQ_EMPTY 0xffffffff
++
+ /* Multi-XRI pool */
+ #define XRI_BATCH               8
+ 
+diff --git a/drivers/scsi/lpfc/lpfc_vmid.c b/drivers/scsi/lpfc/lpfc_vmid.c
+index f64ced04b9125..ed1d7f7b88a38 100644
+--- a/drivers/scsi/lpfc/lpfc_vmid.c
++++ b/drivers/scsi/lpfc/lpfc_vmid.c
+@@ -245,9 +245,7 @@ int lpfc_vmid_get_appid(struct lpfc_vport *vport, char *uuid,
+ 		/* allocate the per cpu variable for holding */
+ 		/* the last access time stamp only if VMID is enabled */
+ 		if (!vmp->last_io_time)
+-			vmp->last_io_time = __alloc_percpu(sizeof(u64),
+-							   __alignof__(struct
+-							   lpfc_vmid));
++			vmp->last_io_time = alloc_percpu_gfp(u64, GFP_ATOMIC);
+ 		if (!vmp->last_io_time) {
+ 			hash_del(&vmp->hnode);
+ 			vmp->flag = LPFC_VMID_SLOT_FREE;
+diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
+index 91d78d0a38fe5..628b08ba6770b 100644
+--- a/drivers/scsi/pm8001/pm8001_hwi.c
++++ b/drivers/scsi/pm8001/pm8001_hwi.c
+@@ -3612,6 +3612,10 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+ 		pm8001_dbg(pm8001_ha, FAIL, " TASK NULL. RETURNING !!!\n");
+ 		return -1;
+ 	}
++
++	if (t->task_proto == SAS_PROTOCOL_INTERNAL_ABORT)
++		atomic_dec(&pm8001_dev->running_req);
++
+ 	ts = &t->task_status;
+ 	if (status != 0)
+ 		pm8001_dbg(pm8001_ha, FAIL, "task abort failed status 0x%x ,tag = 0x%x, scp= 0x%x\n",
+diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
+index bbc4d5890ae6a..e045c6e250902 100644
+--- a/drivers/scsi/qedf/qedf_main.c
++++ b/drivers/scsi/qedf/qedf_main.c
+@@ -1921,6 +1921,27 @@ static int qedf_vport_create(struct fc_vport *vport, bool disabled)
+ 		fc_vport_setlink(vn_port);
+ 	}
+ 
++	/* Set symbolic node name */
++	if (base_qedf->pdev->device == QL45xxx)
++		snprintf(fc_host_symbolic_name(vn_port->host), 256,
++			 "Marvell FastLinQ 45xxx FCoE v%s", QEDF_VERSION);
++
++	if (base_qedf->pdev->device == QL41xxx)
++		snprintf(fc_host_symbolic_name(vn_port->host), 256,
++			 "Marvell FastLinQ 41xxx FCoE v%s", QEDF_VERSION);
++
++	/* Set supported speed */
++	fc_host_supported_speeds(vn_port->host) = n_port->link_supported_speeds;
++
++	/* Set speed */
++	vn_port->link_speed = n_port->link_speed;
++
++	/* Set port type */
++	fc_host_port_type(vn_port->host) = FC_PORTTYPE_NPIV;
++
++	/* Set maxframe size */
++	fc_host_maxframe_size(vn_port->host) = n_port->mfs;
++
+ 	QEDF_INFO(&(base_qedf->dbg_ctx), QEDF_LOG_NPIV, "vn_port=%p.\n",
+ 		   vn_port);
+ 
+diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c
+index 0aa8408464add..d29a1a9cf12fa 100644
+--- a/drivers/slimbus/qcom-ngd-ctrl.c
++++ b/drivers/slimbus/qcom-ngd-ctrl.c
+@@ -1470,7 +1470,13 @@ static int of_qcom_slim_ngd_register(struct device *parent,
+ 		ngd->pdev->dev.of_node = node;
+ 		ctrl->ngd = ngd;
+ 
+-		platform_device_add(ngd->pdev);
++		ret = platform_device_add(ngd->pdev);
++		if (ret) {
++			platform_device_put(ngd->pdev);
++			kfree(ngd);
++			of_node_put(node);
++			return ret;
++		}
+ 		ngd->base = ctrl->base + ngd->id * data->offset +
+ 					(ngd->id - 1) * data->size;
+ 
+@@ -1576,17 +1582,27 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)
+ 	ctrl->pdr = pdr_handle_alloc(slim_pd_status, ctrl);
+ 	if (IS_ERR(ctrl->pdr)) {
+ 		dev_err(dev, "Failed to init PDR handle\n");
+-		return PTR_ERR(ctrl->pdr);
++		ret = PTR_ERR(ctrl->pdr);
++		goto err_pdr_alloc;
+ 	}
+ 
+ 	pds = pdr_add_lookup(ctrl->pdr, "avs/audio", "msm/adsp/audio_pd");
+ 	if (IS_ERR(pds) && PTR_ERR(pds) != -EALREADY) {
++		ret = PTR_ERR(pds);
+ 		dev_err(dev, "pdr add lookup failed: %d\n", ret);
+-		return PTR_ERR(pds);
++		goto err_pdr_lookup;
+ 	}
+ 
+ 	platform_driver_register(&qcom_slim_ngd_driver);
+ 	return of_qcom_slim_ngd_register(dev, ctrl);
++
++err_pdr_alloc:
++	qcom_unregister_ssr_notifier(ctrl->notifier, &ctrl->nb);
++
++err_pdr_lookup:
++	pdr_handle_release(ctrl->pdr);
++
++	return ret;
+ }
+ 
+ static int qcom_slim_ngd_ctrl_remove(struct platform_device *pdev)
+diff --git a/drivers/soc/qcom/smem_state.c b/drivers/soc/qcom/smem_state.c
+index 31faf4aa868e6..e848cc9a3cf80 100644
+--- a/drivers/soc/qcom/smem_state.c
++++ b/drivers/soc/qcom/smem_state.c
+@@ -136,6 +136,7 @@ static void qcom_smem_state_release(struct kref *ref)
+ 	struct qcom_smem_state *state = container_of(ref, struct qcom_smem_state, refcount);
+ 
+ 	list_del(&state->list);
++	of_node_put(state->of_node);
+ 	kfree(state);
+ }
+ 
+@@ -205,7 +206,7 @@ struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node,
+ 
+ 	kref_init(&state->refcount);
+ 
+-	state->of_node = of_node;
++	state->of_node = of_node_get(of_node);
+ 	state->ops = *ops;
+ 	state->priv = priv;
+ 
+diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c
+index 9df9bba242f3e..3e8994d6110e6 100644
+--- a/drivers/soc/qcom/smsm.c
++++ b/drivers/soc/qcom/smsm.c
+@@ -526,7 +526,7 @@ static int qcom_smsm_probe(struct platform_device *pdev)
+ 	for (id = 0; id < smsm->num_hosts; id++) {
+ 		ret = smsm_parse_ipc(smsm, id);
+ 		if (ret < 0)
+-			return ret;
++			goto out_put;
+ 	}
+ 
+ 	/* Acquire the main SMSM state vector */
+@@ -534,13 +534,14 @@ static int qcom_smsm_probe(struct platform_device *pdev)
+ 			      smsm->num_entries * sizeof(u32));
+ 	if (ret < 0 && ret != -EEXIST) {
+ 		dev_err(&pdev->dev, "unable to allocate shared state entry\n");
+-		return ret;
++		goto out_put;
+ 	}
+ 
+ 	states = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL);
+ 	if (IS_ERR(states)) {
+ 		dev_err(&pdev->dev, "Unable to acquire shared state entry\n");
+-		return PTR_ERR(states);
++		ret = PTR_ERR(states);
++		goto out_put;
+ 	}
+ 
+ 	/* Acquire the list of interrupt mask vectors */
+@@ -548,13 +549,14 @@ static int qcom_smsm_probe(struct platform_device *pdev)
+ 	ret = qcom_smem_alloc(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, size);
+ 	if (ret < 0 && ret != -EEXIST) {
+ 		dev_err(&pdev->dev, "unable to allocate smsm interrupt mask\n");
+-		return ret;
++		goto out_put;
+ 	}
+ 
+ 	intr_mask = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL);
+ 	if (IS_ERR(intr_mask)) {
+ 		dev_err(&pdev->dev, "unable to acquire shared memory interrupt mask\n");
+-		return PTR_ERR(intr_mask);
++		ret = PTR_ERR(intr_mask);
++		goto out_put;
+ 	}
+ 
+ 	/* Setup the reference to the local state bits */
+@@ -565,7 +567,8 @@ static int qcom_smsm_probe(struct platform_device *pdev)
+ 	smsm->state = qcom_smem_state_register(local_node, &smsm_state_ops, smsm);
+ 	if (IS_ERR(smsm->state)) {
+ 		dev_err(smsm->dev, "failed to register qcom_smem_state\n");
+-		return PTR_ERR(smsm->state);
++		ret = PTR_ERR(smsm->state);
++		goto out_put;
+ 	}
+ 
+ 	/* Register handlers for remote processor entries of interest. */
+@@ -595,16 +598,19 @@ static int qcom_smsm_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	platform_set_drvdata(pdev, smsm);
++	of_node_put(local_node);
+ 
+ 	return 0;
+ 
+ unwind_interfaces:
++	of_node_put(node);
+ 	for (id = 0; id < smsm->num_entries; id++)
+ 		if (smsm->entries[id].domain)
+ 			irq_domain_remove(smsm->entries[id].domain);
+ 
+ 	qcom_smem_state_unregister(smsm->state);
+-
++out_put:
++	of_node_put(local_node);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
+index 5725c8ef0406a..6f601227da3cb 100644
+--- a/drivers/soc/tegra/Kconfig
++++ b/drivers/soc/tegra/Kconfig
+@@ -136,7 +136,6 @@ config SOC_TEGRA_FUSE
+ 	def_bool y
+ 	depends on ARCH_TEGRA
+ 	select SOC_BUS
+-	select TEGRA20_APB_DMA if ARCH_TEGRA_2x_SOC
+ 
+ config SOC_TEGRA_FLOWCTRL
+ 	bool
+diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
+index b0a8405dbdb19..6542267a224d2 100644
+--- a/drivers/soc/tegra/fuse/fuse-tegra.c
++++ b/drivers/soc/tegra/fuse/fuse-tegra.c
+@@ -568,6 +568,7 @@ static int __init tegra_init_fuse(void)
+ 	np = of_find_matching_node(NULL, car_match);
+ 	if (np) {
+ 		void __iomem *base = of_iomap(np, 0);
++		of_node_put(np);
+ 		if (base) {
+ 			tegra_enable_fuse_clk(base);
+ 			iounmap(base);
+diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
+index 4fbb19557f5ed..42c5fae80efbf 100644
+--- a/drivers/soundwire/cadence_master.c
++++ b/drivers/soundwire/cadence_master.c
+@@ -544,9 +544,12 @@ cdns_fill_msg_resp(struct sdw_cdns *cdns,
+ 		return SDW_CMD_IGNORED;
+ 	}
+ 
+-	/* fill response */
+-	for (i = 0; i < count; i++)
+-		msg->buf[i + offset] = FIELD_GET(CDNS_MCP_RESP_RDATA, cdns->response_buf[i]);
++	if (msg->flags == SDW_MSG_FLAG_READ) {
++		/* fill response */
++		for (i = 0; i < count; i++)
++			msg->buf[i + offset] = FIELD_GET(CDNS_MCP_RESP_RDATA,
++							 cdns->response_buf[i]);
++	}
+ 
+ 	return SDW_CMD_OK;
+ }
+diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c
+index 89d1d0d021fc7..af6c1a93372d9 100644
+--- a/drivers/soundwire/intel.c
++++ b/drivers/soundwire/intel.c
+@@ -1429,7 +1429,6 @@ int intel_link_startup(struct auxiliary_device *auxdev)
+ 	ret = intel_register_dai(sdw);
+ 	if (ret) {
+ 		dev_err(dev, "DAI registration failed: %d\n", ret);
+-		snd_soc_unregister_component(dev);
+ 		goto err_interrupt;
+ 	}
+ 
+diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
+index e12ab5b43f341..4472305479452 100644
+--- a/drivers/spi/spi-cadence-quadspi.c
++++ b/drivers/spi/spi-cadence-quadspi.c
+@@ -1645,7 +1645,7 @@ static int cqspi_probe(struct platform_device *pdev)
+ 	pm_runtime_enable(dev);
+ 	ret = pm_runtime_resume_and_get(dev);
+ 	if (ret < 0)
+-		return ret;
++		goto probe_pm_failed;
+ 
+ 	ret = clk_prepare_enable(cqspi->clk);
+ 	if (ret) {
+@@ -1740,6 +1740,7 @@ probe_reset_failed:
+ 	clk_disable_unprepare(cqspi->clk);
+ probe_clk_failed:
+ 	pm_runtime_put_sync(dev);
++probe_pm_failed:
+ 	pm_runtime_disable(dev);
+ 	return ret;
+ }
+diff --git a/drivers/spi/spi-dw-bt1.c b/drivers/spi/spi-dw-bt1.c
+index c065534161237..3fb89dee595e7 100644
+--- a/drivers/spi/spi-dw-bt1.c
++++ b/drivers/spi/spi-dw-bt1.c
+@@ -293,8 +293,10 @@ static int dw_spi_bt1_probe(struct platform_device *pdev)
+ 	pm_runtime_enable(&pdev->dev);
+ 
+ 	ret = dw_spi_add_host(&pdev->dev, dws);
+-	if (ret)
++	if (ret) {
++		pm_runtime_disable(&pdev->dev);
+ 		goto err_disable_clk;
++	}
+ 
+ 	platform_set_drvdata(pdev, dwsbt1);
+ 
+diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
+index e4cb52e1fe261..6974a1c947aad 100644
+--- a/drivers/spi/spi-meson-spicc.c
++++ b/drivers/spi/spi-meson-spicc.c
+@@ -537,7 +537,7 @@ static unsigned long meson_spicc_pow2_recalc_rate(struct clk_hw *hw,
+ 	struct clk_divider *divider = to_clk_divider(hw);
+ 	struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider);
+ 
+-	if (!spicc->master->cur_msg || !spicc->master->busy)
++	if (!spicc->master->cur_msg)
+ 		return 0;
+ 
+ 	return clk_divider_ops.recalc_rate(hw, parent_rate);
+@@ -549,7 +549,7 @@ static int meson_spicc_pow2_determine_rate(struct clk_hw *hw,
+ 	struct clk_divider *divider = to_clk_divider(hw);
+ 	struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider);
+ 
+-	if (!spicc->master->cur_msg || !spicc->master->busy)
++	if (!spicc->master->cur_msg)
+ 		return -EINVAL;
+ 
+ 	return clk_divider_ops.determine_rate(hw, req);
+@@ -561,7 +561,7 @@ static int meson_spicc_pow2_set_rate(struct clk_hw *hw, unsigned long rate,
+ 	struct clk_divider *divider = to_clk_divider(hw);
+ 	struct meson_spicc_device *spicc = pow2_clk_to_spicc(divider);
+ 
+-	if (!spicc->master->cur_msg || !spicc->master->busy)
++	if (!spicc->master->cur_msg)
+ 		return -EINVAL;
+ 
+ 	return clk_divider_ops.set_rate(hw, rate, parent_rate);
+diff --git a/drivers/spi/spi-mt7621.c b/drivers/spi/spi-mt7621.c
+index b4b9b7309b5e9..351b0ef52bbc8 100644
+--- a/drivers/spi/spi-mt7621.c
++++ b/drivers/spi/spi-mt7621.c
+@@ -340,11 +340,9 @@ static int mt7621_spi_probe(struct platform_device *pdev)
+ 		return PTR_ERR(base);
+ 
+ 	clk = devm_clk_get(&pdev->dev, NULL);
+-	if (IS_ERR(clk)) {
+-		dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n",
+-			status);
+-		return PTR_ERR(clk);
+-	}
++	if (IS_ERR(clk))
++		return dev_err_probe(&pdev->dev, PTR_ERR(clk),
++				     "unable to get SYS clock\n");
+ 
+ 	status = clk_prepare_enable(clk);
+ 	if (status)
+diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c
+index 20b0471729651..061f7394e5b9b 100644
+--- a/drivers/spi/spi-omap-100k.c
++++ b/drivers/spi/spi-omap-100k.c
+@@ -412,6 +412,7 @@ static int omap1_spi100k_probe(struct platform_device *pdev)
+ 	return status;
+ 
+ err_fck:
++	pm_runtime_disable(&pdev->dev);
+ 	clk_disable_unprepare(spi100k->fck);
+ err_ick:
+ 	clk_disable_unprepare(spi100k->ick);
+diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
+index 00d6084306b4a..7d89510dc3f00 100644
+--- a/drivers/spi/spi-qup.c
++++ b/drivers/spi/spi-qup.c
+@@ -1198,8 +1198,10 @@ static int spi_qup_pm_resume_runtime(struct device *device)
+ 		return ret;
+ 
+ 	ret = clk_prepare_enable(controller->cclk);
+-	if (ret)
++	if (ret) {
++		clk_disable_unprepare(controller->iclk);
+ 		return ret;
++	}
+ 
+ 	/* Disable clocks auto gaiting */
+ 	config = readl_relaxed(controller->base + QUP_CONFIG);
+@@ -1245,14 +1247,25 @@ static int spi_qup_resume(struct device *device)
+ 		return ret;
+ 
+ 	ret = clk_prepare_enable(controller->cclk);
+-	if (ret)
++	if (ret) {
++		clk_disable_unprepare(controller->iclk);
+ 		return ret;
++	}
+ 
+ 	ret = spi_qup_set_state(controller, QUP_STATE_RESET);
+ 	if (ret)
+-		return ret;
++		goto disable_clk;
+ 
+-	return spi_master_resume(master);
++	ret = spi_master_resume(master);
++	if (ret)
++		goto disable_clk;
++
++	return 0;
++
++disable_clk:
++	clk_disable_unprepare(controller->cclk);
++	clk_disable_unprepare(controller->iclk);
++	return ret;
+ }
+ #endif /* CONFIG_PM_SLEEP */
+ 
+diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
+index 7f346866614ab..7c22b5c410ce0 100644
+--- a/drivers/spi/spi-s3c64xx.c
++++ b/drivers/spi/spi-s3c64xx.c
+@@ -84,6 +84,7 @@
+ #define S3C64XX_SPI_ST_TX_FIFORDY		(1<<0)
+ 
+ #define S3C64XX_SPI_PACKET_CNT_EN		(1<<16)
++#define S3C64XX_SPI_PACKET_CNT_MASK		GENMASK(15, 0)
+ 
+ #define S3C64XX_SPI_PND_TX_UNDERRUN_CLR		(1<<4)
+ #define S3C64XX_SPI_PND_TX_OVERRUN_CLR		(1<<3)
+@@ -711,6 +712,13 @@ static int s3c64xx_spi_prepare_message(struct spi_master *master,
+ 	return 0;
+ }
+ 
++static size_t s3c64xx_spi_max_transfer_size(struct spi_device *spi)
++{
++	struct spi_controller *ctlr = spi->controller;
++
++	return ctlr->can_dma ? S3C64XX_SPI_PACKET_CNT_MASK : SIZE_MAX;
++}
++
+ static int s3c64xx_spi_transfer_one(struct spi_master *master,
+ 				    struct spi_device *spi,
+ 				    struct spi_transfer *xfer)
+@@ -1152,6 +1160,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
+ 	master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;
+ 	master->prepare_message = s3c64xx_spi_prepare_message;
+ 	master->transfer_one = s3c64xx_spi_transfer_one;
++	master->max_transfer_size = s3c64xx_spi_max_transfer_size;
+ 	master->num_chipselect = sci->num_cs;
+ 	master->use_gpio_descriptors = true;
+ 	master->dma_alignment = 8;
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index 32c01e684af3d..4b42f2302a8a8 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -1097,6 +1097,8 @@ void spi_unmap_buf(struct spi_controller *ctlr, struct device *dev,
+ 	if (sgt->orig_nents) {
+ 		dma_unmap_sg(dev, sgt->sgl, sgt->orig_nents, dir);
+ 		sg_free_table(sgt);
++		sgt->orig_nents = 0;
++		sgt->nents = 0;
+ 	}
+ }
+ 
+diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
+index 2113be40b5a97..58f580e7aacc5 100644
+--- a/drivers/spmi/spmi-pmic-arb.c
++++ b/drivers/spmi/spmi-pmic-arb.c
+@@ -992,7 +992,8 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+ 	 * version 5, there is more than one APID mapped to each PPID.
+ 	 * The owner field for each of these mappings specifies the EE which is
+ 	 * allowed to write to the APID.  The owner of the last (highest) APID
+-	 * for a given PPID will receive interrupts from the PPID.
++	 * which has the IRQ owner bit set for a given PPID will receive
++	 * interrupts from the PPID.
+ 	 */
+ 	for (i = 0; ; i++, apidd++) {
+ 		offset = pmic_arb->ver_ops->apid_map_offset(i);
+@@ -1015,16 +1016,16 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb *pmic_arb)
+ 		apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID;
+ 		prev_apidd = &pmic_arb->apid_data[apid];
+ 
+-		if (valid && is_irq_ee &&
+-				prev_apidd->write_ee == pmic_arb->ee) {
++		if (!valid || apidd->write_ee == pmic_arb->ee) {
++			/* First PPID mapping or one for this EE */
++			pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
++		} else if (valid && is_irq_ee &&
++			   prev_apidd->write_ee == pmic_arb->ee) {
+ 			/*
+ 			 * Duplicate PPID mapping after the one for this EE;
+ 			 * override the irq owner
+ 			 */
+ 			prev_apidd->irq_ee = apidd->irq_ee;
+-		} else if (!valid || is_irq_ee) {
+-			/* First PPID mapping or duplicate for another EE */
+-			pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID;
+ 		}
+ 
+ 		apidd->ppid = ppid;
+diff --git a/drivers/staging/greybus/audio_helper.c b/drivers/staging/greybus/audio_helper.c
+index 05e91e6bc2a08..223987616e074 100644
+--- a/drivers/staging/greybus/audio_helper.c
++++ b/drivers/staging/greybus/audio_helper.c
+@@ -3,7 +3,6 @@
+  * Greybus Audio Sound SoC helper APIs
+  */
+ 
+-#include <linux/debugfs.h>
+ #include <sound/core.h>
+ #include <sound/soc.h>
+ #include <sound/soc-dapm.h>
+@@ -116,10 +115,6 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm,
+ {
+ 	int i;
+ 	struct snd_soc_dapm_widget *w, *tmp_w;
+-#ifdef CONFIG_DEBUG_FS
+-	struct dentry *parent = dapm->debugfs_dapm;
+-	struct dentry *debugfs_w = NULL;
+-#endif
+ 
+ 	mutex_lock(&dapm->card->dapm_mutex);
+ 	for (i = 0; i < num; i++) {
+@@ -139,12 +134,6 @@ int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm,
+ 			continue;
+ 		}
+ 		widget++;
+-#ifdef CONFIG_DEBUG_FS
+-		if (!parent)
+-			debugfs_w = debugfs_lookup(w->name, parent);
+-		debugfs_remove(debugfs_w);
+-		debugfs_w = NULL;
+-#endif
+ 		gbaudio_dapm_free_widget(w);
+ 	}
+ 	mutex_unlock(&dapm->card->dapm_mutex);
+diff --git a/drivers/staging/media/meson/vdec/vdec_hevc.c b/drivers/staging/media/meson/vdec/vdec_hevc.c
+index 9530e580e57a2..afced435c9070 100644
+--- a/drivers/staging/media/meson/vdec/vdec_hevc.c
++++ b/drivers/staging/media/meson/vdec/vdec_hevc.c
+@@ -167,8 +167,12 @@ static int vdec_hevc_start(struct amvdec_session *sess)
+ 
+ 	clk_set_rate(core->vdec_hevc_clk, 666666666);
+ 	ret = clk_prepare_enable(core->vdec_hevc_clk);
+-	if (ret)
++	if (ret) {
++		if (core->platform->revision == VDEC_REVISION_G12A ||
++		    core->platform->revision == VDEC_REVISION_SM1)
++			clk_disable_unprepare(core->vdec_hevcf_clk);
+ 		return ret;
++	}
+ 
+ 	if (core->platform->revision == VDEC_REVISION_SM1)
+ 		regmap_update_bits(core->regmap_ao, AO_RTI_GEN_PWR_SLEEP0,
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
+index 960a0130cd620..55c54dfdc585c 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
+@@ -448,6 +448,8 @@ static int cedrus_probe(struct platform_device *pdev)
+ 	if (!dev)
+ 		return -ENOMEM;
+ 
++	platform_set_drvdata(pdev, dev);
++
+ 	dev->vfd = cedrus_video_device;
+ 	dev->dev = &pdev->dev;
+ 	dev->pdev = pdev;
+@@ -521,8 +523,6 @@ static int cedrus_probe(struct platform_device *pdev)
+ 		goto err_m2m_mc;
+ 	}
+ 
+-	platform_set_drvdata(pdev, dev);
+-
+ 	return 0;
+ 
+ err_m2m_mc:
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+index 3b6aa78a2985f..e7f7602a5ab40 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
+@@ -106,11 +106,11 @@ void cedrus_device_run(void *priv)
+ 
+ 	/* Trigger decoding if setup went well, bail out otherwise. */
+ 	if (!error) {
+-		dev->dec_ops[ctx->current_codec]->trigger(ctx);
+-
+ 		/* Start the watchdog timer. */
+ 		schedule_delayed_work(&dev->watchdog_work,
+ 				      msecs_to_jiffies(2000));
++
++		dev->dec_ops[ctx->current_codec]->trigger(ctx);
+ 	} else {
+ 		v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev,
+ 						 ctx->fh.m2m_ctx,
+diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+index 687f87598f780..095b8464f37a0 100644
+--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
++++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+@@ -234,8 +234,9 @@ static void cedrus_h265_skip_bits(struct cedrus_dev *dev, int num)
+ 		cedrus_write(dev, VE_DEC_H265_TRIGGER,
+ 			     VE_DEC_H265_TRIGGER_FLUSH_BITS |
+ 			     VE_DEC_H265_TRIGGER_TYPE_N_BITS(tmp));
+-		while (cedrus_read(dev, VE_DEC_H265_STATUS) & VE_DEC_H265_STATUS_VLD_BUSY)
+-			udelay(1);
++
++		if (cedrus_wait_for(dev, VE_DEC_H265_STATUS, VE_DEC_H265_STATUS_VLD_BUSY))
++			dev_err_ratelimited(dev->dev, "timed out waiting to skip bits\n");
+ 
+ 		count += tmp;
+ 	}
+diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c
+index b4170f64d1186..03c2c66dbf665 100644
+--- a/drivers/staging/rtl8723bs/core/rtw_cmd.c
++++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c
+@@ -161,8 +161,6 @@ static struct cmd_hdl wlancmds[] = {
+ 
+ int rtw_init_cmd_priv(struct	cmd_priv *pcmdpriv)
+ {
+-	int res = 0;
+-
+ 	init_completion(&pcmdpriv->cmd_queue_comp);
+ 	init_completion(&pcmdpriv->terminate_cmdthread_comp);
+ 
+@@ -175,18 +173,16 @@ int rtw_init_cmd_priv(struct	cmd_priv *pcmdpriv)
+ 
+ 	pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ);
+ 
+-	if (!pcmdpriv->cmd_allocated_buf) {
+-		res = -ENOMEM;
+-		goto exit;
+-	}
++	if (!pcmdpriv->cmd_allocated_buf)
++		return -ENOMEM;
+ 
+ 	pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf  +  CMDBUFF_ALIGN_SZ - ((SIZE_PTR)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1));
+ 
+ 	pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4);
+ 
+ 	if (!pcmdpriv->rsp_allocated_buf) {
+-		res = -ENOMEM;
+-		goto exit;
++		kfree(pcmdpriv->cmd_allocated_buf);
++		return -ENOMEM;
+ 	}
+ 
+ 	pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf  +  4 - ((SIZE_PTR)(pcmdpriv->rsp_allocated_buf) & 3);
+@@ -196,8 +192,8 @@ int rtw_init_cmd_priv(struct	cmd_priv *pcmdpriv)
+ 	pcmdpriv->rsp_cnt = 0;
+ 
+ 	mutex_init(&pcmdpriv->sctx_mutex);
+-exit:
+-	return res;
++
++	return 0;
+ }
+ 
+ static void c2h_wk_callback(struct work_struct *work);
+diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
+index 380d8c9e1239e..68bba3c0e757a 100644
+--- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c
++++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c
+@@ -664,51 +664,36 @@ void rtw_reset_drv_sw(struct adapter *padapter)
+ 
+ u8 rtw_init_drv_sw(struct adapter *padapter)
+ {
+-	u8 ret8 = _SUCCESS;
+-
+ 	rtw_init_default_value(padapter);
+ 
+ 	rtw_init_hal_com_default_value(padapter);
+ 
+-	if (rtw_init_cmd_priv(&padapter->cmdpriv)) {
+-		ret8 = _FAIL;
+-		goto exit;
+-	}
++	if (rtw_init_cmd_priv(&padapter->cmdpriv))
++		return _FAIL;
+ 
+ 	padapter->cmdpriv.padapter = padapter;
+ 
+-	if (rtw_init_evt_priv(&padapter->evtpriv)) {
+-		ret8 = _FAIL;
+-		goto exit;
+-	}
++	if (rtw_init_evt_priv(&padapter->evtpriv))
++		goto free_cmd_priv;
+ 
+-
+-	if (rtw_init_mlme_priv(padapter) == _FAIL) {
+-		ret8 = _FAIL;
+-		goto exit;
+-	}
++	if (rtw_init_mlme_priv(padapter) == _FAIL)
++		goto free_evt_priv;
+ 
+ 	init_mlme_ext_priv(padapter);
+ 
+-	if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL) {
+-		ret8 = _FAIL;
+-		goto exit;
+-	}
++	if (_rtw_init_xmit_priv(&padapter->xmitpriv, padapter) == _FAIL)
++		goto free_mlme_ext;
+ 
+-	if (_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL) {
+-		ret8 = _FAIL;
+-		goto exit;
+-	}
++	if (_rtw_init_recv_priv(&padapter->recvpriv, padapter) == _FAIL)
++		goto free_xmit_priv;
+ 	/*  add for CONFIG_IEEE80211W, none 11w also can use */
+ 	spin_lock_init(&padapter->security_key_mutex);
+ 
+ 	/*  We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */
+ 	/* memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv)); */
+ 
+-	if (_rtw_init_sta_priv(&padapter->stapriv) == _FAIL) {
+-		ret8 = _FAIL;
+-		goto exit;
+-	}
++	if (_rtw_init_sta_priv(&padapter->stapriv) == _FAIL)
++		goto free_recv_priv;
+ 
+ 	padapter->stapriv.padapter = padapter;
+ 	padapter->setband = GHZ24_50;
+@@ -719,9 +704,26 @@ u8 rtw_init_drv_sw(struct adapter *padapter)
+ 
+ 	rtw_hal_dm_init(padapter);
+ 
+-exit:
++	return _SUCCESS;
++
++free_recv_priv:
++	_rtw_free_recv_priv(&padapter->recvpriv);
++
++free_xmit_priv:
++	_rtw_free_xmit_priv(&padapter->xmitpriv);
++
++free_mlme_ext:
++	free_mlme_ext_priv(&padapter->mlmeextpriv);
+ 
+-	return ret8;
++	rtw_free_mlme_priv(&padapter->mlmepriv);
++
++free_evt_priv:
++	rtw_free_evt_priv(&padapter->evtpriv);
++
++free_cmd_priv:
++	rtw_free_cmd_priv(&padapter->cmdpriv);
++
++	return _FAIL;
+ }
+ 
+ void rtw_cancel_all_timer(struct adapter *padapter)
+diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
+index bab08a40fe669..ec7c991e745b7 100644
+--- a/drivers/staging/vt6655/device_main.c
++++ b/drivers/staging/vt6655/device_main.c
+@@ -583,7 +583,7 @@ err_free_rd:
+ 	kfree(desc->rd_info);
+ 
+ err_free_desc:
+-	while (--i) {
++	while (i--) {
+ 		desc = &priv->aRD0Ring[i];
+ 		device_free_rx_buf(priv, desc);
+ 		kfree(desc->rd_info);
+@@ -629,7 +629,7 @@ err_free_rd:
+ 	kfree(desc->rd_info);
+ 
+ err_free_desc:
+-	while (--i) {
++	while (i--) {
+ 		desc = &priv->aRD1Ring[i];
+ 		device_free_rx_buf(priv, desc);
+ 		kfree(desc->rd_info);
+@@ -694,7 +694,7 @@ static int device_init_td0_ring(struct vnt_private *priv)
+ 	return 0;
+ 
+ err_free_desc:
+-	while (--i) {
++	while (i--) {
+ 		desc = &priv->apTD0Rings[i];
+ 		kfree(desc->td_info);
+ 	}
+@@ -734,7 +734,7 @@ static int device_init_td1_ring(struct vnt_private *priv)
+ 	return 0;
+ 
+ err_free_desc:
+-	while (--i) {
++	while (i--) {
+ 		desc = &priv->apTD1Rings[i];
+ 		kfree(desc->td_info);
+ 	}
+diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c
+index b76293cc989c4..7838b6e2dba5c 100644
+--- a/drivers/thermal/cpufreq_cooling.c
++++ b/drivers/thermal/cpufreq_cooling.c
+@@ -501,17 +501,17 @@ __cpufreq_cooling_register(struct device_node *np,
+ 	struct thermal_cooling_device_ops *cooling_ops;
+ 	char *name;
+ 
++	if (IS_ERR_OR_NULL(policy)) {
++		pr_err("%s: cpufreq policy isn't valid: %p\n", __func__, policy);
++		return ERR_PTR(-EINVAL);
++	}
++
+ 	dev = get_cpu_device(policy->cpu);
+ 	if (unlikely(!dev)) {
+ 		pr_warn("No cpu device for cpu %d\n", policy->cpu);
+ 		return ERR_PTR(-ENODEV);
+ 	}
+ 
+-	if (IS_ERR_OR_NULL(policy)) {
+-		pr_err("%s: cpufreq policy isn't valid: %p\n", __func__, policy);
+-		return ERR_PTR(-EINVAL);
+-	}
+-
+ 	i = cpufreq_table_count_valid_entries(policy);
+ 	if (!i) {
+ 		pr_debug("%s: CPUFreq table not found or has no valid entries\n",
+diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c
+index c841ab37e7c6d..46cd799af148d 100644
+--- a/drivers/thermal/intel/intel_powerclamp.c
++++ b/drivers/thermal/intel/intel_powerclamp.c
+@@ -532,8 +532,10 @@ static int start_power_clamp(void)
+ 
+ 	/* prefer BSP */
+ 	control_cpu = 0;
+-	if (!cpu_online(control_cpu))
+-		control_cpu = smp_processor_id();
++	if (!cpu_online(control_cpu)) {
++		control_cpu = get_cpu();
++		put_cpu();
++	}
+ 
+ 	clamping = true;
+ 	schedule_delayed_work(&poll_pkg_cstate_work, 0);
+diff --git a/drivers/thermal/qcom/tsens-v0_1.c b/drivers/thermal/qcom/tsens-v0_1.c
+index f136cb3502384..327f37202c69f 100644
+--- a/drivers/thermal/qcom/tsens-v0_1.c
++++ b/drivers/thermal/qcom/tsens-v0_1.c
+@@ -604,7 +604,7 @@ static const struct tsens_ops ops_8939 = {
+ struct tsens_plat_data data_8939 = {
+ 	.num_sensors	= 10,
+ 	.ops		= &ops_8939,
+-	.hw_ids		= (unsigned int []){ 0, 1, 2, 4, 5, 6, 7, 8, 9, 10 },
++	.hw_ids		= (unsigned int []){ 0, 1, 2, 3, 5, 6, 7, 8, 9, 10 },
+ 
+ 	.feat		= &tsens_v0_1_feat,
+ 	.fields	= tsens_v0_1_regfields,
+diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
+index cb8c9c4ae93a2..b5cd9673e15d3 100644
+--- a/drivers/thunderbolt/nhi.c
++++ b/drivers/thunderbolt/nhi.c
+@@ -28,7 +28,11 @@
+ #define RING_TYPE(ring) ((ring)->is_tx ? "TX ring" : "RX ring")
+ 
+ #define RING_FIRST_USABLE_HOPID	1
+-
++/*
++ * Used with QUIRK_E2E to specify an unused HopID the Rx credits are
++ * transferred.
++ */
++#define RING_E2E_RESERVED_HOPID	RING_FIRST_USABLE_HOPID
+ /*
+  * Minimal number of vectors when we use MSI-X. Two for control channel
+  * Rx/Tx and the rest four are for cross domain DMA paths.
+@@ -38,7 +42,9 @@
+ 
+ #define NHI_MAILBOX_TIMEOUT	500 /* ms */
+ 
++/* Host interface quirks */
+ #define QUIRK_AUTO_CLEAR_INT	BIT(0)
++#define QUIRK_E2E		BIT(1)
+ 
+ static int ring_interrupt_index(struct tb_ring *ring)
+ {
+@@ -458,8 +464,18 @@ static void ring_release_msix(struct tb_ring *ring)
+ 
+ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)
+ {
++	unsigned int start_hop = RING_FIRST_USABLE_HOPID;
+ 	int ret = 0;
+ 
++	if (nhi->quirks & QUIRK_E2E) {
++		start_hop = RING_FIRST_USABLE_HOPID + 1;
++		if (ring->flags & RING_FLAG_E2E && !ring->is_tx) {
++			dev_dbg(&nhi->pdev->dev, "quirking E2E TX HopID %u -> %u\n",
++				ring->e2e_tx_hop, RING_E2E_RESERVED_HOPID);
++			ring->e2e_tx_hop = RING_E2E_RESERVED_HOPID;
++		}
++	}
++
+ 	spin_lock_irq(&nhi->lock);
+ 
+ 	if (ring->hop < 0) {
+@@ -469,7 +485,7 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)
+ 		 * Automatically allocate HopID from the non-reserved
+ 		 * range 1 .. hop_count - 1.
+ 		 */
+-		for (i = RING_FIRST_USABLE_HOPID; i < nhi->hop_count; i++) {
++		for (i = start_hop; i < nhi->hop_count; i++) {
+ 			if (ring->is_tx) {
+ 				if (!nhi->tx_rings[i]) {
+ 					ring->hop = i;
+@@ -484,6 +500,11 @@ static int nhi_alloc_hop(struct tb_nhi *nhi, struct tb_ring *ring)
+ 		}
+ 	}
+ 
++	if (ring->hop > 0 && ring->hop < start_hop) {
++		dev_warn(&nhi->pdev->dev, "invalid hop: %d\n", ring->hop);
++		ret = -EINVAL;
++		goto err_unlock;
++	}
+ 	if (ring->hop < 0 || ring->hop >= nhi->hop_count) {
+ 		dev_warn(&nhi->pdev->dev, "invalid hop: %d\n", ring->hop);
+ 		ret = -EINVAL;
+@@ -1097,12 +1118,26 @@ static void nhi_shutdown(struct tb_nhi *nhi)
+ 
+ static void nhi_check_quirks(struct tb_nhi *nhi)
+ {
+-	/*
+-	 * Intel hardware supports auto clear of the interrupt status
+-	 * reqister right after interrupt is being issued.
+-	 */
+-	if (nhi->pdev->vendor == PCI_VENDOR_ID_INTEL)
++	if (nhi->pdev->vendor == PCI_VENDOR_ID_INTEL) {
++		/*
++		 * Intel hardware supports auto clear of the interrupt
++		 * status register right after interrupt is being
++		 * issued.
++		 */
+ 		nhi->quirks |= QUIRK_AUTO_CLEAR_INT;
++
++		switch (nhi->pdev->device) {
++		case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI:
++		case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI:
++			/*
++			 * Falcon Ridge controller needs the end-to-end
++			 * flow control workaround to avoid losing Rx
++			 * packets when RING_FLAG_E2E is set.
++			 */
++			nhi->quirks |= QUIRK_E2E;
++			break;
++		}
++	}
+ }
+ 
+ static int nhi_check_iommu_pdev(struct pci_dev *pdev, void *data)
+diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
+index 77d7f07ca075f..e7851c9265382 100644
+--- a/drivers/thunderbolt/switch.c
++++ b/drivers/thunderbolt/switch.c
+@@ -2822,6 +2822,26 @@ static void tb_switch_credits_init(struct tb_switch *sw)
+ 		tb_sw_info(sw, "failed to determine preferred buffer allocation, using defaults\n");
+ }
+ 
++static int tb_switch_port_hotplug_enable(struct tb_switch *sw)
++{
++	struct tb_port *port;
++
++	if (tb_switch_is_icm(sw))
++		return 0;
++
++	tb_switch_for_each_port(sw, port) {
++		int res;
++
++		if (!port->cap_usb4)
++			continue;
++
++		res = usb4_port_hotplug_enable(port);
++		if (res)
++			return res;
++	}
++	return 0;
++}
++
+ /**
+  * tb_switch_add() - Add a switch to the domain
+  * @sw: Switch to add
+@@ -2891,6 +2911,10 @@ int tb_switch_add(struct tb_switch *sw)
+ 			return ret;
+ 	}
+ 
++	ret = tb_switch_port_hotplug_enable(sw);
++	if (ret)
++		return ret;
++
+ 	ret = device_add(&sw->dev);
+ 	if (ret) {
+ 		dev_err(&sw->dev, "failed to add device: %d\n", ret);
+diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
+index 5db76de40cc1c..332159f984fc5 100644
+--- a/drivers/thunderbolt/tb.h
++++ b/drivers/thunderbolt/tb.h
+@@ -1174,6 +1174,7 @@ int usb4_switch_add_ports(struct tb_switch *sw);
+ void usb4_switch_remove_ports(struct tb_switch *sw);
+ 
+ int usb4_port_unlock(struct tb_port *port);
++int usb4_port_hotplug_enable(struct tb_port *port);
+ int usb4_port_configure(struct tb_port *port);
+ void usb4_port_unconfigure(struct tb_port *port);
+ int usb4_port_configure_xdomain(struct tb_port *port);
+diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h
+index 1660541103883..bbe38b2d9057c 100644
+--- a/drivers/thunderbolt/tb_regs.h
++++ b/drivers/thunderbolt/tb_regs.h
+@@ -308,6 +308,7 @@ struct tb_regs_port_header {
+ #define ADP_CS_5				0x05
+ #define ADP_CS_5_LCA_MASK			GENMASK(28, 22)
+ #define ADP_CS_5_LCA_SHIFT			22
++#define ADP_CS_5_DHP				BIT(31)
+ 
+ /* TMU adapter registers */
+ #define TMU_ADP_CS_3				0x03
+diff --git a/drivers/thunderbolt/usb4.c b/drivers/thunderbolt/usb4.c
+index 3a2e7126db9dc..f0b5a8f1ed3a3 100644
+--- a/drivers/thunderbolt/usb4.c
++++ b/drivers/thunderbolt/usb4.c
+@@ -1046,6 +1046,26 @@ int usb4_port_unlock(struct tb_port *port)
+ 	return tb_port_write(port, &val, TB_CFG_PORT, ADP_CS_4, 1);
+ }
+ 
++/**
++ * usb4_port_hotplug_enable() - Enables hotplug for a port
++ * @port: USB4 port to operate on
++ *
++ * Enables hot plug events on a given port. This is only intended
++ * to be used on lane, DP-IN, and DP-OUT adapters.
++ */
++int usb4_port_hotplug_enable(struct tb_port *port)
++{
++	int ret;
++	u32 val;
++
++	ret = tb_port_read(port, &val, TB_CFG_PORT, ADP_CS_5, 1);
++	if (ret)
++		return ret;
++
++	val &= ~ADP_CS_5_DHP;
++	return tb_port_write(port, &val, TB_CFG_PORT, ADP_CS_5, 1);
++}
++
+ static int usb4_port_set_configured(struct tb_port *port, bool configured)
+ {
+ 	int ret;
+diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
+index 2e83e7367441c..94fbf0add2ce2 100644
+--- a/drivers/tty/serial/8250/8250_core.c
++++ b/drivers/tty/serial/8250/8250_core.c
+@@ -298,10 +298,9 @@ static void serial8250_backup_timeout(struct timer_list *t)
+ 		jiffies + uart_poll_timeout(&up->port) + HZ / 5);
+ }
+ 
+-static int univ8250_setup_irq(struct uart_8250_port *up)
++static void univ8250_setup_timer(struct uart_8250_port *up)
+ {
+ 	struct uart_port *port = &up->port;
+-	int retval = 0;
+ 
+ 	/*
+ 	 * The above check will only give an accurate result the first time
+@@ -322,10 +321,16 @@ static int univ8250_setup_irq(struct uart_8250_port *up)
+ 	 */
+ 	if (!port->irq)
+ 		mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
+-	else
+-		retval = serial_link_irq_chain(up);
++}
+ 
+-	return retval;
++static int univ8250_setup_irq(struct uart_8250_port *up)
++{
++	struct uart_port *port = &up->port;
++
++	if (port->irq)
++		return serial_link_irq_chain(up);
++
++	return 0;
+ }
+ 
+ static void univ8250_release_irq(struct uart_8250_port *up)
+@@ -381,6 +386,7 @@ static struct uart_ops univ8250_port_ops;
+ static const struct uart_8250_ops univ8250_driver_ops = {
+ 	.setup_irq	= univ8250_setup_irq,
+ 	.release_irq	= univ8250_release_irq,
++	.setup_timer	= univ8250_setup_timer,
+ };
+ 
+ static struct uart_8250_port serial8250_ports[UART_NR];
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
+index f7fbef83583c8..38ee3e42251af 100644
+--- a/drivers/tty/serial/8250/8250_omap.c
++++ b/drivers/tty/serial/8250/8250_omap.c
+@@ -342,6 +342,9 @@ static void omap8250_restore_regs(struct uart_8250_port *up)
+ 	omap8250_update_mdr1(up, priv);
+ 
+ 	up->port.ops->set_mctrl(&up->port, up->port.mctrl);
++
++	if (up->port.rs485.flags & SER_RS485_ENABLED)
++		serial8250_em485_stop_tx(up);
+ }
+ 
+ /*
+diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
+index 6f66dc2ebacc7..8e9f247590bd4 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -1232,6 +1232,10 @@ static void pci_oxsemi_tornado_set_mctrl(struct uart_port *port,
+ 	serial8250_do_set_mctrl(port, mctrl);
+ }
+ 
++/*
++ * We require EFR features for clock programming, so set UPF_FULL_PROBE
++ * for full probing regardless of CONFIG_SERIAL_8250_16550A_VARIANTS setting.
++ */
+ static int pci_oxsemi_tornado_setup(struct serial_private *priv,
+ 				    const struct pciserial_board *board,
+ 				    struct uart_8250_port *up, int idx)
+@@ -1239,6 +1243,7 @@ static int pci_oxsemi_tornado_setup(struct serial_private *priv,
+ 	struct pci_dev *dev = priv->dev;
+ 
+ 	if (pci_oxsemi_tornado_p(dev)) {
++		up->port.flags |= UPF_FULL_PROBE;
+ 		up->port.get_divisor = pci_oxsemi_tornado_get_divisor;
+ 		up->port.set_divisor = pci_oxsemi_tornado_set_divisor;
+ 		up->port.set_mctrl = pci_oxsemi_tornado_set_mctrl;
+@@ -1627,7 +1632,6 @@ static int pci_fintek_init(struct pci_dev *dev)
+ 	resource_size_t bar_data[3];
+ 	u8 config_base;
+ 	struct serial_private *priv = pci_get_drvdata(dev);
+-	struct uart_8250_port *port;
+ 
+ 	if (!(pci_resource_flags(dev, 5) & IORESOURCE_IO) ||
+ 			!(pci_resource_flags(dev, 4) & IORESOURCE_IO) ||
+@@ -1674,13 +1678,7 @@ static int pci_fintek_init(struct pci_dev *dev)
+ 
+ 		pci_write_config_byte(dev, config_base + 0x06, dev->irq);
+ 
+-		if (priv) {
+-			/* re-apply RS232/485 mode when
+-			 * pciserial_resume_ports()
+-			 */
+-			port = serial8250_get_port(priv->line[i]);
+-			uart_rs485_config(&port->port);
+-		} else {
++		if (!priv) {
+ 			/* First init without port data
+ 			 * force init to RS232 Mode
+ 			 */
+diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
+index 39b35a61958c0..2030a92ac66e7 100644
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -600,7 +600,7 @@ EXPORT_SYMBOL_GPL(serial8250_rpm_put);
+ static int serial8250_em485_init(struct uart_8250_port *p)
+ {
+ 	if (p->em485)
+-		return 0;
++		goto deassert_rts;
+ 
+ 	p->em485 = kmalloc(sizeof(struct uart_8250_em485), GFP_ATOMIC);
+ 	if (!p->em485)
+@@ -616,7 +616,9 @@ static int serial8250_em485_init(struct uart_8250_port *p)
+ 	p->em485->active_timer = NULL;
+ 	p->em485->tx_stopped = true;
+ 
+-	p->rs485_stop_tx(p);
++deassert_rts:
++	if (p->em485->tx_stopped)
++		p->rs485_stop_tx(p);
+ 
+ 	return 0;
+ }
+@@ -1021,7 +1023,8 @@ static void autoconfig_16550a(struct uart_8250_port *up)
+ 	up->port.type = PORT_16550A;
+ 	up->capabilities |= UART_CAP_FIFO;
+ 
+-	if (!IS_ENABLED(CONFIG_SERIAL_8250_16550A_VARIANTS))
++	if (!IS_ENABLED(CONFIG_SERIAL_8250_16550A_VARIANTS) &&
++	    !(up->port.flags & UPF_FULL_PROBE))
+ 		return;
+ 
+ 	/*
+@@ -2042,6 +2045,9 @@ EXPORT_SYMBOL_GPL(serial8250_do_set_mctrl);
+ 
+ static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ {
++	if (port->rs485.flags & SER_RS485_ENABLED)
++		return;
++
+ 	if (port->set_mctrl)
+ 		port->set_mctrl(port, mctrl);
+ 	else
+@@ -2294,6 +2300,10 @@ int serial8250_do_startup(struct uart_port *port)
+ 	if (port->irq && (up->port.flags & UPF_SHARE_IRQ))
+ 		up->port.irqflags |= IRQF_SHARED;
+ 
++	retval = up->ops->setup_irq(up);
++	if (retval)
++		goto out;
++
+ 	if (port->irq && !(up->port.flags & UPF_NO_THRE_TEST)) {
+ 		unsigned char iir1;
+ 
+@@ -2336,9 +2346,7 @@ int serial8250_do_startup(struct uart_port *port)
+ 		}
+ 	}
+ 
+-	retval = up->ops->setup_irq(up);
+-	if (retval)
+-		goto out;
++	up->ops->setup_timer(up);
+ 
+ 	/*
+ 	 * Now, initialize the UART
+@@ -3187,9 +3195,6 @@ static void serial8250_config_port(struct uart_port *port, int flags)
+ 	if (flags & UART_CONFIG_TYPE)
+ 		autoconfig(up);
+ 
+-	if (port->rs485.flags & SER_RS485_ENABLED)
+-		uart_rs485_config(port);
+-
+ 	/* if access method is AU, it is a 16550 with a quirk */
+ 	if (port->type == PORT_16550A && port->iotype == UPIO_AU)
+ 		up->bugs |= UART_BUG_NOMSR;
+@@ -3314,8 +3319,13 @@ static void serial8250_console_restore(struct uart_8250_port *up)
+ 	unsigned int baud, quot, frac = 0;
+ 
+ 	termios.c_cflag = port->cons->cflag;
+-	if (port->state->port.tty && termios.c_cflag == 0)
++	termios.c_ispeed = port->cons->ispeed;
++	termios.c_ospeed = port->cons->ospeed;
++	if (port->state->port.tty && termios.c_cflag == 0) {
+ 		termios.c_cflag = port->state->port.tty->termios.c_cflag;
++		termios.c_ispeed = port->state->port.tty->termios.c_ispeed;
++		termios.c_ospeed = port->state->port.tty->termios.c_ospeed;
++	}
+ 
+ 	baud = serial8250_get_baud_rate(port, &termios, NULL);
+ 	quot = serial8250_get_divisor(port, baud, &frac);
+diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c
+index 32caeac129858..a4ce0b63aabdf 100644
+--- a/drivers/tty/serial/ar933x_uart.c
++++ b/drivers/tty/serial/ar933x_uart.c
+@@ -583,6 +583,13 @@ static const struct uart_ops ar933x_uart_ops = {
+ static int ar933x_config_rs485(struct uart_port *port, struct ktermios *termios,
+ 				struct serial_rs485 *rs485conf)
+ {
++	struct ar933x_uart_port *up =
++			container_of(port, struct ar933x_uart_port, port);
++
++	if (port->rs485.flags & SER_RS485_ENABLED)
++		gpiod_set_value(up->rts_gpiod,
++			!!(rs485conf->flags & SER_RS485_RTS_AFTER_SEND));
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
+index db07d6a5d764d..fa5c4633086e6 100644
+--- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c
++++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c
+@@ -1214,12 +1214,6 @@ static int cpm_uart_init_port(struct device_node *np,
+ 	pinfo->port.fifosize = pinfo->tx_nrfifos * pinfo->tx_fifosize;
+ 	spin_lock_init(&pinfo->port.lock);
+ 
+-	pinfo->port.irq = irq_of_parse_and_map(np, 0);
+-	if (pinfo->port.irq == NO_IRQ) {
+-		ret = -EINVAL;
+-		goto out_pram;
+-	}
+-
+ 	for (i = 0; i < NUM_GPIOS; i++) {
+ 		struct gpio_desc *gpiod;
+ 
+@@ -1229,7 +1223,7 @@ static int cpm_uart_init_port(struct device_node *np,
+ 
+ 		if (IS_ERR(gpiod)) {
+ 			ret = PTR_ERR(gpiod);
+-			goto out_irq;
++			goto out_pram;
+ 		}
+ 
+ 		if (gpiod) {
+@@ -1255,8 +1249,6 @@ static int cpm_uart_init_port(struct device_node *np,
+ 
+ 	return cpm_uart_request_port(&pinfo->port);
+ 
+-out_irq:
+-	irq_dispose_mapping(pinfo->port.irq);
+ out_pram:
+ 	cpm_uart_unmap_pram(pinfo, pram);
+ out_mem:
+@@ -1436,11 +1428,17 @@ static int cpm_uart_probe(struct platform_device *ofdev)
+ 	/* initialize the device pointer for the port */
+ 	pinfo->port.dev = &ofdev->dev;
+ 
++	pinfo->port.irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
++	if (!pinfo->port.irq)
++		return -EINVAL;
++
+ 	ret = cpm_uart_init_port(ofdev->dev.of_node, pinfo);
+-	if (ret)
+-		return ret;
++	if (!ret)
++		return uart_add_one_port(&cpm_reg, &pinfo->port);
+ 
+-	return uart_add_one_port(&cpm_reg, &pinfo->port);
++	irq_dispose_mapping(pinfo->port.irq);
++
++	return ret;
+ }
+ 
+ static int cpm_uart_remove(struct platform_device *ofdev)
+diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
+index fbc4b071b3309..34990901c805e 100644
+--- a/drivers/tty/serial/fsl_lpuart.c
++++ b/drivers/tty/serial/fsl_lpuart.c
+@@ -1776,6 +1776,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport)
+ 	if (sport->lpuart_dma_rx_use) {
+ 		del_timer_sync(&sport->lpuart_timer);
+ 		lpuart_dma_rx_free(&sport->port);
++		sport->lpuart_dma_rx_use = false;
+ 	}
+ 
+ 	if (sport->lpuart_dma_tx_use) {
+@@ -1784,6 +1785,7 @@ static void lpuart_dma_shutdown(struct lpuart_port *sport)
+ 			sport->dma_tx_in_progress = false;
+ 			dmaengine_terminate_all(sport->dma_tx_chan);
+ 		}
++		sport->lpuart_dma_tx_use = false;
+ 	}
+ 
+ 	if (sport->dma_tx_chan)
+@@ -2729,15 +2731,13 @@ static int lpuart_probe(struct platform_device *pdev)
+ 	if (ret)
+ 		goto failed_reset;
+ 
+-	ret = uart_add_one_port(&lpuart_reg, &sport->port);
+-	if (ret)
+-		goto failed_attach_port;
+-
+ 	ret = uart_get_rs485_mode(&sport->port);
+ 	if (ret)
+ 		goto failed_get_rs485;
+ 
+-	uart_rs485_config(&sport->port);
++	ret = uart_add_one_port(&lpuart_reg, &sport->port);
++	if (ret)
++		goto failed_attach_port;
+ 
+ 	ret = devm_request_irq(&pdev->dev, sport->port.irq, handler, 0,
+ 				DRIVER_NAME, sport);
+@@ -2747,9 +2747,9 @@ static int lpuart_probe(struct platform_device *pdev)
+ 	return 0;
+ 
+ failed_irq_request:
+-failed_get_rs485:
+ 	uart_remove_one_port(&lpuart_reg, &sport->port);
+ failed_attach_port:
++failed_get_rs485:
+ failed_reset:
+ 	lpuart_disable_clks(sport);
+ 	return ret;
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index 522445a8f666e..278b4033a3cce 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -380,8 +380,7 @@ static void imx_uart_rts_active(struct imx_port *sport, u32 *ucr2)
+ {
+ 	*ucr2 &= ~(UCR2_CTSC | UCR2_CTS);
+ 
+-	sport->port.mctrl |= TIOCM_RTS;
+-	mctrl_gpio_set(sport->gpios, sport->port.mctrl);
++	mctrl_gpio_set(sport->gpios, sport->port.mctrl | TIOCM_RTS);
+ }
+ 
+ /* called with port.lock taken and irqs caller dependent */
+@@ -390,8 +389,7 @@ static void imx_uart_rts_inactive(struct imx_port *sport, u32 *ucr2)
+ 	*ucr2 &= ~UCR2_CTSC;
+ 	*ucr2 |= UCR2_CTS;
+ 
+-	sport->port.mctrl &= ~TIOCM_RTS;
+-	mctrl_gpio_set(sport->gpios, sport->port.mctrl);
++	mctrl_gpio_set(sport->gpios, sport->port.mctrl & ~TIOCM_RTS);
+ }
+ 
+ static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec)
+@@ -2347,8 +2345,6 @@ static int imx_uart_probe(struct platform_device *pdev)
+ 		dev_err(&pdev->dev,
+ 			"low-active RTS not possible when receiver is off, enabling receiver\n");
+ 
+-	uart_rs485_config(&sport->port);
+-
+ 	/* Disable interrupts before requesting them */
+ 	ucr1 = imx_uart_readl(sport, UCR1);
+ 	ucr1 &= ~(UCR1_ADEN | UCR1_TRDYEN | UCR1_IDEN | UCR1_RRDYEN | UCR1_RTSDEN);
+diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c
+index 0ea799bf8dbb1..417a5b6bffc34 100644
+--- a/drivers/tty/serial/jsm/jsm_driver.c
++++ b/drivers/tty/serial/jsm/jsm_driver.c
+@@ -211,7 +211,8 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 
+ 		break;
+ 	default:
+-		return -ENXIO;
++		rc = -ENXIO;
++		goto out_kfree_brd;
+ 	}
+ 
+ 	rc = request_irq(brd->irq, brd->bd_ops->intr, IRQF_SHARED, "JSM", brd);
+diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
+index 12c87cd201a76..74b2784b8b5df 100644
+--- a/drivers/tty/serial/serial_core.c
++++ b/drivers/tty/serial/serial_core.c
+@@ -158,15 +158,10 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
+ 	unsigned long flags;
+ 	unsigned int old;
+ 
+-	if (port->rs485.flags & SER_RS485_ENABLED) {
+-		set &= ~TIOCM_RTS;
+-		clear &= ~TIOCM_RTS;
+-	}
+-
+ 	spin_lock_irqsave(&port->lock, flags);
+ 	old = port->mctrl;
+ 	port->mctrl = (old & ~clear) | set;
+-	if (old != port->mctrl)
++	if (old != port->mctrl && !(port->rs485.flags & SER_RS485_ENABLED))
+ 		port->ops->set_mctrl(port, port->mctrl);
+ 	spin_unlock_irqrestore(&port->lock, flags);
+ }
+@@ -1391,7 +1386,7 @@ static void uart_set_rs485_termination(struct uart_port *port,
+ 				 !!(rs485->flags & SER_RS485_TERMINATE_BUS));
+ }
+ 
+-int uart_rs485_config(struct uart_port *port)
++static int uart_rs485_config(struct uart_port *port)
+ {
+ 	struct serial_rs485 *rs485 = &port->rs485;
+ 	int ret;
+@@ -1405,7 +1400,6 @@ int uart_rs485_config(struct uart_port *port)
+ 
+ 	return ret;
+ }
+-EXPORT_SYMBOL_GPL(uart_rs485_config);
+ 
+ static int uart_get_rs485_config(struct uart_port *port,
+ 			 struct serial_rs485 __user *rs485)
+@@ -1444,8 +1438,13 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port,
+ 
+ 	spin_lock_irqsave(&port->lock, flags);
+ 	ret = port->rs485_config(port, &tty->termios, &rs485);
+-	if (!ret)
++	if (!ret) {
+ 		port->rs485 = rs485;
++
++		/* Reset RTS and other mctrl lines when disabling RS485 */
++		if (!(rs485.flags & SER_RS485_ENABLED))
++			port->ops->set_mctrl(port, port->mctrl);
++	}
+ 	spin_unlock_irqrestore(&port->lock, flags);
+ 	if (ret)
+ 		return ret;
+@@ -2352,7 +2351,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
+ 
+ 		spin_lock_irq(&uport->lock);
+ 		ops->stop_tx(uport);
+-		ops->set_mctrl(uport, 0);
++		if (!(uport->rs485.flags & SER_RS485_ENABLED))
++			ops->set_mctrl(uport, 0);
+ 		/* save mctrl so it can be restored on resume */
+ 		mctrl = uport->mctrl;
+ 		uport->mctrl = 0;
+@@ -2440,7 +2440,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
+ 
+ 		uart_change_pm(state, UART_PM_STATE_ON);
+ 		spin_lock_irq(&uport->lock);
+-		ops->set_mctrl(uport, 0);
++		if (!(uport->rs485.flags & SER_RS485_ENABLED))
++			ops->set_mctrl(uport, 0);
+ 		spin_unlock_irq(&uport->lock);
+ 		if (console_suspend_enabled || !uart_console(uport)) {
+ 			/* Protected by port mutex for now */
+@@ -2451,7 +2452,10 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
+ 				if (tty)
+ 					uart_change_speed(tty, state, NULL);
+ 				spin_lock_irq(&uport->lock);
+-				ops->set_mctrl(uport, uport->mctrl);
++				if (!(uport->rs485.flags & SER_RS485_ENABLED))
++					ops->set_mctrl(uport, uport->mctrl);
++				else
++					uart_rs485_config(uport);
+ 				ops->start_tx(uport);
+ 				spin_unlock_irq(&uport->lock);
+ 				tty_port_set_initialized(port, 1);
+@@ -2558,10 +2562,10 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
+ 		 */
+ 		spin_lock_irqsave(&port->lock, flags);
+ 		port->mctrl &= TIOCM_DTR;
+-		if (port->rs485.flags & SER_RS485_ENABLED &&
+-		    !(port->rs485.flags & SER_RS485_RTS_AFTER_SEND))
+-			port->mctrl |= TIOCM_RTS;
+-		port->ops->set_mctrl(port, port->mctrl);
++		if (!(port->rs485.flags & SER_RS485_ENABLED))
++			port->ops->set_mctrl(port, port->mctrl);
++		else
++			uart_rs485_config(port);
+ 		spin_unlock_irqrestore(&port->lock, flags);
+ 
+ 		/*
+diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
+index 2c85dbf165c4a..9a875558f5ef6 100644
+--- a/drivers/tty/serial/stm32-usart.c
++++ b/drivers/tty/serial/stm32-usart.c
+@@ -131,6 +131,53 @@ static void stm32_usart_clr_bits(struct uart_port *port, u32 reg, u32 bits)
+ 	writel_relaxed(val, port->membase + reg);
+ }
+ 
++static unsigned int stm32_usart_tx_empty(struct uart_port *port)
++{
++	struct stm32_port *stm32_port = to_stm32_port(port);
++	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
++
++	if (readl_relaxed(port->membase + ofs->isr) & USART_SR_TC)
++		return TIOCSER_TEMT;
++
++	return 0;
++}
++
++static void stm32_usart_rs485_rts_enable(struct uart_port *port)
++{
++	struct stm32_port *stm32_port = to_stm32_port(port);
++	struct serial_rs485 *rs485conf = &port->rs485;
++
++	if (stm32_port->hw_flow_control ||
++	    !(rs485conf->flags & SER_RS485_ENABLED))
++		return;
++
++	if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
++		mctrl_gpio_set(stm32_port->gpios,
++			       stm32_port->port.mctrl | TIOCM_RTS);
++	} else {
++		mctrl_gpio_set(stm32_port->gpios,
++			       stm32_port->port.mctrl & ~TIOCM_RTS);
++	}
++}
++
++static void stm32_usart_rs485_rts_disable(struct uart_port *port)
++{
++	struct stm32_port *stm32_port = to_stm32_port(port);
++	struct serial_rs485 *rs485conf = &port->rs485;
++
++	if (stm32_port->hw_flow_control ||
++	    !(rs485conf->flags & SER_RS485_ENABLED))
++		return;
++
++	if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
++		mctrl_gpio_set(stm32_port->gpios,
++			       stm32_port->port.mctrl & ~TIOCM_RTS);
++	} else {
++		mctrl_gpio_set(stm32_port->gpios,
++			       stm32_port->port.mctrl | TIOCM_RTS);
++	}
++}
++
+ static void stm32_usart_config_reg_rs485(u32 *cr1, u32 *cr3, u32 delay_ADE,
+ 					 u32 delay_DDE, u32 baud)
+ {
+@@ -214,6 +261,12 @@ static int stm32_usart_config_rs485(struct uart_port *port, struct ktermios *ter
+ 
+ 	stm32_usart_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit));
+ 
++	/* Adjust RTS polarity in case it's driven in software */
++	if (stm32_usart_tx_empty(port))
++		stm32_usart_rs485_rts_disable(port);
++	else
++		stm32_usart_rs485_rts_enable(port);
++
+ 	return 0;
+ }
+ 
+@@ -529,42 +582,6 @@ static void stm32_usart_tc_interrupt_disable(struct uart_port *port)
+ 	stm32_usart_clr_bits(port, ofs->cr1, USART_CR1_TCIE);
+ }
+ 
+-static void stm32_usart_rs485_rts_enable(struct uart_port *port)
+-{
+-	struct stm32_port *stm32_port = to_stm32_port(port);
+-	struct serial_rs485 *rs485conf = &port->rs485;
+-
+-	if (stm32_port->hw_flow_control ||
+-	    !(rs485conf->flags & SER_RS485_ENABLED))
+-		return;
+-
+-	if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
+-		mctrl_gpio_set(stm32_port->gpios,
+-			       stm32_port->port.mctrl | TIOCM_RTS);
+-	} else {
+-		mctrl_gpio_set(stm32_port->gpios,
+-			       stm32_port->port.mctrl & ~TIOCM_RTS);
+-	}
+-}
+-
+-static void stm32_usart_rs485_rts_disable(struct uart_port *port)
+-{
+-	struct stm32_port *stm32_port = to_stm32_port(port);
+-	struct serial_rs485 *rs485conf = &port->rs485;
+-
+-	if (stm32_port->hw_flow_control ||
+-	    !(rs485conf->flags & SER_RS485_ENABLED))
+-		return;
+-
+-	if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
+-		mctrl_gpio_set(stm32_port->gpios,
+-			       stm32_port->port.mctrl & ~TIOCM_RTS);
+-	} else {
+-		mctrl_gpio_set(stm32_port->gpios,
+-			       stm32_port->port.mctrl | TIOCM_RTS);
+-	}
+-}
+-
+ static void stm32_usart_transmit_chars_pio(struct uart_port *port)
+ {
+ 	struct stm32_port *stm32_port = to_stm32_port(port);
+@@ -807,17 +824,6 @@ static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr)
+ 	return IRQ_HANDLED;
+ }
+ 
+-static unsigned int stm32_usart_tx_empty(struct uart_port *port)
+-{
+-	struct stm32_port *stm32_port = to_stm32_port(port);
+-	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+-
+-	if (readl_relaxed(port->membase + ofs->isr) & USART_SR_TC)
+-		return TIOCSER_TEMT;
+-
+-	return 0;
+-}
+-
+ static void stm32_usart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ {
+ 	struct stm32_port *stm32_port = to_stm32_port(port);
+diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
+index 9e01fe6c0ab8c..769044dfe990a 100644
+--- a/drivers/tty/serial/xilinx_uartps.c
++++ b/drivers/tty/serial/xilinx_uartps.c
+@@ -361,6 +361,8 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
+ 		isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
+ 	}
+ 
++	isrstatus &= port->read_status_mask;
++	isrstatus &= ~port->ignore_status_mask;
+ 	/*
+ 	 * Skip RX processing if RX is disabled as RXEMPTY will never be set
+ 	 * as read bytes will not be removed from the FIFO.
+@@ -1329,12 +1331,20 @@ static int cdns_uart_resume(struct device *device)
+ 	unsigned long flags;
+ 	u32 ctrl_reg;
+ 	int may_wake;
++	int ret;
+ 
+ 	may_wake = device_may_wakeup(device);
+ 
+ 	if (console_suspend_enabled && uart_console(port) && !may_wake) {
+-		clk_enable(cdns_uart->pclk);
+-		clk_enable(cdns_uart->uartclk);
++		ret = clk_enable(cdns_uart->pclk);
++		if (ret)
++			return ret;
++
++		ret = clk_enable(cdns_uart->uartclk);
++		if (ret) {
++			clk_disable(cdns_uart->pclk);
++			return ret;
++		}
+ 
+ 		spin_lock_irqsave(&port->lock, flags);
+ 
+diff --git a/drivers/usb/common/debug.c b/drivers/usb/common/debug.c
+index 075f6b1b2a1a1..f204cec8d380a 100644
+--- a/drivers/usb/common/debug.c
++++ b/drivers/usb/common/debug.c
+@@ -208,30 +208,28 @@ static void usb_decode_set_isoch_delay(__u8 wValue, char *str, size_t size)
+ 	snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", wValue);
+ }
+ 
+-/**
+- * usb_decode_ctrl - Returns human readable representation of control request.
+- * @str: buffer to return a human-readable representation of control request.
+- *       This buffer should have about 200 bytes.
+- * @size: size of str buffer.
+- * @bRequestType: matches the USB bmRequestType field
+- * @bRequest: matches the USB bRequest field
+- * @wValue: matches the USB wValue field (CPU byte order)
+- * @wIndex: matches the USB wIndex field (CPU byte order)
+- * @wLength: matches the USB wLength field (CPU byte order)
+- *
+- * Function returns decoded, formatted and human-readable description of
+- * control request packet.
+- *
+- * The usage scenario for this is for tracepoints, so function as a return
+- * use the same value as in parameters. This approach allows to use this
+- * function in TP_printk
+- *
+- * Important: wValue, wIndex, wLength parameters before invoking this function
+- * should be processed by le16_to_cpu macro.
+- */
+-const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
+-			    __u8 bRequest, __u16 wValue, __u16 wIndex,
+-			    __u16 wLength)
++static void usb_decode_ctrl_generic(char *str, size_t size, __u8 bRequestType,
++				    __u8 bRequest, __u16 wValue, __u16 wIndex,
++				    __u16 wLength)
++{
++	u8 recip = bRequestType & USB_RECIP_MASK;
++	u8 type = bRequestType & USB_TYPE_MASK;
++
++	snprintf(str, size,
++		 "Type=%s Recipient=%s Dir=%s bRequest=%u wValue=%u wIndex=%u wLength=%u",
++		 (type == USB_TYPE_STANDARD)    ? "Standard" :
++		 (type == USB_TYPE_VENDOR)      ? "Vendor" :
++		 (type == USB_TYPE_CLASS)       ? "Class" : "Unknown",
++		 (recip == USB_RECIP_DEVICE)    ? "Device" :
++		 (recip == USB_RECIP_INTERFACE) ? "Interface" :
++		 (recip == USB_RECIP_ENDPOINT)  ? "Endpoint" : "Unknown",
++		 (bRequestType & USB_DIR_IN)    ? "IN" : "OUT",
++		 bRequest, wValue, wIndex, wLength);
++}
++
++static void usb_decode_ctrl_standard(char *str, size_t size, __u8 bRequestType,
++				     __u8 bRequest, __u16 wValue, __u16 wIndex,
++				     __u16 wLength)
+ {
+ 	switch (bRequest) {
+ 	case USB_REQ_GET_STATUS:
+@@ -272,14 +270,48 @@ const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
+ 		usb_decode_set_isoch_delay(wValue, str, size);
+ 		break;
+ 	default:
+-		snprintf(str, size, "%02x %02x %02x %02x %02x %02x %02x %02x",
+-			 bRequestType, bRequest,
+-			 (u8)(cpu_to_le16(wValue) & 0xff),
+-			 (u8)(cpu_to_le16(wValue) >> 8),
+-			 (u8)(cpu_to_le16(wIndex) & 0xff),
+-			 (u8)(cpu_to_le16(wIndex) >> 8),
+-			 (u8)(cpu_to_le16(wLength) & 0xff),
+-			 (u8)(cpu_to_le16(wLength) >> 8));
++		usb_decode_ctrl_generic(str, size, bRequestType, bRequest,
++					wValue, wIndex, wLength);
++		break;
++	}
++}
++
++/**
++ * usb_decode_ctrl - Returns human readable representation of control request.
++ * @str: buffer to return a human-readable representation of control request.
++ *       This buffer should have about 200 bytes.
++ * @size: size of str buffer.
++ * @bRequestType: matches the USB bmRequestType field
++ * @bRequest: matches the USB bRequest field
++ * @wValue: matches the USB wValue field (CPU byte order)
++ * @wIndex: matches the USB wIndex field (CPU byte order)
++ * @wLength: matches the USB wLength field (CPU byte order)
++ *
++ * Function returns decoded, formatted and human-readable description of
++ * control request packet.
++ *
++ * The usage scenario for this is for tracepoints, so function as a return
++ * use the same value as in parameters. This approach allows to use this
++ * function in TP_printk
++ *
++ * Important: wValue, wIndex, wLength parameters before invoking this function
++ * should be processed by le16_to_cpu macro.
++ */
++const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
++			    __u8 bRequest, __u16 wValue, __u16 wIndex,
++			    __u16 wLength)
++{
++	switch (bRequestType & USB_TYPE_MASK) {
++	case USB_TYPE_STANDARD:
++		usb_decode_ctrl_standard(str, size, bRequestType, bRequest,
++					 wValue, wIndex, wLength);
++		break;
++	case USB_TYPE_VENDOR:
++	case USB_TYPE_CLASS:
++	default:
++		usb_decode_ctrl_generic(str, size, bRequestType, bRequest,
++					wValue, wIndex, wLength);
++		break;
+ 	}
+ 
+ 	return str;
+diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c
+index b39c9f1c375d6..e20874caba363 100644
+--- a/drivers/usb/common/usb-conn-gpio.c
++++ b/drivers/usb/common/usb-conn-gpio.c
+@@ -208,10 +208,8 @@ static int usb_conn_probe(struct platform_device *pdev)
+ 	if (PTR_ERR(info->vbus) == -ENODEV)
+ 		info->vbus = NULL;
+ 
+-	if (IS_ERR(info->vbus)) {
+-		ret = PTR_ERR(info->vbus);
+-		return dev_err_probe(dev, ret, "failed to get vbus :%d\n", ret);
+-	}
++	if (IS_ERR(info->vbus))
++		return dev_err_probe(dev, PTR_ERR(info->vbus), "failed to get vbus\n");
+ 
+ 	info->role_sw = usb_role_switch_get(dev);
+ 	if (IS_ERR(info->role_sw))
+diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
+index f99a65a64588f..999b7c9697fcd 100644
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -437,6 +437,10 @@ static const struct usb_device_id usb_quirk_list[] = {
+ 	{ USB_DEVICE(0x1532, 0x0116), .driver_info =
+ 			USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+ 
++	/* Lenovo ThinkPad OneLink+ Dock twin hub controllers (VIA Labs VL812) */
++	{ USB_DEVICE(0x17ef, 0x1018), .driver_info = USB_QUIRK_RESET_RESUME },
++	{ USB_DEVICE(0x17ef, 0x1019), .driver_info = USB_QUIRK_RESET_RESUME },
++
+ 	/* Lenovo USB-C to Ethernet Adapter RTL8153-04 */
+ 	{ USB_DEVICE(0x17ef, 0x720c), .driver_info = USB_QUIRK_NO_LPM },
+ 
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 219d797e22301..68d986361c495 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -407,6 +407,10 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc)
+ 	reg |= FIELD_PREP(DWC3_GFLADJ_REFCLK_FLADJ_MASK, fladj)
+ 	    |  FIELD_PREP(DWC3_GFLADJ_240MHZDECR, decr >> 1)
+ 	    |  FIELD_PREP(DWC3_GFLADJ_240MHZDECR_PLS1, decr & 1);
++
++	if (dwc->gfladj_refclk_lpm_sel)
++		reg |=  DWC3_GFLADJ_REFCLK_LPM_SEL;
++
+ 	dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
+ }
+ 
+@@ -788,7 +792,7 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
+ 	else
+ 		reg |= DWC3_GUSB2PHYCFG_ENBLSLPM;
+ 
+-	if (dwc->dis_u2_freeclk_exists_quirk)
++	if (dwc->dis_u2_freeclk_exists_quirk || dwc->gfladj_refclk_lpm_sel)
+ 		reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
+ 
+ 	dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+@@ -1179,6 +1183,21 @@ static int dwc3_core_init(struct dwc3 *dwc)
+ 		dwc3_writel(dwc->regs, DWC3_GUCTL2, reg);
+ 	}
+ 
++	/*
++	 * When configured in HOST mode, after issuing U3/L2 exit controller
++	 * fails to send proper CRC checksum in CRC5 feild. Because of this
++	 * behaviour Transaction Error is generated, resulting in reset and
++	 * re-enumeration of usb device attached. All the termsel, xcvrsel,
++	 * opmode becomes 0 during end of resume. Enabling bit 10 of GUCTL1
++	 * will correct this problem. This option is to support certain
++	 * legacy ULPI PHYs.
++	 */
++	if (dwc->resume_hs_terminations) {
++		reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
++		reg |= DWC3_GUCTL1_RESUME_OPMODE_HS_HOST;
++		dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
++	}
++
+ 	if (!DWC3_VER_IS_PRIOR(DWC3, 250A)) {
+ 		reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+ 
+@@ -1522,8 +1541,12 @@ static void dwc3_get_properties(struct dwc3 *dwc)
+ 				"snps,dis-del-phy-power-chg-quirk");
+ 	dwc->dis_tx_ipgap_linecheck_quirk = device_property_read_bool(dev,
+ 				"snps,dis-tx-ipgap-linecheck-quirk");
++	dwc->resume_hs_terminations = device_property_read_bool(dev,
++				"snps,resume-hs-terminations");
+ 	dwc->parkmode_disable_ss_quirk = device_property_read_bool(dev,
+ 				"snps,parkmode-disable-ss-quirk");
++	dwc->gfladj_refclk_lpm_sel = device_property_read_bool(dev,
++				"snps,gfladj-refclk-lpm-sel-quirk");
+ 
+ 	dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
+ 				"snps,tx_de_emphasis_quirk");
+@@ -1712,8 +1735,10 @@ static int dwc3_probe(struct platform_device *pdev)
+ 	dwc3_get_properties(dwc);
+ 
+ 	dwc->reset = devm_reset_control_array_get_optional_shared(dev);
+-	if (IS_ERR(dwc->reset))
+-		return PTR_ERR(dwc->reset);
++	if (IS_ERR(dwc->reset)) {
++		ret = PTR_ERR(dwc->reset);
++		goto put_usb_psy;
++	}
+ 
+ 	if (dev->of_node) {
+ 		/*
+@@ -1723,45 +1748,57 @@ static int dwc3_probe(struct platform_device *pdev)
+ 		 * check for them to retain backwards compatibility.
+ 		 */
+ 		dwc->bus_clk = devm_clk_get_optional(dev, "bus_early");
+-		if (IS_ERR(dwc->bus_clk))
+-			return dev_err_probe(dev, PTR_ERR(dwc->bus_clk),
+-					     "could not get bus clock\n");
++		if (IS_ERR(dwc->bus_clk)) {
++			ret = dev_err_probe(dev, PTR_ERR(dwc->bus_clk),
++					    "could not get bus clock\n");
++			goto put_usb_psy;
++		}
+ 
+ 		if (dwc->bus_clk == NULL) {
+ 			dwc->bus_clk = devm_clk_get_optional(dev, "bus_clk");
+-			if (IS_ERR(dwc->bus_clk))
+-				return dev_err_probe(dev, PTR_ERR(dwc->bus_clk),
+-						     "could not get bus clock\n");
++			if (IS_ERR(dwc->bus_clk)) {
++				ret = dev_err_probe(dev, PTR_ERR(dwc->bus_clk),
++						    "could not get bus clock\n");
++				goto put_usb_psy;
++			}
+ 		}
+ 
+ 		dwc->ref_clk = devm_clk_get_optional(dev, "ref");
+-		if (IS_ERR(dwc->ref_clk))
+-			return dev_err_probe(dev, PTR_ERR(dwc->ref_clk),
+-					     "could not get ref clock\n");
++		if (IS_ERR(dwc->ref_clk)) {
++			ret = dev_err_probe(dev, PTR_ERR(dwc->ref_clk),
++					    "could not get ref clock\n");
++			goto put_usb_psy;
++		}
+ 
+ 		if (dwc->ref_clk == NULL) {
+ 			dwc->ref_clk = devm_clk_get_optional(dev, "ref_clk");
+-			if (IS_ERR(dwc->ref_clk))
+-				return dev_err_probe(dev, PTR_ERR(dwc->ref_clk),
+-						     "could not get ref clock\n");
++			if (IS_ERR(dwc->ref_clk)) {
++				ret = dev_err_probe(dev, PTR_ERR(dwc->ref_clk),
++						    "could not get ref clock\n");
++				goto put_usb_psy;
++			}
+ 		}
+ 
+ 		dwc->susp_clk = devm_clk_get_optional(dev, "suspend");
+-		if (IS_ERR(dwc->susp_clk))
+-			return dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
+-					     "could not get suspend clock\n");
++		if (IS_ERR(dwc->susp_clk)) {
++			ret = dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
++					    "could not get suspend clock\n");
++			goto put_usb_psy;
++		}
+ 
+ 		if (dwc->susp_clk == NULL) {
+ 			dwc->susp_clk = devm_clk_get_optional(dev, "suspend_clk");
+-			if (IS_ERR(dwc->susp_clk))
+-				return dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
+-						     "could not get suspend clock\n");
++			if (IS_ERR(dwc->susp_clk)) {
++				ret = dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
++						    "could not get suspend clock\n");
++				goto put_usb_psy;
++			}
+ 		}
+ 	}
+ 
+ 	ret = reset_control_deassert(dwc->reset);
+ 	if (ret)
+-		return ret;
++		goto put_usb_psy;
+ 
+ 	ret = dwc3_clk_enable(dwc);
+ 	if (ret)
+@@ -1861,7 +1898,7 @@ disable_clks:
+ 	dwc3_clk_disable(dwc);
+ assert_reset:
+ 	reset_control_assert(dwc->reset);
+-
++put_usb_psy:
+ 	if (dwc->usb_psy)
+ 		power_supply_put(dwc->usb_psy);
+ 
+diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index 4fe4287dc934e..3ac9313e66f94 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -263,6 +263,7 @@
+ #define DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK	BIT(26)
+ #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW		BIT(24)
+ #define DWC3_GUCTL1_PARKMODE_DISABLE_SS		BIT(17)
++#define DWC3_GUCTL1_RESUME_OPMODE_HS_HOST	BIT(10)
+ 
+ /* Global Status Register */
+ #define DWC3_GSTS_OTG_IP	BIT(10)
+@@ -391,6 +392,7 @@
+ #define DWC3_GFLADJ_30MHZ_SDBND_SEL		BIT(7)
+ #define DWC3_GFLADJ_30MHZ_MASK			0x3f
+ #define DWC3_GFLADJ_REFCLK_FLADJ_MASK		GENMASK(21, 8)
++#define DWC3_GFLADJ_REFCLK_LPM_SEL		BIT(23)
+ #define DWC3_GFLADJ_240MHZDECR			GENMASK(30, 24)
+ #define DWC3_GFLADJ_240MHZDECR_PLS1		BIT(31)
+ 
+@@ -1096,6 +1098,8 @@ struct dwc3_scratchpad_array {
+  *			change quirk.
+  * @dis_tx_ipgap_linecheck_quirk: set if we disable u2mac linestate
+  *			check during HS transmit.
++ * @resume-hs-terminations: Set if we enable quirk for fixing improper crc
++ *			generation after resume from suspend.
+  * @parkmode_disable_ss_quirk: set if we need to disable all SuperSpeed
+  *			instances in park mode.
+  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
+@@ -1311,7 +1315,9 @@ struct dwc3 {
+ 	unsigned		dis_u2_freeclk_exists_quirk:1;
+ 	unsigned		dis_del_phy_power_chg_quirk:1;
+ 	unsigned		dis_tx_ipgap_linecheck_quirk:1;
++	unsigned		resume_hs_terminations:1;
+ 	unsigned		parkmode_disable_ss_quirk:1;
++	unsigned		gfladj_refclk_lpm_sel:1;
+ 
+ 	unsigned		tx_de_emphasis_quirk:1;
+ 	unsigned		tx_de_emphasis:2;
+diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
+index e0fa4b186ec6d..36184a7625273 100644
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -2645,10 +2645,10 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
+ 		unsigned i = 0;
+ 		vla_group(d);
+ 		vla_item(d, struct usb_gadget_strings *, stringtabs,
+-			lang_count + 1);
++			size_add(lang_count, 1));
+ 		vla_item(d, struct usb_gadget_strings, stringtab, lang_count);
+ 		vla_item(d, struct usb_string, strings,
+-			lang_count*(needed_count+1));
++			size_mul(lang_count, (needed_count + 1)));
+ 
+ 		char *vlabuf = kmalloc(vla_group_size(d), GFP_KERNEL);
+ 
+diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c
+index abec5c58f5251..a881c69b1f2bf 100644
+--- a/drivers/usb/gadget/function/f_printer.c
++++ b/drivers/usb/gadget/function/f_printer.c
+@@ -89,7 +89,7 @@ struct printer_dev {
+ 	u8			printer_cdev_open;
+ 	wait_queue_head_t	wait;
+ 	unsigned		q_len;
+-	char			*pnp_string;	/* We don't own memory! */
++	char			**pnp_string;	/* We don't own memory! */
+ 	struct usb_function	function;
+ };
+ 
+@@ -1000,16 +1000,16 @@ static int printer_func_setup(struct usb_function *f,
+ 			if ((wIndex>>8) != dev->interface)
+ 				break;
+ 
+-			if (!dev->pnp_string) {
++			if (!*dev->pnp_string) {
+ 				value = 0;
+ 				break;
+ 			}
+-			value = strlen(dev->pnp_string);
++			value = strlen(*dev->pnp_string);
+ 			buf[0] = (value >> 8) & 0xFF;
+ 			buf[1] = value & 0xFF;
+-			memcpy(buf + 2, dev->pnp_string, value);
++			memcpy(buf + 2, *dev->pnp_string, value);
+ 			DBG(dev, "1284 PNP String: %x %s\n", value,
+-			    dev->pnp_string);
++			    *dev->pnp_string);
+ 			break;
+ 
+ 		case GET_PORT_STATUS: /* Get Port Status */
+@@ -1475,7 +1475,7 @@ static struct usb_function *gprinter_alloc(struct usb_function_instance *fi)
+ 	kref_init(&dev->kref);
+ 	++opts->refcnt;
+ 	dev->minor = opts->minor;
+-	dev->pnp_string = opts->pnp_string;
++	dev->pnp_string = &opts->pnp_string;
+ 	dev->q_len = opts->q_len;
+ 	mutex_unlock(&opts->lock);
+ 
+diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
+index 71669e0e4d007..7ec223849d949 100644
+--- a/drivers/usb/gadget/function/f_uvc.c
++++ b/drivers/usb/gadget/function/f_uvc.c
+@@ -421,7 +421,7 @@ uvc_register_video(struct uvc_device *uvc)
+ 	int ret;
+ 
+ 	/* TODO reference counting. */
+-	memset(&uvc->vdev, 0, sizeof(uvc->video));
++	memset(&uvc->vdev, 0, sizeof(uvc->vdev));
+ 	uvc->vdev.v4l2_dev = &uvc->v4l2_dev;
+ 	uvc->vdev.v4l2_dev->dev = &cdev->gadget->dev;
+ 	uvc->vdev.fops = &uvc_v4l2_fops;
+@@ -897,10 +897,14 @@ static void uvc_function_unbind(struct usb_configuration *c,
+ {
+ 	struct usb_composite_dev *cdev = c->cdev;
+ 	struct uvc_device *uvc = to_uvc(f);
++	struct uvc_video *video = &uvc->video;
+ 	long wait_ret = 1;
+ 
+ 	uvcg_info(f, "%s()\n", __func__);
+ 
++	if (video->async_wq)
++		destroy_workqueue(video->async_wq);
++
+ 	/*
+ 	 * If we know we're connected via v4l2, then there should be a cleanup
+ 	 * of the device from userspace either via UVC_EVENT_DISCONNECT or
+diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h
+index 58e383afdd440..1a31e6c6a5ffb 100644
+--- a/drivers/usb/gadget/function/uvc.h
++++ b/drivers/usb/gadget/function/uvc.h
+@@ -88,6 +88,7 @@ struct uvc_video {
+ 	struct usb_ep *ep;
+ 
+ 	struct work_struct pump;
++	struct workqueue_struct *async_wq;
+ 
+ 	/* Frame parameters */
+ 	u8 bpp;
+diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c
+index fd8f73bb726dd..fddc392b8ab95 100644
+--- a/drivers/usb/gadget/function/uvc_v4l2.c
++++ b/drivers/usb/gadget/function/uvc_v4l2.c
+@@ -170,7 +170,7 @@ uvc_v4l2_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
+ 		return ret;
+ 
+ 	if (uvc->state == UVC_STATE_STREAMING)
+-		schedule_work(&video->pump);
++		queue_work(video->async_wq, &video->pump);
+ 
+ 	return ret;
+ }
+diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
+index c00ce0e91f5d5..bb037fcc90e69 100644
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -277,7 +277,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
+ 	spin_unlock_irqrestore(&video->req_lock, flags);
+ 
+ 	if (uvc->state == UVC_STATE_STREAMING)
+-		schedule_work(&video->pump);
++		queue_work(video->async_wq, &video->pump);
+ }
+ 
+ static int
+@@ -485,7 +485,7 @@ int uvcg_video_enable(struct uvc_video *video, int enable)
+ 
+ 	video->req_int_count = 0;
+ 
+-	schedule_work(&video->pump);
++	queue_work(video->async_wq, &video->pump);
+ 
+ 	return ret;
+ }
+@@ -499,6 +499,11 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc)
+ 	spin_lock_init(&video->req_lock);
+ 	INIT_WORK(&video->pump, uvcg_video_pump);
+ 
++	/* Allocate a work queue for asynchronous video pump handler. */
++	video->async_wq = alloc_workqueue("uvcgadget", WQ_UNBOUND | WQ_HIGHPRI, 0);
++	if (!video->async_wq)
++		return -EINVAL;
++
+ 	video->uvc = uvc;
+ 	video->fcc = V4L2_PIX_FMT_YUYV;
+ 	video->bpp = 16;
+diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c
+index e61155fa63796..f1367b53b2600 100644
+--- a/drivers/usb/host/xhci-dbgcap.c
++++ b/drivers/usb/host/xhci-dbgcap.c
+@@ -988,7 +988,7 @@ xhci_alloc_dbc(struct device *dev, void __iomem *base, const struct dbc_driver *
+ 	dbc->driver = driver;
+ 
+ 	if (readl(&dbc->regs->control) & DBC_CTRL_DBC_ENABLE)
+-		return NULL;
++		goto err;
+ 
+ 	INIT_DELAYED_WORK(&dbc->event_work, xhci_dbc_handle_events);
+ 	spin_lock_init(&dbc->lock);
+diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
+index 8c19e151a9454..9e56aa28efcd4 100644
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -641,7 +641,7 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci,
+ 			num_stream_ctxs, &stream_info->ctx_array_dma,
+ 			mem_flags);
+ 	if (!stream_info->stream_ctx_array)
+-		goto cleanup_ctx;
++		goto cleanup_ring_array;
+ 	memset(stream_info->stream_ctx_array, 0,
+ 			sizeof(struct xhci_stream_ctx)*num_stream_ctxs);
+ 
+@@ -702,6 +702,11 @@ cleanup_rings:
+ 	}
+ 	xhci_free_command(xhci, stream_info->free_streams_command);
+ cleanup_ctx:
++	xhci_free_stream_ctx(xhci,
++		stream_info->num_stream_ctxs,
++		stream_info->stream_ctx_array,
++		stream_info->ctx_array_dma);
++cleanup_ring_array:
+ 	kfree(stream_info->stream_rings);
+ cleanup_info:
+ 	kfree(stream_info);
+diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
+index a8641b6536eea..5fb55bf194931 100644
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -123,7 +123,7 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = {
+ };
+ 
+ static const struct xhci_plat_priv xhci_plat_brcm = {
+-	.quirks = XHCI_RESET_ON_RESUME,
++	.quirks = XHCI_RESET_ON_RESUME | XHCI_SUSPEND_RESUME_CLKS,
+ };
+ 
+ static const struct of_device_id usb_xhci_of_match[] = {
+@@ -437,7 +437,16 @@ static int __maybe_unused xhci_plat_suspend(struct device *dev)
+ 	 * xhci_suspend() needs `do_wakeup` to know whether host is allowed
+ 	 * to do wakeup during suspend.
+ 	 */
+-	return xhci_suspend(xhci, device_may_wakeup(dev));
++	ret = xhci_suspend(xhci, device_may_wakeup(dev));
++	if (ret)
++		return ret;
++
++	if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) {
++		clk_disable_unprepare(xhci->clk);
++		clk_disable_unprepare(xhci->reg_clk);
++	}
++
++	return 0;
+ }
+ 
+ static int __maybe_unused xhci_plat_resume(struct device *dev)
+@@ -446,6 +455,11 @@ static int __maybe_unused xhci_plat_resume(struct device *dev)
+ 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
+ 	int ret;
+ 
++	if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) {
++		clk_prepare_enable(xhci->clk);
++		clk_prepare_enable(xhci->reg_clk);
++	}
++
+ 	ret = xhci_priv_resume_quirk(hcd);
+ 	if (ret)
+ 		return ret;
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 38649284ff889..a7ef675f00fdd 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -1183,7 +1183,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
+ 	/* re-initialize the HC on Restore Error, or Host Controller Error */
+ 	if (temp & (STS_SRE | STS_HCE)) {
+ 		reinit_xhc = true;
+-		xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp);
++		if (!xhci->broken_suspend)
++			xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp);
+ 	}
+ 
+ 	if (reinit_xhc) {
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index 7caa0db5e826d..6dfbf73ee840d 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1899,6 +1899,7 @@ struct xhci_hcd {
+ #define XHCI_NO_SOFT_RETRY	BIT_ULL(40)
+ #define XHCI_BROKEN_D3COLD	BIT_ULL(41)
+ #define XHCI_EP_CTX_BROKEN_DCS	BIT_ULL(42)
++#define XHCI_SUSPEND_RESUME_CLKS	BIT_ULL(43)
+ 
+ 	unsigned int		num_active_eps;
+ 	unsigned int		limit_active_eps;
+diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
+index e9437a176518a..ea39243efee39 100644
+--- a/drivers/usb/misc/idmouse.c
++++ b/drivers/usb/misc/idmouse.c
+@@ -177,10 +177,6 @@ static int idmouse_create_image(struct usb_idmouse *dev)
+ 		bytes_read += bulk_read;
+ 	}
+ 
+-	/* reset the device */
+-reset:
+-	ftip_command(dev, FTIP_RELEASE, 0, 0);
+-
+ 	/* check for valid image */
+ 	/* right border should be black (0x00) */
+ 	for (bytes_read = sizeof(HEADER)-1 + WIDTH-1; bytes_read < IMGSIZE; bytes_read += WIDTH)
+@@ -192,6 +188,10 @@ reset:
+ 		if (dev->bulk_in_buffer[bytes_read] != 0xFF)
+ 			return -EAGAIN;
+ 
++	/* reset the device */
++reset:
++	ftip_command(dev, FTIP_RELEASE, 0, 0);
++
+ 	/* should be IMGSIZE == 65040 */
+ 	dev_dbg(&dev->interface->dev, "read %d bytes fingerprint data\n",
+ 		bytes_read);
+diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
+index 0ca173af87bb6..a3a6282893d09 100644
+--- a/drivers/usb/mtu3/mtu3_core.c
++++ b/drivers/usb/mtu3/mtu3_core.c
+@@ -978,8 +978,6 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb)
+ 		goto irq_err;
+ 	}
+ 
+-	device_init_wakeup(dev, true);
+-
+ 	/* power down device IP for power saving by default */
+ 	mtu3_stop(mtu);
+ 
+diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
+index 4cb65346789d6..d78ae52b4e261 100644
+--- a/drivers/usb/mtu3/mtu3_plat.c
++++ b/drivers/usb/mtu3/mtu3_plat.c
+@@ -356,6 +356,8 @@ static int mtu3_probe(struct platform_device *pdev)
+ 	pm_runtime_enable(dev);
+ 	pm_runtime_get_sync(dev);
+ 
++	device_init_wakeup(dev, true);
++
+ 	ret = ssusb_rscs_init(ssusb);
+ 	if (ret)
+ 		goto comm_init_err;
+diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
+index daada4b66a922..6704a62a16659 100644
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -760,6 +760,9 @@ static void rxstate(struct musb *musb, struct musb_request *req)
+ 			musb_writew(epio, MUSB_RXCSR, csr);
+ 
+ buffer_aint_mapped:
++			fifo_count = min_t(unsigned int,
++					request->length - request->actual,
++					(unsigned int)fifo_count);
+ 			musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *)
+ 					(request->buf + request->actual));
+ 			request->actual += fifo_count;
+diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
+index 4993227ab2930..20dcbccb290b3 100644
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1275,12 +1275,6 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999,
+ 		USB_SC_RBC, USB_PR_BULK, NULL,
+ 		0 ),
+ 
+-UNUSUAL_DEV(0x090c, 0x1000, 0x1100, 0x1100,
+-		"Samsung",
+-		"Flash Drive FIT",
+-		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+-		US_FL_MAX_SECTORS_64),
+-
+ /* aeb */
+ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
+ 		"Feiya",
+diff --git a/drivers/usb/typec/anx7411.c b/drivers/usb/typec/anx7411.c
+index c0f0842d443c6..f178d0eb47b18 100644
+--- a/drivers/usb/typec/anx7411.c
++++ b/drivers/usb/typec/anx7411.c
+@@ -1105,7 +1105,7 @@ static int anx7411_typec_switch_probe(struct anx7411_data *ctx,
+ 	int ret;
+ 	struct device_node *node;
+ 
+-	node = of_find_node_by_name(dev->of_node, "orientation_switch");
++	node = of_get_child_by_name(dev->of_node, "orientation_switch");
+ 	if (!node)
+ 		return 0;
+ 
+@@ -1115,7 +1115,7 @@ static int anx7411_typec_switch_probe(struct anx7411_data *ctx,
+ 		return ret;
+ 	}
+ 
+-	node = of_find_node_by_name(dev->of_node, "mode_switch");
++	node = of_get_child_by_name(dev->of_node, "mode_switch");
+ 	if (!node) {
+ 		dev_err(dev, "no typec mux exist");
+ 		ret = -ENODEV;
+diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c
+index 6364f0d467ea3..74fb5a4c6f21b 100644
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -1067,11 +1067,9 @@ static int ucsi_register_port(struct ucsi *ucsi, int index)
+ 
+ 	cap->fwnode = ucsi_find_fwnode(con);
+ 	con->usb_role_sw = fwnode_usb_role_switch_get(cap->fwnode);
+-	if (IS_ERR(con->usb_role_sw)) {
+-		dev_err(ucsi->dev, "con%d: failed to get usb role switch\n",
+-			con->num);
+-		return PTR_ERR(con->usb_role_sw);
+-	}
++	if (IS_ERR(con->usb_role_sw))
++		return dev_err_probe(ucsi->dev, PTR_ERR(con->usb_role_sw),
++			"con%d: failed to get usb role switch\n", con->num);
+ 
+ 	/* Delay other interactions with the con until registration is complete */
+ 	mutex_lock(&con->lock);
+diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
+index 368330417bde2..5703775af1297 100644
+--- a/drivers/vhost/vsock.c
++++ b/drivers/vhost/vsock.c
+@@ -393,7 +393,7 @@ vhost_vsock_alloc_pkt(struct vhost_virtqueue *vq,
+ 		return NULL;
+ 	}
+ 
+-	pkt->buf = kmalloc(pkt->len, GFP_KERNEL);
++	pkt->buf = kvmalloc(pkt->len, GFP_KERNEL);
+ 	if (!pkt->buf) {
+ 		kfree(pkt);
+ 		return NULL;
+diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c
+index 538f2d40acdac..d245826a9324d 100644
+--- a/drivers/video/aperture.c
++++ b/drivers/video/aperture.c
+@@ -8,6 +8,7 @@
+ #include <linux/pci.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
++#include <linux/sysfb.h>
+ #include <linux/types.h>
+ #include <linux/vgaarb.h>
+ 
+@@ -286,7 +287,20 @@ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t si
+ #if IS_REACHABLE(CONFIG_FB)
+ 	struct apertures_struct *a;
+ 	int ret;
++#endif
++
++	/*
++	 * If a driver asked to unregister a platform device registered by
++	 * sysfb, then can be assumed that this is a driver for a display
++	 * that is set up by the system firmware and has a generic driver.
++	 *
++	 * Drivers for devices that don't have a generic driver will never
++	 * ask for this, so let's assume that a real driver for the display
++	 * was already probed and prevent sysfb to register devices later.
++	 */
++	sysfb_disable();
+ 
++#if IS_REACHABLE(CONFIG_FB)
+ 	a = alloc_apertures(1);
+ 	if (!a)
+ 		return -ENOMEM;
+diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
+index 02b0cf2cfafed..bda4d304feb68 100644
+--- a/drivers/video/fbdev/core/fbmem.c
++++ b/drivers/video/fbdev/core/fbmem.c
+@@ -19,7 +19,6 @@
+ #include <linux/kernel.h>
+ #include <linux/major.h>
+ #include <linux/slab.h>
+-#include <linux/sysfb.h>
+ #include <linux/mm.h>
+ #include <linux/mman.h>
+ #include <linux/vt.h>
+@@ -1777,17 +1776,6 @@ int remove_conflicting_framebuffers(struct apertures_struct *a,
+ 		do_free = true;
+ 	}
+ 
+-	/*
+-	 * If a driver asked to unregister a platform device registered by
+-	 * sysfb, then can be assumed that this is a driver for a display
+-	 * that is set up by the system firmware and has a generic driver.
+-	 *
+-	 * Drivers for devices that don't have a generic driver will never
+-	 * ask for this, so let's assume that a real driver for the display
+-	 * was already probed and prevent sysfb to register devices later.
+-	 */
+-	sysfb_disable();
+-
+ 	mutex_lock(&registration_lock);
+ 	do_remove_conflicting_framebuffers(a, name, primary);
+ 	mutex_unlock(&registration_lock);
+diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
+index d7aa5511c3617..e65bdc499c236 100644
+--- a/drivers/video/fbdev/smscufx.c
++++ b/drivers/video/fbdev/smscufx.c
+@@ -137,6 +137,8 @@ static int ufx_submit_urb(struct ufx_data *dev, struct urb * urb, size_t len);
+ static int ufx_alloc_urb_list(struct ufx_data *dev, int count, size_t size);
+ static void ufx_free_urb_list(struct ufx_data *dev);
+ 
++static DEFINE_MUTEX(disconnect_mutex);
++
+ /* reads a control register */
+ static int ufx_reg_read(struct ufx_data *dev, u32 index, u32 *data)
+ {
+@@ -1071,9 +1073,13 @@ static int ufx_ops_open(struct fb_info *info, int user)
+ 	if (user == 0 && !console)
+ 		return -EBUSY;
+ 
++	mutex_lock(&disconnect_mutex);
++
+ 	/* If the USB device is gone, we don't accept new opens */
+-	if (dev->virtualized)
++	if (dev->virtualized) {
++		mutex_unlock(&disconnect_mutex);
+ 		return -ENODEV;
++	}
+ 
+ 	dev->fb_count++;
+ 
+@@ -1097,6 +1103,8 @@ static int ufx_ops_open(struct fb_info *info, int user)
+ 	pr_debug("open /dev/fb%d user=%d fb_info=%p count=%d",
+ 		info->node, user, info, dev->fb_count);
+ 
++	mutex_unlock(&disconnect_mutex);
++
+ 	return 0;
+ }
+ 
+@@ -1741,6 +1749,8 @@ static void ufx_usb_disconnect(struct usb_interface *interface)
+ {
+ 	struct ufx_data *dev;
+ 
++	mutex_lock(&disconnect_mutex);
++
+ 	dev = usb_get_intfdata(interface);
+ 
+ 	pr_debug("USB disconnect starting\n");
+@@ -1761,6 +1771,8 @@ static void ufx_usb_disconnect(struct usb_interface *interface)
+ 	kref_put(&dev->kref, ufx_free);
+ 
+ 	/* consider ufx_data freed */
++
++	mutex_unlock(&disconnect_mutex);
+ }
+ 
+ static struct usb_driver ufx_driver = {
+diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c
+index 38a861e22c339..7753e586e65a0 100644
+--- a/drivers/video/fbdev/stifb.c
++++ b/drivers/video/fbdev/stifb.c
+@@ -1298,7 +1298,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
+ 	
+ 	/* limit fbsize to max visible screen size */
+ 	if (fix->smem_len > yres*fix->line_length)
+-		fix->smem_len = yres*fix->line_length;
++		fix->smem_len = ALIGN(yres*fix->line_length, 4*1024*1024);
+ 	
+ 	fix->accel = FB_ACCEL_NONE;
+ 
+diff --git a/drivers/xen/gntdev-common.h b/drivers/xen/gntdev-common.h
+index 40ef379c28ab0..9c286b2a19001 100644
+--- a/drivers/xen/gntdev-common.h
++++ b/drivers/xen/gntdev-common.h
+@@ -44,9 +44,10 @@ struct gntdev_unmap_notify {
+ };
+ 
+ struct gntdev_grant_map {
++	atomic_t in_use;
+ 	struct mmu_interval_notifier notifier;
++	bool notifier_init;
+ 	struct list_head next;
+-	struct vm_area_struct *vma;
+ 	int index;
+ 	int count;
+ 	int flags;
+diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
+index 84b143eef395b..4d9a3050de6a3 100644
+--- a/drivers/xen/gntdev.c
++++ b/drivers/xen/gntdev.c
+@@ -286,6 +286,9 @@ void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map)
+ 		 */
+ 	}
+ 
++	if (use_ptemod && map->notifier_init)
++		mmu_interval_notifier_remove(&map->notifier);
++
+ 	if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) {
+ 		notify_remote_via_evtchn(map->notify.event);
+ 		evtchn_put(map->notify.event);
+@@ -298,7 +301,7 @@ void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map)
+ static int find_grant_ptes(pte_t *pte, unsigned long addr, void *data)
+ {
+ 	struct gntdev_grant_map *map = data;
+-	unsigned int pgnr = (addr - map->vma->vm_start) >> PAGE_SHIFT;
++	unsigned int pgnr = (addr - map->pages_vm_start) >> PAGE_SHIFT;
+ 	int flags = map->flags | GNTMAP_application_map | GNTMAP_contains_pte |
+ 		    (1 << _GNTMAP_guest_avail0);
+ 	u64 pte_maddr;
+@@ -367,8 +370,7 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map)
+ 	for (i = 0; i < map->count; i++) {
+ 		if (map->map_ops[i].status == GNTST_okay) {
+ 			map->unmap_ops[i].handle = map->map_ops[i].handle;
+-			if (!use_ptemod)
+-				alloced++;
++			alloced++;
+ 		} else if (!err)
+ 			err = -EINVAL;
+ 
+@@ -377,8 +379,7 @@ int gntdev_map_grant_pages(struct gntdev_grant_map *map)
+ 
+ 		if (use_ptemod) {
+ 			if (map->kmap_ops[i].status == GNTST_okay) {
+-				if (map->map_ops[i].status == GNTST_okay)
+-					alloced++;
++				alloced++;
+ 				map->kunmap_ops[i].handle = map->kmap_ops[i].handle;
+ 			} else if (!err)
+ 				err = -EINVAL;
+@@ -394,8 +395,14 @@ static void __unmap_grant_pages_done(int result,
+ 	unsigned int i;
+ 	struct gntdev_grant_map *map = data->data;
+ 	unsigned int offset = data->unmap_ops - map->unmap_ops;
++	int successful_unmaps = 0;
++	int live_grants;
+ 
+ 	for (i = 0; i < data->count; i++) {
++		if (map->unmap_ops[offset + i].status == GNTST_okay &&
++		    map->unmap_ops[offset + i].handle != INVALID_GRANT_HANDLE)
++			successful_unmaps++;
++
+ 		WARN_ON(map->unmap_ops[offset + i].status != GNTST_okay &&
+ 			map->unmap_ops[offset + i].handle != INVALID_GRANT_HANDLE);
+ 		pr_debug("unmap handle=%d st=%d\n",
+@@ -403,6 +410,10 @@ static void __unmap_grant_pages_done(int result,
+ 			map->unmap_ops[offset+i].status);
+ 		map->unmap_ops[offset+i].handle = INVALID_GRANT_HANDLE;
+ 		if (use_ptemod) {
++			if (map->kunmap_ops[offset + i].status == GNTST_okay &&
++			    map->kunmap_ops[offset + i].handle != INVALID_GRANT_HANDLE)
++				successful_unmaps++;
++
+ 			WARN_ON(map->kunmap_ops[offset + i].status != GNTST_okay &&
+ 				map->kunmap_ops[offset + i].handle != INVALID_GRANT_HANDLE);
+ 			pr_debug("kunmap handle=%u st=%d\n",
+@@ -411,11 +422,15 @@ static void __unmap_grant_pages_done(int result,
+ 			map->kunmap_ops[offset+i].handle = INVALID_GRANT_HANDLE;
+ 		}
+ 	}
++
+ 	/*
+ 	 * Decrease the live-grant counter.  This must happen after the loop to
+ 	 * prevent premature reuse of the grants by gnttab_mmap().
+ 	 */
+-	atomic_sub(data->count, &map->live_grants);
++	live_grants = atomic_sub_return(successful_unmaps, &map->live_grants);
++	if (WARN_ON(live_grants < 0))
++		pr_err("%s: live_grants became negative (%d) after unmapping %d pages!\n",
++		       __func__, live_grants, successful_unmaps);
+ 
+ 	/* Release reference taken by __unmap_grant_pages */
+ 	gntdev_put_map(NULL, map);
+@@ -496,11 +511,7 @@ static void gntdev_vma_close(struct vm_area_struct *vma)
+ 	struct gntdev_priv *priv = file->private_data;
+ 
+ 	pr_debug("gntdev_vma_close %p\n", vma);
+-	if (use_ptemod) {
+-		WARN_ON(map->vma != vma);
+-		mmu_interval_notifier_remove(&map->notifier);
+-		map->vma = NULL;
+-	}
++
+ 	vma->vm_private_data = NULL;
+ 	gntdev_put_map(priv, map);
+ }
+@@ -528,29 +539,30 @@ static bool gntdev_invalidate(struct mmu_interval_notifier *mn,
+ 	struct gntdev_grant_map *map =
+ 		container_of(mn, struct gntdev_grant_map, notifier);
+ 	unsigned long mstart, mend;
++	unsigned long map_start, map_end;
+ 
+ 	if (!mmu_notifier_range_blockable(range))
+ 		return false;
+ 
++	map_start = map->pages_vm_start;
++	map_end = map->pages_vm_start + (map->count << PAGE_SHIFT);
++
+ 	/*
+ 	 * If the VMA is split or otherwise changed the notifier is not
+ 	 * updated, but we don't want to process VA's outside the modified
+ 	 * VMA. FIXME: It would be much more understandable to just prevent
+ 	 * modifying the VMA in the first place.
+ 	 */
+-	if (map->vma->vm_start >= range->end ||
+-	    map->vma->vm_end <= range->start)
++	if (map_start >= range->end || map_end <= range->start)
+ 		return true;
+ 
+-	mstart = max(range->start, map->vma->vm_start);
+-	mend = min(range->end, map->vma->vm_end);
++	mstart = max(range->start, map_start);
++	mend = min(range->end, map_end);
+ 	pr_debug("map %d+%d (%lx %lx), range %lx %lx, mrange %lx %lx\n",
+-			map->index, map->count,
+-			map->vma->vm_start, map->vma->vm_end,
+-			range->start, range->end, mstart, mend);
+-	unmap_grant_pages(map,
+-				(mstart - map->vma->vm_start) >> PAGE_SHIFT,
+-				(mend - mstart) >> PAGE_SHIFT);
++		 map->index, map->count, map_start, map_end,
++		 range->start, range->end, mstart, mend);
++	unmap_grant_pages(map, (mstart - map_start) >> PAGE_SHIFT,
++			  (mend - mstart) >> PAGE_SHIFT);
+ 
+ 	return true;
+ }
+@@ -1030,18 +1042,15 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
+ 		return -EINVAL;
+ 
+ 	pr_debug("map %d+%d at %lx (pgoff %lx)\n",
+-			index, count, vma->vm_start, vma->vm_pgoff);
++		 index, count, vma->vm_start, vma->vm_pgoff);
+ 
+ 	mutex_lock(&priv->lock);
+ 	map = gntdev_find_map_index(priv, index, count);
+ 	if (!map)
+ 		goto unlock_out;
+-	if (use_ptemod && map->vma)
++	if (!atomic_add_unless(&map->in_use, 1, 1))
+ 		goto unlock_out;
+-	if (atomic_read(&map->live_grants)) {
+-		err = -EAGAIN;
+-		goto unlock_out;
+-	}
++
+ 	refcount_inc(&map->users);
+ 
+ 	vma->vm_ops = &gntdev_vmops;
+@@ -1062,15 +1071,16 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
+ 			map->flags |= GNTMAP_readonly;
+ 	}
+ 
++	map->pages_vm_start = vma->vm_start;
++
+ 	if (use_ptemod) {
+-		map->vma = vma;
+ 		err = mmu_interval_notifier_insert_locked(
+ 			&map->notifier, vma->vm_mm, vma->vm_start,
+ 			vma->vm_end - vma->vm_start, &gntdev_mmu_ops);
+-		if (err) {
+-			map->vma = NULL;
++		if (err)
+ 			goto out_unlock_put;
+-		}
++
++		map->notifier_init = true;
+ 	}
+ 	mutex_unlock(&priv->lock);
+ 
+@@ -1087,7 +1097,6 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
+ 		 */
+ 		mmu_interval_read_begin(&map->notifier);
+ 
+-		map->pages_vm_start = vma->vm_start;
+ 		err = apply_to_page_range(vma->vm_mm, vma->vm_start,
+ 					  vma->vm_end - vma->vm_start,
+ 					  find_grant_ptes, map);
+@@ -1116,13 +1125,8 @@ unlock_out:
+ out_unlock_put:
+ 	mutex_unlock(&priv->lock);
+ out_put_map:
+-	if (use_ptemod) {
++	if (use_ptemod)
+ 		unmap_grant_pages(map, 0, map->count);
+-		if (map->vma) {
+-			mmu_interval_notifier_remove(&map->notifier);
+-			map->vma = NULL;
+-		}
+-	}
+ 	gntdev_put_map(priv, map);
+ 	return err;
+ }
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index e0375ba9d0fed..4b9c095070ccf 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -2190,7 +2190,16 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info)
+ 	int need_clear = 0;
+ 	u64 cache_gen;
+ 
+-	if (!root)
++	/*
++	 * Either no extent root (with ibadroots rescue option) or we have
++	 * unsupported RO options. The fs can never be mounted read-write, so no
++	 * need to waste time searching block group items.
++	 *
++	 * This also allows new extent tree related changes to be RO compat,
++	 * no need for a full incompat flag.
++	 */
++	if (!root || (btrfs_super_compat_ro_flags(info->super_copy) &
++		      ~BTRFS_FEATURE_COMPAT_RO_SUPP))
+ 		return fill_dummy_bgs(info);
+ 
+ 	key.objectid = 0;
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 6914cd8024ba0..cfbbd7dc3c46b 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -4888,6 +4888,9 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+ 	    !test_bit(BTRFS_ROOT_RESET_LOCKDEP_CLASS, &root->state))
+ 		lockdep_owner = BTRFS_FS_TREE_OBJECTID;
+ 
++	/* btrfs_clean_tree_block() accesses generation field. */
++	btrfs_set_header_generation(buf, trans->transid);
++
+ 	/*
+ 	 * This needs to stay, because we could allocate a freed block from an
+ 	 * old tree into a new tree, so we need to make sure this new block is
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 5a3f6e0d9688f..19e9df0c86496 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -523,6 +523,7 @@ void btrfs_drop_extent_cache(struct btrfs_inode *inode, u64 start, u64 end,
+ 		testend = 0;
+ 	}
+ 	while (1) {
++		bool ends_after_range = false;
+ 		int no_splits = 0;
+ 
+ 		modified = false;
+@@ -539,10 +540,12 @@ void btrfs_drop_extent_cache(struct btrfs_inode *inode, u64 start, u64 end,
+ 			write_unlock(&em_tree->lock);
+ 			break;
+ 		}
++		if (testend && em->start + em->len > start + len)
++			ends_after_range = true;
+ 		flags = em->flags;
+ 		gen = em->generation;
+ 		if (skip_pinned && test_bit(EXTENT_FLAG_PINNED, &em->flags)) {
+-			if (testend && em->start + em->len >= start + len) {
++			if (ends_after_range) {
+ 				free_extent_map(em);
+ 				write_unlock(&em_tree->lock);
+ 				break;
+@@ -592,7 +595,7 @@ void btrfs_drop_extent_cache(struct btrfs_inode *inode, u64 start, u64 end,
+ 			split = split2;
+ 			split2 = NULL;
+ 		}
+-		if (testend && em->start + em->len > start + len) {
++		if (ends_after_range) {
+ 			u64 diff = start + len - em->start;
+ 
+ 			split->start = start + len;
+@@ -630,14 +633,42 @@ void btrfs_drop_extent_cache(struct btrfs_inode *inode, u64 start, u64 end,
+ 			} else {
+ 				ret = add_extent_mapping(em_tree, split,
+ 							 modified);
+-				ASSERT(ret == 0); /* Logic error */
++				/* Logic error, shouldn't happen. */
++				ASSERT(ret == 0);
++				if (WARN_ON(ret != 0) && modified)
++					btrfs_set_inode_full_sync(inode);
+ 			}
+ 			free_extent_map(split);
+ 			split = NULL;
+ 		}
+ next:
+-		if (extent_map_in_tree(em))
++		if (extent_map_in_tree(em)) {
++			/*
++			 * If the extent map is still in the tree it means that
++			 * either of the following is true:
++			 *
++			 * 1) It fits entirely in our range (doesn't end beyond
++			 *    it or starts before it);
++			 *
++			 * 2) It starts before our range and/or ends after our
++			 *    range, and we were not able to allocate the extent
++			 *    maps for split operations, @split and @split2.
++			 *
++			 * If we are at case 2) then we just remove the entire
++			 * extent map - this is fine since if anyone needs it to
++			 * access the subranges outside our range, will just
++			 * load it again from the subvolume tree's file extent
++			 * item. However if the extent map was in the list of
++			 * modified extents, then we must mark the inode for a
++			 * full fsync, otherwise a fast fsync will miss this
++			 * extent if it's new and needs to be logged.
++			 */
++			if ((em->start < start || ends_after_range) && modified) {
++				ASSERT(no_splits);
++				btrfs_set_inode_full_sync(inode);
++			}
+ 			remove_extent_mapping(em_tree, em);
++		}
+ 		write_unlock(&em_tree->lock);
+ 
+ 		/* once for us */
+@@ -2200,14 +2231,6 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+ 
+ 	atomic_inc(&root->log_batch);
+ 
+-	/*
+-	 * Always check for the full sync flag while holding the inode's lock,
+-	 * to avoid races with other tasks. The flag must be either set all the
+-	 * time during logging or always off all the time while logging.
+-	 */
+-	full_sync = test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+-			     &BTRFS_I(inode)->runtime_flags);
+-
+ 	/*
+ 	 * Before we acquired the inode's lock and the mmap lock, someone may
+ 	 * have dirtied more pages in the target range. We need to make sure
+@@ -2232,6 +2255,17 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+ 		goto out;
+ 	}
+ 
++	/*
++	 * Always check for the full sync flag while holding the inode's lock,
++	 * to avoid races with other tasks. The flag must be either set all the
++	 * time during logging or always off all the time while logging.
++	 * We check the flag here after starting delalloc above, because when
++	 * running delalloc the full sync flag may be set if we need to drop
++	 * extra extent map ranges due to temporary memory allocation failures.
++	 */
++	full_sync = test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
++			     &BTRFS_I(inode)->runtime_flags);
++
+ 	/*
+ 	 * We have to do this here to avoid the priority inversion of waiting on
+ 	 * IO of a lower priority task while holding a transaction open.
+@@ -3810,6 +3844,7 @@ const struct file_operations btrfs_file_operations = {
+ 	.mmap		= btrfs_file_mmap,
+ 	.open		= btrfs_file_open,
+ 	.release	= btrfs_release_file,
++	.get_unmapped_area = thp_get_unmapped_area,
+ 	.fsync		= btrfs_sync_file,
+ 	.fallocate	= btrfs_fallocate,
+ 	.unlocked_ioctl	= btrfs_ioctl,
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index 996da650ecdc3..015b0440df5dc 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -48,6 +48,25 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
+ 			      struct btrfs_free_space *info, u64 offset,
+ 			      u64 bytes, bool update_stats);
+ 
++static void __btrfs_remove_free_space_cache_locked(
++				struct btrfs_free_space_ctl *ctl)
++{
++	struct btrfs_free_space *info;
++	struct rb_node *node;
++
++	while ((node = rb_last(&ctl->free_space_offset)) != NULL) {
++		info = rb_entry(node, struct btrfs_free_space, offset_index);
++		if (!info->bitmap) {
++			unlink_free_space(ctl, info, true);
++			kmem_cache_free(btrfs_free_space_cachep, info);
++		} else {
++			free_bitmap(ctl, info);
++		}
++
++		cond_resched_lock(&ctl->tree_lock);
++	}
++}
++
+ static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
+ 					       struct btrfs_path *path,
+ 					       u64 offset)
+@@ -693,6 +712,12 @@ static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl)
+ 
+ 	max_bitmaps = max_t(u64, max_bitmaps, 1);
+ 
++	if (ctl->total_bitmaps > max_bitmaps)
++		btrfs_err(block_group->fs_info,
++"invalid free space control: bg start=%llu len=%llu total_bitmaps=%u unit=%u max_bitmaps=%llu bytes_per_bg=%llu",
++			  block_group->start, block_group->length,
++			  ctl->total_bitmaps, ctl->unit, max_bitmaps,
++			  bytes_per_bg);
+ 	ASSERT(ctl->total_bitmaps <= max_bitmaps);
+ 
+ 	/*
+@@ -875,7 +900,14 @@ out:
+ 	return ret;
+ free_cache:
+ 	io_ctl_drop_pages(&io_ctl);
+-	__btrfs_remove_free_space_cache(ctl);
++
++	/*
++	 * We need to call the _locked variant so we don't try to update the
++	 * discard counters.
++	 */
++	spin_lock(&ctl->tree_lock);
++	__btrfs_remove_free_space_cache_locked(ctl);
++	spin_unlock(&ctl->tree_lock);
+ 	goto out;
+ }
+ 
+@@ -1001,7 +1033,13 @@ int load_free_space_cache(struct btrfs_block_group *block_group)
+ 		if (ret == 0)
+ 			ret = 1;
+ 	} else {
++		/*
++		 * We need to call the _locked variant so we don't try to update
++		 * the discard counters.
++		 */
++		spin_lock(&tmp_ctl.tree_lock);
+ 		__btrfs_remove_free_space_cache(&tmp_ctl);
++		spin_unlock(&tmp_ctl.tree_lock);
+ 		btrfs_warn(fs_info,
+ 			   "block group %llu has wrong amount of free space",
+ 			   block_group->start);
+@@ -2964,25 +3002,6 @@ static void __btrfs_return_cluster_to_free_space(
+ 	btrfs_put_block_group(block_group);
+ }
+ 
+-static void __btrfs_remove_free_space_cache_locked(
+-				struct btrfs_free_space_ctl *ctl)
+-{
+-	struct btrfs_free_space *info;
+-	struct rb_node *node;
+-
+-	while ((node = rb_last(&ctl->free_space_offset)) != NULL) {
+-		info = rb_entry(node, struct btrfs_free_space, offset_index);
+-		if (!info->bitmap) {
+-			unlink_free_space(ctl, info, true);
+-			kmem_cache_free(btrfs_free_space_cachep, info);
+-		} else {
+-			free_bitmap(ctl, info);
+-		}
+-
+-		cond_resched_lock(&ctl->tree_lock);
+-	}
+-}
+-
+ void __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl)
+ {
+ 	spin_lock(&ctl->tree_lock);
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index db723c0026bd2..ba323dcb0a0b8 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -1174,6 +1174,21 @@ out_add_root:
+ 		fs_info->qgroup_rescan_running = true;
+ 	        btrfs_queue_work(fs_info->qgroup_rescan_workers,
+ 	                         &fs_info->qgroup_rescan_work);
++	} else {
++		/*
++		 * We have set both BTRFS_FS_QUOTA_ENABLED and
++		 * BTRFS_QGROUP_STATUS_FLAG_ON, so we can only fail with
++		 * -EINPROGRESS. That can happen because someone started the
++		 * rescan worker by calling quota rescan ioctl before we
++		 * attempted to initialize the rescan worker. Failure due to
++		 * quotas disabled in the meanwhile is not possible, because
++		 * we are holding a write lock on fs_info->subvol_sem, which
++		 * is also acquired when disabling quotas.
++		 * Ignore such error, and any other error would need to undo
++		 * everything we did in the transaction we just committed.
++		 */
++		ASSERT(ret == -EINPROGRESS);
++		ret = 0;
+ 	}
+ 
+ out_free_path:
+diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
+index 3afe5fa50a631..7d9b09e3ca70c 100644
+--- a/fs/btrfs/scrub.c
++++ b/fs/btrfs/scrub.c
+@@ -729,6 +729,13 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock)
+ 	dev = sblock->sectors[0]->dev;
+ 	fs_info = sblock->sctx->fs_info;
+ 
++	/* Super block error, no need to search extent tree. */
++	if (sblock->sectors[0]->flags & BTRFS_EXTENT_FLAG_SUPER) {
++		btrfs_warn_in_rcu(fs_info, "%s on device %s, physical %llu",
++			errstr, rcu_str_deref(dev->name),
++			sblock->sectors[0]->physical);
++		return;
++	}
+ 	path = btrfs_alloc_path();
+ 	if (!path)
+ 		return;
+@@ -804,7 +811,7 @@ static inline void scrub_put_recover(struct btrfs_fs_info *fs_info,
+ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
+ {
+ 	struct scrub_ctx *sctx = sblock_to_check->sctx;
+-	struct btrfs_device *dev;
++	struct btrfs_device *dev = sblock_to_check->sectors[0]->dev;
+ 	struct btrfs_fs_info *fs_info;
+ 	u64 logical;
+ 	unsigned int failed_mirror_index;
+@@ -825,13 +832,15 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
+ 	fs_info = sctx->fs_info;
+ 	if (sblock_to_check->sectors[0]->flags & BTRFS_EXTENT_FLAG_SUPER) {
+ 		/*
+-		 * if we find an error in a super block, we just report it.
++		 * If we find an error in a super block, we just report it.
+ 		 * They will get written with the next transaction commit
+ 		 * anyway
+ 		 */
++		scrub_print_warning("super block error", sblock_to_check);
+ 		spin_lock(&sctx->stat_lock);
+ 		++sctx->stat.super_errors;
+ 		spin_unlock(&sctx->stat_lock);
++		btrfs_dev_stat_inc_and_print(dev, BTRFS_DEV_STAT_CORRUPTION_ERRS);
+ 		return 0;
+ 	}
+ 	logical = sblock_to_check->sectors[0]->logical;
+@@ -840,7 +849,6 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check)
+ 	is_metadata = !(sblock_to_check->sectors[0]->flags &
+ 			BTRFS_EXTENT_FLAG_DATA);
+ 	have_csum = sblock_to_check->sectors[0]->have_csum;
+-	dev = sblock_to_check->sectors[0]->dev;
+ 
+ 	if (!sctx->is_dev_replace && btrfs_repair_one_zone(fs_info, logical))
+ 		return 0;
+@@ -1762,7 +1770,7 @@ static int scrub_checksum(struct scrub_block *sblock)
+ 	else if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK)
+ 		ret = scrub_checksum_tree_block(sblock);
+ 	else if (flags & BTRFS_EXTENT_FLAG_SUPER)
+-		(void)scrub_checksum_super(sblock);
++		ret = scrub_checksum_super(sblock);
+ 	else
+ 		WARN_ON(1);
+ 	if (ret)
+@@ -1901,23 +1909,6 @@ static int scrub_checksum_super(struct scrub_block *sblock)
+ 	if (memcmp(calculated_csum, s->csum, sctx->fs_info->csum_size))
+ 		++fail_cor;
+ 
+-	if (fail_cor + fail_gen) {
+-		/*
+-		 * if we find an error in a super block, we just report it.
+-		 * They will get written with the next transaction commit
+-		 * anyway
+-		 */
+-		spin_lock(&sctx->stat_lock);
+-		++sctx->stat.super_errors;
+-		spin_unlock(&sctx->stat_lock);
+-		if (fail_cor)
+-			btrfs_dev_stat_inc_and_print(sector->dev,
+-				BTRFS_DEV_STAT_CORRUPTION_ERRS);
+-		else
+-			btrfs_dev_stat_inc_and_print(sector->dev,
+-				BTRFS_DEV_STAT_GENERATION_ERRS);
+-	}
+-
+ 	return fail_cor + fail_gen;
+ }
+ 
+@@ -4102,6 +4093,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
+ 	int ret;
+ 	struct btrfs_device *dev;
+ 	unsigned int nofs_flag;
++	bool need_commit = false;
+ 
+ 	if (btrfs_fs_closing(fs_info))
+ 		return -EAGAIN;
+@@ -4205,6 +4197,12 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
+ 	 */
+ 	nofs_flag = memalloc_nofs_save();
+ 	if (!is_dev_replace) {
++		u64 old_super_errors;
++
++		spin_lock(&sctx->stat_lock);
++		old_super_errors = sctx->stat.super_errors;
++		spin_unlock(&sctx->stat_lock);
++
+ 		btrfs_info(fs_info, "scrub: started on devid %llu", devid);
+ 		/*
+ 		 * by holding device list mutex, we can
+@@ -4213,6 +4211,16 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
+ 		mutex_lock(&fs_info->fs_devices->device_list_mutex);
+ 		ret = scrub_supers(sctx, dev);
+ 		mutex_unlock(&fs_info->fs_devices->device_list_mutex);
++
++		spin_lock(&sctx->stat_lock);
++		/*
++		 * Super block errors found, but we can not commit transaction
++		 * at current context, since btrfs_commit_transaction() needs
++		 * to pause the current running scrub (hold by ourselves).
++		 */
++		if (sctx->stat.super_errors > old_super_errors && !sctx->readonly)
++			need_commit = true;
++		spin_unlock(&sctx->stat_lock);
+ 	}
+ 
+ 	if (!ret)
+@@ -4239,6 +4247,25 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
+ 	scrub_workers_put(fs_info);
+ 	scrub_put_ctx(sctx);
+ 
++	/*
++	 * We found some super block errors before, now try to force a
++	 * transaction commit, as scrub has finished.
++	 */
++	if (need_commit) {
++		struct btrfs_trans_handle *trans;
++
++		trans = btrfs_start_transaction(fs_info->tree_root, 0);
++		if (IS_ERR(trans)) {
++			ret = PTR_ERR(trans);
++			btrfs_err(fs_info,
++	"scrub: failed to start transaction to fix super block errors: %d", ret);
++			return ret;
++		}
++		ret = btrfs_commit_transaction(trans);
++		if (ret < 0)
++			btrfs_err(fs_info,
++	"scrub: failed to commit transaction to fix super block errors: %d", ret);
++	}
+ 	return ret;
+ out:
+ 	scrub_workers_put(fs_info);
+diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
+index f89beac3c6656..ad3ce9700eaf3 100644
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -626,6 +626,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
+ 	int saved_compress_level;
+ 	bool saved_compress_force;
+ 	int no_compress = 0;
++	const bool remounting = test_bit(BTRFS_FS_STATE_REMOUNTING, &info->fs_state);
+ 
+ 	if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE))
+ 		btrfs_set_opt(info->mount_opt, FREE_SPACE_TREE);
+@@ -1137,10 +1138,12 @@ out:
+ 	}
+ 	if (!ret)
+ 		ret = btrfs_check_mountopts_zoned(info);
+-	if (!ret && btrfs_test_opt(info, SPACE_CACHE))
+-		btrfs_info(info, "disk space caching is enabled");
+-	if (!ret && btrfs_test_opt(info, FREE_SPACE_TREE))
+-		btrfs_info(info, "using free space tree");
++	if (!ret && !remounting) {
++		if (btrfs_test_opt(info, SPACE_CACHE))
++			btrfs_info(info, "disk space caching is enabled");
++		if (btrfs_test_opt(info, FREE_SPACE_TREE))
++			btrfs_info(info, "using free space tree");
++	}
+ 	return ret;
+ }
+ 
+@@ -2112,6 +2115,15 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
+ 			ret = -EINVAL;
+ 			goto restore;
+ 		}
++		if (btrfs_super_compat_ro_flags(fs_info->super_copy) &
++		    ~BTRFS_FEATURE_COMPAT_RO_SUPP) {
++			btrfs_err(fs_info,
++		"can not remount read-write due to unsupported optional flags 0x%llx",
++				btrfs_super_compat_ro_flags(fs_info->super_copy) &
++				~BTRFS_FEATURE_COMPAT_RO_SUPP);
++			ret = -EINVAL;
++			goto restore;
++		}
+ 		if (fs_info->fs_devices->rw_devices == 0) {
+ 			ret = -EACCES;
+ 			goto restore;
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+index 3bc94bcc7177e..71386978858eb 100644
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -639,7 +639,7 @@ cifs_chan_is_iface_active(struct cifs_ses *ses,
+ int
+ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server);
+ int
+-SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon);
++SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_mount);
+ 
+ void extract_unc_hostname(const char *unc, const char **h, size_t *len);
+ int copy_path_name(char *dst, const char *src);
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 7ae6f2c08153e..e960dda893c63 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -155,7 +155,7 @@ static void smb2_query_server_interfaces(struct work_struct *work)
+ 	/*
+ 	 * query server network interfaces, in case they change
+ 	 */
+-	rc = SMB3_request_interfaces(0, tcon);
++	rc = SMB3_request_interfaces(0, tcon, false);
+ 	if (rc) {
+ 		cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n",
+ 				__func__, rc);
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 6f38b134a3468..7d756721e1a68 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -4271,6 +4271,15 @@ static ssize_t __cifs_readv(
+ 		len = ctx->len;
+ 	}
+ 
++	if (direct) {
++		rc = filemap_write_and_wait_range(file->f_inode->i_mapping,
++						  offset, offset + len - 1);
++		if (rc) {
++			kref_put(&ctx->refcount, cifs_aio_ctx_release);
++			return -EAGAIN;
++		}
++	}
++
+ 	/* grab a lock here due to read response handlers can access ctx */
+ 	mutex_lock(&ctx->aio_mutex);
+ 
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index 421be43af4253..b02552e5f3eeb 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -512,8 +512,7 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
+ 
+ static int
+ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+-			size_t buf_len,
+-			struct cifs_ses *ses)
++			size_t buf_len, struct cifs_ses *ses, bool in_mount)
+ {
+ 	struct network_interface_info_ioctl_rsp *p;
+ 	struct sockaddr_in *addr4;
+@@ -543,6 +542,20 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ 	}
+ 	spin_unlock(&ses->iface_lock);
+ 
++	/*
++	 * Samba server e.g. can return an empty interface list in some cases,
++	 * which would only be a problem if we were requesting multichannel
++	 */
++	if (bytes_left == 0) {
++		/* avoid spamming logs every 10 minutes, so log only in mount */
++		if ((ses->chan_max > 1) && in_mount)
++			cifs_dbg(VFS,
++				 "empty network interface list returned by server %s\n",
++				 ses->server->hostname);
++		rc = -EINVAL;
++		goto out;
++	}
++
+ 	while (bytes_left >= sizeof(*p)) {
+ 		memset(&tmp_iface, 0, sizeof(tmp_iface));
+ 		tmp_iface.speed = le64_to_cpu(p->LinkSpeed);
+@@ -673,7 +686,7 @@ out:
+ }
+ 
+ int
+-SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
++SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_mount)
+ {
+ 	int rc;
+ 	unsigned int ret_data_len = 0;
+@@ -693,7 +706,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
+ 		goto out;
+ 	}
+ 
+-	rc = parse_server_interfaces(out_buf, ret_data_len, ses);
++	rc = parse_server_interfaces(out_buf, ret_data_len, ses, in_mount);
+ 	if (rc)
+ 		goto out;
+ 
+@@ -729,7 +742,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
+ 	if (rc)
+ 		return;
+ 
+-	SMB3_request_interfaces(xid, tcon);
++	SMB3_request_interfaces(xid, tcon, true /* called during  mount */);
+ 
+ 	SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
+ 			FS_ATTRIBUTE_INFORMATION);
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 6352ab32c7e7a..5016d742576d0 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -1169,9 +1169,9 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
+ 		pneg_inbuf->Dialects[0] =
+ 			cpu_to_le16(server->vals->protocol_id);
+ 		pneg_inbuf->DialectCount = cpu_to_le16(1);
+-		/* structure is big enough for 3 dialects, sending only 1 */
++		/* structure is big enough for 4 dialects, sending only 1 */
+ 		inbuflen = sizeof(*pneg_inbuf) -
+-				sizeof(pneg_inbuf->Dialects[0]) * 2;
++				sizeof(pneg_inbuf->Dialects[0]) * 3;
+ 	}
+ 
+ 	rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
+@@ -2411,7 +2411,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
+ 	unsigned int acelen, acl_size, ace_count;
+ 	unsigned int owner_offset = 0;
+ 	unsigned int group_offset = 0;
+-	struct smb3_acl acl;
++	struct smb3_acl acl = {};
+ 
+ 	*len = roundup(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 4), 8);
+ 
+@@ -2484,6 +2484,7 @@ create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
+ 	acl.AclRevision = ACL_REVISION; /* See 2.4.4.1 of MS-DTYP */
+ 	acl.AclSize = cpu_to_le16(acl_size);
+ 	acl.AceCount = cpu_to_le16(ace_count);
++	/* acl.Sbz1 and Sbz2 MBZ so are not set here, but initialized above */
+ 	memcpy(aclptr, &acl, sizeof(struct smb3_acl));
+ 
+ 	buf->ccontext.DataLength = cpu_to_le32(ptr - (__u8 *)&buf->sd);
+diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
+index 1a5fc3314dbf5..4640fc4a8b133 100644
+--- a/fs/cifs/smb2transport.c
++++ b/fs/cifs/smb2transport.c
+@@ -225,9 +225,9 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+ 	struct smb_rqst drqst;
+ 
+ 	ses = smb2_find_smb_ses(server, le64_to_cpu(shdr->SessionId));
+-	if (!ses) {
++	if (unlikely(!ses)) {
+ 		cifs_server_dbg(VFS, "%s: Could not find session\n", __func__);
+-		return 0;
++		return -ENOENT;
+ 	}
+ 
+ 	memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE);
+@@ -557,8 +557,10 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+ 	u8 key[SMB3_SIGN_KEY_SIZE];
+ 
+ 	rc = smb2_get_sign_key(le64_to_cpu(shdr->SessionId), server, key);
+-	if (rc)
+-		return 0;
++	if (unlikely(rc)) {
++		cifs_server_dbg(VFS, "%s: Could not get signing key\n", __func__);
++		return rc;
++	}
+ 
+ 	if (allocate_crypto) {
+ 		rc = cifs_alloc_hash("cmac(aes)", &hash, &sdesc);
+diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c
+index 19ef136f9e4fc..a44cc42b63171 100644
+--- a/fs/dlm/ast.c
++++ b/fs/dlm/ast.c
+@@ -200,13 +200,13 @@ void dlm_add_cb(struct dlm_lkb *lkb, uint32_t flags, int mode, int status,
+ 	if (!prev_seq) {
+ 		kref_get(&lkb->lkb_ref);
+ 
++		mutex_lock(&ls->ls_cb_mutex);
+ 		if (test_bit(LSFL_CB_DELAY, &ls->ls_flags)) {
+-			mutex_lock(&ls->ls_cb_mutex);
+ 			list_add(&lkb->lkb_cb_list, &ls->ls_cb_delay);
+-			mutex_unlock(&ls->ls_cb_mutex);
+ 		} else {
+ 			queue_work(ls->ls_callback_wq, &lkb->lkb_cb_work);
+ 		}
++		mutex_unlock(&ls->ls_cb_mutex);
+ 	}
+  out:
+ 	mutex_unlock(&lkb->lkb_cb_mutex);
+@@ -288,7 +288,9 @@ void dlm_callback_stop(struct dlm_ls *ls)
+ 
+ void dlm_callback_suspend(struct dlm_ls *ls)
+ {
++	mutex_lock(&ls->ls_cb_mutex);
+ 	set_bit(LSFL_CB_DELAY, &ls->ls_flags);
++	mutex_unlock(&ls->ls_cb_mutex);
+ 
+ 	if (ls->ls_callback_wq)
+ 		flush_workqueue(ls->ls_callback_wq);
+diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
+index dac7eb75dba95..4ac0478c07267 100644
+--- a/fs/dlm/lock.c
++++ b/fs/dlm/lock.c
+@@ -2864,17 +2864,9 @@ static int set_unlock_args(uint32_t flags, void *astarg, struct dlm_args *args)
+ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
+ 			      struct dlm_args *args)
+ {
+-	int rv = -EINVAL;
++	int rv = -EBUSY;
+ 
+ 	if (args->flags & DLM_LKF_CONVERT) {
+-		if (lkb->lkb_flags & DLM_IFL_MSTCPY)
+-			goto out;
+-
+-		if (args->flags & DLM_LKF_QUECVT &&
+-		    !__quecvt_compat_matrix[lkb->lkb_grmode+1][args->mode+1])
+-			goto out;
+-
+-		rv = -EBUSY;
+ 		if (lkb->lkb_status != DLM_LKSTS_GRANTED)
+ 			goto out;
+ 
+@@ -2884,6 +2876,14 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
+ 
+ 		if (is_overlap(lkb))
+ 			goto out;
++
++		rv = -EINVAL;
++		if (lkb->lkb_flags & DLM_IFL_MSTCPY)
++			goto out;
++
++		if (args->flags & DLM_LKF_QUECVT &&
++		    !__quecvt_compat_matrix[lkb->lkb_grmode+1][args->mode+1])
++			goto out;
+ 	}
+ 
+ 	lkb->lkb_exflags = args->flags;
+@@ -3623,7 +3623,7 @@ static void send_args(struct dlm_rsb *r, struct dlm_lkb *lkb,
+ 	case cpu_to_le32(DLM_MSG_REQUEST_REPLY):
+ 	case cpu_to_le32(DLM_MSG_CONVERT_REPLY):
+ 	case cpu_to_le32(DLM_MSG_GRANT):
+-		if (!lkb->lkb_lvbptr)
++		if (!lkb->lkb_lvbptr || !(lkb->lkb_exflags & DLM_LKF_VALBLK))
+ 			break;
+ 		memcpy(ms->m_extra, lkb->lkb_lvbptr, r->res_ls->ls_lvblen);
+ 		break;
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index a4e84e8d94c87..59f64c596233b 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -1336,6 +1336,8 @@ struct dlm_msg *dlm_lowcomms_new_msg(int nodeid, int len, gfp_t allocation,
+ 		return NULL;
+ 	}
+ 
++	/* for dlm_lowcomms_commit_msg() */
++	kref_get(&msg->ref);
+ 	/* we assume if successful commit must called */
+ 	msg->idx = idx;
+ 	return msg;
+@@ -1375,6 +1377,8 @@ void dlm_lowcomms_commit_msg(struct dlm_msg *msg)
+ {
+ 	_dlm_lowcomms_commit_msg(msg);
+ 	srcu_read_unlock(&connections_srcu, msg->idx);
++	/* because dlm_lowcomms_new_msg() */
++	kref_put(&msg->ref, dlm_msg_release);
+ }
+ #endif
+ 
+diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c
+index 95a403720e8c7..16cf9a2835574 100644
+--- a/fs/erofs/inode.c
++++ b/fs/erofs/inode.c
+@@ -214,7 +214,7 @@ static int erofs_fill_symlink(struct inode *inode, void *kaddr,
+ 
+ 	/* if it cannot be handled with fast symlink scheme */
+ 	if (vi->datalayout != EROFS_INODE_FLAT_INLINE ||
+-	    inode->i_size >= EROFS_BLKSIZ) {
++	    inode->i_size >= EROFS_BLKSIZ || inode->i_size < 0) {
+ 		inode->i_op = &erofs_symlink_iops;
+ 		return 0;
+ 	}
+diff --git a/fs/erofs/super.c b/fs/erofs/super.c
+index 3173debeaa5a1..9716d355a63ef 100644
+--- a/fs/erofs/super.c
++++ b/fs/erofs/super.c
+@@ -879,7 +879,7 @@ static void erofs_kill_sb(struct super_block *sb)
+ 	WARN_ON(sb->s_magic != EROFS_SUPER_MAGIC);
+ 
+ 	if (erofs_is_fscache_mode(sb))
+-		generic_shutdown_super(sb);
++		kill_anon_super(sb);
+ 	else
+ 		kill_block_super(sb);
+ 
+diff --git a/fs/eventfd.c b/fs/eventfd.c
+index 3627dd7d25db8..c0ffee99ad238 100644
+--- a/fs/eventfd.c
++++ b/fs/eventfd.c
+@@ -69,17 +69,17 @@ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
+ 	 * it returns false, the eventfd_signal() call should be deferred to a
+ 	 * safe context.
+ 	 */
+-	if (WARN_ON_ONCE(current->in_eventfd_signal))
++	if (WARN_ON_ONCE(current->in_eventfd))
+ 		return 0;
+ 
+ 	spin_lock_irqsave(&ctx->wqh.lock, flags);
+-	current->in_eventfd_signal = 1;
++	current->in_eventfd = 1;
+ 	if (ULLONG_MAX - ctx->count < n)
+ 		n = ULLONG_MAX - ctx->count;
+ 	ctx->count += n;
+ 	if (waitqueue_active(&ctx->wqh))
+ 		wake_up_locked_poll(&ctx->wqh, EPOLLIN);
+-	current->in_eventfd_signal = 0;
++	current->in_eventfd = 0;
+ 	spin_unlock_irqrestore(&ctx->wqh.lock, flags);
+ 
+ 	return n;
+@@ -253,8 +253,10 @@ static ssize_t eventfd_read(struct kiocb *iocb, struct iov_iter *to)
+ 		__set_current_state(TASK_RUNNING);
+ 	}
+ 	eventfd_ctx_do_read(ctx, &ucnt);
++	current->in_eventfd = 1;
+ 	if (waitqueue_active(&ctx->wqh))
+ 		wake_up_locked_poll(&ctx->wqh, EPOLLOUT);
++	current->in_eventfd = 0;
+ 	spin_unlock_irq(&ctx->wqh.lock);
+ 	if (unlikely(copy_to_iter(&ucnt, sizeof(ucnt), to) != sizeof(ucnt)))
+ 		return -EFAULT;
+@@ -301,8 +303,10 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c
+ 	}
+ 	if (likely(res > 0)) {
+ 		ctx->count += ucnt;
++		current->in_eventfd = 1;
+ 		if (waitqueue_active(&ctx->wqh))
+ 			wake_up_locked_poll(&ctx->wqh, EPOLLIN);
++		current->in_eventfd = 0;
+ 	}
+ 	spin_unlock_irq(&ctx->wqh.lock);
+ 
+diff --git a/fs/ext2/super.c b/fs/ext2/super.c
+index 252c742379cfb..03f2af98b1b48 100644
+--- a/fs/ext2/super.c
++++ b/fs/ext2/super.c
+@@ -163,7 +163,7 @@ static void ext2_put_super (struct super_block * sb)
+ 	db_count = sbi->s_gdb_count;
+ 	for (i = 0; i < db_count; i++)
+ 		brelse(sbi->s_group_desc[i]);
+-	kfree(sbi->s_group_desc);
++	kvfree(sbi->s_group_desc);
+ 	kfree(sbi->s_debts);
+ 	percpu_counter_destroy(&sbi->s_freeblocks_counter);
+ 	percpu_counter_destroy(&sbi->s_freeinodes_counter);
+@@ -1052,6 +1052,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
+ 			sbi->s_blocks_per_group);
+ 		goto failed_mount;
+ 	}
++	/* At least inode table, bitmaps, and sb have to fit in one group */
++	if (sbi->s_blocks_per_group <= sbi->s_itb_per_group + 3) {
++		ext2_msg(sb, KERN_ERR,
++			"error: #blocks per group smaller than metadata size: %lu <= %lu",
++			sbi->s_blocks_per_group, sbi->s_inodes_per_group + 3);
++		goto failed_mount;
++	}
+ 	if (sbi->s_frags_per_group > sb->s_blocksize * 8) {
+ 		ext2_msg(sb, KERN_ERR,
+ 			"error: #fragments per group too big: %lu",
+@@ -1065,9 +1072,14 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
+ 			sbi->s_inodes_per_group);
+ 		goto failed_mount;
+ 	}
++	if (sb_bdev_nr_blocks(sb) < le32_to_cpu(es->s_blocks_count)) {
++		ext2_msg(sb, KERN_ERR,
++			 "bad geometry: block count %u exceeds size of device (%u blocks)",
++			 le32_to_cpu(es->s_blocks_count),
++			 (unsigned)sb_bdev_nr_blocks(sb));
++		goto failed_mount;
++	}
+ 
+-	if (EXT2_BLOCKS_PER_GROUP(sb) == 0)
+-		goto cantfind_ext2;
+ 	sbi->s_groups_count = ((le32_to_cpu(es->s_blocks_count) -
+ 				le32_to_cpu(es->s_first_data_block) - 1)
+ 					/ EXT2_BLOCKS_PER_GROUP(sb)) + 1;
+@@ -1080,7 +1092,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
+ 	}
+ 	db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) /
+ 		   EXT2_DESC_PER_BLOCK(sb);
+-	sbi->s_group_desc = kmalloc_array(db_count,
++	sbi->s_group_desc = kvmalloc_array(db_count,
+ 					   sizeof(struct buffer_head *),
+ 					   GFP_KERNEL);
+ 	if (sbi->s_group_desc == NULL) {
+@@ -1206,7 +1218,7 @@ failed_mount2:
+ 	for (i = 0; i < db_count; i++)
+ 		brelse(sbi->s_group_desc[i]);
+ failed_mount_group_desc:
+-	kfree(sbi->s_group_desc);
++	kvfree(sbi->s_group_desc);
+ 	kfree(sbi->s_debts);
+ failed_mount:
+ 	brelse(bh);
+diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c
+index 2af962cbb835f..b26f304baa52e 100644
+--- a/fs/ext4/fast_commit.c
++++ b/fs/ext4/fast_commit.c
+@@ -874,22 +874,25 @@ static int ext4_fc_write_inode(struct inode *inode, u32 *crc)
+ 	tl.fc_tag = cpu_to_le16(EXT4_FC_TAG_INODE);
+ 	tl.fc_len = cpu_to_le16(inode_len + sizeof(fc_inode.fc_ino));
+ 
++	ret = -ECANCELED;
+ 	dst = ext4_fc_reserve_space(inode->i_sb,
+ 			sizeof(tl) + inode_len + sizeof(fc_inode.fc_ino), crc);
+ 	if (!dst)
+-		return -ECANCELED;
++		goto err;
+ 
+ 	if (!ext4_fc_memcpy(inode->i_sb, dst, &tl, sizeof(tl), crc))
+-		return -ECANCELED;
++		goto err;
+ 	dst += sizeof(tl);
+ 	if (!ext4_fc_memcpy(inode->i_sb, dst, &fc_inode, sizeof(fc_inode), crc))
+-		return -ECANCELED;
++		goto err;
+ 	dst += sizeof(fc_inode);
+ 	if (!ext4_fc_memcpy(inode->i_sb, dst, (u8 *)ext4_raw_inode(&iloc),
+ 					inode_len, crc))
+-		return -ECANCELED;
+-
+-	return 0;
++		goto err;
++	ret = 0;
++err:
++	brelse(iloc.bh);
++	return ret;
+ }
+ 
+ /*
+@@ -1491,13 +1494,15 @@ static int ext4_fc_record_modified_inode(struct super_block *sb, int ino)
+ 		if (state->fc_modified_inodes[i] == ino)
+ 			return 0;
+ 	if (state->fc_modified_inodes_used == state->fc_modified_inodes_size) {
+-		state->fc_modified_inodes = krealloc(
+-				state->fc_modified_inodes,
++		int *fc_modified_inodes;
++
++		fc_modified_inodes = krealloc(state->fc_modified_inodes,
+ 				sizeof(int) * (state->fc_modified_inodes_size +
+ 				EXT4_FC_REPLAY_REALLOC_INCREMENT),
+ 				GFP_KERNEL);
+-		if (!state->fc_modified_inodes)
++		if (!fc_modified_inodes)
+ 			return -ENOMEM;
++		state->fc_modified_inodes = fc_modified_inodes;
+ 		state->fc_modified_inodes_size +=
+ 			EXT4_FC_REPLAY_REALLOC_INCREMENT;
+ 	}
+@@ -1682,15 +1687,18 @@ int ext4_fc_record_regions(struct super_block *sb, int ino,
+ 	if (replay && state->fc_regions_used != state->fc_regions_valid)
+ 		state->fc_regions_used = state->fc_regions_valid;
+ 	if (state->fc_regions_used == state->fc_regions_size) {
++		struct ext4_fc_alloc_region *fc_regions;
++
++		fc_regions = krealloc(state->fc_regions,
++				      sizeof(struct ext4_fc_alloc_region) *
++				      (state->fc_regions_size +
++				       EXT4_FC_REPLAY_REALLOC_INCREMENT),
++				      GFP_KERNEL);
++		if (!fc_regions)
++			return -ENOMEM;
+ 		state->fc_regions_size +=
+ 			EXT4_FC_REPLAY_REALLOC_INCREMENT;
+-		state->fc_regions = krealloc(
+-					state->fc_regions,
+-					state->fc_regions_size *
+-					sizeof(struct ext4_fc_alloc_region),
+-					GFP_KERNEL);
+-		if (!state->fc_regions)
+-			return -ENOMEM;
++		state->fc_regions = fc_regions;
+ 	}
+ 	region = &state->fc_regions[state->fc_regions_used++];
+ 	region->ino = ino;
+diff --git a/fs/ext4/file.c b/fs/ext4/file.c
+index 109d07629f81f..847a2f806b8f6 100644
+--- a/fs/ext4/file.c
++++ b/fs/ext4/file.c
+@@ -528,6 +528,12 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
+ 		ret = -EAGAIN;
+ 		goto out;
+ 	}
++	/*
++	 * Make sure inline data cannot be created anymore since we are going
++	 * to allocate blocks for DIO. We know the inode does not have any
++	 * inline data now because ext4_dio_supported() checked for that.
++	 */
++	ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
+ 
+ 	offset = iocb->ki_pos;
+ 	count = ret;
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 601214453c3ae..6da73be32bff3 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1188,6 +1188,13 @@ retry_grab:
+ 	page = grab_cache_page_write_begin(mapping, index);
+ 	if (!page)
+ 		return -ENOMEM;
++	/*
++	 * The same as page allocation, we prealloc buffer heads before
++	 * starting the handle.
++	 */
++	if (!page_has_buffers(page))
++		create_empty_buffers(page, inode->i_sb->s_blocksize, 0);
++
+ 	unlock_page(page);
+ 
+ retry_journal:
+@@ -5342,6 +5349,7 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
+ 	int error, rc = 0;
+ 	int orphan = 0;
+ 	const unsigned int ia_valid = attr->ia_valid;
++	bool inc_ivers = true;
+ 
+ 	if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb))))
+ 		return -EIO;
+@@ -5425,8 +5433,8 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
+ 			return -EINVAL;
+ 		}
+ 
+-		if (IS_I_VERSION(inode) && attr->ia_size != inode->i_size)
+-			inode_inc_iversion(inode);
++		if (attr->ia_size == inode->i_size)
++			inc_ivers = false;
+ 
+ 		if (shrink) {
+ 			if (ext4_should_order_data(inode)) {
+@@ -5528,6 +5536,8 @@ out_mmap_sem:
+ 	}
+ 
+ 	if (!error) {
++		if (inc_ivers)
++			inode_inc_iversion(inode);
+ 		setattr_copy(mnt_userns, inode, attr);
+ 		mark_inode_dirty(inode);
+ 	}
+@@ -5731,9 +5741,6 @@ int ext4_mark_iloc_dirty(handle_t *handle,
+ 	}
+ 	ext4_fc_track_inode(handle, inode);
+ 
+-	if (IS_I_VERSION(inode))
+-		inode_inc_iversion(inode);
+-
+ 	/* the do_update_inode consumes one bh->b_count */
+ 	get_bh(iloc->bh);
+ 
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index 3cf3ec4b1c214..ad3a294a88eb2 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -452,6 +452,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
+ 	swap_inode_data(inode, inode_bl);
+ 
+ 	inode->i_ctime = inode_bl->i_ctime = current_time(inode);
++	inode_inc_iversion(inode);
+ 
+ 	inode->i_generation = prandom_u32();
+ 	inode_bl->i_generation = prandom_u32();
+@@ -665,6 +666,7 @@ static int ext4_ioctl_setflags(struct inode *inode,
+ 	ext4_set_inode_flags(inode, false);
+ 
+ 	inode->i_ctime = current_time(inode);
++	inode_inc_iversion(inode);
+ 
+ 	err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+ flags_err:
+@@ -775,6 +777,7 @@ static int ext4_ioctl_setproject(struct inode *inode, __u32 projid)
+ 
+ 	EXT4_I(inode)->i_projid = kprojid;
+ 	inode->i_ctime = current_time(inode);
++	inode_inc_iversion(inode);
+ out_dirty:
+ 	rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
+ 	if (!err)
+@@ -1257,6 +1260,7 @@ static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ 		err = ext4_reserve_inode_write(handle, inode, &iloc);
+ 		if (err == 0) {
+ 			inode->i_ctime = current_time(inode);
++			inode_inc_iversion(inode);
+ 			inode->i_generation = generation;
+ 			err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+ 		}
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 3a31b662f6619..4183a4cb4a21e 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -85,15 +85,20 @@ static struct buffer_head *ext4_append(handle_t *handle,
+ 		return bh;
+ 	inode->i_size += inode->i_sb->s_blocksize;
+ 	EXT4_I(inode)->i_disksize = inode->i_size;
++	err = ext4_mark_inode_dirty(handle, inode);
++	if (err)
++		goto out;
+ 	BUFFER_TRACE(bh, "get_write_access");
+ 	err = ext4_journal_get_write_access(handle, inode->i_sb, bh,
+ 					    EXT4_JTR_NONE);
+-	if (err) {
+-		brelse(bh);
+-		ext4_std_error(inode->i_sb, err);
+-		return ERR_PTR(err);
+-	}
++	if (err)
++		goto out;
+ 	return bh;
++
++out:
++	brelse(bh);
++	ext4_std_error(inode->i_sb, err);
++	return ERR_PTR(err);
+ }
+ 
+ static int ext4_dx_csum_verify(struct inode *inode,
+@@ -126,7 +131,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
+ 	struct ext4_dir_entry *dirent;
+ 	int is_dx_block = 0;
+ 
+-	if (block >= inode->i_size) {
++	if (block >= inode->i_size >> inode->i_blkbits) {
+ 		ext4_error_inode(inode, func, line, block,
+ 		       "Attempting to read directory block (%u) that is past i_size (%llu)",
+ 		       block, inode->i_size);
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index fea2a68d067b0..6dfe9ccae0c50 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -2122,7 +2122,7 @@ retry:
+ 			goto out;
+ 	}
+ 
+-	if (ext4_blocks_count(es) == n_blocks_count)
++	if (ext4_blocks_count(es) == n_blocks_count && n_blocks_count_retry == 0)
+ 		goto out;
+ 
+ 	err = ext4_alloc_flex_bg_array(sb, n_group + 1);
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 9a66abcca1a85..091db733834ee 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -205,19 +205,12 @@ int ext4_read_bh(struct buffer_head *bh, blk_opf_t op_flags, bh_end_io_t *end_io
+ 
+ int ext4_read_bh_lock(struct buffer_head *bh, blk_opf_t op_flags, bool wait)
+ {
+-	if (trylock_buffer(bh)) {
+-		if (wait)
+-			return ext4_read_bh(bh, op_flags, NULL);
++	lock_buffer(bh);
++	if (!wait) {
+ 		ext4_read_bh_nowait(bh, op_flags, NULL);
+ 		return 0;
+ 	}
+-	if (wait) {
+-		wait_on_buffer(bh);
+-		if (buffer_uptodate(bh))
+-			return 0;
+-		return -EIO;
+-	}
+-	return 0;
++	return ext4_read_bh(bh, op_flags, NULL);
+ }
+ 
+ /*
+@@ -264,7 +257,8 @@ void ext4_sb_breadahead_unmovable(struct super_block *sb, sector_t block)
+ 	struct buffer_head *bh = sb_getblk_gfp(sb, block, 0);
+ 
+ 	if (likely(bh)) {
+-		ext4_read_bh_lock(bh, REQ_RAHEAD, false);
++		if (trylock_buffer(bh))
++			ext4_read_bh_nowait(bh, REQ_RAHEAD, NULL);
+ 		brelse(bh);
+ 	}
+ }
+@@ -1585,7 +1579,7 @@ enum {
+ 	Opt_inlinecrypt,
+ 	Opt_usrjquota, Opt_grpjquota, Opt_quota,
+ 	Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err,
+-	Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_i_version,
++	Opt_usrquota, Opt_grpquota, Opt_prjquota,
+ 	Opt_dax, Opt_dax_always, Opt_dax_inode, Opt_dax_never,
+ 	Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_warn_on_error,
+ 	Opt_nowarn_on_error, Opt_mblk_io_submit, Opt_debug_want_extra_isize,
+@@ -1694,7 +1688,7 @@ static const struct fs_parameter_spec ext4_param_specs[] = {
+ 	fsparam_flag	("barrier",		Opt_barrier),
+ 	fsparam_u32	("barrier",		Opt_barrier),
+ 	fsparam_flag	("nobarrier",		Opt_nobarrier),
+-	fsparam_flag	("i_version",		Opt_i_version),
++	fsparam_flag	("i_version",		Opt_removed),
+ 	fsparam_flag	("dax",			Opt_dax),
+ 	fsparam_enum	("dax",			Opt_dax_type, ext4_param_dax),
+ 	fsparam_u32	("stripe",		Opt_stripe),
+@@ -2140,11 +2134,6 @@ static int ext4_parse_param(struct fs_context *fc, struct fs_parameter *param)
+ 	case Opt_abort:
+ 		ctx_set_mount_flag(ctx, EXT4_MF_FS_ABORTED);
+ 		return 0;
+-	case Opt_i_version:
+-		ext4_msg(NULL, KERN_WARNING, deprecated_msg, param->key, "5.20");
+-		ext4_msg(NULL, KERN_WARNING, "Use iversion instead\n");
+-		ctx_set_flags(ctx, SB_I_VERSION);
+-		return 0;
+ 	case Opt_inlinecrypt:
+ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT
+ 		ctx_set_flags(ctx, SB_INLINECRYPT);
+@@ -2814,14 +2803,6 @@ static void ext4_apply_options(struct fs_context *fc, struct super_block *sb)
+ 	sb->s_flags &= ~ctx->mask_s_flags;
+ 	sb->s_flags |= ctx->vals_s_flags;
+ 
+-	/*
+-	 * i_version differs from common mount option iversion so we have
+-	 * to let vfs know that it was set, otherwise it would get cleared
+-	 * on remount
+-	 */
+-	if (ctx->mask_s_flags & SB_I_VERSION)
+-		fc->sb_flags |= SB_I_VERSION;
+-
+ #define APPLY(X) ({ if (ctx->spec & EXT4_SPEC_##X) sbi->X = ctx->X; })
+ 	APPLY(s_commit_interval);
+ 	APPLY(s_stripe);
+@@ -2970,8 +2951,6 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
+ 		SEQ_OPTS_PRINT("min_batch_time=%u", sbi->s_min_batch_time);
+ 	if (nodefs || sbi->s_max_batch_time != EXT4_DEF_MAX_BATCH_TIME)
+ 		SEQ_OPTS_PRINT("max_batch_time=%u", sbi->s_max_batch_time);
+-	if (sb->s_flags & SB_I_VERSION)
+-		SEQ_OPTS_PUTS("i_version");
+ 	if (nodefs || sbi->s_stripe)
+ 		SEQ_OPTS_PRINT("stripe=%lu", sbi->s_stripe);
+ 	if (nodefs || EXT4_MOUNT_DATA_FLAGS &
+@@ -3767,6 +3746,7 @@ static int ext4_lazyinit_thread(void *arg)
+ 	unsigned long next_wakeup, cur;
+ 
+ 	BUG_ON(NULL == eli);
++	set_freezable();
+ 
+ cont_thread:
+ 	while (true) {
+@@ -3982,9 +3962,9 @@ int ext4_register_li_request(struct super_block *sb,
+ 		goto out;
+ 	}
+ 
+-	if (test_opt(sb, NO_PREFETCH_BLOCK_BITMAPS) &&
+-	    (first_not_zeroed == ngroups || sb_rdonly(sb) ||
+-	     !test_opt(sb, INIT_INODE_TABLE)))
++	if (sb_rdonly(sb) ||
++	    (test_opt(sb, NO_PREFETCH_BLOCK_BITMAPS) &&
++	     (first_not_zeroed == ngroups || !test_opt(sb, INIT_INODE_TABLE))))
+ 		goto out;
+ 
+ 	elr = ext4_li_request_new(sb, first_not_zeroed);
+@@ -4640,6 +4620,9 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
+ 	sb->s_flags = (sb->s_flags & ~SB_POSIXACL) |
+ 		(test_opt(sb, POSIX_ACL) ? SB_POSIXACL : 0);
+ 
++	/* i_version is always enabled now */
++	sb->s_flags |= SB_I_VERSION;
++
+ 	if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV &&
+ 	    (ext4_has_compat_features(sb) ||
+ 	     ext4_has_ro_compat_features(sb) ||
+@@ -6653,7 +6636,7 @@ static int ext4_write_info(struct super_block *sb, int type)
+ 	handle_t *handle;
+ 
+ 	/* Data block + inode block */
+-	handle = ext4_journal_start(d_inode(sb->s_root), EXT4_HT_QUOTA, 2);
++	handle = ext4_journal_start_sb(sb, EXT4_HT_QUOTA, 2);
+ 	if (IS_ERR(handle))
+ 		return PTR_ERR(handle);
+ 	ret = dquot_commit_info(sb, type);
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 533216e80fa2b..36d6ba7190b6d 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -2412,6 +2412,7 @@ retry_inode:
+ 	if (!error) {
+ 		ext4_xattr_update_super_block(handle, inode->i_sb);
+ 		inode->i_ctime = current_time(inode);
++		inode_inc_iversion(inode);
+ 		if (!value)
+ 			no_expand = 0;
+ 		error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
+index 8259e0fa97e1f..e04ed60cc9e26 100644
+--- a/fs/f2fs/checkpoint.c
++++ b/fs/f2fs/checkpoint.c
+@@ -140,7 +140,7 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
+ 	unsigned int segno, offset;
+ 	bool exist;
+ 
+-	if (type != DATA_GENERIC_ENHANCE && type != DATA_GENERIC_ENHANCE_READ)
++	if (type == DATA_GENERIC)
+ 		return true;
+ 
+ 	segno = GET_SEGNO(sbi, blkaddr);
+@@ -148,6 +148,13 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
+ 	se = get_seg_entry(sbi, segno);
+ 
+ 	exist = f2fs_test_bit(offset, se->cur_valid_map);
++	if (exist && type == DATA_GENERIC_ENHANCE_UPDATE) {
++		f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
++			 blkaddr, exist);
++		set_sbi_flag(sbi, SBI_NEED_FSCK);
++		return exist;
++	}
++
+ 	if (!exist && type == DATA_GENERIC_ENHANCE) {
+ 		f2fs_err(sbi, "Inconsistent error blkaddr:%u, sit bitmap:%d",
+ 			 blkaddr, exist);
+@@ -185,6 +192,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
+ 	case DATA_GENERIC:
+ 	case DATA_GENERIC_ENHANCE:
+ 	case DATA_GENERIC_ENHANCE_READ:
++	case DATA_GENERIC_ENHANCE_UPDATE:
+ 		if (unlikely(blkaddr >= MAX_BLKADDR(sbi) ||
+ 				blkaddr < MAIN_BLKADDR(sbi))) {
+ 			f2fs_warn(sbi, "access invalid blkaddr:%u",
+@@ -1053,7 +1061,8 @@ void f2fs_remove_dirty_inode(struct inode *inode)
+ 	spin_unlock(&sbi->inode_lock[type]);
+ }
+ 
+-int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
++int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type,
++						bool from_cp)
+ {
+ 	struct list_head *head;
+ 	struct inode *inode;
+@@ -1088,11 +1097,15 @@ retry:
+ 	if (inode) {
+ 		unsigned long cur_ino = inode->i_ino;
+ 
+-		F2FS_I(inode)->cp_task = current;
++		if (from_cp)
++			F2FS_I(inode)->cp_task = current;
++		F2FS_I(inode)->wb_task = current;
+ 
+ 		filemap_fdatawrite(inode->i_mapping);
+ 
+-		F2FS_I(inode)->cp_task = NULL;
++		F2FS_I(inode)->wb_task = NULL;
++		if (from_cp)
++			F2FS_I(inode)->cp_task = NULL;
+ 
+ 		iput(inode);
+ 		/* We need to give cpu to another writers. */
+@@ -1221,7 +1234,7 @@ retry_flush_dents:
+ 	/* write all the dirty dentry pages */
+ 	if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
+ 		f2fs_unlock_all(sbi);
+-		err = f2fs_sync_dirty_inodes(sbi, DIR_INODE);
++		err = f2fs_sync_dirty_inodes(sbi, DIR_INODE, true);
+ 		if (err)
+ 			return err;
+ 		cond_resched();
+@@ -1892,15 +1905,27 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi)
+ void f2fs_stop_ckpt_thread(struct f2fs_sb_info *sbi)
+ {
+ 	struct ckpt_req_control *cprc = &sbi->cprc_info;
++	struct task_struct *ckpt_task;
+ 
+-	if (cprc->f2fs_issue_ckpt) {
+-		struct task_struct *ckpt_task = cprc->f2fs_issue_ckpt;
++	if (!cprc->f2fs_issue_ckpt)
++		return;
+ 
+-		cprc->f2fs_issue_ckpt = NULL;
+-		kthread_stop(ckpt_task);
++	ckpt_task = cprc->f2fs_issue_ckpt;
++	cprc->f2fs_issue_ckpt = NULL;
++	kthread_stop(ckpt_task);
+ 
+-		flush_remained_ckpt_reqs(sbi, NULL);
+-	}
++	f2fs_flush_ckpt_thread(sbi);
++}
++
++void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi)
++{
++	struct ckpt_req_control *cprc = &sbi->cprc_info;
++
++	flush_remained_ckpt_reqs(sbi, NULL);
++
++	/* Let's wait for the previous dispatched checkpoint. */
++	while (atomic_read(&cprc->queued_ckpt))
++		io_schedule_timeout(DEFAULT_IO_TIMEOUT);
+ }
+ 
+ void f2fs_init_ckpt_req_control(struct f2fs_sb_info *sbi)
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index aa3ccddfa0376..5e88272d94e42 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -2856,7 +2856,7 @@ out:
+ 	}
+ 	unlock_page(page);
+ 	if (!S_ISDIR(inode->i_mode) && !IS_NOQUOTA(inode) &&
+-			!F2FS_I(inode)->cp_task && allow_balance)
++			!F2FS_I(inode)->wb_task && allow_balance)
+ 		f2fs_balance_fs(sbi, need_balance_fs);
+ 
+ 	if (unlikely(f2fs_cp_error(sbi))) {
+@@ -3156,7 +3156,7 @@ static inline bool __should_serialize_io(struct inode *inode,
+ 					struct writeback_control *wbc)
+ {
+ 	/* to avoid deadlock in path of data flush */
+-	if (F2FS_I(inode)->cp_task)
++	if (F2FS_I(inode)->wb_task)
+ 		return false;
+ 
+ 	if (!S_ISREG(inode->i_mode))
+diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
+index 866e72b29bd5a..761fd42c93f23 100644
+--- a/fs/f2fs/extent_cache.c
++++ b/fs/f2fs/extent_cache.c
+@@ -804,9 +804,8 @@ void f2fs_drop_extent_tree(struct inode *inode)
+ 	if (!f2fs_may_extent_tree(inode))
+ 		return;
+ 
+-	set_inode_flag(inode, FI_NO_EXTENT);
+-
+ 	write_lock(&et->lock);
++	set_inode_flag(inode, FI_NO_EXTENT);
+ 	__free_extent_tree(sbi, et);
+ 	if (et->largest.len) {
+ 		et->largest.len = 0;
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 3c7cdb70fe2ef..1e57b11ffe2a6 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -266,6 +266,10 @@ enum {
+ 					 * condition of read on truncated area
+ 					 * by extent_cache
+ 					 */
++	DATA_GENERIC_ENHANCE_UPDATE,	/*
++					 * strong check on range and segment
++					 * bitmap for update case
++					 */
+ 	META_GENERIC,
+ };
+ 
+@@ -782,6 +786,7 @@ struct f2fs_inode_info {
+ 	unsigned int clevel;		/* maximum level of given file name */
+ 	struct task_struct *task;	/* lookup and create consistency */
+ 	struct task_struct *cp_task;	/* separate cp/wb IO stats*/
++	struct task_struct *wb_task;	/* indicate inode is in context of writeback */
+ 	nid_t i_xattr_nid;		/* node id that contains xattrs */
+ 	loff_t	last_disk_size;		/* lastly written file size */
+ 	spinlock_t i_size_lock;		/* protect last_disk_size */
+@@ -3707,6 +3712,7 @@ static inline bool f2fs_need_rand_seg(struct f2fs_sb_info *sbi)
+  * checkpoint.c
+  */
+ void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io);
++void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi);
+ struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
+ struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
+ struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index);
+@@ -3736,7 +3742,8 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi);
+ int f2fs_get_valid_checkpoint(struct f2fs_sb_info *sbi);
+ void f2fs_update_dirty_folio(struct inode *inode, struct folio *folio);
+ void f2fs_remove_dirty_inode(struct inode *inode);
+-int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type);
++int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type,
++								bool from_cp);
+ void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type);
+ u64 f2fs_get_sectors_written(struct f2fs_sb_info *sbi);
+ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc);
+@@ -4508,7 +4515,12 @@ static inline bool f2fs_force_buffered_io(struct inode *inode,
+ 	/* disallow direct IO if any of devices has unaligned blksize */
+ 	if (f2fs_is_multi_device(sbi) && !sbi->aligned_blksize)
+ 		return true;
+-
++	/*
++	 * for blkzoned device, fallback direct IO to buffered IO, so
++	 * all IOs can be serialized by log-structured write.
++	 */
++	if (f2fs_sb_has_blkzoned(sbi) && (rw == WRITE))
++		return true;
+ 	if (f2fs_lfs_mode(sbi) && (rw == WRITE)) {
+ 		if (block_unaligned_IO(inode, iocb, iter))
+ 			return true;
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 6da21d405ce1e..73881314bdda8 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -97,14 +97,10 @@ static int gc_thread_func(void *data)
+ 		 */
+ 		if (sbi->gc_mode == GC_URGENT_HIGH) {
+ 			spin_lock(&sbi->gc_urgent_high_lock);
+-			if (sbi->gc_urgent_high_limited) {
+-				if (!sbi->gc_urgent_high_remaining) {
+-					sbi->gc_urgent_high_limited = false;
+-					spin_unlock(&sbi->gc_urgent_high_lock);
+-					sbi->gc_mode = GC_NORMAL;
+-					continue;
+-				}
+-				sbi->gc_urgent_high_remaining--;
++			if (sbi->gc_urgent_high_limited &&
++					!sbi->gc_urgent_high_remaining--) {
++				sbi->gc_urgent_high_limited = false;
++				sbi->gc_mode = GC_NORMAL;
+ 			}
+ 			spin_unlock(&sbi->gc_urgent_high_lock);
+ 		}
+@@ -1082,7 +1078,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+ {
+ 	struct page *node_page;
+ 	nid_t nid;
+-	unsigned int ofs_in_node;
++	unsigned int ofs_in_node, max_addrs;
+ 	block_t source_blkaddr;
+ 
+ 	nid = le32_to_cpu(sum->nid);
+@@ -1108,6 +1104,14 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
+ 		return false;
+ 	}
+ 
++	max_addrs = IS_INODE(node_page) ? DEF_ADDRS_PER_INODE :
++						DEF_ADDRS_PER_BLOCK;
++	if (ofs_in_node >= max_addrs) {
++		f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u",
++			ofs_in_node, dni->ino, dni->nid, max_addrs);
++		return false;
++	}
++
+ 	*nofs = ofs_of_node(node_page);
+ 	source_blkaddr = data_blkaddr(NULL, node_page, ofs_in_node);
+ 	f2fs_put_page(node_page, 1);
+diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
+index dcd0a1e350951..5c9facec98f69 100644
+--- a/fs/f2fs/recovery.c
++++ b/fs/f2fs/recovery.c
+@@ -474,7 +474,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
+ 	struct dnode_of_data tdn = *dn;
+ 	nid_t ino, nid;
+ 	struct inode *inode;
+-	unsigned int offset;
++	unsigned int offset, ofs_in_node, max_addrs;
+ 	block_t bidx;
+ 	int i;
+ 
+@@ -501,15 +501,24 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
+ got_it:
+ 	/* Use the locked dnode page and inode */
+ 	nid = le32_to_cpu(sum.nid);
++	ofs_in_node = le16_to_cpu(sum.ofs_in_node);
++
++	max_addrs = ADDRS_PER_PAGE(dn->node_page, dn->inode);
++	if (ofs_in_node >= max_addrs) {
++		f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%lu, nid:%u, max:%u",
++			ofs_in_node, dn->inode->i_ino, nid, max_addrs);
++		return -EFSCORRUPTED;
++	}
++
+ 	if (dn->inode->i_ino == nid) {
+ 		tdn.nid = nid;
+ 		if (!dn->inode_page_locked)
+ 			lock_page(dn->inode_page);
+ 		tdn.node_page = dn->inode_page;
+-		tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node);
++		tdn.ofs_in_node = ofs_in_node;
+ 		goto truncate_out;
+ 	} else if (dn->nid == nid) {
+-		tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node);
++		tdn.ofs_in_node = ofs_in_node;
+ 		goto truncate_out;
+ 	}
+ 
+@@ -698,6 +707,14 @@ retry_prev:
+ 				goto err;
+ 			}
+ 
++			if (f2fs_is_valid_blkaddr(sbi, dest,
++					DATA_GENERIC_ENHANCE_UPDATE)) {
++				f2fs_err(sbi, "Inconsistent dest blkaddr:%u, ino:%lu, ofs:%u",
++					dest, inode->i_ino, dn.ofs_in_node);
++				err = -EFSCORRUPTED;
++				goto err;
++			}
++
+ 			/* write dummy data page */
+ 			f2fs_replace_block(sbi, &dn, src, dest,
+ 						ni.version, false, false);
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index 0de21f82d7bc8..84bad18ce13d5 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -476,7 +476,7 @@ do_sync:
+ 		mutex_lock(&sbi->flush_lock);
+ 
+ 		blk_start_plug(&plug);
+-		f2fs_sync_dirty_inodes(sbi, FILE_INODE);
++		f2fs_sync_dirty_inodes(sbi, FILE_INODE, false);
+ 		blk_finish_plug(&plug);
+ 
+ 		mutex_unlock(&sbi->flush_lock);
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 2451623c05a7a..5415c06d8246f 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -301,10 +301,10 @@ static void f2fs_destroy_casefold_cache(void) { }
+ 
+ static inline void limit_reserve_root(struct f2fs_sb_info *sbi)
+ {
+-	block_t limit = min((sbi->user_block_count << 1) / 1000,
++	block_t limit = min((sbi->user_block_count >> 3),
+ 			sbi->user_block_count - sbi->reserved_blocks);
+ 
+-	/* limit is 0.2% */
++	/* limit is 12.5% */
+ 	if (test_opt(sbi, RESERVE_ROOT) &&
+ 			F2FS_OPTION(sbi).root_reserved_blocks > limit) {
+ 		F2FS_OPTION(sbi).root_reserved_blocks = limit;
+@@ -1666,9 +1666,8 @@ static int f2fs_freeze(struct super_block *sb)
+ 	if (is_sbi_flag_set(F2FS_SB(sb), SBI_IS_DIRTY))
+ 		return -EINVAL;
+ 
+-	/* ensure no checkpoint required */
+-	if (!llist_empty(&F2FS_SB(sb)->cprc_info.issue_list))
+-		return -EINVAL;
++	/* Let's flush checkpoints and stop the thread. */
++	f2fs_flush_ckpt_thread(F2FS_SB(sb));
+ 
+ 	/* to avoid deadlock on f2fs_evict_inode->SB_FREEZE_FS */
+ 	set_sbi_flag(F2FS_SB(sb), SBI_IS_FREEZING);
+@@ -2181,6 +2180,9 @@ static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi)
+ 	f2fs_up_write(&sbi->gc_lock);
+ 
+ 	f2fs_sync_fs(sbi->sb, 1);
++
++	/* Let's ensure there's no pending checkpoint anymore */
++	f2fs_flush_ckpt_thread(sbi);
+ }
+ 
+ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+@@ -2346,6 +2348,9 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
+ 		f2fs_stop_ckpt_thread(sbi);
+ 		need_restart_ckpt = true;
+ 	} else {
++		/* Flush if the prevous checkpoint, if exists. */
++		f2fs_flush_ckpt_thread(sbi);
++
+ 		err = f2fs_start_ckpt_thread(sbi);
+ 		if (err) {
+ 			f2fs_err(sbi,
+diff --git a/fs/file_table.c b/fs/file_table.c
+index 99c6796c9f28a..dd88701e54a93 100644
+--- a/fs/file_table.c
++++ b/fs/file_table.c
+@@ -324,12 +324,7 @@ static void __fput(struct file *file)
+ 	}
+ 	fops_put(file->f_op);
+ 	put_pid(file->f_owner.pid);
+-	if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
+-		i_readcount_dec(inode);
+-	if (mode & FMODE_WRITER) {
+-		put_write_access(inode);
+-		__mnt_drop_write(mnt);
+-	}
++	put_file_access(file);
+ 	dput(dentry);
+ 	if (unlikely(mode & FMODE_NEED_UNMOUNT))
+ 		dissolve_on_fput(mnt);
+diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
+index 08a1993ab7fd3..443f83382b9bd 100644
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1718,9 +1718,14 @@ static int writeback_single_inode(struct inode *inode,
+ 	 */
+ 	if (!(inode->i_state & I_DIRTY_ALL))
+ 		inode_cgwb_move_to_attached(inode, wb);
+-	else if (!(inode->i_state & I_SYNC_QUEUED) &&
+-		 (inode->i_state & I_DIRTY))
+-		redirty_tail_locked(inode, wb);
++	else if (!(inode->i_state & I_SYNC_QUEUED)) {
++		if ((inode->i_state & I_DIRTY))
++			redirty_tail_locked(inode, wb);
++		else if (inode->i_state & I_DIRTY_TIME) {
++			inode->dirtied_when = jiffies;
++			inode_io_list_move_locked(inode, wb, &wb->b_dirty_time);
++		}
++	}
+ 
+ 	spin_unlock(&wb->list_lock);
+ 	inode_sync_complete(inode);
+@@ -2369,6 +2374,20 @@ void __mark_inode_dirty(struct inode *inode, int flags)
+ 	trace_writeback_mark_inode_dirty(inode, flags);
+ 
+ 	if (flags & I_DIRTY_INODE) {
++		/*
++		 * Inode timestamp update will piggback on this dirtying.
++		 * We tell ->dirty_inode callback that timestamps need to
++		 * be updated by setting I_DIRTY_TIME in flags.
++		 */
++		if (inode->i_state & I_DIRTY_TIME) {
++			spin_lock(&inode->i_lock);
++			if (inode->i_state & I_DIRTY_TIME) {
++				inode->i_state &= ~I_DIRTY_TIME;
++				flags |= I_DIRTY_TIME;
++			}
++			spin_unlock(&inode->i_lock);
++		}
++
+ 		/*
+ 		 * Notify the filesystem about the inode being dirtied, so that
+ 		 * (if needed) it can update on-disk fields and journal the
+@@ -2378,7 +2397,8 @@ void __mark_inode_dirty(struct inode *inode, int flags)
+ 		 */
+ 		trace_writeback_dirty_inode_start(inode, flags);
+ 		if (sb->s_op->dirty_inode)
+-			sb->s_op->dirty_inode(inode, flags & I_DIRTY_INODE);
++			sb->s_op->dirty_inode(inode,
++				flags & (I_DIRTY_INODE | I_DIRTY_TIME));
+ 		trace_writeback_dirty_inode(inode, flags);
+ 
+ 		/* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
+@@ -2399,21 +2419,15 @@ void __mark_inode_dirty(struct inode *inode, int flags)
+ 	 */
+ 	smp_mb();
+ 
+-	if (((inode->i_state & flags) == flags) ||
+-	    (dirtytime && (inode->i_state & I_DIRTY_INODE)))
++	if ((inode->i_state & flags) == flags)
+ 		return;
+ 
+ 	spin_lock(&inode->i_lock);
+-	if (dirtytime && (inode->i_state & I_DIRTY_INODE))
+-		goto out_unlock_inode;
+ 	if ((inode->i_state & flags) != flags) {
+ 		const int was_dirty = inode->i_state & I_DIRTY;
+ 
+ 		inode_attach_wb(inode, NULL);
+ 
+-		/* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
+-		if (flags & I_DIRTY_INODE)
+-			inode->i_state &= ~I_DIRTY_TIME;
+ 		inode->i_state |= flags;
+ 
+ 		/*
+@@ -2486,7 +2500,6 @@ void __mark_inode_dirty(struct inode *inode, int flags)
+ out_unlock:
+ 	if (wb)
+ 		spin_unlock(&wb->list_lock);
+-out_unlock_inode:
+ 	spin_unlock(&inode->i_lock);
+ }
+ EXPORT_SYMBOL(__mark_inode_dirty);
+diff --git a/fs/internal.h b/fs/internal.h
+index 3e206d3e317c4..4372d67a37533 100644
+--- a/fs/internal.h
++++ b/fs/internal.h
+@@ -102,6 +102,16 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
+ extern struct file *alloc_empty_file(int, const struct cred *);
+ extern struct file *alloc_empty_file_noaccount(int, const struct cred *);
+ 
++static inline void put_file_access(struct file *file)
++{
++	if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
++		i_readcount_dec(file->f_inode);
++	} else if (file->f_mode & FMODE_WRITER) {
++		put_write_access(file->f_inode);
++		__mnt_drop_write(file->f_path.mnt);
++	}
++}
++
+ /*
+  * super.c
+  */
+diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
+index ca5c62901541e..77d59c159248d 100644
+--- a/fs/iomap/buffered-io.c
++++ b/fs/iomap/buffered-io.c
+@@ -1421,7 +1421,7 @@ iomap_writepage_map(struct iomap_writepage_ctx *wpc,
+ 	if (!count)
+ 		folio_end_writeback(folio);
+ done:
+-	mapping_set_error(folio->mapping, error);
++	mapping_set_error(inode->i_mapping, error);
+ 	return error;
+ }
+ 
+diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
+index b2b2bc9b88d9d..ec2b55879e3a9 100644
+--- a/fs/jbd2/commit.c
++++ b/fs/jbd2/commit.c
+@@ -570,7 +570,7 @@ void jbd2_journal_commit_transaction(journal_t *journal)
+ 	journal->j_running_transaction = NULL;
+ 	start_time = ktime_get();
+ 	commit_transaction->t_log_start = journal->j_head;
+-	wake_up(&journal->j_wait_transaction_locked);
++	wake_up_all(&journal->j_wait_transaction_locked);
+ 	write_unlock(&journal->j_state_lock);
+ 
+ 	jbd2_debug(3, "JBD2: commit phase 2a\n");
+diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
+index 6350d3857c896..7e08d416a5fd5 100644
+--- a/fs/jbd2/journal.c
++++ b/fs/jbd2/journal.c
+@@ -923,10 +923,16 @@ int jbd2_fc_wait_bufs(journal_t *journal, int num_blks)
+ 	for (i = j_fc_off - 1; i >= j_fc_off - num_blks; i--) {
+ 		bh = journal->j_fc_wbuf[i];
+ 		wait_on_buffer(bh);
++		/*
++		 * Update j_fc_off so jbd2_fc_release_bufs can release remain
++		 * buffer head.
++		 */
++		if (unlikely(!buffer_uptodate(bh))) {
++			journal->j_fc_off = i + 1;
++			return -EIO;
++		}
+ 		put_bh(bh);
+ 		journal->j_fc_wbuf[i] = NULL;
+-		if (unlikely(!buffer_uptodate(bh)))
+-			return -EIO;
+ 	}
+ 
+ 	return 0;
+diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
+index f548479615c69..3688d16fe83b0 100644
+--- a/fs/jbd2/recovery.c
++++ b/fs/jbd2/recovery.c
+@@ -256,6 +256,7 @@ static int fc_do_one_pass(journal_t *journal,
+ 		err = journal->j_fc_replay_callback(journal, bh, pass,
+ 					next_fc_block - journal->j_fc_first,
+ 					expected_commit_id);
++		brelse(bh);
+ 		next_fc_block++;
+ 		if (err < 0 || err == JBD2_FC_REPLAY_STOP)
+ 			break;
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index e1be93ccd81cb..6a404ac1c178f 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -168,7 +168,7 @@ static void wait_transaction_locked(journal_t *journal)
+ 	int need_to_start;
+ 	tid_t tid = journal->j_running_transaction->t_tid;
+ 
+-	prepare_to_wait(&journal->j_wait_transaction_locked, &wait,
++	prepare_to_wait_exclusive(&journal->j_wait_transaction_locked, &wait,
+ 			TASK_UNINTERRUPTIBLE);
+ 	need_to_start = !tid_geq(journal->j_commit_request, tid);
+ 	read_unlock(&journal->j_state_lock);
+@@ -194,7 +194,7 @@ static void wait_transaction_switching(journal_t *journal)
+ 		read_unlock(&journal->j_state_lock);
+ 		return;
+ 	}
+-	prepare_to_wait(&journal->j_wait_transaction_locked, &wait,
++	prepare_to_wait_exclusive(&journal->j_wait_transaction_locked, &wait,
+ 			TASK_UNINTERRUPTIBLE);
+ 	read_unlock(&journal->j_state_lock);
+ 	/*
+@@ -920,7 +920,7 @@ void jbd2_journal_unlock_updates (journal_t *journal)
+ 	write_lock(&journal->j_state_lock);
+ 	--journal->j_barrier_count;
+ 	write_unlock(&journal->j_state_lock);
+-	wake_up(&journal->j_wait_transaction_locked);
++	wake_up_all(&journal->j_wait_transaction_locked);
+ }
+ 
+ static void warn_dirty_buffer(struct buffer_head *bh)
+diff --git a/fs/ksmbd/server.c b/fs/ksmbd/server.c
+index ce42bff42ef9f..a0d635304754a 100644
+--- a/fs/ksmbd/server.c
++++ b/fs/ksmbd/server.c
+@@ -235,10 +235,8 @@ send:
+ 	if (work->sess && work->sess->enc && work->encrypted &&
+ 	    conn->ops->encrypt_resp) {
+ 		rc = conn->ops->encrypt_resp(work);
+-		if (rc < 0) {
++		if (rc < 0)
+ 			conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
+-			goto send;
+-		}
+ 	}
+ 
+ 	ksmbd_conn_write(work);
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
+index 19412ac701a65..7a9497a7b0a30 100644
+--- a/fs/ksmbd/smb2pdu.c
++++ b/fs/ksmbd/smb2pdu.c
+@@ -3808,11 +3808,6 @@ static int __query_dir(struct dir_context *ctx, const char *name, int namlen,
+ 	return 0;
+ }
+ 
+-static void restart_ctx(struct dir_context *ctx)
+-{
+-	ctx->pos = 0;
+-}
+-
+ static int verify_info_level(int info_level)
+ {
+ 	switch (info_level) {
+@@ -3921,7 +3916,6 @@ int smb2_query_dir(struct ksmbd_work *work)
+ 	if (srch_flag & SMB2_REOPEN || srch_flag & SMB2_RESTART_SCANS) {
+ 		ksmbd_debug(SMB, "Restart directory scan\n");
+ 		generic_file_llseek(dir_fp->filp, 0, SEEK_SET);
+-		restart_ctx(&dir_fp->readdir_data.ctx);
+ 	}
+ 
+ 	memset(&d_info, 0, sizeof(struct ksmbd_dir_info));
+@@ -3968,11 +3962,9 @@ int smb2_query_dir(struct ksmbd_work *work)
+ 	 */
+ 	if (!d_info.out_buf_len && !d_info.num_entry)
+ 		goto no_buf_len;
+-	if (rc == 0)
+-		restart_ctx(&dir_fp->readdir_data.ctx);
+-	if (rc == -ENOSPC)
++	if (rc > 0 || rc == -ENOSPC)
+ 		rc = 0;
+-	if (rc)
++	else if (rc)
+ 		goto err_out;
+ 
+ 	d_info.wptr = d_info.rptr;
+@@ -4029,6 +4021,8 @@ err_out2:
+ 		rsp->hdr.Status = STATUS_NO_MEMORY;
+ 	else if (rc == -EFAULT)
+ 		rsp->hdr.Status = STATUS_INVALID_INFO_CLASS;
++	else if (rc == -EIO)
++		rsp->hdr.Status = STATUS_FILE_CORRUPT_ERROR;
+ 	if (!rsp->hdr.Status)
+ 		rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
+ 
+@@ -7643,11 +7637,16 @@ int smb2_ioctl(struct ksmbd_work *work)
+ 			goto out;
+ 		}
+ 
+-		if (in_buf_len < sizeof(struct validate_negotiate_info_req))
+-			return -EINVAL;
++		if (in_buf_len < offsetof(struct validate_negotiate_info_req,
++					  Dialects)) {
++			ret = -EINVAL;
++			goto out;
++		}
+ 
+-		if (out_buf_len < sizeof(struct validate_negotiate_info_rsp))
+-			return -EINVAL;
++		if (out_buf_len < sizeof(struct validate_negotiate_info_rsp)) {
++			ret = -EINVAL;
++			goto out;
++		}
+ 
+ 		ret = fsctl_validate_negotiate_info(conn,
+ 			(struct validate_negotiate_info_req *)&req->Buffer[0],
+diff --git a/fs/ksmbd/smb_common.c b/fs/ksmbd/smb_common.c
+index 7f8ab14fb8ec1..d96da872d70a1 100644
+--- a/fs/ksmbd/smb_common.c
++++ b/fs/ksmbd/smb_common.c
+@@ -4,6 +4,8 @@
+  *   Copyright (C) 2018 Namjae Jeon <linkinjeon@kernel.org>
+  */
+ 
++#include <linux/user_namespace.h>
++
+ #include "smb_common.h"
+ #include "server.h"
+ #include "misc.h"
+@@ -625,8 +627,8 @@ int ksmbd_override_fsids(struct ksmbd_work *work)
+ 	if (!cred)
+ 		return -ENOMEM;
+ 
+-	cred->fsuid = make_kuid(current_user_ns(), uid);
+-	cred->fsgid = make_kgid(current_user_ns(), gid);
++	cred->fsuid = make_kuid(&init_user_ns, uid);
++	cred->fsgid = make_kgid(&init_user_ns, gid);
+ 
+ 	gi = groups_alloc(0);
+ 	if (!gi) {
+diff --git a/fs/mbcache.c b/fs/mbcache.c
+index 47ccfcbe0a22e..e272ad738faff 100644
+--- a/fs/mbcache.c
++++ b/fs/mbcache.c
+@@ -90,8 +90,14 @@ int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
+ 		return -ENOMEM;
+ 
+ 	INIT_LIST_HEAD(&entry->e_list);
+-	/* Initial hash reference */
+-	atomic_set(&entry->e_refcnt, 1);
++	/*
++	 * We create entry with two references. One reference is kept by the
++	 * hash table, the other reference is used to protect us from
++	 * mb_cache_entry_delete_or_get() until the entry is fully setup. This
++	 * avoids nesting of cache->c_list_lock into hash table bit locks which
++	 * is problematic for RT.
++	 */
++	atomic_set(&entry->e_refcnt, 2);
+ 	entry->e_key = key;
+ 	entry->e_value = value;
+ 	entry->e_reusable = reusable;
+@@ -106,15 +112,12 @@ int mb_cache_entry_create(struct mb_cache *cache, gfp_t mask, u32 key,
+ 		}
+ 	}
+ 	hlist_bl_add_head(&entry->e_hash_list, head);
+-	/*
+-	 * Add entry to LRU list before it can be found by
+-	 * mb_cache_entry_delete() to avoid races
+-	 */
++	hlist_bl_unlock(head);
+ 	spin_lock(&cache->c_list_lock);
+ 	list_add_tail(&entry->e_list, &cache->c_list);
+ 	cache->c_entry_count++;
+ 	spin_unlock(&cache->c_list_lock);
+-	hlist_bl_unlock(head);
++	mb_cache_entry_put(cache, entry);
+ 
+ 	return 0;
+ }
+diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
+index a41cca619338d..5b1e771238b35 100644
+--- a/fs/nfsd/nfs3proc.c
++++ b/fs/nfsd/nfs3proc.c
+@@ -150,7 +150,6 @@ nfsd3_proc_read(struct svc_rqst *rqstp)
+ {
+ 	struct nfsd3_readargs *argp = rqstp->rq_argp;
+ 	struct nfsd3_readres *resp = rqstp->rq_resp;
+-	u32 max_blocksize = svc_max_payload(rqstp);
+ 	unsigned int len;
+ 	int v;
+ 
+@@ -159,7 +158,8 @@ nfsd3_proc_read(struct svc_rqst *rqstp)
+ 				(unsigned long) argp->count,
+ 				(unsigned long long) argp->offset);
+ 
+-	argp->count = min_t(u32, argp->count, max_blocksize);
++	argp->count = min_t(u32, argp->count, svc_max_payload(rqstp));
++	argp->count = min_t(u32, argp->count, rqstp->rq_res.buflen);
+ 	if (argp->offset > (u64)OFFSET_MAX)
+ 		argp->offset = (u64)OFFSET_MAX;
+ 	if (argp->offset + argp->count > (u64)OFFSET_MAX)
+@@ -563,13 +563,14 @@ static void nfsd3_init_dirlist_pages(struct svc_rqst *rqstp,
+ {
+ 	struct xdr_buf *buf = &resp->dirlist;
+ 	struct xdr_stream *xdr = &resp->xdr;
+-
+-	count = clamp(count, (u32)(XDR_UNIT * 2), svc_max_payload(rqstp));
++	unsigned int sendbuf = min_t(unsigned int, rqstp->rq_res.buflen,
++				     svc_max_payload(rqstp));
+ 
+ 	memset(buf, 0, sizeof(*buf));
+ 
+ 	/* Reserve room for the NULL ptr & eof flag (-2 words) */
+-	buf->buflen = count - XDR_UNIT * 2;
++	buf->buflen = clamp(count, (u32)(XDR_UNIT * 2), sendbuf);
++	buf->buflen -= XDR_UNIT * 2;
+ 	buf->pages = rqstp->rq_next_page;
+ 	rqstp->rq_next_page += (buf->buflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ 
+diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
+index a72ab97f77efe..6ba25a5b76e17 100644
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -2633,9 +2633,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
+ 	status = nfserr_minor_vers_mismatch;
+ 	if (nfsd_minorversion(nn, args->minorversion, NFSD_TEST) <= 0)
+ 		goto out;
+-	status = nfserr_resource;
+-	if (args->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
+-		goto out;
+ 
+ 	status = nfs41_check_op_ordering(args);
+ 	if (status) {
+@@ -2648,10 +2645,20 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
+ 
+ 	rqstp->rq_lease_breaker = (void **)&cstate->clp;
+ 
+-	trace_nfsd_compound(rqstp, args->opcnt);
++	trace_nfsd_compound(rqstp, args->client_opcnt);
+ 	while (!status && resp->opcnt < args->opcnt) {
+ 		op = &args->ops[resp->opcnt++];
+ 
++		if (unlikely(resp->opcnt == NFSD_MAX_OPS_PER_COMPOUND)) {
++			/* If there are still more operations to process,
++			 * stop here and report NFS4ERR_RESOURCE. */
++			if (cstate->minorversion == 0 &&
++			    args->client_opcnt > resp->opcnt) {
++				op->status = nfserr_resource;
++				goto encode_op;
++			}
++		}
++
+ 		/*
+ 		 * The XDR decode routines may have pre-set op->status;
+ 		 * for example, if there is a miscellaneous XDR error
+@@ -2727,8 +2734,8 @@ encode_op:
+ 			status = op->status;
+ 		}
+ 
+-		trace_nfsd_compound_status(args->opcnt, resp->opcnt, status,
+-					   nfsd4_op_name(op->opnum));
++		trace_nfsd_compound_status(args->client_opcnt, resp->opcnt,
++					   status, nfsd4_op_name(op->opnum));
+ 
+ 		nfsd4_cstate_clear_replay(cstate);
+ 		nfsd4_increment_op_stats(op->opnum);
+diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
+index c634483d85d2a..8f24485e0f04f 100644
+--- a/fs/nfsd/nfs4recover.c
++++ b/fs/nfsd/nfs4recover.c
+@@ -815,8 +815,10 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
+ 				princhash.data = memdup_user(
+ 						&ci->cc_princhash.cp_data,
+ 						princhashlen);
+-				if (IS_ERR_OR_NULL(princhash.data))
++				if (IS_ERR_OR_NULL(princhash.data)) {
++					kfree(name.data);
+ 					return -EFAULT;
++				}
+ 				princhash.len = princhashlen;
+ 			} else
+ 				princhash.len = 0;
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index c5d199d7e6b4e..0bc36472f8b7b 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -1049,6 +1049,7 @@ static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp)
+ 
+ static void nfs4_free_deleg(struct nfs4_stid *stid)
+ {
++	WARN_ON(!list_empty(&stid->sc_cp_list));
+ 	kmem_cache_free(deleg_slab, stid);
+ 	atomic_long_dec(&num_delegations);
+ }
+@@ -1462,6 +1463,7 @@ static void nfs4_free_ol_stateid(struct nfs4_stid *stid)
+ 	release_all_access(stp);
+ 	if (stp->st_stateowner)
+ 		nfs4_put_stateowner(stp->st_stateowner);
++	WARN_ON(!list_empty(&stid->sc_cp_list));
+ 	kmem_cache_free(stateid_slab, stid);
+ }
+ 
+@@ -6684,6 +6686,7 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
+ 	struct nfs4_client *clp = s->st_stid.sc_client;
+ 	bool unhashed;
+ 	LIST_HEAD(reaplist);
++	struct nfs4_ol_stateid *stp;
+ 
+ 	spin_lock(&clp->cl_lock);
+ 	unhashed = unhash_open_stateid(s, &reaplist);
+@@ -6692,6 +6695,8 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
+ 		if (unhashed)
+ 			put_ol_stateid_locked(s, &reaplist);
+ 		spin_unlock(&clp->cl_lock);
++		list_for_each_entry(stp, &reaplist, st_locks)
++			nfs4_free_cpntf_statelist(clp->net, &stp->st_stid);
+ 		free_ol_stateid_reaplist(&reaplist);
+ 	} else {
+ 		spin_unlock(&clp->cl_lock);
+diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
+index 1e9690a061eca..2960d0a8e8f9a 100644
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -2357,16 +2357,10 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
+ 
+ 	if (xdr_stream_decode_u32(argp->xdr, &argp->minorversion) < 0)
+ 		return false;
+-	if (xdr_stream_decode_u32(argp->xdr, &argp->opcnt) < 0)
++	if (xdr_stream_decode_u32(argp->xdr, &argp->client_opcnt) < 0)
+ 		return false;
+-
+-	/*
+-	 * NFS4ERR_RESOURCE is a more helpful error than GARBAGE_ARGS
+-	 * here, so we return success at the xdr level so that
+-	 * nfsd4_proc can handle this is an NFS-level error.
+-	 */
+-	if (argp->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
+-		return true;
++	argp->opcnt = min_t(u32, argp->client_opcnt,
++			    NFSD_MAX_OPS_PER_COMPOUND);
+ 
+ 	if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
+ 		argp->ops = kzalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
+@@ -3994,7 +3988,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
+ 	}
+ 	if (resp->xdr->buf->page_len && splice_ok) {
+ 		WARN_ON_ONCE(1);
+-		return nfserr_resource;
++		return nfserr_serverfault;
+ 	}
+ 	xdr_commit_encode(xdr);
+ 
+diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
+index 7381972f16774..4b19cc727ea50 100644
+--- a/fs/nfsd/nfsproc.c
++++ b/fs/nfsd/nfsproc.c
+@@ -185,6 +185,7 @@ nfsd_proc_read(struct svc_rqst *rqstp)
+ 		argp->count, argp->offset);
+ 
+ 	argp->count = min_t(u32, argp->count, NFSSVC_MAXBLKSIZE_V2);
++	argp->count = min_t(u32, argp->count, rqstp->rq_res.buflen);
+ 
+ 	v = 0;
+ 	len = argp->count;
+@@ -567,12 +568,11 @@ static void nfsd_init_dirlist_pages(struct svc_rqst *rqstp,
+ 	struct xdr_buf *buf = &resp->dirlist;
+ 	struct xdr_stream *xdr = &resp->xdr;
+ 
+-	count = clamp(count, (u32)(XDR_UNIT * 2), svc_max_payload(rqstp));
+-
+ 	memset(buf, 0, sizeof(*buf));
+ 
+ 	/* Reserve room for the NULL ptr & eof flag (-2 words) */
+-	buf->buflen = count - XDR_UNIT * 2;
++	buf->buflen = clamp(count, (u32)(XDR_UNIT * 2), (u32)PAGE_SIZE);
++	buf->buflen -= XDR_UNIT * 2;
+ 	buf->pages = rqstp->rq_next_page;
+ 	rqstp->rq_next_page++;
+ 
+diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
+index 96267258e6291..466e2786fc976 100644
+--- a/fs/nfsd/xdr4.h
++++ b/fs/nfsd/xdr4.h
+@@ -717,9 +717,10 @@ struct nfsd4_compoundargs {
+ 	struct svcxdr_tmpbuf		*to_free;
+ 	struct svc_rqst			*rqstp;
+ 
+-	u32				taglen;
+ 	char *				tag;
++	u32				taglen;
+ 	u32				minorversion;
++	u32				client_opcnt;
+ 	u32				opcnt;
+ 	struct nfsd4_op			*ops;
+ 	struct nfsd4_op			iops[8];
+diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
+index 51363d4e8636b..26a76ebfe58fc 100644
+--- a/fs/ntfs3/inode.c
++++ b/fs/ntfs3/inode.c
+@@ -1927,8 +1927,6 @@ const struct inode_operations ntfs_link_inode_operations = {
+ 	.setattr	= ntfs3_setattr,
+ 	.listxattr	= ntfs_listxattr,
+ 	.permission	= ntfs_permission,
+-	.get_acl	= ntfs_get_acl,
+-	.set_acl	= ntfs_set_acl,
+ };
+ 
+ const struct address_space_operations ntfs_aops = {
+diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c
+index 6ae1f56b7358f..7de8718c68a90 100644
+--- a/fs/ntfs3/xattr.c
++++ b/fs/ntfs3/xattr.c
+@@ -625,67 +625,6 @@ int ntfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
+ 	return ntfs_set_acl_ex(mnt_userns, inode, acl, type, false);
+ }
+ 
+-static int ntfs_xattr_get_acl(struct user_namespace *mnt_userns,
+-			      struct inode *inode, int type, void *buffer,
+-			      size_t size)
+-{
+-	struct posix_acl *acl;
+-	int err;
+-
+-	if (!(inode->i_sb->s_flags & SB_POSIXACL)) {
+-		ntfs_inode_warn(inode, "add mount option \"acl\" to use acl");
+-		return -EOPNOTSUPP;
+-	}
+-
+-	acl = ntfs_get_acl(inode, type, false);
+-	if (IS_ERR(acl))
+-		return PTR_ERR(acl);
+-
+-	if (!acl)
+-		return -ENODATA;
+-
+-	err = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
+-	posix_acl_release(acl);
+-
+-	return err;
+-}
+-
+-static int ntfs_xattr_set_acl(struct user_namespace *mnt_userns,
+-			      struct inode *inode, int type, const void *value,
+-			      size_t size)
+-{
+-	struct posix_acl *acl;
+-	int err;
+-
+-	if (!(inode->i_sb->s_flags & SB_POSIXACL)) {
+-		ntfs_inode_warn(inode, "add mount option \"acl\" to use acl");
+-		return -EOPNOTSUPP;
+-	}
+-
+-	if (!inode_owner_or_capable(mnt_userns, inode))
+-		return -EPERM;
+-
+-	if (!value) {
+-		acl = NULL;
+-	} else {
+-		acl = posix_acl_from_xattr(&init_user_ns, value, size);
+-		if (IS_ERR(acl))
+-			return PTR_ERR(acl);
+-
+-		if (acl) {
+-			err = posix_acl_valid(&init_user_ns, acl);
+-			if (err)
+-				goto release_and_out;
+-		}
+-	}
+-
+-	err = ntfs_set_acl(mnt_userns, inode, acl, type);
+-
+-release_and_out:
+-	posix_acl_release(acl);
+-	return err;
+-}
+-
+ /*
+  * ntfs_init_acl - Initialize the ACLs of a new inode.
+  *
+@@ -852,23 +791,6 @@ static int ntfs_getxattr(const struct xattr_handler *handler, struct dentry *de,
+ 		goto out;
+ 	}
+ 
+-#ifdef CONFIG_NTFS3_FS_POSIX_ACL
+-	if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 &&
+-	     !memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
+-		     sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) ||
+-	    (name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 &&
+-	     !memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
+-		     sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) {
+-		/* TODO: init_user_ns? */
+-		err = ntfs_xattr_get_acl(
+-			&init_user_ns, inode,
+-			name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1
+-				? ACL_TYPE_ACCESS
+-				: ACL_TYPE_DEFAULT,
+-			buffer, size);
+-		goto out;
+-	}
+-#endif
+ 	/* Deal with NTFS extended attribute. */
+ 	err = ntfs_get_ea(inode, name, name_len, buffer, size, NULL);
+ 
+@@ -981,22 +903,6 @@ set_new_fa:
+ 		goto out;
+ 	}
+ 
+-#ifdef CONFIG_NTFS3_FS_POSIX_ACL
+-	if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 &&
+-	     !memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS,
+-		     sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) ||
+-	    (name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 &&
+-	     !memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT,
+-		     sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) {
+-		err = ntfs_xattr_set_acl(
+-			mnt_userns, inode,
+-			name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1
+-				? ACL_TYPE_ACCESS
+-				: ACL_TYPE_DEFAULT,
+-			value, size);
+-		goto out;
+-	}
+-#endif
+ 	/* Deal with NTFS extended attribute. */
+ 	err = ntfs_set_ea(inode, name, name_len, value, size, flags, 0);
+ 
+@@ -1086,7 +992,7 @@ static bool ntfs_xattr_user_list(struct dentry *dentry)
+ }
+ 
+ // clang-format off
+-static const struct xattr_handler ntfs_xattr_handler = {
++static const struct xattr_handler ntfs_other_xattr_handler = {
+ 	.prefix	= "",
+ 	.get	= ntfs_getxattr,
+ 	.set	= ntfs_setxattr,
+@@ -1094,7 +1000,11 @@ static const struct xattr_handler ntfs_xattr_handler = {
+ };
+ 
+ const struct xattr_handler *ntfs_xattr_handlers[] = {
+-	&ntfs_xattr_handler,
++#ifdef CONFIG_NTFS3_FS_POSIX_ACL
++	&posix_acl_access_xattr_handler,
++	&posix_acl_default_xattr_handler,
++#endif
++	&ntfs_other_xattr_handler,
+ 	NULL,
+ };
+ // clang-format on
+diff --git a/fs/open.c b/fs/open.c
+index cf7e5c350a54b..a81319b6177f6 100644
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -842,7 +842,9 @@ static int do_dentry_open(struct file *f,
+ 		return 0;
+ 	}
+ 
+-	if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
++	if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
++		i_readcount_inc(inode);
++	} else if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
+ 		error = get_write_access(inode);
+ 		if (unlikely(error))
+ 			goto cleanup_file;
+@@ -882,8 +884,6 @@ static int do_dentry_open(struct file *f,
+ 			goto cleanup_all;
+ 	}
+ 	f->f_mode |= FMODE_OPENED;
+-	if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
+-		i_readcount_inc(inode);
+ 	if ((f->f_mode & FMODE_READ) &&
+ 	     likely(f->f_op->read || f->f_op->read_iter))
+ 		f->f_mode |= FMODE_CAN_READ;
+@@ -937,10 +937,7 @@ cleanup_all:
+ 	if (WARN_ON_ONCE(error > 0))
+ 		error = -EINVAL;
+ 	fops_put(f->f_op);
+-	if (f->f_mode & FMODE_WRITER) {
+-		put_write_access(inode);
+-		__mnt_drop_write(f->f_path.mnt);
+-	}
++	put_file_access(f);
+ cleanup_file:
+ 	path_put(&f->f_path);
+ 	f->f_path.mnt = NULL;
+diff --git a/fs/posix_acl.c b/fs/posix_acl.c
+index 5af33800743e4..abe387700ba9d 100644
+--- a/fs/posix_acl.c
++++ b/fs/posix_acl.c
+@@ -710,9 +710,9 @@ EXPORT_SYMBOL(posix_acl_update_mode);
+ /*
+  * Fix up the uids and gids in posix acl extended attributes in place.
+  */
+-static int posix_acl_fix_xattr_common(void *value, size_t size)
++static int posix_acl_fix_xattr_common(const void *value, size_t size)
+ {
+-	struct posix_acl_xattr_header *header = value;
++	const struct posix_acl_xattr_header *header = value;
+ 	int count;
+ 
+ 	if (!header)
+@@ -720,13 +720,13 @@ static int posix_acl_fix_xattr_common(void *value, size_t size)
+ 	if (size < sizeof(struct posix_acl_xattr_header))
+ 		return -EINVAL;
+ 	if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
+-		return -EINVAL;
++		return -EOPNOTSUPP;
+ 
+ 	count = posix_acl_xattr_count(size);
+ 	if (count < 0)
+ 		return -EINVAL;
+ 	if (count == 0)
+-		return -EINVAL;
++		return 0;
+ 
+ 	return count;
+ }
+@@ -748,7 +748,7 @@ void posix_acl_getxattr_idmapped_mnt(struct user_namespace *mnt_userns,
+ 		return;
+ 
+ 	count = posix_acl_fix_xattr_common(value, size);
+-	if (count < 0)
++	if (count <= 0)
+ 		return;
+ 
+ 	for (end = entry + count; entry != end; entry++) {
+@@ -788,7 +788,7 @@ void posix_acl_setxattr_idmapped_mnt(struct user_namespace *mnt_userns,
+ 		return;
+ 
+ 	count = posix_acl_fix_xattr_common(value, size);
+-	if (count < 0)
++	if (count <= 0)
+ 		return;
+ 
+ 	for (end = entry + count; entry != end; entry++) {
+@@ -822,7 +822,7 @@ static void posix_acl_fix_xattr_userns(
+ 	kgid_t gid;
+ 
+ 	count = posix_acl_fix_xattr_common(value, size);
+-	if (count < 0)
++	if (count <= 0)
+ 		return;
+ 
+ 	for (end = entry + count; entry != end; entry++) {
+@@ -870,16 +870,9 @@ posix_acl_from_xattr(struct user_namespace *user_ns,
+ 	struct posix_acl *acl;
+ 	struct posix_acl_entry *acl_e;
+ 
+-	if (!value)
+-		return NULL;
+-	if (size < sizeof(struct posix_acl_xattr_header))
+-		 return ERR_PTR(-EINVAL);
+-	if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
+-		return ERR_PTR(-EOPNOTSUPP);
+-
+-	count = posix_acl_xattr_count(size);
++	count = posix_acl_fix_xattr_common(value, size);
+ 	if (count < 0)
+-		return ERR_PTR(-EINVAL);
++		return ERR_PTR(count);
+ 	if (count == 0)
+ 		return NULL;
+ 	
+diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c
+index 5f2405994280a..7e65d67de9f33 100644
+--- a/fs/quota/quota_tree.c
++++ b/fs/quota/quota_tree.c
+@@ -71,6 +71,35 @@ static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)
+ 	return ret;
+ }
+ 
++static inline int do_check_range(struct super_block *sb, const char *val_name,
++				 uint val, uint min_val, uint max_val)
++{
++	if (val < min_val || val > max_val) {
++		quota_error(sb, "Getting %s %u out of range %u-%u",
++			    val_name, val, min_val, max_val);
++		return -EUCLEAN;
++	}
++
++	return 0;
++}
++
++static int check_dquot_block_header(struct qtree_mem_dqinfo *info,
++				    struct qt_disk_dqdbheader *dh)
++{
++	int err = 0;
++
++	err = do_check_range(info->dqi_sb, "dqdh_next_free",
++			     le32_to_cpu(dh->dqdh_next_free), 0,
++			     info->dqi_blocks - 1);
++	if (err)
++		return err;
++	err = do_check_range(info->dqi_sb, "dqdh_prev_free",
++			     le32_to_cpu(dh->dqdh_prev_free), 0,
++			     info->dqi_blocks - 1);
++
++	return err;
++}
++
+ /* Remove empty block from list and return it */
+ static int get_free_dqblk(struct qtree_mem_dqinfo *info)
+ {
+@@ -85,6 +114,9 @@ static int get_free_dqblk(struct qtree_mem_dqinfo *info)
+ 		ret = read_blk(info, blk, buf);
+ 		if (ret < 0)
+ 			goto out_buf;
++		ret = check_dquot_block_header(info, dh);
++		if (ret)
++			goto out_buf;
+ 		info->dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
+ 	}
+ 	else {
+@@ -232,6 +264,9 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
+ 		*err = read_blk(info, blk, buf);
+ 		if (*err < 0)
+ 			goto out_buf;
++		*err = check_dquot_block_header(info, dh);
++		if (*err)
++			goto out_buf;
+ 	} else {
+ 		blk = get_free_dqblk(info);
+ 		if ((int)blk < 0) {
+@@ -424,6 +459,9 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
+ 		goto out_buf;
+ 	}
+ 	dh = (struct qt_disk_dqdbheader *)buf;
++	ret = check_dquot_block_header(info, dh);
++	if (ret)
++		goto out_buf;
+ 	le16_add_cpu(&dh->dqdh_entries, -1);
+ 	if (!le16_to_cpu(dh->dqdh_entries)) {	/* Block got free? */
+ 		ret = remove_free_dqentry(info, buf, blk);
+diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
+index 175de70e3adfd..0c1d33c4f74c1 100644
+--- a/fs/userfaultfd.c
++++ b/fs/userfaultfd.c
+@@ -991,7 +991,7 @@ static int resolve_userfault_fork(struct userfaultfd_ctx *new,
+ 	int fd;
+ 
+ 	fd = anon_inode_getfd_secure("[userfaultfd]", &userfaultfd_fops, new,
+-			O_RDWR | (new->flags & UFFD_SHARED_FCNTL_FLAGS), inode);
++			O_RDONLY | (new->flags & UFFD_SHARED_FCNTL_FLAGS), inode);
+ 	if (fd < 0)
+ 		return fd;
+ 
+@@ -2094,7 +2094,7 @@ SYSCALL_DEFINE1(userfaultfd, int, flags)
+ 	mmgrab(ctx->mm);
+ 
+ 	fd = anon_inode_getfd_secure("[userfaultfd]", &userfaultfd_fops, ctx,
+-			O_RDWR | (flags & UFFD_SHARED_FCNTL_FLAGS), NULL);
++			O_RDONLY | (flags & UFFD_SHARED_FCNTL_FLAGS), NULL);
+ 	if (fd < 0) {
+ 		mmdrop(ctx->mm);
+ 		kmem_cache_free(userfaultfd_ctx_cachep, ctx);
+diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
+index 9ac59814bbb6c..f029c6702dda1 100644
+--- a/fs/xfs/xfs_super.c
++++ b/fs/xfs/xfs_super.c
+@@ -653,7 +653,7 @@ xfs_fs_destroy_inode(
+ static void
+ xfs_fs_dirty_inode(
+ 	struct inode			*inode,
+-	int				flag)
++	int				flags)
+ {
+ 	struct xfs_inode		*ip = XFS_I(inode);
+ 	struct xfs_mount		*mp = ip->i_mount;
+@@ -661,7 +661,13 @@ xfs_fs_dirty_inode(
+ 
+ 	if (!(inode->i_sb->s_flags & SB_LAZYTIME))
+ 		return;
+-	if (flag != I_DIRTY_SYNC || !(inode->i_state & I_DIRTY_TIME))
++
++	/*
++	 * Only do the timestamp update if the inode is dirty (I_DIRTY_SYNC)
++	 * and has dirty timestamp (I_DIRTY_TIME). I_DIRTY_TIME can be passed
++	 * in flags possibly together with I_DIRTY_SYNC.
++	 */
++	if ((flags & ~I_DIRTY_TIME) != I_DIRTY_SYNC || !(flags & I_DIRTY_TIME))
+ 		return;
+ 
+ 	if (xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp))
+diff --git a/include/dt-bindings/clock/samsung,exynosautov9.h b/include/dt-bindings/clock/samsung,exynosautov9.h
+index ea9f91b4eb1a3..a7db6516593fe 100644
+--- a/include/dt-bindings/clock/samsung,exynosautov9.h
++++ b/include/dt-bindings/clock/samsung,exynosautov9.h
+@@ -226,21 +226,21 @@
+ #define CLK_GOUT_PERIC0_IPCLK_8		28
+ #define CLK_GOUT_PERIC0_IPCLK_9		29
+ #define CLK_GOUT_PERIC0_IPCLK_10	30
+-#define CLK_GOUT_PERIC0_IPCLK_11	30
+-#define CLK_GOUT_PERIC0_PCLK_0		31
+-#define CLK_GOUT_PERIC0_PCLK_1		32
+-#define CLK_GOUT_PERIC0_PCLK_2		33
+-#define CLK_GOUT_PERIC0_PCLK_3		34
+-#define CLK_GOUT_PERIC0_PCLK_4		35
+-#define CLK_GOUT_PERIC0_PCLK_5		36
+-#define CLK_GOUT_PERIC0_PCLK_6		37
+-#define CLK_GOUT_PERIC0_PCLK_7		38
+-#define CLK_GOUT_PERIC0_PCLK_8		39
+-#define CLK_GOUT_PERIC0_PCLK_9		40
+-#define CLK_GOUT_PERIC0_PCLK_10		41
+-#define CLK_GOUT_PERIC0_PCLK_11		42
++#define CLK_GOUT_PERIC0_IPCLK_11	31
++#define CLK_GOUT_PERIC0_PCLK_0		32
++#define CLK_GOUT_PERIC0_PCLK_1		33
++#define CLK_GOUT_PERIC0_PCLK_2		34
++#define CLK_GOUT_PERIC0_PCLK_3		35
++#define CLK_GOUT_PERIC0_PCLK_4		36
++#define CLK_GOUT_PERIC0_PCLK_5		37
++#define CLK_GOUT_PERIC0_PCLK_6		38
++#define CLK_GOUT_PERIC0_PCLK_7		39
++#define CLK_GOUT_PERIC0_PCLK_8		40
++#define CLK_GOUT_PERIC0_PCLK_9		41
++#define CLK_GOUT_PERIC0_PCLK_10		42
++#define CLK_GOUT_PERIC0_PCLK_11		43
+ 
+-#define PERIC0_NR_CLK			43
++#define PERIC0_NR_CLK			44
+ 
+ /* CMU_PERIC1 */
+ #define CLK_MOUT_PERIC1_BUS_USER	1
+@@ -272,21 +272,21 @@
+ #define CLK_GOUT_PERIC1_IPCLK_8		28
+ #define CLK_GOUT_PERIC1_IPCLK_9		29
+ #define CLK_GOUT_PERIC1_IPCLK_10	30
+-#define CLK_GOUT_PERIC1_IPCLK_11	30
+-#define CLK_GOUT_PERIC1_PCLK_0		31
+-#define CLK_GOUT_PERIC1_PCLK_1		32
+-#define CLK_GOUT_PERIC1_PCLK_2		33
+-#define CLK_GOUT_PERIC1_PCLK_3		34
+-#define CLK_GOUT_PERIC1_PCLK_4		35
+-#define CLK_GOUT_PERIC1_PCLK_5		36
+-#define CLK_GOUT_PERIC1_PCLK_6		37
+-#define CLK_GOUT_PERIC1_PCLK_7		38
+-#define CLK_GOUT_PERIC1_PCLK_8		39
+-#define CLK_GOUT_PERIC1_PCLK_9		40
+-#define CLK_GOUT_PERIC1_PCLK_10		41
+-#define CLK_GOUT_PERIC1_PCLK_11		42
++#define CLK_GOUT_PERIC1_IPCLK_11	31
++#define CLK_GOUT_PERIC1_PCLK_0		32
++#define CLK_GOUT_PERIC1_PCLK_1		33
++#define CLK_GOUT_PERIC1_PCLK_2		34
++#define CLK_GOUT_PERIC1_PCLK_3		35
++#define CLK_GOUT_PERIC1_PCLK_4		36
++#define CLK_GOUT_PERIC1_PCLK_5		37
++#define CLK_GOUT_PERIC1_PCLK_6		38
++#define CLK_GOUT_PERIC1_PCLK_7		39
++#define CLK_GOUT_PERIC1_PCLK_8		40
++#define CLK_GOUT_PERIC1_PCLK_9		41
++#define CLK_GOUT_PERIC1_PCLK_10		42
++#define CLK_GOUT_PERIC1_PCLK_11		43
+ 
+-#define PERIC1_NR_CLK			43
++#define PERIC1_NR_CLK			44
+ 
+ /* CMU_PERIS */
+ #define CLK_MOUT_PERIS_BUS_USER		1
+diff --git a/include/linux/ata.h b/include/linux/ata.h
+index 21292b5bbb550..e3050e153a716 100644
+--- a/include/linux/ata.h
++++ b/include/linux/ata.h
+@@ -566,6 +566,18 @@ struct ata_bmdma_prd {
+ 	((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
+ 	  ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
+ 	 ((id)[ATA_ID_FEATURE_SUPP] & (1 << 2)))
++#define ata_id_has_devslp(id)	\
++	((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
++	  ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
++	 ((id)[ATA_ID_FEATURE_SUPP] & (1 << 8)))
++#define ata_id_has_ncq_autosense(id) \
++	((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
++	  ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
++	 ((id)[ATA_ID_FEATURE_SUPP] & (1 << 7)))
++#define ata_id_has_dipm(id)	\
++	((((id)[ATA_ID_SATA_CAPABILITY] != 0x0000) && \
++	  ((id)[ATA_ID_SATA_CAPABILITY] != 0xffff)) && \
++	 ((id)[ATA_ID_FEATURE_SUPP] & (1 << 3)))
+ #define ata_id_iordy_disable(id) ((id)[ATA_ID_CAPABILITY] & (1 << 10))
+ #define ata_id_has_iordy(id) ((id)[ATA_ID_CAPABILITY] & (1 << 11))
+ #define ata_id_u32(id,n)	\
+@@ -578,9 +590,6 @@ struct ata_bmdma_prd {
+ 
+ #define ata_id_cdb_intr(id)	(((id)[ATA_ID_CONFIG] & 0x60) == 0x20)
+ #define ata_id_has_da(id)	((id)[ATA_ID_SATA_CAPABILITY_2] & (1 << 4))
+-#define ata_id_has_devslp(id)	((id)[ATA_ID_FEATURE_SUPP] & (1 << 8))
+-#define ata_id_has_ncq_autosense(id) \
+-				((id)[ATA_ID_FEATURE_SUPP] & (1 << 7))
+ 
+ static inline bool ata_id_has_hipm(const u16 *id)
+ {
+@@ -592,17 +601,6 @@ static inline bool ata_id_has_hipm(const u16 *id)
+ 	return val & (1 << 9);
+ }
+ 
+-static inline bool ata_id_has_dipm(const u16 *id)
+-{
+-	u16 val = id[ATA_ID_FEATURE_SUPP];
+-
+-	if (val == 0 || val == 0xffff)
+-		return false;
+-
+-	return val & (1 << 3);
+-}
+-
+-
+ static inline bool ata_id_has_fua(const u16 *id)
+ {
+ 	if ((id[ATA_ID_CFSSE] & 0xC000) != 0x4000)
+@@ -771,16 +769,21 @@ static inline bool ata_id_has_read_log_dma_ext(const u16 *id)
+ 
+ static inline bool ata_id_has_sense_reporting(const u16 *id)
+ {
+-	if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15)))
++	if (!(id[ATA_ID_CFS_ENABLE_2] & BIT(15)))
++		return false;
++	if ((id[ATA_ID_COMMAND_SET_3] & (BIT(15) | BIT(14))) != BIT(14))
+ 		return false;
+-	return id[ATA_ID_COMMAND_SET_3] & (1 << 6);
++	return id[ATA_ID_COMMAND_SET_3] & BIT(6);
+ }
+ 
+ static inline bool ata_id_sense_reporting_enabled(const u16 *id)
+ {
+-	if (!(id[ATA_ID_CFS_ENABLE_2] & (1 << 15)))
++	if (!ata_id_has_sense_reporting(id))
++		return false;
++	/* ata_id_has_sense_reporting() == true, word 86 must have bit 15 set */
++	if ((id[ATA_ID_COMMAND_SET_4] & (BIT(15) | BIT(14))) != BIT(14))
+ 		return false;
+-	return id[ATA_ID_COMMAND_SET_4] & (1 << 6);
++	return id[ATA_ID_COMMAND_SET_4] & BIT(6);
+ }
+ 
+ /**
+diff --git a/include/linux/bio.h b/include/linux/bio.h
+index ca22b06700a94..2c5806997bbf7 100644
+--- a/include/linux/bio.h
++++ b/include/linux/bio.h
+@@ -509,7 +509,7 @@ static inline void bio_set_dev(struct bio *bio, struct block_device *bdev)
+ {
+ 	bio_clear_flag(bio, BIO_REMAPPED);
+ 	if (bio->bi_bdev != bdev)
+-		bio_clear_flag(bio, BIO_THROTTLED);
++		bio_clear_flag(bio, BIO_BPS_THROTTLED);
+ 	bio->bi_bdev = bdev;
+ 	bio_associate_blkg(bio);
+ }
+diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
+index 92294a5fb0836..1532cd07a5976 100644
+--- a/include/linux/blk-mq.h
++++ b/include/linux/blk-mq.h
+@@ -268,9 +268,16 @@ static inline void rq_list_move(struct request **src, struct request **dst,
+ 	rq_list_add(dst, rq);
+ }
+ 
++/**
++ * enum blk_eh_timer_return - How the timeout handler should proceed
++ * @BLK_EH_DONE: The block driver completed the command or will complete it at
++ *	a later time.
++ * @BLK_EH_RESET_TIMER: Reset the request timer and continue waiting for the
++ *	request to complete.
++ */
+ enum blk_eh_timer_return {
+-	BLK_EH_DONE,		/* drivers has completed the command */
+-	BLK_EH_RESET_TIMER,	/* reset timer and try again */
++	BLK_EH_DONE,
++	BLK_EH_RESET_TIMER,
+ };
+ 
+ #define BLK_TAG_ALLOC_FIFO 0 /* allocate starting from 0 */
+diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
+index 1ef99790f6ed3..41afb4cfb9b0d 100644
+--- a/include/linux/blk_types.h
++++ b/include/linux/blk_types.h
+@@ -325,7 +325,7 @@ enum {
+ 	BIO_QUIET,		/* Make BIO Quiet */
+ 	BIO_CHAIN,		/* chained bio, ->bi_remaining in effect */
+ 	BIO_REFFED,		/* bio has elevated ->bi_cnt */
+-	BIO_THROTTLED,		/* This bio has already been subjected to
++	BIO_BPS_THROTTLED,	/* This bio has already been subjected to
+ 				 * throttling rules. Don't do it again. */
+ 	BIO_TRACE_COMPLETION,	/* bio_endio() should trace the final completion
+ 				 * of this bio. */
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index 20c26aed78962..80fc8a88c610d 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -891,6 +891,7 @@ struct bpf_dispatcher {
+ 	struct bpf_dispatcher_prog progs[BPF_DISPATCHER_MAX];
+ 	int num_progs;
+ 	void *image;
++	void *rw_image;
+ 	u32 image_off;
+ 	struct bpf_ksym ksym;
+ };
+@@ -909,7 +910,7 @@ int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, struct bpf_trampolin
+ struct bpf_trampoline *bpf_trampoline_get(u64 key,
+ 					  struct bpf_attach_target_info *tgt_info);
+ void bpf_trampoline_put(struct bpf_trampoline *tr);
+-int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs);
++int arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs);
+ #define BPF_DISPATCHER_INIT(_name) {				\
+ 	.mutex = __MUTEX_INITIALIZER(_name.mutex),		\
+ 	.func = &_name##_func,					\
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
+index 2e3bad8640dc4..1fdddbf3546b4 100644
+--- a/include/linux/bpf_verifier.h
++++ b/include/linux/bpf_verifier.h
+@@ -212,6 +212,17 @@ struct bpf_reference_state {
+ 	 * is used purely to inform the user of a reference leak.
+ 	 */
+ 	int insn_idx;
++	/* There can be a case like:
++	 * main (frame 0)
++	 *  cb (frame 1)
++	 *   func (frame 3)
++	 *    cb (frame 4)
++	 * Hence for frame 4, if callback_ref just stored boolean, it would be
++	 * impossible to distinguish nested callback refs. Hence store the
++	 * frameno and compare that to callback_ref in check_reference_leak when
++	 * exiting a callback function.
++	 */
++	int callback_ref;
+ };
+ 
+ /* state of the program:
+diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
+index dce631e678dd6..8d9eec5f6d8bb 100644
+--- a/include/linux/dynamic_debug.h
++++ b/include/linux/dynamic_debug.h
+@@ -55,9 +55,6 @@ struct _ddebug {
+ 
+ #if defined(CONFIG_DYNAMIC_DEBUG_CORE)
+ 
+-/* exported for module authors to exercise >control */
+-int dynamic_debug_exec_queries(const char *query, const char *modname);
+-
+ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
+ 				const char *modname);
+ extern int ddebug_remove_module(const char *mod_name);
+@@ -201,7 +198,7 @@ static inline int ddebug_remove_module(const char *mod)
+ static inline int ddebug_dyndbg_module_param_cb(char *param, char *val,
+ 						const char *modname)
+ {
+-	if (strstr(param, "dyndbg")) {
++	if (!strcmp(param, "dyndbg")) {
+ 		/* avoid pr_warn(), which wants pr_fmt() fully defined */
+ 		printk(KERN_WARNING "dyndbg param is supported only in "
+ 			"CONFIG_DYNAMIC_DEBUG builds\n");
+@@ -221,12 +218,6 @@ static inline int ddebug_dyndbg_module_param_cb(char *param, char *val,
+ 				rowsize, groupsize, buf, len, ascii);	\
+ 	} while (0)
+ 
+-static inline int dynamic_debug_exec_queries(const char *query, const char *modname)
+-{
+-	pr_warn("kernel not built with CONFIG_DYNAMIC_DEBUG_CORE\n");
+-	return 0;
+-}
+-
+ #endif /* !CONFIG_DYNAMIC_DEBUG_CORE */
+ 
+ #endif
+diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h
+index 305d5f19093b9..30eb30d6909b0 100644
+--- a/include/linux/eventfd.h
++++ b/include/linux/eventfd.h
+@@ -46,7 +46,7 @@ void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt);
+ 
+ static inline bool eventfd_signal_allowed(void)
+ {
+-	return !current->in_eventfd_signal;
++	return !current->in_eventfd;
+ }
+ 
+ #else /* CONFIG_EVENTFD */
+diff --git a/include/linux/export-internal.h b/include/linux/export-internal.h
+index c2b1d4fd59873..fe7e6ba918f10 100644
+--- a/include/linux/export-internal.h
++++ b/include/linux/export-internal.h
+@@ -10,8 +10,10 @@
+ #include <linux/compiler.h>
+ #include <linux/types.h>
+ 
+-/* __used is needed to keep __crc_* for LTO */
+ #define SYMBOL_CRC(sym, crc, sec)   \
+-	u32 __section("___kcrctab" sec "+" #sym) __used __crc_##sym = crc
++	asm(".section \"___kcrctab" sec "+" #sym "\",\"a\""	"\n" \
++	    "__crc_" #sym ":"					"\n" \
++	    ".long " #crc					"\n" \
++	    ".previous"						"\n")
+ 
+ #endif /* __LINUX_EXPORT_INTERNAL_H__ */
+diff --git a/include/linux/filter.h b/include/linux/filter.h
+index a5f21dc3c4327..f2c47df5ad2ad 100644
+--- a/include/linux/filter.h
++++ b/include/linux/filter.h
+@@ -1018,6 +1018,8 @@ extern long bpf_jit_limit_max;
+ 
+ typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);
+ 
++void bpf_jit_fill_hole_with_zero(void *area, unsigned int size);
++
+ struct bpf_binary_header *
+ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
+ 		     unsigned int alignment,
+@@ -1030,6 +1032,9 @@ void bpf_jit_free(struct bpf_prog *fp);
+ struct bpf_binary_header *
+ bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);
+ 
++void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns);
++void bpf_prog_pack_free(struct bpf_binary_header *hdr);
++
+ static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
+ {
+ 	return list_empty(&fp->aux->ksym.lnode) ||
+diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h
+index 3b401fa0f3746..fce2fb2fc9626 100644
+--- a/include/linux/fortify-string.h
++++ b/include/linux/fortify-string.h
+@@ -19,7 +19,8 @@ void __write_overflow_field(size_t avail, size_t wanted) __compiletime_warning("
+ 	unsigned char *__p = (unsigned char *)(p);		\
+ 	size_t __ret = (size_t)-1;				\
+ 	size_t __p_size = __builtin_object_size(p, 1);		\
+-	if (__p_size != (size_t)-1) {				\
++	if (__p_size != (size_t)-1 &&				\
++	    __builtin_constant_p(*__p)) {			\
+ 		size_t __p_len = __p_size - 1;			\
+ 		if (__builtin_constant_p(__p[__p_len]) &&	\
+ 		    __p[__p_len] == '\0')			\
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 9eced4cc286ee..56a4b4b02477d 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -2371,13 +2371,14 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
+  *			don't have to write inode on fdatasync() when only
+  *			e.g. the timestamps have changed.
+  * I_DIRTY_PAGES	Inode has dirty pages.  Inode itself may be clean.
+- * I_DIRTY_TIME		The inode itself only has dirty timestamps, and the
++ * I_DIRTY_TIME		The inode itself has dirty timestamps, and the
+  *			lazytime mount option is enabled.  We keep track of this
+  *			separately from I_DIRTY_SYNC in order to implement
+  *			lazytime.  This gets cleared if I_DIRTY_INODE
+- *			(I_DIRTY_SYNC and/or I_DIRTY_DATASYNC) gets set.  I.e.
+- *			either I_DIRTY_TIME *or* I_DIRTY_INODE can be set in
+- *			i_state, but not both.  I_DIRTY_PAGES may still be set.
++ *			(I_DIRTY_SYNC and/or I_DIRTY_DATASYNC) gets set. But
++ *			I_DIRTY_TIME can still be set if I_DIRTY_SYNC is already
++ *			in place because writeback might already be in progress
++ *			and we don't want to lose the time update
+  * I_NEW		Serves as both a mutex and completion notification.
+  *			New inodes set I_NEW.  If two processes both create
+  *			the same inode, one of them will release its inode and
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+index 3ec981a0d8b3a..67c88b82fc32d 100644
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -207,8 +207,8 @@ struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
+ struct page *follow_huge_pd(struct vm_area_struct *vma,
+ 			    unsigned long address, hugepd_t hpd,
+ 			    int flags, int pdshift);
+-struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+-				pmd_t *pmd, int flags);
++struct page *follow_huge_pmd_pte(struct vm_area_struct *vma, unsigned long address,
++				 int flags);
+ struct page *follow_huge_pud(struct mm_struct *mm, unsigned long address,
+ 				pud_t *pud, int flags);
+ struct page *follow_huge_pgd(struct mm_struct *mm, unsigned long address,
+@@ -312,8 +312,8 @@ static inline struct page *follow_huge_pd(struct vm_area_struct *vma,
+ 	return NULL;
+ }
+ 
+-static inline struct page *follow_huge_pmd(struct mm_struct *mm,
+-				unsigned long address, pmd_t *pmd, int flags)
++static inline struct page *follow_huge_pmd_pte(struct vm_area_struct *vma,
++				unsigned long address, int flags)
+ {
+ 	return NULL;
+ }
+diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h
+index aa1d4da03538b..77c2885c4c130 100644
+--- a/include/linux/hw_random.h
++++ b/include/linux/hw_random.h
+@@ -50,6 +50,7 @@ struct hwrng {
+ 	struct list_head list;
+ 	struct kref ref;
+ 	struct completion cleanup_done;
++	struct completion dying;
+ };
+ 
+ struct device;
+@@ -61,4 +62,6 @@ extern int devm_hwrng_register(struct device *dev, struct hwrng *rng);
+ extern void hwrng_unregister(struct hwrng *rng);
+ extern void devm_hwrng_unregister(struct device *dve, struct hwrng *rng);
+ 
++extern long hwrng_msleep(struct hwrng *rng, unsigned int msecs);
++
+ #endif /* LINUX_HWRANDOM_H_ */
+diff --git a/include/linux/iio/iio-opaque.h b/include/linux/iio/iio-opaque.h
+index 6b3586b3f952f..d1f8b30a7c8b7 100644
+--- a/include/linux/iio/iio-opaque.h
++++ b/include/linux/iio/iio-opaque.h
+@@ -11,6 +11,7 @@
+  *				checked by device drivers but should be considered
+  *				read-only as this is a core internal bit
+  * @driver_module:		used to make it harder to undercut users
++ * @mlock_key:			lockdep class for iio_dev lock
+  * @info_exist_lock:		lock to prevent use during removal
+  * @trig_readonly:		mark the current trigger immutable
+  * @event_interface:		event chrdevs associated with interrupt lines
+@@ -42,6 +43,7 @@ struct iio_dev_opaque {
+ 	int				currentmode;
+ 	int				id;
+ 	struct module			*driver_module;
++	struct lock_class_key		mlock_key;
+ 	struct mutex			info_exist_lock;
+ 	bool				trig_readonly;
+ 	struct iio_event_interface	*event_interface;
+diff --git a/include/linux/iova.h b/include/linux/iova.h
+index c6ba6d95d79c2..83c00fac2acb1 100644
+--- a/include/linux/iova.h
++++ b/include/linux/iova.h
+@@ -75,7 +75,7 @@ static inline unsigned long iova_pfn(struct iova_domain *iovad, dma_addr_t iova)
+ 	return iova >> iova_shift(iovad);
+ }
+ 
+-#if IS_ENABLED(CONFIG_IOMMU_IOVA)
++#if IS_REACHABLE(CONFIG_IOMMU_IOVA)
+ int iova_cache_get(void);
+ void iova_cache_put(void);
+ 
+diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
+index 8a30de08e9139..c726ea7812552 100644
+--- a/include/linux/mmc/card.h
++++ b/include/linux/mmc/card.h
+@@ -293,6 +293,7 @@ struct mmc_card {
+ #define MMC_QUIRK_BROKEN_IRQ_POLLING	(1<<11)	/* Polling SDIO_CCCR_INTx could create a fake interrupt */
+ #define MMC_QUIRK_TRIM_BROKEN	(1<<12)		/* Skip trim */
+ #define MMC_QUIRK_BROKEN_HPI	(1<<13)		/* Disable broken HPI support */
++#define MMC_QUIRK_BROKEN_SD_DISCARD	(1<<14)	/* Disable broken SD discard support */
+ 
+ 	bool			reenable_cmdq;	/* Re-enable Command Queue */
+ 
+diff --git a/include/linux/once.h b/include/linux/once.h
+index b14d8b309d52b..176ab75b42df7 100644
+--- a/include/linux/once.h
++++ b/include/linux/once.h
+@@ -5,10 +5,18 @@
+ #include <linux/types.h>
+ #include <linux/jump_label.h>
+ 
++/* Helpers used from arbitrary contexts.
++ * Hard irqs are blocked, be cautious.
++ */
+ bool __do_once_start(bool *done, unsigned long *flags);
+ void __do_once_done(bool *done, struct static_key_true *once_key,
+ 		    unsigned long *flags, struct module *mod);
+ 
++/* Variant for process contexts only. */
++bool __do_once_slow_start(bool *done);
++void __do_once_slow_done(bool *done, struct static_key_true *once_key,
++			 struct module *mod);
++
+ /* Call a function exactly once. The idea of DO_ONCE() is to perform
+  * a function call such as initialization of random seeds, etc, only
+  * once, where DO_ONCE() can live in the fast-path. After @func has
+@@ -52,7 +60,27 @@ void __do_once_done(bool *done, struct static_key_true *once_key,
+ 		___ret;							     \
+ 	})
+ 
++/* Variant of DO_ONCE() for process/sleepable contexts. */
++#define DO_ONCE_SLOW(func, ...)						     \
++	({								     \
++		bool ___ret = false;					     \
++		static bool __section(".data.once") ___done = false;	     \
++		static DEFINE_STATIC_KEY_TRUE(___once_key);		     \
++		if (static_branch_unlikely(&___once_key)) {		     \
++			___ret = __do_once_slow_start(&___done);	     \
++			if (unlikely(___ret)) {				     \
++				func(__VA_ARGS__);			     \
++				__do_once_slow_done(&___done, &___once_key,  \
++						    THIS_MODULE);	     \
++			}						     \
++		}							     \
++		___ret;							     \
++	})
++
+ #define get_random_once(buf, nbytes)					     \
+ 	DO_ONCE(get_random_bytes, (buf), (nbytes))
+ 
++#define get_random_slow_once(buf, nbytes)				     \
++	DO_ONCE_SLOW(get_random_bytes, (buf), (nbytes))
++
+ #endif /* _LINUX_ONCE_H */
+diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
+index dac53fd3afea3..2504df9a0453e 100644
+--- a/include/linux/ring_buffer.h
++++ b/include/linux/ring_buffer.h
+@@ -101,7 +101,7 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k
+ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full);
+ __poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
+ 			  struct file *filp, poll_table *poll_table);
+-
++void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu);
+ 
+ #define RING_BUFFER_ALL_CPUS -1
+ 
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index e7b2f8a5c711c..8d82d6d326701 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -936,7 +936,7 @@ struct task_struct {
+ #endif
+ #ifdef CONFIG_EVENTFD
+ 	/* Recursion prevention for eventfd_signal() */
+-	unsigned			in_eventfd_signal:1;
++	unsigned			in_eventfd:1;
+ #endif
+ #ifdef CONFIG_IOMMU_SVA
+ 	unsigned			pasid_activated:1;
+diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
+index 8c7b793aa4d70..16e3d75a324c7 100644
+--- a/include/linux/serial_8250.h
++++ b/include/linux/serial_8250.h
+@@ -74,6 +74,7 @@ struct uart_8250_port;
+ struct uart_8250_ops {
+ 	int		(*setup_irq)(struct uart_8250_port *);
+ 	void		(*release_irq)(struct uart_8250_port *);
++	void		(*setup_timer)(struct uart_8250_port *);
+ };
+ 
+ struct uart_8250_em485 {
+diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
+index 1eaea9fe44d8e..beb2ffd31feaf 100644
+--- a/include/linux/serial_core.h
++++ b/include/linux/serial_core.h
+@@ -422,7 +422,7 @@ struct uart_icount {
+ 	__u32	buf_overrun;
+ };
+ 
+-typedef unsigned int __bitwise upf_t;
++typedef u64 __bitwise upf_t;
+ typedef unsigned int __bitwise upstat_t;
+ 
+ struct uart_port {
+@@ -530,6 +530,7 @@ struct uart_port {
+ #define UPF_FIXED_PORT		((__force upf_t) (1 << 29))
+ #define UPF_DEAD		((__force upf_t) (1 << 30))
+ #define UPF_IOREMAP		((__force upf_t) (1 << 31))
++#define UPF_FULL_PROBE		((__force upf_t) (1ULL << 32))
+ 
+ #define __UPF_CHANGE_MASK	0x17fff
+ #define UPF_CHANGE_MASK		((__force upf_t) __UPF_CHANGE_MASK)
+@@ -950,5 +951,4 @@ static inline int uart_handle_break(struct uart_port *port)
+ 					 !((cflag) & CLOCAL))
+ 
+ int uart_get_rs485_mode(struct uart_port *port);
+-int uart_rs485_config(struct uart_port *port);
+ #endif /* LINUX_SERIAL_CORE_H */
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 18e163a3460dd..f02ef6e6171b3 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -796,6 +796,7 @@ typedef unsigned char *sk_buff_data_t;
+  *	@csum_level: indicates the number of consecutive checksums found in
+  *		the packet minus one that have been verified as
+  *		CHECKSUM_UNNECESSARY (max 3)
++ *	@scm_io_uring: SKB holds io_uring registered files
+  *	@dst_pending_confirm: need to confirm neighbour
+  *	@decrypted: Decrypted SKB
+  *	@slow_gro: state present at GRO time, slower prepare step required
+@@ -975,6 +976,7 @@ struct sk_buff {
+ #endif
+ 	__u8			slow_gro:1;
+ 	__u8			csum_not_inet:1;
++	__u8			scm_io_uring:1;
+ 
+ #ifdef CONFIG_NET_SCHED
+ 	__u16			tc_index;	/* traffic control index */
+diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
+index daecb009c05b5..0ca8a8ffb47e4 100644
+--- a/include/linux/sunrpc/svc.h
++++ b/include/linux/sunrpc/svc.h
+@@ -544,16 +544,27 @@ static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
+ }
+ 
+ /**
+- * svcxdr_init_decode - Prepare an xdr_stream for svc Call decoding
++ * svcxdr_init_decode - Prepare an xdr_stream for Call decoding
+  * @rqstp: controlling server RPC transaction context
+  *
++ * This function currently assumes the RPC header in rq_arg has
++ * already been decoded. Upon return, xdr->p points to the
++ * location of the upper layer header.
+  */
+ static inline void svcxdr_init_decode(struct svc_rqst *rqstp)
+ {
+ 	struct xdr_stream *xdr = &rqstp->rq_arg_stream;
+-	struct kvec *argv = rqstp->rq_arg.head;
++	struct xdr_buf *buf = &rqstp->rq_arg;
++	struct kvec *argv = buf->head;
+ 
+-	xdr_init_decode(xdr, &rqstp->rq_arg, argv->iov_base, NULL);
++	/*
++	 * svc_getnl() and friends do not keep the xdr_buf's ::len
++	 * field up to date. Refresh that field before initializing
++	 * the argument decoding stream.
++	 */
++	buf->len = buf->head->iov_len + buf->page_len + buf->tail->iov_len;
++
++	xdr_init_decode(xdr, buf, argv->iov_base, NULL);
+ 	xdr_set_scratch_page(xdr, rqstp->rq_scratch_page);
+ }
+ 
+@@ -576,7 +587,7 @@ static inline void svcxdr_init_encode(struct svc_rqst *rqstp)
+ 	xdr->end = resv->iov_base + PAGE_SIZE - rqstp->rq_auth_slack;
+ 	buf->len = resv->iov_len;
+ 	xdr->page_ptr = buf->pages - 1;
+-	buf->buflen = PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages);
++	buf->buflen = PAGE_SIZE * (rqstp->rq_page_end - buf->pages);
+ 	buf->buflen -= rqstp->rq_auth_slack;
+ 	xdr->rqst = NULL;
+ }
+diff --git a/include/linux/tcp.h b/include/linux/tcp.h
+index a9fbe22732c3b..4791fd8019454 100644
+--- a/include/linux/tcp.h
++++ b/include/linux/tcp.h
+@@ -295,7 +295,7 @@ struct tcp_sock {
+ 	u32	packets_out;	/* Packets which are "in flight"	*/
+ 	u32	retrans_out;	/* Retransmitted packets out		*/
+ 	u32	max_packets_out;  /* max packets_out in last window */
+-	u32	max_packets_seq;  /* right edge of max_packets_out flight */
++	u32	cwnd_usage_seq;  /* right edge of cwnd usage tracking flight */
+ 
+ 	u16	urg_data;	/* Saved octet of OOB data and control flags */
+ 	u8	ecn_flags;	/* ECN status bits.			*/
+diff --git a/include/linux/trace.h b/include/linux/trace.h
+index bf169612ffe12..b5e16e438448f 100644
+--- a/include/linux/trace.h
++++ b/include/linux/trace.h
+@@ -2,8 +2,6 @@
+ #ifndef _LINUX_TRACE_H
+ #define _LINUX_TRACE_H
+ 
+-#ifdef CONFIG_TRACING
+-
+ #define TRACE_EXPORT_FUNCTION	BIT(0)
+ #define TRACE_EXPORT_EVENT	BIT(1)
+ #define TRACE_EXPORT_MARKER	BIT(2)
+@@ -28,6 +26,8 @@ struct trace_export {
+ 	int flags;
+ };
+ 
++#ifdef CONFIG_TRACING
++
+ int register_ftrace_export(struct trace_export *export);
+ int unregister_ftrace_export(struct trace_export *export);
+ 
+@@ -48,6 +48,38 @@ void osnoise_arch_unregister(void);
+ void osnoise_trace_irq_entry(int id);
+ void osnoise_trace_irq_exit(int id, const char *desc);
+ 
++#else /* CONFIG_TRACING */
++static inline int register_ftrace_export(struct trace_export *export)
++{
++	return -EINVAL;
++}
++static inline int unregister_ftrace_export(struct trace_export *export)
++{
++	return 0;
++}
++static inline void trace_printk_init_buffers(void)
++{
++}
++static inline int trace_array_printk(struct trace_array *tr, unsigned long ip,
++				     const char *fmt, ...)
++{
++	return 0;
++}
++static inline int trace_array_init_printk(struct trace_array *tr)
++{
++	return -EINVAL;
++}
++static inline void trace_array_put(struct trace_array *tr)
++{
++}
++static inline struct trace_array *trace_array_get_by_name(const char *name)
++{
++	return NULL;
++}
++static inline int trace_array_destroy(struct trace_array *tr)
++{
++	return 0;
++}
+ #endif	/* CONFIG_TRACING */
+ 
+ #endif	/* _LINUX_TRACE_H */
+diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
+index 8401dec93c155..20749bd9db718 100644
+--- a/include/linux/trace_events.h
++++ b/include/linux/trace_events.h
+@@ -92,6 +92,7 @@ struct trace_iterator {
+ 	unsigned int		temp_size;
+ 	char			*fmt;	/* modified format holder */
+ 	unsigned int		fmt_size;
++	long			wait_index;
+ 
+ 	/* trace_seq for __print_flags() and __print_symbolic() etc. */
+ 	struct trace_seq	tmp_seq;
+diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
+index a8994f307fc38..03b64bf876a46 100644
+--- a/include/net/ieee802154_netdev.h
++++ b/include/net/ieee802154_netdev.h
+@@ -185,21 +185,27 @@ static inline int
+ ieee802154_sockaddr_check_size(struct sockaddr_ieee802154 *daddr, int len)
+ {
+ 	struct ieee802154_addr_sa *sa;
++	int ret = 0;
+ 
+ 	sa = &daddr->addr;
+ 	if (len < IEEE802154_MIN_NAMELEN)
+ 		return -EINVAL;
+ 	switch (sa->addr_type) {
++	case IEEE802154_ADDR_NONE:
++		break;
+ 	case IEEE802154_ADDR_SHORT:
+ 		if (len < IEEE802154_NAMELEN_SHORT)
+-			return -EINVAL;
++			ret = -EINVAL;
+ 		break;
+ 	case IEEE802154_ADDR_LONG:
+ 		if (len < IEEE802154_NAMELEN_LONG)
+-			return -EINVAL;
++			ret = -EINVAL;
++		break;
++	default:
++		ret = -EINVAL;
+ 		break;
+ 	}
+-	return 0;
++	return ret;
+ }
+ 
+ static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a,
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index d10962b9f0d0d..95c1d51393ac4 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -1295,11 +1295,14 @@ static inline bool tcp_is_cwnd_limited(const struct sock *sk)
+ {
+ 	const struct tcp_sock *tp = tcp_sk(sk);
+ 
++	if (tp->is_cwnd_limited)
++		return true;
++
+ 	/* If in slow start, ensure cwnd grows to twice what was ACKed. */
+ 	if (tcp_in_slow_start(tp))
+ 		return tcp_snd_cwnd(tp) < 2 * tp->max_packets_out;
+ 
+-	return tp->is_cwnd_limited;
++	return false;
+ }
+ 
+ /* BBR congestion control needs pacing.
+diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
+index 59a217ca2dfd3..4eff7fc7ae586 100644
+--- a/include/uapi/linux/bpf.h
++++ b/include/uapi/linux/bpf.h
+@@ -1233,7 +1233,7 @@ enum {
+ 
+ /* Query effective (directly attached + inherited from ancestor cgroups)
+  * programs that will be executed for events within a cgroup.
+- * attach_flags with this flag are returned only for directly attached programs.
++ * attach_flags with this flag are always returned 0.
+  */
+ #define BPF_F_QUERY_EFFECTIVE	(1U << 0)
+ 
+@@ -1432,7 +1432,10 @@ union bpf_attr {
+ 		__u32		attach_flags;
+ 		__aligned_u64	prog_ids;
+ 		__u32		prog_cnt;
+-		__aligned_u64	prog_attach_flags; /* output: per-program attach_flags */
++		/* output: per-program attach_flags.
++		 * not allowed to be set during effective query.
++		 */
++		__aligned_u64	prog_attach_flags;
+ 	} query;
+ 
+ 	struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
+diff --git a/include/uapi/rdma/mlx5-abi.h b/include/uapi/rdma/mlx5-abi.h
+index 86be4a92b67bf..a96b7d2770e15 100644
+--- a/include/uapi/rdma/mlx5-abi.h
++++ b/include/uapi/rdma/mlx5-abi.h
+@@ -104,6 +104,7 @@ enum mlx5_ib_alloc_ucontext_resp_mask {
+ 	MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_ECE               = 1UL << 2,
+ 	MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_SQD2RTS           = 1UL << 3,
+ 	MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_REAL_TIME_TS	   = 1UL << 4,
++	MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_MKEY_UPDATE_TAG   = 1UL << 5,
+ };
+ 
+ enum mlx5_user_cmds_supp_uhw {
+diff --git a/io_uring/fdinfo.c b/io_uring/fdinfo.c
+index b29e2d02216f2..2ddf321c94893 100644
+--- a/io_uring/fdinfo.c
++++ b/io_uring/fdinfo.c
+@@ -60,6 +60,7 @@ static __cold void __io_uring_show_fdinfo(struct io_ring_ctx *ctx,
+ 	unsigned int cq_head = READ_ONCE(r->cq.head);
+ 	unsigned int cq_tail = READ_ONCE(r->cq.tail);
+ 	unsigned int cq_shift = 0;
++	unsigned int sq_shift = 0;
+ 	unsigned int sq_entries, cq_entries;
+ 	bool has_lock;
+ 	bool is_cqe32 = (ctx->flags & IORING_SETUP_CQE32);
+@@ -67,6 +68,8 @@ static __cold void __io_uring_show_fdinfo(struct io_ring_ctx *ctx,
+ 
+ 	if (is_cqe32)
+ 		cq_shift = 1;
++	if (ctx->flags & IORING_SETUP_SQE128)
++		sq_shift = 1;
+ 
+ 	/*
+ 	 * we may get imprecise sqe and cqe info if uring is actively running
+@@ -82,19 +85,36 @@ static __cold void __io_uring_show_fdinfo(struct io_ring_ctx *ctx,
+ 	seq_printf(m, "CqHead:\t%u\n", cq_head);
+ 	seq_printf(m, "CqTail:\t%u\n", cq_tail);
+ 	seq_printf(m, "CachedCqTail:\t%u\n", ctx->cached_cq_tail);
+-	seq_printf(m, "SQEs:\t%u\n", sq_tail - ctx->cached_sq_head);
++	seq_printf(m, "SQEs:\t%u\n", sq_tail - sq_head);
+ 	sq_entries = min(sq_tail - sq_head, ctx->sq_entries);
+ 	for (i = 0; i < sq_entries; i++) {
+ 		unsigned int entry = i + sq_head;
+-		unsigned int sq_idx = READ_ONCE(ctx->sq_array[entry & sq_mask]);
+ 		struct io_uring_sqe *sqe;
++		unsigned int sq_idx;
+ 
++		sq_idx = READ_ONCE(ctx->sq_array[entry & sq_mask]);
+ 		if (sq_idx > sq_mask)
+ 			continue;
+-		sqe = &ctx->sq_sqes[sq_idx];
+-		seq_printf(m, "%5u: opcode:%d, fd:%d, flags:%x, user_data:%llu\n",
+-			   sq_idx, sqe->opcode, sqe->fd, sqe->flags,
+-			   sqe->user_data);
++		sqe = &ctx->sq_sqes[sq_idx << sq_shift];
++		seq_printf(m, "%5u: opcode:%s, fd:%d, flags:%x, off:%llu, "
++			      "addr:0x%llx, rw_flags:0x%x, buf_index:%d "
++			      "user_data:%llu",
++			   sq_idx, io_uring_get_opcode(sqe->opcode), sqe->fd,
++			   sqe->flags, (unsigned long long) sqe->off,
++			   (unsigned long long) sqe->addr, sqe->rw_flags,
++			   sqe->buf_index, sqe->user_data);
++		if (sq_shift) {
++			u64 *sqeb = (void *) (sqe + 1);
++			int size = sizeof(struct io_uring_sqe) / sizeof(u64);
++			int j;
++
++			for (j = 0; j < size; j++) {
++				seq_printf(m, ", e%d:0x%llx", j,
++						(unsigned long long) *sqeb);
++				sqeb++;
++			}
++		}
++		seq_printf(m, "\n");
+ 	}
+ 	seq_printf(m, "CQEs:\t%u\n", cq_tail - cq_head);
+ 	cq_entries = min(cq_tail - cq_head, ctx->cq_entries);
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index 242d896c00f34..c5dd483a7de2f 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -567,7 +567,7 @@ static bool __io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force)
+ 
+ 	io_cq_lock(ctx);
+ 	while (!list_empty(&ctx->cq_overflow_list)) {
+-		struct io_uring_cqe *cqe = io_get_cqe(ctx);
++		struct io_uring_cqe *cqe = io_get_cqe_overflow(ctx, true);
+ 		struct io_overflow_cqe *ocqe;
+ 
+ 		if (!cqe && !force)
+@@ -694,12 +694,19 @@ bool io_req_cqe_overflow(struct io_kiocb *req)
+  * control dependency is enough as we're using WRITE_ONCE to
+  * fill the cq entry
+  */
+-struct io_uring_cqe *__io_get_cqe(struct io_ring_ctx *ctx)
++struct io_uring_cqe *__io_get_cqe(struct io_ring_ctx *ctx, bool overflow)
+ {
+ 	struct io_rings *rings = ctx->rings;
+ 	unsigned int off = ctx->cached_cq_tail & (ctx->cq_entries - 1);
+ 	unsigned int free, queued, len;
+ 
++	/*
++	 * Posting into the CQ when there are pending overflowed CQEs may break
++	 * ordering guarantees, which will affect links, F_MORE users and more.
++	 * Force overflow the completion.
++	 */
++	if (!overflow && (ctx->check_cq & BIT(IO_CHECK_CQ_OVERFLOW_BIT)))
++		return NULL;
+ 
+ 	/* userspace may cheat modifying the tail, be safe and do min */
+ 	queued = min(__io_cqring_events(ctx), ctx->cq_entries);
+@@ -823,8 +830,12 @@ inline void __io_req_complete(struct io_kiocb *req, unsigned issue_flags)
+ 
+ void io_req_complete_failed(struct io_kiocb *req, s32 res)
+ {
++	const struct io_op_def *def = &io_op_defs[req->opcode];
++
+ 	req_set_fail(req);
+ 	io_req_set_res(req, res, io_put_kbuf(req, IO_URING_F_UNLOCKED));
++	if (def->fail)
++		def->fail(req);
+ 	io_req_complete_post(req);
+ }
+ 
+@@ -2228,6 +2239,7 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
+ 
+ 	do {
+ 		io_cqring_overflow_flush(ctx);
++
+ 		if (io_cqring_events(ctx) >= min_events)
+ 			return 0;
+ 		if (!io_run_task_work())
+@@ -2418,12 +2430,6 @@ static void io_req_caches_free(struct io_ring_ctx *ctx)
+ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx)
+ {
+ 	io_sq_thread_finish(ctx);
+-
+-	if (ctx->mm_account) {
+-		mmdrop(ctx->mm_account);
+-		ctx->mm_account = NULL;
+-	}
+-
+ 	io_rsrc_refs_drop(ctx);
+ 	/* __io_rsrc_put_work() may need uring_lock to progress, wait w/o it */
+ 	io_wait_rsrc_data(ctx->buf_data);
+@@ -2466,6 +2472,10 @@ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx)
+ 	WARN_ON_ONCE(!list_empty(&ctx->ltimeout_list));
+ 	WARN_ON_ONCE(ctx->notif_slots || ctx->nr_notif_slots);
+ 
++	if (ctx->mm_account) {
++		mmdrop(ctx->mm_account);
++		ctx->mm_account = NULL;
++	}
+ 	io_mem_free(ctx->rings);
+ 	io_mem_free(ctx->sq_sqes);
+ 
+@@ -3706,6 +3716,9 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
+ 	if (WARN_ON_ONCE(percpu_ref_is_dying(&ctx->refs)))
+ 		return -ENXIO;
+ 
++	if (ctx->submitter_task && ctx->submitter_task != current)
++		return -EEXIST;
++
+ 	if (ctx->restricted) {
+ 		if (opcode >= IORING_REGISTER_LAST)
+ 			return -EINVAL;
+diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h
+index 2f73f83af9604..45809ae6f64ef 100644
+--- a/io_uring/io_uring.h
++++ b/io_uring/io_uring.h
+@@ -24,7 +24,7 @@ enum {
+ 	IOU_STOP_MULTISHOT	= -ECANCELED,
+ };
+ 
+-struct io_uring_cqe *__io_get_cqe(struct io_ring_ctx *ctx);
++struct io_uring_cqe *__io_get_cqe(struct io_ring_ctx *ctx, bool overflow);
+ bool io_req_cqe_overflow(struct io_kiocb *req);
+ int io_run_task_work_sig(void);
+ void io_req_complete_failed(struct io_kiocb *req, s32 res);
+@@ -91,7 +91,8 @@ static inline void io_cq_lock(struct io_ring_ctx *ctx)
+ 
+ void io_cq_unlock_post(struct io_ring_ctx *ctx);
+ 
+-static inline struct io_uring_cqe *io_get_cqe(struct io_ring_ctx *ctx)
++static inline struct io_uring_cqe *io_get_cqe_overflow(struct io_ring_ctx *ctx,
++						       bool overflow)
+ {
+ 	if (likely(ctx->cqe_cached < ctx->cqe_sentinel)) {
+ 		struct io_uring_cqe *cqe = ctx->cqe_cached;
+@@ -103,7 +104,12 @@ static inline struct io_uring_cqe *io_get_cqe(struct io_ring_ctx *ctx)
+ 		return cqe;
+ 	}
+ 
+-	return __io_get_cqe(ctx);
++	return __io_get_cqe(ctx, overflow);
++}
++
++static inline struct io_uring_cqe *io_get_cqe(struct io_ring_ctx *ctx)
++{
++	return io_get_cqe_overflow(ctx, false);
+ }
+ 
+ static inline bool __io_fill_cqe_req(struct io_ring_ctx *ctx,
+diff --git a/io_uring/net.c b/io_uring/net.c
+index 60e392f7f2dcd..4878bf40f8b1c 100644
+--- a/io_uring/net.c
++++ b/io_uring/net.c
+@@ -46,6 +46,7 @@ struct io_connect {
+ 	struct file			*file;
+ 	struct sockaddr __user		*addr;
+ 	int				addr_len;
++	bool				in_progress;
+ };
+ 
+ struct io_sr_msg {
+@@ -55,21 +56,13 @@ struct io_sr_msg {
+ 		struct user_msghdr __user	*umsg;
+ 		void __user			*buf;
+ 	};
++	unsigned			len;
++	unsigned			done_io;
+ 	unsigned			msg_flags;
+-	unsigned			flags;
+-	size_t				len;
+-	size_t				done_io;
+-};
+-
+-struct io_sendzc {
+-	struct file			*file;
+-	void __user			*buf;
+-	size_t				len;
+-	unsigned			msg_flags;
+-	unsigned			flags;
+-	unsigned			addr_len;
++	u16				flags;
++	/* used only for sendzc */
++	u16				addr_len;
+ 	void __user			*addr;
+-	size_t				done_io;
+ 	struct io_kiocb 		*notif;
+ };
+ 
+@@ -163,10 +156,13 @@ static int io_setup_async_msg(struct io_kiocb *req,
+ 	}
+ 	req->flags |= REQ_F_NEED_CLEANUP;
+ 	memcpy(async_msg, kmsg, sizeof(*kmsg));
+-	async_msg->msg.msg_name = &async_msg->addr;
++	if (async_msg->msg.msg_name)
++		async_msg->msg.msg_name = &async_msg->addr;
+ 	/* if were using fast_iov, set it to the new one */
+-	if (!async_msg->free_iov)
+-		async_msg->msg.msg_iter.iov = async_msg->fast_iov;
++	if (!kmsg->free_iov) {
++		size_t fast_idx = kmsg->msg.msg_iter.iov - kmsg->fast_iov;
++		async_msg->msg.msg_iter.iov = &async_msg->fast_iov[fast_idx];
++	}
+ 
+ 	return -EAGAIN;
+ }
+@@ -184,7 +180,7 @@ static int io_sendmsg_copy_hdr(struct io_kiocb *req,
+ 
+ int io_sendzc_prep_async(struct io_kiocb *req)
+ {
+-	struct io_sendzc *zc = io_kiocb_to_cmd(req, struct io_sendzc);
++	struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
+ 	struct io_async_msghdr *io;
+ 	int ret;
+ 
+@@ -879,18 +875,17 @@ out_free:
+ 	return ret;
+ }
+ 
+-void io_sendzc_cleanup(struct io_kiocb *req)
++void io_send_zc_cleanup(struct io_kiocb *req)
+ {
+-	struct io_sendzc *zc = io_kiocb_to_cmd(req, struct io_sendzc);
++	struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
+ 
+-	zc->notif->flags |= REQ_F_CQE_SKIP;
+ 	io_notif_flush(zc->notif);
+ 	zc->notif = NULL;
+ }
+ 
+-int io_sendzc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
++int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+ {
+-	struct io_sendzc *zc = io_kiocb_to_cmd(req, struct io_sendzc);
++	struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
+ 	struct io_ring_ctx *ctx = req->ctx;
+ 	struct io_kiocb *notif;
+ 
+@@ -993,14 +988,14 @@ static int io_sg_from_iter(struct sock *sk, struct sk_buff *skb,
+ 	return ret;
+ }
+ 
+-int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
++int io_send_zc(struct io_kiocb *req, unsigned int issue_flags)
+ {
+ 	struct sockaddr_storage __address, *addr = NULL;
+-	struct io_sendzc *zc = io_kiocb_to_cmd(req, struct io_sendzc);
++	struct io_sr_msg *zc = io_kiocb_to_cmd(req, struct io_sr_msg);
+ 	struct msghdr msg;
+ 	struct iovec iov;
+ 	struct socket *sock;
+-	unsigned msg_flags, cflags;
++	unsigned msg_flags;
+ 	int ret, min_ret = 0;
+ 
+ 	sock = sock_from_file(req->file);
+@@ -1068,8 +1063,6 @@ int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
+ 			req->flags |= REQ_F_PARTIAL_IO;
+ 			return io_setup_async_addr(req, addr, issue_flags);
+ 		}
+-		if (ret < 0 && !zc->done_io)
+-			zc->notif->flags |= REQ_F_CQE_SKIP;
+ 		if (ret == -ERESTARTSYS)
+ 			ret = -EINTR;
+ 		req_set_fail(req);
+@@ -1080,13 +1073,38 @@ int io_sendzc(struct io_kiocb *req, unsigned int issue_flags)
+ 	else if (zc->done_io)
+ 		ret = zc->done_io;
+ 
+-	io_notif_flush(zc->notif);
+-	req->flags &= ~REQ_F_NEED_CLEANUP;
+-	cflags = ret >= 0 ? IORING_CQE_F_MORE : 0;
+-	io_req_set_res(req, ret, cflags);
++	/*
++	 * If we're in io-wq we can't rely on tw ordering guarantees, defer
++	 * flushing notif to io_send_zc_cleanup()
++	 */
++	if (!(issue_flags & IO_URING_F_UNLOCKED)) {
++		io_notif_flush(zc->notif);
++		req->flags &= ~REQ_F_NEED_CLEANUP;
++	}
++	io_req_set_res(req, ret, IORING_CQE_F_MORE);
+ 	return IOU_OK;
+ }
+ 
++void io_sendrecv_fail(struct io_kiocb *req)
++{
++	struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
++	int res = req->cqe.res;
++
++	if (req->flags & REQ_F_PARTIAL_IO)
++		res = sr->done_io;
++	io_req_set_res(req, res, req->cqe.flags);
++}
++
++void io_send_zc_fail(struct io_kiocb *req)
++{
++	struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
++
++	if (req->flags & REQ_F_PARTIAL_IO)
++		req->cqe.res = sr->done_io;
++	if (req->flags & REQ_F_NEED_CLEANUP)
++		req->cqe.flags |= IORING_CQE_F_MORE;
++}
++
+ int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+ {
+ 	struct io_accept *accept = io_kiocb_to_cmd(req, struct io_accept);
+@@ -1250,6 +1268,7 @@ int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+ 
+ 	conn->addr = u64_to_user_ptr(READ_ONCE(sqe->addr));
+ 	conn->addr_len =  READ_ONCE(sqe->addr2);
++	conn->in_progress = false;
+ 	return 0;
+ }
+ 
+@@ -1261,6 +1280,16 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
+ 	int ret;
+ 	bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
+ 
++	if (connect->in_progress) {
++		struct socket *socket;
++
++		ret = -ENOTSOCK;
++		socket = sock_from_file(req->file);
++		if (socket)
++			ret = sock_error(socket->sk);
++		goto out;
++	}
++
+ 	if (req_has_async_data(req)) {
+ 		io = req->async_data;
+ 	} else {
+@@ -1277,13 +1306,17 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)
+ 	ret = __sys_connect_file(req->file, &io->address,
+ 					connect->addr_len, file_flags);
+ 	if ((ret == -EAGAIN || ret == -EINPROGRESS) && force_nonblock) {
+-		if (req_has_async_data(req))
+-			return -EAGAIN;
+-		if (io_alloc_async_data(req)) {
+-			ret = -ENOMEM;
+-			goto out;
++		if (ret == -EINPROGRESS) {
++			connect->in_progress = true;
++		} else {
++			if (req_has_async_data(req))
++				return -EAGAIN;
++			if (io_alloc_async_data(req)) {
++				ret = -ENOMEM;
++				goto out;
++			}
++			memcpy(req->async_data, &__io, sizeof(__io));
+ 		}
+-		memcpy(req->async_data, &__io, sizeof(__io));
+ 		return -EAGAIN;
+ 	}
+ 	if (ret == -ERESTARTSYS)
+diff --git a/io_uring/net.h b/io_uring/net.h
+index d744a0a874e75..4090d008fd55a 100644
+--- a/io_uring/net.h
++++ b/io_uring/net.h
+@@ -43,6 +43,8 @@ int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+ int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags);
+ int io_recv(struct io_kiocb *req, unsigned int issue_flags);
+ 
++void io_sendrecv_fail(struct io_kiocb *req);
++
+ int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+ int io_accept(struct io_kiocb *req, unsigned int issue_flags);
+ 
+@@ -53,9 +55,10 @@ int io_connect_prep_async(struct io_kiocb *req);
+ int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+ int io_connect(struct io_kiocb *req, unsigned int issue_flags);
+ 
+-int io_sendzc(struct io_kiocb *req, unsigned int issue_flags);
+-int io_sendzc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+-void io_sendzc_cleanup(struct io_kiocb *req);
++int io_send_zc(struct io_kiocb *req, unsigned int issue_flags);
++int io_send_zc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
++void io_send_zc_cleanup(struct io_kiocb *req);
++void io_send_zc_fail(struct io_kiocb *req);
+ 
+ void io_netmsg_cache_free(struct io_cache_entry *entry);
+ #else
+diff --git a/io_uring/opdef.c b/io_uring/opdef.c
+index c4dddd0fd7094..3b15cdb6dbbc5 100644
+--- a/io_uring/opdef.c
++++ b/io_uring/opdef.c
+@@ -69,6 +69,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.issue			= io_read,
+ 		.prep_async		= io_readv_prep_async,
+ 		.cleanup		= io_readv_writev_cleanup,
++		.fail			= io_rw_fail,
+ 	},
+ 	[IORING_OP_WRITEV] = {
+ 		.needs_file		= 1,
+@@ -85,6 +86,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.issue			= io_write,
+ 		.prep_async		= io_writev_prep_async,
+ 		.cleanup		= io_readv_writev_cleanup,
++		.fail			= io_rw_fail,
+ 	},
+ 	[IORING_OP_FSYNC] = {
+ 		.needs_file		= 1,
+@@ -105,6 +107,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.name			= "READ_FIXED",
+ 		.prep			= io_prep_rw,
+ 		.issue			= io_read,
++		.fail			= io_rw_fail,
+ 	},
+ 	[IORING_OP_WRITE_FIXED] = {
+ 		.needs_file		= 1,
+@@ -119,6 +122,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.name			= "WRITE_FIXED",
+ 		.prep			= io_prep_rw,
+ 		.issue			= io_write,
++		.fail			= io_rw_fail,
+ 	},
+ 	[IORING_OP_POLL_ADD] = {
+ 		.needs_file		= 1,
+@@ -153,6 +157,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.issue			= io_sendmsg,
+ 		.prep_async		= io_sendmsg_prep_async,
+ 		.cleanup		= io_sendmsg_recvmsg_cleanup,
++		.fail			= io_sendrecv_fail,
+ #else
+ 		.prep			= io_eopnotsupp_prep,
+ #endif
+@@ -170,6 +175,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.issue			= io_recvmsg,
+ 		.prep_async		= io_recvmsg_prep_async,
+ 		.cleanup		= io_sendmsg_recvmsg_cleanup,
++		.fail			= io_sendrecv_fail,
+ #else
+ 		.prep			= io_eopnotsupp_prep,
+ #endif
+@@ -273,6 +279,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.name			= "READ",
+ 		.prep			= io_prep_rw,
+ 		.issue			= io_read,
++		.fail			= io_rw_fail,
+ 	},
+ 	[IORING_OP_WRITE] = {
+ 		.needs_file		= 1,
+@@ -287,6 +294,7 @@ const struct io_op_def io_op_defs[] = {
+ 		.name			= "WRITE",
+ 		.prep			= io_prep_rw,
+ 		.issue			= io_write,
++		.fail			= io_rw_fail,
+ 	},
+ 	[IORING_OP_FADVISE] = {
+ 		.needs_file		= 1,
+@@ -310,6 +318,7 @@ const struct io_op_def io_op_defs[] = {
+ #if defined(CONFIG_NET)
+ 		.prep			= io_sendmsg_prep,
+ 		.issue			= io_send,
++		.fail			= io_sendrecv_fail,
+ #else
+ 		.prep			= io_eopnotsupp_prep,
+ #endif
+@@ -325,6 +334,7 @@ const struct io_op_def io_op_defs[] = {
+ #if defined(CONFIG_NET)
+ 		.prep			= io_recvmsg_prep,
+ 		.issue			= io_recv,
++		.fail			= io_sendrecv_fail,
+ #else
+ 		.prep			= io_eopnotsupp_prep,
+ #endif
+@@ -480,10 +490,11 @@ const struct io_op_def io_op_defs[] = {
+ 		.manual_alloc		= 1,
+ #if defined(CONFIG_NET)
+ 		.async_size		= sizeof(struct io_async_msghdr),
+-		.prep			= io_sendzc_prep,
+-		.issue			= io_sendzc,
++		.prep			= io_send_zc_prep,
++		.issue			= io_send_zc,
+ 		.prep_async		= io_sendzc_prep_async,
+-		.cleanup		= io_sendzc_cleanup,
++		.cleanup		= io_send_zc_cleanup,
++		.fail			= io_send_zc_fail,
+ #else
+ 		.prep			= io_eopnotsupp_prep,
+ #endif
+diff --git a/io_uring/opdef.h b/io_uring/opdef.h
+index 763c6e54e2ee5..3efe06d25473a 100644
+--- a/io_uring/opdef.h
++++ b/io_uring/opdef.h
+@@ -36,6 +36,7 @@ struct io_op_def {
+ 	int (*issue)(struct io_kiocb *, unsigned int);
+ 	int (*prep_async)(struct io_kiocb *);
+ 	void (*cleanup)(struct io_kiocb *);
++	void (*fail)(struct io_kiocb *);
+ };
+ 
+ extern const struct io_op_def io_op_defs[];
+diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
+index cf32721132141..50721c17c6cb3 100644
+--- a/io_uring/rsrc.c
++++ b/io_uring/rsrc.c
+@@ -855,6 +855,7 @@ int __io_scm_file_account(struct io_ring_ctx *ctx, struct file *file)
+ 
+ 		UNIXCB(skb).fp = fpl;
+ 		skb->sk = sk;
++		skb->scm_io_uring = 1;
+ 		skb->destructor = unix_destruct_scm;
+ 		refcount_add(skb->truesize, &sk->sk_wmem_alloc);
+ 	}
+diff --git a/io_uring/rw.c b/io_uring/rw.c
+index 76ebcfebc9a6e..60c08a944e2fb 100644
+--- a/io_uring/rw.c
++++ b/io_uring/rw.c
+@@ -184,19 +184,34 @@ static void kiocb_end_write(struct io_kiocb *req)
+ 	}
+ }
+ 
+-static bool __io_complete_rw_common(struct io_kiocb *req, long res)
++/*
++ * Trigger the notifications after having done some IO, and finish the write
++ * accounting, if any.
++ */
++static void io_req_io_end(struct io_kiocb *req)
+ {
+ 	struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
+ 
++	WARN_ON(!in_task());
++
+ 	if (rw->kiocb.ki_flags & IOCB_WRITE) {
+ 		kiocb_end_write(req);
+ 		fsnotify_modify(req->file);
+ 	} else {
+ 		fsnotify_access(req->file);
+ 	}
++}
++
++static bool __io_complete_rw_common(struct io_kiocb *req, long res)
++{
+ 	if (unlikely(res != req->cqe.res)) {
+ 		if ((res == -EAGAIN || res == -EOPNOTSUPP) &&
+ 		    io_rw_should_reissue(req)) {
++			/*
++			 * Reissue will start accounting again, finish the
++			 * current cycle.
++			 */
++			io_req_io_end(req);
+ 			req->flags |= REQ_F_REISSUE | REQ_F_PARTIAL_IO;
+ 			return true;
+ 		}
+@@ -220,6 +235,12 @@ static inline int io_fixup_rw_res(struct io_kiocb *req, long res)
+ 	return res;
+ }
+ 
++static void io_req_rw_complete(struct io_kiocb *req, bool *locked)
++{
++	io_req_io_end(req);
++	io_req_task_complete(req, locked);
++}
++
+ static void io_complete_rw(struct kiocb *kiocb, long res)
+ {
+ 	struct io_rw *rw = container_of(kiocb, struct io_rw, kiocb);
+@@ -228,7 +249,7 @@ static void io_complete_rw(struct kiocb *kiocb, long res)
+ 	if (__io_complete_rw_common(req, res))
+ 		return;
+ 	io_req_set_res(req, io_fixup_rw_res(req, res), 0);
+-	req->io_task_work.func = io_req_task_complete;
++	req->io_task_work.func = io_req_rw_complete;
+ 	io_req_task_work_add(req);
+ }
+ 
+@@ -261,6 +282,11 @@ static int kiocb_done(struct io_kiocb *req, ssize_t ret,
+ 		req->file->f_pos = rw->kiocb.ki_pos;
+ 	if (ret >= 0 && (rw->kiocb.ki_complete == io_complete_rw)) {
+ 		if (!__io_complete_rw_common(req, ret)) {
++			/*
++			 * Safe to call io_end from here as we're inline
++			 * from the submission path.
++			 */
++			io_req_io_end(req);
+ 			io_req_set_res(req, final_ret,
+ 				       io_put_kbuf(req, issue_flags));
+ 			return IOU_OK;
+@@ -794,10 +820,12 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags)
+ 	iov_iter_restore(&s->iter, &s->iter_state);
+ 
+ 	ret2 = io_setup_async_rw(req, iovec, s, true);
+-	if (ret2)
+-		return ret2;
+-
+ 	iovec = NULL;
++	if (ret2) {
++		ret = ret > 0 ? ret : ret2;
++		goto done;
++	}
++
+ 	io = req->async_data;
+ 	s = &io->s;
+ 	/*
+@@ -823,6 +851,7 @@ int io_read(struct io_kiocb *req, unsigned int issue_flags)
+ 			return -EAGAIN;
+ 		}
+ 
++		req->cqe.res = iov_iter_count(&s->iter);
+ 		/*
+ 		 * Now retry read with the IOCB_WAITQ parts set in the iocb. If
+ 		 * we get -EIOCBQUEUED, then we'll get a notification when the
+@@ -984,6 +1013,14 @@ static void io_cqring_ev_posted_iopoll(struct io_ring_ctx *ctx)
+ 		io_cqring_wake(ctx);
+ }
+ 
++void io_rw_fail(struct io_kiocb *req)
++{
++	int res;
++
++	res = io_fixup_rw_res(req, req->cqe.res);
++	io_req_set_res(req, res, req->cqe.flags);
++}
++
+ int io_do_iopoll(struct io_ring_ctx *ctx, bool force_nonspin)
+ {
+ 	struct io_wq_work_node *pos, *start, *prev;
+diff --git a/io_uring/rw.h b/io_uring/rw.h
+index 0204c3fcafa51..3b733f4b610ac 100644
+--- a/io_uring/rw.h
++++ b/io_uring/rw.h
+@@ -21,3 +21,4 @@ int io_readv_prep_async(struct io_kiocb *req);
+ int io_write(struct io_kiocb *req, unsigned int issue_flags);
+ int io_writev_prep_async(struct io_kiocb *req);
+ void io_readv_writev_cleanup(struct io_kiocb *req);
++void io_rw_fail(struct io_kiocb *req);
+diff --git a/ipc/mqueue.c b/ipc/mqueue.c
+index f98de32aeea17..9cf314b3f079f 100644
+--- a/ipc/mqueue.c
++++ b/ipc/mqueue.c
+@@ -1746,6 +1746,7 @@ out_filesystem:
+ 	unregister_filesystem(&mqueue_fs_type);
+ out_sysctl:
+ 	kmem_cache_destroy(mqueue_inode_cachep);
++	retire_mq_sysctls(&init_ipc_ns);
+ 	return error;
+ }
+ 
+diff --git a/kernel/auditsc.c b/kernel/auditsc.c
+index 79a5da1bc5bb6..63a6fe99aa3a8 100644
+--- a/kernel/auditsc.c
++++ b/kernel/auditsc.c
+@@ -1016,7 +1016,6 @@ static void audit_reset_context(struct audit_context *ctx)
+ 	WARN_ON(!list_empty(&ctx->killed_trees));
+ 	audit_free_module(ctx);
+ 	ctx->fds[0] = -1;
+-	audit_proctitle_free(ctx);
+ 	ctx->type = 0; /* reset last for audit_free_*() */
+ }
+ 
+@@ -1077,6 +1076,7 @@ static inline void audit_free_context(struct audit_context *context)
+ {
+ 	/* resetting is extra work, but it is likely just noise */
+ 	audit_reset_context(context);
++	audit_proctitle_free(context);
+ 	free_tree_refs(context);
+ 	kfree(context->filterkey);
+ 	kfree(context);
+@@ -2069,7 +2069,7 @@ void __audit_syscall_exit(int success, long return_code)
+ 	/* run through both filters to ensure we set the filterkey properly */
+ 	audit_filter_syscall(current, context);
+ 	audit_filter_inodes(current, context);
+-	if (context->current_state < AUDIT_STATE_RECORD)
++	if (context->current_state != AUDIT_STATE_RECORD)
+ 		goto out;
+ 
+ 	audit_log_exit();
+diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c
+index 8ce40fd869f6a..d13ffb00e9813 100644
+--- a/kernel/bpf/bpf_local_storage.c
++++ b/kernel/bpf/bpf_local_storage.c
+@@ -555,11 +555,11 @@ void bpf_local_storage_map_free(struct bpf_local_storage_map *smap,
+ 				struct bpf_local_storage_elem, map_node))) {
+ 			if (busy_counter) {
+ 				migrate_disable();
+-				__this_cpu_inc(*busy_counter);
++				this_cpu_inc(*busy_counter);
+ 			}
+ 			bpf_selem_unlink(selem, false);
+ 			if (busy_counter) {
+-				__this_cpu_dec(*busy_counter);
++				this_cpu_dec(*busy_counter);
+ 				migrate_enable();
+ 			}
+ 			cond_resched_rcu();
+diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c
+index fa71d58b7deda..832a0e48a2a16 100644
+--- a/kernel/bpf/bpf_lsm.c
++++ b/kernel/bpf/bpf_lsm.c
+@@ -41,17 +41,21 @@ BTF_SET_END(bpf_lsm_hooks)
+  */
+ BTF_SET_START(bpf_lsm_current_hooks)
+ /* operate on freshly allocated sk without any cgroup association */
++#ifdef CONFIG_SECURITY_NETWORK
+ BTF_ID(func, bpf_lsm_sk_alloc_security)
+ BTF_ID(func, bpf_lsm_sk_free_security)
++#endif
+ BTF_SET_END(bpf_lsm_current_hooks)
+ 
+ /* List of LSM hooks that trigger while the socket is properly locked.
+  */
+ BTF_SET_START(bpf_lsm_locked_sockopt_hooks)
++#ifdef CONFIG_SECURITY_NETWORK
+ BTF_ID(func, bpf_lsm_socket_sock_rcv_skb)
+ BTF_ID(func, bpf_lsm_sock_graft)
+ BTF_ID(func, bpf_lsm_inet_csk_clone)
+ BTF_ID(func, bpf_lsm_inet_conn_established)
++#endif
+ BTF_SET_END(bpf_lsm_locked_sockopt_hooks)
+ 
+ /* List of LSM hooks that trigger while the socket is _not_ locked,
+@@ -59,8 +63,10 @@ BTF_SET_END(bpf_lsm_locked_sockopt_hooks)
+  * in the early init phase.
+  */
+ BTF_SET_START(bpf_lsm_unlocked_sockopt_hooks)
++#ifdef CONFIG_SECURITY_NETWORK
+ BTF_ID(func, bpf_lsm_socket_post_create)
+ BTF_ID(func, bpf_lsm_socket_socketpair)
++#endif
+ BTF_SET_END(bpf_lsm_unlocked_sockopt_hooks)
+ 
+ #ifdef CONFIG_CGROUP_BPF
+diff --git a/kernel/bpf/bpf_task_storage.c b/kernel/bpf/bpf_task_storage.c
+index e9014dc626820..6f290623347e0 100644
+--- a/kernel/bpf/bpf_task_storage.c
++++ b/kernel/bpf/bpf_task_storage.c
+@@ -26,20 +26,20 @@ static DEFINE_PER_CPU(int, bpf_task_storage_busy);
+ static void bpf_task_storage_lock(void)
+ {
+ 	migrate_disable();
+-	__this_cpu_inc(bpf_task_storage_busy);
++	this_cpu_inc(bpf_task_storage_busy);
+ }
+ 
+ static void bpf_task_storage_unlock(void)
+ {
+-	__this_cpu_dec(bpf_task_storage_busy);
++	this_cpu_dec(bpf_task_storage_busy);
+ 	migrate_enable();
+ }
+ 
+ static bool bpf_task_storage_trylock(void)
+ {
+ 	migrate_disable();
+-	if (unlikely(__this_cpu_inc_return(bpf_task_storage_busy) != 1)) {
+-		__this_cpu_dec(bpf_task_storage_busy);
++	if (unlikely(this_cpu_inc_return(bpf_task_storage_busy) != 1)) {
++		this_cpu_dec(bpf_task_storage_busy);
+ 		migrate_enable();
+ 		return false;
+ 	}
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
+index 7e64447659f3d..36fd4b509294a 100644
+--- a/kernel/bpf/btf.c
++++ b/kernel/bpf/btf.c
+@@ -3128,7 +3128,7 @@ static int btf_struct_resolve(struct btf_verifier_env *env,
+ 	if (v->next_member) {
+ 		const struct btf_type *last_member_type;
+ 		const struct btf_member *last_member;
+-		u16 last_member_type_id;
++		u32 last_member_type_id;
+ 
+ 		last_member = btf_type_member(v->t) + v->next_member - 1;
+ 		last_member_type_id = last_member->type;
+diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
+index 4a400cd637316..22888aaa68b66 100644
+--- a/kernel/bpf/cgroup.c
++++ b/kernel/bpf/cgroup.c
+@@ -1020,6 +1020,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+ 			      union bpf_attr __user *uattr)
+ {
+ 	__u32 __user *prog_attach_flags = u64_to_user_ptr(attr->query.prog_attach_flags);
++	bool effective_query = attr->query.query_flags & BPF_F_QUERY_EFFECTIVE;
+ 	__u32 __user *prog_ids = u64_to_user_ptr(attr->query.prog_ids);
+ 	enum bpf_attach_type type = attr->query.attach_type;
+ 	enum cgroup_bpf_attach_type from_atype, to_atype;
+@@ -1029,8 +1030,12 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+ 	int total_cnt = 0;
+ 	u32 flags;
+ 
++	if (effective_query && prog_attach_flags)
++		return -EINVAL;
++
+ 	if (type == BPF_LSM_CGROUP) {
+-		if (attr->query.prog_cnt && prog_ids && !prog_attach_flags)
++		if (!effective_query && attr->query.prog_cnt &&
++		    prog_ids && !prog_attach_flags)
+ 			return -EINVAL;
+ 
+ 		from_atype = CGROUP_LSM_START;
+@@ -1045,7 +1050,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+ 	}
+ 
+ 	for (atype = from_atype; atype <= to_atype; atype++) {
+-		if (attr->query.query_flags & BPF_F_QUERY_EFFECTIVE) {
++		if (effective_query) {
+ 			effective = rcu_dereference_protected(cgrp->bpf.effective[atype],
+ 							      lockdep_is_held(&cgroup_mutex));
+ 			total_cnt += bpf_prog_array_length(effective);
+@@ -1054,6 +1059,8 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+ 		}
+ 	}
+ 
++	/* always output uattr->query.attach_flags as 0 during effective query */
++	flags = effective_query ? 0 : flags;
+ 	if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags)))
+ 		return -EFAULT;
+ 	if (copy_to_user(&uattr->query.prog_cnt, &total_cnt, sizeof(total_cnt)))
+@@ -1068,7 +1075,7 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+ 	}
+ 
+ 	for (atype = from_atype; atype <= to_atype && total_cnt; atype++) {
+-		if (attr->query.query_flags & BPF_F_QUERY_EFFECTIVE) {
++		if (effective_query) {
+ 			effective = rcu_dereference_protected(cgrp->bpf.effective[atype],
+ 							      lockdep_is_held(&cgroup_mutex));
+ 			cnt = min_t(int, bpf_prog_array_length(effective), total_cnt);
+@@ -1090,15 +1097,16 @@ static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
+ 				if (++i == cnt)
+ 					break;
+ 			}
+-		}
+ 
+-		if (prog_attach_flags) {
+-			flags = cgrp->bpf.flags[atype];
++			if (prog_attach_flags) {
++				flags = cgrp->bpf.flags[atype];
+ 
+-			for (i = 0; i < cnt; i++)
+-				if (copy_to_user(prog_attach_flags + i, &flags, sizeof(flags)))
+-					return -EFAULT;
+-			prog_attach_flags += cnt;
++				for (i = 0; i < cnt; i++)
++					if (copy_to_user(prog_attach_flags + i,
++							 &flags, sizeof(flags)))
++						return -EFAULT;
++				prog_attach_flags += cnt;
++			}
+ 		}
+ 
+ 		prog_ids += cnt;
+diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
+index 3d9eb3ae334ce..c4600a5781de1 100644
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -825,6 +825,11 @@ struct bpf_prog_pack {
+ 	unsigned long bitmap[];
+ };
+ 
++void bpf_jit_fill_hole_with_zero(void *area, unsigned int size)
++{
++	memset(area, 0, size);
++}
++
+ #define BPF_PROG_SIZE_TO_NBITS(size)	(round_up(size, BPF_PROG_CHUNK_SIZE) / BPF_PROG_CHUNK_SIZE)
+ 
+ static DEFINE_MUTEX(pack_mutex);
+@@ -864,7 +869,7 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
+ 	return pack;
+ }
+ 
+-static void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
++void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
+ {
+ 	unsigned int nbits = BPF_PROG_SIZE_TO_NBITS(size);
+ 	struct bpf_prog_pack *pack;
+@@ -905,7 +910,7 @@ out:
+ 	return ptr;
+ }
+ 
+-static void bpf_prog_pack_free(struct bpf_binary_header *hdr)
++void bpf_prog_pack_free(struct bpf_binary_header *hdr)
+ {
+ 	struct bpf_prog_pack *pack = NULL, *tmp;
+ 	unsigned int nbits;
+diff --git a/kernel/bpf/dispatcher.c b/kernel/bpf/dispatcher.c
+index 2444bd15cc2d0..fa64b80b8bcab 100644
+--- a/kernel/bpf/dispatcher.c
++++ b/kernel/bpf/dispatcher.c
+@@ -85,12 +85,12 @@ static bool bpf_dispatcher_remove_prog(struct bpf_dispatcher *d,
+ 	return false;
+ }
+ 
+-int __weak arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
++int __weak arch_prepare_bpf_dispatcher(void *image, void *buf, s64 *funcs, int num_funcs)
+ {
+ 	return -ENOTSUPP;
+ }
+ 
+-static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image)
++static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image, void *buf)
+ {
+ 	s64 ips[BPF_DISPATCHER_MAX] = {}, *ipsp = &ips[0];
+ 	int i;
+@@ -99,12 +99,12 @@ static int bpf_dispatcher_prepare(struct bpf_dispatcher *d, void *image)
+ 		if (d->progs[i].prog)
+ 			*ipsp++ = (s64)(uintptr_t)d->progs[i].prog->bpf_func;
+ 	}
+-	return arch_prepare_bpf_dispatcher(image, &ips[0], d->num_progs);
++	return arch_prepare_bpf_dispatcher(image, buf, &ips[0], d->num_progs);
+ }
+ 
+ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
+ {
+-	void *old, *new;
++	void *old, *new, *tmp;
+ 	u32 noff;
+ 	int err;
+ 
+@@ -117,8 +117,14 @@ static void bpf_dispatcher_update(struct bpf_dispatcher *d, int prev_num_progs)
+ 	}
+ 
+ 	new = d->num_progs ? d->image + noff : NULL;
++	tmp = d->num_progs ? d->rw_image + noff : NULL;
+ 	if (new) {
+-		if (bpf_dispatcher_prepare(d, new))
++		/* Prepare the dispatcher in d->rw_image. Then use
++		 * bpf_arch_text_copy to update d->image, which is RO+X.
++		 */
++		if (bpf_dispatcher_prepare(d, new, tmp))
++			return;
++		if (IS_ERR(bpf_arch_text_copy(new, tmp, PAGE_SIZE / 2)))
+ 			return;
+ 	}
+ 
+@@ -140,9 +146,18 @@ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
+ 
+ 	mutex_lock(&d->mutex);
+ 	if (!d->image) {
+-		d->image = bpf_jit_alloc_exec_page();
++		d->image = bpf_prog_pack_alloc(PAGE_SIZE, bpf_jit_fill_hole_with_zero);
+ 		if (!d->image)
+ 			goto out;
++		d->rw_image = bpf_jit_alloc_exec(PAGE_SIZE);
++		if (!d->rw_image) {
++			u32 size = PAGE_SIZE;
++
++			bpf_arch_text_copy(d->image, &size, sizeof(size));
++			bpf_prog_pack_free((struct bpf_binary_header *)d->image);
++			d->image = NULL;
++			goto out;
++		}
+ 		bpf_image_ksym_add(d->image, &d->ksym);
+ 	}
+ 
+diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
+index 6c530a5e560a4..75f77df910dcc 100644
+--- a/kernel/bpf/hashtab.c
++++ b/kernel/bpf/hashtab.c
+@@ -162,17 +162,25 @@ static inline int htab_lock_bucket(const struct bpf_htab *htab,
+ 				   unsigned long *pflags)
+ {
+ 	unsigned long flags;
++	bool use_raw_lock;
+ 
+ 	hash = hash & HASHTAB_MAP_LOCK_MASK;
+ 
+-	migrate_disable();
++	use_raw_lock = htab_use_raw_lock(htab);
++	if (use_raw_lock)
++		preempt_disable();
++	else
++		migrate_disable();
+ 	if (unlikely(__this_cpu_inc_return(*(htab->map_locked[hash])) != 1)) {
+ 		__this_cpu_dec(*(htab->map_locked[hash]));
+-		migrate_enable();
++		if (use_raw_lock)
++			preempt_enable();
++		else
++			migrate_enable();
+ 		return -EBUSY;
+ 	}
+ 
+-	if (htab_use_raw_lock(htab))
++	if (use_raw_lock)
+ 		raw_spin_lock_irqsave(&b->raw_lock, flags);
+ 	else
+ 		spin_lock_irqsave(&b->lock, flags);
+@@ -185,13 +193,18 @@ static inline void htab_unlock_bucket(const struct bpf_htab *htab,
+ 				      struct bucket *b, u32 hash,
+ 				      unsigned long flags)
+ {
++	bool use_raw_lock = htab_use_raw_lock(htab);
++
+ 	hash = hash & HASHTAB_MAP_LOCK_MASK;
+-	if (htab_use_raw_lock(htab))
++	if (use_raw_lock)
+ 		raw_spin_unlock_irqrestore(&b->raw_lock, flags);
+ 	else
+ 		spin_unlock_irqrestore(&b->lock, flags);
+ 	__this_cpu_dec(*(htab->map_locked[hash]));
+-	migrate_enable();
++	if (use_raw_lock)
++		preempt_enable();
++	else
++		migrate_enable();
+ }
+ 
+ static bool htab_lru_map_delete_node(void *arg, struct bpf_lru_node *node);
+@@ -1691,8 +1704,11 @@ again_nocopy:
+ 	/* do not grab the lock unless need it (bucket_cnt > 0). */
+ 	if (locked) {
+ 		ret = htab_lock_bucket(htab, b, batch, &flags);
+-		if (ret)
+-			goto next_batch;
++		if (ret) {
++			rcu_read_unlock();
++			bpf_enable_instrumentation();
++			goto after_loop;
++		}
+ 	}
+ 
+ 	bucket_cnt = 0;
+diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
+index 3814b0fd3a2c5..ed7649b047041 100644
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -1468,6 +1468,8 @@ BPF_CALL_4(bpf_dynptr_from_mem, void *, data, u32, size, u64, flags, struct bpf_
+ {
+ 	int err;
+ 
++	BTF_TYPE_EMIT(struct bpf_dynptr);
++
+ 	err = bpf_dynptr_check_size(size);
+ 	if (err)
+ 		goto error;
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index f798acd43a280..22e7a805c6723 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -4395,7 +4395,9 @@ static int bpf_task_fd_query(const union bpf_attr *attr,
+ 	if (attr->task_fd_query.flags != 0)
+ 		return -EINVAL;
+ 
++	rcu_read_lock();
+ 	task = get_pid_task(find_vpid(pid), PIDTYPE_PID);
++	rcu_read_unlock();
+ 	if (!task)
+ 		return -ENOENT;
+ 
+diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
+index ff87e38af8a7a..ad76940b02ccf 100644
+--- a/kernel/bpf/trampoline.c
++++ b/kernel/bpf/trampoline.c
+@@ -895,7 +895,7 @@ u64 notrace __bpf_prog_enter(struct bpf_prog *prog, struct bpf_tramp_run_ctx *ru
+ 
+ 	run_ctx->saved_run_ctx = bpf_set_run_ctx(&run_ctx->run_ctx);
+ 
+-	if (unlikely(__this_cpu_inc_return(*(prog->active)) != 1)) {
++	if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) {
+ 		inc_misses_counter(prog);
+ 		return 0;
+ 	}
+@@ -930,7 +930,7 @@ void notrace __bpf_prog_exit(struct bpf_prog *prog, u64 start, struct bpf_tramp_
+ 	bpf_reset_run_ctx(run_ctx->saved_run_ctx);
+ 
+ 	update_prog_stats(prog, start);
+-	__this_cpu_dec(*(prog->active));
++	this_cpu_dec(*(prog->active));
+ 	migrate_enable();
+ 	rcu_read_unlock();
+ }
+@@ -966,7 +966,7 @@ u64 notrace __bpf_prog_enter_sleepable(struct bpf_prog *prog, struct bpf_tramp_r
+ 	migrate_disable();
+ 	might_fault();
+ 
+-	if (unlikely(__this_cpu_inc_return(*(prog->active)) != 1)) {
++	if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) {
+ 		inc_misses_counter(prog);
+ 		return 0;
+ 	}
+@@ -982,7 +982,7 @@ void notrace __bpf_prog_exit_sleepable(struct bpf_prog *prog, u64 start,
+ 	bpf_reset_run_ctx(run_ctx->saved_run_ctx);
+ 
+ 	update_prog_stats(prog, start);
+-	__this_cpu_dec(*(prog->active));
++	this_cpu_dec(*(prog->active));
+ 	migrate_enable();
+ 	rcu_read_unlock_trace();
+ }
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 3eadb14e090b7..8b5ea7f6b5365 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -467,25 +467,11 @@ static bool type_is_rdonly_mem(u32 type)
+ 	return type & MEM_RDONLY;
+ }
+ 
+-static bool arg_type_may_be_refcounted(enum bpf_arg_type type)
+-{
+-	return type == ARG_PTR_TO_SOCK_COMMON;
+-}
+-
+ static bool type_may_be_null(u32 type)
+ {
+ 	return type & PTR_MAYBE_NULL;
+ }
+ 
+-static bool may_be_acquire_function(enum bpf_func_id func_id)
+-{
+-	return func_id == BPF_FUNC_sk_lookup_tcp ||
+-		func_id == BPF_FUNC_sk_lookup_udp ||
+-		func_id == BPF_FUNC_skc_lookup_tcp ||
+-		func_id == BPF_FUNC_map_lookup_elem ||
+-	        func_id == BPF_FUNC_ringbuf_reserve;
+-}
+-
+ static bool is_acquire_function(enum bpf_func_id func_id,
+ 				const struct bpf_map *map)
+ {
+@@ -518,6 +504,26 @@ static bool is_ptr_cast_function(enum bpf_func_id func_id)
+ 		func_id == BPF_FUNC_skc_to_tcp_request_sock;
+ }
+ 
++static bool is_dynptr_ref_function(enum bpf_func_id func_id)
++{
++	return func_id == BPF_FUNC_dynptr_data;
++}
++
++static bool helper_multiple_ref_obj_use(enum bpf_func_id func_id,
++					const struct bpf_map *map)
++{
++	int ref_obj_uses = 0;
++
++	if (is_ptr_cast_function(func_id))
++		ref_obj_uses++;
++	if (is_acquire_function(func_id, map))
++		ref_obj_uses++;
++	if (is_dynptr_ref_function(func_id))
++		ref_obj_uses++;
++
++	return ref_obj_uses > 1;
++}
++
+ static bool is_cmpxchg_insn(const struct bpf_insn *insn)
+ {
+ 	return BPF_CLASS(insn->code) == BPF_STX &&
+@@ -1086,6 +1092,7 @@ static int acquire_reference_state(struct bpf_verifier_env *env, int insn_idx)
+ 	id = ++env->id_gen;
+ 	state->refs[new_ofs].id = id;
+ 	state->refs[new_ofs].insn_idx = insn_idx;
++	state->refs[new_ofs].callback_ref = state->in_callback_fn ? state->frameno : 0;
+ 
+ 	return id;
+ }
+@@ -1098,6 +1105,9 @@ static int release_reference_state(struct bpf_func_state *state, int ptr_id)
+ 	last_idx = state->acquired_refs - 1;
+ 	for (i = 0; i < state->acquired_refs; i++) {
+ 		if (state->refs[i].id == ptr_id) {
++			/* Cannot release caller references in callbacks */
++			if (state->in_callback_fn && state->refs[i].callback_ref != state->frameno)
++				return -EINVAL;
+ 			if (last_idx && i != last_idx)
+ 				memcpy(&state->refs[i], &state->refs[last_idx],
+ 				       sizeof(*state->refs));
+@@ -6456,33 +6466,6 @@ static bool check_arg_pair_ok(const struct bpf_func_proto *fn)
+ 	return true;
+ }
+ 
+-static bool check_refcount_ok(const struct bpf_func_proto *fn, int func_id)
+-{
+-	int count = 0;
+-
+-	if (arg_type_may_be_refcounted(fn->arg1_type))
+-		count++;
+-	if (arg_type_may_be_refcounted(fn->arg2_type))
+-		count++;
+-	if (arg_type_may_be_refcounted(fn->arg3_type))
+-		count++;
+-	if (arg_type_may_be_refcounted(fn->arg4_type))
+-		count++;
+-	if (arg_type_may_be_refcounted(fn->arg5_type))
+-		count++;
+-
+-	/* A reference acquiring function cannot acquire
+-	 * another refcounted ptr.
+-	 */
+-	if (may_be_acquire_function(func_id) && count)
+-		return false;
+-
+-	/* We only support one arg being unreferenced at the moment,
+-	 * which is sufficient for the helper functions we have right now.
+-	 */
+-	return count <= 1;
+-}
+-
+ static bool check_btf_id_ok(const struct bpf_func_proto *fn)
+ {
+ 	int i;
+@@ -6506,8 +6489,7 @@ static int check_func_proto(const struct bpf_func_proto *fn, int func_id,
+ {
+ 	return check_raw_mode_ok(fn) &&
+ 	       check_arg_pair_ok(fn) &&
+-	       check_btf_id_ok(fn) &&
+-	       check_refcount_ok(fn, func_id) ? 0 : -EINVAL;
++	       check_btf_id_ok(fn) ? 0 : -EINVAL;
+ }
+ 
+ /* Packet data might have moved, any old PTR_TO_PACKET[_META,_END]
+@@ -6941,10 +6923,17 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
+ 		caller->regs[BPF_REG_0] = *r0;
+ 	}
+ 
+-	/* Transfer references to the caller */
+-	err = copy_reference_state(caller, callee);
+-	if (err)
+-		return err;
++	/* callback_fn frame should have released its own additions to parent's
++	 * reference state at this point, or check_reference_leak would
++	 * complain, hence it must be the same as the caller. There is no need
++	 * to copy it back.
++	 */
++	if (!callee->in_callback_fn) {
++		/* Transfer references to the caller */
++		err = copy_reference_state(caller, callee);
++		if (err)
++			return err;
++	}
+ 
+ 	*insn_idx = callee->callsite + 1;
+ 	if (env->log.level & BPF_LOG_LEVEL) {
+@@ -7066,13 +7055,20 @@ record_func_key(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
+ static int check_reference_leak(struct bpf_verifier_env *env)
+ {
+ 	struct bpf_func_state *state = cur_func(env);
++	bool refs_lingering = false;
+ 	int i;
+ 
++	if (state->frameno && !state->in_callback_fn)
++		return 0;
++
+ 	for (i = 0; i < state->acquired_refs; i++) {
++		if (state->in_callback_fn && state->refs[i].callback_ref != state->frameno)
++			continue;
+ 		verbose(env, "Unreleased reference id=%d alloc_insn=%d\n",
+ 			state->refs[i].id, state->refs[i].insn_idx);
++		refs_lingering = true;
+ 	}
+-	return state->acquired_refs ? -EINVAL : 0;
++	return refs_lingering ? -EINVAL : 0;
+ }
+ 
+ static int check_bpf_snprintf_call(struct bpf_verifier_env *env,
+@@ -7344,6 +7340,23 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ 			}
+ 		}
+ 		break;
++	case BPF_FUNC_dynptr_data:
++		for (i = 0; i < MAX_BPF_FUNC_REG_ARGS; i++) {
++			if (arg_type_is_dynptr(fn->arg_type[i])) {
++				if (meta.ref_obj_id) {
++					verbose(env, "verifier internal error: meta.ref_obj_id already set\n");
++					return -EFAULT;
++				}
++				/* Find the id of the dynptr we're tracking the reference of */
++				meta.ref_obj_id = stack_slot_get_id(env, &regs[BPF_REG_1 + i]);
++				break;
++			}
++		}
++		if (i == MAX_BPF_FUNC_REG_ARGS) {
++			verbose(env, "verifier internal error: no dynptr in bpf_dynptr_data()\n");
++			return -EFAULT;
++		}
++		break;
+ 	}
+ 
+ 	if (err)
+@@ -7460,7 +7473,13 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ 	if (type_may_be_null(regs[BPF_REG_0].type))
+ 		regs[BPF_REG_0].id = ++env->id_gen;
+ 
+-	if (is_ptr_cast_function(func_id)) {
++	if (helper_multiple_ref_obj_use(func_id, meta.map_ptr)) {
++		verbose(env, "verifier internal error: func %s#%d sets ref_obj_id more than once\n",
++			func_id_name(func_id), func_id);
++		return -EFAULT;
++	}
++
++	if (is_ptr_cast_function(func_id) || is_dynptr_ref_function(func_id)) {
+ 		/* For release_reference() */
+ 		regs[BPF_REG_0].ref_obj_id = meta.ref_obj_id;
+ 	} else if (is_acquire_function(func_id, meta.map_ptr)) {
+@@ -7472,21 +7491,6 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
+ 		regs[BPF_REG_0].id = id;
+ 		/* For release_reference() */
+ 		regs[BPF_REG_0].ref_obj_id = id;
+-	} else if (func_id == BPF_FUNC_dynptr_data) {
+-		int dynptr_id = 0, i;
+-
+-		/* Find the id of the dynptr we're acquiring a reference to */
+-		for (i = 0; i < MAX_BPF_FUNC_REG_ARGS; i++) {
+-			if (arg_type_is_dynptr(fn->arg_type[i])) {
+-				if (dynptr_id) {
+-					verbose(env, "verifier internal error: multiple dynptr args in func\n");
+-					return -EFAULT;
+-				}
+-				dynptr_id = stack_slot_get_id(env, &regs[BPF_REG_1 + i]);
+-			}
+-		}
+-		/* For release_reference() */
+-		regs[BPF_REG_0].ref_obj_id = dynptr_id;
+ 	}
+ 
+ 	do_refine_retval_range(regs, fn->ret_type, func_id, &meta);
+@@ -12333,6 +12337,16 @@ static int do_check(struct bpf_verifier_env *env)
+ 					return -EINVAL;
+ 				}
+ 
++				/* We must do check_reference_leak here before
++				 * prepare_func_exit to handle the case when
++				 * state->curframe > 0, it may be a callback
++				 * function, for which reference_state must
++				 * match caller reference state when it exits.
++				 */
++				err = check_reference_leak(env);
++				if (err)
++					return err;
++
+ 				if (state->curframe) {
+ 					/* exit from nested function */
+ 					err = prepare_func_exit(env, &env->insn_idx);
+@@ -12342,10 +12356,6 @@ static int do_check(struct bpf_verifier_env *env)
+ 					continue;
+ 				}
+ 
+-				err = check_reference_leak(env);
+-				if (err)
+-					return err;
+-
+ 				err = check_return_code(env);
+ 				if (err)
+ 					return err;
+diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
+index 5f2090d051acb..29296a6374efa 100644
+--- a/kernel/cgroup/cgroup.c
++++ b/kernel/cgroup/cgroup.c
+@@ -6638,8 +6638,12 @@ struct cgroup *cgroup_get_from_path(const char *path)
+ {
+ 	struct kernfs_node *kn;
+ 	struct cgroup *cgrp = ERR_PTR(-ENOENT);
++	struct cgroup *root_cgrp;
+ 
+-	kn = kernfs_walk_and_get(cgrp_dfl_root.cgrp.kn, path);
++	spin_lock_irq(&css_set_lock);
++	root_cgrp = current_cgns_cgroup_from_root(&cgrp_dfl_root);
++	kn = kernfs_walk_and_get(root_cgrp->kn, path);
++	spin_unlock_irq(&css_set_lock);
+ 	if (!kn)
+ 		goto out;
+ 
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index 1f3a55297f39d..50bf837571ac8 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -33,6 +33,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/kernel.h>
+ #include <linux/kmod.h>
++#include <linux/kthread.h>
+ #include <linux/list.h>
+ #include <linux/mempolicy.h>
+ #include <linux/mm.h>
+@@ -1127,10 +1128,18 @@ static void update_tasks_cpumask(struct cpuset *cs)
+ {
+ 	struct css_task_iter it;
+ 	struct task_struct *task;
++	bool top_cs = cs == &top_cpuset;
+ 
+ 	css_task_iter_start(&cs->css, 0, &it);
+-	while ((task = css_task_iter_next(&it)))
++	while ((task = css_task_iter_next(&it))) {
++		/*
++		 * Percpu kthreads in top_cpuset are ignored
++		 */
++		if (top_cs && (task->flags & PF_KTHREAD) &&
++		    kthread_is_per_cpu(task))
++			continue;
+ 		set_cpus_allowed_ptr(task, cs->effective_cpus);
++	}
+ 	css_task_iter_end(&it);
+ }
+ 
+@@ -2092,12 +2101,7 @@ static int update_prstate(struct cpuset *cs, int new_prs)
+ 		update_flag(CS_CPU_EXCLUSIVE, cs, 0);
+ 	}
+ 
+-	/*
+-	 * Update cpumask of parent's tasks except when it is the top
+-	 * cpuset as some system daemons cannot be mapped to other CPUs.
+-	 */
+-	if (parent != &top_cpuset)
+-		update_tasks_cpumask(parent);
++	update_tasks_cpumask(parent);
+ 
+ 	if (parent->child_ecpus_count)
+ 		update_sibling_cpumasks(parent, cs, &tmpmask);
+diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
+index 5d03a2ad10661..30187b1d82759 100644
+--- a/kernel/livepatch/transition.c
++++ b/kernel/livepatch/transition.c
+@@ -610,9 +610,23 @@ void klp_reverse_transition(void)
+ /* Called from copy_process() during fork */
+ void klp_copy_process(struct task_struct *child)
+ {
+-	child->patch_state = current->patch_state;
+ 
+-	/* TIF_PATCH_PENDING gets copied in setup_thread_stack() */
++	/*
++	 * The parent process may have gone through a KLP transition since
++	 * the thread flag was copied in setup_thread_stack earlier. Bring
++	 * the task flag up to date with the parent here.
++	 *
++	 * The operation is serialized against all klp_*_transition()
++	 * operations by the tasklist_lock. The only exception is
++	 * klp_update_patch_state(current), but we cannot race with
++	 * that because we are current.
++	 */
++	if (test_tsk_thread_flag(current, TIF_PATCH_PENDING))
++		set_tsk_thread_flag(child, TIF_PATCH_PENDING);
++	else
++		clear_tsk_thread_flag(child, TIF_PATCH_PENDING);
++
++	child->patch_state = current->patch_state;
+ }
+ 
+ /*
+diff --git a/kernel/module/tracking.c b/kernel/module/tracking.c
+index 7f8133044d092..af52cabfe6321 100644
+--- a/kernel/module/tracking.c
++++ b/kernel/module/tracking.c
+@@ -21,6 +21,9 @@ int try_add_tainted_module(struct module *mod)
+ 
+ 	module_assert_mutex_or_preempt();
+ 
++	if (!mod->taints)
++		goto out;
++
+ 	list_for_each_entry_rcu(mod_taint, &unloaded_tainted_modules, list,
+ 				lockdep_is_held(&module_mutex)) {
+ 		if (!strcmp(mod_taint->name, mod->name) &&
+diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
+index 83c7e6620d403..f5bf6fb430dab 100644
+--- a/kernel/rcu/tasks.h
++++ b/kernel/rcu/tasks.h
+@@ -560,7 +560,7 @@ static int __noreturn rcu_tasks_kthread(void *arg)
+ static void synchronize_rcu_tasks_generic(struct rcu_tasks *rtp)
+ {
+ 	/* Complain if the scheduler has not started.  */
+-	RCU_LOCKDEP_WARN(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE,
++	WARN_ONCE(rcu_scheduler_active == RCU_SCHEDULER_INACTIVE,
+ 			 "synchronize_rcu_tasks called too soon");
+ 
+ 	// If the grace-period kthread is running, use it.
+@@ -1500,6 +1500,7 @@ static void rcu_tasks_trace_pregp_step(struct list_head *hop)
+ 		if (rcu_tasks_trace_pertask_prep(t, true))
+ 			trc_add_holdout(t, hop);
+ 		rcu_read_unlock();
++		cond_resched_tasks_rcu_qs();
+ 	}
+ 
+ 	// Only after all running tasks have been accounted for is it
+@@ -1520,6 +1521,7 @@ static void rcu_tasks_trace_pregp_step(struct list_head *hop)
+ 			raw_spin_lock_irqsave_rcu_node(rtpcp, flags);
+ 		}
+ 		raw_spin_unlock_irqrestore_rcu_node(rtpcp, flags);
++		cond_resched_tasks_rcu_qs();
+ 	}
+ 
+ 	// Re-enable CPU hotplug now that the holdout list is populated.
+@@ -1619,6 +1621,7 @@ static void check_all_holdout_tasks_trace(struct list_head *hop,
+ 			trc_del_holdout(t);
+ 		else if (needreport)
+ 			show_stalled_task_trace(t, firstreport);
++		cond_resched_tasks_rcu_qs();
+ 	}
+ 
+ 	// Re-enable CPU hotplug now that the holdout list scan has completed.
+diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
+index 79aea7df4345e..eb435941e92fd 100644
+--- a/kernel/rcu/tree.c
++++ b/kernel/rcu/tree.c
+@@ -3183,15 +3183,16 @@ static void fill_page_cache_func(struct work_struct *work)
+ 		bnode = (struct kvfree_rcu_bulk_data *)
+ 			__get_free_page(GFP_KERNEL | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
+ 
+-		if (bnode) {
+-			raw_spin_lock_irqsave(&krcp->lock, flags);
+-			pushed = put_cached_bnode(krcp, bnode);
+-			raw_spin_unlock_irqrestore(&krcp->lock, flags);
++		if (!bnode)
++			break;
+ 
+-			if (!pushed) {
+-				free_page((unsigned long) bnode);
+-				break;
+-			}
++		raw_spin_lock_irqsave(&krcp->lock, flags);
++		pushed = put_cached_bnode(krcp, bnode);
++		raw_spin_unlock_irqrestore(&krcp->lock, flags);
++
++		if (!pushed) {
++			free_page((unsigned long) bnode);
++			break;
+ 		}
+ 	}
+ 
+diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
+index 438ecae6bd7e7..49468b4d1b43f 100644
+--- a/kernel/rcu/tree_plugin.h
++++ b/kernel/rcu/tree_plugin.h
+@@ -641,7 +641,8 @@ static void rcu_read_unlock_special(struct task_struct *t)
+ 
+ 		expboost = (t->rcu_blocked_node && READ_ONCE(t->rcu_blocked_node->exp_tasks)) ||
+ 			   (rdp->grpmask & READ_ONCE(rnp->expmask)) ||
+-			   IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD) ||
++			   (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD) &&
++			   ((rdp->grpmask & READ_ONCE(rnp->qsmask)) || t->rcu_blocked_node)) ||
+ 			   (IS_ENABLED(CONFIG_RCU_BOOST) && irqs_were_disabled &&
+ 			    t->rcu_blocked_node);
+ 		// Need to defer quiescent state until everything is enabled.
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index 68e5cdd24cef8..b1daf7c9b895a 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -1026,6 +1026,22 @@ static const struct bpf_func_proto bpf_get_func_ip_proto_tracing = {
+ 	.arg1_type	= ARG_PTR_TO_CTX,
+ };
+ 
++#ifdef CONFIG_X86_KERNEL_IBT
++static unsigned long get_entry_ip(unsigned long fentry_ip)
++{
++	u32 instr;
++
++	/* Being extra safe in here in case entry ip is on the page-edge. */
++	if (get_kernel_nofault(instr, (u32 *) fentry_ip - 1))
++		return fentry_ip;
++	if (is_endbr(instr))
++		fentry_ip -= ENDBR_INSN_SIZE;
++	return fentry_ip;
++}
++#else
++#define get_entry_ip(fentry_ip) fentry_ip
++#endif
++
+ BPF_CALL_1(bpf_get_func_ip_kprobe, struct pt_regs *, regs)
+ {
+ 	struct kprobe *kp = kprobe_running();
+@@ -2414,13 +2430,13 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link,
+ }
+ 
+ static void
+-kprobe_multi_link_handler(struct fprobe *fp, unsigned long entry_ip,
++kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip,
+ 			  struct pt_regs *regs)
+ {
+ 	struct bpf_kprobe_multi_link *link;
+ 
+ 	link = container_of(fp, struct bpf_kprobe_multi_link, fp);
+-	kprobe_multi_link_prog_run(link, entry_ip, regs);
++	kprobe_multi_link_prog_run(link, get_entry_ip(fentry_ip), regs);
+ }
+ 
+ static int symbols_cmp_r(const void *a, const void *b, const void *priv)
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 439e2ab6905ee..83362a1557916 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -1644,6 +1644,18 @@ ftrace_find_tramp_ops_any_other(struct dyn_ftrace *rec, struct ftrace_ops *op_ex
+ static struct ftrace_ops *
+ ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, struct ftrace_ops *ops);
+ 
++static bool skip_record(struct dyn_ftrace *rec)
++{
++	/*
++	 * At boot up, weak functions are set to disable. Function tracing
++	 * can be enabled before they are, and they still need to be disabled now.
++	 * If the record is disabled, still continue if it is marked as already
++	 * enabled (this is needed to keep the accounting working).
++	 */
++	return rec->flags & FTRACE_FL_DISABLED &&
++		!(rec->flags & FTRACE_FL_ENABLED);
++}
++
+ static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
+ 				     int filter_hash,
+ 				     bool inc)
+@@ -1693,7 +1705,7 @@ static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
+ 		int in_hash = 0;
+ 		int match = 0;
+ 
+-		if (rec->flags & FTRACE_FL_DISABLED)
++		if (skip_record(rec))
+ 			continue;
+ 
+ 		if (all) {
+@@ -2126,7 +2138,7 @@ static int ftrace_check_record(struct dyn_ftrace *rec, bool enable, bool update)
+ 
+ 	ftrace_bug_type = FTRACE_BUG_UNKNOWN;
+ 
+-	if (rec->flags & FTRACE_FL_DISABLED)
++	if (skip_record(rec))
+ 		return FTRACE_UPDATE_IGNORE;
+ 
+ 	/*
+@@ -2241,7 +2253,7 @@ static int ftrace_check_record(struct dyn_ftrace *rec, bool enable, bool update)
+ 	if (update) {
+ 		/* If there's no more users, clear all flags */
+ 		if (!ftrace_rec_count(rec))
+-			rec->flags = 0;
++			rec->flags &= FTRACE_FL_DISABLED;
+ 		else
+ 			/*
+ 			 * Just disable the record, but keep the ops TRAMP
+@@ -2634,7 +2646,7 @@ void __weak ftrace_replace_code(int mod_flags)
+ 
+ 	do_for_each_ftrace_rec(pg, rec) {
+ 
+-		if (rec->flags & FTRACE_FL_DISABLED)
++		if (skip_record(rec))
+ 			continue;
+ 
+ 		failed = __ftrace_replace_code(rec, enable);
+@@ -5427,6 +5439,8 @@ static struct ftrace_ops stub_ops = {
+  * it is safe to modify the ftrace record, where it should be
+  * currently calling @old_addr directly, to call @new_addr.
+  *
++ * This is called with direct_mutex locked.
++ *
+  * Safety checks should be made to make sure that the code at
+  * @rec->ip is currently calling @old_addr. And this must
+  * also update entry->direct to @new_addr.
+@@ -5439,6 +5453,8 @@ int __weak ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
+ 	unsigned long ip = rec->ip;
+ 	int ret;
+ 
++	lockdep_assert_held(&direct_mutex);
++
+ 	/*
+ 	 * The ftrace_lock was used to determine if the record
+ 	 * had more than one registered user to it. If it did,
+@@ -5461,7 +5477,7 @@ int __weak ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
+ 	if (ret)
+ 		goto out_lock;
+ 
+-	ret = register_ftrace_function(&stub_ops);
++	ret = register_ftrace_function_nolock(&stub_ops);
+ 	if (ret) {
+ 		ftrace_set_filter_ip(&stub_ops, ip, 1, 0);
+ 		goto out_lock;
+@@ -6081,8 +6097,12 @@ int ftrace_regex_release(struct inode *inode, struct file *file)
+ 
+ 		if (filter_hash) {
+ 			orig_hash = &iter->ops->func_hash->filter_hash;
+-			if (iter->tr && !list_empty(&iter->tr->mod_trace))
+-				iter->hash->flags |= FTRACE_HASH_FL_MOD;
++			if (iter->tr) {
++				if (list_empty(&iter->tr->mod_trace))
++					iter->hash->flags &= ~FTRACE_HASH_FL_MOD;
++				else
++					iter->hash->flags |= FTRACE_HASH_FL_MOD;
++			}
+ 		} else
+ 			orig_hash = &iter->ops->func_hash->notrace_hash;
+ 
+diff --git a/kernel/trace/kprobe_event_gen_test.c b/kernel/trace/kprobe_event_gen_test.c
+index 18b0f1cbb947f..80e04a1e19772 100644
+--- a/kernel/trace/kprobe_event_gen_test.c
++++ b/kernel/trace/kprobe_event_gen_test.c
+@@ -35,6 +35,45 @@
+ static struct trace_event_file *gen_kprobe_test;
+ static struct trace_event_file *gen_kretprobe_test;
+ 
++#define KPROBE_GEN_TEST_FUNC	"do_sys_open"
++
++/* X86 */
++#if defined(CONFIG_X86_64) || defined(CONFIG_X86_32)
++#define KPROBE_GEN_TEST_ARG0	"dfd=%ax"
++#define KPROBE_GEN_TEST_ARG1	"filename=%dx"
++#define KPROBE_GEN_TEST_ARG2	"flags=%cx"
++#define KPROBE_GEN_TEST_ARG3	"mode=+4($stack)"
++
++/* ARM64 */
++#elif defined(CONFIG_ARM64)
++#define KPROBE_GEN_TEST_ARG0	"dfd=%x0"
++#define KPROBE_GEN_TEST_ARG1	"filename=%x1"
++#define KPROBE_GEN_TEST_ARG2	"flags=%x2"
++#define KPROBE_GEN_TEST_ARG3	"mode=%x3"
++
++/* ARM */
++#elif defined(CONFIG_ARM)
++#define KPROBE_GEN_TEST_ARG0	"dfd=%r0"
++#define KPROBE_GEN_TEST_ARG1	"filename=%r1"
++#define KPROBE_GEN_TEST_ARG2	"flags=%r2"
++#define KPROBE_GEN_TEST_ARG3	"mode=%r3"
++
++/* RISCV */
++#elif defined(CONFIG_RISCV)
++#define KPROBE_GEN_TEST_ARG0	"dfd=%a0"
++#define KPROBE_GEN_TEST_ARG1	"filename=%a1"
++#define KPROBE_GEN_TEST_ARG2	"flags=%a2"
++#define KPROBE_GEN_TEST_ARG3	"mode=%a3"
++
++/* others */
++#else
++#define KPROBE_GEN_TEST_ARG0	NULL
++#define KPROBE_GEN_TEST_ARG1	NULL
++#define KPROBE_GEN_TEST_ARG2	NULL
++#define KPROBE_GEN_TEST_ARG3	NULL
++#endif
++
++
+ /*
+  * Test to make sure we can create a kprobe event, then add more
+  * fields.
+@@ -58,14 +97,14 @@ static int __init test_gen_kprobe_cmd(void)
+ 	 * fields.
+ 	 */
+ 	ret = kprobe_event_gen_cmd_start(&cmd, "gen_kprobe_test",
+-					 "do_sys_open",
+-					 "dfd=%ax", "filename=%dx");
++					 KPROBE_GEN_TEST_FUNC,
++					 KPROBE_GEN_TEST_ARG0, KPROBE_GEN_TEST_ARG1);
+ 	if (ret)
+ 		goto free;
+ 
+ 	/* Use kprobe_event_add_fields to add the rest of the fields */
+ 
+-	ret = kprobe_event_add_fields(&cmd, "flags=%cx", "mode=+4($stack)");
++	ret = kprobe_event_add_fields(&cmd, KPROBE_GEN_TEST_ARG2, KPROBE_GEN_TEST_ARG3);
+ 	if (ret)
+ 		goto free;
+ 
+@@ -128,7 +167,7 @@ static int __init test_gen_kretprobe_cmd(void)
+ 	 * Define the kretprobe event.
+ 	 */
+ 	ret = kretprobe_event_gen_cmd_start(&cmd, "gen_kretprobe_test",
+-					    "do_sys_open",
++					    KPROBE_GEN_TEST_FUNC,
+ 					    "$retval");
+ 	if (ret)
+ 		goto free;
+@@ -206,7 +245,7 @@ static void __exit kprobe_event_gen_test_exit(void)
+ 	WARN_ON(kprobe_event_delete("gen_kprobe_test"));
+ 
+ 	/* Disable the event or you can't remove it */
+-	WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr,
++	WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
+ 					  "kprobes",
+ 					  "gen_kretprobe_test", false));
+ 
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index d59b6a328b7fe..c3f354cfc5ba1 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -413,6 +413,7 @@ struct rb_irq_work {
+ 	struct irq_work			work;
+ 	wait_queue_head_t		waiters;
+ 	wait_queue_head_t		full_waiters;
++	long				wait_index;
+ 	bool				waiters_pending;
+ 	bool				full_waiters_pending;
+ 	bool				wakeup_full;
+@@ -917,12 +918,44 @@ static void rb_wake_up_waiters(struct irq_work *work)
+ 	struct rb_irq_work *rbwork = container_of(work, struct rb_irq_work, work);
+ 
+ 	wake_up_all(&rbwork->waiters);
+-	if (rbwork->wakeup_full) {
++	if (rbwork->full_waiters_pending || rbwork->wakeup_full) {
+ 		rbwork->wakeup_full = false;
++		rbwork->full_waiters_pending = false;
+ 		wake_up_all(&rbwork->full_waiters);
+ 	}
+ }
+ 
++/**
++ * ring_buffer_wake_waiters - wake up any waiters on this ring buffer
++ * @buffer: The ring buffer to wake waiters on
++ *
++ * In the case of a file that represents a ring buffer is closing,
++ * it is prudent to wake up any waiters that are on this.
++ */
++void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu)
++{
++	struct ring_buffer_per_cpu *cpu_buffer;
++	struct rb_irq_work *rbwork;
++
++	if (cpu == RING_BUFFER_ALL_CPUS) {
++
++		/* Wake up individual ones too. One level recursion */
++		for_each_buffer_cpu(buffer, cpu)
++			ring_buffer_wake_waiters(buffer, cpu);
++
++		rbwork = &buffer->irq_work;
++	} else {
++		cpu_buffer = buffer->buffers[cpu];
++		rbwork = &cpu_buffer->irq_work;
++	}
++
++	rbwork->wait_index++;
++	/* make sure the waiters see the new index */
++	smp_wmb();
++
++	rb_wake_up_waiters(&rbwork->work);
++}
++
+ /**
+  * ring_buffer_wait - wait for input to the ring buffer
+  * @buffer: buffer to wait on
+@@ -938,6 +971,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ 	struct ring_buffer_per_cpu *cpu_buffer;
+ 	DEFINE_WAIT(wait);
+ 	struct rb_irq_work *work;
++	long wait_index;
+ 	int ret = 0;
+ 
+ 	/*
+@@ -956,6 +990,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ 		work = &cpu_buffer->irq_work;
+ 	}
+ 
++	wait_index = READ_ONCE(work->wait_index);
+ 
+ 	while (true) {
+ 		if (full)
+@@ -1011,7 +1046,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ 			nr_pages = cpu_buffer->nr_pages;
+ 			dirty = ring_buffer_nr_dirty_pages(buffer, cpu);
+ 			if (!cpu_buffer->shortest_full ||
+-			    cpu_buffer->shortest_full < full)
++			    cpu_buffer->shortest_full > full)
+ 				cpu_buffer->shortest_full = full;
+ 			raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
+ 			if (!pagebusy &&
+@@ -1020,6 +1055,11 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
+ 		}
+ 
+ 		schedule();
++
++		/* Make sure to see the new wait index */
++		smp_rmb();
++		if (wait_index != work->wait_index)
++			break;
+ 	}
+ 
+ 	if (full)
+@@ -2608,6 +2648,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
+ 		/* Mark the rest of the page with padding */
+ 		rb_event_set_padding(event);
+ 
++		/* Make sure the padding is visible before the write update */
++		smp_wmb();
++
+ 		/* Set the write back to the previous setting */
+ 		local_sub(length, &tail_page->write);
+ 		return;
+@@ -2619,6 +2662,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
+ 	/* time delta must be non zero */
+ 	event->time_delta = 1;
+ 
++	/* Make sure the padding is visible before the tail_page->write update */
++	smp_wmb();
++
+ 	/* Set write to end of buffer */
+ 	length = (tail + length) - BUF_PAGE_SIZE;
+ 	local_sub(length, &tail_page->write);
+@@ -4587,6 +4633,33 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
+ 	arch_spin_unlock(&cpu_buffer->lock);
+ 	local_irq_restore(flags);
+ 
++	/*
++	 * The writer has preempt disable, wait for it. But not forever
++	 * Although, 1 second is pretty much "forever"
++	 */
++#define USECS_WAIT	1000000
++        for (nr_loops = 0; nr_loops < USECS_WAIT; nr_loops++) {
++		/* If the write is past the end of page, a writer is still updating it */
++		if (likely(!reader || rb_page_write(reader) <= BUF_PAGE_SIZE))
++			break;
++
++		udelay(1);
++
++		/* Get the latest version of the reader write value */
++		smp_rmb();
++	}
++
++	/* The writer is not moving forward? Something is wrong */
++	if (RB_WARN_ON(cpu_buffer, nr_loops == USECS_WAIT))
++		reader = NULL;
++
++	/*
++	 * Make sure we see any padding after the write update
++	 * (see rb_reset_tail())
++	 */
++	smp_rmb();
++
++
+ 	return reader;
+ }
+ 
+@@ -5616,7 +5689,15 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
+ 		unsigned int pos = 0;
+ 		unsigned int size;
+ 
+-		if (full)
++		/*
++		 * If a full page is expected, this can still be returned
++		 * if there's been a previous partial read and the
++		 * rest of the page can be read and the commit page is off
++		 * the reader page.
++		 */
++		if (full &&
++		    (!read || (len < (commit - read)) ||
++		     cpu_buffer->reader_page == cpu_buffer->commit_page))
+ 			goto out_unlock;
+ 
+ 		if (len > (commit - read))
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index d3005279165d9..cc65887b31bd9 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1193,12 +1193,14 @@ void *tracing_cond_snapshot_data(struct trace_array *tr)
+ {
+ 	void *cond_data = NULL;
+ 
++	local_irq_disable();
+ 	arch_spin_lock(&tr->max_lock);
+ 
+ 	if (tr->cond_snapshot)
+ 		cond_data = tr->cond_snapshot->cond_data;
+ 
+ 	arch_spin_unlock(&tr->max_lock);
++	local_irq_enable();
+ 
+ 	return cond_data;
+ }
+@@ -1334,9 +1336,11 @@ int tracing_snapshot_cond_enable(struct trace_array *tr, void *cond_data,
+ 		goto fail_unlock;
+ 	}
+ 
++	local_irq_disable();
+ 	arch_spin_lock(&tr->max_lock);
+ 	tr->cond_snapshot = cond_snapshot;
+ 	arch_spin_unlock(&tr->max_lock);
++	local_irq_enable();
+ 
+ 	mutex_unlock(&trace_types_lock);
+ 
+@@ -1363,6 +1367,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr)
+ {
+ 	int ret = 0;
+ 
++	local_irq_disable();
+ 	arch_spin_lock(&tr->max_lock);
+ 
+ 	if (!tr->cond_snapshot)
+@@ -1373,6 +1378,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr)
+ 	}
+ 
+ 	arch_spin_unlock(&tr->max_lock);
++	local_irq_enable();
+ 
+ 	return ret;
+ }
+@@ -2200,6 +2206,11 @@ static size_t tgid_map_max;
+ 
+ #define SAVED_CMDLINES_DEFAULT 128
+ #define NO_CMDLINE_MAP UINT_MAX
++/*
++ * Preemption must be disabled before acquiring trace_cmdline_lock.
++ * The various trace_arrays' max_lock must be acquired in a context
++ * where interrupt is disabled.
++ */
+ static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+ struct saved_cmdlines_buffer {
+ 	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
+@@ -2412,7 +2423,11 @@ static int trace_save_cmdline(struct task_struct *tsk)
+ 	 * the lock, but we also don't want to spin
+ 	 * nor do we want to disable interrupts,
+ 	 * so if we miss here, then better luck next time.
++	 *
++	 * This is called within the scheduler and wake up, so interrupts
++	 * had better been disabled and run queue lock been held.
+ 	 */
++	lockdep_assert_preemption_disabled();
+ 	if (!arch_spin_trylock(&trace_cmdline_lock))
+ 		return 0;
+ 
+@@ -5890,9 +5905,11 @@ tracing_saved_cmdlines_size_read(struct file *filp, char __user *ubuf,
+ 	char buf[64];
+ 	int r;
+ 
++	preempt_disable();
+ 	arch_spin_lock(&trace_cmdline_lock);
+ 	r = scnprintf(buf, sizeof(buf), "%u\n", savedcmd->cmdline_num);
+ 	arch_spin_unlock(&trace_cmdline_lock);
++	preempt_enable();
+ 
+ 	return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+ }
+@@ -5917,10 +5934,12 @@ static int tracing_resize_saved_cmdlines(unsigned int val)
+ 		return -ENOMEM;
+ 	}
+ 
++	preempt_disable();
+ 	arch_spin_lock(&trace_cmdline_lock);
+ 	savedcmd_temp = savedcmd;
+ 	savedcmd = s;
+ 	arch_spin_unlock(&trace_cmdline_lock);
++	preempt_enable();
+ 	free_saved_cmdlines_buffer(savedcmd_temp);
+ 
+ 	return 0;
+@@ -6373,10 +6392,12 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf)
+ 
+ #ifdef CONFIG_TRACER_SNAPSHOT
+ 	if (t->use_max_tr) {
++		local_irq_disable();
+ 		arch_spin_lock(&tr->max_lock);
+ 		if (tr->cond_snapshot)
+ 			ret = -EBUSY;
+ 		arch_spin_unlock(&tr->max_lock);
++		local_irq_enable();
+ 		if (ret)
+ 			goto out;
+ 	}
+@@ -6407,12 +6428,12 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf)
+ 	if (tr->current_trace->reset)
+ 		tr->current_trace->reset(tr);
+ 
++#ifdef CONFIG_TRACER_MAX_TRACE
++	had_max_tr = tr->current_trace->use_max_tr;
++
+ 	/* Current trace needs to be nop_trace before synchronize_rcu */
+ 	tr->current_trace = &nop_trace;
+ 
+-#ifdef CONFIG_TRACER_MAX_TRACE
+-	had_max_tr = tr->allocated_snapshot;
+-
+ 	if (had_max_tr && !t->use_max_tr) {
+ 		/*
+ 		 * We need to make sure that the update_max_tr sees that
+@@ -6425,11 +6446,13 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf)
+ 		free_snapshot(tr);
+ 	}
+ 
+-	if (t->use_max_tr && !had_max_tr) {
++	if (t->use_max_tr && !tr->allocated_snapshot) {
+ 		ret = tracing_alloc_snapshot_instance(tr);
+ 		if (ret < 0)
+ 			goto out;
+ 	}
++#else
++	tr->current_trace = &nop_trace;
+ #endif
+ 
+ 	if (t->init) {
+@@ -7436,10 +7459,12 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
+ 		goto out;
+ 	}
+ 
++	local_irq_disable();
+ 	arch_spin_lock(&tr->max_lock);
+ 	if (tr->cond_snapshot)
+ 		ret = -EBUSY;
+ 	arch_spin_unlock(&tr->max_lock);
++	local_irq_enable();
+ 	if (ret)
+ 		goto out;
+ 
+@@ -8137,6 +8162,12 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
+ 
+ 	__trace_array_put(iter->tr);
+ 
++	iter->wait_index++;
++	/* Make sure the waiters see the new wait_index */
++	smp_wmb();
++
++	ring_buffer_wake_waiters(iter->array_buffer->buffer, iter->cpu_file);
++
+ 	if (info->spare)
+ 		ring_buffer_free_read_page(iter->array_buffer->buffer,
+ 					   info->spare_cpu, info->spare);
+@@ -8290,6 +8321,8 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
+ 
+ 	/* did we read anything? */
+ 	if (!spd.nr_pages) {
++		long wait_index;
++
+ 		if (ret)
+ 			goto out;
+ 
+@@ -8297,10 +8330,21 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
+ 		if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK))
+ 			goto out;
+ 
++		wait_index = READ_ONCE(iter->wait_index);
++
+ 		ret = wait_on_pipe(iter, iter->tr->buffer_percent);
+ 		if (ret)
+ 			goto out;
+ 
++		/* No need to wait after waking up when tracing is off */
++		if (!tracer_tracing_is_on(iter->tr))
++			goto out;
++
++		/* Make sure we see the new wait_index */
++		smp_rmb();
++		if (wait_index != iter->wait_index)
++			goto out;
++
+ 		goto again;
+ 	}
+ 
+@@ -8311,12 +8355,34 @@ out:
+ 	return ret;
+ }
+ 
++/* An ioctl call with cmd 0 to the ring buffer file will wake up all waiters */
++static long tracing_buffers_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++{
++	struct ftrace_buffer_info *info = file->private_data;
++	struct trace_iterator *iter = &info->iter;
++
++	if (cmd)
++		return -ENOIOCTLCMD;
++
++	mutex_lock(&trace_types_lock);
++
++	iter->wait_index++;
++	/* Make sure the waiters see the new wait_index */
++	smp_wmb();
++
++	ring_buffer_wake_waiters(iter->array_buffer->buffer, iter->cpu_file);
++
++	mutex_unlock(&trace_types_lock);
++	return 0;
++}
++
+ static const struct file_operations tracing_buffers_fops = {
+ 	.open		= tracing_buffers_open,
+ 	.read		= tracing_buffers_read,
+ 	.poll		= tracing_buffers_poll,
+ 	.release	= tracing_buffers_release,
+ 	.splice_read	= tracing_buffers_splice_read,
++	.unlocked_ioctl = tracing_buffers_ioctl,
+ 	.llseek		= no_llseek,
+ };
+ 
+@@ -9005,6 +9071,8 @@ rb_simple_write(struct file *filp, const char __user *ubuf,
+ 			tracer_tracing_off(tr);
+ 			if (tr->current_trace->stop)
+ 				tr->current_trace->stop(tr);
++			/* Wake up any waiters */
++			ring_buffer_wake_waiters(buffer, RING_BUFFER_ALL_CPUS);
+ 		}
+ 		mutex_unlock(&trace_types_lock);
+ 	}
+diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
+index 1783e34789124..860f5fb9514d7 100644
+--- a/kernel/trace/trace_eprobe.c
++++ b/kernel/trace/trace_eprobe.c
+@@ -16,6 +16,7 @@
+ #include "trace_dynevent.h"
+ #include "trace_probe.h"
+ #include "trace_probe_tmpl.h"
++#include "trace_probe_kernel.h"
+ 
+ #define EPROBE_EVENT_SYSTEM "eprobes"
+ 
+@@ -453,29 +454,14 @@ NOKPROBE_SYMBOL(process_fetch_insn)
+ static nokprobe_inline int
+ fetch_store_strlen_user(unsigned long addr)
+ {
+-	const void __user *uaddr =  (__force const void __user *)addr;
+-
+-	return strnlen_user_nofault(uaddr, MAX_STRING_SIZE);
++	return kern_fetch_store_strlen_user(addr);
+ }
+ 
+ /* Return the length of string -- including null terminal byte */
+ static nokprobe_inline int
+ fetch_store_strlen(unsigned long addr)
+ {
+-	int ret, len = 0;
+-	u8 c;
+-
+-#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+-	if (addr < TASK_SIZE)
+-		return fetch_store_strlen_user(addr);
+-#endif
+-
+-	do {
+-		ret = copy_from_kernel_nofault(&c, (u8 *)addr + len, 1);
+-		len++;
+-	} while (c && ret == 0 && len < MAX_STRING_SIZE);
+-
+-	return (ret < 0) ? ret : len;
++	return kern_fetch_store_strlen(addr);
+ }
+ 
+ /*
+@@ -485,21 +471,7 @@ fetch_store_strlen(unsigned long addr)
+ static nokprobe_inline int
+ fetch_store_string_user(unsigned long addr, void *dest, void *base)
+ {
+-	const void __user *uaddr =  (__force const void __user *)addr;
+-	int maxlen = get_loc_len(*(u32 *)dest);
+-	void *__dest;
+-	long ret;
+-
+-	if (unlikely(!maxlen))
+-		return -ENOMEM;
+-
+-	__dest = get_loc_data(dest, base);
+-
+-	ret = strncpy_from_user_nofault(__dest, uaddr, maxlen);
+-	if (ret >= 0)
+-		*(u32 *)dest = make_data_loc(ret, __dest - base);
+-
+-	return ret;
++	return kern_fetch_store_string_user(addr, dest, base);
+ }
+ 
+ /*
+@@ -509,29 +481,7 @@ fetch_store_string_user(unsigned long addr, void *dest, void *base)
+ static nokprobe_inline int
+ fetch_store_string(unsigned long addr, void *dest, void *base)
+ {
+-	int maxlen = get_loc_len(*(u32 *)dest);
+-	void *__dest;
+-	long ret;
+-
+-#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+-	if ((unsigned long)addr < TASK_SIZE)
+-		return fetch_store_string_user(addr, dest, base);
+-#endif
+-
+-	if (unlikely(!maxlen))
+-		return -ENOMEM;
+-
+-	__dest = get_loc_data(dest, base);
+-
+-	/*
+-	 * Try to get string again, since the string can be changed while
+-	 * probing.
+-	 */
+-	ret = strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen);
+-	if (ret >= 0)
+-		*(u32 *)dest = make_data_loc(ret, __dest - base);
+-
+-	return ret;
++	return kern_fetch_store_string(addr, dest, base);
+ }
+ 
+ static nokprobe_inline int
+@@ -968,8 +918,7 @@ static int __trace_eprobe_create(int argc, const char *argv[])
+ 	}
+ 
+ 	if (!event) {
+-		strscpy(buf1, argv[1], MAX_EVENT_NAME_LEN);
+-		sanitize_event_name(buf1);
++		strscpy(buf1, sys_event, MAX_EVENT_NAME_LEN);
+ 		event = buf1;
+ 	}
+ 
+diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
+index 5e8c07aef071b..e310052dc83ce 100644
+--- a/kernel/trace/trace_events_synth.c
++++ b/kernel/trace/trace_events_synth.c
+@@ -17,6 +17,8 @@
+ /* for gfp flag names */
+ #include <linux/trace_events.h>
+ #include <trace/events/mmflags.h>
++#include "trace_probe.h"
++#include "trace_probe_kernel.h"
+ 
+ #include "trace_synth.h"
+ 
+@@ -409,6 +411,7 @@ static unsigned int trace_string(struct synth_trace_event *entry,
+ {
+ 	unsigned int len = 0;
+ 	char *str_field;
++	int ret;
+ 
+ 	if (is_dynamic) {
+ 		u32 data_offset;
+@@ -417,19 +420,27 @@ static unsigned int trace_string(struct synth_trace_event *entry,
+ 		data_offset += event->n_u64 * sizeof(u64);
+ 		data_offset += data_size;
+ 
+-		str_field = (char *)entry + data_offset;
+-
+-		len = strlen(str_val) + 1;
+-		strscpy(str_field, str_val, len);
++		len = kern_fetch_store_strlen((unsigned long)str_val);
+ 
+ 		data_offset |= len << 16;
+ 		*(u32 *)&entry->fields[*n_u64] = data_offset;
+ 
++		ret = kern_fetch_store_string((unsigned long)str_val, &entry->fields[*n_u64], entry);
++
+ 		(*n_u64)++;
+ 	} else {
+ 		str_field = (char *)&entry->fields[*n_u64];
+ 
+-		strscpy(str_field, str_val, STR_VAR_LEN_MAX);
++#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
++		if ((unsigned long)str_val < TASK_SIZE)
++			ret = strncpy_from_user_nofault(str_field, str_val, STR_VAR_LEN_MAX);
++		else
++#endif
++			ret = strncpy_from_kernel_nofault(str_field, str_val, STR_VAR_LEN_MAX);
++
++		if (ret < 0)
++			strcpy(str_field, FAULT_STRING);
++
+ 		(*n_u64) += STR_VAR_LEN_MAX / sizeof(u64);
+ 	}
+ 
+@@ -462,7 +473,7 @@ static notrace void trace_event_raw_event_synth(void *__data,
+ 		val_idx = var_ref_idx[field_pos];
+ 		str_val = (char *)(long)var_ref_vals[val_idx];
+ 
+-		len = strlen(str_val) + 1;
++		len = kern_fetch_store_strlen((unsigned long)str_val);
+ 
+ 		fields_size += len;
+ 	}
+diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
+index 23f7f0ec4f4cf..5a75b039e5860 100644
+--- a/kernel/trace/trace_kprobe.c
++++ b/kernel/trace/trace_kprobe.c
+@@ -20,6 +20,7 @@
+ #include "trace_kprobe_selftest.h"
+ #include "trace_probe.h"
+ #include "trace_probe_tmpl.h"
++#include "trace_probe_kernel.h"
+ 
+ #define KPROBE_EVENT_SYSTEM "kprobes"
+ #define KRETPROBE_MAXACTIVE_MAX 4096
+@@ -1223,29 +1224,14 @@ static const struct file_operations kprobe_profile_ops = {
+ static nokprobe_inline int
+ fetch_store_strlen_user(unsigned long addr)
+ {
+-	const void __user *uaddr =  (__force const void __user *)addr;
+-
+-	return strnlen_user_nofault(uaddr, MAX_STRING_SIZE);
++	return kern_fetch_store_strlen_user(addr);
+ }
+ 
+ /* Return the length of string -- including null terminal byte */
+ static nokprobe_inline int
+ fetch_store_strlen(unsigned long addr)
+ {
+-	int ret, len = 0;
+-	u8 c;
+-
+-#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+-	if (addr < TASK_SIZE)
+-		return fetch_store_strlen_user(addr);
+-#endif
+-
+-	do {
+-		ret = copy_from_kernel_nofault(&c, (u8 *)addr + len, 1);
+-		len++;
+-	} while (c && ret == 0 && len < MAX_STRING_SIZE);
+-
+-	return (ret < 0) ? ret : len;
++	return kern_fetch_store_strlen(addr);
+ }
+ 
+ /*
+@@ -1255,21 +1241,7 @@ fetch_store_strlen(unsigned long addr)
+ static nokprobe_inline int
+ fetch_store_string_user(unsigned long addr, void *dest, void *base)
+ {
+-	const void __user *uaddr =  (__force const void __user *)addr;
+-	int maxlen = get_loc_len(*(u32 *)dest);
+-	void *__dest;
+-	long ret;
+-
+-	if (unlikely(!maxlen))
+-		return -ENOMEM;
+-
+-	__dest = get_loc_data(dest, base);
+-
+-	ret = strncpy_from_user_nofault(__dest, uaddr, maxlen);
+-	if (ret >= 0)
+-		*(u32 *)dest = make_data_loc(ret, __dest - base);
+-
+-	return ret;
++	return kern_fetch_store_string_user(addr, dest, base);
+ }
+ 
+ /*
+@@ -1279,29 +1251,7 @@ fetch_store_string_user(unsigned long addr, void *dest, void *base)
+ static nokprobe_inline int
+ fetch_store_string(unsigned long addr, void *dest, void *base)
+ {
+-	int maxlen = get_loc_len(*(u32 *)dest);
+-	void *__dest;
+-	long ret;
+-
+-#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+-	if ((unsigned long)addr < TASK_SIZE)
+-		return fetch_store_string_user(addr, dest, base);
+-#endif
+-
+-	if (unlikely(!maxlen))
+-		return -ENOMEM;
+-
+-	__dest = get_loc_data(dest, base);
+-
+-	/*
+-	 * Try to get string again, since the string can be changed while
+-	 * probing.
+-	 */
+-	ret = strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen);
+-	if (ret >= 0)
+-		*(u32 *)dest = make_data_loc(ret, __dest - base);
+-
+-	return ret;
++	return kern_fetch_store_string(addr, dest, base);
+ }
+ 
+ static nokprobe_inline int
+diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c
+index 313439920a8ce..78d536d3ff3db 100644
+--- a/kernel/trace/trace_osnoise.c
++++ b/kernel/trace/trace_osnoise.c
+@@ -1786,8 +1786,9 @@ static int start_per_cpu_kthreads(void)
+ 	for_each_cpu(cpu, current_mask) {
+ 		retval = start_kthread(cpu);
+ 		if (retval) {
++			cpus_read_unlock();
+ 			stop_per_cpu_kthreads();
+-			break;
++			return retval;
+ 		}
+ 	}
+ 
+diff --git a/kernel/trace/trace_probe_kernel.h b/kernel/trace/trace_probe_kernel.h
+new file mode 100644
+index 0000000000000..77dbd9ff97826
+--- /dev/null
++++ b/kernel/trace/trace_probe_kernel.h
+@@ -0,0 +1,115 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef __TRACE_PROBE_KERNEL_H_
++#define __TRACE_PROBE_KERNEL_H_
++
++#define FAULT_STRING "(fault)"
++
++/*
++ * This depends on trace_probe.h, but can not include it due to
++ * the way trace_probe_tmpl.h is used by trace_kprobe.c and trace_eprobe.c.
++ * Which means that any other user must include trace_probe.h before including
++ * this file.
++ */
++/* Return the length of string -- including null terminal byte */
++static nokprobe_inline int
++kern_fetch_store_strlen_user(unsigned long addr)
++{
++	const void __user *uaddr =  (__force const void __user *)addr;
++	int ret;
++
++	ret = strnlen_user_nofault(uaddr, MAX_STRING_SIZE);
++	/*
++	 * strnlen_user_nofault returns zero on fault, insert the
++	 * FAULT_STRING when that occurs.
++	 */
++	if (ret <= 0)
++		return strlen(FAULT_STRING) + 1;
++	return ret;
++}
++
++/* Return the length of string -- including null terminal byte */
++static nokprobe_inline int
++kern_fetch_store_strlen(unsigned long addr)
++{
++	int ret, len = 0;
++	u8 c;
++
++#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
++	if (addr < TASK_SIZE)
++		return kern_fetch_store_strlen_user(addr);
++#endif
++
++	do {
++		ret = copy_from_kernel_nofault(&c, (u8 *)addr + len, 1);
++		len++;
++	} while (c && ret == 0 && len < MAX_STRING_SIZE);
++
++	/* For faults, return enough to hold the FAULT_STRING */
++	return (ret < 0) ? strlen(FAULT_STRING) + 1 : len;
++}
++
++static nokprobe_inline void set_data_loc(int ret, void *dest, void *__dest, void *base, int len)
++{
++	if (ret >= 0) {
++		*(u32 *)dest = make_data_loc(ret, __dest - base);
++	} else {
++		strscpy(__dest, FAULT_STRING, len);
++		ret = strlen(__dest) + 1;
++	}
++}
++
++/*
++ * Fetch a null-terminated string from user. Caller MUST set *(u32 *)buf
++ * with max length and relative data location.
++ */
++static nokprobe_inline int
++kern_fetch_store_string_user(unsigned long addr, void *dest, void *base)
++{
++	const void __user *uaddr =  (__force const void __user *)addr;
++	int maxlen = get_loc_len(*(u32 *)dest);
++	void *__dest;
++	long ret;
++
++	if (unlikely(!maxlen))
++		return -ENOMEM;
++
++	__dest = get_loc_data(dest, base);
++
++	ret = strncpy_from_user_nofault(__dest, uaddr, maxlen);
++	set_data_loc(ret, dest, __dest, base, maxlen);
++
++	return ret;
++}
++
++/*
++ * Fetch a null-terminated string. Caller MUST set *(u32 *)buf with max
++ * length and relative data location.
++ */
++static nokprobe_inline int
++kern_fetch_store_string(unsigned long addr, void *dest, void *base)
++{
++	int maxlen = get_loc_len(*(u32 *)dest);
++	void *__dest;
++	long ret;
++
++#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
++	if ((unsigned long)addr < TASK_SIZE)
++		return kern_fetch_store_string_user(addr, dest, base);
++#endif
++
++	if (unlikely(!maxlen))
++		return -ENOMEM;
++
++	__dest = get_loc_data(dest, base);
++
++	/*
++	 * Try to get string again, since the string can be changed while
++	 * probing.
++	 */
++	ret = strncpy_from_kernel_nofault(__dest, (void *)addr, maxlen);
++	set_data_loc(ret, dest, __dest, base, maxlen);
++
++	return ret;
++}
++
++#endif /* __TRACE_PROBE_KERNEL_H_ */
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index d3e5f36bb01e0..cb131fad117cc 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -231,6 +231,11 @@ config DEBUG_INFO
+ 	  in the "Debug information" choice below, indicating that debug
+ 	  information will be generated for build targets.
+ 
++# Clang is known to generate .{s,u}leb128 with symbol deltas with DWARF5, which
++# some targets may not support: https://sourceware.org/bugzilla/show_bug.cgi?id=27215
++config AS_HAS_NON_CONST_LEB128
++	def_bool $(as-instr,.uleb128 .Lexpr_end4 - .Lexpr_start3\n.Lexpr_start3:\n.Lexpr_end4:)
++
+ choice
+ 	prompt "Debug information"
+ 	depends on DEBUG_KERNEL
+@@ -253,6 +258,7 @@ config DEBUG_INFO_NONE
+ config DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
+ 	bool "Rely on the toolchain's implicit default DWARF version"
+ 	select DEBUG_INFO
++	depends on !CC_IS_CLANG || AS_IS_LLVM || CLANG_VERSION < 140000 || (AS_IS_GNU && AS_VERSION >= 23502 && AS_HAS_NON_CONST_LEB128)
+ 	help
+ 	  The implicit default version of DWARF debug info produced by a
+ 	  toolchain changes over time.
+@@ -264,7 +270,7 @@ config DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
+ config DEBUG_INFO_DWARF4
+ 	bool "Generate DWARF Version 4 debuginfo"
+ 	select DEBUG_INFO
+-	depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502)))
++	depends on !CC_IS_CLANG || AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502)
+ 	help
+ 	  Generate DWARF v4 debug info. This requires gcc 4.5+, binutils 2.35.2
+ 	  if using clang without clang's integrated assembler, and gdb 7.0+.
+@@ -276,7 +282,7 @@ config DEBUG_INFO_DWARF4
+ config DEBUG_INFO_DWARF5
+ 	bool "Generate DWARF Version 5 debuginfo"
+ 	select DEBUG_INFO
+-	depends on !CC_IS_CLANG || (CC_IS_CLANG && (AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502)))
++	depends on !CC_IS_CLANG || AS_IS_LLVM || (AS_IS_GNU && AS_VERSION >= 23502 && AS_HAS_NON_CONST_LEB128)
+ 	help
+ 	  Generate DWARF v5 debug info. Requires binutils 2.35.2, gcc 5.0+ (gcc
+ 	  5.0+ accepts the -gdwarf-5 flag but only had partial support for some
+diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
+index dd7f56af9aed3..c9b3d9e5d470f 100644
+--- a/lib/dynamic_debug.c
++++ b/lib/dynamic_debug.c
+@@ -211,10 +211,11 @@ static int ddebug_change(const struct ddebug_query *query,
+ 				continue;
+ #ifdef CONFIG_JUMP_LABEL
+ 			if (dp->flags & _DPRINTK_FLAGS_PRINT) {
+-				if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT))
++				if (!(newflags & _DPRINTK_FLAGS_PRINT))
+ 					static_branch_disable(&dp->key.dd_key_true);
+-			} else if (modifiers->flags & _DPRINTK_FLAGS_PRINT)
++			} else if (newflags & _DPRINTK_FLAGS_PRINT) {
+ 				static_branch_enable(&dp->key.dd_key_true);
++			}
+ #endif
+ 			dp->flags = newflags;
+ 			v4pr_info("changed %s:%d [%s]%s =%s\n",
+@@ -383,10 +384,6 @@ static int ddebug_parse_query(char *words[], int nwords,
+ 		return -EINVAL;
+ 	}
+ 
+-	if (modname)
+-		/* support $modname.dyndbg=<multiple queries> */
+-		query->module = modname;
+-
+ 	for (i = 0; i < nwords; i += 2) {
+ 		char *keyword = words[i];
+ 		char *arg = words[i+1];
+@@ -427,6 +424,13 @@ static int ddebug_parse_query(char *words[], int nwords,
+ 		if (rc)
+ 			return rc;
+ 	}
++	if (!query->module && modname)
++		/*
++		 * support $modname.dyndbg=<multiple queries>, when
++		 * not given in the query itself
++		 */
++		query->module = modname;
++
+ 	vpr_info_dq(query, "parsed");
+ 	return 0;
+ }
+@@ -553,35 +557,6 @@ static int ddebug_exec_queries(char *query, const char *modname)
+ 	return nfound;
+ }
+ 
+-/**
+- * dynamic_debug_exec_queries - select and change dynamic-debug prints
+- * @query: query-string described in admin-guide/dynamic-debug-howto
+- * @modname: string containing module name, usually &module.mod_name
+- *
+- * This uses the >/proc/dynamic_debug/control reader, allowing module
+- * authors to modify their dynamic-debug callsites. The modname is
+- * canonically struct module.mod_name, but can also be null or a
+- * module-wildcard, for example: "drm*".
+- */
+-int dynamic_debug_exec_queries(const char *query, const char *modname)
+-{
+-	int rc;
+-	char *qry; /* writable copy of query */
+-
+-	if (!query) {
+-		pr_err("non-null query/command string expected\n");
+-		return -EINVAL;
+-	}
+-	qry = kstrndup(query, PAGE_SIZE, GFP_KERNEL);
+-	if (!qry)
+-		return -ENOMEM;
+-
+-	rc = ddebug_exec_queries(qry, modname);
+-	kfree(qry);
+-	return rc;
+-}
+-EXPORT_SYMBOL_GPL(dynamic_debug_exec_queries);
+-
+ #define PREFIX_SIZE 64
+ 
+ static int remaining(int wrote)
+diff --git a/lib/once.c b/lib/once.c
+index 59149bf3bfb4a..351f66aad310a 100644
+--- a/lib/once.c
++++ b/lib/once.c
+@@ -66,3 +66,33 @@ void __do_once_done(bool *done, struct static_key_true *once_key,
+ 	once_disable_jump(once_key, mod);
+ }
+ EXPORT_SYMBOL(__do_once_done);
++
++static DEFINE_MUTEX(once_mutex);
++
++bool __do_once_slow_start(bool *done)
++	__acquires(once_mutex)
++{
++	mutex_lock(&once_mutex);
++	if (*done) {
++		mutex_unlock(&once_mutex);
++		/* Keep sparse happy by restoring an even lock count on
++		 * this mutex. In case we return here, we don't call into
++		 * __do_once_done but return early in the DO_ONCE_SLOW() macro.
++		 */
++		__acquire(once_mutex);
++		return false;
++	}
++
++	return true;
++}
++EXPORT_SYMBOL(__do_once_slow_start);
++
++void __do_once_slow_done(bool *done, struct static_key_true *once_key,
++			 struct module *mod)
++	__releases(once_mutex)
++{
++	*done = true;
++	mutex_unlock(&once_mutex);
++	once_disable_jump(once_key, mod);
++}
++EXPORT_SYMBOL(__do_once_slow_done);
+diff --git a/mm/damon/vaddr.c b/mm/damon/vaddr.c
+index 3c7b9d6dca95d..1d16c6c796386 100644
+--- a/mm/damon/vaddr.c
++++ b/mm/damon/vaddr.c
+@@ -304,6 +304,11 @@ static int damon_mkold_pmd_entry(pmd_t *pmd, unsigned long addr,
+ 
+ 	if (pmd_huge(*pmd)) {
+ 		ptl = pmd_lock(walk->mm, pmd);
++		if (!pmd_present(*pmd)) {
++			spin_unlock(ptl);
++			return 0;
++		}
++
+ 		if (pmd_huge(*pmd)) {
+ 			damon_pmdp_mkold(pmd, walk->mm, addr);
+ 			spin_unlock(ptl);
+@@ -431,6 +436,11 @@ static int damon_young_pmd_entry(pmd_t *pmd, unsigned long addr,
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ 	if (pmd_huge(*pmd)) {
+ 		ptl = pmd_lock(walk->mm, pmd);
++		if (!pmd_present(*pmd)) {
++			spin_unlock(ptl);
++			return 0;
++		}
++
+ 		if (!pmd_huge(*pmd)) {
+ 			spin_unlock(ptl);
+ 			goto regular_page;
+diff --git a/mm/gup.c b/mm/gup.c
+index 00926abb44263..251cb6a10bc0d 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -530,6 +530,18 @@ static struct page *follow_page_pte(struct vm_area_struct *vma,
+ 	if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) ==
+ 			 (FOLL_PIN | FOLL_GET)))
+ 		return ERR_PTR(-EINVAL);
++
++	/*
++	 * Considering PTE level hugetlb, like continuous-PTE hugetlb on
++	 * ARM64 architecture.
++	 */
++	if (is_vm_hugetlb_page(vma)) {
++		page = follow_huge_pmd_pte(vma, address, flags);
++		if (page)
++			return page;
++		return no_page_table(vma, flags);
++	}
++
+ retry:
+ 	if (unlikely(pmd_bad(*pmd)))
+ 		return no_page_table(vma, flags);
+@@ -662,7 +674,7 @@ static struct page *follow_pmd_mask(struct vm_area_struct *vma,
+ 	if (pmd_none(pmdval))
+ 		return no_page_table(vma, flags);
+ 	if (pmd_huge(pmdval) && is_vm_hugetlb_page(vma)) {
+-		page = follow_huge_pmd(mm, address, pmd, flags);
++		page = follow_huge_pmd_pte(vma, address, flags);
+ 		if (page)
+ 			return page;
+ 		return no_page_table(vma, flags);
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 0bdfc7e1c933f..513b523ba75b3 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -5059,6 +5059,7 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct
+ 		 * unmapped and its refcount is dropped, so just clear pte here.
+ 		 */
+ 		if (unlikely(!pte_present(pte))) {
++#ifdef CONFIG_PTE_MARKER_UFFD_WP
+ 			/*
+ 			 * If the pte was wr-protected by uffd-wp in any of the
+ 			 * swap forms, meanwhile the caller does not want to
+@@ -5070,6 +5071,7 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct
+ 				set_huge_pte_at(mm, address, ptep,
+ 						make_pte_marker(PTE_MARKER_UFFD_WP));
+ 			else
++#endif
+ 				huge_pte_clear(mm, address, ptep, sz);
+ 			spin_unlock(ptl);
+ 			continue;
+@@ -5098,11 +5100,13 @@ static void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct
+ 		tlb_remove_huge_tlb_entry(h, tlb, ptep, address);
+ 		if (huge_pte_dirty(pte))
+ 			set_page_dirty(page);
++#ifdef CONFIG_PTE_MARKER_UFFD_WP
+ 		/* Leave a uffd-wp pte marker if needed */
+ 		if (huge_pte_uffd_wp(pte) &&
+ 		    !(zap_flags & ZAP_FLAG_DROP_MARKER))
+ 			set_huge_pte_at(mm, address, ptep,
+ 					make_pte_marker(PTE_MARKER_UFFD_WP));
++#endif
+ 		hugetlb_count_sub(pages_per_huge_page(h), mm);
+ 		page_remove_rmap(page, vma, true);
+ 
+@@ -5478,7 +5482,6 @@ static inline vm_fault_t hugetlb_handle_userfault(struct vm_area_struct *vma,
+ 						  unsigned long addr,
+ 						  unsigned long reason)
+ {
+-	vm_fault_t ret;
+ 	u32 hash;
+ 	struct vm_fault vmf = {
+ 		.vma = vma,
+@@ -5496,18 +5499,14 @@ static inline vm_fault_t hugetlb_handle_userfault(struct vm_area_struct *vma,
+ 	};
+ 
+ 	/*
+-	 * hugetlb_fault_mutex and i_mmap_rwsem must be
+-	 * dropped before handling userfault.  Reacquire
+-	 * after handling fault to make calling code simpler.
++	 * vma_lock and hugetlb_fault_mutex must be dropped before handling
++	 * userfault. Also mmap_lock will be dropped during handling
++	 * userfault, any vma operation should be careful from here.
+ 	 */
+ 	hash = hugetlb_fault_mutex_hash(mapping, idx);
+ 	mutex_unlock(&hugetlb_fault_mutex_table[hash]);
+ 	i_mmap_unlock_read(mapping);
+-	ret = handle_userfault(&vmf, reason);
+-	i_mmap_lock_read(mapping);
+-	mutex_lock(&hugetlb_fault_mutex_table[hash]);
+-
+-	return ret;
++	return handle_userfault(&vmf, reason);
+ }
+ 
+ static vm_fault_t hugetlb_no_page(struct mm_struct *mm,
+@@ -5525,6 +5524,7 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm,
+ 	spinlock_t *ptl;
+ 	unsigned long haddr = address & huge_page_mask(h);
+ 	bool new_page, new_pagecache_page = false;
++	u32 hash = hugetlb_fault_mutex_hash(mapping, idx);
+ 
+ 	/*
+ 	 * Currently, we are forced to kill the process in the event the
+@@ -5535,7 +5535,7 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm,
+ 	if (is_vma_resv_set(vma, HPAGE_RESV_UNMAPPED)) {
+ 		pr_warn_ratelimited("PID %d killed due to inadequate hugepage pool\n",
+ 			   current->pid);
+-		return ret;
++		goto out;
+ 	}
+ 
+ 	/*
+@@ -5552,12 +5552,10 @@ retry:
+ 	page = find_lock_page(mapping, idx);
+ 	if (!page) {
+ 		/* Check for page in userfault range */
+-		if (userfaultfd_missing(vma)) {
+-			ret = hugetlb_handle_userfault(vma, mapping, idx,
++		if (userfaultfd_missing(vma))
++			return hugetlb_handle_userfault(vma, mapping, idx,
+ 						       flags, haddr, address,
+ 						       VM_UFFD_MISSING);
+-			goto out;
+-		}
+ 
+ 		page = alloc_huge_page(vma, haddr, 0);
+ 		if (IS_ERR(page)) {
+@@ -5617,10 +5615,9 @@ retry:
+ 		if (userfaultfd_minor(vma)) {
+ 			unlock_page(page);
+ 			put_page(page);
+-			ret = hugetlb_handle_userfault(vma, mapping, idx,
++			return hugetlb_handle_userfault(vma, mapping, idx,
+ 						       flags, haddr, address,
+ 						       VM_UFFD_MINOR);
+-			goto out;
+ 		}
+ 	}
+ 
+@@ -5678,6 +5675,8 @@ retry:
+ 
+ 	unlock_page(page);
+ out:
++	mutex_unlock(&hugetlb_fault_mutex_table[hash]);
++	i_mmap_unlock_read(mapping);
+ 	return ret;
+ 
+ backout:
+@@ -5776,11 +5775,13 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+ 
+ 	entry = huge_ptep_get(ptep);
+ 	/* PTE markers should be handled the same way as none pte */
+-	if (huge_pte_none_mostly(entry)) {
+-		ret = hugetlb_no_page(mm, vma, mapping, idx, address, ptep,
++	if (huge_pte_none_mostly(entry))
++		/*
++		 * hugetlb_no_page will drop vma lock and hugetlb fault
++		 * mutex internally, which make us return immediately.
++		 */
++		return hugetlb_no_page(mm, vma, mapping, idx, address, ptep,
+ 				      entry, flags);
+-		goto out_mutex;
+-	}
+ 
+ 	ret = 0;
+ 
+@@ -6946,12 +6947,13 @@ follow_huge_pd(struct vm_area_struct *vma,
+ }
+ 
+ struct page * __weak
+-follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+-		pmd_t *pmd, int flags)
++follow_huge_pmd_pte(struct vm_area_struct *vma, unsigned long address, int flags)
+ {
++	struct hstate *h = hstate_vma(vma);
++	struct mm_struct *mm = vma->vm_mm;
+ 	struct page *page = NULL;
+ 	spinlock_t *ptl;
+-	pte_t pte;
++	pte_t *ptep, pte;
+ 
+ 	/*
+ 	 * FOLL_PIN is not supported for follow_page(). Ordinary GUP goes via
+@@ -6961,17 +6963,15 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+ 		return NULL;
+ 
+ retry:
+-	ptl = pmd_lockptr(mm, pmd);
+-	spin_lock(ptl);
+-	/*
+-	 * make sure that the address range covered by this pmd is not
+-	 * unmapped from other threads.
+-	 */
+-	if (!pmd_huge(*pmd))
+-		goto out;
+-	pte = huge_ptep_get((pte_t *)pmd);
++	ptep = huge_pte_offset(mm, address, huge_page_size(h));
++	if (!ptep)
++		return NULL;
++
++	ptl = huge_pte_lock(h, mm, ptep);
++	pte = huge_ptep_get(ptep);
+ 	if (pte_present(pte)) {
+-		page = pmd_page(*pmd) + ((address & ~PMD_MASK) >> PAGE_SHIFT);
++		page = pte_page(pte) +
++			((address & ~huge_page_mask(h)) >> PAGE_SHIFT);
+ 		/*
+ 		 * try_grab_page() should always succeed here, because: a) we
+ 		 * hold the pmd (ptl) lock, and b) we've just checked that the
+@@ -6987,7 +6987,7 @@ retry:
+ 	} else {
+ 		if (is_hugetlb_entry_migration(pte)) {
+ 			spin_unlock(ptl);
+-			__migration_entry_wait_huge((pte_t *)pmd, ptl);
++			__migration_entry_wait_huge(ptep, ptl);
+ 			goto retry;
+ 		}
+ 		/*
+diff --git a/mm/memory.c b/mm/memory.c
+index a78814413ac03..de0dbe09b013f 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -1393,10 +1393,12 @@ zap_install_uffd_wp_if_needed(struct vm_area_struct *vma,
+ 			      unsigned long addr, pte_t *pte,
+ 			      struct zap_details *details, pte_t pteval)
+ {
++#ifdef CONFIG_PTE_MARKER_UFFD_WP
+ 	if (zap_drop_file_uffd_wp(details))
+ 		return;
+ 
+ 	pte_install_uffd_wp_if_needed(vma, addr, pte, pteval);
++#endif
+ }
+ 
+ static unsigned long zap_pte_range(struct mmu_gather *tlb,
+diff --git a/mm/mmap.c b/mm/mmap.c
+index 9d780f415be3c..36c08e2c78da7 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -1797,7 +1797,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
+ 	if (!arch_validate_flags(vma->vm_flags)) {
+ 		error = -EINVAL;
+ 		if (file)
+-			goto unmap_and_free_vma;
++			goto close_and_free_vma;
+ 		else
+ 			goto free_vma;
+ 	}
+@@ -1844,6 +1844,9 @@ out:
+ 
+ 	return addr;
+ 
++close_and_free_vma:
++	if (vma->vm_ops && vma->vm_ops->close)
++		vma->vm_ops->close(vma);
+ unmap_and_free_vma:
+ 	fput(vma->vm_file);
+ 	vma->vm_file = NULL;
+diff --git a/mm/mprotect.c b/mm/mprotect.c
+index bc6bddd156ca6..51e7dbd26b6ad 100644
+--- a/mm/mprotect.c
++++ b/mm/mprotect.c
+@@ -260,6 +260,7 @@ static unsigned long change_pte_range(struct mmu_gather *tlb,
+ 		} else {
+ 			/* It must be an none page, or what else?.. */
+ 			WARN_ON_ONCE(!pte_none(oldpte));
++#ifdef CONFIG_PTE_MARKER_UFFD_WP
+ 			if (unlikely(uffd_wp && !vma_is_anonymous(vma))) {
+ 				/*
+ 				 * For file-backed mem, we need to be able to
+@@ -271,6 +272,7 @@ static unsigned long change_pte_range(struct mmu_gather *tlb,
+ 					   make_pte_marker(PTE_MARKER_UFFD_WP));
+ 				pages++;
+ 			}
++#endif
+ 		}
+ 	} while (pte++, addr += PAGE_SIZE, addr != end);
+ 	arch_leave_lazy_mmu_mode();
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index 9873d2e679885..6ae5aa5c0927b 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -2400,6 +2400,10 @@ static int hci_suspend_notifier(struct notifier_block *nb, unsigned long action,
+ 		container_of(nb, struct hci_dev, suspend_notifier);
+ 	int ret = 0;
+ 
++	/* Userspace has full control of this device. Do nothing. */
++	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
++		return NOTIFY_DONE;
++
+ 	if (action == PM_SUSPEND_PREPARE)
+ 		ret = hci_suspend_dev(hdev);
+ 	else if (action == PM_POST_SUSPEND)
+@@ -3478,15 +3482,27 @@ static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb)
+ 	return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len);
+ }
+ 
+-static void __check_timeout(struct hci_dev *hdev, unsigned int cnt)
++static void __check_timeout(struct hci_dev *hdev, unsigned int cnt, u8 type)
+ {
+-	if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
+-		/* ACL tx timeout must be longer than maximum
+-		 * link supervision timeout (40.9 seconds) */
+-		if (!cnt && time_after(jiffies, hdev->acl_last_tx +
+-				       HCI_ACL_TX_TIMEOUT))
+-			hci_link_tx_to(hdev, ACL_LINK);
++	unsigned long last_tx;
++
++	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
++		return;
++
++	switch (type) {
++	case LE_LINK:
++		last_tx = hdev->le_last_tx;
++		break;
++	default:
++		last_tx = hdev->acl_last_tx;
++		break;
+ 	}
++
++	/* tx timeout must be longer than maximum link supervision timeout
++	 * (40.9 seconds)
++	 */
++	if (!cnt && time_after(jiffies, last_tx + HCI_ACL_TX_TIMEOUT))
++		hci_link_tx_to(hdev, type);
+ }
+ 
+ /* Schedule SCO */
+@@ -3544,7 +3560,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev)
+ 	struct sk_buff *skb;
+ 	int quote;
+ 
+-	__check_timeout(hdev, cnt);
++	__check_timeout(hdev, cnt, ACL_LINK);
+ 
+ 	while (hdev->acl_cnt &&
+ 	       (chan = hci_chan_sent(hdev, ACL_LINK, &quote))) {
+@@ -3587,8 +3603,6 @@ static void hci_sched_acl_blk(struct hci_dev *hdev)
+ 	int quote;
+ 	u8 type;
+ 
+-	__check_timeout(hdev, cnt);
+-
+ 	BT_DBG("%s", hdev->name);
+ 
+ 	if (hdev->dev_type == HCI_AMP)
+@@ -3596,6 +3610,8 @@ static void hci_sched_acl_blk(struct hci_dev *hdev)
+ 	else
+ 		type = ACL_LINK;
+ 
++	__check_timeout(hdev, cnt, type);
++
+ 	while (hdev->block_cnt > 0 &&
+ 	       (chan = hci_chan_sent(hdev, type, &quote))) {
+ 		u32 priority = (skb_peek(&chan->data_q))->priority;
+@@ -3669,7 +3685,7 @@ static void hci_sched_le(struct hci_dev *hdev)
+ 
+ 	cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt;
+ 
+-	__check_timeout(hdev, cnt);
++	__check_timeout(hdev, cnt, LE_LINK);
+ 
+ 	tmp = cnt;
+ 	while (cnt && (chan = hci_chan_sent(hdev, LE_LINK, &quote))) {
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index d6f0e6ca0e7e0..ab79a978deb5b 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -6778,6 +6778,13 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data,
+ 		goto unlock;
+ 	}
+ 
++	if (conn->type != ISO_LINK) {
++		bt_dev_err(hdev,
++			   "Invalid connection link type handle 0x%4.4x",
++			   handle);
++		goto unlock;
++	}
++
+ 	if (conn->role == HCI_ROLE_SLAVE) {
+ 		__le32 interval;
+ 
+@@ -6898,6 +6905,13 @@ static void hci_le_create_big_complete_evt(struct hci_dev *hdev, void *data,
+ 	if (!conn)
+ 		goto unlock;
+ 
++	if (conn->type != ISO_LINK) {
++		bt_dev_err(hdev,
++			   "Invalid connection link type handle 0x%2.2x",
++			   ev->handle);
++		goto unlock;
++	}
++
+ 	if (ev->num_bis)
+ 		conn->handle = __le16_to_cpu(ev->bis_handle[0]);
+ 
+diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
+index 0d015d4a8e414..bd8358b44aa4c 100644
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -887,7 +887,6 @@ static int hci_sock_release(struct socket *sock)
+ 			 */
+ 			hci_dev_do_close(hdev);
+ 			hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
+-			hci_register_suspend_notifier(hdev);
+ 			mgmt_index_added(hdev);
+ 		}
+ 
+@@ -1216,7 +1215,6 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
+ 		}
+ 
+ 		mgmt_index_removed(hdev);
+-		hci_unregister_suspend_notifier(hdev);
+ 
+ 		err = hci_dev_open(hdev->id);
+ 		if (err) {
+@@ -1231,7 +1229,6 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
+ 				err = 0;
+ 			} else {
+ 				hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
+-				hci_register_suspend_notifier(hdev);
+ 				mgmt_index_added(hdev);
+ 				hci_dev_put(hdev);
+ 				goto done;
+diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
+index fbd5613eebfc2..f70798589bf51 100644
+--- a/net/bluetooth/hci_sync.c
++++ b/net/bluetooth/hci_sync.c
+@@ -4355,6 +4355,7 @@ int hci_dev_open_sync(struct hci_dev *hdev)
+ 		    hci_dev_test_flag(hdev, HCI_MGMT) &&
+ 		    hdev->dev_type == HCI_PRIMARY) {
+ 			ret = hci_powered_update_sync(hdev);
++			mgmt_power_on(hdev, ret);
+ 		}
+ 	} else {
+ 		/* Init failed, cleanup */
+diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
+index 4e3e0451b08c1..08542dfc2dc53 100644
+--- a/net/bluetooth/hci_sysfs.c
++++ b/net/bluetooth/hci_sysfs.c
+@@ -48,6 +48,9 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
+ 
+ 	BT_DBG("conn %p", conn);
+ 
++	if (device_is_registered(&conn->dev))
++		return;
++
+ 	dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
+ 
+ 	if (device_add(&conn->dev) < 0) {
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 2c9de67daadcf..1f34b82ca0ec9 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -61,6 +61,9 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
+ 
+ static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
+ 		     struct sk_buff_head *skbs, u8 event);
++static void l2cap_retrans_timeout(struct work_struct *work);
++static void l2cap_monitor_timeout(struct work_struct *work);
++static void l2cap_ack_timeout(struct work_struct *work);
+ 
+ static inline u8 bdaddr_type(u8 link_type, u8 bdaddr_type)
+ {
+@@ -476,6 +479,9 @@ struct l2cap_chan *l2cap_chan_create(void)
+ 	write_unlock(&chan_list_lock);
+ 
+ 	INIT_DELAYED_WORK(&chan->chan_timer, l2cap_chan_timeout);
++	INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
++	INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
++	INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
+ 
+ 	chan->state = BT_OPEN;
+ 
+@@ -3320,10 +3326,6 @@ int l2cap_ertm_init(struct l2cap_chan *chan)
+ 	chan->rx_state = L2CAP_RX_STATE_RECV;
+ 	chan->tx_state = L2CAP_TX_STATE_XMIT;
+ 
+-	INIT_DELAYED_WORK(&chan->retrans_timer, l2cap_retrans_timeout);
+-	INIT_DELAYED_WORK(&chan->monitor_timer, l2cap_monitor_timeout);
+-	INIT_DELAYED_WORK(&chan->ack_timer, l2cap_ack_timeout);
+-
+ 	skb_queue_head_init(&chan->srej_q);
+ 
+ 	err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win);
+@@ -4307,6 +4309,12 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
+ 		}
+ 	}
+ 
++	chan = l2cap_chan_hold_unless_zero(chan);
++	if (!chan) {
++		err = -EBADSLT;
++		goto unlock;
++	}
++
+ 	err = 0;
+ 
+ 	l2cap_chan_lock(chan);
+@@ -4336,6 +4344,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
+ 	}
+ 
+ 	l2cap_chan_unlock(chan);
++	l2cap_chan_put(chan);
+ 
+ unlock:
+ 	mutex_unlock(&conn->chan_lock);
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
+index 72e6595a71cc0..3d1cd06669688 100644
+--- a/net/bluetooth/mgmt.c
++++ b/net/bluetooth/mgmt.c
+@@ -1050,7 +1050,7 @@ static void discov_off(struct work_struct *work)
+ 
+ static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev)
+ {
+-	if (hci_dev_test_and_set_flag(hdev, HCI_MGMT))
++	if (hci_dev_test_flag(hdev, HCI_MGMT))
+ 		return;
+ 
+ 	BT_INFO("MGMT ver %d.%d", MGMT_VERSION, MGMT_REVISION);
+@@ -1065,6 +1065,8 @@ static void mgmt_init_hdev(struct sock *sk, struct hci_dev *hdev)
+ 	 * it
+ 	 */
+ 	hci_dev_clear_flag(hdev, HCI_BONDABLE);
++
++	hci_dev_set_flag(hdev, HCI_MGMT);
+ }
+ 
+ static int read_controller_info(struct sock *sk, struct hci_dev *hdev,
+diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
+index 4bf4ea6cbb5ee..21e24da4847f0 100644
+--- a/net/bluetooth/rfcomm/sock.c
++++ b/net/bluetooth/rfcomm/sock.c
+@@ -902,7 +902,10 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how)
+ 	lock_sock(sk);
+ 	if (!sk->sk_shutdown) {
+ 		sk->sk_shutdown = SHUTDOWN_MASK;
++
++		release_sock(sk);
+ 		__rfcomm_sock_close(sk);
++		lock_sock(sk);
+ 
+ 		if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
+ 		    !(current->flags & PF_EXITING))
+diff --git a/net/can/bcm.c b/net/can/bcm.c
+index e60161bec850a..f16271a7ae2e8 100644
+--- a/net/can/bcm.c
++++ b/net/can/bcm.c
+@@ -274,6 +274,7 @@ static void bcm_can_tx(struct bcm_op *op)
+ 	struct sk_buff *skb;
+ 	struct net_device *dev;
+ 	struct canfd_frame *cf = op->frames + op->cfsiz * op->currframe;
++	int err;
+ 
+ 	/* no target device? => exit */
+ 	if (!op->ifindex)
+@@ -298,11 +299,11 @@ static void bcm_can_tx(struct bcm_op *op)
+ 	/* send with loopback */
+ 	skb->dev = dev;
+ 	can_skb_set_owner(skb, op->sk);
+-	can_send(skb, 1);
++	err = can_send(skb, 1);
++	if (!err)
++		op->frames_abs++;
+ 
+-	/* update statistics */
+ 	op->currframe++;
+-	op->frames_abs++;
+ 
+ 	/* reached last frame? */
+ 	if (op->currframe >= op->nframes)
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 5dc3860e9fc7e..7105529abb0f6 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -1173,8 +1173,8 @@ proto_again:
+ 			nhoff += sizeof(*vlan);
+ 		}
+ 
+-		if (dissector_uses_key(flow_dissector,
+-				       FLOW_DISSECTOR_KEY_NUM_OF_VLANS)) {
++		if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_NUM_OF_VLANS) &&
++		    !(key_control->flags & FLOW_DIS_ENCAPSULATION)) {
+ 			struct flow_dissector_key_num_of_vlans *key_nvs;
+ 
+ 			key_nvs = skb_flow_dissector_target(flow_dissector,
+diff --git a/net/core/skmsg.c b/net/core/skmsg.c
+index 188f8558d27d1..ca70525621c71 100644
+--- a/net/core/skmsg.c
++++ b/net/core/skmsg.c
+@@ -434,8 +434,10 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
+ 			if (copied + copy > len)
+ 				copy = len - copied;
+ 			copy = copy_page_to_iter(page, sge->offset, copy, iter);
+-			if (!copy)
+-				return copied ? copied : -EFAULT;
++			if (!copy) {
++				copied = copied ? copied : -EFAULT;
++				goto out;
++			}
+ 
+ 			copied += copy;
+ 			if (likely(!peek)) {
+@@ -455,7 +457,7 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
+ 				 * didn't copy the entire length lets just break.
+ 				 */
+ 				if (copy != sge->length)
+-					return copied;
++					goto out;
+ 				sk_msg_iter_var_next(i);
+ 			}
+ 
+@@ -477,7 +479,9 @@ int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg,
+ 		}
+ 		msg_rx = sk_psock_peek_msg(psock);
+ 	}
+-
++out:
++	if (psock->work_state.skb && copied > 0)
++		schedule_work(&psock->work);
+ 	return copied;
+ }
+ EXPORT_SYMBOL_GPL(sk_msg_recvmsg);
+diff --git a/net/core/stream.c b/net/core/stream.c
+index ccc083cdef232..1105057ce00a5 100644
+--- a/net/core/stream.c
++++ b/net/core/stream.c
+@@ -159,7 +159,8 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
+ 		*timeo_p = current_timeo;
+ 	}
+ out:
+-	remove_wait_queue(sk_sleep(sk), &wait);
++	if (!sock_flag(sk, SOCK_DEAD))
++		remove_wait_queue(sk_sleep(sk), &wait);
+ 	return err;
+ 
+ do_error:
+diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
+index 7889e1ef7fad6..6e55fae4c6860 100644
+--- a/net/ieee802154/socket.c
++++ b/net/ieee802154/socket.c
+@@ -272,6 +272,10 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
+ 		err = -EMSGSIZE;
+ 		goto out_dev;
+ 	}
++	if (!size) {
++		err = 0;
++		goto out_dev;
++	}
+ 
+ 	hlen = LL_RESERVED_SPACE(dev);
+ 	tlen = dev->needed_tailroom;
+diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
+index ffd57523331fd..405a8c2aea641 100644
+--- a/net/ipv4/datagram.c
++++ b/net/ipv4/datagram.c
+@@ -42,6 +42,8 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
+ 			oif = inet->mc_index;
+ 		if (!saddr)
+ 			saddr = inet->mc_addr;
++	} else if (!oif) {
++		oif = inet->uc_index;
+ 	}
+ 	fl4 = &inet->cork.fl.u.ip4;
+ 	rt = ip_route_connect(fl4, usin->sin_addr.s_addr, saddr, oif,
+diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
+index 935026f4c807e..170152772d332 100644
+--- a/net/ipv4/esp4_offload.c
++++ b/net/ipv4/esp4_offload.c
+@@ -110,7 +110,10 @@ static struct sk_buff *xfrm4_tunnel_gso_segment(struct xfrm_state *x,
+ 						struct sk_buff *skb,
+ 						netdev_features_t features)
+ {
+-	return skb_eth_gso_segment(skb, features, htons(ETH_P_IP));
++	__be16 type = x->inner_mode.family == AF_INET6 ? htons(ETH_P_IPV6)
++						       : htons(ETH_P_IP);
++
++	return skb_eth_gso_segment(skb, features, type);
+ }
+ 
+ static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index b9d995b5ce24c..f5950a7172d61 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -729,8 +729,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+ 	if (likely(remaining > 1))
+ 		remaining &= ~1U;
+ 
+-	net_get_random_once(table_perturb,
+-			    INET_TABLE_PERTURB_SIZE * sizeof(*table_perturb));
++	get_random_slow_once(table_perturb,
++			     INET_TABLE_PERTURB_SIZE * sizeof(*table_perturb));
+ 	index = port_offset & (INET_TABLE_PERTURB_SIZE - 1);
+ 
+ 	offset = READ_ONCE(table_perturb[index]) + (port_offset >> 32);
+diff --git a/net/ipv4/netfilter/nft_fib_ipv4.c b/net/ipv4/netfilter/nft_fib_ipv4.c
+index b75cac69bd7e6..7ade04ff972d7 100644
+--- a/net/ipv4/netfilter/nft_fib_ipv4.c
++++ b/net/ipv4/netfilter/nft_fib_ipv4.c
+@@ -83,6 +83,9 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ 	else
+ 		oif = NULL;
+ 
++	if (priv->flags & NFTA_FIB_F_IIF)
++		fl4.flowi4_oif = l3mdev_master_ifindex_rcu(oif);
++
+ 	if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
+ 	    nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
+ 		nft_fib_store_result(dest, priv, nft_in(pkt));
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index e373dde1f46f7..5f1d84d901c71 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -3137,6 +3137,8 @@ int tcp_disconnect(struct sock *sk, int flags)
+ 	tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
+ 	tcp_snd_cwnd_set(tp, TCP_INIT_CWND);
+ 	tp->snd_cwnd_cnt = 0;
++	tp->is_cwnd_limited = 0;
++	tp->max_packets_out = 0;
+ 	tp->window_clamp = 0;
+ 	tp->delivered = 0;
+ 	tp->delivered_ce = 0;
+@@ -4442,12 +4444,16 @@ static void __tcp_alloc_md5sig_pool(void)
+ 	 * to memory. See smp_rmb() in tcp_get_md5sig_pool()
+ 	 */
+ 	smp_wmb();
+-	tcp_md5sig_pool_populated = true;
++	/* Paired with READ_ONCE() from tcp_alloc_md5sig_pool()
++	 * and tcp_get_md5sig_pool().
++	*/
++	WRITE_ONCE(tcp_md5sig_pool_populated, true);
+ }
+ 
+ bool tcp_alloc_md5sig_pool(void)
+ {
+-	if (unlikely(!tcp_md5sig_pool_populated)) {
++	/* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */
++	if (unlikely(!READ_ONCE(tcp_md5sig_pool_populated))) {
+ 		mutex_lock(&tcp_md5sig_mutex);
+ 
+ 		if (!tcp_md5sig_pool_populated) {
+@@ -4458,7 +4464,8 @@ bool tcp_alloc_md5sig_pool(void)
+ 
+ 		mutex_unlock(&tcp_md5sig_mutex);
+ 	}
+-	return tcp_md5sig_pool_populated;
++	/* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */
++	return READ_ONCE(tcp_md5sig_pool_populated);
+ }
+ EXPORT_SYMBOL(tcp_alloc_md5sig_pool);
+ 
+@@ -4474,7 +4481,8 @@ struct tcp_md5sig_pool *tcp_get_md5sig_pool(void)
+ {
+ 	local_bh_disable();
+ 
+-	if (tcp_md5sig_pool_populated) {
++	/* Paired with WRITE_ONCE() from __tcp_alloc_md5sig_pool() */
++	if (READ_ONCE(tcp_md5sig_pool_populated)) {
+ 		/* coupled with smp_wmb() in __tcp_alloc_md5sig_pool() */
+ 		smp_rmb();
+ 		return this_cpu_ptr(&tcp_md5sig_pool);
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 290019de766dc..c69f4d966024c 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1875,15 +1875,20 @@ static void tcp_cwnd_validate(struct sock *sk, bool is_cwnd_limited)
+ 	const struct tcp_congestion_ops *ca_ops = inet_csk(sk)->icsk_ca_ops;
+ 	struct tcp_sock *tp = tcp_sk(sk);
+ 
+-	/* Track the maximum number of outstanding packets in each
+-	 * window, and remember whether we were cwnd-limited then.
++	/* Track the strongest available signal of the degree to which the cwnd
++	 * is fully utilized. If cwnd-limited then remember that fact for the
++	 * current window. If not cwnd-limited then track the maximum number of
++	 * outstanding packets in the current window. (If cwnd-limited then we
++	 * chose to not update tp->max_packets_out to avoid an extra else
++	 * clause with no functional impact.)
+ 	 */
+-	if (!before(tp->snd_una, tp->max_packets_seq) ||
+-	    tp->packets_out > tp->max_packets_out ||
+-	    is_cwnd_limited) {
+-		tp->max_packets_out = tp->packets_out;
+-		tp->max_packets_seq = tp->snd_nxt;
++	if (!before(tp->snd_una, tp->cwnd_usage_seq) ||
++	    is_cwnd_limited ||
++	    (!tp->is_cwnd_limited &&
++	     tp->packets_out > tp->max_packets_out)) {
+ 		tp->is_cwnd_limited = is_cwnd_limited;
++		tp->max_packets_out = tp->packets_out;
++		tp->cwnd_usage_seq = tp->snd_nxt;
+ 	}
+ 
+ 	if (tcp_is_cwnd_limited(sk)) {
+diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
+index 3a293838a91db..79d43548279cb 100644
+--- a/net/ipv6/esp6_offload.c
++++ b/net/ipv6/esp6_offload.c
+@@ -145,7 +145,10 @@ static struct sk_buff *xfrm6_tunnel_gso_segment(struct xfrm_state *x,
+ 						struct sk_buff *skb,
+ 						netdev_features_t features)
+ {
+-	return skb_eth_gso_segment(skb, features, htons(ETH_P_IPV6));
++	__be16 type = x->inner_mode.family == AF_INET ? htons(ETH_P_IP)
++						      : htons(ETH_P_IPV6);
++
++	return skb_eth_gso_segment(skb, features, type);
+ }
+ 
+ static struct sk_buff *xfrm6_transport_gso_segment(struct xfrm_state *x,
+diff --git a/net/ipv6/netfilter/nft_fib_ipv6.c b/net/ipv6/netfilter/nft_fib_ipv6.c
+index 8970d0b4faeb4..1d7e520d9966c 100644
+--- a/net/ipv6/netfilter/nft_fib_ipv6.c
++++ b/net/ipv6/netfilter/nft_fib_ipv6.c
+@@ -41,6 +41,9 @@ static int nft_fib6_flowi_init(struct flowi6 *fl6, const struct nft_fib *priv,
+ 	if (ipv6_addr_type(&fl6->daddr) & IPV6_ADDR_LINKLOCAL) {
+ 		lookup_flags |= RT6_LOOKUP_F_IFACE;
+ 		fl6->flowi6_oif = get_ifindex(dev ? dev : pkt->skb->dev);
++	} else if ((priv->flags & NFTA_FIB_F_IIF) &&
++		   (netif_is_l3_master(dev) || netif_is_l3_slave(dev))) {
++		fl6->flowi6_oif = dev->ifindex;
+ 	}
+ 
+ 	if (ipv6_addr_type(&fl6->saddr) & IPV6_ADDR_UNICAST)
+@@ -197,7 +200,8 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ 	if (rt->rt6i_flags & (RTF_REJECT | RTF_ANYCAST | RTF_LOCAL))
+ 		goto put_rt_err;
+ 
+-	if (oif && oif != rt->rt6i_idev->dev)
++	if (oif && oif != rt->rt6i_idev->dev &&
++	    l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) != oif->ifindex)
+ 		goto put_rt_err;
+ 
+ 	nft_fib_store_result(dest, priv, rt->rt6i_idev->dev);
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index a4f6971b7a190..65f34945a7678 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1610,6 +1610,18 @@ static int sta_link_apply_parameters(struct ieee80211_local *local,
+ 		rcu_dereference_protected(sta->link[link_id],
+ 					  lockdep_is_held(&local->sta_mtx));
+ 
++	/*
++	 * If there are no changes, then accept a link that doesn't exist,
++	 * unless it's a new link.
++	 */
++	if (params->link_id < 0 && !new_link &&
++	    !params->link_mac && !params->txpwr_set &&
++	    !params->supported_rates_len &&
++	    !params->ht_capa && !params->vht_capa &&
++	    !params->he_capa && !params->eht_capa &&
++	    !params->opmode_notif_used)
++		return 0;
++
+ 	if (!link || !link_sta)
+ 		return -EINVAL;
+ 
+@@ -1625,6 +1637,8 @@ static int sta_link_apply_parameters(struct ieee80211_local *local,
+ 					     params->link_mac)) {
+ 			return -EINVAL;
+ 		}
++	} else if (new_link) {
++		return -EINVAL;
+ 	}
+ 
+ 	if (params->txpwr_set) {
+@@ -3597,9 +3611,6 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
+ 	case NL80211_IFTYPE_MESH_POINT: {
+ 		struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+ 
+-		if (params->chandef.width != sdata->vif.bss_conf.chandef.width)
+-			return -EINVAL;
+-
+ 		/* changes into another band are not supported */
+ 		if (sdata->vif.bss_conf.chandef.chan->band !=
+ 		    params->chandef.chan->band)
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index fc764984d687f..654414caeb71e 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -1220,14 +1220,21 @@ static void ieee80211_assoc_add_ml_elem(struct ieee80211_sub_if_data *sdata,
+ 	ml_elem = skb_put(skb, sizeof(*ml_elem));
+ 	ml_elem->control =
+ 		cpu_to_le16(IEEE80211_ML_CONTROL_TYPE_BASIC |
+-			    IEEE80211_MLC_BASIC_PRES_EML_CAPA |
+ 			    IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP);
+ 	common = skb_put(skb, sizeof(*common));
+ 	common->len = sizeof(*common) +
+-		      2 + /* EML capabilities */
+ 		      2;  /* MLD capa/ops */
+ 	memcpy(common->mld_mac_addr, sdata->vif.addr, ETH_ALEN);
+-	skb_put_data(skb, &eml_capa, sizeof(eml_capa));
++
++	/* add EML_CAPA only if needed, see Draft P802.11be_D2.1, 35.3.17 */
++	if (eml_capa &
++	    cpu_to_le16((IEEE80211_EML_CAP_EMLSR_SUPP |
++			 IEEE80211_EML_CAP_EMLMR_SUPPORT))) {
++		common->len += 2; /* EML capabilities */
++		ml_elem->control |=
++			cpu_to_le16(IEEE80211_MLC_BASIC_PRES_EML_CAPA);
++		skb_put_data(skb, &eml_capa, sizeof(eml_capa));
++	}
+ 	/* need indication from userspace to support this */
+ 	mld_capa_ops &= ~cpu_to_le16(IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP);
+ 	skb_put_data(skb, &mld_capa_ops, sizeof(mld_capa_ops));
+@@ -5122,7 +5129,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ 	resp.req_ies = ifmgd->assoc_req_ies;
+ 	resp.req_ies_len = ifmgd->assoc_req_ies_len;
+ 	if (sdata->vif.valid_links)
+-		resp.ap_mld_addr = assoc_data->ap_addr;
++		resp.ap_mld_addr = sdata->vif.cfg.ap_addr;
+ 	cfg80211_rx_assoc_resp(sdata->dev, &resp);
+ notify_driver:
+ 	drv_mgd_complete_tx(sdata->local, sdata, &info);
+@@ -6284,6 +6291,8 @@ void ieee80211_mgd_setup_link(struct ieee80211_link_data *link)
+ 	if (sdata->u.mgd.assoc_data)
+ 		ether_addr_copy(link->conf->addr,
+ 				sdata->u.mgd.assoc_data->link[link_id].addr);
++	else if (!is_valid_ether_addr(link->conf->addr))
++		eth_random_addr(link->conf->addr);
+ }
+ 
+ /* scan finished notification */
+@@ -6371,9 +6380,6 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
+ 		goto out_err;
+ 	}
+ 
+-	if (mlo && !is_valid_ether_addr(link->conf->addr))
+-		eth_random_addr(link->conf->addr);
+-
+ 	if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data)) {
+ 		err = -EINVAL;
+ 		goto out_err;
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index 58998d8217784..9d7b238a67372 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -2799,6 +2799,7 @@ hash:
+ void ieee80211_sta_remove_link(struct sta_info *sta, unsigned int link_id)
+ {
+ 	struct ieee80211_sub_if_data *sdata = sta->sdata;
++	u16 old_links = sta->sta.valid_links;
+ 
+ 	lockdep_assert_held(&sdata->local->sta_mtx);
+ 
+@@ -2806,8 +2807,7 @@ void ieee80211_sta_remove_link(struct sta_info *sta, unsigned int link_id)
+ 
+ 	if (test_sta_flag(sta, WLAN_STA_INSERTED))
+ 		drv_change_sta_links(sdata->local, sdata, &sta->sta,
+-				     sta->sta.valid_links,
+-				     sta->sta.valid_links & ~BIT(link_id));
++				     old_links, sta->sta.valid_links);
+ 
+ 	sta_remove_link(sta, link_id, true);
+ }
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 1357a2729a4ba..8f261cd5b3a50 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -67,6 +67,7 @@ struct conntrack_gc_work {
+ 	struct delayed_work	dwork;
+ 	u32			next_bucket;
+ 	u32			avg_timeout;
++	u32			count;
+ 	u32			start_time;
+ 	bool			exiting;
+ 	bool			early_drop;
+@@ -85,10 +86,12 @@ static DEFINE_MUTEX(nf_conntrack_mutex);
+ /* clamp timeouts to this value (TCP unacked) */
+ #define GC_SCAN_INTERVAL_CLAMP	(300ul * HZ)
+ 
+-/* large initial bias so that we don't scan often just because we have
+- * three entries with a 1s timeout.
++/* Initial bias pretending we have 100 entries at the upper bound so we don't
++ * wakeup often just because we have three entries with a 1s timeout while still
++ * allowing non-idle machines to wakeup more often when needed.
+  */
+-#define GC_SCAN_INTERVAL_INIT	INT_MAX
++#define GC_SCAN_INITIAL_COUNT	100
++#define GC_SCAN_INTERVAL_INIT	GC_SCAN_INTERVAL_MAX
+ 
+ #define GC_SCAN_MAX_DURATION	msecs_to_jiffies(10)
+ #define GC_SCAN_EXPIRED_MAX	(64000u / HZ)
+@@ -1466,6 +1469,7 @@ static void gc_worker(struct work_struct *work)
+ 	unsigned int expired_count = 0;
+ 	unsigned long next_run;
+ 	s32 delta_time;
++	long count;
+ 
+ 	gc_work = container_of(work, struct conntrack_gc_work, dwork.work);
+ 
+@@ -1475,10 +1479,12 @@ static void gc_worker(struct work_struct *work)
+ 
+ 	if (i == 0) {
+ 		gc_work->avg_timeout = GC_SCAN_INTERVAL_INIT;
++		gc_work->count = GC_SCAN_INITIAL_COUNT;
+ 		gc_work->start_time = start_time;
+ 	}
+ 
+ 	next_run = gc_work->avg_timeout;
++	count = gc_work->count;
+ 
+ 	end_time = start_time + GC_SCAN_MAX_DURATION;
+ 
+@@ -1498,8 +1504,8 @@ static void gc_worker(struct work_struct *work)
+ 
+ 		hlist_nulls_for_each_entry_rcu(h, n, &ct_hash[i], hnnode) {
+ 			struct nf_conntrack_net *cnet;
+-			unsigned long expires;
+ 			struct net *net;
++			long expires;
+ 
+ 			tmp = nf_ct_tuplehash_to_ctrack(h);
+ 
+@@ -1513,6 +1519,7 @@ static void gc_worker(struct work_struct *work)
+ 
+ 				gc_work->next_bucket = i;
+ 				gc_work->avg_timeout = next_run;
++				gc_work->count = count;
+ 
+ 				delta_time = nfct_time_stamp - gc_work->start_time;
+ 
+@@ -1528,8 +1535,8 @@ static void gc_worker(struct work_struct *work)
+ 			}
+ 
+ 			expires = clamp(nf_ct_expires(tmp), GC_SCAN_INTERVAL_MIN, GC_SCAN_INTERVAL_CLAMP);
++			expires = (expires - (long)next_run) / ++count;
+ 			next_run += expires;
+-			next_run /= 2u;
+ 
+ 			if (nf_conntrack_max95 == 0 || gc_worker_skip_ct(tmp))
+ 				continue;
+@@ -1570,6 +1577,7 @@ static void gc_worker(struct work_struct *work)
+ 		delta_time = nfct_time_stamp - end_time;
+ 		if (delta_time > 0 && i < hashsz) {
+ 			gc_work->avg_timeout = next_run;
++			gc_work->count = count;
+ 			gc_work->next_bucket = i;
+ 			next_run = 0;
+ 			goto early_exit;
+diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
+index 6c9d153afbeee..93c596e3b22b9 100644
+--- a/net/openvswitch/datapath.c
++++ b/net/openvswitch/datapath.c
+@@ -252,10 +252,17 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
+ 
+ 		upcall.mru = OVS_CB(skb)->mru;
+ 		error = ovs_dp_upcall(dp, skb, key, &upcall, 0);
+-		if (unlikely(error))
+-			kfree_skb(skb);
+-		else
++		switch (error) {
++		case 0:
++		case -EAGAIN:
++		case -ERESTARTSYS:
++		case -EINTR:
+ 			consume_skb(skb);
++			break;
++		default:
++			kfree_skb(skb);
++			break;
++		}
+ 		stats_counter = &stats->n_missed;
+ 		goto out;
+ 	}
+@@ -551,8 +558,9 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
+ out:
+ 	if (err)
+ 		skb_tx_error(skb);
+-	kfree_skb(user_skb);
+-	kfree_skb(nskb);
++	consume_skb(user_skb);
++	consume_skb(nskb);
++
+ 	return err;
+ }
+ 
+diff --git a/net/rds/tcp.c b/net/rds/tcp.c
+index 73ee2771093d6..d0ff413f697c3 100644
+--- a/net/rds/tcp.c
++++ b/net/rds/tcp.c
+@@ -166,10 +166,10 @@ void rds_tcp_reset_callbacks(struct socket *sock,
+ 	 */
+ 	atomic_set(&cp->cp_state, RDS_CONN_RESETTING);
+ 	wait_event(cp->cp_waitq, !test_bit(RDS_IN_XMIT, &cp->cp_flags));
+-	lock_sock(osock->sk);
+ 	/* reset receive side state for rds_tcp_data_recv() for osock  */
+ 	cancel_delayed_work_sync(&cp->cp_send_w);
+ 	cancel_delayed_work_sync(&cp->cp_recv_w);
++	lock_sock(osock->sk);
+ 	if (tc->t_tinc) {
+ 		rds_inc_put(&tc->t_tinc->ti_inc);
+ 		tc->t_tinc = NULL;
+diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
+index 4d27300c287c4..5f33472aad360 100644
+--- a/net/sched/cls_u32.c
++++ b/net/sched/cls_u32.c
+@@ -1040,7 +1040,11 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
+ 	}
+ #endif
+ 
+-	memcpy(&n->sel, s, sel_size);
++	unsafe_memcpy(&n->sel, s, sel_size,
++		      /* A composite flex-array structure destination,
++		       * which was correctly sized with struct_size(),
++		       * bounds-checked against nla_len(), and allocated
++		       * above. */);
+ 	RCU_INIT_POINTER(n->ht_up, ht);
+ 	n->handle = handle;
+ 	n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
+diff --git a/net/sctp/auth.c b/net/sctp/auth.c
+index db6b7373d16c3..34964145514e6 100644
+--- a/net/sctp/auth.c
++++ b/net/sctp/auth.c
+@@ -863,12 +863,17 @@ int sctp_auth_set_key(struct sctp_endpoint *ep,
+ 	}
+ 
+ 	list_del_init(&shkey->key_list);
+-	sctp_auth_shkey_release(shkey);
+ 	list_add(&cur_key->key_list, sh_keys);
+ 
+-	if (asoc && asoc->active_key_id == auth_key->sca_keynumber)
+-		sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL);
++	if (asoc && asoc->active_key_id == auth_key->sca_keynumber &&
++	    sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL)) {
++		list_del_init(&cur_key->key_list);
++		sctp_auth_shkey_release(cur_key);
++		list_add(&shkey->key_list, sh_keys);
++		return -ENOMEM;
++	}
+ 
++	sctp_auth_shkey_release(shkey);
+ 	return 0;
+ }
+ 
+@@ -902,8 +907,13 @@ int sctp_auth_set_active_key(struct sctp_endpoint *ep,
+ 		return -EINVAL;
+ 
+ 	if (asoc) {
++		__u16  active_key_id = asoc->active_key_id;
++
+ 		asoc->active_key_id = key_id;
+-		sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL);
++		if (sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL)) {
++			asoc->active_key_id = active_key_id;
++			return -ENOMEM;
++		}
+ 	} else
+ 		ep->active_key_id = key_id;
+ 
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index bf338b782fc4c..d686804119c99 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -569,12 +569,6 @@ static void unix_sock_destructor(struct sock *sk)
+ 
+ 	skb_queue_purge(&sk->sk_receive_queue);
+ 
+-#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
+-	if (u->oob_skb) {
+-		kfree_skb(u->oob_skb);
+-		u->oob_skb = NULL;
+-	}
+-#endif
+ 	DEBUG_NET_WARN_ON_ONCE(refcount_read(&sk->sk_wmem_alloc));
+ 	DEBUG_NET_WARN_ON_ONCE(!sk_unhashed(sk));
+ 	DEBUG_NET_WARN_ON_ONCE(sk->sk_socket);
+@@ -620,6 +614,13 @@ static void unix_release_sock(struct sock *sk, int embrion)
+ 
+ 	unix_state_unlock(sk);
+ 
++#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
++	if (u->oob_skb) {
++		kfree_skb(u->oob_skb);
++		u->oob_skb = NULL;
++	}
++#endif
++
+ 	wake_up_interruptible_all(&u->peer_wait);
+ 
+ 	if (skpair != NULL) {
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index d45d5366115a7..dc27635403932 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -204,6 +204,7 @@ void wait_for_unix_gc(void)
+ /* The external entry point: unix_gc() */
+ void unix_gc(void)
+ {
++	struct sk_buff *next_skb, *skb;
+ 	struct unix_sock *u;
+ 	struct unix_sock *next;
+ 	struct sk_buff_head hitlist;
+@@ -297,11 +298,30 @@ void unix_gc(void)
+ 
+ 	spin_unlock(&unix_gc_lock);
+ 
++	/* We need io_uring to clean its registered files, ignore all io_uring
++	 * originated skbs. It's fine as io_uring doesn't keep references to
++	 * other io_uring instances and so killing all other files in the cycle
++	 * will put all io_uring references forcing it to go through normal
++	 * release.path eventually putting registered files.
++	 */
++	skb_queue_walk_safe(&hitlist, skb, next_skb) {
++		if (skb->scm_io_uring) {
++			__skb_unlink(skb, &hitlist);
++			skb_queue_tail(&skb->sk->sk_receive_queue, skb);
++		}
++	}
++
+ 	/* Here we are. Hitlist is filled. Die. */
+ 	__skb_queue_purge(&hitlist);
+ 
+ 	spin_lock(&unix_gc_lock);
+ 
++	/* There could be io_uring registered files, just push them back to
++	 * the inflight list
++	 */
++	list_for_each_entry_safe(u, next, &gc_candidates, link)
++		list_move_tail(&u->link, &gc_inflight_list);
++
+ 	/* All candidates should have been detached by now. */
+ 	BUG_ON(!list_empty(&gc_candidates));
+ 
+diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
+index ec2c2afbf0d06..3a12aee33e92f 100644
+--- a/net/vmw_vsock/virtio_transport_common.c
++++ b/net/vmw_vsock/virtio_transport_common.c
+@@ -1342,7 +1342,7 @@ EXPORT_SYMBOL_GPL(virtio_transport_recv_pkt);
+ 
+ void virtio_transport_free_pkt(struct virtio_vsock_pkt *pkt)
+ {
+-	kfree(pkt->buf);
++	kvfree(pkt->buf);
+ 	kfree(pkt);
+ }
+ EXPORT_SYMBOL_GPL(virtio_transport_free_pkt);
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index c7383ede794fc..d5c7a5aa68532 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -2389,6 +2389,10 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev)
+ 		switch (iftype) {
+ 		case NL80211_IFTYPE_AP:
+ 		case NL80211_IFTYPE_P2P_GO:
++			if (!wdev->links[link].ap.beacon_interval)
++				continue;
++			chandef = wdev->links[link].ap.chandef;
++			break;
+ 		case NL80211_IFTYPE_MESH_POINT:
+ 			if (!wdev->u.mesh.beacon_interval)
+ 				continue;
+diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
+index 7bada4e8460ba..9f0561b67c12e 100644
+--- a/net/xdp/xsk.c
++++ b/net/xdp/xsk.c
+@@ -355,16 +355,15 @@ static u32 xsk_tx_peek_release_fallback(struct xsk_buff_pool *pool, u32 max_entr
+ 	return nb_pkts;
+ }
+ 
+-u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries)
++u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 nb_pkts)
+ {
+ 	struct xdp_sock *xs;
+-	u32 nb_pkts;
+ 
+ 	rcu_read_lock();
+ 	if (!list_is_singular(&pool->xsk_tx_list)) {
+ 		/* Fallback to the non-batched version */
+ 		rcu_read_unlock();
+-		return xsk_tx_peek_release_fallback(pool, max_entries);
++		return xsk_tx_peek_release_fallback(pool, nb_pkts);
+ 	}
+ 
+ 	xs = list_first_or_null_rcu(&pool->xsk_tx_list, struct xdp_sock, tx_list);
+@@ -373,12 +372,7 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries)
+ 		goto out;
+ 	}
+ 
+-	max_entries = xskq_cons_nb_entries(xs->tx, max_entries);
+-	nb_pkts = xskq_cons_read_desc_batch(xs->tx, pool, max_entries);
+-	if (!nb_pkts) {
+-		xs->tx->queue_empty_descs++;
+-		goto out;
+-	}
++	nb_pkts = xskq_cons_nb_entries(xs->tx, nb_pkts);
+ 
+ 	/* This is the backpressure mechanism for the Tx path. Try to
+ 	 * reserve space in the completion queue for all packets, but
+@@ -386,12 +380,18 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries)
+ 	 * packets. This avoids having to implement any buffering in
+ 	 * the Tx path.
+ 	 */
+-	nb_pkts = xskq_prod_reserve_addr_batch(pool->cq, pool->tx_descs, nb_pkts);
++	nb_pkts = xskq_prod_nb_free(pool->cq, nb_pkts);
+ 	if (!nb_pkts)
+ 		goto out;
+ 
+-	xskq_cons_release_n(xs->tx, max_entries);
++	nb_pkts = xskq_cons_read_desc_batch(xs->tx, pool, nb_pkts);
++	if (!nb_pkts) {
++		xs->tx->queue_empty_descs++;
++		goto out;
++	}
++
+ 	__xskq_cons_release(xs->tx);
++	xskq_prod_write_addr_batch(pool->cq, pool->tx_descs, nb_pkts);
+ 	xs->sk.sk_write_space(&xs->sk);
+ 
+ out:
+diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h
+index fb20bf7207cfb..c6fb6b7636582 100644
+--- a/net/xdp/xsk_queue.h
++++ b/net/xdp/xsk_queue.h
+@@ -205,6 +205,11 @@ static inline bool xskq_cons_read_desc(struct xsk_queue *q,
+ 	return false;
+ }
+ 
++static inline void xskq_cons_release_n(struct xsk_queue *q, u32 cnt)
++{
++	q->cached_cons += cnt;
++}
++
+ static inline u32 xskq_cons_read_desc_batch(struct xsk_queue *q, struct xsk_buff_pool *pool,
+ 					    u32 max)
+ {
+@@ -226,6 +231,8 @@ static inline u32 xskq_cons_read_desc_batch(struct xsk_queue *q, struct xsk_buff
+ 		cached_cons++;
+ 	}
+ 
++	/* Release valid plus any invalid entries */
++	xskq_cons_release_n(q, cached_cons - q->cached_cons);
+ 	return nb_entries;
+ }
+ 
+@@ -291,11 +298,6 @@ static inline void xskq_cons_release(struct xsk_queue *q)
+ 	q->cached_cons++;
+ }
+ 
+-static inline void xskq_cons_release_n(struct xsk_queue *q, u32 cnt)
+-{
+-	q->cached_cons += cnt;
+-}
+-
+ static inline u32 xskq_cons_present_entries(struct xsk_queue *q)
+ {
+ 	/* No barriers needed since data is not accessed */
+@@ -350,21 +352,17 @@ static inline int xskq_prod_reserve_addr(struct xsk_queue *q, u64 addr)
+ 	return 0;
+ }
+ 
+-static inline u32 xskq_prod_reserve_addr_batch(struct xsk_queue *q, struct xdp_desc *descs,
+-					       u32 max)
++static inline void xskq_prod_write_addr_batch(struct xsk_queue *q, struct xdp_desc *descs,
++					      u32 nb_entries)
+ {
+ 	struct xdp_umem_ring *ring = (struct xdp_umem_ring *)q->ring;
+-	u32 nb_entries, i, cached_prod;
+-
+-	nb_entries = xskq_prod_nb_free(q, max);
++	u32 i, cached_prod;
+ 
+ 	/* A, matches D */
+ 	cached_prod = q->cached_prod;
+ 	for (i = 0; i < nb_entries; i++)
+ 		ring->desc[cached_prod++ & q->ring_mask] = descs[i].addr;
+ 	q->cached_prod = cached_prod;
+-
+-	return nb_entries;
+ }
+ 
+ static inline int xskq_prod_reserve_desc(struct xsk_queue *q,
+diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
+index b2f4ec9c537f0..aa5220565763c 100644
+--- a/net/xfrm/xfrm_input.c
++++ b/net/xfrm/xfrm_input.c
+@@ -24,7 +24,8 @@
+ #include "xfrm_inout.h"
+ 
+ struct xfrm_trans_tasklet {
+-	struct tasklet_struct tasklet;
++	struct work_struct work;
++	spinlock_t queue_lock;
+ 	struct sk_buff_head queue;
+ };
+ 
+@@ -760,18 +761,22 @@ int xfrm_input_resume(struct sk_buff *skb, int nexthdr)
+ }
+ EXPORT_SYMBOL(xfrm_input_resume);
+ 
+-static void xfrm_trans_reinject(struct tasklet_struct *t)
++static void xfrm_trans_reinject(struct work_struct *work)
+ {
+-	struct xfrm_trans_tasklet *trans = from_tasklet(trans, t, tasklet);
++	struct xfrm_trans_tasklet *trans = container_of(work, struct xfrm_trans_tasklet, work);
+ 	struct sk_buff_head queue;
+ 	struct sk_buff *skb;
+ 
+ 	__skb_queue_head_init(&queue);
++	spin_lock_bh(&trans->queue_lock);
+ 	skb_queue_splice_init(&trans->queue, &queue);
++	spin_unlock_bh(&trans->queue_lock);
+ 
++	local_bh_disable();
+ 	while ((skb = __skb_dequeue(&queue)))
+ 		XFRM_TRANS_SKB_CB(skb)->finish(XFRM_TRANS_SKB_CB(skb)->net,
+ 					       NULL, skb);
++	local_bh_enable();
+ }
+ 
+ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
+@@ -789,8 +794,10 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
+ 
+ 	XFRM_TRANS_SKB_CB(skb)->finish = finish;
+ 	XFRM_TRANS_SKB_CB(skb)->net = net;
++	spin_lock_bh(&trans->queue_lock);
+ 	__skb_queue_tail(&trans->queue, skb);
+-	tasklet_schedule(&trans->tasklet);
++	spin_unlock_bh(&trans->queue_lock);
++	schedule_work(&trans->work);
+ 	return 0;
+ }
+ EXPORT_SYMBOL(xfrm_trans_queue_net);
+@@ -817,7 +824,8 @@ void __init xfrm_input_init(void)
+ 		struct xfrm_trans_tasklet *trans;
+ 
+ 		trans = &per_cpu(xfrm_trans_tasklet, i);
++		spin_lock_init(&trans->queue_lock);
+ 		__skb_queue_head_init(&trans->queue);
+-		tasklet_setup(&trans->tasklet, xfrm_trans_reinject);
++		INIT_WORK(&trans->work, xfrm_trans_reinject);
+ 	}
+ }
+diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c
+index cb40ff0ff28da..92ad336a83ab5 100644
+--- a/net/xfrm/xfrm_ipcomp.c
++++ b/net/xfrm/xfrm_ipcomp.c
+@@ -203,6 +203,7 @@ static void ipcomp_free_scratches(void)
+ 		vfree(*per_cpu_ptr(scratches, i));
+ 
+ 	free_percpu(scratches);
++	ipcomp_scratches = NULL;
+ }
+ 
+ static void * __percpu *ipcomp_alloc_scratches(void)
+diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
+index ece44b7350613..2bc08ace38a3b 100644
+--- a/scripts/Kbuild.include
++++ b/scripts/Kbuild.include
+@@ -100,8 +100,29 @@ echo-cmd = $(if $($(quiet)cmd_$(1)),\
+  quiet_redirect :=
+ silent_redirect := exec >/dev/null;
+ 
++# Delete the target on interruption
++#
++# GNU Make automatically deletes the target if it has already been changed by
++# the interrupted recipe. So, you can safely stop the build by Ctrl-C (Make
++# will delete incomplete targets), and resume it later.
++#
++# However, this does not work when the stderr is piped to another program, like
++#  $ make >&2 | tee log
++# Make dies with SIGPIPE before cleaning the targets.
++#
++# To address it, we clean the target in signal traps.
++#
++# Make deletes the target when it catches SIGHUP, SIGINT, SIGQUIT, SIGTERM.
++# So, we cover them, and also SIGPIPE just in case.
++#
++# Of course, this is unneeded for phony targets.
++delete-on-interrupt = \
++	$(if $(filter-out $(PHONY), $@), \
++		$(foreach sig, HUP INT QUIT TERM PIPE, \
++			trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);))
++
+ # printing commands
+-cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(cmd_$(1))
++cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(delete-on-interrupt) $(cmd_$(1))
+ 
+ ###
+ # if_changed      - execute command if any prerequisite is newer than
+diff --git a/scripts/package/mkspec b/scripts/package/mkspec
+index 8fa7c5b8a1a15..c920c1b18e7ad 100755
+--- a/scripts/package/mkspec
++++ b/scripts/package/mkspec
+@@ -88,10 +88,10 @@ $S
+ 	mkdir -p %{buildroot}/boot
+ 	%ifarch ia64
+ 	mkdir -p %{buildroot}/boot/efi
+-	cp \$($MAKE image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE
++	cp \$($MAKE -s image_name) %{buildroot}/boot/efi/vmlinuz-$KERNELRELEASE
+ 	ln -s efi/vmlinuz-$KERNELRELEASE %{buildroot}/boot/
+ 	%else
+-	cp \$($MAKE image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE
++	cp \$($MAKE -s image_name) %{buildroot}/boot/vmlinuz-$KERNELRELEASE
+ 	%endif
+ $M	$MAKE %{?_smp_mflags} INSTALL_MOD_PATH=%{buildroot} modules_install
+ 	$MAKE %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
+diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh
+index 2dccf141241d7..20af56ce245c5 100755
+--- a/scripts/selinux/install_policy.sh
++++ b/scripts/selinux/install_policy.sh
+@@ -78,7 +78,7 @@ cd /etc/selinux/dummy/contexts/files
+ $SF -F file_contexts /
+ 
+ mounts=`cat /proc/$$/mounts | \
+-	egrep "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \
++	grep -E "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \
+ 	awk '{ print $2 '}`
+ $SF -F file_contexts $mounts
+ 
+diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
+index bde74fcecee38..3e0fbbd995342 100644
+--- a/security/integrity/ima/ima_appraise.c
++++ b/security/integrity/ima/ima_appraise.c
+@@ -750,22 +750,26 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name,
+ 	const struct evm_ima_xattr_data *xvalue = xattr_value;
+ 	int digsig = 0;
+ 	int result;
++	int err;
+ 
+ 	result = ima_protect_xattr(dentry, xattr_name, xattr_value,
+ 				   xattr_value_len);
+ 	if (result == 1) {
+ 		if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST))
+ 			return -EINVAL;
++
++		err = validate_hash_algo(dentry, xvalue, xattr_value_len);
++		if (err)
++			return err;
++
+ 		digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG);
+ 	} else if (!strcmp(xattr_name, XATTR_NAME_EVM) && xattr_value_len > 0) {
+ 		digsig = (xvalue->type == EVM_XATTR_PORTABLE_DIGSIG);
+ 	}
+ 	if (result == 1 || evm_revalidate_status(xattr_name)) {
+-		result = validate_hash_algo(dentry, xvalue, xattr_value_len);
+-		if (result)
+-			return result;
+-
+ 		ima_reset_appraise_flags(d_backing_inode(dentry), digsig);
++		if (result == 1)
++			result = 0;
+ 	}
+ 	return result;
+ }
+diff --git a/security/loadpin/Kconfig b/security/loadpin/Kconfig
+index 70e7985b2561c..994c1d9376e6b 100644
+--- a/security/loadpin/Kconfig
++++ b/security/loadpin/Kconfig
+@@ -33,4 +33,4 @@ config SECURITY_LOADPIN_VERITY
+ 	  on the LoadPin securityfs entry 'dm-verity'. The ioctl
+ 	  expects a file descriptor of a file with verity digests as
+ 	  parameter. The file must be located on the pinned root and
+-	  contain a comma separated list of digests.
++	  contain one digest per line.
+diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c
+index 5b2ca028f5aab..494ec0c207fad 100644
+--- a/sound/core/pcm_dmaengine.c
++++ b/sound/core/pcm_dmaengine.c
+@@ -133,12 +133,14 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data);
+ 
+ static void dmaengine_pcm_dma_complete(void *arg)
+ {
++	unsigned int new_pos;
+ 	struct snd_pcm_substream *substream = arg;
+ 	struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
+ 
+-	prtd->pos += snd_pcm_lib_period_bytes(substream);
+-	if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream))
+-		prtd->pos = 0;
++	new_pos = prtd->pos + snd_pcm_lib_period_bytes(substream);
++	if (new_pos >= snd_pcm_lib_buffer_bytes(substream))
++		new_pos = 0;
++	prtd->pos = new_pos;
+ 
+ 	snd_pcm_period_elapsed(substream);
+ }
+diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
+index 6963d5a487b32..d8edb60550724 100644
+--- a/sound/core/rawmidi.c
++++ b/sound/core/rawmidi.c
+@@ -1899,10 +1899,8 @@ static int snd_rawmidi_free(struct snd_rawmidi *rmidi)
+ 
+ 	snd_info_free_entry(rmidi->proc_entry);
+ 	rmidi->proc_entry = NULL;
+-	mutex_lock(&register_mutex);
+ 	if (rmidi->ops && rmidi->ops->dev_unregister)
+ 		rmidi->ops->dev_unregister(rmidi);
+-	mutex_unlock(&register_mutex);
+ 
+ 	snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]);
+ 	snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]);
+diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
+index 7ed0a2a910352..2751bf2ff61bc 100644
+--- a/sound/core/sound_oss.c
++++ b/sound/core/sound_oss.c
+@@ -162,7 +162,6 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
+ 		mutex_unlock(&sound_oss_mutex);
+ 		return -ENOENT;
+ 	}
+-	unregister_sound_special(minor);
+ 	switch (SNDRV_MINOR_OSS_DEVICE(minor)) {
+ 	case SNDRV_MINOR_OSS_PCM:
+ 		track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_AUDIO);
+@@ -174,12 +173,18 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
+ 		track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1);
+ 		break;
+ 	}
+-	if (track2 >= 0) {
+-		unregister_sound_special(track2);
++	if (track2 >= 0)
+ 		snd_oss_minors[track2] = NULL;
+-	}
+ 	snd_oss_minors[minor] = NULL;
+ 	mutex_unlock(&sound_oss_mutex);
++
++	/* call unregister_sound_special() outside sound_oss_mutex;
++	 * otherwise may deadlock, as it can trigger the release of a card
++	 */
++	unregister_sound_special(minor);
++	if (track2 >= 0)
++		unregister_sound_special(track2);
++
+ 	kfree(mptr);
+ 	return 0;
+ }
+diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c
+index 5a478649f3381..b9eb3208f2888 100644
+--- a/sound/hda/intel-dsp-config.c
++++ b/sound/hda/intel-dsp-config.c
+@@ -427,6 +427,11 @@ static const struct config_entry config_table[] = {
+ 		.device = 0x51cd,
+ 	},
+ 	/* Alderlake-PS */
++	{
++		.flags = FLAG_SOF,
++		.device = 0x51c9,
++		.codec_hid =  &essx_83x6,
++	},
+ 	{
+ 		.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
+ 		.device = 0x51c9,
+diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
+index 53a2b89f8983c..e63621bcb2142 100644
+--- a/sound/pci/hda/hda_beep.c
++++ b/sound/pci/hda/hda_beep.c
+@@ -118,6 +118,12 @@ static int snd_hda_beep_event(struct input_dev *dev, unsigned int type,
+ 	return 0;
+ }
+ 
++static void turn_on_beep(struct hda_beep *beep)
++{
++	if (beep->keep_power_at_enable)
++		snd_hda_power_up_pm(beep->codec);
++}
++
+ static void turn_off_beep(struct hda_beep *beep)
+ {
+ 	cancel_work_sync(&beep->beep_work);
+@@ -125,6 +131,8 @@ static void turn_off_beep(struct hda_beep *beep)
+ 		/* turn off beep */
+ 		generate_tone(beep, 0);
+ 	}
++	if (beep->keep_power_at_enable)
++		snd_hda_power_down_pm(beep->codec);
+ }
+ 
+ /**
+@@ -140,7 +148,9 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
+ 	enable = !!enable;
+ 	if (beep->enabled != enable) {
+ 		beep->enabled = enable;
+-		if (!enable)
++		if (enable)
++			turn_on_beep(beep);
++		else
+ 			turn_off_beep(beep);
+ 		return 1;
+ 	}
+@@ -167,7 +177,8 @@ static int beep_dev_disconnect(struct snd_device *device)
+ 		input_unregister_device(beep->dev);
+ 	else
+ 		input_free_device(beep->dev);
+-	turn_off_beep(beep);
++	if (beep->enabled)
++		turn_off_beep(beep);
+ 	return 0;
+ }
+ 
+diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
+index a25358a4807ab..db76e3ddba654 100644
+--- a/sound/pci/hda/hda_beep.h
++++ b/sound/pci/hda/hda_beep.h
+@@ -25,6 +25,7 @@ struct hda_beep {
+ 	unsigned int enabled:1;
+ 	unsigned int linear_tone:1;	/* linear tone for IDT/STAC codec */
+ 	unsigned int playing:1;
++	unsigned int keep_power_at_enable:1;	/* set by driver */
+ 	struct work_struct beep_work; /* scheduled task for beep event */
+ 	struct mutex mutex;
+ 	void (*power_hook)(struct hda_beep *beep, bool on);
+diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
+index 384426d7e9ddc..4ae8b9574778b 100644
+--- a/sound/pci/hda/hda_codec.c
++++ b/sound/pci/hda/hda_codec.c
+@@ -931,8 +931,28 @@ snd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr,
+ 	}
+ 
+ 	codec->bus = bus;
++	codec->depop_delay = -1;
++	codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
++	codec->core.dev.release = snd_hda_codec_dev_release;
++	codec->core.exec_verb = codec_exec_verb;
+ 	codec->core.type = HDA_DEV_LEGACY;
+ 
++	mutex_init(&codec->spdif_mutex);
++	mutex_init(&codec->control_mutex);
++	snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
++	snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
++	snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
++	snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
++	snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
++	snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
++	snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
++	snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8);
++	INIT_LIST_HEAD(&codec->conn_list);
++	INIT_LIST_HEAD(&codec->pcm_list_head);
++	INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
++	refcount_set(&codec->pcm_ref, 1);
++	init_waitqueue_head(&codec->remove_sleep);
++
+ 	return codec;
+ }
+ EXPORT_SYMBOL_GPL(snd_hda_codec_device_init);
+@@ -985,29 +1005,8 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
+ 	if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
+ 		return -EINVAL;
+ 
+-	codec->core.dev.release = snd_hda_codec_dev_release;
+-	codec->core.exec_verb = codec_exec_verb;
+-
+ 	codec->card = card;
+ 	codec->addr = codec_addr;
+-	mutex_init(&codec->spdif_mutex);
+-	mutex_init(&codec->control_mutex);
+-	snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
+-	snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
+-	snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
+-	snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
+-	snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
+-	snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
+-	snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
+-	snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8);
+-	INIT_LIST_HEAD(&codec->conn_list);
+-	INIT_LIST_HEAD(&codec->pcm_list_head);
+-	refcount_set(&codec->pcm_ref, 1);
+-	init_waitqueue_head(&codec->remove_sleep);
+-
+-	INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
+-	codec->depop_delay = -1;
+-	codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
+ 
+ #ifdef CONFIG_PM
+ 	codec->power_jiffies = jiffies;
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index c239d9dbbaefe..287f4f78e7b1e 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -53,7 +53,8 @@ MODULE_PARM_DESC(enable_all_pins, "Forcibly enable all pins");
+ 
+ struct hdmi_spec_per_cvt {
+ 	hda_nid_t cvt_nid;
+-	int assigned;
++	bool assigned;		/* the stream has been assigned */
++	bool silent_stream;	/* silent stream activated */
+ 	unsigned int channels_min;
+ 	unsigned int channels_max;
+ 	u32 rates;
+@@ -988,7 +989,8 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
+  * of the pin.
+  */
+ static int hdmi_choose_cvt(struct hda_codec *codec,
+-			   int pin_idx, int *cvt_id)
++			   int pin_idx, int *cvt_id,
++			   bool silent)
+ {
+ 	struct hdmi_spec *spec = codec->spec;
+ 	struct hdmi_spec_per_pin *per_pin;
+@@ -1003,6 +1005,9 @@ static int hdmi_choose_cvt(struct hda_codec *codec,
+ 
+ 	if (per_pin && per_pin->silent_stream) {
+ 		cvt_idx = cvt_nid_to_cvt_index(codec, per_pin->cvt_nid);
++		per_cvt = get_cvt(spec, cvt_idx);
++		if (per_cvt->assigned && !silent)
++			return -EBUSY;
+ 		if (cvt_id)
+ 			*cvt_id = cvt_idx;
+ 		return 0;
+@@ -1013,7 +1018,7 @@ static int hdmi_choose_cvt(struct hda_codec *codec,
+ 		per_cvt = get_cvt(spec, cvt_idx);
+ 
+ 		/* Must not already be assigned */
+-		if (per_cvt->assigned)
++		if (per_cvt->assigned || per_cvt->silent_stream)
+ 			continue;
+ 		if (per_pin == NULL)
+ 			break;
+@@ -1199,12 +1204,12 @@ static int hdmi_pcm_open_no_pin(struct hda_pcm_stream *hinfo,
+ 	if (pcm_idx < 0)
+ 		return -EINVAL;
+ 
+-	err = hdmi_choose_cvt(codec, -1, &cvt_idx);
++	err = hdmi_choose_cvt(codec, -1, &cvt_idx, false);
+ 	if (err)
+ 		return err;
+ 
+ 	per_cvt = get_cvt(spec, cvt_idx);
+-	per_cvt->assigned = 1;
++	per_cvt->assigned = true;
+ 	hinfo->nid = per_cvt->cvt_nid;
+ 
+ 	pin_cvt_fixup(codec, NULL, per_cvt->cvt_nid);
+@@ -1267,18 +1272,17 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
+ 		}
+ 	}
+ 
+-	err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx);
++	err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, false);
+ 	if (err < 0)
+ 		goto unlock;
+ 
+ 	per_cvt = get_cvt(spec, cvt_idx);
+ 	/* Claim converter */
+-	per_cvt->assigned = 1;
++	per_cvt->assigned = true;
+ 
+ 	set_bit(pcm_idx, &spec->pcm_in_use);
+ 	per_pin = get_pin(spec, pin_idx);
+ 	per_pin->cvt_nid = per_cvt->cvt_nid;
+-	per_pin->silent_stream = false;
+ 	hinfo->nid = per_cvt->cvt_nid;
+ 
+ 	/* flip stripe flag for the assigned stream if supported */
+@@ -1308,7 +1312,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
+ 		snd_hdmi_eld_update_pcm_info(&eld->info, hinfo);
+ 		if (hinfo->channels_min > hinfo->channels_max ||
+ 		    !hinfo->rates || !hinfo->formats) {
+-			per_cvt->assigned = 0;
++			per_cvt->assigned = false;
+ 			hinfo->nid = 0;
+ 			snd_hda_spdif_ctls_unassign(codec, pcm_idx);
+ 			err = -ENODEV;
+@@ -1760,14 +1764,14 @@ static void silent_stream_enable(struct hda_codec *codec,
+ 	}
+ 
+ 	pin_idx = pin_id_to_pin_index(codec, per_pin->pin_nid, per_pin->dev_id);
+-	err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx);
++	err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, true);
+ 	if (err) {
+ 		codec_err(codec, "hdmi: no free converter to enable silent mode\n");
+ 		goto unlock_out;
+ 	}
+ 
+ 	per_cvt = get_cvt(spec, cvt_idx);
+-	per_cvt->assigned = 1;
++	per_cvt->silent_stream = true;
+ 	per_pin->cvt_nid = per_cvt->cvt_nid;
+ 	per_pin->silent_stream = true;
+ 
+@@ -1827,7 +1831,7 @@ static void silent_stream_disable(struct hda_codec *codec,
+ 	cvt_idx = cvt_nid_to_cvt_index(codec, per_pin->cvt_nid);
+ 	if (cvt_idx >= 0 && cvt_idx < spec->num_cvts) {
+ 		per_cvt = get_cvt(spec, cvt_idx);
+-		per_cvt->assigned = 0;
++		per_cvt->silent_stream = false;
+ 	}
+ 
+ 	if (spec->silent_stream_type == SILENT_STREAM_I915) {
+@@ -2223,7 +2227,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
+ 			goto unlock;
+ 		}
+ 		per_cvt = get_cvt(spec, cvt_idx);
+-		per_cvt->assigned = 0;
++		per_cvt->assigned = false;
+ 		hinfo->nid = 0;
+ 
+ 		azx_stream(get_azx_dev(substream))->stripe = 0;
+@@ -2747,9 +2751,6 @@ static void generic_acomp_pin_eld_notify(void *audio_ptr, int port, int dev_id)
+ 	 */
+ 	if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND)
+ 		return;
+-	/* ditto during suspend/resume process itself */
+-	if (snd_hdac_is_in_pm(&codec->core))
+-		return;
+ 
+ 	check_presence_and_report(codec, pin_nid, dev_id);
+ }
+@@ -2933,9 +2934,6 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe)
+ 	 */
+ 	if (codec->core.dev.power.power_state.event == PM_EVENT_SUSPEND)
+ 		return;
+-	/* ditto during suspend/resume process itself */
+-	if (snd_hdac_is_in_pm(&codec->core))
+-		return;
+ 
+ 	snd_hdac_i915_set_bclk(&codec->bus->core);
+ 	check_presence_and_report(codec, pin_nid, dev_id);
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 3dc19174670eb..8f7905e0b376b 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8427,11 +8427,13 @@ static const struct hda_fixup alc269_fixups[] = {
+ 	[ALC285_FIXUP_ASUS_G533Z_PINS] = {
+ 		.type = HDA_FIXUP_PINS,
+ 		.v.pins = (const struct hda_pintbl[]) {
+-			{ 0x14, 0x90170120 },
++			{ 0x14, 0x90170152 }, /* Speaker Surround Playback Switch */
++			{ 0x19, 0x03a19020 }, /* Mic Boost Volume */
++			{ 0x1a, 0x03a11c30 }, /* Mic Boost Volume */
++			{ 0x1e, 0x90170151 }, /* Rear jack, IN OUT EAPD Detect */
++			{ 0x21, 0x03211420 },
+ 			{ }
+ 		},
+-		.chained = true,
+-		.chain_id = ALC294_FIXUP_ASUS_G513_PINS,
+ 	},
+ 	[ALC294_FIXUP_ASUS_COEF_1B] = {
+ 		.type = HDA_FIXUP_VERBS,
+@@ -9186,7 +9188,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
+ 	SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
+ 	SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
+-	SND_PCI_QUIRK(0x1028, 0x087d, "Dell Precision 5530", ALC289_FIXUP_DUAL_SPK),
+ 	SND_PCI_QUIRK(0x1028, 0x08ad, "Dell WYSE AIO", ALC225_FIXUP_DELL_WYSE_AIO_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x1028, 0x08ae, "Dell WYSE NB", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
+@@ -9410,6 +9411,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
+ 	SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
+ 	SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
++	SND_PCI_QUIRK(0x1043, 0x1f92, "ASUS ROG Flow X16", ALC289_FIXUP_ASUS_GA401),
+ 	SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
+ 	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
+ 	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
+@@ -9431,6 +9433,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE),
+ 	SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x10ec, 0x1230, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
++	SND_PCI_QUIRK(0x10ec, 0x124c, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
+ 	SND_PCI_QUIRK(0x10ec, 0x1252, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
+ 	SND_PCI_QUIRK(0x10ec, 0x1254, "Intel Reference board", ALC295_FIXUP_CHROME_BOOK),
+ 	SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-SZ6", ALC269_FIXUP_HEADSET_MODE),
+diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
+index 7f340f18599c9..a794a01a68ca6 100644
+--- a/sound/pci/hda/patch_sigmatel.c
++++ b/sound/pci/hda/patch_sigmatel.c
+@@ -4311,6 +4311,8 @@ static int stac_parse_auto_config(struct hda_codec *codec)
+ 		if (codec->beep) {
+ 			/* IDT/STAC codecs have linear beep tone parameter */
+ 			codec->beep->linear_tone = spec->linear_tone_beep;
++			/* keep power up while beep is enabled */
++			codec->beep->keep_power_at_enable = 1;
+ 			/* if no beep switch is available, make its own one */
+ 			caps = query_amp_caps(codec, nid, HDA_OUTPUT);
+ 			if (!(caps & AC_AMPCAP_MUTE)) {
+@@ -4444,28 +4446,6 @@ static int stac_suspend(struct hda_codec *codec)
+ 
+ 	return 0;
+ }
+-
+-static int stac_check_power_status(struct hda_codec *codec, hda_nid_t nid)
+-{
+-#ifdef CONFIG_SND_HDA_INPUT_BEEP
+-	struct sigmatel_spec *spec = codec->spec;
+-#endif
+-	int ret = snd_hda_gen_check_power_status(codec, nid);
+-
+-#ifdef CONFIG_SND_HDA_INPUT_BEEP
+-	if (nid == spec->gen.beep_nid && codec->beep) {
+-		if (codec->beep->enabled != spec->beep_power_on) {
+-			spec->beep_power_on = codec->beep->enabled;
+-			if (spec->beep_power_on)
+-				snd_hda_power_up_pm(codec);
+-			else
+-				snd_hda_power_down_pm(codec);
+-		}
+-		ret |= spec->beep_power_on;
+-	}
+-#endif
+-	return ret;
+-}
+ #else
+ #define stac_suspend		NULL
+ #endif /* CONFIG_PM */
+@@ -4478,7 +4458,6 @@ static const struct hda_codec_ops stac_patch_ops = {
+ 	.unsol_event = snd_hda_jack_unsol_event,
+ #ifdef CONFIG_PM
+ 	.suspend = stac_suspend,
+-	.check_power_status = stac_check_power_status,
+ #endif
+ };
+ 
+diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c
+index 2c8e960cc9a6a..5bb23ebe12166 100644
+--- a/sound/soc/amd/acp/acp-pci.c
++++ b/sound/soc/amd/acp/acp-pci.c
+@@ -104,6 +104,7 @@ static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id
+ 	addr = pci_resource_start(pci, 0);
+ 	chip->base = devm_ioremap(&pci->dev, addr, pci_resource_len(pci, 0));
+ 	if (!chip->base) {
++		platform_device_unregister(dmic_dev);
+ 		ret = -ENOMEM;
+ 		goto release_regions;
+ 	}
+diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
+index e0b24e1daef3d..2cb50d5cf1a9a 100644
+--- a/sound/soc/amd/yc/acp6x-mach.c
++++ b/sound/soc/amd/yc/acp6x-mach.c
+@@ -171,6 +171,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "21J6"),
+ 		}
+ 	},
++	{
++		.driver_data = &acp6x_card,
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "82"),
++		}
++	},
++	{
++		.driver_data = &acp6x_card,
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"),
++		}
++	},
+ 	{}
+ };
+ 
+diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
+index 50ecf30e6136a..4746c87004512 100644
+--- a/sound/soc/codecs/da7219.c
++++ b/sound/soc/codecs/da7219.c
+@@ -2196,6 +2196,7 @@ static int da7219_register_dai_clks(struct snd_soc_component *component)
+ 			dai_clk_lookup = clkdev_hw_create(dai_clk_hw, init.name,
+ 							  "%s", dev_name(dev));
+ 			if (!dai_clk_lookup) {
++				clk_hw_unregister(dai_clk_hw);
+ 				ret = -ENOMEM;
+ 				goto err;
+ 			} else {
+@@ -2217,12 +2218,12 @@ static int da7219_register_dai_clks(struct snd_soc_component *component)
+ 	return 0;
+ 
+ err:
+-	do {
++	while (--i >= 0) {
+ 		if (da7219->dai_clks_lookup[i])
+ 			clkdev_drop(da7219->dai_clks_lookup[i]);
+ 
+ 		clk_hw_unregister(&da7219->dai_clks_hw[i]);
+-	} while (i-- > 0);
++	}
+ 
+ 	if (np)
+ 		kfree(da7219->clk_hw_data);
+diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c
+index 55503ba480bb6..e162a08d99452 100644
+--- a/sound/soc/codecs/lpass-tx-macro.c
++++ b/sound/soc/codecs/lpass-tx-macro.c
+@@ -823,17 +823,23 @@ static int tx_macro_tx_mixer_put(struct snd_kcontrol *kcontrol,
+ 	struct tx_macro *tx = snd_soc_component_get_drvdata(component);
+ 
+ 	if (enable) {
++		if (tx->active_decimator[dai_id] == dec_id)
++			return 0;
++
+ 		set_bit(dec_id, &tx->active_ch_mask[dai_id]);
+ 		tx->active_ch_cnt[dai_id]++;
+ 		tx->active_decimator[dai_id] = dec_id;
+ 	} else {
++		if (tx->active_decimator[dai_id] == -1)
++			return 0;
++
+ 		tx->active_ch_cnt[dai_id]--;
+ 		clear_bit(dec_id, &tx->active_ch_mask[dai_id]);
+ 		tx->active_decimator[dai_id] = -1;
+ 	}
+ 	snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
+ 
+-	return 0;
++	return 1;
+ }
+ 
+ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
+@@ -1019,9 +1025,12 @@ static int tx_macro_dec_mode_put(struct snd_kcontrol *kcontrol,
+ 	int path = e->shift_l;
+ 	struct tx_macro *tx = snd_soc_component_get_drvdata(component);
+ 
++	if (tx->dec_mode[path] == value)
++		return 0;
++
+ 	tx->dec_mode[path] = value;
+ 
+-	return 0;
++	return 1;
+ }
+ 
+ static int tx_macro_get_bcs(struct snd_kcontrol *kcontrol,
+diff --git a/sound/soc/codecs/mt6359-accdet.c b/sound/soc/codecs/mt6359-accdet.c
+index c190628e29056..7f624854948c7 100644
+--- a/sound/soc/codecs/mt6359-accdet.c
++++ b/sound/soc/codecs/mt6359-accdet.c
+@@ -965,7 +965,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev)
+ 	mutex_init(&priv->res_lock);
+ 
+ 	priv->accdet_irq = platform_get_irq(pdev, 0);
+-	if (priv->accdet_irq) {
++	if (priv->accdet_irq >= 0) {
+ 		ret = devm_request_threaded_irq(&pdev->dev, priv->accdet_irq,
+ 						NULL, mt6359_accdet_irq,
+ 						IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+@@ -979,7 +979,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev)
+ 
+ 	if (priv->caps & ACCDET_PMIC_EINT0) {
+ 		priv->accdet_eint0 = platform_get_irq(pdev, 1);
+-		if (priv->accdet_eint0) {
++		if (priv->accdet_eint0 >= 0) {
+ 			ret = devm_request_threaded_irq(&pdev->dev,
+ 							priv->accdet_eint0,
+ 							NULL, mt6359_accdet_irq,
+@@ -994,7 +994,7 @@ static int mt6359_accdet_probe(struct platform_device *pdev)
+ 		}
+ 	} else if (priv->caps & ACCDET_PMIC_EINT1) {
+ 		priv->accdet_eint1 = platform_get_irq(pdev, 2);
+-		if (priv->accdet_eint1) {
++		if (priv->accdet_eint1 >= 0) {
+ 			ret = devm_request_threaded_irq(&pdev->dev,
+ 							priv->accdet_eint1,
+ 							NULL, mt6359_accdet_irq,
+diff --git a/sound/soc/codecs/mt6660.c b/sound/soc/codecs/mt6660.c
+index ba11555796ad8..45e0df13afb9f 100644
+--- a/sound/soc/codecs/mt6660.c
++++ b/sound/soc/codecs/mt6660.c
+@@ -503,13 +503,17 @@ static int mt6660_i2c_probe(struct i2c_client *client)
+ 		dev_err(chip->dev, "read chip revision fail\n");
+ 		goto probe_fail;
+ 	}
+-	pm_runtime_set_active(chip->dev);
+-	pm_runtime_enable(chip->dev);
+ 
+ 	ret = devm_snd_soc_register_component(chip->dev,
+ 					       &mt6660_component_driver,
+ 					       &mt6660_codec_dai, 1);
++	if (!ret) {
++		pm_runtime_set_active(chip->dev);
++		pm_runtime_enable(chip->dev);
++	}
++
+ 	return ret;
++
+ probe_fail:
+ 	_mt6660_chip_power_on(chip, 0);
+ 	mutex_destroy(&chip->io_lock);
+diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c
+index 846d9d3ecc9de..39902f77a2e0f 100644
+--- a/sound/soc/codecs/tas2764.c
++++ b/sound/soc/codecs/tas2764.c
+@@ -34,6 +34,9 @@ struct tas2764_priv {
+ 	
+ 	int v_sense_slot;
+ 	int i_sense_slot;
++
++	bool dac_powered;
++	bool unmuted;
+ };
+ 
+ static void tas2764_reset(struct tas2764_priv *tas2764)
+@@ -50,34 +53,22 @@ static void tas2764_reset(struct tas2764_priv *tas2764)
+ 	usleep_range(1000, 2000);
+ }
+ 
+-static int tas2764_set_bias_level(struct snd_soc_component *component,
+-				 enum snd_soc_bias_level level)
++static int tas2764_update_pwr_ctrl(struct tas2764_priv *tas2764)
+ {
+-	struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
++	struct snd_soc_component *component = tas2764->component;
++	unsigned int val;
++	int ret;
+ 
+-	switch (level) {
+-	case SND_SOC_BIAS_ON:
+-		snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+-					      TAS2764_PWR_CTRL_MASK,
+-					      TAS2764_PWR_CTRL_ACTIVE);
+-		break;
+-	case SND_SOC_BIAS_STANDBY:
+-	case SND_SOC_BIAS_PREPARE:
+-		snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+-					      TAS2764_PWR_CTRL_MASK,
+-					      TAS2764_PWR_CTRL_MUTE);
+-		break;
+-	case SND_SOC_BIAS_OFF:
+-		snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+-					      TAS2764_PWR_CTRL_MASK,
+-					      TAS2764_PWR_CTRL_SHUTDOWN);
+-		break;
++	if (tas2764->dac_powered)
++		val = tas2764->unmuted ?
++			TAS2764_PWR_CTRL_ACTIVE : TAS2764_PWR_CTRL_MUTE;
++	else
++		val = TAS2764_PWR_CTRL_SHUTDOWN;
+ 
+-	default:
+-		dev_err(tas2764->dev,
+-				"wrong power level setting %d\n", level);
+-		return -EINVAL;
+-	}
++	ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
++					    TAS2764_PWR_CTRL_MASK, val);
++	if (ret < 0)
++		return ret;
+ 
+ 	return 0;
+ }
+@@ -114,9 +105,7 @@ static int tas2764_codec_resume(struct snd_soc_component *component)
+ 		usleep_range(1000, 2000);
+ 	}
+ 
+-	ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+-					    TAS2764_PWR_CTRL_MASK,
+-					    TAS2764_PWR_CTRL_ACTIVE);
++	ret = tas2764_update_pwr_ctrl(tas2764);
+ 
+ 	if (ret < 0)
+ 		return ret;
+@@ -150,14 +139,12 @@ static int tas2764_dac_event(struct snd_soc_dapm_widget *w,
+ 
+ 	switch (event) {
+ 	case SND_SOC_DAPM_POST_PMU:
+-		ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+-						    TAS2764_PWR_CTRL_MASK,
+-						    TAS2764_PWR_CTRL_MUTE);
++		tas2764->dac_powered = true;
++		ret = tas2764_update_pwr_ctrl(tas2764);
+ 		break;
+ 	case SND_SOC_DAPM_PRE_PMD:
+-		ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+-						    TAS2764_PWR_CTRL_MASK,
+-						    TAS2764_PWR_CTRL_SHUTDOWN);
++		tas2764->dac_powered = false;
++		ret = tas2764_update_pwr_ctrl(tas2764);
+ 		break;
+ 	default:
+ 		dev_err(tas2764->dev, "Unsupported event\n");
+@@ -202,17 +189,11 @@ static const struct snd_soc_dapm_route tas2764_audio_map[] = {
+ 
+ static int tas2764_mute(struct snd_soc_dai *dai, int mute, int direction)
+ {
+-	struct snd_soc_component *component = dai->component;
+-	int ret;
+-
+-	ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+-					    TAS2764_PWR_CTRL_MASK,
+-					    mute ? TAS2764_PWR_CTRL_MUTE : 0);
++	struct tas2764_priv *tas2764 =
++			snd_soc_component_get_drvdata(dai->component);
+ 
+-	if (ret < 0)
+-		return ret;
+-
+-	return 0;
++	tas2764->unmuted = !mute;
++	return tas2764_update_pwr_ctrl(tas2764);
+ }
+ 
+ static int tas2764_set_bitwidth(struct tas2764_priv *tas2764, int bitwidth)
+@@ -485,7 +466,7 @@ static struct snd_soc_dai_driver tas2764_dai_driver[] = {
+ 		.id = 0,
+ 		.playback = {
+ 			.stream_name    = "ASI1 Playback",
+-			.channels_min   = 2,
++			.channels_min   = 1,
+ 			.channels_max   = 2,
+ 			.rates      = TAS2764_RATES,
+ 			.formats    = TAS2764_FORMATS,
+@@ -526,12 +507,6 @@ static int tas2764_codec_probe(struct snd_soc_component *component)
+ 	if (ret < 0)
+ 		return ret;
+ 
+-	ret = snd_soc_component_update_bits(component, TAS2764_PWR_CTRL,
+-					    TAS2764_PWR_CTRL_MASK,
+-					    TAS2764_PWR_CTRL_MUTE);
+-	if (ret < 0)
+-		return ret;
+-
+ 	return 0;
+ }
+ 
+@@ -549,7 +524,6 @@ static const struct snd_soc_component_driver soc_component_driver_tas2764 = {
+ 	.probe			= tas2764_codec_probe,
+ 	.suspend		= tas2764_codec_suspend,
+ 	.resume			= tas2764_codec_resume,
+-	.set_bias_level		= tas2764_set_bias_level,
+ 	.controls		= tas2764_snd_controls,
+ 	.num_controls		= ARRAY_SIZE(tas2764_snd_controls),
+ 	.dapm_widgets		= tas2764_dapm_widgets,
+diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c
+index 98baef594bf31..31009283e7d4a 100644
+--- a/sound/soc/codecs/wcd-mbhc-v2.c
++++ b/sound/soc/codecs/wcd-mbhc-v2.c
+@@ -714,11 +714,12 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc)
+ 	struct snd_soc_component *component = mbhc->component;
+ 	int ret;
+ 
+-	ret = pm_runtime_resume_and_get(component->dev);
++	ret = pm_runtime_get_sync(component->dev);
+ 	if (ret < 0 && ret != -EACCES) {
+ 		dev_err_ratelimited(component->dev,
+-				    "pm_runtime_resume_and_get failed in %s, ret %d\n",
++				    "pm_runtime_get_sync failed in %s, ret %d\n",
+ 				    __func__, ret);
++		pm_runtime_put_noidle(component->dev);
+ 		return ret;
+ 	}
+ 
+@@ -1096,11 +1097,12 @@ static void wcd_correct_swch_plug(struct work_struct *work)
+ 	mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch);
+ 	component = mbhc->component;
+ 
+-	ret = pm_runtime_resume_and_get(component->dev);
++	ret = pm_runtime_get_sync(component->dev);
+ 	if (ret < 0 && ret != -EACCES) {
+ 		dev_err_ratelimited(component->dev,
+-				    "pm_runtime_resume_and_get failed in %s, ret %d\n",
++				    "pm_runtime_get_sync failed in %s, ret %d\n",
+ 				    __func__, ret);
++		pm_runtime_put_noidle(component->dev);
+ 		return;
+ 	}
+ 	micbias_mv = wcd_mbhc_get_micbias(mbhc);
+diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
+index beeeb35e80321..8a1f741de948a 100644
+--- a/sound/soc/codecs/wcd9335.c
++++ b/sound/soc/codecs/wcd9335.c
+@@ -1974,8 +1974,8 @@ static int wcd9335_trigger(struct snd_pcm_substream *substream, int cmd,
+ 	case SNDRV_PCM_TRIGGER_STOP:
+ 	case SNDRV_PCM_TRIGGER_SUSPEND:
+ 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+-		slim_stream_unprepare(dai_data->sruntime);
+ 		slim_stream_disable(dai_data->sruntime);
++		slim_stream_unprepare(dai_data->sruntime);
+ 		break;
+ 	default:
+ 		break;
+diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c
+index f56907d0942db..28175c746b9ae 100644
+--- a/sound/soc/codecs/wcd934x.c
++++ b/sound/soc/codecs/wcd934x.c
+@@ -1913,8 +1913,8 @@ static int wcd934x_trigger(struct snd_pcm_substream *substream, int cmd,
+ 	case SNDRV_PCM_TRIGGER_STOP:
+ 	case SNDRV_PCM_TRIGGER_SUSPEND:
+ 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+-		slim_stream_unprepare(dai_data->sruntime);
+ 		slim_stream_disable(dai_data->sruntime);
++		slim_stream_unprepare(dai_data->sruntime);
+ 		break;
+ 	default:
+ 		break;
+diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
+index af7d324e33525..c09c9ac51b3e7 100644
+--- a/sound/soc/codecs/wm5102.c
++++ b/sound/soc/codecs/wm5102.c
+@@ -2099,9 +2099,6 @@ static int wm5102_probe(struct platform_device *pdev)
+ 		regmap_update_bits(arizona->regmap, wm5102_digital_vu[i],
+ 				   WM5102_DIG_VU, WM5102_DIG_VU);
+ 
+-	pm_runtime_enable(&pdev->dev);
+-	pm_runtime_idle(&pdev->dev);
+-
+ 	ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
+ 				  "ADSP2 Compressed IRQ", wm5102_adsp2_irq,
+ 				  wm5102);
+@@ -2134,6 +2131,9 @@ static int wm5102_probe(struct platform_device *pdev)
+ 		goto err_spk_irqs;
+ 	}
+ 
++	pm_runtime_enable(&pdev->dev);
++	pm_runtime_idle(&pdev->dev);
++
+ 	return ret;
+ 
+ err_spk_irqs:
+diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
+index f3f4a10bf0f7c..fc634c995834d 100644
+--- a/sound/soc/codecs/wm5110.c
++++ b/sound/soc/codecs/wm5110.c
+@@ -2457,9 +2457,6 @@ static int wm5110_probe(struct platform_device *pdev)
+ 		regmap_update_bits(arizona->regmap, wm5110_digital_vu[i],
+ 				   WM5110_DIG_VU, WM5110_DIG_VU);
+ 
+-	pm_runtime_enable(&pdev->dev);
+-	pm_runtime_idle(&pdev->dev);
+-
+ 	ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
+ 				  "ADSP2 Compressed IRQ", wm5110_adsp2_irq,
+ 				  wm5110);
+@@ -2492,6 +2489,9 @@ static int wm5110_probe(struct platform_device *pdev)
+ 		goto err_spk_irqs;
+ 	}
+ 
++	pm_runtime_enable(&pdev->dev);
++	pm_runtime_idle(&pdev->dev);
++
+ 	return ret;
+ 
+ err_spk_irqs:
+diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c
+index 210ad662fc26d..77136a5216059 100644
+--- a/sound/soc/codecs/wm8997.c
++++ b/sound/soc/codecs/wm8997.c
+@@ -1161,9 +1161,6 @@ static int wm8997_probe(struct platform_device *pdev)
+ 		regmap_update_bits(arizona->regmap, wm8997_digital_vu[i],
+ 				   WM8997_DIG_VU, WM8997_DIG_VU);
+ 
+-	pm_runtime_enable(&pdev->dev);
+-	pm_runtime_idle(&pdev->dev);
+-
+ 	arizona_init_common(arizona);
+ 
+ 	ret = arizona_init_vol_limit(arizona);
+@@ -1182,6 +1179,9 @@ static int wm8997_probe(struct platform_device *pdev)
+ 		goto err_spk_irqs;
+ 	}
+ 
++	pm_runtime_enable(&pdev->dev);
++	pm_runtime_idle(&pdev->dev);
++
+ 	return ret;
+ 
+ err_spk_irqs:
+diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
+index cfaa45ede916a..8a2e9771bb50e 100644
+--- a/sound/soc/codecs/wm_adsp.c
++++ b/sound/soc/codecs/wm_adsp.c
+@@ -1602,7 +1602,9 @@ static int wm_adsp_buffer_init(struct wm_adsp *dsp)
+ 	if (list_empty(&dsp->buffer_list)) {
+ 		/* Fall back to legacy support */
+ 		ret = wm_adsp_buffer_parse_legacy(dsp);
+-		if (ret)
++		if (ret == -ENODEV)
++			adsp_info(dsp, "Legacy support not available\n");
++		else if (ret)
+ 			adsp_warn(dsp, "Failed to parse legacy: %d\n", ret);
+ 	}
+ 
+diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
+index 8b61582753c86..9af4c4a35eb16 100644
+--- a/sound/soc/fsl/eukrea-tlv320.c
++++ b/sound/soc/fsl/eukrea-tlv320.c
+@@ -86,7 +86,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
+ 	int ret;
+ 	int int_port = 0, ext_port;
+ 	struct device_node *np = pdev->dev.of_node;
+-	struct device_node *ssi_np = NULL, *codec_np = NULL;
++	struct device_node *ssi_np = NULL, *codec_np = NULL, *tmp_np = NULL;
+ 
+ 	eukrea_tlv320.dev = &pdev->dev;
+ 	if (np) {
+@@ -143,7 +143,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	if (machine_is_eukrea_cpuimx27() ||
+-	    of_find_compatible_node(NULL, NULL, "fsl,imx21-audmux")) {
++	    (tmp_np = of_find_compatible_node(NULL, NULL, "fsl,imx21-audmux"))) {
+ 		imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
+ 			IMX_AUDMUX_V1_PCR_SYN |
+ 			IMX_AUDMUX_V1_PCR_TFSDIR |
+@@ -158,10 +158,11 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
+ 			IMX_AUDMUX_V1_PCR_SYN |
+ 			IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
+ 		);
++		of_node_put(tmp_np);
+ 	} else if (machine_is_eukrea_cpuimx25sd() ||
+ 		   machine_is_eukrea_cpuimx35sd() ||
+ 		   machine_is_eukrea_cpuimx51sd() ||
+-		   of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux")) {
++		   (tmp_np = of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux"))) {
+ 		if (!np)
+ 			ext_port = machine_is_eukrea_cpuimx25sd() ?
+ 				4 : 3;
+@@ -178,6 +179,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
+ 			IMX_AUDMUX_V2_PTCR_SYN,
+ 			IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)
+ 		);
++		of_node_put(tmp_np);
+ 	} else {
+ 		if (np) {
+ 			/* The eukrea,asoc-tlv320 driver was explicitly
+diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359.c b/sound/soc/mediatek/mt8195/mt8195-mt6359.c
+index c530e3fc27e43..961e769602d6a 100644
+--- a/sound/soc/mediatek/mt8195/mt8195-mt6359.c
++++ b/sound/soc/mediatek/mt8195/mt8195-mt6359.c
+@@ -1383,7 +1383,13 @@ static int mt8195_mt6359_dev_probe(struct platform_device *pdev)
+ 		sof_priv->num_streams = ARRAY_SIZE(g_sof_conn_streams);
+ 		sof_priv->sof_dai_link_fixup = mt8195_dai_link_fixup;
+ 		soc_card_data->sof_priv = sof_priv;
++		card->probe = mtk_sof_card_probe;
+ 		card->late_probe = mtk_sof_card_late_probe;
++		if (!card->topology_shortname_created) {
++			snprintf(card->topology_shortname, 32, "sof-%s", card->name);
++			card->topology_shortname_created = true;
++		}
++		card->name = card->topology_shortname;
+ 		sof_on = 1;
+ 	}
+ 
+diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
+index f5f3540a9e186..a8758ad68442d 100644
+--- a/sound/soc/rockchip/rockchip_i2s.c
++++ b/sound/soc/rockchip/rockchip_i2s.c
+@@ -126,7 +126,6 @@ static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai)
+ static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
+ {
+ 	unsigned int val = 0;
+-	int retry = 10;
+ 	int ret = 0;
+ 
+ 	spin_lock(&i2s->lock);
+@@ -163,18 +162,14 @@ static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
+ 						 I2S_CLR_TXC | I2S_CLR_RXC);
+ 			if (ret < 0)
+ 				goto end;
+-			regmap_read(i2s->regmap, I2S_CLR, &val);
+-
+-			/* Should wait for clear operation to finish */
+-			while (val) {
+-				regmap_read(i2s->regmap, I2S_CLR, &val);
+-				retry--;
+-				if (!retry) {
+-					dev_warn(i2s->dev, "fail to clear\n");
+-					ret = -EBUSY;
+-					break;
+-				}
+-			}
++			ret = regmap_read_poll_timeout_atomic(i2s->regmap,
++							      I2S_CLR,
++							      val,
++							      val == 0,
++							      20,
++							      200);
++			if (ret < 0)
++				dev_warn(i2s->dev, "fail to clear: %d\n", ret);
+ 		}
+ 	}
+ end:
+@@ -188,7 +183,6 @@ end:
+ static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
+ {
+ 	unsigned int val = 0;
+-	int retry = 10;
+ 	int ret = 0;
+ 
+ 	spin_lock(&i2s->lock);
+@@ -226,17 +220,14 @@ static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
+ 						 I2S_CLR_TXC | I2S_CLR_RXC);
+ 			if (ret < 0)
+ 				goto end;
+-			regmap_read(i2s->regmap, I2S_CLR, &val);
+-			/* Should wait for clear operation to finish */
+-			while (val) {
+-				regmap_read(i2s->regmap, I2S_CLR, &val);
+-				retry--;
+-				if (!retry) {
+-					dev_warn(i2s->dev, "fail to clear\n");
+-					ret = -EBUSY;
+-					break;
+-				}
+-			}
++			ret = regmap_read_poll_timeout_atomic(i2s->regmap,
++							      I2S_CLR,
++							      val,
++							      val == 0,
++							      20,
++							      200);
++			if (ret < 0)
++				dev_warn(i2s->dev, "fail to clear: %d\n", ret);
+ 		}
+ 	}
+ end:
+diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c
+index 6156445bcb69a..e39eb2ac7e955 100644
+--- a/sound/soc/sh/rcar/ctu.c
++++ b/sound/soc/sh/rcar/ctu.c
+@@ -171,7 +171,11 @@ static int rsnd_ctu_init(struct rsnd_mod *mod,
+ 			 struct rsnd_dai_stream *io,
+ 			 struct rsnd_priv *priv)
+ {
+-	rsnd_mod_power_on(mod);
++	int ret;
++
++	ret = rsnd_mod_power_on(mod);
++	if (ret < 0)
++		return ret;
+ 
+ 	rsnd_ctu_activation(mod);
+ 
+diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
+index 5137e03a9d7c7..16befcbc312cb 100644
+--- a/sound/soc/sh/rcar/dvc.c
++++ b/sound/soc/sh/rcar/dvc.c
+@@ -186,7 +186,11 @@ static int rsnd_dvc_init(struct rsnd_mod *mod,
+ 			 struct rsnd_dai_stream *io,
+ 			 struct rsnd_priv *priv)
+ {
+-	rsnd_mod_power_on(mod);
++	int ret;
++
++	ret = rsnd_mod_power_on(mod);
++	if (ret < 0)
++		return ret;
+ 
+ 	rsnd_dvc_activation(mod);
+ 
+diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c
+index 3572c2c5686c7..1de0e085804cc 100644
+--- a/sound/soc/sh/rcar/mix.c
++++ b/sound/soc/sh/rcar/mix.c
+@@ -146,7 +146,11 @@ static int rsnd_mix_init(struct rsnd_mod *mod,
+ 			 struct rsnd_dai_stream *io,
+ 			 struct rsnd_priv *priv)
+ {
+-	rsnd_mod_power_on(mod);
++	int ret;
++
++	ret = rsnd_mod_power_on(mod);
++	if (ret < 0)
++		return ret;
+ 
+ 	rsnd_mix_activation(mod);
+ 
+diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
+index 0ea84ae57c6ac..f832165e46bc0 100644
+--- a/sound/soc/sh/rcar/src.c
++++ b/sound/soc/sh/rcar/src.c
+@@ -463,11 +463,14 @@ static int rsnd_src_init(struct rsnd_mod *mod,
+ 			 struct rsnd_priv *priv)
+ {
+ 	struct rsnd_src *src = rsnd_mod_to_src(mod);
++	int ret;
+ 
+ 	/* reset sync convert_rate */
+ 	src->sync.val = 0;
+ 
+-	rsnd_mod_power_on(mod);
++	ret = rsnd_mod_power_on(mod);
++	if (ret < 0)
++		return ret;
+ 
+ 	rsnd_src_activation(mod);
+ 
+diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
+index 43c5e27dc5c86..7ade6c5ed96ff 100644
+--- a/sound/soc/sh/rcar/ssi.c
++++ b/sound/soc/sh/rcar/ssi.c
+@@ -480,7 +480,9 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
+ 
+ 	ssi->usrcnt++;
+ 
+-	rsnd_mod_power_on(mod);
++	ret = rsnd_mod_power_on(mod);
++	if (ret < 0)
++		return ret;
+ 
+ 	rsnd_ssi_config_init(mod, io);
+ 
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index 4f60c0a833110..4d9b91e7e14f1 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -723,7 +723,7 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
+ 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
+ 
+ 	snd_soc_dpcm_mutex_lock(rtd);
+-	soc_pcm_clean(rtd, substream, 0);
++	__soc_pcm_close(rtd, substream);
+ 	snd_soc_dpcm_mutex_unlock(rtd);
+ 	return 0;
+ }
+diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
+index 6d4ecbe14adf3..ada2e67757494 100644
+--- a/sound/soc/sof/intel/hda.c
++++ b/sound/soc/sof/intel/hda.c
+@@ -376,6 +376,10 @@ static int dmic_num_override = -1;
+ module_param_named(dmic_num, dmic_num_override, int, 0444);
+ MODULE_PARM_DESC(dmic_num, "SOF HDA DMIC number");
+ 
++static int mclk_id_override = -1;
++module_param_named(mclk_id, mclk_id_override, int, 0444);
++MODULE_PARM_DESC(mclk_id, "SOF SSP mclk_id");
++
+ #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
+ static bool hda_codec_use_common_hdmi = IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI);
+ module_param_named(use_common_hdmi, hda_codec_use_common_hdmi, bool, 0444);
+@@ -1565,6 +1569,13 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
+ 
+ 			sof_pdata->tplg_filename = tplg_filename;
+ 		}
++
++		/* check if mclk_id should be modified from topology defaults */
++		if (mclk_id_override >= 0) {
++			dev_info(sdev->dev, "Overriding topology with MCLK %d from kernel_parameter\n", mclk_id_override);
++			sdev->mclk_id_override = true;
++			sdev->mclk_id_quirk = mclk_id_override;
++		}
+ 	}
+ 
+ 	/*
+diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c
+index 65923e7a5976f..a39b43850f0ed 100644
+--- a/sound/soc/sof/ipc3-topology.c
++++ b/sound/soc/sof/ipc3-topology.c
+@@ -1249,6 +1249,7 @@ static int sof_link_afe_load(struct snd_soc_component *scomp, struct snd_sof_dai
+ static int sof_link_ssp_load(struct snd_soc_component *scomp, struct snd_sof_dai_link *slink,
+ 			     struct sof_ipc_dai_config *config, struct snd_sof_dai *dai)
+ {
++	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
+ 	struct snd_soc_tplg_hw_config *hw_config = slink->hw_configs;
+ 	struct sof_dai_private_data *private = dai->private;
+ 	u32 size = sizeof(*config);
+@@ -1273,6 +1274,12 @@ static int sof_link_ssp_load(struct snd_soc_component *scomp, struct snd_sof_dai
+ 
+ 		config[i].hdr.size = size;
+ 
++		if (sdev->mclk_id_override) {
++			dev_dbg(scomp->dev, "tplg: overriding topology mclk_id %d by quirk %d\n",
++				config[i].ssp.mclk_id, sdev->mclk_id_quirk);
++			config[i].ssp.mclk_id = sdev->mclk_id_quirk;
++		}
++
+ 		/* copy differentiating hw configs to ipc structs */
+ 		config[i].ssp.mclk_rate = le32_to_cpu(hw_config[i].mclk_rate);
+ 		config[i].ssp.bclk_rate = le32_to_cpu(hw_config[i].bclk_rate);
+diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
+index 64929dc9af397..340d92452d7c2 100644
+--- a/sound/soc/sof/ipc4-topology.c
++++ b/sound/soc/sof/ipc4-topology.c
+@@ -1544,9 +1544,16 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
+ 	msg->data_ptr = ipc_data;
+ 
+ 	ret = sof_ipc_tx_message(sdev->ipc, msg, ipc_size, NULL, 0);
+-	if (ret < 0)
++	if (ret < 0) {
+ 		dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name);
+ 
++		if (swidget->id != snd_soc_dapm_scheduler) {
++			struct sof_ipc4_fw_module *fw_module = swidget->module_info;
++
++			ida_free(&fw_module->m_ida, swidget->instance_id);
++		}
++	}
++
+ 	return ret;
+ }
+ 
+diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c
+index 9c146015cd1b7..ff575de7e46a4 100644
+--- a/sound/soc/sof/mediatek/mt8195/mt8195.c
++++ b/sound/soc/sof/mediatek/mt8195/mt8195.c
+@@ -652,4 +652,5 @@ static struct platform_driver snd_sof_of_mt8195_driver = {
+ module_platform_driver(snd_sof_of_mt8195_driver);
+ 
+ MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
++MODULE_IMPORT_NS(SND_SOC_SOF_MTK_COMMON);
+ MODULE_LICENSE("Dual BSD/GPL");
+diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
+index d627092b399d7..643fd1036d60b 100644
+--- a/sound/soc/sof/sof-pci-dev.c
++++ b/sound/soc/sof/sof-pci-dev.c
+@@ -138,7 +138,7 @@ static const struct dmi_system_id community_key_platforms[] = {
+ 		.ident = "Google Chromebooks",
+ 		.callback = chromebook_use_community_key,
+ 		.matches = {
+-			DMI_MATCH(DMI_SYS_VENDOR, "Google"),
++			DMI_MATCH(DMI_PRODUCT_FAMILY, "Google"),
+ 		}
+ 	},
+ 	{},
+diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
+index 823583086279b..828c74bb75f89 100644
+--- a/sound/soc/sof/sof-priv.h
++++ b/sound/soc/sof/sof-priv.h
+@@ -594,6 +594,10 @@ struct snd_sof_dev {
+ 	/* to protect the ipc_rx_handler_list  and  dsp_state_handler_list list */
+ 	struct mutex client_event_handler_mutex;
+ 
++	/* quirks to override topology values */
++	bool mclk_id_override;
++	u16  mclk_id_quirk; /* same size as in IPC3 definitions */
++
+ 	void *private;			/* core does not touch this */
+ };
+ 
+diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
+index 04f2912e14181..643fc8a170184 100644
+--- a/sound/soc/stm/stm32_adfsdm.c
++++ b/sound/soc/stm/stm32_adfsdm.c
+@@ -335,8 +335,6 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
+ 
+ 	dev_set_drvdata(&pdev->dev, priv);
+ 
+-	pm_runtime_enable(&pdev->dev);
+-
+ 	ret = devm_snd_soc_register_component(&pdev->dev,
+ 					      &stm32_adfsdm_dai_component,
+ 					      &priv->dai_drv, 1);
+@@ -366,9 +364,13 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
+ #endif
+ 
+ 	ret = snd_soc_add_component(component, NULL, 0);
+-	if (ret < 0)
++	if (ret < 0) {
+ 		dev_err(&pdev->dev, "%s: Failed to register PCM platform\n",
+ 			__func__);
++		return ret;
++	}
++
++	pm_runtime_enable(&pdev->dev);
+ 
+ 	return ret;
+ }
+diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c
+index 6aafe793eec44..ce7f6942308f9 100644
+--- a/sound/soc/stm/stm32_i2s.c
++++ b/sound/soc/stm/stm32_i2s.c
+@@ -1136,8 +1136,6 @@ static int stm32_i2s_probe(struct platform_device *pdev)
+ 		return dev_err_probe(&pdev->dev, PTR_ERR(i2s->regmap),
+ 				     "Regmap init error\n");
+ 
+-	pm_runtime_enable(&pdev->dev);
+-
+ 	ret = snd_dmaengine_pcm_register(&pdev->dev, &stm32_i2s_pcm_config, 0);
+ 	if (ret)
+ 		return dev_err_probe(&pdev->dev, ret, "PCM DMA register error\n");
+@@ -1180,6 +1178,8 @@ static int stm32_i2s_probe(struct platform_device *pdev)
+ 			FIELD_GET(I2S_VERR_MIN_MASK, val));
+ 	}
+ 
++	pm_runtime_enable(&pdev->dev);
++
+ 	return ret;
+ 
+ error:
+diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c
+index 0f71467567176..d399c906bb921 100644
+--- a/sound/soc/stm/stm32_spdifrx.c
++++ b/sound/soc/stm/stm32_spdifrx.c
+@@ -1002,8 +1002,6 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
+ 	udelay(2);
+ 	reset_control_deassert(rst);
+ 
+-	pm_runtime_enable(&pdev->dev);
+-
+ 	pcm_config = &stm32_spdifrx_pcm_config;
+ 	ret = snd_dmaengine_pcm_register(&pdev->dev, pcm_config, 0);
+ 	if (ret)
+@@ -1036,6 +1034,8 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
+ 			FIELD_GET(SPDIFRX_VERR_MIN_MASK, ver));
+ 	}
+ 
++	pm_runtime_enable(&pdev->dev);
++
+ 	return ret;
+ 
+ error:
+diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
+index 830beb38bf156..fdf3165acd700 100644
+--- a/sound/soc/sunxi/sun4i-codec.c
++++ b/sound/soc/sunxi/sun4i-codec.c
+@@ -1232,6 +1232,9 @@ static const struct snd_soc_component_driver sun8i_a23_codec_codec = {
+ static const struct snd_soc_component_driver sun4i_codec_component = {
+ 	.name			= "sun4i-codec",
+ 	.legacy_dai_naming	= 1,
++#ifdef CONFIG_DEBUG_FS
++	.debugfs_prefix		= "cpu",
++#endif
+ };
+ 
+ #define SUN4I_CODEC_RATES	SNDRV_PCM_RATE_CONTINUOUS
+diff --git a/sound/usb/card.c b/sound/usb/card.c
+index 706d249a9ad6b..a5ed11ea11456 100644
+--- a/sound/usb/card.c
++++ b/sound/usb/card.c
+@@ -690,7 +690,7 @@ static bool get_alias_id(struct usb_device *dev, unsigned int *id)
+ 	return false;
+ }
+ 
+-static bool check_delayed_register_option(struct snd_usb_audio *chip, int iface)
++static int check_delayed_register_option(struct snd_usb_audio *chip)
+ {
+ 	int i;
+ 	unsigned int id, inum;
+@@ -699,14 +699,31 @@ static bool check_delayed_register_option(struct snd_usb_audio *chip, int iface)
+ 		if (delayed_register[i] &&
+ 		    sscanf(delayed_register[i], "%x:%x", &id, &inum) == 2 &&
+ 		    id == chip->usb_id)
+-			return iface < inum;
++			return inum;
+ 	}
+ 
+-	return false;
++	return -1;
+ }
+ 
+ static const struct usb_device_id usb_audio_ids[]; /* defined below */
+ 
++/* look for the last interface that matches with our ids and remember it */
++static void find_last_interface(struct snd_usb_audio *chip)
++{
++	struct usb_host_config *config = chip->dev->actconfig;
++	struct usb_interface *intf;
++	int i;
++
++	if (!config)
++		return;
++	for (i = 0; i < config->desc.bNumInterfaces; i++) {
++		intf = config->interface[i];
++		if (usb_match_id(intf, usb_audio_ids))
++			chip->last_iface = intf->altsetting[0].desc.bInterfaceNumber;
++	}
++	usb_audio_dbg(chip, "Found last interface = %d\n", chip->last_iface);
++}
++
+ /* look for the corresponding quirk */
+ static const struct snd_usb_audio_quirk *
+ get_alias_quirk(struct usb_device *dev, unsigned int id)
+@@ -813,6 +830,7 @@ static int usb_audio_probe(struct usb_interface *intf,
+ 			err = -ENODEV;
+ 			goto __error;
+ 		}
++		find_last_interface(chip);
+ 	}
+ 
+ 	if (chip->num_interfaces >= MAX_CARD_INTERFACES) {
+@@ -862,11 +880,11 @@ static int usb_audio_probe(struct usb_interface *intf,
+ 		chip->need_delayed_register = false; /* clear again */
+ 	}
+ 
+-	/* we are allowed to call snd_card_register() many times, but first
+-	 * check to see if a device needs to skip it or do anything special
++	/* register card if we reach to the last interface or to the specified
++	 * one given via option
+ 	 */
+-	if (!snd_usb_registration_quirk(chip, ifnum) &&
+-	    !check_delayed_register_option(chip, ifnum)) {
++	if (check_delayed_register_option(chip) == ifnum ||
++	    usb_interface_claimed(usb_ifnum_to_if(dev, chip->last_iface))) {
+ 		err = snd_card_register(chip->card);
+ 		if (err < 0)
+ 			goto __error;
+diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
+index eb71df9da831a..2420dc994632a 100644
+--- a/sound/usb/endpoint.c
++++ b/sound/usb/endpoint.c
+@@ -39,6 +39,7 @@ struct snd_usb_iface_ref {
+ struct snd_usb_clock_ref {
+ 	unsigned char clock;
+ 	atomic_t locked;
++	int opened;
+ 	int rate;
+ 	struct list_head list;
+ };
+@@ -93,12 +94,13 @@ static inline unsigned get_usb_high_speed_rate(unsigned int rate)
+  */
+ static void release_urb_ctx(struct snd_urb_ctx *u)
+ {
+-	if (u->buffer_size)
++	if (u->urb && u->buffer_size)
+ 		usb_free_coherent(u->ep->chip->dev, u->buffer_size,
+ 				  u->urb->transfer_buffer,
+ 				  u->urb->transfer_dma);
+ 	usb_free_urb(u->urb);
+ 	u->urb = NULL;
++	u->buffer_size = 0;
+ }
+ 
+ static const char *usb_error_string(int err)
+@@ -801,6 +803,7 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip,
+ 				ep = NULL;
+ 				goto unlock;
+ 			}
++			ep->clock_ref->opened++;
+ 		}
+ 
+ 		ep->cur_audiofmt = fp;
+@@ -924,8 +927,10 @@ void snd_usb_endpoint_close(struct snd_usb_audio *chip,
+ 		endpoint_set_interface(chip, ep, false);
+ 
+ 	if (!--ep->opened) {
+-		if (ep->clock_ref && !atomic_read(&ep->clock_ref->locked))
+-			ep->clock_ref->rate = 0;
++		if (ep->clock_ref) {
++			if (!--ep->clock_ref->opened)
++				ep->clock_ref->rate = 0;
++		}
+ 		ep->iface = 0;
+ 		ep->altsetting = 0;
+ 		ep->cur_audiofmt = NULL;
+@@ -1261,6 +1266,7 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep)
+ 	if (!ep->syncbuf)
+ 		return -ENOMEM;
+ 
++	ep->nurbs = SYNC_URBS;
+ 	for (i = 0; i < SYNC_URBS; i++) {
+ 		struct snd_urb_ctx *u = &ep->urb[i];
+ 		u->index = i;
+@@ -1280,8 +1286,6 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep)
+ 		u->urb->complete = snd_complete_urb;
+ 	}
+ 
+-	ep->nurbs = SYNC_URBS;
+-
+ 	return 0;
+ 
+ out_of_memory:
+@@ -1633,8 +1637,7 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, bool keep_pending)
+ 			WRITE_ONCE(ep->sync_source->sync_sink, NULL);
+ 		stop_urbs(ep, false, keep_pending);
+ 		if (ep->clock_ref)
+-			if (!atomic_dec_return(&ep->clock_ref->locked))
+-				ep->clock_ref->rate = 0;
++			atomic_dec(&ep->clock_ref->locked);
+ 	}
+ }
+ 
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index f93201a830b5a..06dfdd45cff8c 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -2985,6 +2985,82 @@ YAMAHA_DEVICE(0x7010, "UB99"),
+ 		}
+ 	}
+ },
++/* DIGIDESIGN MBOX 3 */
++{
++	USB_DEVICE(0x0dba, 0x5000),
++	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
++		.vendor_name = "Digidesign",
++		.product_name = "Mbox 3",
++		.ifnum = QUIRK_ANY_INTERFACE,
++		.type = QUIRK_COMPOSITE,
++		.data = (const struct snd_usb_audio_quirk[]) {
++			{
++				.ifnum = 0,
++				.type = QUIRK_IGNORE_INTERFACE
++			},
++			{
++				.ifnum = 1,
++				.type = QUIRK_IGNORE_INTERFACE
++			},
++			{
++				.ifnum = 2,
++				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
++				.data = &(const struct audioformat) {
++					.formats = SNDRV_PCM_FMTBIT_S24_3LE,
++					.channels = 4,
++					.iface = 2,
++					.altsetting = 1,
++					.altset_idx = 1,
++					.attributes = 0x00,
++					.endpoint = 0x01,
++					.ep_attr = USB_ENDPOINT_XFER_ISOC |
++						USB_ENDPOINT_SYNC_ASYNC,
++					.rates = SNDRV_PCM_RATE_48000,
++					.rate_min = 48000,
++					.rate_max = 48000,
++					.nr_rates = 1,
++					.rate_table = (unsigned int[]) {
++						48000
++					}
++				}
++			},
++			{
++				.ifnum = 3,
++				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
++				.data = &(const struct audioformat) {
++					.formats = SNDRV_PCM_FMTBIT_S24_3LE,
++					.channels = 4,
++					.iface = 3,
++					.altsetting = 1,
++					.altset_idx = 1,
++					.endpoint = 0x81,
++					.attributes = 0x00,
++					.ep_attr = USB_ENDPOINT_XFER_ISOC |
++						USB_ENDPOINT_SYNC_ASYNC,
++					.maxpacksize = 0x009c,
++					.rates = SNDRV_PCM_RATE_48000,
++					.rate_min = 48000,
++					.rate_max = 48000,
++					.nr_rates = 1,
++					.rate_table = (unsigned int[]) {
++						48000
++					}
++				}
++			},
++			{
++				.ifnum = 4,
++				.type = QUIRK_MIDI_FIXED_ENDPOINT,
++				.data = &(const struct snd_usb_midi_endpoint_info) {
++					.out_cables = 0x0001,
++					.in_cables  = 0x0001
++				}
++			},
++			{
++				.ifnum = -1
++			}
++		}
++	}
++},
+ {
+ 	/* Tascam US122 MKII - playback-only support */
+ 	USB_DEVICE_VENDOR_SPEC(0x0644, 0x8021),
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index 5b4d8f5eade20..eadac586bcc83 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1020,6 +1020,304 @@ static int snd_usb_axefx3_boot_quirk(struct usb_device *dev)
+ 	return 0;
+ }
+ 
++static void mbox3_setup_48_24_magic(struct usb_device *dev)
++{
++	/* The Mbox 3 is "little endian" */
++	/* max volume is: 0x0000. */
++	/* min volume is: 0x0080 (shown in little endian form) */
++
++
++	/* Load 48000Hz rate into buffer */
++	u8 com_buff[4] = {0x80, 0xbb, 0x00, 0x00};
++
++	/* Set 48000Hz sample rate */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			0x01, 0x21, 0x0100, 0x0001, &com_buff, 4);  //Is this really needed?
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			0x01, 0x21, 0x0100, 0x8101, &com_buff, 4);
++
++	/* Deactivate Tuner */
++	/* on  = 0x01*/
++	/* off = 0x00*/
++	com_buff[0] = 0x00;
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++		0x01, 0x21, 0x0003, 0x2001, &com_buff, 1);
++
++	/* Set clock source to Internal (as opposed to S/PDIF) */
++	com_buff[0] = 0x01;
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0100, 0x8001, &com_buff, 1);
++
++	/* Mute the hardware loopbacks to start the device in a known state. */
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x80;
++	/* Analogue input 1 left channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0110, 0x4001, &com_buff, 2);
++	/* Analogue input 1 right channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0111, 0x4001, &com_buff, 2);
++	/* Analogue input 2 left channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0114, 0x4001, &com_buff, 2);
++	/* Analogue input 2 right channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0115, 0x4001, &com_buff, 2);
++	/* Analogue input 3 left channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0118, 0x4001, &com_buff, 2);
++	/* Analogue input 3 right channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0119, 0x4001, &com_buff, 2);
++	/* Analogue input 4 left channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x011c, 0x4001, &com_buff, 2);
++	/* Analogue input 4 right channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x011d, 0x4001, &com_buff, 2);
++
++	/* Set software sends to output */
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x00;
++	/* Analogue software return 1 left channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0100, 0x4001, &com_buff, 2);
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x80;
++	/* Analogue software return 1 right channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0101, 0x4001, &com_buff, 2);
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x80;
++	/* Analogue software return 2 left channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0104, 0x4001, &com_buff, 2);
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x00;
++	/* Analogue software return 2 right channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0105, 0x4001, &com_buff, 2);
++
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x80;
++	/* Analogue software return 3 left channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0108, 0x4001, &com_buff, 2);
++	/* Analogue software return 3 right channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0109, 0x4001, &com_buff, 2);
++	/* Analogue software return 4 left channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x010c, 0x4001, &com_buff, 2);
++	/* Analogue software return 4 right channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x010d, 0x4001, &com_buff, 2);
++
++	/* Return to muting sends */
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x80;
++	/* Analogue fx return left channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0120, 0x4001, &com_buff, 2);
++	/* Analogue fx return right channel: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0121, 0x4001, &com_buff, 2);
++
++	/* Analogue software input 1 fx send: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0100, 0x4201, &com_buff, 2);
++	/* Analogue software input 2 fx send: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0101, 0x4201, &com_buff, 2);
++	/* Analogue software input 3 fx send: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0102, 0x4201, &com_buff, 2);
++	/* Analogue software input 4 fx send: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0103, 0x4201, &com_buff, 2);
++	/* Analogue input 1 fx send: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0104, 0x4201, &com_buff, 2);
++	/* Analogue input 2 fx send: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0105, 0x4201, &com_buff, 2);
++	/* Analogue input 3 fx send: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0106, 0x4201, &com_buff, 2);
++	/* Analogue input 4 fx send: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0107, 0x4201, &com_buff, 2);
++
++	/* Toggle allowing host control */
++	com_buff[0] = 0x02;
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			3, 0x21, 0x0000, 0x2001, &com_buff, 1);
++
++	/* Do not dim fx returns */
++	com_buff[0] = 0x00;
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			3, 0x21, 0x0002, 0x2001, &com_buff, 1);
++
++	/* Do not set fx returns to mono */
++	com_buff[0] = 0x00;
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			3, 0x21, 0x0001, 0x2001, &com_buff, 1);
++
++	/* Mute the S/PDIF hardware loopback
++	 * same odd volume logic here as above
++	 */
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x80;
++	/* S/PDIF hardware input 1 left channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0112, 0x4001, &com_buff, 2);
++	/* S/PDIF hardware input 1 right channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0113, 0x4001, &com_buff, 2);
++	/* S/PDIF hardware input 2 left channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0116, 0x4001, &com_buff, 2);
++	/* S/PDIF hardware input 2 right channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0117, 0x4001, &com_buff, 2);
++	/* S/PDIF hardware input 3 left channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x011a, 0x4001, &com_buff, 2);
++	/* S/PDIF hardware input 3 right channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x011b, 0x4001, &com_buff, 2);
++	/* S/PDIF hardware input 4 left channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x011e, 0x4001, &com_buff, 2);
++	/* S/PDIF hardware input 4 right channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x011f, 0x4001, &com_buff, 2);
++	/* S/PDIF software return 1 left channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0102, 0x4001, &com_buff, 2);
++	/* S/PDIF software return 1 right channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0103, 0x4001, &com_buff, 2);
++	/* S/PDIF software return 2 left channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0106, 0x4001, &com_buff, 2);
++	/* S/PDIF software return 2 right channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0107, 0x4001, &com_buff, 2);
++
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x00;
++	/* S/PDIF software return 3 left channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x010a, 0x4001, &com_buff, 2);
++
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x80;
++	/* S/PDIF software return 3 right channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x010b, 0x4001, &com_buff, 2);
++	/* S/PDIF software return 4 left channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x010e, 0x4001, &com_buff, 2);
++
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x00;
++	/* S/PDIF software return 4 right channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x010f, 0x4001, &com_buff, 2);
++
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x80;
++	/* S/PDIF fx returns left channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0122, 0x4001, &com_buff, 2);
++	/* S/PDIF fx returns right channel */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0123, 0x4001, &com_buff, 2);
++
++	/* Set the dropdown "Effect" to the first option */
++	/* Room1  = 0x00 */
++	/* Room2  = 0x01 */
++	/* Room3  = 0x02 */
++	/* Hall 1 = 0x03 */
++	/* Hall 2 = 0x04 */
++	/* Plate  = 0x05 */
++	/* Delay  = 0x06 */
++	/* Echo   = 0x07 */
++	com_buff[0] = 0x00;
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0200, 0x4301, &com_buff, 1);	/* max is 0xff */
++	/* min is 0x00 */
++
++
++	/* Set the effect duration to 0 */
++	/* max is 0xffff */
++	/* min is 0x0000 */
++	com_buff[0] = 0x00;
++	com_buff[1] = 0x00;
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0400, 0x4301, &com_buff, 2);
++
++	/* Set the effect volume and feedback to 0 */
++	/* max is 0xff */
++	/* min is 0x00 */
++	com_buff[0] = 0x00;
++	/* feedback: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0500, 0x4301, &com_buff, 1);
++	/* volume: */
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			1, 0x21, 0x0300, 0x4301, &com_buff, 1);
++
++	/* Set soft button hold duration */
++	/* 0x03 = 250ms */
++	/* 0x05 = 500ms DEFAULT */
++	/* 0x08 = 750ms */
++	/* 0x0a = 1sec */
++	com_buff[0] = 0x05;
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			3, 0x21, 0x0005, 0x2001, &com_buff, 1);
++
++	/* Use dim LEDs for button of state */
++	com_buff[0] = 0x00;
++	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
++			3, 0x21, 0x0004, 0x2001, &com_buff, 1);
++}
++
++#define MBOX3_DESCRIPTOR_SIZE	464
++
++static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
++{
++	struct usb_host_config *config = dev->actconfig;
++	int err;
++	int descriptor_size;
++
++	descriptor_size = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
++
++	if (descriptor_size != MBOX3_DESCRIPTOR_SIZE) {
++		dev_err(&dev->dev, "Invalid descriptor size=%d.\n", descriptor_size);
++		return -ENODEV;
++	}
++
++	dev_dbg(&dev->dev, "device initialised!\n");
++
++	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
++		&dev->descriptor, sizeof(dev->descriptor));
++	config = dev->actconfig;
++	if (err < 0)
++		dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
++
++	err = usb_reset_configuration(dev);
++	if (err < 0)
++		dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
++	dev_dbg(&dev->dev, "mbox3_boot: new boot length = %d\n",
++		le16_to_cpu(get_cfg_desc(config)->wTotalLength));
++
++	mbox3_setup_48_24_magic(dev);
++	dev_info(&dev->dev, "Digidesign Mbox 3: 24bit 48kHz");
++
++	return 0; /* Successful boot */
++}
+ 
+ #define MICROBOOK_BUF_SIZE 128
+ 
+@@ -1324,6 +1622,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
+ 	case USB_ID(0x0dba, 0x3000):
+ 		/* Digidesign Mbox 2 */
+ 		return snd_usb_mbox2_boot_quirk(dev);
++	case USB_ID(0x0dba, 0x5000):
++		/* Digidesign Mbox 3 */
++		return snd_usb_mbox3_boot_quirk(dev);
++
+ 
+ 	case USB_ID(0x1235, 0x0010): /* Focusrite Novation Saffire 6 USB */
+ 	case USB_ID(0x1235, 0x0018): /* Focusrite Novation Twitch */
+@@ -1728,48 +2030,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
+ 	}
+ }
+ 
+-/*
+- * registration quirk:
+- * the registration is skipped if a device matches with the given ID,
+- * unless the interface reaches to the defined one.  This is for delaying
+- * the registration until the last known interface, so that the card and
+- * devices appear at the same time.
+- */
+-
+-struct registration_quirk {
+-	unsigned int usb_id;	/* composed via USB_ID() */
+-	unsigned int interface;	/* the interface to trigger register */
+-};
+-
+-#define REG_QUIRK_ENTRY(vendor, product, iface) \
+-	{ .usb_id = USB_ID(vendor, product), .interface = (iface) }
+-
+-static const struct registration_quirk registration_quirks[] = {
+-	REG_QUIRK_ENTRY(0x0951, 0x16d8, 2),	/* Kingston HyperX AMP */
+-	REG_QUIRK_ENTRY(0x0951, 0x16ed, 2),	/* Kingston HyperX Cloud Alpha S */
+-	REG_QUIRK_ENTRY(0x0951, 0x16ea, 2),	/* Kingston HyperX Cloud Flight S */
+-	REG_QUIRK_ENTRY(0x0ecb, 0x1f46, 2),	/* JBL Quantum 600 */
+-	REG_QUIRK_ENTRY(0x0ecb, 0x1f47, 2),	/* JBL Quantum 800 */
+-	REG_QUIRK_ENTRY(0x0ecb, 0x1f4c, 2),	/* JBL Quantum 400 */
+-	REG_QUIRK_ENTRY(0x0ecb, 0x2039, 2),	/* JBL Quantum 400 */
+-	REG_QUIRK_ENTRY(0x0ecb, 0x203c, 2),	/* JBL Quantum 600 */
+-	REG_QUIRK_ENTRY(0x0ecb, 0x203e, 2),	/* JBL Quantum 800 */
+-	{ 0 }					/* terminator */
+-};
+-
+-/* return true if skipping registration */
+-bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface)
+-{
+-	const struct registration_quirk *q;
+-
+-	for (q = registration_quirks; q->usb_id; q++)
+-		if (chip->usb_id == q->usb_id)
+-			return iface < q->interface;
+-
+-	/* Register as normal */
+-	return false;
+-}
+-
+ /*
+  * driver behavior quirk flags
+  */
+diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
+index 31abb7cb01a52..f9bfd5ac7bab0 100644
+--- a/sound/usb/quirks.h
++++ b/sound/usb/quirks.h
+@@ -48,8 +48,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
+ 					  struct audioformat *fp,
+ 					  int stream);
+ 
+-bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface);
+-
+ void snd_usb_init_quirk_flags(struct snd_usb_audio *chip);
+ 
+ #endif /* __USBAUDIO_QUIRKS_H */
+diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
+index ffbb4b0d09a07..2c6575029b1cd 100644
+--- a/sound/usb/usbaudio.h
++++ b/sound/usb/usbaudio.h
+@@ -37,6 +37,7 @@ struct snd_usb_audio {
+ 	unsigned int quirk_flags;
+ 	unsigned int need_delayed_register:1; /* warn for delayed registration */
+ 	int num_interfaces;
++	int last_iface;
+ 	int num_suspended_intf;
+ 	int sample_rate_read_error;
+ 
+diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
+index 125798b0bc5dd..19924b6ce796f 100644
+--- a/tools/bpf/bpftool/btf_dumper.c
++++ b/tools/bpf/bpftool/btf_dumper.c
+@@ -452,7 +452,7 @@ static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset,
+ 					     *(char *)data);
+ 		break;
+ 	case BTF_INT_BOOL:
+-		jsonw_bool(jw, *(int *)data);
++		jsonw_bool(jw, *(bool *)data);
+ 		break;
+ 	default:
+ 		/* shouldn't happen */
+diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c
+index cced668fb2a3c..b46a998d8f8df 100644
+--- a/tools/bpf/bpftool/cgroup.c
++++ b/tools/bpf/bpftool/cgroup.c
+@@ -136,8 +136,8 @@ static int show_bpf_prog(int id, enum bpf_attach_type attach_type,
+ 			jsonw_string_field(json_wtr, "attach_type", attach_type_str);
+ 		else
+ 			jsonw_uint_field(json_wtr, "attach_type", attach_type);
+-		jsonw_string_field(json_wtr, "attach_flags",
+-				   attach_flags_str);
++		if (!(query_flags & BPF_F_QUERY_EFFECTIVE))
++			jsonw_string_field(json_wtr, "attach_flags", attach_flags_str);
+ 		jsonw_string_field(json_wtr, "name", prog_name);
+ 		if (attach_btf_name)
+ 			jsonw_string_field(json_wtr, "attach_btf_name", attach_btf_name);
+@@ -150,7 +150,10 @@ static int show_bpf_prog(int id, enum bpf_attach_type attach_type,
+ 			printf("%-15s", attach_type_str);
+ 		else
+ 			printf("type %-10u", attach_type);
+-		printf(" %-15s %-15s", attach_flags_str, prog_name);
++		if (query_flags & BPF_F_QUERY_EFFECTIVE)
++			printf(" %-15s", prog_name);
++		else
++			printf(" %-15s %-15s", attach_flags_str, prog_name);
+ 		if (attach_btf_name)
+ 			printf(" %-15s", attach_btf_name);
+ 		else if (info.attach_btf_id)
+@@ -195,6 +198,32 @@ static int cgroup_has_attached_progs(int cgroup_fd)
+ 
+ 	return no_prog ? 0 : 1;
+ }
++
++static int show_effective_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
++				    int level)
++{
++	LIBBPF_OPTS(bpf_prog_query_opts, p);
++	__u32 prog_ids[1024] = {0};
++	__u32 iter;
++	int ret;
++
++	p.query_flags = query_flags;
++	p.prog_cnt = ARRAY_SIZE(prog_ids);
++	p.prog_ids = prog_ids;
++
++	ret = bpf_prog_query_opts(cgroup_fd, type, &p);
++	if (ret)
++		return ret;
++
++	if (p.prog_cnt == 0)
++		return 0;
++
++	for (iter = 0; iter < p.prog_cnt; iter++)
++		show_bpf_prog(prog_ids[iter], type, NULL, level);
++
++	return 0;
++}
++
+ static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
+ 				   int level)
+ {
+@@ -245,6 +274,14 @@ static int show_attached_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
+ 	return 0;
+ }
+ 
++static int show_bpf_progs(int cgroup_fd, enum bpf_attach_type type,
++			  int level)
++{
++	return query_flags & BPF_F_QUERY_EFFECTIVE ?
++	       show_effective_bpf_progs(cgroup_fd, type, level) :
++	       show_attached_bpf_progs(cgroup_fd, type, level);
++}
++
+ static int do_show(int argc, char **argv)
+ {
+ 	enum bpf_attach_type type;
+@@ -292,6 +329,8 @@ static int do_show(int argc, char **argv)
+ 
+ 	if (json_output)
+ 		jsonw_start_array(json_wtr);
++	else if (query_flags & BPF_F_QUERY_EFFECTIVE)
++		printf("%-8s %-15s %-15s\n", "ID", "AttachType", "Name");
+ 	else
+ 		printf("%-8s %-15s %-15s %-15s\n", "ID", "AttachType",
+ 		       "AttachFlags", "Name");
+@@ -304,7 +343,7 @@ static int do_show(int argc, char **argv)
+ 		 * If we were able to get the show for at least one
+ 		 * attach type, let's return 0.
+ 		 */
+-		if (show_attached_bpf_progs(cgroup_fd, type, 0) == 0)
++		if (show_bpf_progs(cgroup_fd, type, 0) == 0)
+ 			ret = 0;
+ 	}
+ 
+@@ -362,7 +401,7 @@ static int do_show_tree_fn(const char *fpath, const struct stat *sb,
+ 
+ 	btf_vmlinux = libbpf_find_kernel_btf();
+ 	for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++)
+-		show_attached_bpf_progs(cgroup_fd, type, ftw->level);
++		show_bpf_progs(cgroup_fd, type, ftw->level);
+ 
+ 	if (errno == EINVAL)
+ 		/* Last attach type does not support query.
+@@ -436,6 +475,11 @@ static int do_show_tree(int argc, char **argv)
+ 
+ 	if (json_output)
+ 		jsonw_start_array(json_wtr);
++	else if (query_flags & BPF_F_QUERY_EFFECTIVE)
++		printf("%s\n"
++		       "%-8s %-15s %-15s\n",
++		       "CgroupPath",
++		       "ID", "AttachType", "Name");
+ 	else
+ 		printf("%s\n"
+ 		       "%-8s %-15s %-15s %-15s\n",
+diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
+index 451cefc2d0da9..ccd7457f92bff 100644
+--- a/tools/bpf/bpftool/main.c
++++ b/tools/bpf/bpftool/main.c
+@@ -435,6 +435,16 @@ int main(int argc, char **argv)
+ 
+ 	setlinebuf(stdout);
+ 
++#ifdef USE_LIBCAP
++	/* Libcap < 2.63 hooks before main() to compute the number of
++	 * capabilities of the running kernel, and doing so it calls prctl()
++	 * which may fail and set errno to non-zero.
++	 * Let's reset errno to make sure this does not interfere with the
++	 * batch mode.
++	 */
++	errno = 0;
++#endif
++
+ 	last_do_help = do_help;
+ 	pretty_output = false;
+ 	json_output = false;
+diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
+index 59a217ca2dfd3..4eff7fc7ae586 100644
+--- a/tools/include/uapi/linux/bpf.h
++++ b/tools/include/uapi/linux/bpf.h
+@@ -1233,7 +1233,7 @@ enum {
+ 
+ /* Query effective (directly attached + inherited from ancestor cgroups)
+  * programs that will be executed for events within a cgroup.
+- * attach_flags with this flag are returned only for directly attached programs.
++ * attach_flags with this flag are always returned 0.
+  */
+ #define BPF_F_QUERY_EFFECTIVE	(1U << 0)
+ 
+@@ -1432,7 +1432,10 @@ union bpf_attr {
+ 		__u32		attach_flags;
+ 		__aligned_u64	prog_ids;
+ 		__u32		prog_cnt;
+-		__aligned_u64	prog_attach_flags; /* output: per-program attach_flags */
++		/* output: per-program attach_flags.
++		 * not allowed to be set during effective query.
++		 */
++		__aligned_u64	prog_attach_flags;
+ 	} query;
+ 
+ 	struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
+diff --git a/tools/lib/bpf/bpf_tracing.h b/tools/lib/bpf/bpf_tracing.h
+index 43ca3aff2292f..5fdb93da423b5 100644
+--- a/tools/lib/bpf/bpf_tracing.h
++++ b/tools/lib/bpf/bpf_tracing.h
+@@ -426,7 +426,7 @@ struct pt_regs;
+  */
+ #define BPF_PROG(name, args...)						    \
+ name(unsigned long long *ctx);						    \
+-static __attribute__((always_inline)) typeof(name(0))			    \
++static __always_inline typeof(name(0))					    \
+ ____##name(unsigned long long *ctx, ##args);				    \
+ typeof(name(0)) name(unsigned long long *ctx)				    \
+ {									    \
+@@ -435,7 +435,7 @@ typeof(name(0)) name(unsigned long long *ctx)				    \
+ 	return ____##name(___bpf_ctx_cast(args));			    \
+ 	_Pragma("GCC diagnostic pop")					    \
+ }									    \
+-static __attribute__((always_inline)) typeof(name(0))			    \
++static __always_inline typeof(name(0))					    \
+ ____##name(unsigned long long *ctx, ##args)
+ 
+ struct pt_regs;
+@@ -460,7 +460,7 @@ struct pt_regs;
+  */
+ #define BPF_KPROBE(name, args...)					    \
+ name(struct pt_regs *ctx);						    \
+-static __attribute__((always_inline)) typeof(name(0))			    \
++static __always_inline typeof(name(0))					    \
+ ____##name(struct pt_regs *ctx, ##args);				    \
+ typeof(name(0)) name(struct pt_regs *ctx)				    \
+ {									    \
+@@ -469,7 +469,7 @@ typeof(name(0)) name(struct pt_regs *ctx)				    \
+ 	return ____##name(___bpf_kprobe_args(args));			    \
+ 	_Pragma("GCC diagnostic pop")					    \
+ }									    \
+-static __attribute__((always_inline)) typeof(name(0))			    \
++static __always_inline typeof(name(0))					    \
+ ____##name(struct pt_regs *ctx, ##args)
+ 
+ #define ___bpf_kretprobe_args0()       ctx
+@@ -484,7 +484,7 @@ ____##name(struct pt_regs *ctx, ##args)
+  */
+ #define BPF_KRETPROBE(name, args...)					    \
+ name(struct pt_regs *ctx);						    \
+-static __attribute__((always_inline)) typeof(name(0))			    \
++static __always_inline typeof(name(0))					    \
+ ____##name(struct pt_regs *ctx, ##args);				    \
+ typeof(name(0)) name(struct pt_regs *ctx)				    \
+ {									    \
+@@ -540,7 +540,7 @@ static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args)
+ #define BPF_KSYSCALL(name, args...)					    \
+ name(struct pt_regs *ctx);						    \
+ extern _Bool LINUX_HAS_SYSCALL_WRAPPER __kconfig;			    \
+-static __attribute__((always_inline)) typeof(name(0))			    \
++static __always_inline typeof(name(0))					    \
+ ____##name(struct pt_regs *ctx, ##args);				    \
+ typeof(name(0)) name(struct pt_regs *ctx)				    \
+ {									    \
+@@ -555,7 +555,7 @@ typeof(name(0)) name(struct pt_regs *ctx)				    \
+ 		return ____##name(___bpf_syscall_args(args));		    \
+ 	_Pragma("GCC diagnostic pop")					    \
+ }									    \
+-static __attribute__((always_inline)) typeof(name(0))			    \
++static __always_inline typeof(name(0))					    \
+ ____##name(struct pt_regs *ctx, ##args)
+ 
+ #define BPF_KPROBE_SYSCALL BPF_KSYSCALL
+diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
+index 583760df83b42..d421d656a0765 100644
+--- a/tools/lib/bpf/btf.h
++++ b/tools/lib/bpf/btf.h
+@@ -487,6 +487,8 @@ static inline struct btf_enum *btf_enum(const struct btf_type *t)
+ 	return (struct btf_enum *)(t + 1);
+ }
+ 
++struct btf_enum64;
++
+ static inline struct btf_enum64 *btf_enum64(const struct btf_type *t)
+ {
+ 	return (struct btf_enum64 *)(t + 1);
+@@ -494,7 +496,28 @@ static inline struct btf_enum64 *btf_enum64(const struct btf_type *t)
+ 
+ static inline __u64 btf_enum64_value(const struct btf_enum64 *e)
+ {
+-	return ((__u64)e->val_hi32 << 32) | e->val_lo32;
++	/* struct btf_enum64 is introduced in Linux 6.0, which is very
++	 * bleeding-edge. Here we are avoiding relying on struct btf_enum64
++	 * definition coming from kernel UAPI headers to support wider range
++	 * of system-wide kernel headers.
++	 *
++	 * Given this header can be also included from C++ applications, that
++	 * further restricts C tricks we can use (like using compatible
++	 * anonymous struct). So just treat struct btf_enum64 as
++	 * a three-element array of u32 and access second (lo32) and third
++	 * (hi32) elements directly.
++	 *
++	 * For reference, here is a struct btf_enum64 definition:
++	 *
++	 * const struct btf_enum64 {
++	 *	__u32	name_off;
++	 *	__u32	val_lo32;
++	 *	__u32	val_hi32;
++	 * };
++	 */
++	const __u32 *e64 = (const __u32 *)e;
++
++	return ((__u64)e64[2] << 32) | e64[1];
+ }
+ 
+ static inline struct btf_member *btf_members(const struct btf_type *t)
+diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
+index 627edb5bb6def..4221f73a74d01 100644
+--- a/tools/lib/bpf/btf_dump.c
++++ b/tools/lib/bpf/btf_dump.c
+@@ -2385,7 +2385,7 @@ int btf_dump__dump_type_data(struct btf_dump *d, __u32 id,
+ 	d->typed_dump->indent_lvl = OPTS_GET(opts, indent_level, 0);
+ 
+ 	/* default indent string is a tab */
+-	if (!opts->indent_str)
++	if (!OPTS_GET(opts, indent_str, NULL))
+ 		d->typed_dump->indent_str[0] = '\t';
+ 	else
+ 		libbpf_strlcpy(d->typed_dump->indent_str, opts->indent_str,
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index 50d41815f431a..e36c44090720e 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -9056,11 +9056,15 @@ static int libbpf_find_attach_btf_id(struct bpf_program *prog, const char *attac
+ 	int err = 0;
+ 
+ 	/* BPF program's BTF ID */
+-	if (attach_prog_fd) {
++	if (prog->type == BPF_PROG_TYPE_EXT || attach_prog_fd) {
++		if (!attach_prog_fd) {
++			pr_warn("prog '%s': attach program FD is not set\n", prog->name);
++			return -EINVAL;
++		}
+ 		err = libbpf_find_prog_btf_id(attach_name, attach_prog_fd);
+ 		if (err < 0) {
+-			pr_warn("failed to find BPF program (FD %d) BTF ID for '%s': %d\n",
+-				 attach_prog_fd, attach_name, err);
++			pr_warn("prog '%s': failed to find BPF program (FD %d) BTF ID for '%s': %d\n",
++				 prog->name, attach_prog_fd, attach_name, err);
+ 			return err;
+ 		}
+ 		*btf_obj_fd = 0;
+@@ -9077,7 +9081,8 @@ static int libbpf_find_attach_btf_id(struct bpf_program *prog, const char *attac
+ 		err = find_kernel_btf_id(prog->obj, attach_name, attach_type, btf_obj_fd, btf_type_id);
+ 	}
+ 	if (err) {
+-		pr_warn("failed to find kernel BTF type ID of '%s': %d\n", attach_name, err);
++		pr_warn("prog '%s': failed to find kernel BTF type ID of '%s': %d\n",
++			prog->name, attach_name, err);
+ 		return err;
+ 	}
+ 	return 0;
+@@ -10662,15 +10667,17 @@ static const char *arch_specific_lib_paths(void)
+ static int resolve_full_path(const char *file, char *result, size_t result_sz)
+ {
+ 	const char *search_paths[3] = {};
+-	int i;
++	int i, perm;
+ 
+ 	if (str_has_sfx(file, ".so") || strstr(file, ".so.")) {
+ 		search_paths[0] = getenv("LD_LIBRARY_PATH");
+ 		search_paths[1] = "/usr/lib64:/usr/lib";
+ 		search_paths[2] = arch_specific_lib_paths();
++		perm = R_OK;
+ 	} else {
+ 		search_paths[0] = getenv("PATH");
+ 		search_paths[1] = "/usr/bin:/usr/sbin";
++		perm = R_OK | X_OK;
+ 	}
+ 
+ 	for (i = 0; i < ARRAY_SIZE(search_paths); i++) {
+@@ -10689,8 +10696,8 @@ static int resolve_full_path(const char *file, char *result, size_t result_sz)
+ 			if (!seg_len)
+ 				continue;
+ 			snprintf(result, result_sz, "%.*s/%s", seg_len, s, file);
+-			/* ensure it is an executable file/link */
+-			if (access(result, R_OK | X_OK) < 0)
++			/* ensure it has required permissions */
++			if (access(result, perm) < 0)
+ 				continue;
+ 			pr_debug("resolved '%s' to '%s'\n", file, result);
+ 			return 0;
+diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
+index 61493c4cddac1..9f956e6058ed9 100644
+--- a/tools/lib/bpf/libbpf.h
++++ b/tools/lib/bpf/libbpf.h
+@@ -118,7 +118,9 @@ struct bpf_object_open_opts {
+ 	 * auto-pinned to that path on load; defaults to "/sys/fs/bpf".
+ 	 */
+ 	const char *pin_root_path;
+-	long :0;
++
++	__u32 :32; /* stub out now removed attach_prog_fd */
++
+ 	/* Additional kernel config content that augments and overrides
+ 	 * system Kconfig for CONFIG_xxx externs.
+ 	 */
+diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
+index 0b5398786bf3d..6d495656f554c 100644
+--- a/tools/lib/bpf/libbpf_probes.c
++++ b/tools/lib/bpf/libbpf_probes.c
+@@ -193,7 +193,7 @@ static int probe_map_create(enum bpf_map_type map_type)
+ 	LIBBPF_OPTS(bpf_map_create_opts, opts);
+ 	int key_size, value_size, max_entries;
+ 	__u32 btf_key_type_id = 0, btf_value_type_id = 0;
+-	int fd = -1, btf_fd = -1, fd_inner = -1, exp_err = 0, err;
++	int fd = -1, btf_fd = -1, fd_inner = -1, exp_err = 0, err = 0;
+ 
+ 	key_size	= sizeof(__u32);
+ 	value_size	= sizeof(__u32);
+diff --git a/tools/lib/bpf/nlattr.c b/tools/lib/bpf/nlattr.c
+index f57e77a6e40fd..3900d052ed19e 100644
+--- a/tools/lib/bpf/nlattr.c
++++ b/tools/lib/bpf/nlattr.c
+@@ -32,7 +32,7 @@ static struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
+ 
+ static int nla_ok(const struct nlattr *nla, int remaining)
+ {
+-	return remaining >= sizeof(*nla) &&
++	return remaining >= (int)sizeof(*nla) &&
+ 	       nla->nla_len >= sizeof(*nla) &&
+ 	       nla->nla_len <= remaining;
+ }
+diff --git a/tools/lib/bpf/usdt.bpf.h b/tools/lib/bpf/usdt.bpf.h
+index 4f2adc0bd6ca3..fdfd235e52c42 100644
+--- a/tools/lib/bpf/usdt.bpf.h
++++ b/tools/lib/bpf/usdt.bpf.h
+@@ -232,7 +232,7 @@ long bpf_usdt_cookie(struct pt_regs *ctx)
+  */
+ #define BPF_USDT(name, args...)						    \
+ name(struct pt_regs *ctx);						    \
+-static __attribute__((always_inline)) typeof(name(0))			    \
++static __always_inline typeof(name(0))					    \
+ ____##name(struct pt_regs *ctx, ##args);				    \
+ typeof(name(0)) name(struct pt_regs *ctx)				    \
+ {									    \
+@@ -241,7 +241,7 @@ typeof(name(0)) name(struct pt_regs *ctx)				    \
+         return ____##name(___bpf_usdt_args(args));			    \
+         _Pragma("GCC diagnostic pop")					    \
+ }									    \
+-static __attribute__((always_inline)) typeof(name(0))			    \
++static __always_inline typeof(name(0))					    \
+ ____##name(struct pt_regs *ctx, ##args)
+ 
+ #endif /* __USDT_BPF_H__ */
+diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
+index c25e957c1e520..7e24b09b1163a 100644
+--- a/tools/objtool/elf.c
++++ b/tools/objtool/elf.c
+@@ -619,6 +619,11 @@ static int elf_update_symbol(struct elf *elf, struct section *symtab,
+ 	Elf64_Xword entsize = symtab->sh.sh_entsize;
+ 	int max_idx, idx = sym->idx;
+ 	Elf_Scn *s, *t = NULL;
++	bool is_special_shndx = sym->sym.st_shndx >= SHN_LORESERVE &&
++				sym->sym.st_shndx != SHN_XINDEX;
++
++	if (is_special_shndx)
++		shndx = sym->sym.st_shndx;
+ 
+ 	s = elf_getscn(elf->elf, symtab->idx);
+ 	if (!s) {
+@@ -704,7 +709,7 @@ static int elf_update_symbol(struct elf *elf, struct section *symtab,
+ 	}
+ 
+ 	/* setup extended section index magic and write the symbol */
+-	if (shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) {
++	if ((shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) || is_special_shndx) {
+ 		sym->sym.st_shndx = shndx;
+ 		if (!shndx_data)
+ 			shndx = 0;
+diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
+index 13933020a79eb..12f271ae2ddd2 100644
+--- a/tools/perf/arch/x86/util/intel-pt.c
++++ b/tools/perf/arch/x86/util/intel-pt.c
+@@ -871,7 +871,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
+ 		 * User space tasks can migrate between CPUs, so when tracing
+ 		 * selected CPUs, sideband for all CPUs is still needed.
+ 		 */
+-		need_system_wide_tracking = evlist->core.has_user_cpus &&
++		need_system_wide_tracking = opts->target.cpu_list &&
+ 					    !intel_pt_evsel->core.attr.exclude_user;
+ 
+ 		tracking_evsel = evlist__add_aux_dummy(evlist, need_system_wide_tracking);
+diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
+index d5e9fc8106dd8..48b9ddd0c5c5c 100644
+--- a/tools/perf/util/intel-pt.c
++++ b/tools/perf/util/intel-pt.c
+@@ -4033,6 +4033,7 @@ static const char * const intel_pt_info_fmts[] = {
+ 	[INTEL_PT_SNAPSHOT_MODE]	= "  Snapshot mode       %"PRId64"\n",
+ 	[INTEL_PT_PER_CPU_MMAPS]	= "  Per-cpu maps        %"PRId64"\n",
+ 	[INTEL_PT_MTC_BIT]		= "  MTC bit             %#"PRIx64"\n",
++	[INTEL_PT_MTC_FREQ_BITS]	= "  MTC freq bits       %#"PRIx64"\n",
+ 	[INTEL_PT_TSC_CTC_N]		= "  TSC:CTC numerator   %"PRIu64"\n",
+ 	[INTEL_PT_TSC_CTC_D]		= "  TSC:CTC denominator %"PRIu64"\n",
+ 	[INTEL_PT_CYC_BIT]		= "  CYC bit             %#"PRIx64"\n",
+@@ -4047,8 +4048,12 @@ static void intel_pt_print_info(__u64 *arr, int start, int finish)
+ 	if (!dump_trace)
+ 		return;
+ 
+-	for (i = start; i <= finish; i++)
+-		fprintf(stdout, intel_pt_info_fmts[i], arr[i]);
++	for (i = start; i <= finish; i++) {
++		const char *fmt = intel_pt_info_fmts[i];
++
++		if (fmt)
++			fprintf(stdout, fmt, arr[i]);
++	}
+ }
+ 
+ static void intel_pt_print_info_str(const char *name, const char *str)
+diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
+index f3b2c2a87456b..c1c57165bf9fc 100644
+--- a/tools/perf/util/parse-events.c
++++ b/tools/perf/util/parse-events.c
+@@ -254,6 +254,9 @@ __add_event(struct list_head *list, int *idx,
+ 	struct perf_cpu_map *cpus = pmu ? perf_cpu_map__get(pmu->cpus) :
+ 			       cpu_list ? perf_cpu_map__new(cpu_list) : NULL;
+ 
++	if (pmu)
++		perf_pmu__warn_invalid_formats(pmu);
++
+ 	if (pmu && attr->type == PERF_TYPE_RAW)
+ 		perf_pmu__warn_invalid_config(pmu, attr->config, name);
+ 
+diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
+index 89655d53117ae..82455b073c2f2 100644
+--- a/tools/perf/util/pmu.c
++++ b/tools/perf/util/pmu.c
+@@ -1005,6 +1005,23 @@ err:
+ 	return NULL;
+ }
+ 
++void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu)
++{
++	struct perf_pmu_format *format;
++
++	/* fake pmu doesn't have format list */
++	if (pmu == &perf_pmu__fake)
++		return;
++
++	list_for_each_entry(format, &pmu->format, list)
++		if (format->value >= PERF_PMU_FORMAT_VALUE_CONFIG_END) {
++			pr_warning("WARNING: '%s' format '%s' requires 'perf_event_attr::config%d'"
++				   "which is not supported by this version of perf!\n",
++				   pmu->name, format->name, format->value);
++			return;
++		}
++}
++
+ static struct perf_pmu *pmu_find(const char *name)
+ {
+ 	struct perf_pmu *pmu;
+diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
+index a7b0f9507510b..68e15c38ae710 100644
+--- a/tools/perf/util/pmu.h
++++ b/tools/perf/util/pmu.h
+@@ -17,6 +17,7 @@ enum {
+ 	PERF_PMU_FORMAT_VALUE_CONFIG,
+ 	PERF_PMU_FORMAT_VALUE_CONFIG1,
+ 	PERF_PMU_FORMAT_VALUE_CONFIG2,
++	PERF_PMU_FORMAT_VALUE_CONFIG_END,
+ };
+ 
+ #define PERF_PMU_FORMAT_BITS 64
+@@ -139,6 +140,7 @@ int perf_pmu__caps_parse(struct perf_pmu *pmu);
+ 
+ void perf_pmu__warn_invalid_config(struct perf_pmu *pmu, __u64 config,
+ 				   const char *name);
++void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu);
+ 
+ bool perf_pmu__has_hybrid(void);
+ int perf_pmu__match(char *pattern, char *name, char *tok);
+diff --git a/tools/perf/util/pmu.l b/tools/perf/util/pmu.l
+index a15d9fbd7c0ed..58b4926cfaca9 100644
+--- a/tools/perf/util/pmu.l
++++ b/tools/perf/util/pmu.l
+@@ -27,8 +27,6 @@ num_dec         [0-9]+
+ 
+ {num_dec}	{ return value(10); }
+ config		{ return PP_CONFIG; }
+-config1		{ return PP_CONFIG1; }
+-config2		{ return PP_CONFIG2; }
+ -		{ return '-'; }
+ :		{ return ':'; }
+ ,		{ return ','; }
+diff --git a/tools/perf/util/pmu.y b/tools/perf/util/pmu.y
+index bfd7e8509869b..283efe059819d 100644
+--- a/tools/perf/util/pmu.y
++++ b/tools/perf/util/pmu.y
+@@ -20,7 +20,7 @@ do { \
+ 
+ %}
+ 
+-%token PP_CONFIG PP_CONFIG1 PP_CONFIG2
++%token PP_CONFIG
+ %token PP_VALUE PP_ERROR
+ %type <num> PP_VALUE
+ %type <bits> bit_term
+@@ -47,18 +47,11 @@ PP_CONFIG ':' bits
+ 				      $3));
+ }
+ |
+-PP_CONFIG1 ':' bits
++PP_CONFIG PP_VALUE ':' bits
+ {
+ 	ABORT_ON(perf_pmu__new_format(format, name,
+-				      PERF_PMU_FORMAT_VALUE_CONFIG1,
+-				      $3));
+-}
+-|
+-PP_CONFIG2 ':' bits
+-{
+-	ABORT_ON(perf_pmu__new_format(format, name,
+-				      PERF_PMU_FORMAT_VALUE_CONFIG2,
+-				      $3));
++				      $2,
++				      $4));
+ }
+ 
+ bits:
+diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
+index 831dc32d45fad..b7d2a0cd0ac28 100644
+--- a/tools/power/x86/turbostat/turbostat.c
++++ b/tools/power/x86/turbostat/turbostat.c
+@@ -4560,7 +4560,6 @@ static double rapl_dram_energy_units_probe(int model, double rapl_energy_units)
+ 	case INTEL_FAM6_SKYLAKE_X:	/* SKX */
+ 	case INTEL_FAM6_XEON_PHI_KNL:	/* KNL */
+ 	case INTEL_FAM6_ICELAKE_X:	/* ICX */
+-	case INTEL_FAM6_SAPPHIRERAPIDS_X:	/* SPR */
+ 		return (rapl_dram_energy_units = 15.3 / 1000000);
+ 	default:
+ 		return (rapl_energy_units);
+diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.c b/tools/testing/selftests/arm64/signal/testcases/testcases.c
+index 84c36bee4d82a..d98828cb542be 100644
+--- a/tools/testing/selftests/arm64/signal/testcases/testcases.c
++++ b/tools/testing/selftests/arm64/signal/testcases/testcases.c
+@@ -33,7 +33,7 @@ bool validate_extra_context(struct extra_context *extra, char **err)
+ 		return false;
+ 
+ 	fprintf(stderr, "Validating EXTRA...\n");
+-	term = GET_RESV_NEXT_HEAD(extra);
++	term = GET_RESV_NEXT_HEAD(&extra->head);
+ 	if (!term || term->magic || term->size) {
+ 		*err = "Missing terminator after EXTRA context";
+ 		return false;
+diff --git a/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c b/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c
+index 78c76496b14ad..b595556315bc3 100644
+--- a/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c
++++ b/tools/testing/selftests/bpf/map_tests/array_map_batch_ops.c
+@@ -3,6 +3,7 @@
+ #include <stdio.h>
+ #include <errno.h>
+ #include <string.h>
++#include <unistd.h>
+ 
+ #include <bpf/bpf.h>
+ #include <bpf/libbpf.h>
+@@ -137,6 +138,7 @@ static void __test_map_lookup_and_update_batch(bool is_pcpu)
+ 	free(keys);
+ 	free(values);
+ 	free(visited);
++	close(map_fd);
+ }
+ 
+ static void array_map_batch_ops(void)
+diff --git a/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c b/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c
+index f807d53fd8dd4..1230ccf901280 100644
+--- a/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c
++++ b/tools/testing/selftests/bpf/map_tests/htab_map_batch_ops.c
+@@ -3,6 +3,7 @@
+ #include <stdio.h>
+ #include <errno.h>
+ #include <string.h>
++#include <unistd.h>
+ 
+ #include <bpf/bpf.h>
+ #include <bpf/libbpf.h>
+@@ -255,6 +256,7 @@ void __test_map_lookup_and_delete_batch(bool is_pcpu)
+ 	free(visited);
+ 	if (!is_pcpu)
+ 		free(values);
++	close(map_fd);
+ }
+ 
+ void htab_map_batch_ops(void)
+diff --git a/tools/testing/selftests/bpf/map_tests/lpm_trie_map_batch_ops.c b/tools/testing/selftests/bpf/map_tests/lpm_trie_map_batch_ops.c
+index 87d07b596e170..b66d56ddb7ef2 100644
+--- a/tools/testing/selftests/bpf/map_tests/lpm_trie_map_batch_ops.c
++++ b/tools/testing/selftests/bpf/map_tests/lpm_trie_map_batch_ops.c
+@@ -7,6 +7,7 @@
+ #include <errno.h>
+ #include <string.h>
+ #include <stdlib.h>
++#include <unistd.h>
+ 
+ #include <bpf/bpf.h>
+ #include <bpf/libbpf.h>
+@@ -150,4 +151,5 @@ void test_lpm_trie_map_batch_ops(void)
+ 	free(keys);
+ 	free(values);
+ 	free(visited);
++	close(map_fd);
+ }
+diff --git a/tools/testing/selftests/bpf/prog_tests/cgroup_link.c b/tools/testing/selftests/bpf/prog_tests/cgroup_link.c
+index 9e6e6aad347c7..15093a69510eb 100644
+--- a/tools/testing/selftests/bpf/prog_tests/cgroup_link.c
++++ b/tools/testing/selftests/bpf/prog_tests/cgroup_link.c
+@@ -71,10 +71,9 @@ void serial_test_cgroup_link(void)
+ 
+ 	ping_and_check(cg_nr, 0);
+ 
+-	/* query the number of effective progs and attach flags in root cg */
++	/* query the number of attached progs and attach flags in root cg */
+ 	err = bpf_prog_query(cgs[0].fd, BPF_CGROUP_INET_EGRESS,
+-			     BPF_F_QUERY_EFFECTIVE, &attach_flags, NULL,
+-			     &prog_cnt);
++			     0, &attach_flags, NULL, &prog_cnt);
+ 	CHECK_FAIL(err);
+ 	CHECK_FAIL(attach_flags != BPF_F_ALLOW_MULTI);
+ 	if (CHECK(prog_cnt != 1, "effect_cnt", "exp %d, got %d\n", 1, prog_cnt))
+@@ -85,17 +84,15 @@ void serial_test_cgroup_link(void)
+ 			     BPF_F_QUERY_EFFECTIVE, NULL, NULL,
+ 			     &prog_cnt);
+ 	CHECK_FAIL(err);
+-	CHECK_FAIL(attach_flags != BPF_F_ALLOW_MULTI);
+ 	if (CHECK(prog_cnt != cg_nr, "effect_cnt", "exp %d, got %d\n",
+ 		  cg_nr, prog_cnt))
+ 		goto cleanup;
+ 
+ 	/* query the effective prog IDs in last cg */
+ 	err = bpf_prog_query(cgs[last_cg].fd, BPF_CGROUP_INET_EGRESS,
+-			     BPF_F_QUERY_EFFECTIVE, &attach_flags,
+-			     prog_ids, &prog_cnt);
++			     BPF_F_QUERY_EFFECTIVE, NULL, prog_ids,
++			     &prog_cnt);
+ 	CHECK_FAIL(err);
+-	CHECK_FAIL(attach_flags != BPF_F_ALLOW_MULTI);
+ 	if (CHECK(prog_cnt != cg_nr, "effect_cnt", "exp %d, got %d\n",
+ 		  cg_nr, prog_cnt))
+ 		goto cleanup;
+diff --git a/tools/testing/selftests/bpf/progs/kprobe_multi.c b/tools/testing/selftests/bpf/progs/kprobe_multi.c
+index 08f95a8155d1b..98c3399e15c03 100644
+--- a/tools/testing/selftests/bpf/progs/kprobe_multi.c
++++ b/tools/testing/selftests/bpf/progs/kprobe_multi.c
+@@ -36,15 +36,13 @@ __u64 kretprobe_test6_result = 0;
+ __u64 kretprobe_test7_result = 0;
+ __u64 kretprobe_test8_result = 0;
+ 
+-extern bool CONFIG_X86_KERNEL_IBT __kconfig __weak;
+-
+ static void kprobe_multi_check(void *ctx, bool is_return)
+ {
+ 	if (bpf_get_current_pid_tgid() >> 32 != pid)
+ 		return;
+ 
+ 	__u64 cookie = test_cookie ? bpf_get_attach_cookie(ctx) : 0;
+-	__u64 addr = bpf_get_func_ip(ctx) - (CONFIG_X86_KERNEL_IBT ? 4 : 0);
++	__u64 addr = bpf_get_func_ip(ctx);
+ 
+ #define SET(__var, __addr, __cookie) ({			\
+ 	if (((const void *) addr == __addr) &&		\
+diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c
+index cbebfaa7c1e82..4d42ffea00388 100644
+--- a/tools/testing/selftests/bpf/test_maps.c
++++ b/tools/testing/selftests/bpf/test_maps.c
+@@ -658,13 +658,13 @@ static void test_sockmap(unsigned int tasks, void *data)
+ {
+ 	struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_msg, *bpf_map_break;
+ 	int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break;
++	struct bpf_object *parse_obj, *verdict_obj, *msg_obj;
+ 	int ports[] = {50200, 50201, 50202, 50204};
+ 	int err, i, fd, udp, sfd[6] = {0xdeadbeef};
+ 	u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0};
+ 	int parse_prog, verdict_prog, msg_prog;
+ 	struct sockaddr_in addr;
+ 	int one = 1, s, sc, rc;
+-	struct bpf_object *obj;
+ 	struct timeval to;
+ 	__u32 key, value;
+ 	pid_t pid[tasks];
+@@ -760,6 +760,7 @@ static void test_sockmap(unsigned int tasks, void *data)
+ 		       i, udp);
+ 		goto out_sockmap;
+ 	}
++	close(udp);
+ 
+ 	/* Test update without programs */
+ 	for (i = 0; i < 6; i++) {
+@@ -822,27 +823,27 @@ static void test_sockmap(unsigned int tasks, void *data)
+ 
+ 	/* Load SK_SKB program and Attach */
+ 	err = bpf_prog_test_load(SOCKMAP_PARSE_PROG,
+-			    BPF_PROG_TYPE_SK_SKB, &obj, &parse_prog);
++			    BPF_PROG_TYPE_SK_SKB, &parse_obj, &parse_prog);
+ 	if (err) {
+ 		printf("Failed to load SK_SKB parse prog\n");
+ 		goto out_sockmap;
+ 	}
+ 
+ 	err = bpf_prog_test_load(SOCKMAP_TCP_MSG_PROG,
+-			    BPF_PROG_TYPE_SK_MSG, &obj, &msg_prog);
++			    BPF_PROG_TYPE_SK_MSG, &msg_obj, &msg_prog);
+ 	if (err) {
+ 		printf("Failed to load SK_SKB msg prog\n");
+ 		goto out_sockmap;
+ 	}
+ 
+ 	err = bpf_prog_test_load(SOCKMAP_VERDICT_PROG,
+-			    BPF_PROG_TYPE_SK_SKB, &obj, &verdict_prog);
++			    BPF_PROG_TYPE_SK_SKB, &verdict_obj, &verdict_prog);
+ 	if (err) {
+ 		printf("Failed to load SK_SKB verdict prog\n");
+ 		goto out_sockmap;
+ 	}
+ 
+-	bpf_map_rx = bpf_object__find_map_by_name(obj, "sock_map_rx");
++	bpf_map_rx = bpf_object__find_map_by_name(verdict_obj, "sock_map_rx");
+ 	if (!bpf_map_rx) {
+ 		printf("Failed to load map rx from verdict prog\n");
+ 		goto out_sockmap;
+@@ -854,7 +855,7 @@ static void test_sockmap(unsigned int tasks, void *data)
+ 		goto out_sockmap;
+ 	}
+ 
+-	bpf_map_tx = bpf_object__find_map_by_name(obj, "sock_map_tx");
++	bpf_map_tx = bpf_object__find_map_by_name(verdict_obj, "sock_map_tx");
+ 	if (!bpf_map_tx) {
+ 		printf("Failed to load map tx from verdict prog\n");
+ 		goto out_sockmap;
+@@ -866,7 +867,7 @@ static void test_sockmap(unsigned int tasks, void *data)
+ 		goto out_sockmap;
+ 	}
+ 
+-	bpf_map_msg = bpf_object__find_map_by_name(obj, "sock_map_msg");
++	bpf_map_msg = bpf_object__find_map_by_name(verdict_obj, "sock_map_msg");
+ 	if (!bpf_map_msg) {
+ 		printf("Failed to load map msg from msg_verdict prog\n");
+ 		goto out_sockmap;
+@@ -878,7 +879,7 @@ static void test_sockmap(unsigned int tasks, void *data)
+ 		goto out_sockmap;
+ 	}
+ 
+-	bpf_map_break = bpf_object__find_map_by_name(obj, "sock_map_break");
++	bpf_map_break = bpf_object__find_map_by_name(verdict_obj, "sock_map_break");
+ 	if (!bpf_map_break) {
+ 		printf("Failed to load map tx from verdict prog\n");
+ 		goto out_sockmap;
+@@ -1124,7 +1125,9 @@ static void test_sockmap(unsigned int tasks, void *data)
+ 	}
+ 	close(fd);
+ 	close(map_fd_rx);
+-	bpf_object__close(obj);
++	bpf_object__close(parse_obj);
++	bpf_object__close(msg_obj);
++	bpf_object__close(verdict_obj);
+ 	return;
+ out:
+ 	for (i = 0; i < 6; i++)
+@@ -1282,8 +1285,11 @@ static void test_map_in_map(void)
+ 			printf("Inner map mim.inner was not destroyed\n");
+ 			goto out_map_in_map;
+ 		}
++
++		close(fd);
+ 	}
+ 
++	bpf_object__close(obj);
+ 	return;
+ 
+ out_map_in_map:
+diff --git a/tools/testing/selftests/bpf/xsk.c b/tools/testing/selftests/bpf/xsk.c
+index f2721a4ae7c50..0b3ff49c740d4 100644
+--- a/tools/testing/selftests/bpf/xsk.c
++++ b/tools/testing/selftests/bpf/xsk.c
+@@ -1237,15 +1237,15 @@ void xsk_socket__delete(struct xsk_socket *xsk)
+ 	ctx = xsk->ctx;
+ 	umem = ctx->umem;
+ 
+-	xsk_put_ctx(ctx, true);
+-
+-	if (!ctx->refcount) {
++	if (ctx->refcount == 1) {
+ 		xsk_delete_bpf_maps(xsk);
+ 		close(ctx->prog_fd);
+ 		if (ctx->has_bpf_link)
+ 			close(ctx->link_fd);
+ 	}
+ 
++	xsk_put_ctx(ctx, true);
++
+ 	err = xsk_get_mmap_offsets(xsk->fd, &off);
+ 	if (!err) {
+ 		if (xsk->rx) {
+diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
+index 74d56d971bafc..091402dc53908 100644
+--- a/tools/testing/selftests/bpf/xskxceiver.c
++++ b/tools/testing/selftests/bpf/xskxceiver.c
+@@ -1606,6 +1606,8 @@ static struct ifobject *ifobject_create(void)
+ 	if (!ifobj->umem)
+ 		goto out_umem;
+ 
++	ifobj->ns_fd = -1;
++
+ 	return ifobj;
+ 
+ out_umem:
+@@ -1617,6 +1619,8 @@ out_xsk_arr:
+ 
+ static void ifobject_delete(struct ifobject *ifobj)
+ {
++	if (ifobj->ns_fd != -1)
++		close(ifobj->ns_fd);
+ 	free(ifobj->umem);
+ 	free(ifobj->xsk_arr);
+ 	free(ifobj);
+diff --git a/tools/testing/selftests/cpu-hotplug/config b/tools/testing/selftests/cpu-hotplug/config
+deleted file mode 100644
+index d4aca2ad5069b..0000000000000
+--- a/tools/testing/selftests/cpu-hotplug/config
++++ /dev/null
+@@ -1 +0,0 @@
+-CONFIG_NOTIFIER_ERROR_INJECTION=y
+diff --git a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
+index 0d26b5e3f9667..4c1d6d9abecc3 100755
+--- a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
++++ b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
+@@ -4,6 +4,7 @@
+ SYSFS=
+ # Kselftest framework requirement - SKIP code is 4.
+ ksft_skip=4
++retval=0
+ 
+ prerequisite()
+ {
+@@ -102,10 +103,10 @@ online_cpu_expect_success()
+ 
+ 	if ! online_cpu $cpu; then
+ 		echo $FUNCNAME $cpu: unexpected fail >&2
+-		exit 1
++		retval=1
+ 	elif ! cpu_is_online $cpu; then
+ 		echo $FUNCNAME $cpu: unexpected offline >&2
+-		exit 1
++		retval=1
+ 	fi
+ }
+ 
+@@ -115,10 +116,10 @@ online_cpu_expect_fail()
+ 
+ 	if online_cpu $cpu 2> /dev/null; then
+ 		echo $FUNCNAME $cpu: unexpected success >&2
+-		exit 1
++		retval=1
+ 	elif ! cpu_is_offline $cpu; then
+ 		echo $FUNCNAME $cpu: unexpected online >&2
+-		exit 1
++		retval=1
+ 	fi
+ }
+ 
+@@ -128,10 +129,10 @@ offline_cpu_expect_success()
+ 
+ 	if ! offline_cpu $cpu; then
+ 		echo $FUNCNAME $cpu: unexpected fail >&2
+-		exit 1
++		retval=1
+ 	elif ! cpu_is_offline $cpu; then
+ 		echo $FUNCNAME $cpu: unexpected offline >&2
+-		exit 1
++		retval=1
+ 	fi
+ }
+ 
+@@ -141,16 +142,33 @@ offline_cpu_expect_fail()
+ 
+ 	if offline_cpu $cpu 2> /dev/null; then
+ 		echo $FUNCNAME $cpu: unexpected success >&2
+-		exit 1
++		retval=1
+ 	elif ! cpu_is_online $cpu; then
+ 		echo $FUNCNAME $cpu: unexpected offline >&2
+-		exit 1
++		retval=1
+ 	fi
+ }
+ 
+-error=-12
++online_all_hot_pluggable_cpus()
++{
++	for cpu in `hotplaggable_offline_cpus`; do
++		online_cpu_expect_success $cpu
++	done
++}
++
++offline_all_hot_pluggable_cpus()
++{
++	local reserve_cpu=$online_max
++	for cpu in `hotpluggable_online_cpus`; do
++		# Reserve one cpu oneline at least.
++		if [ $cpu -eq $reserve_cpu ];then
++			continue
++		fi
++		offline_cpu_expect_success $cpu
++	done
++}
++
+ allcpus=0
+-priority=0
+ online_cpus=0
+ online_max=0
+ offline_cpus=0
+@@ -158,31 +176,20 @@ offline_max=0
+ present_cpus=0
+ present_max=0
+ 
+-while getopts e:ahp: opt; do
++while getopts ah opt; do
+ 	case $opt in
+-	e)
+-		error=$OPTARG
+-		;;
+ 	a)
+ 		allcpus=1
+ 		;;
+ 	h)
+-		echo "Usage $0 [ -a ] [ -e errno ] [ -p notifier-priority ]"
++		echo "Usage $0 [ -a ]"
+ 		echo -e "\t default offline one cpu"
+ 		echo -e "\t run with -a option to offline all cpus"
+ 		exit
+ 		;;
+-	p)
+-		priority=$OPTARG
+-		;;
+ 	esac
+ done
+ 
+-if ! [ "$error" -ge -4095 -a "$error" -lt 0 ]; then
+-	echo "error code must be -4095 <= errno < 0" >&2
+-	exit 1
+-fi
+-
+ prerequisite
+ 
+ #
+@@ -201,7 +208,7 @@ if [ $allcpus -eq 0 ]; then
+ 		offline_cpu_expect_success $present_max
+ 		online_cpu $present_max
+ 	fi
+-	exit 0
++	exit $retval
+ else
+ 	echo "Full scope test: all hotplug cpus"
+ 	echo -e "\t online all offline cpus"
+@@ -209,85 +216,10 @@ else
+ 	echo -e "\t online all offline cpus"
+ fi
+ 
+-#
+-# Online all hot-pluggable CPUs
+-#
+-for cpu in `hotplaggable_offline_cpus`; do
+-	online_cpu_expect_success $cpu
+-done
+-
+-#
+-# Offline all hot-pluggable CPUs
+-#
+-for cpu in `hotpluggable_online_cpus`; do
+-	offline_cpu_expect_success $cpu
+-done
+-
+-#
+-# Online all hot-pluggable CPUs again
+-#
+-for cpu in `hotplaggable_offline_cpus`; do
+-	online_cpu_expect_success $cpu
+-done
+-
+-#
+-# Test with cpu notifier error injection
+-#
++online_all_hot_pluggable_cpus
+ 
+-DEBUGFS=`mount -t debugfs | head -1 | awk '{ print $3 }'`
+-NOTIFIER_ERR_INJECT_DIR=$DEBUGFS/notifier-error-inject/cpu
++offline_all_hot_pluggable_cpus
+ 
+-prerequisite_extra()
+-{
+-	msg="skip extra tests:"
+-
+-	/sbin/modprobe -q -r cpu-notifier-error-inject
+-	/sbin/modprobe -q cpu-notifier-error-inject priority=$priority
+-
+-	if [ ! -d "$DEBUGFS" ]; then
+-		echo $msg debugfs is not mounted >&2
+-		exit $ksft_skip
+-	fi
+-
+-	if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
+-		echo $msg cpu-notifier-error-inject module is not available >&2
+-		exit $ksft_skip
+-	fi
+-}
+-
+-prerequisite_extra
+-
+-#
+-# Offline all hot-pluggable CPUs
+-#
+-echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+-for cpu in `hotpluggable_online_cpus`; do
+-	offline_cpu_expect_success $cpu
+-done
+-
+-#
+-# Test CPU hot-add error handling (offline => online)
+-#
+-echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
+-for cpu in `hotplaggable_offline_cpus`; do
+-	online_cpu_expect_fail $cpu
+-done
+-
+-#
+-# Online all hot-pluggable CPUs
+-#
+-echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_UP_PREPARE/error
+-for cpu in `hotplaggable_offline_cpus`; do
+-	online_cpu_expect_success $cpu
+-done
+-
+-#
+-# Test CPU hot-remove error handling (online => offline)
+-#
+-echo $error > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+-for cpu in `hotpluggable_online_cpus`; do
+-	offline_cpu_expect_fail $cpu
+-done
++online_all_hot_pluggable_cpus
+ 
+-echo 0 > $NOTIFIER_ERR_INJECT_DIR/actions/CPU_DOWN_PREPARE/error
+-/sbin/modprobe -q -r cpu-notifier-error-inject
++exit $retval
+diff --git a/tools/testing/selftests/net/fcnal-test.sh b/tools/testing/selftests/net/fcnal-test.sh
+index 03b586760164a..31c3b6ebd388b 100755
+--- a/tools/testing/selftests/net/fcnal-test.sh
++++ b/tools/testing/selftests/net/fcnal-test.sh
+@@ -1466,6 +1466,13 @@ ipv4_udp_novrf()
+ 		run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -0 ${NSA_IP}
+ 		log_test_addr ${a} $? 0 "Client, device bind via IP_UNICAST_IF"
+ 
++		log_start
++		run_cmd_nsb nettest -D -s &
++		sleep 1
++		run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -0 ${NSA_IP} -U
++		log_test_addr ${a} $? 0 "Client, device bind via IP_UNICAST_IF, with connect()"
++
++
+ 		log_start
+ 		show_hint "Should fail 'Connection refused'"
+ 		run_cmd nettest -D -r ${a}
+@@ -1525,6 +1532,13 @@ ipv4_udp_novrf()
+ 	run_cmd nettest -D -d ${NSA_DEV} -S -r ${a}
+ 	log_test_addr ${a} $? 0 "Global server, device client via IP_UNICAST_IF, local connection"
+ 
++	log_start
++	run_cmd nettest -s -D &
++	sleep 1
++	run_cmd nettest -D -d ${NSA_DEV} -S -r ${a} -U
++	log_test_addr ${a} $? 0 "Global server, device client via IP_UNICAST_IF, local connection, with connect()"
++
++
+ 	# IPv4 with device bind has really weird behavior - it overrides the
+ 	# fib lookup, generates an rtable and tries to send the packet. This
+ 	# causes failures for local traffic at different places
+@@ -1550,6 +1564,15 @@ ipv4_udp_novrf()
+ 		sleep 1
+ 		run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S
+ 		log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection"
++
++		log_start
++		show_hint "Should fail since addresses on loopback are out of device scope"
++		run_cmd nettest -D -s &
++		sleep 1
++		run_cmd nettest -D -r ${a} -d ${NSA_DEV} -S -U
++		log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection, with connect()"
++
++
+ 	done
+ 
+ 	a=${NSA_IP}
+@@ -3157,6 +3180,13 @@ ipv6_udp_novrf()
+ 		sleep 1
+ 		run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -S
+ 		log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection"
++
++		log_start
++		show_hint "Should fail 'No route to host' since addresses on loopback are out of device scope"
++		run_cmd nettest -6 -D -s &
++		sleep 1
++		run_cmd nettest -6 -D -r ${a} -d ${NSA_DEV} -S -U
++		log_test_addr ${a} $? 1 "Global server, device client via IP_UNICAST_IF, local connection, with connect()"
+ 	done
+ 
+ 	a=${NSA_IP6}
+diff --git a/tools/testing/selftests/net/nettest.c b/tools/testing/selftests/net/nettest.c
+index d9a6fd2cd9d31..7900fa98eccb1 100644
+--- a/tools/testing/selftests/net/nettest.c
++++ b/tools/testing/selftests/net/nettest.c
+@@ -127,6 +127,9 @@ struct sock_args {
+ 
+ 	/* ESP in UDP encap test */
+ 	int use_xfrm;
++
++	/* use send() and connect() instead of sendto */
++	int datagram_connect;
+ };
+ 
+ static int server_mode;
+@@ -979,6 +982,11 @@ static int send_msg(int sd, void *addr, socklen_t alen, struct sock_args *args)
+ 			log_err_errno("write failed sending msg to peer");
+ 			return 1;
+ 		}
++	} else if (args->datagram_connect) {
++		if (send(sd, msg, msglen, 0) < 0) {
++			log_err_errno("send failed sending msg to peer");
++			return 1;
++		}
+ 	} else if (args->ifindex && args->use_cmsg) {
+ 		if (send_msg_cmsg(sd, addr, alen, args->ifindex, args->version))
+ 			return 1;
+@@ -1659,7 +1667,7 @@ static int connectsock(void *addr, socklen_t alen, struct sock_args *args)
+ 	if (args->has_local_ip && bind_socket(sd, args))
+ 		goto err;
+ 
+-	if (args->type != SOCK_STREAM)
++	if (args->type != SOCK_STREAM && !args->datagram_connect)
+ 		goto out;
+ 
+ 	if (args->password && tcp_md5sig(sd, addr, alen, args))
+@@ -1854,7 +1862,7 @@ static int ipc_parent(int cpid, int fd, struct sock_args *args)
+ 	return client_status;
+ }
+ 
+-#define GETOPT_STR  "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SCi6xL:0:1:2:3:Fbqf"
++#define GETOPT_STR  "sr:l:c:p:t:g:P:DRn:M:X:m:d:I:BN:O:SUCi6xL:0:1:2:3:Fbqf"
+ #define OPT_FORCE_BIND_KEY_IFINDEX 1001
+ #define OPT_NO_BIND_KEY_IFINDEX 1002
+ 
+@@ -1891,6 +1899,7 @@ static void print_usage(char *prog)
+ 	"    -I dev        bind socket to given device name - server mode\n"
+ 	"    -S            use setsockopt (IP_UNICAST_IF or IP_MULTICAST_IF)\n"
+ 	"                  to set device binding\n"
++	"    -U            Use connect() and send() for datagram sockets\n"
+ 	"    -f            bind socket with the IP[V6]_FREEBIND option\n"
+ 	"    -C            use cmsg and IP_PKTINFO to specify device binding\n"
+ 	"\n"
+@@ -2074,6 +2083,9 @@ int main(int argc, char *argv[])
+ 		case 'x':
+ 			args.use_xfrm = 1;
+ 			break;
++		case 'U':
++			args.datagram_connect = 1;
++			break;
+ 		default:
+ 			print_usage(argv[0]);
+ 			return 1;
+diff --git a/tools/testing/selftests/tpm2/tpm2.py b/tools/testing/selftests/tpm2/tpm2.py
+index 057a4f49c79d9..c7363c6764fc6 100644
+--- a/tools/testing/selftests/tpm2/tpm2.py
++++ b/tools/testing/selftests/tpm2/tpm2.py
+@@ -371,6 +371,10 @@ class Client:
+             fcntl.fcntl(self.tpm, fcntl.F_SETFL, flags)
+             self.tpm_poll = select.poll()
+ 
++    def __del__(self):
++        if self.tpm:
++            self.tpm.close()
++
+     def close(self):
+         self.tpm.close()
+ 


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-10-15 10:03 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-10-15 10:03 UTC (permalink / raw
  To: gentoo-commits

commit:     58312dccbb21fc15f32fa785cf6cf9ac33621b65
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Oct 15 10:03:13 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Oct 15 10:03:13 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=58312dcc

Linux patch 6.0.2

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

 0000_README            |    4 +
 1001_linux-6.0.2.patch | 1404 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1408 insertions(+)

diff --git a/0000_README b/0000_README
index d41088d3..5fd3d6cf 100644
--- a/0000_README
+++ b/0000_README
@@ -47,6 +47,10 @@ Patch:  1000_linux-6.0.1.patch
 From:   http://www.kernel.org
 Desc:   Linux 6.0.1
 
+Patch:  1001_linux-6.0.2.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.2
+
 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/1001_linux-6.0.2.patch b/1001_linux-6.0.2.patch
new file mode 100644
index 00000000..7b3df1df
--- /dev/null
+++ b/1001_linux-6.0.2.patch
@@ -0,0 +1,1404 @@
+diff --git a/Makefile b/Makefile
+index 3193969f1eb37..aa449693ad09d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 1
++SUBLEVEL = 2
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
+index 4d7aaab827023..3537b0500f4d0 100644
+--- a/arch/powerpc/include/asm/paca.h
++++ b/arch/powerpc/include/asm/paca.h
+@@ -263,7 +263,6 @@ struct paca_struct {
+ 	u64 l1d_flush_size;
+ #endif
+ #ifdef CONFIG_PPC_PSERIES
+-	struct rtas_args *rtas_args_reentrant;
+ 	u8 *mce_data_buf;		/* buffer to hold per cpu rtas errlog */
+ #endif /* CONFIG_PPC_PSERIES */
+ 
+diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
+index 00531af17ce05..56319aea646e6 100644
+--- a/arch/powerpc/include/asm/rtas.h
++++ b/arch/powerpc/include/asm/rtas.h
+@@ -240,7 +240,6 @@ extern struct rtas_t rtas;
+ extern int rtas_token(const char *service);
+ extern int rtas_service_present(const char *service);
+ extern int rtas_call(int token, int, int, int *, ...);
+-int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...);
+ void rtas_call_unlocked(struct rtas_args *args, int token, int nargs,
+ 			int nret, ...);
+ extern void __noreturn rtas_restart(char *cmd);
+diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
+index ba593fd601245..dfd097b79160a 100644
+--- a/arch/powerpc/kernel/paca.c
++++ b/arch/powerpc/kernel/paca.c
+@@ -16,7 +16,6 @@
+ #include <asm/kexec.h>
+ #include <asm/svm.h>
+ #include <asm/ultravisor.h>
+-#include <asm/rtas.h>
+ 
+ #include "setup.h"
+ 
+@@ -170,30 +169,6 @@ static struct slb_shadow * __init new_slb_shadow(int cpu, unsigned long limit)
+ }
+ #endif /* CONFIG_PPC_64S_HASH_MMU */
+ 
+-#ifdef CONFIG_PPC_PSERIES
+-/**
+- * new_rtas_args() - Allocates rtas args
+- * @cpu:	CPU number
+- * @limit:	Memory limit for this allocation
+- *
+- * Allocates a struct rtas_args and return it's pointer,
+- * if not in Hypervisor mode
+- *
+- * Return:	Pointer to allocated rtas_args
+- *		NULL if CPU in Hypervisor Mode
+- */
+-static struct rtas_args * __init new_rtas_args(int cpu, unsigned long limit)
+-{
+-	limit = min_t(unsigned long, limit, RTAS_INSTANTIATE_MAX);
+-
+-	if (early_cpu_has_feature(CPU_FTR_HVMODE))
+-		return NULL;
+-
+-	return alloc_paca_data(sizeof(struct rtas_args), L1_CACHE_BYTES,
+-			       limit, cpu);
+-}
+-#endif /* CONFIG_PPC_PSERIES */
+-
+ /* The Paca is an array with one entry per processor.  Each contains an
+  * lppaca, which contains the information shared between the
+  * hypervisor and Linux.
+@@ -232,10 +207,6 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
+ 	/* For now -- if we have threads this will be adjusted later */
+ 	new_paca->tcd_ptr = &new_paca->tcd;
+ #endif
+-
+-#ifdef CONFIG_PPC_PSERIES
+-	new_paca->rtas_args_reentrant = NULL;
+-#endif
+ }
+ 
+ /* Put the paca pointer into r13 and SPRG_PACA */
+@@ -307,9 +278,6 @@ void __init allocate_paca(int cpu)
+ #endif
+ #ifdef CONFIG_PPC_64S_HASH_MMU
+ 	paca->slb_shadow_ptr = new_slb_shadow(cpu, limit);
+-#endif
+-#ifdef CONFIG_PPC_PSERIES
+-	paca->rtas_args_reentrant = new_rtas_args(cpu, limit);
+ #endif
+ 	paca_struct_size += sizeof(struct paca_struct);
+ }
+diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
+index 6931339722948..0b8a858aa8479 100644
+--- a/arch/powerpc/kernel/rtas.c
++++ b/arch/powerpc/kernel/rtas.c
+@@ -43,7 +43,6 @@
+ #include <asm/time.h>
+ #include <asm/mmu.h>
+ #include <asm/topology.h>
+-#include <asm/paca.h>
+ 
+ /* This is here deliberately so it's only used in this file */
+ void enter_rtas(unsigned long);
+@@ -932,59 +931,6 @@ void rtas_activate_firmware(void)
+ 		pr_err("ibm,activate-firmware failed (%i)\n", fwrc);
+ }
+ 
+-#ifdef CONFIG_PPC_PSERIES
+-/**
+- * rtas_call_reentrant() - Used for reentrant rtas calls
+- * @token:	Token for desired reentrant RTAS call
+- * @nargs:	Number of Input Parameters
+- * @nret:	Number of Output Parameters
+- * @outputs:	Array of outputs
+- * @...:	Inputs for desired RTAS call
+- *
+- * According to LoPAR documentation, only "ibm,int-on", "ibm,int-off",
+- * "ibm,get-xive" and "ibm,set-xive" are currently reentrant.
+- * Reentrant calls need their own rtas_args buffer, so not using rtas.args, but
+- * PACA one instead.
+- *
+- * Return:	-1 on error,
+- *		First output value of RTAS call if (nret > 0),
+- *		0 otherwise,
+- */
+-int rtas_call_reentrant(int token, int nargs, int nret, int *outputs, ...)
+-{
+-	va_list list;
+-	struct rtas_args *args;
+-	unsigned long flags;
+-	int i, ret = 0;
+-
+-	if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE)
+-		return -1;
+-
+-	local_irq_save(flags);
+-	preempt_disable();
+-
+-	/* We use the per-cpu (PACA) rtas args buffer */
+-	args = local_paca->rtas_args_reentrant;
+-
+-	va_start(list, outputs);
+-	va_rtas_call_unlocked(args, token, nargs, nret, list);
+-	va_end(list);
+-
+-	if (nret > 1 && outputs)
+-		for (i = 0; i < nret - 1; ++i)
+-			outputs[i] = be32_to_cpu(args->rets[i + 1]);
+-
+-	if (nret > 0)
+-		ret = be32_to_cpu(args->rets[0]);
+-
+-	local_irq_restore(flags);
+-	preempt_enable();
+-
+-	return ret;
+-}
+-
+-#endif /* CONFIG_PPC_PSERIES */
+-
+ /**
+  * get_pseries_errorlog() - Find a specific pseries error log in an RTAS
+  *                          extended event log.
+diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c
+index 9e7007f9aca5c..f8320f8e5bc79 100644
+--- a/arch/powerpc/sysdev/xics/ics-rtas.c
++++ b/arch/powerpc/sysdev/xics/ics-rtas.c
+@@ -36,8 +36,8 @@ static void ics_rtas_unmask_irq(struct irq_data *d)
+ 
+ 	server = xics_get_irq_server(d->irq, irq_data_get_affinity_mask(d), 0);
+ 
+-	call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq,
+-					  server, DEFAULT_PRIORITY);
++	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq, server,
++				DEFAULT_PRIORITY);
+ 	if (call_status != 0) {
+ 		printk(KERN_ERR
+ 			"%s: ibm_set_xive irq %u server %x returned %d\n",
+@@ -46,7 +46,7 @@ static void ics_rtas_unmask_irq(struct irq_data *d)
+ 	}
+ 
+ 	/* Now unmask the interrupt (often a no-op) */
+-	call_status = rtas_call_reentrant(ibm_int_on, 1, 1, NULL, hw_irq);
++	call_status = rtas_call(ibm_int_on, 1, 1, NULL, hw_irq);
+ 	if (call_status != 0) {
+ 		printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n",
+ 			__func__, hw_irq, call_status);
+@@ -68,7 +68,7 @@ static void ics_rtas_mask_real_irq(unsigned int hw_irq)
+ 	if (hw_irq == XICS_IPI)
+ 		return;
+ 
+-	call_status = rtas_call_reentrant(ibm_int_off, 1, 1, NULL, hw_irq);
++	call_status = rtas_call(ibm_int_off, 1, 1, NULL, hw_irq);
+ 	if (call_status != 0) {
+ 		printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
+ 			__func__, hw_irq, call_status);
+@@ -76,8 +76,8 @@ static void ics_rtas_mask_real_irq(unsigned int hw_irq)
+ 	}
+ 
+ 	/* Have to set XIVE to 0xff to be able to remove a slot */
+-	call_status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL, hw_irq,
+-					  xics_default_server, 0xff);
++	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq,
++				xics_default_server, 0xff);
+ 	if (call_status != 0) {
+ 		printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
+ 			__func__, hw_irq, call_status);
+@@ -108,7 +108,7 @@ static int ics_rtas_set_affinity(struct irq_data *d,
+ 	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
+ 		return -1;
+ 
+-	status = rtas_call_reentrant(ibm_get_xive, 1, 3, xics_status, hw_irq);
++	status = rtas_call(ibm_get_xive, 1, 3, xics_status, hw_irq);
+ 
+ 	if (status) {
+ 		printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
+@@ -126,8 +126,8 @@ static int ics_rtas_set_affinity(struct irq_data *d,
+ 	pr_debug("%s: irq %d [hw 0x%x] server: 0x%x\n", __func__, d->irq,
+ 		 hw_irq, irq_server);
+ 
+-	status = rtas_call_reentrant(ibm_set_xive, 3, 1, NULL,
+-				     hw_irq, irq_server, xics_status[1]);
++	status = rtas_call(ibm_set_xive, 3, 1, NULL,
++			   hw_irq, irq_server, xics_status[1]);
+ 
+ 	if (status) {
+ 		printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
+@@ -158,7 +158,7 @@ static int ics_rtas_check(struct ics *ics, unsigned int hw_irq)
+ 		return -EINVAL;
+ 
+ 	/* Check if RTAS knows about this interrupt */
+-	rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, hw_irq);
++	rc = rtas_call(ibm_get_xive, 1, 3, status, hw_irq);
+ 	if (rc)
+ 		return -ENXIO;
+ 
+@@ -174,7 +174,7 @@ static long ics_rtas_get_server(struct ics *ics, unsigned long vec)
+ {
+ 	int rc, status[2];
+ 
+-	rc = rtas_call_reentrant(ibm_get_xive, 1, 3, status, vec);
++	rc = rtas_call(ibm_get_xive, 1, 3, status, vec);
+ 	if (rc)
+ 		return -1;
+ 	return status[0];
+diff --git a/drivers/char/mem.c b/drivers/char/mem.c
+index 32a932a065a6a..5611d127363e4 100644
+--- a/drivers/char/mem.c
++++ b/drivers/char/mem.c
+@@ -712,8 +712,8 @@ static const struct memdev {
+ #endif
+ 	 [5] = { "zero", 0666, &zero_fops, FMODE_NOWAIT },
+ 	 [7] = { "full", 0666, &full_fops, 0 },
+-	 [8] = { "random", 0666, &random_fops, 0 },
+-	 [9] = { "urandom", 0666, &urandom_fops, 0 },
++	 [8] = { "random", 0666, &random_fops, FMODE_NOWAIT },
++	 [9] = { "urandom", 0666, &urandom_fops, FMODE_NOWAIT },
+ #ifdef CONFIG_PRINTK
+ 	[11] = { "kmsg", 0644, &kmsg_fops, 0 },
+ #endif
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index 79d7d4e4e5828..060f999dcffb3 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -920,20 +920,23 @@ EXPORT_SYMBOL_GPL(unregister_random_vmfork_notifier);
+ #endif
+ 
+ struct fast_pool {
+-	struct work_struct mix;
+ 	unsigned long pool[4];
+ 	unsigned long last;
+ 	unsigned int count;
++	struct timer_list mix;
+ };
+ 
++static void mix_interrupt_randomness(struct timer_list *work);
++
+ static DEFINE_PER_CPU(struct fast_pool, irq_randomness) = {
+ #ifdef CONFIG_64BIT
+ #define FASTMIX_PERM SIPHASH_PERMUTATION
+-	.pool = { SIPHASH_CONST_0, SIPHASH_CONST_1, SIPHASH_CONST_2, SIPHASH_CONST_3 }
++	.pool = { SIPHASH_CONST_0, SIPHASH_CONST_1, SIPHASH_CONST_2, SIPHASH_CONST_3 },
+ #else
+ #define FASTMIX_PERM HSIPHASH_PERMUTATION
+-	.pool = { HSIPHASH_CONST_0, HSIPHASH_CONST_1, HSIPHASH_CONST_2, HSIPHASH_CONST_3 }
++	.pool = { HSIPHASH_CONST_0, HSIPHASH_CONST_1, HSIPHASH_CONST_2, HSIPHASH_CONST_3 },
+ #endif
++	.mix = __TIMER_INITIALIZER(mix_interrupt_randomness, 0)
+ };
+ 
+ /*
+@@ -975,7 +978,7 @@ int __cold random_online_cpu(unsigned int cpu)
+ }
+ #endif
+ 
+-static void mix_interrupt_randomness(struct work_struct *work)
++static void mix_interrupt_randomness(struct timer_list *work)
+ {
+ 	struct fast_pool *fast_pool = container_of(work, struct fast_pool, mix);
+ 	/*
+@@ -1006,7 +1009,7 @@ static void mix_interrupt_randomness(struct work_struct *work)
+ 	local_irq_enable();
+ 
+ 	mix_pool_bytes(pool, sizeof(pool));
+-	credit_init_bits(max(1u, (count & U16_MAX) / 64));
++	credit_init_bits(clamp_t(unsigned int, (count & U16_MAX) / 64, 1, sizeof(pool) * 8));
+ 
+ 	memzero_explicit(pool, sizeof(pool));
+ }
+@@ -1029,10 +1032,11 @@ void add_interrupt_randomness(int irq)
+ 	if (new_count < 1024 && !time_is_before_jiffies(fast_pool->last + HZ))
+ 		return;
+ 
+-	if (unlikely(!fast_pool->mix.func))
+-		INIT_WORK(&fast_pool->mix, mix_interrupt_randomness);
+ 	fast_pool->count |= MIX_INFLIGHT;
+-	queue_work_on(raw_smp_processor_id(), system_highpri_wq, &fast_pool->mix);
++	if (!timer_pending(&fast_pool->mix)) {
++		fast_pool->mix.expires = jiffies;
++		add_timer_on(&fast_pool->mix, raw_smp_processor_id());
++	}
+ }
+ EXPORT_SYMBOL_GPL(add_interrupt_randomness);
+ 
+@@ -1347,6 +1351,11 @@ static ssize_t random_read_iter(struct kiocb *kiocb, struct iov_iter *iter)
+ {
+ 	int ret;
+ 
++	if (!crng_ready() &&
++	    ((kiocb->ki_flags & (IOCB_NOWAIT | IOCB_NOIO)) ||
++	     (kiocb->ki_filp->f_flags & O_NONBLOCK)))
++		return -EAGAIN;
++
+ 	ret = wait_for_random_bytes();
+ 	if (ret != 0)
+ 		return ret;
+diff --git a/drivers/crypto/qat/qat_common/qat_asym_algs.c b/drivers/crypto/qat/qat_common/qat_asym_algs.c
+index 095ed2a404d2f..85b0f30712e16 100644
+--- a/drivers/crypto/qat/qat_common/qat_asym_algs.c
++++ b/drivers/crypto/qat/qat_common/qat_asym_algs.c
+@@ -333,13 +333,13 @@ static int qat_dh_compute_value(struct kpp_request *req)
+ 	qat_req->out.dh.out_tab[1] = 0;
+ 	/* Mapping in.in.b or in.in_g2.xa is the same */
+ 	qat_req->phy_in = dma_map_single(dev, &qat_req->in.dh.in.b,
+-					 sizeof(qat_req->in.dh.in.b),
++					 sizeof(struct qat_dh_input_params),
+ 					 DMA_TO_DEVICE);
+ 	if (unlikely(dma_mapping_error(dev, qat_req->phy_in)))
+ 		goto unmap_dst;
+ 
+ 	qat_req->phy_out = dma_map_single(dev, &qat_req->out.dh.r,
+-					  sizeof(qat_req->out.dh.r),
++					  sizeof(struct qat_dh_output_params),
+ 					  DMA_TO_DEVICE);
+ 	if (unlikely(dma_mapping_error(dev, qat_req->phy_out)))
+ 		goto unmap_in_params;
+@@ -730,13 +730,13 @@ static int qat_rsa_enc(struct akcipher_request *req)
+ 	qat_req->in.rsa.in_tab[3] = 0;
+ 	qat_req->out.rsa.out_tab[1] = 0;
+ 	qat_req->phy_in = dma_map_single(dev, &qat_req->in.rsa.enc.m,
+-					 sizeof(qat_req->in.rsa.enc.m),
++					 sizeof(struct qat_rsa_input_params),
+ 					 DMA_TO_DEVICE);
+ 	if (unlikely(dma_mapping_error(dev, qat_req->phy_in)))
+ 		goto unmap_dst;
+ 
+ 	qat_req->phy_out = dma_map_single(dev, &qat_req->out.rsa.enc.c,
+-					  sizeof(qat_req->out.rsa.enc.c),
++					  sizeof(struct qat_rsa_output_params),
+ 					  DMA_TO_DEVICE);
+ 	if (unlikely(dma_mapping_error(dev, qat_req->phy_out)))
+ 		goto unmap_in_params;
+@@ -876,13 +876,13 @@ static int qat_rsa_dec(struct akcipher_request *req)
+ 		qat_req->in.rsa.in_tab[3] = 0;
+ 	qat_req->out.rsa.out_tab[1] = 0;
+ 	qat_req->phy_in = dma_map_single(dev, &qat_req->in.rsa.dec.c,
+-					 sizeof(qat_req->in.rsa.dec.c),
++					 sizeof(struct qat_rsa_input_params),
+ 					 DMA_TO_DEVICE);
+ 	if (unlikely(dma_mapping_error(dev, qat_req->phy_in)))
+ 		goto unmap_dst;
+ 
+ 	qat_req->phy_out = dma_map_single(dev, &qat_req->out.rsa.dec.m,
+-					  sizeof(qat_req->out.rsa.dec.m),
++					  sizeof(struct qat_rsa_output_params),
+ 					  DMA_TO_DEVICE);
+ 	if (unlikely(dma_mapping_error(dev, qat_req->phy_out)))
+ 		goto unmap_in_params;
+diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
+index 18190b529bca3..3da5fd5b5aaf4 100644
+--- a/drivers/input/joystick/xpad.c
++++ b/drivers/input/joystick/xpad.c
+@@ -113,6 +113,8 @@ static const struct xpad_device {
+ 	u8 xtype;
+ } xpad_device[] = {
+ 	{ 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 },
++	{ 0x03eb, 0xff01, "Wooting One (Legacy)", 0, XTYPE_XBOX360 },
++	{ 0x03eb, 0xff02, "Wooting Two (Legacy)", 0, XTYPE_XBOX360 },
+ 	{ 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX },
+ 	{ 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX },
+ 	{ 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX },
+@@ -244,6 +246,7 @@ static const struct xpad_device {
+ 	{ 0x0f0d, 0x0063, "Hori Real Arcade Pro Hayabusa (USA) Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
+ 	{ 0x0f0d, 0x0067, "HORIPAD ONE", 0, XTYPE_XBOXONE },
+ 	{ 0x0f0d, 0x0078, "Hori Real Arcade Pro V Kai Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
++	{ 0x0f0d, 0x00c5, "Hori Fighting Commander ONE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
+ 	{ 0x0f30, 0x010b, "Philips Recoil", 0, XTYPE_XBOX },
+ 	{ 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
+ 	{ 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
+@@ -260,6 +263,7 @@ static const struct xpad_device {
+ 	{ 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+ 	{ 0x1430, 0xf801, "RedOctane Controller", 0, XTYPE_XBOX360 },
+ 	{ 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
++	{ 0x146b, 0x0604, "Bigben Interactive DAIJA Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ 	{ 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+ 	{ 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
+ 	{ 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE },
+@@ -325,6 +329,7 @@ static const struct xpad_device {
+ 	{ 0x24c6, 0x5502, "Hori Fighting Stick VX Alt", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ 	{ 0x24c6, 0x5503, "Hori Fighting Edge", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ 	{ 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 },
++	{ 0x24c6, 0x5510, "Hori Fighting Commander ONE (Xbox 360/PC Mode)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ 	{ 0x24c6, 0x550d, "Hori GEM Xbox controller", 0, XTYPE_XBOX360 },
+ 	{ 0x24c6, 0x550e, "Hori Real Arcade Pro V Kai 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ 	{ 0x24c6, 0x551a, "PowerA FUSION Pro Controller", 0, XTYPE_XBOXONE },
+@@ -334,6 +339,14 @@ static const struct xpad_device {
+ 	{ 0x24c6, 0x5b03, "Thrustmaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 },
+ 	{ 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+ 	{ 0x24c6, 0xfafe, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
++	{ 0x2563, 0x058d, "OneXPlayer Gamepad", 0, XTYPE_XBOX360 },
++	{ 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE },
++	{ 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 },
++	{ 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 },
++	{ 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 },
++	{ 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 },
++	{ 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 },
++	{ 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 },
+ 	{ 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 },
+ 	{ 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX },
+ 	{ 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
+@@ -419,6 +432,7 @@ static const signed short xpad_abs_triggers[] = {
+ static const struct usb_device_id xpad_table[] = {
+ 	{ USB_INTERFACE_INFO('X', 'B', 0) },	/* X-Box USB-IF not approved class */
+ 	XPAD_XBOX360_VENDOR(0x0079),		/* GPD Win 2 Controller */
++	XPAD_XBOX360_VENDOR(0x03eb),		/* Wooting Keyboards (Legacy) */
+ 	XPAD_XBOX360_VENDOR(0x044f),		/* Thrustmaster X-Box 360 controllers */
+ 	XPAD_XBOX360_VENDOR(0x045e),		/* Microsoft X-Box 360 controllers */
+ 	XPAD_XBOXONE_VENDOR(0x045e),		/* Microsoft X-Box One controllers */
+@@ -429,6 +443,7 @@ static const struct usb_device_id xpad_table[] = {
+ 	{ USB_DEVICE(0x0738, 0x4540) },		/* Mad Catz Beat Pad */
+ 	XPAD_XBOXONE_VENDOR(0x0738),		/* Mad Catz FightStick TE 2 */
+ 	XPAD_XBOX360_VENDOR(0x07ff),		/* Mad Catz GamePad */
++	XPAD_XBOX360_VENDOR(0x0c12),		/* Zeroplus X-Box 360 controllers */
+ 	XPAD_XBOX360_VENDOR(0x0e6f),		/* 0x0e6f X-Box 360 controllers */
+ 	XPAD_XBOXONE_VENDOR(0x0e6f),		/* 0x0e6f X-Box One controllers */
+ 	XPAD_XBOX360_VENDOR(0x0f0d),		/* Hori Controllers */
+@@ -450,8 +465,12 @@ static const struct usb_device_id xpad_table[] = {
+ 	XPAD_XBOXONE_VENDOR(0x20d6),		/* PowerA Controllers */
+ 	XPAD_XBOX360_VENDOR(0x24c6),		/* PowerA Controllers */
+ 	XPAD_XBOXONE_VENDOR(0x24c6),		/* PowerA Controllers */
++	XPAD_XBOX360_VENDOR(0x2563),		/* OneXPlayer Gamepad */
++	XPAD_XBOX360_VENDOR(0x260d),		/* Dareu H101 */
++	XPAD_XBOXONE_VENDOR(0x2dc8),		/* 8BitDo Pro 2 Wired Controller for Xbox */
+ 	XPAD_XBOXONE_VENDOR(0x2e24),		/* Hyperkin Duke X-Box One pad */
+ 	XPAD_XBOX360_VENDOR(0x2f24),		/* GameSir Controllers */
++	XPAD_XBOX360_VENDOR(0x31e3),		/* Wooting Keyboards */
+ 	XPAD_XBOX360_VENDOR(0x3285),		/* Nacon GC-100 */
+ 	{ }
+ };
+@@ -1972,7 +1991,6 @@ static struct usb_driver xpad_driver = {
+ 	.disconnect	= xpad_disconnect,
+ 	.suspend	= xpad_suspend,
+ 	.resume		= xpad_resume,
+-	.reset_resume	= xpad_resume,
+ 	.id_table	= xpad_table,
+ };
+ 
+diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
+index 8f786a225dcf8..11530b4ec3892 100644
+--- a/drivers/misc/pci_endpoint_test.c
++++ b/drivers/misc/pci_endpoint_test.c
+@@ -332,6 +332,22 @@ static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
+ 	return false;
+ }
+ 
++static int pci_endpoint_test_validate_xfer_params(struct device *dev,
++		struct pci_endpoint_test_xfer_param *param, size_t alignment)
++{
++	if (!param->size) {
++		dev_dbg(dev, "Data size is zero\n");
++		return -EINVAL;
++	}
++
++	if (param->size > SIZE_MAX - alignment) {
++		dev_dbg(dev, "Maximum transfer data size exceeded\n");
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
+ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
+ 				   unsigned long arg)
+ {
+@@ -363,9 +379,11 @@ static bool pci_endpoint_test_copy(struct pci_endpoint_test *test,
+ 		return false;
+ 	}
+ 
++	err = pci_endpoint_test_validate_xfer_params(dev, &param, alignment);
++	if (err)
++		return false;
++
+ 	size = param.size;
+-	if (size > SIZE_MAX - alignment)
+-		goto err;
+ 
+ 	use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
+ 	if (use_dma)
+@@ -497,9 +515,11 @@ static bool pci_endpoint_test_write(struct pci_endpoint_test *test,
+ 		return false;
+ 	}
+ 
++	err = pci_endpoint_test_validate_xfer_params(dev, &param, alignment);
++	if (err)
++		return false;
++
+ 	size = param.size;
+-	if (size > SIZE_MAX - alignment)
+-		goto err;
+ 
+ 	use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
+ 	if (use_dma)
+@@ -595,9 +615,11 @@ static bool pci_endpoint_test_read(struct pci_endpoint_test *test,
+ 		return false;
+ 	}
+ 
++	err = pci_endpoint_test_validate_xfer_params(dev, &param, alignment);
++	if (err)
++		return false;
++
+ 	size = param.size;
+-	if (size > SIZE_MAX - alignment)
+-		goto err;
+ 
+ 	use_dma = !!(param.flags & PCITEST_FLAGS_USE_DMA);
+ 	if (use_dma)
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index 1f301a5fb3969..ee34814bd12b5 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -4526,6 +4526,8 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
+ 
+ 	rx_status.band = channel->band;
+ 	rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
++	if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates)
++		goto out;
+ 	rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
+ 
+ 	hdr = (void *)skb->data;
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 67d3335e9cc84..57cc2bb5b1a2b 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -2834,6 +2834,8 @@ static void nvme_reset_work(struct work_struct *work)
+ 		nvme_start_admin_queue(&dev->ctrl);
+ 	}
+ 
++	dma_set_min_align_mask(dev->dev, NVME_CTRL_PAGE_SIZE - 1);
++
+ 	/*
+ 	 * Limit the max command size to prevent iod->sg allocations going
+ 	 * over a single page.
+@@ -2846,7 +2848,6 @@ static void nvme_reset_work(struct work_struct *work)
+ 	 * Don't limit the IOMMU merged segment size.
+ 	 */
+ 	dma_set_max_seg_size(dev->dev, 0xffffffff);
+-	dma_set_min_align_mask(dev->dev, NVME_CTRL_PAGE_SIZE - 1);
+ 
+ 	mutex_unlock(&dev->shutdown_lock);
+ 
+diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
+index 5dd2932382ee3..bb69fa8b956a3 100644
+--- a/drivers/scsi/qla2xxx/qla_gbl.h
++++ b/drivers/scsi/qla2xxx/qla_gbl.h
+@@ -193,8 +193,6 @@ extern int ql2xsecenable;
+ extern int ql2xenforce_iocb_limit;
+ extern int ql2xabts_wait_nvme;
+ extern u32 ql2xnvme_queues;
+-extern int ql2xrspq_follow_inptr;
+-extern int ql2xrspq_follow_inptr_legacy;
+ 
+ extern int qla2x00_loop_reset(scsi_qla_host_t *);
+ extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
+diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
+index 76e79f350a226..e19fde304e5c6 100644
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -3764,7 +3764,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
+ 	struct purex_entry_24xx *purex_entry;
+ 	struct purex_item *pure_item;
+ 	u16 rsp_in = 0, cur_ring_index;
+-	int follow_inptr, is_shadow_hba;
++	int is_shadow_hba;
+ 
+ 	if (!ha->flags.fw_started)
+ 		return;
+@@ -3774,25 +3774,18 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
+ 		qla_cpu_update(rsp->qpair, smp_processor_id());
+ 	}
+ 
+-#define __update_rsp_in(_update, _is_shadow_hba, _rsp, _rsp_in)		\
++#define __update_rsp_in(_is_shadow_hba, _rsp, _rsp_in)			\
+ 	do {								\
+-		if (_update) {						\
+-			_rsp_in = _is_shadow_hba ? *(_rsp)->in_ptr :	\
++		_rsp_in = _is_shadow_hba ? *(_rsp)->in_ptr :		\
+ 				rd_reg_dword_relaxed((_rsp)->rsp_q_in);	\
+-		}							\
+ 	} while (0)
+ 
+ 	is_shadow_hba = IS_SHADOW_REG_CAPABLE(ha);
+-	follow_inptr = is_shadow_hba ? ql2xrspq_follow_inptr :
+-				ql2xrspq_follow_inptr_legacy;
+ 
+-	__update_rsp_in(follow_inptr, is_shadow_hba, rsp, rsp_in);
++	__update_rsp_in(is_shadow_hba, rsp, rsp_in);
+ 
+-	while ((likely(follow_inptr &&
+-		       rsp->ring_index != rsp_in &&
+-		       rsp->ring_ptr->signature != RESPONSE_PROCESSED)) ||
+-		       (!follow_inptr &&
+-			rsp->ring_ptr->signature != RESPONSE_PROCESSED)) {
++	while (rsp->ring_index != rsp_in &&
++		       rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
+ 		pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
+ 		cur_ring_index = rsp->ring_index;
+ 
+@@ -3906,8 +3899,7 @@ process_err:
+ 				}
+ 				pure_item = qla27xx_copy_fpin_pkt(vha,
+ 							  (void **)&pkt, &rsp);
+-				__update_rsp_in(follow_inptr, is_shadow_hba,
+-						rsp, rsp_in);
++				__update_rsp_in(is_shadow_hba, rsp, rsp_in);
+ 				if (!pure_item)
+ 					break;
+ 				qla24xx_queue_purex_item(vha, pure_item,
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 0bd0fd1042dfe..1c7fb6484db20 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -338,16 +338,6 @@ module_param(ql2xdelay_before_pci_error_handling, uint, 0644);
+ MODULE_PARM_DESC(ql2xdelay_before_pci_error_handling,
+ 	"Number of seconds delayed before qla begin PCI error self-handling (default: 5).\n");
+ 
+-int ql2xrspq_follow_inptr = 1;
+-module_param(ql2xrspq_follow_inptr, int, 0644);
+-MODULE_PARM_DESC(ql2xrspq_follow_inptr,
+-		 "Follow RSP IN pointer for RSP updates for HBAs 27xx and newer (default: 1).");
+-
+-int ql2xrspq_follow_inptr_legacy = 1;
+-module_param(ql2xrspq_follow_inptr_legacy, int, 0644);
+-MODULE_PARM_DESC(ql2xrspq_follow_inptr_legacy,
+-		 "Follow RSP IN pointer for RSP updates for HBAs older than 27XX. (default: 1).");
+-
+ static void qla2x00_clear_drv_active(struct qla_hw_data *);
+ static void qla2x00_free_device(scsi_qla_host_t *);
+ static int qla2xxx_map_queues(struct Scsi_Host *shost);
+diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
+index e6420f2127ce1..8def242675ef3 100644
+--- a/drivers/scsi/stex.c
++++ b/drivers/scsi/stex.c
+@@ -665,16 +665,17 @@ static int stex_queuecommand_lck(struct scsi_cmnd *cmd)
+ 		return 0;
+ 	case PASSTHRU_CMD:
+ 		if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) {
+-			struct st_drvver ver;
++			const struct st_drvver ver = {
++				.major = ST_VER_MAJOR,
++				.minor = ST_VER_MINOR,
++				.oem = ST_OEM,
++				.build = ST_BUILD_VER,
++				.signature[0] = PASSTHRU_SIGNATURE,
++				.console_id = host->max_id - 1,
++				.host_no = hba->host->host_no,
++			};
+ 			size_t cp_len = sizeof(ver);
+ 
+-			ver.major = ST_VER_MAJOR;
+-			ver.minor = ST_VER_MINOR;
+-			ver.oem = ST_OEM;
+-			ver.build = ST_BUILD_VER;
+-			ver.signature[0] = PASSTHRU_SIGNATURE;
+-			ver.console_id = host->max_id - 1;
+-			ver.host_no = hba->host->host_no;
+ 			cp_len = scsi_sg_copy_from_buffer(cmd, &ver, cp_len);
+ 			if (sizeof(ver) == cp_len)
+ 				cmd->result = DID_OK << 16;
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index d0237b30c9bef..219d797e22301 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -23,7 +23,6 @@
+ #include <linux/delay.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/of.h>
+-#include <linux/of_graph.h>
+ #include <linux/acpi.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/reset.h>
+@@ -86,7 +85,7 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
+ 		 * mode. If the controller supports DRD but the dr_mode is not
+ 		 * specified or set to OTG, then set the mode to peripheral.
+ 		 */
+-		if (mode == USB_DR_MODE_OTG && !dwc->edev &&
++		if (mode == USB_DR_MODE_OTG &&
+ 		    (!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) ||
+ 		     !device_property_read_bool(dwc->dev, "usb-role-switch")) &&
+ 		    !DWC3_VER_IS_PRIOR(DWC3, 330A))
+@@ -1668,46 +1667,6 @@ static void dwc3_check_params(struct dwc3 *dwc)
+ 	}
+ }
+ 
+-static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
+-{
+-	struct device *dev = dwc->dev;
+-	struct device_node *np_phy;
+-	struct extcon_dev *edev = NULL;
+-	const char *name;
+-
+-	if (device_property_read_bool(dev, "extcon"))
+-		return extcon_get_edev_by_phandle(dev, 0);
+-
+-	/*
+-	 * Device tree platforms should get extcon via phandle.
+-	 * On ACPI platforms, we get the name from a device property.
+-	 * This device property is for kernel internal use only and
+-	 * is expected to be set by the glue code.
+-	 */
+-	if (device_property_read_string(dev, "linux,extcon-name", &name) == 0)
+-		return extcon_get_extcon_dev(name);
+-
+-	/*
+-	 * Try to get an extcon device from the USB PHY controller's "port"
+-	 * node. Check if it has the "port" node first, to avoid printing the
+-	 * error message from underlying code, as it's a valid case: extcon
+-	 * device (and "port" node) may be missing in case of "usb-role-switch"
+-	 * or OTG mode.
+-	 */
+-	np_phy = of_parse_phandle(dev->of_node, "phys", 0);
+-	if (of_graph_is_present(np_phy)) {
+-		struct device_node *np_conn;
+-
+-		np_conn = of_graph_get_remote_node(np_phy, -1, -1);
+-		if (np_conn)
+-			edev = extcon_find_edev_by_node(np_conn);
+-		of_node_put(np_conn);
+-	}
+-	of_node_put(np_phy);
+-
+-	return edev;
+-}
+-
+ static int dwc3_probe(struct platform_device *pdev)
+ {
+ 	struct device		*dev = &pdev->dev;
+@@ -1844,13 +1803,6 @@ static int dwc3_probe(struct platform_device *pdev)
+ 		goto err2;
+ 	}
+ 
+-	dwc->edev = dwc3_get_extcon(dwc);
+-	if (IS_ERR(dwc->edev)) {
+-		ret = PTR_ERR(dwc->edev);
+-		dev_err_probe(dwc->dev, ret, "failed to get extcon\n");
+-		goto err3;
+-	}
+-
+ 	ret = dwc3_get_dr_mode(dwc);
+ 	if (ret)
+ 		goto err3;
+diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c
+index 039bf241769af..8cad9e7d33687 100644
+--- a/drivers/usb/dwc3/drd.c
++++ b/drivers/usb/dwc3/drd.c
+@@ -8,6 +8,7 @@
+  */
+ 
+ #include <linux/extcon.h>
++#include <linux/of_graph.h>
+ #include <linux/of_platform.h>
+ #include <linux/platform_device.h>
+ #include <linux/property.h>
+@@ -438,6 +439,51 @@ static int dwc3_drd_notifier(struct notifier_block *nb,
+ 	return NOTIFY_DONE;
+ }
+ 
++static struct extcon_dev *dwc3_get_extcon(struct dwc3 *dwc)
++{
++	struct device *dev = dwc->dev;
++	struct device_node *np_phy;
++	struct extcon_dev *edev = NULL;
++	const char *name;
++
++	if (device_property_read_bool(dev, "extcon"))
++		return extcon_get_edev_by_phandle(dev, 0);
++
++	/*
++	 * Device tree platforms should get extcon via phandle.
++	 * On ACPI platforms, we get the name from a device property.
++	 * This device property is for kernel internal use only and
++	 * is expected to be set by the glue code.
++	 */
++	if (device_property_read_string(dev, "linux,extcon-name", &name) == 0) {
++		edev = extcon_get_extcon_dev(name);
++		if (!edev)
++			return ERR_PTR(-EPROBE_DEFER);
++
++		return edev;
++	}
++
++	/*
++	 * Try to get an extcon device from the USB PHY controller's "port"
++	 * node. Check if it has the "port" node first, to avoid printing the
++	 * error message from underlying code, as it's a valid case: extcon
++	 * device (and "port" node) may be missing in case of "usb-role-switch"
++	 * or OTG mode.
++	 */
++	np_phy = of_parse_phandle(dev->of_node, "phys", 0);
++	if (of_graph_is_present(np_phy)) {
++		struct device_node *np_conn;
++
++		np_conn = of_graph_get_remote_node(np_phy, -1, -1);
++		if (np_conn)
++			edev = extcon_find_edev_by_node(np_conn);
++		of_node_put(np_conn);
++	}
++	of_node_put(np_phy);
++
++	return edev;
++}
++
+ #if IS_ENABLED(CONFIG_USB_ROLE_SWITCH)
+ #define ROLE_SWITCH 1
+ static int dwc3_usb_role_switch_set(struct usb_role_switch *sw,
+@@ -542,6 +588,10 @@ int dwc3_drd_init(struct dwc3 *dwc)
+ 	    device_property_read_bool(dwc->dev, "usb-role-switch"))
+ 		return dwc3_setup_role_switch(dwc);
+ 
++	dwc->edev = dwc3_get_extcon(dwc);
++	if (IS_ERR(dwc->edev))
++		return PTR_ERR(dwc->edev);
++
+ 	if (dwc->edev) {
+ 		dwc->edev_nb.notifier_call = dwc3_drd_notifier;
+ 		ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST,
+diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
+index 586ef5551e76e..b1e844bf31f81 100644
+--- a/drivers/usb/serial/qcserial.c
++++ b/drivers/usb/serial/qcserial.c
+@@ -177,6 +177,7 @@ static const struct usb_device_id id_table[] = {
+ 	{DEVICE_SWI(0x413c, 0x81b3)},	/* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
+ 	{DEVICE_SWI(0x413c, 0x81b5)},	/* Dell Wireless 5811e QDL */
+ 	{DEVICE_SWI(0x413c, 0x81b6)},	/* Dell Wireless 5811e QDL */
++	{DEVICE_SWI(0x413c, 0x81c2)},	/* Dell Wireless 5811e */
+ 	{DEVICE_SWI(0x413c, 0x81cb)},	/* Dell Wireless 5816e QDL */
+ 	{DEVICE_SWI(0x413c, 0x81cc)},	/* Dell Wireless 5816e */
+ 	{DEVICE_SWI(0x413c, 0x81cf)},   /* Dell Wireless 5819 */
+diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
+index 67f63cfeade5c..232dd7b6cca14 100644
+--- a/fs/nilfs2/inode.c
++++ b/fs/nilfs2/inode.c
+@@ -328,6 +328,7 @@ struct inode *nilfs_new_inode(struct inode *dir, umode_t mode)
+ 	struct inode *inode;
+ 	struct nilfs_inode_info *ii;
+ 	struct nilfs_root *root;
++	struct buffer_head *bh;
+ 	int err = -ENOMEM;
+ 	ino_t ino;
+ 
+@@ -343,11 +344,25 @@ struct inode *nilfs_new_inode(struct inode *dir, umode_t mode)
+ 	ii->i_state = BIT(NILFS_I_NEW);
+ 	ii->i_root = root;
+ 
+-	err = nilfs_ifile_create_inode(root->ifile, &ino, &ii->i_bh);
++	err = nilfs_ifile_create_inode(root->ifile, &ino, &bh);
+ 	if (unlikely(err))
+ 		goto failed_ifile_create_inode;
+ 	/* reference count of i_bh inherits from nilfs_mdt_read_block() */
+ 
++	if (unlikely(ino < NILFS_USER_INO)) {
++		nilfs_warn(sb,
++			   "inode bitmap is inconsistent for reserved inodes");
++		do {
++			brelse(bh);
++			err = nilfs_ifile_create_inode(root->ifile, &ino, &bh);
++			if (unlikely(err))
++				goto failed_ifile_create_inode;
++		} while (ino < NILFS_USER_INO);
++
++		nilfs_info(sb, "repaired inode bitmap for reserved inodes");
++	}
++	ii->i_bh = bh;
++
+ 	atomic64_inc(&root->inodes_count);
+ 	inode_init_owner(&init_user_ns, inode, dir, mode);
+ 	inode->i_ino = ino;
+@@ -440,6 +455,8 @@ int nilfs_read_inode_common(struct inode *inode,
+ 	inode->i_atime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec);
+ 	inode->i_ctime.tv_nsec = le32_to_cpu(raw_inode->i_ctime_nsec);
+ 	inode->i_mtime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec);
++	if (nilfs_is_metadata_file_inode(inode) && !S_ISREG(inode->i_mode))
++		return -EIO; /* this inode is for metadata and corrupted */
+ 	if (inode->i_nlink == 0)
+ 		return -ESTALE; /* this inode is deleted */
+ 
+diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
+index 0afe0832c7547..56d2c6fc61753 100644
+--- a/fs/nilfs2/segment.c
++++ b/fs/nilfs2/segment.c
+@@ -875,9 +875,11 @@ static int nilfs_segctor_create_checkpoint(struct nilfs_sc_info *sci)
+ 		nilfs_mdt_mark_dirty(nilfs->ns_cpfile);
+ 		nilfs_cpfile_put_checkpoint(
+ 			nilfs->ns_cpfile, nilfs->ns_cno, bh_cp);
+-	} else
+-		WARN_ON(err == -EINVAL || err == -ENOENT);
+-
++	} else if (err == -EINVAL || err == -ENOENT) {
++		nilfs_error(sci->sc_super,
++			    "checkpoint creation failed due to metadata corruption.");
++		err = -EIO;
++	}
+ 	return err;
+ }
+ 
+@@ -891,7 +893,11 @@ static int nilfs_segctor_fill_in_checkpoint(struct nilfs_sc_info *sci)
+ 	err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, nilfs->ns_cno, 0,
+ 					  &raw_cp, &bh_cp);
+ 	if (unlikely(err)) {
+-		WARN_ON(err == -EINVAL || err == -ENOENT);
++		if (err == -EINVAL || err == -ENOENT) {
++			nilfs_error(sci->sc_super,
++				    "checkpoint finalization failed due to metadata corruption.");
++			err = -EIO;
++		}
+ 		goto failed_ibh;
+ 	}
+ 	raw_cp->cp_snapshot_list.ssl_next = 0;
+@@ -2786,10 +2792,9 @@ int nilfs_attach_log_writer(struct super_block *sb, struct nilfs_root *root)
+ 	inode_attach_wb(nilfs->ns_bdev->bd_inode, NULL);
+ 
+ 	err = nilfs_segctor_start_thread(nilfs->ns_writer);
+-	if (err) {
+-		kfree(nilfs->ns_writer);
+-		nilfs->ns_writer = NULL;
+-	}
++	if (unlikely(err))
++		nilfs_detach_log_writer(sb);
++
+ 	return err;
+ }
+ 
+diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
+index bac55decf900a..7d3622db38edc 100644
+--- a/include/scsi/scsi_cmnd.h
++++ b/include/scsi/scsi_cmnd.h
+@@ -201,7 +201,7 @@ static inline unsigned int scsi_get_resid(struct scsi_cmnd *cmd)
+ 	for_each_sg(scsi_sglist(cmd), sg, nseg, __i)
+ 
+ static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd,
+-					   void *buf, int buflen)
++					   const void *buf, int buflen)
+ {
+ 	return sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
+ 				   buf, buflen);
+diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
+index e192e1ec02610..9583643b70332 100644
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1704,6 +1704,14 @@ struct ieee802_11_elems {
+ 
+ 	/* whether a parse error occurred while retrieving these elements */
+ 	bool parse_error;
++
++	/*
++	 * scratch buffer that can be used for various element parsing related
++	 * tasks, e.g., element de-fragmentation etc.
++	 */
++	size_t scratch_len;
++	u8 *scratch_pos;
++	u8 scratch[];
+ };
+ 
+ static inline struct ieee80211_local *hw_to_local(
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 45d7e71661e3f..211de01bf6153 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -1967,10 +1967,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
+ 
+ 		if (mmie_keyidx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS ||
+ 		    mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
+-		    NUM_DEFAULT_BEACON_KEYS) {
+-			cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
+-						     skb->data,
+-						     skb->len);
++				   NUM_DEFAULT_BEACON_KEYS) {
++			if (rx->sdata->dev)
++				cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
++							     skb->data,
++							     skb->len);
+ 			return RX_DROP_MONITOR; /* unexpected BIP keyidx */
+ 		}
+ 
+@@ -2121,7 +2122,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
+ 	/* either the frame has been decrypted or will be dropped */
+ 	status->flag |= RX_FLAG_DECRYPTED;
+ 
+-	if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE))
++	if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE &&
++		     rx->sdata->dev))
+ 		cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
+ 					     skb->data, skb->len);
+ 
+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
+index efcefb2dd8826..4fc3d545e6667 100644
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -1442,6 +1442,8 @@ static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len,
+ 	for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
+ 		if (elem->datalen < 2)
+ 			continue;
++		if (elem->data[0] < 1 || elem->data[0] > 8)
++			continue;
+ 
+ 		for_each_element(sub, elem->data + 1, elem->datalen - 1) {
+ 			u8 new_bssid[ETH_ALEN];
+@@ -1501,24 +1503,26 @@ ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)
+ 	const struct element *non_inherit = NULL;
+ 	u8 *nontransmitted_profile;
+ 	int nontransmitted_profile_len = 0;
++	size_t scratch_len = params->len;
+ 
+-	elems = kzalloc(sizeof(*elems), GFP_ATOMIC);
++	elems = kzalloc(sizeof(*elems) + scratch_len, GFP_ATOMIC);
+ 	if (!elems)
+ 		return NULL;
+ 	elems->ie_start = params->start;
+ 	elems->total_len = params->len;
+-
+-	nontransmitted_profile = kmalloc(params->len, GFP_ATOMIC);
+-	if (nontransmitted_profile) {
+-		nontransmitted_profile_len =
+-			ieee802_11_find_bssid_profile(params->start, params->len,
+-						      elems, params->bss,
+-						      nontransmitted_profile);
+-		non_inherit =
+-			cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
+-					       nontransmitted_profile,
+-					       nontransmitted_profile_len);
+-	}
++	elems->scratch_len = scratch_len;
++	elems->scratch_pos = elems->scratch;
++
++	nontransmitted_profile = elems->scratch_pos;
++	nontransmitted_profile_len =
++		ieee802_11_find_bssid_profile(params->start, params->len,
++					      elems, params->bss,
++					      nontransmitted_profile);
++	elems->scratch_pos += nontransmitted_profile_len;
++	elems->scratch_len -= nontransmitted_profile_len;
++	non_inherit = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
++					     nontransmitted_profile,
++					     nontransmitted_profile_len);
+ 
+ 	elems->crc = _ieee802_11_parse_elems_full(params, elems, non_inherit);
+ 
+@@ -1552,8 +1556,6 @@ ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)
+ 	    offsetofend(struct ieee80211_bssid_index, dtim_count))
+ 		elems->dtim_count = elems->bssid_index->dtim_count;
+ 
+-	kfree(nontransmitted_profile);
+-
+ 	return elems;
+ }
+ 
+diff --git a/net/mctp/af_mctp.c b/net/mctp/af_mctp.c
+index c2fc2a7b25285..b6b5e496fa403 100644
+--- a/net/mctp/af_mctp.c
++++ b/net/mctp/af_mctp.c
+@@ -295,11 +295,12 @@ __must_hold(&net->mctp.keys_lock)
+ 	mctp_dev_release_key(key->dev, key);
+ 	spin_unlock_irqrestore(&key->lock, flags);
+ 
+-	hlist_del(&key->hlist);
+-	hlist_del(&key->sklist);
+-
+-	/* unref for the lists */
+-	mctp_key_unref(key);
++	if (!hlist_unhashed(&key->hlist)) {
++		hlist_del_init(&key->hlist);
++		hlist_del_init(&key->sklist);
++		/* unref for the lists */
++		mctp_key_unref(key);
++	}
+ 
+ 	kfree_skb(skb);
+ }
+@@ -373,9 +374,17 @@ static int mctp_ioctl_alloctag(struct mctp_sock *msk, unsigned long arg)
+ 
+ 	ctl.tag = tag | MCTP_TAG_OWNER | MCTP_TAG_PREALLOC;
+ 	if (copy_to_user((void __user *)arg, &ctl, sizeof(ctl))) {
+-		spin_lock_irqsave(&key->lock, flags);
+-		__mctp_key_remove(key, net, flags, MCTP_TRACE_KEY_DROPPED);
++		unsigned long fl2;
++		/* Unwind our key allocation: the keys list lock needs to be
++		 * taken before the individual key locks, and we need a valid
++		 * flags value (fl2) to pass to __mctp_key_remove, hence the
++		 * second spin_lock_irqsave() rather than a plain spin_lock().
++		 */
++		spin_lock_irqsave(&net->mctp.keys_lock, flags);
++		spin_lock_irqsave(&key->lock, fl2);
++		__mctp_key_remove(key, net, fl2, MCTP_TRACE_KEY_DROPPED);
+ 		mctp_key_unref(key);
++		spin_unlock_irqrestore(&net->mctp.keys_lock, flags);
+ 		return -EFAULT;
+ 	}
+ 
+diff --git a/net/mctp/route.c b/net/mctp/route.c
+index 3b24b8d18b5b5..2155f15a074cd 100644
+--- a/net/mctp/route.c
++++ b/net/mctp/route.c
+@@ -228,12 +228,12 @@ __releases(&key->lock)
+ 
+ 	if (!key->manual_alloc) {
+ 		spin_lock_irqsave(&net->mctp.keys_lock, flags);
+-		hlist_del(&key->hlist);
+-		hlist_del(&key->sklist);
++		if (!hlist_unhashed(&key->hlist)) {
++			hlist_del_init(&key->hlist);
++			hlist_del_init(&key->sklist);
++			mctp_key_unref(key);
++		}
+ 		spin_unlock_irqrestore(&net->mctp.keys_lock, flags);
+-
+-		/* unref for the lists */
+-		mctp_key_unref(key);
+ 	}
+ 
+ 	/* and one for the local reference */
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 0134e5d5c81a4..39fb9cc25cdca 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -143,18 +143,12 @@ static inline void bss_ref_get(struct cfg80211_registered_device *rdev,
+ 	lockdep_assert_held(&rdev->bss_lock);
+ 
+ 	bss->refcount++;
+-	if (bss->pub.hidden_beacon_bss) {
+-		bss = container_of(bss->pub.hidden_beacon_bss,
+-				   struct cfg80211_internal_bss,
+-				   pub);
+-		bss->refcount++;
+-	}
+-	if (bss->pub.transmitted_bss) {
+-		bss = container_of(bss->pub.transmitted_bss,
+-				   struct cfg80211_internal_bss,
+-				   pub);
+-		bss->refcount++;
+-	}
++
++	if (bss->pub.hidden_beacon_bss)
++		bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++;
++
++	if (bss->pub.transmitted_bss)
++		bss_from_pub(bss->pub.transmitted_bss)->refcount++;
+ }
+ 
+ static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
+@@ -304,7 +298,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
+ 	tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
+ 	tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
+ 
+-	while (tmp_old + tmp_old[1] + 2 - ie <= ielen) {
++	while (tmp_old + 2 - ie <= ielen &&
++	       tmp_old + tmp_old[1] + 2 - ie <= ielen) {
+ 		if (tmp_old[0] == 0) {
+ 			tmp_old++;
+ 			continue;
+@@ -364,7 +359,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
+ 	 * copied to new ie, skip ssid, capability, bssid-index ie
+ 	 */
+ 	tmp_new = sub_copy;
+-	while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
++	while (tmp_new + 2 - sub_copy <= subie_len &&
++	       tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
+ 		if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP ||
+ 		      tmp_new[0] == WLAN_EID_SSID)) {
+ 			memcpy(pos, tmp_new, tmp_new[1] + 2);
+@@ -427,6 +423,15 @@ cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss,
+ 
+ 	rcu_read_unlock();
+ 
++	/*
++	 * This is a bit weird - it's not on the list, but already on another
++	 * one! The only way that could happen is if there's some BSSID/SSID
++	 * shared by multiple APs in their multi-BSSID profiles, potentially
++	 * with hidden SSID mixed in ... ignore it.
++	 */
++	if (!list_empty(&nontrans_bss->nontrans_list))
++		return -EINVAL;
++
+ 	/* add to the list */
+ 	list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list);
+ 	return 0;
+@@ -1602,6 +1607,23 @@ struct cfg80211_non_tx_bss {
+ 	u8 bssid_index;
+ };
+ 
++static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known,
++					 const struct cfg80211_bss_ies *new_ies,
++					 const struct cfg80211_bss_ies *old_ies)
++{
++	struct cfg80211_internal_bss *bss;
++
++	/* Assign beacon IEs to all sub entries */
++	list_for_each_entry(bss, &known->hidden_list, hidden_list) {
++		const struct cfg80211_bss_ies *ies;
++
++		ies = rcu_access_pointer(bss->pub.beacon_ies);
++		WARN_ON(ies != old_ies);
++
++		rcu_assign_pointer(bss->pub.beacon_ies, new_ies);
++	}
++}
++
+ static bool
+ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
+ 			  struct cfg80211_internal_bss *known,
+@@ -1625,7 +1647,6 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
+ 			kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
+ 	} else if (rcu_access_pointer(new->pub.beacon_ies)) {
+ 		const struct cfg80211_bss_ies *old;
+-		struct cfg80211_internal_bss *bss;
+ 
+ 		if (known->pub.hidden_beacon_bss &&
+ 		    !list_empty(&known->hidden_list)) {
+@@ -1653,16 +1674,7 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
+ 		if (old == rcu_access_pointer(known->pub.ies))
+ 			rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
+ 
+-		/* Assign beacon IEs to all sub entries */
+-		list_for_each_entry(bss, &known->hidden_list, hidden_list) {
+-			const struct cfg80211_bss_ies *ies;
+-
+-			ies = rcu_access_pointer(bss->pub.beacon_ies);
+-			WARN_ON(ies != old);
+-
+-			rcu_assign_pointer(bss->pub.beacon_ies,
+-					   new->pub.beacon_ies);
+-		}
++		cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old);
+ 
+ 		if (old)
+ 			kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
+@@ -1739,6 +1751,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
+ 		new->refcount = 1;
+ 		INIT_LIST_HEAD(&new->hidden_list);
+ 		INIT_LIST_HEAD(&new->pub.nontrans_list);
++		/* we'll set this later if it was non-NULL */
++		new->pub.transmitted_bss = NULL;
+ 
+ 		if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
+ 			hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
+@@ -2021,10 +2035,15 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
+ 		spin_lock_bh(&rdev->bss_lock);
+ 		if (cfg80211_add_nontrans_list(non_tx_data->tx_bss,
+ 					       &res->pub)) {
+-			if (__cfg80211_unlink_bss(rdev, res))
++			if (__cfg80211_unlink_bss(rdev, res)) {
+ 				rdev->bss_generation++;
++				res = NULL;
++			}
+ 		}
+ 		spin_unlock_bh(&rdev->bss_lock);
++
++		if (!res)
++			return NULL;
+ 	}
+ 
+ 	trace_cfg80211_return_bss(&res->pub);
+@@ -2143,6 +2162,8 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
+ 	for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
+ 		if (elem->datalen < 4)
+ 			continue;
++		if (elem->data[0] < 1 || (int)elem->data[0] > 8)
++			continue;
+ 		for_each_element(sub, elem->data + 1, elem->datalen - 1) {
+ 			u8 profile_len;
+ 
+@@ -2279,7 +2300,7 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
+ 	size_t new_ie_len;
+ 	struct cfg80211_bss_ies *new_ies;
+ 	const struct cfg80211_bss_ies *old;
+-	u8 cpy_len;
++	size_t cpy_len;
+ 
+ 	lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock);
+ 
+@@ -2346,6 +2367,8 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
+ 	} else {
+ 		old = rcu_access_pointer(nontrans_bss->beacon_ies);
+ 		rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies);
++		cfg80211_update_hidden_bsses(bss_from_pub(nontrans_bss),
++					     new_ies, old);
+ 		rcu_assign_pointer(nontrans_bss->ies, new_ies);
+ 		if (old)
+ 			kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
+diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c
+index 093894a640dca..b78753d27d8ea 100644
+--- a/security/integrity/platform_certs/load_uefi.c
++++ b/security/integrity/platform_certs/load_uefi.c
+@@ -31,7 +31,7 @@ static const struct dmi_system_id uefi_skip_cert[] = {
+ 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,1") },
+ 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,2") },
+ 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir9,1") },
+-	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacMini8,1") },
++	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "Macmini8,1") },
+ 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") },
+ 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") },
+ 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") },
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 6f30c374f896e..1631e1de84046 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2554,7 +2554,8 @@ static const struct pci_device_id azx_ids[] = {
+ 	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },
+ 	/* Poulsbo */
+ 	{ PCI_DEVICE(0x8086, 0x811b),
+-	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
++	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE |
++	  AZX_DCAPS_POSFIX_LPIB },
+ 	/* Oaktrail */
+ 	{ PCI_DEVICE(0x8086, 0x080a),
+ 	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE },
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index f9d46ae4c7b71..3dc19174670eb 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6741,6 +6741,11 @@ static void cs35l41_fixup_spi_two(struct hda_codec *codec, const struct hda_fixu
+ 	cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 2);
+ }
+ 
++static void cs35l41_fixup_spi1_two(struct hda_codec *codec, const struct hda_fixup *fix, int action)
++{
++	cs35l41_generic_fixup(codec, action, "spi1", "CSC3551", 2);
++}
++
+ static void cs35l41_fixup_spi_four(struct hda_codec *codec, const struct hda_fixup *fix, int action)
+ {
+ 	cs35l41_generic_fixup(codec, action, "spi0", "CSC3551", 4);
+@@ -7132,6 +7137,8 @@ enum {
+ 	ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED,
+ 	ALC245_FIXUP_CS35L41_SPI_2,
+ 	ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED,
++	ALC245_FIXUP_CS35L41_SPI1_2,
++	ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED,
+ 	ALC245_FIXUP_CS35L41_SPI_4,
+ 	ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED,
+ 	ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
+@@ -8979,6 +8986,16 @@ static const struct hda_fixup alc269_fixups[] = {
+ 		.chained = true,
+ 		.chain_id = ALC285_FIXUP_HP_GPIO_LED,
+ 	},
++	[ALC245_FIXUP_CS35L41_SPI1_2] = {
++		.type = HDA_FIXUP_FUNC,
++		.v.func = cs35l41_fixup_spi1_two,
++	},
++	[ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED] = {
++		.type = HDA_FIXUP_FUNC,
++		.v.func = cs35l41_fixup_spi1_two,
++		.chained = true,
++		.chain_id = ALC285_FIXUP_HP_GPIO_LED,
++	},
+ 	[ALC245_FIXUP_CS35L41_SPI_4] = {
+ 		.type = HDA_FIXUP_FUNC,
+ 		.v.func = cs35l41_fixup_spi_four,
+@@ -9341,6 +9358,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8aa8, "HP EliteBook 640 G9 (MB 8AA6)", ALC236_FIXUP_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8aab, "HP EliteBook 650 G9 (MB 8AA9)", ALC236_FIXUP_HP_GPIO_LED),
++	 SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI1_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
+ 	SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-10-12 11:16 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-10-12 11:16 UTC (permalink / raw
  To: gentoo-commits

commit:     8490dd01d19bf4575c039ed85c60163a5c2bad17
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 12 11:16:28 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Oct 12 11:16:28 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=8490dd01

Linux patch 6.0.1

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

 0000_README            |   4 +
 1000_linux-6.0.1.patch | 771 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 775 insertions(+)

diff --git a/0000_README b/0000_README
index b1b7f794..d41088d3 100644
--- a/0000_README
+++ b/0000_README
@@ -43,6 +43,10 @@ EXPERIMENTAL
 Individual Patch Descriptions:
 --------------------------------------------------------------------------
 
+Patch:  1000_linux-6.0.1.patch
+From:   http://www.kernel.org
+Desc:   Linux 6.0.1
+
 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/1000_linux-6.0.1.patch b/1000_linux-6.0.1.patch
new file mode 100644
index 00000000..9165364b
--- /dev/null
+++ b/1000_linux-6.0.1.patch
@@ -0,0 +1,771 @@
+diff --git a/Documentation/process/code-of-conduct-interpretation.rst b/Documentation/process/code-of-conduct-interpretation.rst
+index e899f14a4ba24..4f8a06b00f608 100644
+--- a/Documentation/process/code-of-conduct-interpretation.rst
++++ b/Documentation/process/code-of-conduct-interpretation.rst
+@@ -51,7 +51,7 @@ the Technical Advisory Board (TAB) or other maintainers if you're
+ uncertain how to handle situations that come up.  It will not be
+ considered a violation report unless you want it to be.  If you are
+ uncertain about approaching the TAB or any other maintainers, please
+-reach out to our conflict mediator, Mishi Choudhary <mishi@linux.com>.
++reach out to our conflict mediator, Joanna Lee <joanna.lee@gesmer.com>.
+ 
+ In the end, "be kind to each other" is really what the end goal is for
+ everybody.  We know everyone is human and we all fail at times, but the
+diff --git a/Makefile b/Makefile
+index 8478e13e9424a..3193969f1eb37 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 0
+-SUBLEVEL = 0
++SUBLEVEL = 1
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+@@ -831,8 +831,8 @@ endif
+ # Initialize all stack variables with a zero value.
+ ifdef CONFIG_INIT_STACK_ALL_ZERO
+ KBUILD_CFLAGS	+= -ftrivial-auto-var-init=zero
+-ifdef CONFIG_CC_IS_CLANG
+-# https://bugs.llvm.org/show_bug.cgi?id=45497
++ifdef CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER
++# https://github.com/llvm/llvm-project/issues/44842
+ KBUILD_CFLAGS	+= -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang
+ endif
+ endif
+diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
+index 0be8a2403212d..87455d12970f3 100644
+--- a/arch/riscv/kernel/cpu.c
++++ b/arch/riscv/kernel/cpu.c
+@@ -92,10 +92,10 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
+  */
+ static struct riscv_isa_ext_data isa_ext_arr[] = {
+ 	__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
++	__RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
+ 	__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
+ 	__RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
+ 	__RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
+-	__RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
+ 	__RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX),
+ };
+ 
+diff --git a/arch/sparc/include/asm/smp_32.h b/arch/sparc/include/asm/smp_32.h
+index 856081761b0fc..2cf7971d7f6c9 100644
+--- a/arch/sparc/include/asm/smp_32.h
++++ b/arch/sparc/include/asm/smp_32.h
+@@ -33,9 +33,6 @@ extern volatile unsigned long cpu_callin_map[NR_CPUS];
+ extern cpumask_t smp_commenced_mask;
+ extern struct linux_prom_registers smp_penguin_ctable;
+ 
+-typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long,
+-		       unsigned long, unsigned long);
+-
+ void cpu_panic(void);
+ 
+ /*
+@@ -57,7 +54,7 @@ void smp_bogo(struct seq_file *);
+ void smp_info(struct seq_file *);
+ 
+ struct sparc32_ipi_ops {
+-	void (*cross_call)(smpfunc_t func, cpumask_t mask, unsigned long arg1,
++	void (*cross_call)(void *func, cpumask_t mask, unsigned long arg1,
+ 			   unsigned long arg2, unsigned long arg3,
+ 			   unsigned long arg4);
+ 	void (*resched)(int cpu);
+@@ -66,28 +63,28 @@ struct sparc32_ipi_ops {
+ };
+ extern const struct sparc32_ipi_ops *sparc32_ipi_ops;
+ 
+-static inline void xc0(smpfunc_t func)
++static inline void xc0(void *func)
+ {
+ 	sparc32_ipi_ops->cross_call(func, *cpu_online_mask, 0, 0, 0, 0);
+ }
+ 
+-static inline void xc1(smpfunc_t func, unsigned long arg1)
++static inline void xc1(void *func, unsigned long arg1)
+ {
+ 	sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, 0, 0, 0);
+ }
+-static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
++static inline void xc2(void *func, unsigned long arg1, unsigned long arg2)
+ {
+ 	sparc32_ipi_ops->cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0);
+ }
+ 
+-static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
++static inline void xc3(void *func, unsigned long arg1, unsigned long arg2,
+ 		       unsigned long arg3)
+ {
+ 	sparc32_ipi_ops->cross_call(func, *cpu_online_mask,
+ 				    arg1, arg2, arg3, 0);
+ }
+ 
+-static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
++static inline void xc4(void *func, unsigned long arg1, unsigned long arg2,
+ 		       unsigned long arg3, unsigned long arg4)
+ {
+ 	sparc32_ipi_ops->cross_call(func, *cpu_online_mask,
+diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
+index 1eed26d423fb2..991e9ad3d3e8f 100644
+--- a/arch/sparc/kernel/leon_smp.c
++++ b/arch/sparc/kernel/leon_smp.c
+@@ -359,7 +359,7 @@ void leonsmp_ipi_interrupt(void)
+ }
+ 
+ static struct smp_funcall {
+-	smpfunc_t func;
++	void *func;
+ 	unsigned long arg1;
+ 	unsigned long arg2;
+ 	unsigned long arg3;
+@@ -372,7 +372,7 @@ static struct smp_funcall {
+ static DEFINE_SPINLOCK(cross_call_lock);
+ 
+ /* Cross calls must be serialized, at least currently. */
+-static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
++static void leon_cross_call(void *func, cpumask_t mask, unsigned long arg1,
+ 			    unsigned long arg2, unsigned long arg3,
+ 			    unsigned long arg4)
+ {
+@@ -384,7 +384,7 @@ static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+ 
+ 		{
+ 			/* If you make changes here, make sure gcc generates proper code... */
+-			register smpfunc_t f asm("i0") = func;
++			register void *f asm("i0") = func;
+ 			register unsigned long a1 asm("i1") = arg1;
+ 			register unsigned long a2 asm("i2") = arg2;
+ 			register unsigned long a3 asm("i3") = arg3;
+@@ -444,11 +444,13 @@ static void leon_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+ /* Running cross calls. */
+ void leon_cross_call_irq(void)
+ {
++	void (*func)(unsigned long, unsigned long, unsigned long, unsigned long,
++		     unsigned long) = ccall_info.func;
+ 	int i = smp_processor_id();
+ 
+ 	ccall_info.processors_in[i] = 1;
+-	ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3,
+-			ccall_info.arg4, ccall_info.arg5);
++	func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, ccall_info.arg4,
++	     ccall_info.arg5);
+ 	ccall_info.processors_out[i] = 1;
+ }
+ 
+diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
+index ff30f03beb7c7..9a62a5cf33370 100644
+--- a/arch/sparc/kernel/sun4d_smp.c
++++ b/arch/sparc/kernel/sun4d_smp.c
+@@ -268,7 +268,7 @@ static void sun4d_ipi_resched(int cpu)
+ }
+ 
+ static struct smp_funcall {
+-	smpfunc_t func;
++	void *func;
+ 	unsigned long arg1;
+ 	unsigned long arg2;
+ 	unsigned long arg3;
+@@ -281,7 +281,7 @@ static struct smp_funcall {
+ static DEFINE_SPINLOCK(cross_call_lock);
+ 
+ /* Cross calls must be serialized, at least currently. */
+-static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
++static void sun4d_cross_call(void *func, cpumask_t mask, unsigned long arg1,
+ 			     unsigned long arg2, unsigned long arg3,
+ 			     unsigned long arg4)
+ {
+@@ -296,7 +296,7 @@ static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+ 			 * If you make changes here, make sure
+ 			 * gcc generates proper code...
+ 			 */
+-			register smpfunc_t f asm("i0") = func;
++			register void *f asm("i0") = func;
+ 			register unsigned long a1 asm("i1") = arg1;
+ 			register unsigned long a2 asm("i2") = arg2;
+ 			register unsigned long a3 asm("i3") = arg3;
+@@ -353,11 +353,13 @@ static void sun4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+ /* Running cross calls. */
+ void smp4d_cross_call_irq(void)
+ {
++	void (*func)(unsigned long, unsigned long, unsigned long, unsigned long,
++		     unsigned long) = ccall_info.func;
+ 	int i = hard_smp_processor_id();
+ 
+ 	ccall_info.processors_in[i] = 1;
+-	ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3,
+-			ccall_info.arg4, ccall_info.arg5);
++	func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, ccall_info.arg4,
++	     ccall_info.arg5);
+ 	ccall_info.processors_out[i] = 1;
+ }
+ 
+diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
+index 228a6527082dc..056df034e79ee 100644
+--- a/arch/sparc/kernel/sun4m_smp.c
++++ b/arch/sparc/kernel/sun4m_smp.c
+@@ -157,7 +157,7 @@ static void sun4m_ipi_mask_one(int cpu)
+ }
+ 
+ static struct smp_funcall {
+-	smpfunc_t func;
++	void *func;
+ 	unsigned long arg1;
+ 	unsigned long arg2;
+ 	unsigned long arg3;
+@@ -170,7 +170,7 @@ static struct smp_funcall {
+ static DEFINE_SPINLOCK(cross_call_lock);
+ 
+ /* Cross calls must be serialized, at least currently. */
+-static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
++static void sun4m_cross_call(void *func, cpumask_t mask, unsigned long arg1,
+ 			     unsigned long arg2, unsigned long arg3,
+ 			     unsigned long arg4)
+ {
+@@ -230,11 +230,13 @@ static void sun4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1,
+ /* Running cross calls. */
+ void smp4m_cross_call_irq(void)
+ {
++	void (*func)(unsigned long, unsigned long, unsigned long, unsigned long,
++		     unsigned long) = ccall_info.func;
+ 	int i = smp_processor_id();
+ 
+ 	ccall_info.processors_in[i] = 1;
+-	ccall_info.func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3,
+-			ccall_info.arg4, ccall_info.arg5);
++	func(ccall_info.arg1, ccall_info.arg2, ccall_info.arg3, ccall_info.arg4,
++	     ccall_info.arg5);
+ 	ccall_info.processors_out[i] = 1;
+ }
+ 
+diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
+index a9aa6a92c7fee..13f027afc875c 100644
+--- a/arch/sparc/mm/srmmu.c
++++ b/arch/sparc/mm/srmmu.c
+@@ -1636,19 +1636,19 @@ static void __init get_srmmu_type(void)
+ /* Local cross-calls. */
+ static void smp_flush_page_for_dma(unsigned long page)
+ {
+-	xc1((smpfunc_t) local_ops->page_for_dma, page);
++	xc1(local_ops->page_for_dma, page);
+ 	local_ops->page_for_dma(page);
+ }
+ 
+ static void smp_flush_cache_all(void)
+ {
+-	xc0((smpfunc_t) local_ops->cache_all);
++	xc0(local_ops->cache_all);
+ 	local_ops->cache_all();
+ }
+ 
+ static void smp_flush_tlb_all(void)
+ {
+-	xc0((smpfunc_t) local_ops->tlb_all);
++	xc0(local_ops->tlb_all);
+ 	local_ops->tlb_all();
+ }
+ 
+@@ -1659,7 +1659,7 @@ static void smp_flush_cache_mm(struct mm_struct *mm)
+ 		cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ 		cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ 		if (!cpumask_empty(&cpu_mask))
+-			xc1((smpfunc_t) local_ops->cache_mm, (unsigned long) mm);
++			xc1(local_ops->cache_mm, (unsigned long)mm);
+ 		local_ops->cache_mm(mm);
+ 	}
+ }
+@@ -1671,7 +1671,7 @@ static void smp_flush_tlb_mm(struct mm_struct *mm)
+ 		cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ 		cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ 		if (!cpumask_empty(&cpu_mask)) {
+-			xc1((smpfunc_t) local_ops->tlb_mm, (unsigned long) mm);
++			xc1(local_ops->tlb_mm, (unsigned long)mm);
+ 			if (atomic_read(&mm->mm_users) == 1 && current->active_mm == mm)
+ 				cpumask_copy(mm_cpumask(mm),
+ 					     cpumask_of(smp_processor_id()));
+@@ -1691,8 +1691,8 @@ static void smp_flush_cache_range(struct vm_area_struct *vma,
+ 		cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ 		cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ 		if (!cpumask_empty(&cpu_mask))
+-			xc3((smpfunc_t) local_ops->cache_range,
+-			    (unsigned long) vma, start, end);
++			xc3(local_ops->cache_range, (unsigned long)vma, start,
++			    end);
+ 		local_ops->cache_range(vma, start, end);
+ 	}
+ }
+@@ -1708,8 +1708,8 @@ static void smp_flush_tlb_range(struct vm_area_struct *vma,
+ 		cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ 		cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ 		if (!cpumask_empty(&cpu_mask))
+-			xc3((smpfunc_t) local_ops->tlb_range,
+-			    (unsigned long) vma, start, end);
++			xc3(local_ops->tlb_range, (unsigned long)vma, start,
++			    end);
+ 		local_ops->tlb_range(vma, start, end);
+ 	}
+ }
+@@ -1723,8 +1723,7 @@ static void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
+ 		cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ 		cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ 		if (!cpumask_empty(&cpu_mask))
+-			xc2((smpfunc_t) local_ops->cache_page,
+-			    (unsigned long) vma, page);
++			xc2(local_ops->cache_page, (unsigned long)vma, page);
+ 		local_ops->cache_page(vma, page);
+ 	}
+ }
+@@ -1738,8 +1737,7 @@ static void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+ 		cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ 		cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ 		if (!cpumask_empty(&cpu_mask))
+-			xc2((smpfunc_t) local_ops->tlb_page,
+-			    (unsigned long) vma, page);
++			xc2(local_ops->tlb_page, (unsigned long)vma, page);
+ 		local_ops->tlb_page(vma, page);
+ 	}
+ }
+@@ -1753,7 +1751,7 @@ static void smp_flush_page_to_ram(unsigned long page)
+ 	 * XXX This experiment failed, research further... -DaveM
+ 	 */
+ #if 1
+-	xc1((smpfunc_t) local_ops->page_to_ram, page);
++	xc1(local_ops->page_to_ram, page);
+ #endif
+ 	local_ops->page_to_ram(page);
+ }
+@@ -1764,8 +1762,7 @@ static void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
+ 	cpumask_copy(&cpu_mask, mm_cpumask(mm));
+ 	cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+ 	if (!cpumask_empty(&cpu_mask))
+-		xc2((smpfunc_t) local_ops->sig_insns,
+-		    (unsigned long) mm, insn_addr);
++		xc2(local_ops->sig_insns, (unsigned long)mm, insn_addr);
+ 	local_ops->sig_insns(mm, insn_addr);
+ }
+ 
+diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
+index 9be1376f9a627..285ecbf107c95 100644
+--- a/drivers/gpio/gpiolib-acpi.c
++++ b/drivers/gpio/gpiolib-acpi.c
+@@ -32,9 +32,16 @@ MODULE_PARM_DESC(ignore_wake,
+ 		 "controller@pin combos on which to ignore the ACPI wake flag "
+ 		 "ignore_wake=controller@pin[,controller@pin[,...]]");
+ 
++static char *ignore_interrupt;
++module_param(ignore_interrupt, charp, 0444);
++MODULE_PARM_DESC(ignore_interrupt,
++		 "controller@pin combos on which to ignore interrupt "
++		 "ignore_interrupt=controller@pin[,controller@pin[,...]]");
++
+ struct acpi_gpiolib_dmi_quirk {
+ 	bool no_edge_events_on_boot;
+ 	char *ignore_wake;
++	char *ignore_interrupt;
+ };
+ 
+ /**
+@@ -317,14 +324,15 @@ static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip,
+ 	return desc;
+ }
+ 
+-static bool acpi_gpio_in_ignore_list(const char *controller_in, unsigned int pin_in)
++static bool acpi_gpio_in_ignore_list(const char *ignore_list, const char *controller_in,
++				     unsigned int pin_in)
+ {
+ 	const char *controller, *pin_str;
+ 	unsigned int pin;
+ 	char *endp;
+ 	int len;
+ 
+-	controller = ignore_wake;
++	controller = ignore_list;
+ 	while (controller) {
+ 		pin_str = strchr(controller, '@');
+ 		if (!pin_str)
+@@ -348,7 +356,7 @@ static bool acpi_gpio_in_ignore_list(const char *controller_in, unsigned int pin
+ 
+ 	return false;
+ err:
+-	pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_wake: %s\n", ignore_wake);
++	pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_...: %s\n", ignore_list);
+ 	return false;
+ }
+ 
+@@ -360,7 +368,7 @@ static bool acpi_gpio_irq_is_wake(struct device *parent,
+ 	if (agpio->wake_capable != ACPI_WAKE_CAPABLE)
+ 		return false;
+ 
+-	if (acpi_gpio_in_ignore_list(dev_name(parent), pin)) {
++	if (acpi_gpio_in_ignore_list(ignore_wake, dev_name(parent), pin)) {
+ 		dev_info(parent, "Ignoring wakeup on pin %u\n", pin);
+ 		return false;
+ 	}
+@@ -427,6 +435,11 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
+ 		goto fail_unlock_irq;
+ 	}
+ 
++	if (acpi_gpio_in_ignore_list(ignore_interrupt, dev_name(chip->parent), pin)) {
++		dev_info(chip->parent, "Ignoring interrupt on pin %u\n", pin);
++		return AE_OK;
++	}
++
+ 	event = kzalloc(sizeof(*event), GFP_KERNEL);
+ 	if (!event)
+ 		goto fail_unlock_irq;
+@@ -1563,6 +1576,20 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = {
+ 			.ignore_wake = "INT33FF:01@0",
+ 		},
+ 	},
++	{
++		/*
++		 * Interrupt storm caused from edge triggered floating pin
++		 * Found in BIOS UX325UAZ.300
++		 * https://bugzilla.kernel.org/show_bug.cgi?id=216208
++		 */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UAZ_UM325UAZ"),
++		},
++		.driver_data = &(struct acpi_gpiolib_dmi_quirk) {
++			.ignore_interrupt = "AMDI0030:00@18",
++		},
++	},
+ 	{} /* Terminating entry */
+ };
+ 
+@@ -1585,6 +1612,9 @@ static int __init acpi_gpio_setup_params(void)
+ 	if (ignore_wake == NULL && quirk && quirk->ignore_wake)
+ 		ignore_wake = quirk->ignore_wake;
+ 
++	if (ignore_interrupt == NULL && quirk && quirk->ignore_interrupt)
++		ignore_interrupt = quirk->ignore_interrupt;
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c
+index 66430553cc451..36752cf2cac97 100644
+--- a/drivers/hwmon/aquacomputer_d5next.c
++++ b/drivers/hwmon/aquacomputer_d5next.c
+@@ -110,7 +110,7 @@ static u16 octo_ctrl_fan_offsets[] = { 0x5B, 0xB0, 0x105, 0x15A, 0x1AF, 0x204, 0
+ static u8 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 };
+ 
+ /* Fan speed registers in Quadro control report (from 0-100%) */
+-static u16 quadro_ctrl_fan_offsets[] = { 0x36, 0x8b, 0xe0, 0x135 };
++static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 };
+ 
+ /* Labels for D5 Next */
+ static const char *const label_d5next_temp[] = {
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
+index cfe804bc8d205..148ea636ef979 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -412,7 +412,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
+ 	if (entry->hash != 0xffff) {
+ 		ppe->foe_table[entry->hash].ib1 &= ~MTK_FOE_IB1_STATE;
+ 		ppe->foe_table[entry->hash].ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE,
+-							      MTK_FOE_STATE_UNBIND);
++							      MTK_FOE_STATE_INVALID);
+ 		dma_wmb();
+ 	}
+ 	entry->hash = 0xffff;
+diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
+index f48a23adbc35d..094e812e9e692 100644
+--- a/drivers/usb/mon/mon_bin.c
++++ b/drivers/usb/mon/mon_bin.c
+@@ -1268,6 +1268,11 @@ static int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma)
+ {
+ 	/* don't do anything here: "fault" will set up page table entries */
+ 	vma->vm_ops = &mon_bin_vm_ops;
++
++	if (vma->vm_flags & VM_WRITE)
++		return -EPERM;
++
++	vma->vm_flags &= ~VM_MAYWRITE;
+ 	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+ 	vma->vm_private_data = filp->private_data;
+ 	mon_bin_vma_open(vma);
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 52d59be920342..787e63fd7f99b 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -1319,8 +1319,7 @@ static u32 get_ftdi_divisor(struct tty_struct *tty,
+ 		case 38400: div_value = ftdi_sio_b38400; break;
+ 		case 57600: div_value = ftdi_sio_b57600;  break;
+ 		case 115200: div_value = ftdi_sio_b115200; break;
+-		} /* baud */
+-		if (div_value == 0) {
++		default:
+ 			dev_dbg(dev, "%s - Baudrate (%d) requested is not supported\n",
+ 				__func__,  baud);
+ 			div_value = ftdi_sio_b9600;
+diff --git a/fs/coredump.c b/fs/coredump.c
+index 1ab4f5b76a1e7..3538f3a63965d 100644
+--- a/fs/coredump.c
++++ b/fs/coredump.c
+@@ -841,7 +841,7 @@ static int dump_emit_page(struct coredump_params *cprm, struct page *page)
+ 	};
+ 	struct iov_iter iter;
+ 	struct file *file = cprm->file;
+-	loff_t pos = file->f_pos;
++	loff_t pos;
+ 	ssize_t n;
+ 
+ 	if (cprm->to_skip) {
+@@ -853,6 +853,7 @@ static int dump_emit_page(struct coredump_params *cprm, struct page *page)
+ 		return 0;
+ 	if (dump_interrupted())
+ 		return 0;
++	pos = file->f_pos;
+ 	iov_iter_bvec(&iter, WRITE, &bvec, 1, PAGE_SIZE);
+ 	n = __kernel_write_iter(cprm->file, &iter, &pos);
+ 	if (n != PAGE_SIZE)
+diff --git a/fs/inode.c b/fs/inode.c
+index ba1de23c13c1e..b608528efd3a4 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -192,8 +192,6 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
+ 	inode->i_wb_frn_history = 0;
+ #endif
+ 
+-	if (security_inode_alloc(inode))
+-		goto out;
+ 	spin_lock_init(&inode->i_lock);
+ 	lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
+ 
+@@ -228,11 +226,12 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
+ 	inode->i_fsnotify_mask = 0;
+ #endif
+ 	inode->i_flctx = NULL;
++
++	if (unlikely(security_inode_alloc(inode)))
++		return -ENOMEM;
+ 	this_cpu_inc(nr_inodes);
+ 
+ 	return 0;
+-out:
+-	return -ENOMEM;
+ }
+ EXPORT_SYMBOL(inode_init_always);
+ 
+diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
+index 647722e847b41..f787c3f524b03 100644
+--- a/include/net/xsk_buff_pool.h
++++ b/include/net/xsk_buff_pool.h
+@@ -95,7 +95,7 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs,
+ 						struct xdp_umem *umem);
+ int xp_assign_dev(struct xsk_buff_pool *pool, struct net_device *dev,
+ 		  u16 queue_id, u16 flags);
+-int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_umem *umem,
++int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_sock *umem_xs,
+ 			 struct net_device *dev, u16 queue_id);
+ int xp_alloc_tx_descs(struct xsk_buff_pool *pool, struct xdp_sock *xs);
+ void xp_destroy(struct xsk_buff_pool *pool);
+diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
+index 1f961f9982d27..3814b0fd3a2c5 100644
+--- a/kernel/bpf/helpers.c
++++ b/kernel/bpf/helpers.c
+@@ -1627,26 +1627,12 @@ bpf_base_func_proto(enum bpf_func_id func_id)
+ 		return &bpf_ringbuf_discard_proto;
+ 	case BPF_FUNC_ringbuf_query:
+ 		return &bpf_ringbuf_query_proto;
+-	case BPF_FUNC_ringbuf_reserve_dynptr:
+-		return &bpf_ringbuf_reserve_dynptr_proto;
+-	case BPF_FUNC_ringbuf_submit_dynptr:
+-		return &bpf_ringbuf_submit_dynptr_proto;
+-	case BPF_FUNC_ringbuf_discard_dynptr:
+-		return &bpf_ringbuf_discard_dynptr_proto;
+ 	case BPF_FUNC_for_each_map_elem:
+ 		return &bpf_for_each_map_elem_proto;
+ 	case BPF_FUNC_loop:
+ 		return &bpf_loop_proto;
+ 	case BPF_FUNC_strncmp:
+ 		return &bpf_strncmp_proto;
+-	case BPF_FUNC_dynptr_from_mem:
+-		return &bpf_dynptr_from_mem_proto;
+-	case BPF_FUNC_dynptr_read:
+-		return &bpf_dynptr_read_proto;
+-	case BPF_FUNC_dynptr_write:
+-		return &bpf_dynptr_write_proto;
+-	case BPF_FUNC_dynptr_data:
+-		return &bpf_dynptr_data_proto;
+ 	default:
+ 		break;
+ 	}
+@@ -1675,6 +1661,20 @@ bpf_base_func_proto(enum bpf_func_id func_id)
+ 		return &bpf_timer_cancel_proto;
+ 	case BPF_FUNC_kptr_xchg:
+ 		return &bpf_kptr_xchg_proto;
++	case BPF_FUNC_ringbuf_reserve_dynptr:
++		return &bpf_ringbuf_reserve_dynptr_proto;
++	case BPF_FUNC_ringbuf_submit_dynptr:
++		return &bpf_ringbuf_submit_dynptr_proto;
++	case BPF_FUNC_ringbuf_discard_dynptr:
++		return &bpf_ringbuf_discard_dynptr_proto;
++	case BPF_FUNC_dynptr_from_mem:
++		return &bpf_dynptr_from_mem_proto;
++	case BPF_FUNC_dynptr_read:
++		return &bpf_dynptr_read_proto;
++	case BPF_FUNC_dynptr_write:
++		return &bpf_dynptr_write_proto;
++	case BPF_FUNC_dynptr_data:
++		return &bpf_dynptr_data_proto;
+ 	default:
+ 		break;
+ 	}
+diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
+index 27760627370db..f798acd43a280 100644
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -598,7 +598,7 @@ void bpf_map_free_kptrs(struct bpf_map *map, void *map_value)
+ 		if (off_desc->type == BPF_KPTR_UNREF) {
+ 			u64 *p = (u64 *)btf_id_ptr;
+ 
+-			WRITE_ONCE(p, 0);
++			WRITE_ONCE(*p, 0);
+ 			continue;
+ 		}
+ 		old_ptr = xchg(btf_id_ptr, 0);
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
+index b3a5a3cc93720..9873d2e679885 100644
+--- a/net/bluetooth/hci_core.c
++++ b/net/bluetooth/hci_core.c
+@@ -597,6 +597,15 @@ static int hci_dev_do_reset(struct hci_dev *hdev)
+ 
+ 	/* Cancel these to avoid queueing non-chained pending work */
+ 	hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
++	/* Wait for
++	 *
++	 *    if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
++	 *        queue_delayed_work(&hdev->{cmd,ncmd}_timer)
++	 *
++	 * inside RCU section to see the flag or complete scheduling.
++	 */
++	synchronize_rcu();
++	/* Explicitly cancel works in case scheduled after setting the flag. */
+ 	cancel_delayed_work(&hdev->cmd_timer);
+ 	cancel_delayed_work(&hdev->ncmd_timer);
+ 
+@@ -4056,12 +4065,14 @@ static void hci_cmd_work(struct work_struct *work)
+ 			if (res < 0)
+ 				__hci_cmd_sync_cancel(hdev, -res);
+ 
++			rcu_read_lock();
+ 			if (test_bit(HCI_RESET, &hdev->flags) ||
+ 			    hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
+ 				cancel_delayed_work(&hdev->cmd_timer);
+ 			else
+-				schedule_delayed_work(&hdev->cmd_timer,
+-						      HCI_CMD_TIMEOUT);
++				queue_delayed_work(hdev->workqueue, &hdev->cmd_timer,
++						   HCI_CMD_TIMEOUT);
++			rcu_read_unlock();
+ 		} else {
+ 			skb_queue_head(&hdev->cmd_q, skb);
+ 			queue_work(hdev->workqueue, &hdev->cmd_work);
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index 6643c9c20fa46..d6f0e6ca0e7e0 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -3766,16 +3766,18 @@ static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd)
+ {
+ 	cancel_delayed_work(&hdev->cmd_timer);
+ 
++	rcu_read_lock();
+ 	if (!test_bit(HCI_RESET, &hdev->flags)) {
+ 		if (ncmd) {
+ 			cancel_delayed_work(&hdev->ncmd_timer);
+ 			atomic_set(&hdev->cmd_cnt, 1);
+ 		} else {
+ 			if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
+-				schedule_delayed_work(&hdev->ncmd_timer,
+-						      HCI_NCMD_TIMEOUT);
++				queue_delayed_work(hdev->workqueue, &hdev->ncmd_timer,
++						   HCI_NCMD_TIMEOUT);
+ 		}
+ 	}
++	rcu_read_unlock();
+ }
+ 
+ static u8 hci_cc_le_read_buffer_size_v2(struct hci_dev *hdev, void *data,
+diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
+index 5b4ce6ba1bc7f..7bada4e8460ba 100644
+--- a/net/xdp/xsk.c
++++ b/net/xdp/xsk.c
+@@ -954,8 +954,8 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
+ 				goto out_unlock;
+ 			}
+ 
+-			err = xp_assign_dev_shared(xs->pool, umem_xs->umem,
+-						   dev, qid);
++			err = xp_assign_dev_shared(xs->pool, umem_xs, dev,
++						   qid);
+ 			if (err) {
+ 				xp_destroy(xs->pool);
+ 				xs->pool = NULL;
+diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c
+index a71a8c6edf553..ed6c71826d31f 100644
+--- a/net/xdp/xsk_buff_pool.c
++++ b/net/xdp/xsk_buff_pool.c
+@@ -212,17 +212,18 @@ err_unreg_pool:
+ 	return err;
+ }
+ 
+-int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_umem *umem,
++int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_sock *umem_xs,
+ 			 struct net_device *dev, u16 queue_id)
+ {
+ 	u16 flags;
++	struct xdp_umem *umem = umem_xs->umem;
+ 
+ 	/* One fill and completion ring required for each queue id. */
+ 	if (!pool->fq || !pool->cq)
+ 		return -EINVAL;
+ 
+ 	flags = umem->zc ? XDP_ZEROCOPY : XDP_COPY;
+-	if (pool->uses_need_wakeup)
++	if (umem_xs->pool->uses_need_wakeup)
+ 		flags |= XDP_USE_NEED_WAKEUP;
+ 
+ 	return xp_assign_dev(pool, dev, queue_id, flags);
+diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
+index 6ae482158bc41..52bd7df84fd64 100644
+--- a/scripts/Makefile.extrawarn
++++ b/scripts/Makefile.extrawarn
+@@ -64,6 +64,7 @@ KBUILD_CFLAGS += -Wno-sign-compare
+ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)
+ KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare
+ KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access)
++KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict)
+ endif
+ 
+ endif
+diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
+index bd2aabb2c60f9..995bc42003e6c 100644
+--- a/security/Kconfig.hardening
++++ b/security/Kconfig.hardening
+@@ -22,11 +22,17 @@ menu "Memory initialization"
+ config CC_HAS_AUTO_VAR_INIT_PATTERN
+ 	def_bool $(cc-option,-ftrivial-auto-var-init=pattern)
+ 
+-config CC_HAS_AUTO_VAR_INIT_ZERO
+-	# GCC ignores the -enable flag, so we can test for the feature with
+-	# a single invocation using the flag, but drop it as appropriate in
+-	# the Makefile, depending on the presence of Clang.
++config CC_HAS_AUTO_VAR_INIT_ZERO_BARE
++	def_bool $(cc-option,-ftrivial-auto-var-init=zero)
++
++config CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER
++	# Clang 16 and later warn about using the -enable flag, but it
++	# is required before then.
+ 	def_bool $(cc-option,-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang)
++	depends on !CC_HAS_AUTO_VAR_INIT_ZERO_BARE
++
++config CC_HAS_AUTO_VAR_INIT_ZERO
++	def_bool CC_HAS_AUTO_VAR_INIT_ZERO_BARE || CC_HAS_AUTO_VAR_INIT_ZERO_ENABLER
+ 
+ choice
+ 	prompt "Initialize kernel stack variables at function entry"


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-10-03  9:31 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-10-03  9:31 UTC (permalink / raw
  To: gentoo-commits

commit:     47fadfe6806d9429b6e567e2f4123e0984621a41
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Oct  3 09:30:51 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Oct  3 09:30:51 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=47fadfe6

Remove unneeded patch

Removed:
2700_revert-drm-i915-dma-resv-obj-fix.patch

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

 0000_README                                 |   4 --
 2700_revert-drm-i915-dma-resv-obj-fix.patch | 107 ----------------------------
 2 files changed, 111 deletions(-)

diff --git a/0000_README b/0000_README
index b3a5a14c..b1b7f794 100644
--- a/0000_README
+++ b/0000_README
@@ -59,10 +59,6 @@ Patch:  2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
 From:   https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw
 Desc:   Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758
 
-Patch:  2700_revert-drm-i915-dma-resv-obj-fix.patch
-From:   https://bugs.gentoo.org/866023
-Desc:   Revert Revert for drm i915 thanks to Luigi 'Comio' Mantellini 
-
 Patch:  2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
 From:   https://bugs.gentoo.org/710790
 Desc:   tmp513 requies REGMAP_I2C to build.  Select it by default in Kconfig. See bug #710790. Thanks to Phil Stracchino

diff --git a/2700_revert-drm-i915-dma-resv-obj-fix.patch b/2700_revert-drm-i915-dma-resv-obj-fix.patch
deleted file mode 100644
index a9fcaf4a..00000000
--- a/2700_revert-drm-i915-dma-resv-obj-fix.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From d481c481ca7813d688ffcb1c5418b48f83d945c1 Mon Sep 17 00:00:00 2001
-From: Luigi 'Comio' Mantellini <luigi.mantellini@gmail.com>
-Date: Sun, 28 Aug 2022 09:17:35 +0200
-Subject: [PATCH] Revert "drm/i915: Individualize fences before adding to
- dma_resv obj"
-
-This reverts commit 842d9346b2fdda4d2fb8ccb5b87faef1ac01ab51.
----
- .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  3 +-
- drivers/gpu/drm/i915/i915_vma.c               | 48 ++++++++-----------
- 2 files changed, 21 insertions(+), 30 deletions(-)
-
-diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
-index 30fe847c6664..c326bd2b444f 100644
---- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
-+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
-@@ -999,8 +999,7 @@ static int eb_validate_vmas(struct i915_execbuffer *eb)
- 			}
- 		}
- 
--		/* Reserve enough slots to accommodate composite fences */
--		err = dma_resv_reserve_fences(vma->obj->base.resv, eb->num_batches);
-+		err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
- 		if (err)
- 			return err;
- 
-diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
-index 16460b169ed2..e71826f0e4b1 100644
---- a/drivers/gpu/drm/i915/i915_vma.c
-+++ b/drivers/gpu/drm/i915/i915_vma.c
-@@ -23,7 +23,6 @@
-  */
- 
- #include <linux/sched/mm.h>
--#include <linux/dma-fence-array.h>
- #include <drm/drm_gem.h>
- 
- #include "display/intel_frontbuffer.h"
-@@ -1839,21 +1838,6 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
- 	if (unlikely(err))
- 		return err;
- 
--	/*
--	 * Reserve fences slot early to prevent an allocation after preparing
--	 * the workload and associating fences with dma_resv.
--	 */
--	if (fence && !(flags & __EXEC_OBJECT_NO_RESERVE)) {
--		struct dma_fence *curr;
--		int idx;
--
--		dma_fence_array_for_each(curr, idx, fence)
--			;
--		err = dma_resv_reserve_fences(vma->obj->base.resv, idx);
--		if (unlikely(err))
--			return err;
--	}
--
- 	if (flags & EXEC_OBJECT_WRITE) {
- 		struct intel_frontbuffer *front;
- 
-@@ -1863,23 +1847,31 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
- 				i915_active_add_request(&front->write, rq);
- 			intel_frontbuffer_put(front);
- 		}
--	}
- 
--	if (fence) {
--		struct dma_fence *curr;
--		enum dma_resv_usage usage;
--		int idx;
-+		if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
-+			err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
-+			if (unlikely(err))
-+				return err;
-+		}
- 
--		obj->read_domains = 0;
--		if (flags & EXEC_OBJECT_WRITE) {
--			usage = DMA_RESV_USAGE_WRITE;
-+		if (fence) {
-+			dma_resv_add_fence(vma->obj->base.resv, fence,
-+					   DMA_RESV_USAGE_WRITE);
- 			obj->write_domain = I915_GEM_DOMAIN_RENDER;
--		} else {
--			usage = DMA_RESV_USAGE_READ;
-+			obj->read_domains = 0;
-+		}
-+	} else {
-+		if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
-+			err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
-+			if (unlikely(err))
-+				return err;
- 		}
- 
--		dma_fence_array_for_each(curr, idx, fence)
--			dma_resv_add_fence(vma->obj->base.resv, curr, usage);
-+		if (fence) {
-+			dma_resv_add_fence(vma->obj->base.resv, fence,
-+					   DMA_RESV_USAGE_READ);
-+			obj->write_domain = 0;
-+		}
- 	}
- 
- 	if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence)
--- 
-2.37.2
-


^ permalink raw reply related	[flat|nested] 27+ messages in thread
* [gentoo-commits] proj/linux-patches:6.0 commit in: /
@ 2022-09-11 22:30 Mike Pagano
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Pagano @ 2022-09-11 22:30 UTC (permalink / raw
  To: gentoo-commits

commit:     f0dc7817c3af87cf128b5b1bc20a94d9f910b987
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sun Sep 11 22:30:20 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sun Sep 11 22:30:20 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=f0dc7817

Add genpatches

Bluetooth: Check key sizes only when Secure Simple Pairing is
enabled. See bug #686758
tmp513 requies REGMAP_I2C to build.  Select it by default in Kconfig.
See bug #710790. Thanks to Phil Stracchino
sign-file: full functionality with modern LibreSSL
Kernel Self Protection patch
CPU Optimization patch
Print firmware info (Reqs CONFIG_GENTOO_PRINT_FIRMWARE_INFO
Patch to enable link security restrictions by default.
Patch to support for namespace user.pax.* on tmpfs.

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

 0000_README                                        |  37 ++
 1500_XATTR_USER_PREFIX.patch                       |  67 ++
 ...ble-link-security-restrictions-by-default.patch |  17 +
 1700_sparc-address-warray-bound-warnings.patch     |  17 +
 ...zes-only-if-Secure-Simple-Pairing-enabled.patch |  37 ++
 2700_revert-drm-i915-dma-resv-obj-fix.patch        | 107 ++++
 ...3-Fix-build-issue-by-selecting-CONFIG_REG.patch |  30 +
 2920_sign-file-patch-for-libressl.patch            |  16 +
 3000_Support-printing-firmware-info.patch          |  14 +
 5010_enable-cpu-optimizations-universal.patch      | 675 +++++++++++++++++++++
 10 files changed, 1017 insertions(+)

diff --git a/0000_README b/0000_README
index 90189932..b3a5a14c 100644
--- a/0000_README
+++ b/0000_README
@@ -43,6 +43,43 @@ EXPERIMENTAL
 Individual Patch Descriptions:
 --------------------------------------------------------------------------
 
+Patch:  1500_XATTR_USER_PREFIX.patch
+From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
+Desc:   Support for namespace user.pax.* on tmpfs.
+
+Patch:  1510_fs-enable-link-security-restrictions-by-default.patch
+From:   http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/
+Desc:   Enable link security restrictions by default.
+
+Patch:  1700_sparc-address-warray-bound-warnings.patch
+From:	https://github.com/KSPP/linux/issues/109
+Desc:	Address -Warray-bounds warnings 
+
+Patch:  2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
+From:   https://lore.kernel.org/linux-bluetooth/20190522070540.48895-1-marcel@holtmann.org/raw
+Desc:   Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758
+
+Patch:  2700_revert-drm-i915-dma-resv-obj-fix.patch
+From:   https://bugs.gentoo.org/866023
+Desc:   Revert Revert for drm i915 thanks to Luigi 'Comio' Mantellini 
+
+Patch:  2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
+From:   https://bugs.gentoo.org/710790
+Desc:   tmp513 requies REGMAP_I2C to build.  Select it by default in Kconfig. See bug #710790. Thanks to Phil Stracchino
+
+Patch:  2920_sign-file-patch-for-libressl.patch
+From:   https://bugs.gentoo.org/717166
+Desc:   sign-file: full functionality with modern LibreSSL
+
+Patch:  3000_Support-printing-firmware-info.patch
+From:   https://bugs.gentoo.org/732852
+Desc:   Print firmware info (Reqs CONFIG_GENTOO_PRINT_FIRMWARE_INFO). Thanks to Georgy Yakovlev
+
 Patch:  4567_distro-Gentoo-Kconfig.patch
 From:   Tom Wijsman <TomWij@gentoo.org>
 Desc:   Add Gentoo Linux support config settings and defaults.
+
+Patch:  5010_enable-cpu-optimizations-universal.patch
+From:   https://github.com/graysky2/kernel_compiler_patch
+Desc:   Kernel >= 5.15 patch enables gcc = v11.1+ optimizations for additional CPUs.
+

diff --git a/1500_XATTR_USER_PREFIX.patch b/1500_XATTR_USER_PREFIX.patch
new file mode 100644
index 00000000..245dcc29
--- /dev/null
+++ b/1500_XATTR_USER_PREFIX.patch
@@ -0,0 +1,67 @@
+From: Anthony G. Basile <blueness@gentoo.org>
+
+This patch adds support for a restricted user-controlled namespace on
+tmpfs filesystem used to house PaX flags.  The namespace must be of the
+form user.pax.* and its value cannot exceed a size of 8 bytes.
+
+This is needed even on all Gentoo systems so that XATTR_PAX flags
+are preserved for users who might build packages using portage on
+a tmpfs system with a non-hardened kernel and then switch to a
+hardened kernel with XATTR_PAX enabled.
+
+The namespace is added to any user with Extended Attribute support
+enabled for tmpfs.  Users who do not enable xattrs will not have
+the XATTR_PAX flags preserved.
+
+diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h
+index 1590c49..5eab462 100644
+--- a/include/uapi/linux/xattr.h
++++ b/include/uapi/linux/xattr.h
+@@ -73,5 +73,9 @@
+ #define XATTR_POSIX_ACL_DEFAULT  "posix_acl_default"
+ #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT
+ 
++/* User namespace */
++#define XATTR_PAX_PREFIX XATTR_USER_PREFIX "pax."
++#define XATTR_PAX_FLAGS_SUFFIX "flags"
++#define XATTR_NAME_PAX_FLAGS XATTR_PAX_PREFIX XATTR_PAX_FLAGS_SUFFIX
+ 
+ #endif /* _UAPI_LINUX_XATTR_H */
+--- a/mm/shmem.c	2020-05-04 15:30:27.042035334 -0400
++++ b/mm/shmem.c	2020-05-04 15:34:57.013881725 -0400
+@@ -3238,6 +3238,14 @@ static int shmem_xattr_handler_set(const
+ 	struct shmem_inode_info *info = SHMEM_I(inode);
+ 
+ 	name = xattr_full_name(handler, name);
++
++	if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
++		if (strcmp(name, XATTR_NAME_PAX_FLAGS))
++			return -EOPNOTSUPP;
++		if (size > 8)
++			return -EINVAL;
++	}
++
+ 	return simple_xattr_set(&info->xattrs, name, value, size, flags, NULL);
+ }
+ 
+@@ -3253,6 +3261,12 @@ static const struct xattr_handler shmem_
+ 	.set = shmem_xattr_handler_set,
+ };
+ 
++static const struct xattr_handler shmem_user_xattr_handler = {
++	.prefix = XATTR_USER_PREFIX,
++	.get = shmem_xattr_handler_get,
++	.set = shmem_xattr_handler_set,
++};
++
+ static const struct xattr_handler *shmem_xattr_handlers[] = {
+ #ifdef CONFIG_TMPFS_POSIX_ACL
+ 	&posix_acl_access_xattr_handler,
+@@ -3260,6 +3274,7 @@ static const struct xattr_handler *shmem
+ #endif
+ 	&shmem_security_xattr_handler,
+ 	&shmem_trusted_xattr_handler,
++	&shmem_user_xattr_handler,
+ 	NULL
+ };
+ 

diff --git a/1510_fs-enable-link-security-restrictions-by-default.patch b/1510_fs-enable-link-security-restrictions-by-default.patch
new file mode 100644
index 00000000..e8c30157
--- /dev/null
+++ b/1510_fs-enable-link-security-restrictions-by-default.patch
@@ -0,0 +1,17 @@
+--- a/fs/namei.c	2022-01-23 13:02:27.876558299 -0500
++++ b/fs/namei.c	2022-03-06 12:47:39.375719693 -0500
+@@ -1020,10 +1020,10 @@ static inline void put_link(struct namei
+ 		path_put(&last->link);
+ }
+ 
+-static int sysctl_protected_symlinks __read_mostly;
+-static int sysctl_protected_hardlinks __read_mostly;
+-static int sysctl_protected_fifos __read_mostly;
+-static int sysctl_protected_regular __read_mostly;
++static int sysctl_protected_symlinks __read_mostly = 1;
++static int sysctl_protected_hardlinks __read_mostly = 1;
++int sysctl_protected_fifos __read_mostly = 1;
++int sysctl_protected_regular __read_mostly = 1;
+ 
+ #ifdef CONFIG_SYSCTL
+ static struct ctl_table namei_sysctls[] = {

diff --git a/1700_sparc-address-warray-bound-warnings.patch b/1700_sparc-address-warray-bound-warnings.patch
new file mode 100644
index 00000000..f9393555
--- /dev/null
+++ b/1700_sparc-address-warray-bound-warnings.patch
@@ -0,0 +1,17 @@
+--- a/arch/sparc/mm/init_64.c	2022-05-24 16:48:40.749677491 -0400
++++ b/arch/sparc/mm/init_64.c	2022-05-24 16:55:15.511356945 -0400
+@@ -3052,11 +3052,11 @@ static inline resource_size_t compute_ke
+ static void __init kernel_lds_init(void)
+ {
+ 	code_resource.start = compute_kern_paddr(_text);
+-	code_resource.end   = compute_kern_paddr(_etext - 1);
++	code_resource.end   = compute_kern_paddr(_etext) - 1;
+ 	data_resource.start = compute_kern_paddr(_etext);
+-	data_resource.end   = compute_kern_paddr(_edata - 1);
++	data_resource.end   = compute_kern_paddr(_edata) - 1;
+ 	bss_resource.start  = compute_kern_paddr(__bss_start);
+-	bss_resource.end    = compute_kern_paddr(_end - 1);
++	bss_resource.end    = compute_kern_paddr(_end) - 1;
+ }
+ 
+ static int __init report_memory(void)

diff --git a/2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch b/2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
new file mode 100644
index 00000000..394ad48f
--- /dev/null
+++ b/2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
@@ -0,0 +1,37 @@
+The encryption is only mandatory to be enforced when both sides are using
+Secure Simple Pairing and this means the key size check makes only sense
+in that case.
+
+On legacy Bluetooth 2.0 and earlier devices like mice the encryption was
+optional and thus causing an issue if the key size check is not bound to
+using Secure Simple Pairing.
+
+Fixes: d5bb334a8e17 ("Bluetooth: Align minimum encryption key size for LE and BR/EDR connections")
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Cc: stable@vger.kernel.org
+---
+ net/bluetooth/hci_conn.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 3cf0764d5793..7516cdde3373 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -1272,8 +1272,13 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
+ 			return 0;
+ 	}
+ 
+-	if (hci_conn_ssp_enabled(conn) &&
+-	    !test_bit(HCI_CONN_ENCRYPT, &conn->flags))
++	/* If Secure Simple Pairing is not enabled, then legacy connection
++	 * setup is used and no encryption or key sizes can be enforced.
++	 */
++	if (!hci_conn_ssp_enabled(conn))
++		return 1;
++
++	if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
+ 		return 0;
+ 
+ 	/* The minimum encryption key size needs to be enforced by the
+-- 
+2.20.1

diff --git a/2700_revert-drm-i915-dma-resv-obj-fix.patch b/2700_revert-drm-i915-dma-resv-obj-fix.patch
new file mode 100644
index 00000000..a9fcaf4a
--- /dev/null
+++ b/2700_revert-drm-i915-dma-resv-obj-fix.patch
@@ -0,0 +1,107 @@
+From d481c481ca7813d688ffcb1c5418b48f83d945c1 Mon Sep 17 00:00:00 2001
+From: Luigi 'Comio' Mantellini <luigi.mantellini@gmail.com>
+Date: Sun, 28 Aug 2022 09:17:35 +0200
+Subject: [PATCH] Revert "drm/i915: Individualize fences before adding to
+ dma_resv obj"
+
+This reverts commit 842d9346b2fdda4d2fb8ccb5b87faef1ac01ab51.
+---
+ .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  3 +-
+ drivers/gpu/drm/i915/i915_vma.c               | 48 ++++++++-----------
+ 2 files changed, 21 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+index 30fe847c6664..c326bd2b444f 100644
+--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
++++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+@@ -999,8 +999,7 @@ static int eb_validate_vmas(struct i915_execbuffer *eb)
+ 			}
+ 		}
+ 
+-		/* Reserve enough slots to accommodate composite fences */
+-		err = dma_resv_reserve_fences(vma->obj->base.resv, eb->num_batches);
++		err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
+ 		if (err)
+ 			return err;
+ 
+diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
+index 16460b169ed2..e71826f0e4b1 100644
+--- a/drivers/gpu/drm/i915/i915_vma.c
++++ b/drivers/gpu/drm/i915/i915_vma.c
+@@ -23,7 +23,6 @@
+  */
+ 
+ #include <linux/sched/mm.h>
+-#include <linux/dma-fence-array.h>
+ #include <drm/drm_gem.h>
+ 
+ #include "display/intel_frontbuffer.h"
+@@ -1839,21 +1838,6 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
+ 	if (unlikely(err))
+ 		return err;
+ 
+-	/*
+-	 * Reserve fences slot early to prevent an allocation after preparing
+-	 * the workload and associating fences with dma_resv.
+-	 */
+-	if (fence && !(flags & __EXEC_OBJECT_NO_RESERVE)) {
+-		struct dma_fence *curr;
+-		int idx;
+-
+-		dma_fence_array_for_each(curr, idx, fence)
+-			;
+-		err = dma_resv_reserve_fences(vma->obj->base.resv, idx);
+-		if (unlikely(err))
+-			return err;
+-	}
+-
+ 	if (flags & EXEC_OBJECT_WRITE) {
+ 		struct intel_frontbuffer *front;
+ 
+@@ -1863,23 +1847,31 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
+ 				i915_active_add_request(&front->write, rq);
+ 			intel_frontbuffer_put(front);
+ 		}
+-	}
+ 
+-	if (fence) {
+-		struct dma_fence *curr;
+-		enum dma_resv_usage usage;
+-		int idx;
++		if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
++			err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
++			if (unlikely(err))
++				return err;
++		}
+ 
+-		obj->read_domains = 0;
+-		if (flags & EXEC_OBJECT_WRITE) {
+-			usage = DMA_RESV_USAGE_WRITE;
++		if (fence) {
++			dma_resv_add_fence(vma->obj->base.resv, fence,
++					   DMA_RESV_USAGE_WRITE);
+ 			obj->write_domain = I915_GEM_DOMAIN_RENDER;
+-		} else {
+-			usage = DMA_RESV_USAGE_READ;
++			obj->read_domains = 0;
++		}
++	} else {
++		if (!(flags & __EXEC_OBJECT_NO_RESERVE)) {
++			err = dma_resv_reserve_fences(vma->obj->base.resv, 1);
++			if (unlikely(err))
++				return err;
+ 		}
+ 
+-		dma_fence_array_for_each(curr, idx, fence)
+-			dma_resv_add_fence(vma->obj->base.resv, curr, usage);
++		if (fence) {
++			dma_resv_add_fence(vma->obj->base.resv, fence,
++					   DMA_RESV_USAGE_READ);
++			obj->write_domain = 0;
++		}
+ 	}
+ 
+ 	if (flags & EXEC_OBJECT_NEEDS_FENCE && vma->fence)
+-- 
+2.37.2
+

diff --git a/2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch b/2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
new file mode 100644
index 00000000..43356857
--- /dev/null
+++ b/2900_tmp513-Fix-build-issue-by-selecting-CONFIG_REG.patch
@@ -0,0 +1,30 @@
+From dc328d75a6f37f4ff11a81ae16b1ec88c3197640 Mon Sep 17 00:00:00 2001
+From: Mike Pagano <mpagano@gentoo.org>
+Date: Mon, 23 Mar 2020 08:20:06 -0400
+Subject: [PATCH 1/1] This driver requires REGMAP_I2C to build.  Select it by
+ default in Kconfig. Reported at gentoo bugzilla:
+ https://bugs.gentoo.org/710790
+Cc: mpagano@gentoo.org
+
+Reported-by: Phil Stracchino <phils@caerllewys.net>
+
+Signed-off-by: Mike Pagano <mpagano@gentoo.org>
+---
+ drivers/hwmon/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index 47ac20aee06f..530b4f29ba85 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -1769,6 +1769,7 @@ config SENSORS_TMP421
+ config SENSORS_TMP513
+ 	tristate "Texas Instruments TMP513 and compatibles"
+ 	depends on I2C
++	select REGMAP_I2C
+ 	help
+ 	  If you say yes here you get support for Texas Instruments TMP512,
+ 	  and TMP513 temperature and power supply sensor chips.
+-- 
+2.24.1
+

diff --git a/2920_sign-file-patch-for-libressl.patch b/2920_sign-file-patch-for-libressl.patch
new file mode 100644
index 00000000..e6ec017d
--- /dev/null
+++ b/2920_sign-file-patch-for-libressl.patch
@@ -0,0 +1,16 @@
+--- a/scripts/sign-file.c	2020-05-20 18:47:21.282820662 -0400
++++ b/scripts/sign-file.c	2020-05-20 18:48:37.991081899 -0400
+@@ -41,9 +41,10 @@
+  * signing with anything other than SHA1 - so we're stuck with that if such is
+  * the case.
+  */
+-#if defined(LIBRESSL_VERSION_NUMBER) || \
+-	OPENSSL_VERSION_NUMBER < 0x10000000L || \
+-	defined(OPENSSL_NO_CMS)
++#if defined(OPENSSL_NO_CMS) || \
++	( defined(LIBRESSL_VERSION_NUMBER) \
++	&& (LIBRESSL_VERSION_NUMBER < 0x3010000fL) ) || \
++	OPENSSL_VERSION_NUMBER < 0x10000000L
+ #define USE_PKCS7
+ #endif
+ #ifndef USE_PKCS7

diff --git a/3000_Support-printing-firmware-info.patch b/3000_Support-printing-firmware-info.patch
new file mode 100644
index 00000000..a630cfbe
--- /dev/null
+++ b/3000_Support-printing-firmware-info.patch
@@ -0,0 +1,14 @@
+--- a/drivers/base/firmware_loader/main.c	2021-08-24 15:42:07.025482085 -0400
++++ b/drivers/base/firmware_loader/main.c	2021-08-24 15:44:40.782975313 -0400
+@@ -809,6 +809,11 @@ _request_firmware(const struct firmware
+ 
+ 	ret = _request_firmware_prepare(&fw, name, device, buf, size,
+ 					offset, opt_flags);
++
++#ifdef CONFIG_GENTOO_PRINT_FIRMWARE_INFO
++        printk(KERN_NOTICE "Loading firmware: %s\n", name);
++#endif
++
+ 	if (ret <= 0) /* error or already assigned */
+ 		goto out;
+ 

diff --git a/5010_enable-cpu-optimizations-universal.patch b/5010_enable-cpu-optimizations-universal.patch
new file mode 100644
index 00000000..b9c03cb6
--- /dev/null
+++ b/5010_enable-cpu-optimizations-universal.patch
@@ -0,0 +1,675 @@
+From b5892719c43f739343c628e3d357471a3bdaa368 Mon Sep 17 00:00:00 2001
+From: graysky <graysky@archlinux.us>
+Date: Tue, 15 Mar 2022 05:58:43 -0400
+Subject: [PATCH] more uarches for kernel 5.17+
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+FEATURES
+This patch adds additional CPU options to the Linux kernel accessible under:
+ Processor type and features  --->
+  Processor family --->
+
+With the release of gcc 11.1 and clang 12.0, several generic 64-bit levels are
+offered which are good for supported Intel or AMD CPUs:
+• x86-64-v2
+• x86-64-v3
+• x86-64-v4
+
+Users of glibc 2.33 and above can see which level is supported by current
+hardware by running:
+  /lib/ld-linux-x86-64.so.2 --help | grep supported
+
+Alternatively, compare the flags from /proc/cpuinfo to this list.[1]
+
+CPU-specific microarchitectures include:
+• AMD Improved K8-family
+• AMD K10-family
+• AMD Family 10h (Barcelona)
+• AMD Family 14h (Bobcat)
+• AMD Family 16h (Jaguar)
+• AMD Family 15h (Bulldozer)
+• AMD Family 15h (Piledriver)
+• AMD Family 15h (Steamroller)
+• AMD Family 15h (Excavator)
+• AMD Family 17h (Zen)
+• AMD Family 17h (Zen 2)
+• AMD Family 19h (Zen 3)†
+• Intel Silvermont low-power processors
+• Intel Goldmont low-power processors (Apollo Lake and Denverton)
+• Intel Goldmont Plus low-power processors (Gemini Lake)
+• Intel 1st Gen Core i3/i5/i7 (Nehalem)
+• Intel 1.5 Gen Core i3/i5/i7 (Westmere)
+• Intel 2nd Gen Core i3/i5/i7 (Sandybridge)
+• Intel 3rd Gen Core i3/i5/i7 (Ivybridge)
+• Intel 4th Gen Core i3/i5/i7 (Haswell)
+• Intel 5th Gen Core i3/i5/i7 (Broadwell)
+• Intel 6th Gen Core i3/i5/i7 (Skylake)
+• Intel 6th Gen Core i7/i9 (Skylake X)
+• Intel 8th Gen Core i3/i5/i7 (Cannon Lake)
+• Intel 10th Gen Core i7/i9 (Ice Lake)
+• Intel Xeon (Cascade Lake)
+• Intel Xeon (Cooper Lake)*
+• Intel 3rd Gen 10nm++ i3/i5/i7/i9-family (Tiger Lake)*
+• Intel 3rd Gen 10nm++ Xeon (Sapphire Rapids)‡
+• Intel 11th Gen i3/i5/i7/i9-family (Rocket Lake)‡
+• Intel 12th Gen i3/i5/i7/i9-family (Alder Lake)‡
+
+Notes: If not otherwise noted, gcc >=9.1 is required for support.
+       *Requires gcc >=10.1 or clang >=10.0
+       †Required gcc >=10.3 or clang >=12.0
+       ‡Required gcc >=11.1 or clang >=12.0
+
+It also offers to compile passing the 'native' option which, "selects the CPU
+to generate code for at compilation time by determining the processor type of
+the compiling machine. Using -march=native enables all instruction subsets
+supported by the local machine and will produce code optimized for the local
+machine under the constraints of the selected instruction set."[2]
+
+Users of Intel CPUs should select the 'Intel-Native' option and users of AMD
+CPUs should select the 'AMD-Native' option.
+
+MINOR NOTES RELATING TO INTEL ATOM PROCESSORS
+This patch also changes -march=atom to -march=bonnell in accordance with the
+gcc v4.9 changes. Upstream is using the deprecated -match=atom flags when I
+believe it should use the newer -march=bonnell flag for atom processors.[3]
+
+It is not recommended to compile on Atom-CPUs with the 'native' option.[4] The
+recommendation is to use the 'atom' option instead.
+
+BENEFITS
+Small but real speed increases are measurable using a make endpoint comparing
+a generic kernel to one built with one of the respective microarchs.
+
+See the following experimental evidence supporting this statement:
+https://github.com/graysky2/kernel_gcc_patch
+
+REQUIREMENTS
+linux version 5.17+
+gcc version >=9.0 or clang version >=9.0
+
+ACKNOWLEDGMENTS
+This patch builds on the seminal work by Jeroen.[5]
+
+REFERENCES
+1.  https://gitlab.com/x86-psABIs/x86-64-ABI/-/commit/77566eb03bc6a326811cb7e9
+2.  https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html#index-x86-Options
+3.  https://bugzilla.kernel.org/show_bug.cgi?id=77461
+4.  https://github.com/graysky2/kernel_gcc_patch/issues/15
+5.  http://www.linuxforge.net/docs/linux/linux-gcc.php
+
+Signed-off-by: graysky <graysky@archlinux.us>
+---
+ arch/x86/Kconfig.cpu            | 332 ++++++++++++++++++++++++++++++--
+ arch/x86/Makefile               |  40 +++-
+ arch/x86/include/asm/vermagic.h |  66 +++++++
+ 3 files changed, 424 insertions(+), 14 deletions(-)
+
+diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
+index 542377cd419d..22b919cdb6d1 100644
+--- a/arch/x86/Kconfig.cpu
++++ b/arch/x86/Kconfig.cpu
+@@ -157,7 +157,7 @@ config MPENTIUM4
+ 
+ 
+ config MK6
+-	bool "K6/K6-II/K6-III"
++	bool "AMD K6/K6-II/K6-III"
+ 	depends on X86_32
+ 	help
+ 	  Select this for an AMD K6-family processor.  Enables use of
+@@ -165,7 +165,7 @@ config MK6
+ 	  flags to GCC.
+ 
+ config MK7
+-	bool "Athlon/Duron/K7"
++	bool "AMD Athlon/Duron/K7"
+ 	depends on X86_32
+ 	help
+ 	  Select this for an AMD Athlon K7-family processor.  Enables use of
+@@ -173,12 +173,98 @@ config MK7
+ 	  flags to GCC.
+ 
+ config MK8
+-	bool "Opteron/Athlon64/Hammer/K8"
++	bool "AMD Opteron/Athlon64/Hammer/K8"
+ 	help
+ 	  Select this for an AMD Opteron or Athlon64 Hammer-family processor.
+ 	  Enables use of some extended instructions, and passes appropriate
+ 	  optimization flags to GCC.
+ 
++config MK8SSE3
++	bool "AMD Opteron/Athlon64/Hammer/K8 with SSE3"
++	help
++	  Select this for improved AMD Opteron or Athlon64 Hammer-family processors.
++	  Enables use of some extended instructions, and passes appropriate
++	  optimization flags to GCC.
++
++config MK10
++	bool "AMD 61xx/7x50/PhenomX3/X4/II/K10"
++	help
++	  Select this for an AMD 61xx Eight-Core Magny-Cours, Athlon X2 7x50,
++	  Phenom X3/X4/II, Athlon II X2/X3/X4, or Turion II-family processor.
++	  Enables use of some extended instructions, and passes appropriate
++	  optimization flags to GCC.
++
++config MBARCELONA
++	bool "AMD Barcelona"
++	help
++	  Select this for AMD Family 10h Barcelona processors.
++
++	  Enables -march=barcelona
++
++config MBOBCAT
++	bool "AMD Bobcat"
++	help
++	  Select this for AMD Family 14h Bobcat processors.
++
++	  Enables -march=btver1
++
++config MJAGUAR
++	bool "AMD Jaguar"
++	help
++	  Select this for AMD Family 16h Jaguar processors.
++
++	  Enables -march=btver2
++
++config MBULLDOZER
++	bool "AMD Bulldozer"
++	help
++	  Select this for AMD Family 15h Bulldozer processors.
++
++	  Enables -march=bdver1
++
++config MPILEDRIVER
++	bool "AMD Piledriver"
++	help
++	  Select this for AMD Family 15h Piledriver processors.
++
++	  Enables -march=bdver2
++
++config MSTEAMROLLER
++	bool "AMD Steamroller"
++	help
++	  Select this for AMD Family 15h Steamroller processors.
++
++	  Enables -march=bdver3
++
++config MEXCAVATOR
++	bool "AMD Excavator"
++	help
++	  Select this for AMD Family 15h Excavator processors.
++
++	  Enables -march=bdver4
++
++config MZEN
++	bool "AMD Zen"
++	help
++	  Select this for AMD Family 17h Zen processors.
++
++	  Enables -march=znver1
++
++config MZEN2
++	bool "AMD Zen 2"
++	help
++	  Select this for AMD Family 17h Zen 2 processors.
++
++	  Enables -march=znver2
++
++config MZEN3
++	bool "AMD Zen 3"
++	depends on (CC_IS_GCC && GCC_VERSION >= 100300) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++	help
++	  Select this for AMD Family 19h Zen 3 processors.
++
++	  Enables -march=znver3
++
+ config MCRUSOE
+ 	bool "Crusoe"
+ 	depends on X86_32
+@@ -270,7 +356,7 @@ config MPSC
+ 	  in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one.
+ 
+ config MCORE2
+-	bool "Core 2/newer Xeon"
++	bool "Intel Core 2"
+ 	help
+ 
+ 	  Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and
+@@ -278,6 +364,8 @@ config MCORE2
+ 	  family in /proc/cpuinfo. Newer ones have 6 and older ones 15
+ 	  (not a typo)
+ 
++	  Enables -march=core2
++
+ config MATOM
+ 	bool "Intel Atom"
+ 	help
+@@ -287,6 +375,182 @@ config MATOM
+ 	  accordingly optimized code. Use a recent GCC with specific Atom
+ 	  support in order to fully benefit from selecting this option.
+ 
++config MNEHALEM
++	bool "Intel Nehalem"
++	select X86_P6_NOP
++	help
++
++	  Select this for 1st Gen Core processors in the Nehalem family.
++
++	  Enables -march=nehalem
++
++config MWESTMERE
++	bool "Intel Westmere"
++	select X86_P6_NOP
++	help
++
++	  Select this for the Intel Westmere formerly Nehalem-C family.
++
++	  Enables -march=westmere
++
++config MSILVERMONT
++	bool "Intel Silvermont"
++	select X86_P6_NOP
++	help
++
++	  Select this for the Intel Silvermont platform.
++
++	  Enables -march=silvermont
++
++config MGOLDMONT
++	bool "Intel Goldmont"
++	select X86_P6_NOP
++	help
++
++	  Select this for the Intel Goldmont platform including Apollo Lake and Denverton.
++
++	  Enables -march=goldmont
++
++config MGOLDMONTPLUS
++	bool "Intel Goldmont Plus"
++	select X86_P6_NOP
++	help
++
++	  Select this for the Intel Goldmont Plus platform including Gemini Lake.
++
++	  Enables -march=goldmont-plus
++
++config MSANDYBRIDGE
++	bool "Intel Sandy Bridge"
++	select X86_P6_NOP
++	help
++
++	  Select this for 2nd Gen Core processors in the Sandy Bridge family.
++
++	  Enables -march=sandybridge
++
++config MIVYBRIDGE
++	bool "Intel Ivy Bridge"
++	select X86_P6_NOP
++	help
++
++	  Select this for 3rd Gen Core processors in the Ivy Bridge family.
++
++	  Enables -march=ivybridge
++
++config MHASWELL
++	bool "Intel Haswell"
++	select X86_P6_NOP
++	help
++
++	  Select this for 4th Gen Core processors in the Haswell family.
++
++	  Enables -march=haswell
++
++config MBROADWELL
++	bool "Intel Broadwell"
++	select X86_P6_NOP
++	help
++
++	  Select this for 5th Gen Core processors in the Broadwell family.
++
++	  Enables -march=broadwell
++
++config MSKYLAKE
++	bool "Intel Skylake"
++	select X86_P6_NOP
++	help
++
++	  Select this for 6th Gen Core processors in the Skylake family.
++
++	  Enables -march=skylake
++
++config MSKYLAKEX
++	bool "Intel Skylake X"
++	select X86_P6_NOP
++	help
++
++	  Select this for 6th Gen Core processors in the Skylake X family.
++
++	  Enables -march=skylake-avx512
++
++config MCANNONLAKE
++	bool "Intel Cannon Lake"
++	select X86_P6_NOP
++	help
++
++	  Select this for 8th Gen Core processors
++
++	  Enables -march=cannonlake
++
++config MICELAKE
++	bool "Intel Ice Lake"
++	select X86_P6_NOP
++	help
++
++	  Select this for 10th Gen Core processors in the Ice Lake family.
++
++	  Enables -march=icelake-client
++
++config MCASCADELAKE
++	bool "Intel Cascade Lake"
++	select X86_P6_NOP
++	help
++
++	  Select this for Xeon processors in the Cascade Lake family.
++
++	  Enables -march=cascadelake
++
++config MCOOPERLAKE
++	bool "Intel Cooper Lake"
++	depends on (CC_IS_GCC && GCC_VERSION > 100100) || (CC_IS_CLANG && CLANG_VERSION >= 100000)
++	select X86_P6_NOP
++	help
++
++	  Select this for Xeon processors in the Cooper Lake family.
++
++	  Enables -march=cooperlake
++
++config MTIGERLAKE
++	bool "Intel Tiger Lake"
++	depends on  (CC_IS_GCC && GCC_VERSION > 100100) || (CC_IS_CLANG && CLANG_VERSION >= 100000)
++	select X86_P6_NOP
++	help
++
++	  Select this for third-generation 10 nm process processors in the Tiger Lake family.
++
++	  Enables -march=tigerlake
++
++config MSAPPHIRERAPIDS
++	bool "Intel Sapphire Rapids"
++	depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++	select X86_P6_NOP
++	help
++
++	  Select this for third-generation 10 nm process processors in the Sapphire Rapids family.
++
++	  Enables -march=sapphirerapids
++
++config MROCKETLAKE
++	bool "Intel Rocket Lake"
++	depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++	select X86_P6_NOP
++	help
++
++	  Select this for eleventh-generation processors in the Rocket Lake family.
++
++	  Enables -march=rocketlake
++
++config MALDERLAKE
++	bool "Intel Alder Lake"
++	depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++	select X86_P6_NOP
++	help
++
++	  Select this for twelfth-generation processors in the Alder Lake family.
++
++	  Enables -march=alderlake
++
+ config GENERIC_CPU
+ 	bool "Generic-x86-64"
+ 	depends on X86_64
+@@ -294,6 +558,50 @@ config GENERIC_CPU
+ 	  Generic x86-64 CPU.
+ 	  Run equally well on all x86-64 CPUs.
+ 
++config GENERIC_CPU2
++	bool "Generic-x86-64-v2"
++	depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++	depends on X86_64
++	help
++	  Generic x86-64 CPU.
++	  Run equally well on all x86-64 CPUs with min support of x86-64-v2.
++
++config GENERIC_CPU3
++	bool "Generic-x86-64-v3"
++	depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++	depends on X86_64
++	help
++	  Generic x86-64-v3 CPU with v3 instructions.
++	  Run equally well on all x86-64 CPUs with min support of x86-64-v3.
++
++config GENERIC_CPU4
++	bool "Generic-x86-64-v4"
++	depends on (CC_IS_GCC && GCC_VERSION > 110000) || (CC_IS_CLANG && CLANG_VERSION >= 120000)
++	depends on X86_64
++	help
++	  Generic x86-64 CPU with v4 instructions.
++	  Run equally well on all x86-64 CPUs with min support of x86-64-v4.
++
++config MNATIVE_INTEL
++	bool "Intel-Native optimizations autodetected by the compiler"
++	help
++
++	  Clang 3.8, GCC 4.2 and above support -march=native, which automatically detects
++	  the optimum settings to use based on your processor. Do NOT use this
++	  for AMD CPUs.  Intel Only!
++
++	  Enables -march=native
++
++config MNATIVE_AMD
++	bool "AMD-Native optimizations autodetected by the compiler"
++	help
++
++	  Clang 3.8, GCC 4.2 and above support -march=native, which automatically detects
++	  the optimum settings to use based on your processor. Do NOT use this
++	  for Intel CPUs.  AMD Only!
++
++	  Enables -march=native
++
+ endchoice
+ 
+ config X86_GENERIC
+@@ -318,7 +626,7 @@ config X86_INTERNODE_CACHE_SHIFT
+ config X86_L1_CACHE_SHIFT
+ 	int
+ 	default "7" if MPENTIUM4 || MPSC
+-	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
++	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD || X86_GENERIC || GENERIC_CPU || GENERIC_CPU2 || GENERIC_CPU3 || GENERIC_CPU4
+ 	default "4" if MELAN || M486SX || M486 || MGEODEGX1
+ 	default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
+ 
+@@ -336,11 +644,11 @@ config X86_ALIGNMENT_16
+ 
+ config X86_INTEL_USERCOPY
+ 	def_bool y
+-	depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2
++	depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL
+ 
+ config X86_USE_PPRO_CHECKSUM
+ 	def_bool y
+-	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM
++	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD
+ 
+ #
+ # P6_NOPs are a relatively minor optimization that require a family >=
+@@ -356,26 +664,26 @@ config X86_USE_PPRO_CHECKSUM
+ config X86_P6_NOP
+ 	def_bool y
+ 	depends on X86_64
+-	depends on (MCORE2 || MPENTIUM4 || MPSC)
++	depends on (MCORE2 || MPENTIUM4 || MPSC || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL)
+ 
+ config X86_TSC
+ 	def_bool y
+-	depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) || X86_64
++	depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD) || X86_64
+ 
+ config X86_CMPXCHG64
+ 	def_bool y
+-	depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586TSC || M586MMX || MATOM || MGEODE_LX || MGEODEGX1 || MK6 || MK7 || MK8
++	depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586TSC || M586MMX || MATOM || MGEODE_LX || MGEODEGX1 || MK6 || MK7 || MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD
+ 
+ # this should be set for all -march=.. options where the compiler
+ # generates cmov.
+ config X86_CMOV
+ 	def_bool y
+-	depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
++	depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD)
+ 
+ config X86_MINIMUM_CPU_FAMILY
+ 	int
+ 	default "64" if X86_64
+-	default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8)
++	default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8 ||  MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MJAGUAR || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MZEN2 || MZEN3 || MNEHALEM || MWESTMERE || MSILVERMONT || MGOLDMONT || MGOLDMONTPLUS || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MSKYLAKEX || MCANNONLAKE || MICELAKE || MCASCADELAKE || MCOOPERLAKE || MTIGERLAKE || MSAPPHIRERAPIDS || MROCKETLAKE || MALDERLAKE || MNATIVE_INTEL || MNATIVE_AMD)
+ 	default "5" if X86_32 && X86_CMPXCHG64
+ 	default "4"
+ 
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index e84cdd409b64..7d3bbf060079 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -131,8 +131,44 @@ else
+         # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu)
+         cflags-$(CONFIG_MK8)		+= -march=k8
+         cflags-$(CONFIG_MPSC)		+= -march=nocona
+-        cflags-$(CONFIG_MCORE2)		+= -march=core2
+-        cflags-$(CONFIG_MATOM)		+= -march=atom
++        cflags-$(CONFIG_MK8SSE3)	+= -march=k8-sse3
++        cflags-$(CONFIG_MK10) 		+= -march=amdfam10
++        cflags-$(CONFIG_MBARCELONA) 	+= -march=barcelona
++        cflags-$(CONFIG_MBOBCAT) 	+= -march=btver1
++        cflags-$(CONFIG_MJAGUAR) 	+= -march=btver2
++        cflags-$(CONFIG_MBULLDOZER) 	+= -march=bdver1
++        cflags-$(CONFIG_MPILEDRIVER)	+= -march=bdver2 -mno-tbm
++        cflags-$(CONFIG_MSTEAMROLLER) 	+= -march=bdver3 -mno-tbm
++        cflags-$(CONFIG_MEXCAVATOR) 	+= -march=bdver4 -mno-tbm
++        cflags-$(CONFIG_MZEN) 		+= -march=znver1
++        cflags-$(CONFIG_MZEN2) 	+= -march=znver2
++        cflags-$(CONFIG_MZEN3) 	+= -march=znver3
++        cflags-$(CONFIG_MNATIVE_INTEL) += -march=native
++        cflags-$(CONFIG_MNATIVE_AMD) 	+= -march=native
++        cflags-$(CONFIG_MATOM) 	+= -march=bonnell
++        cflags-$(CONFIG_MCORE2) 	+= -march=core2
++        cflags-$(CONFIG_MNEHALEM) 	+= -march=nehalem
++        cflags-$(CONFIG_MWESTMERE) 	+= -march=westmere
++        cflags-$(CONFIG_MSILVERMONT) 	+= -march=silvermont
++        cflags-$(CONFIG_MGOLDMONT) 	+= -march=goldmont
++        cflags-$(CONFIG_MGOLDMONTPLUS) += -march=goldmont-plus
++        cflags-$(CONFIG_MSANDYBRIDGE) 	+= -march=sandybridge
++        cflags-$(CONFIG_MIVYBRIDGE) 	+= -march=ivybridge
++        cflags-$(CONFIG_MHASWELL) 	+= -march=haswell
++        cflags-$(CONFIG_MBROADWELL) 	+= -march=broadwell
++        cflags-$(CONFIG_MSKYLAKE) 	+= -march=skylake
++        cflags-$(CONFIG_MSKYLAKEX) 	+= -march=skylake-avx512
++        cflags-$(CONFIG_MCANNONLAKE) 	+= -march=cannonlake
++        cflags-$(CONFIG_MICELAKE) 	+= -march=icelake-client
++        cflags-$(CONFIG_MCASCADELAKE) 	+= -march=cascadelake
++        cflags-$(CONFIG_MCOOPERLAKE) 	+= -march=cooperlake
++        cflags-$(CONFIG_MTIGERLAKE) 	+= -march=tigerlake
++        cflags-$(CONFIG_MSAPPHIRERAPIDS) += -march=sapphirerapids
++        cflags-$(CONFIG_MROCKETLAKE) 	+= -march=rocketlake
++        cflags-$(CONFIG_MALDERLAKE) 	+= -march=alderlake
++        cflags-$(CONFIG_GENERIC_CPU2) 	+= -march=x86-64-v2
++        cflags-$(CONFIG_GENERIC_CPU3) 	+= -march=x86-64-v3
++        cflags-$(CONFIG_GENERIC_CPU4) 	+= -march=x86-64-v4
+         cflags-$(CONFIG_GENERIC_CPU)	+= -mtune=generic
+         KBUILD_CFLAGS += $(cflags-y)
+ 
+diff --git a/arch/x86/include/asm/vermagic.h b/arch/x86/include/asm/vermagic.h
+index 75884d2cdec3..4e6a08d4c7e5 100644
+--- a/arch/x86/include/asm/vermagic.h
++++ b/arch/x86/include/asm/vermagic.h
+@@ -17,6 +17,48 @@
+ #define MODULE_PROC_FAMILY "586MMX "
+ #elif defined CONFIG_MCORE2
+ #define MODULE_PROC_FAMILY "CORE2 "
++#elif defined CONFIG_MNATIVE_INTEL
++#define MODULE_PROC_FAMILY "NATIVE_INTEL "
++#elif defined CONFIG_MNATIVE_AMD
++#define MODULE_PROC_FAMILY "NATIVE_AMD "
++#elif defined CONFIG_MNEHALEM
++#define MODULE_PROC_FAMILY "NEHALEM "
++#elif defined CONFIG_MWESTMERE
++#define MODULE_PROC_FAMILY "WESTMERE "
++#elif defined CONFIG_MSILVERMONT
++#define MODULE_PROC_FAMILY "SILVERMONT "
++#elif defined CONFIG_MGOLDMONT
++#define MODULE_PROC_FAMILY "GOLDMONT "
++#elif defined CONFIG_MGOLDMONTPLUS
++#define MODULE_PROC_FAMILY "GOLDMONTPLUS "
++#elif defined CONFIG_MSANDYBRIDGE
++#define MODULE_PROC_FAMILY "SANDYBRIDGE "
++#elif defined CONFIG_MIVYBRIDGE
++#define MODULE_PROC_FAMILY "IVYBRIDGE "
++#elif defined CONFIG_MHASWELL
++#define MODULE_PROC_FAMILY "HASWELL "
++#elif defined CONFIG_MBROADWELL
++#define MODULE_PROC_FAMILY "BROADWELL "
++#elif defined CONFIG_MSKYLAKE
++#define MODULE_PROC_FAMILY "SKYLAKE "
++#elif defined CONFIG_MSKYLAKEX
++#define MODULE_PROC_FAMILY "SKYLAKEX "
++#elif defined CONFIG_MCANNONLAKE
++#define MODULE_PROC_FAMILY "CANNONLAKE "
++#elif defined CONFIG_MICELAKE
++#define MODULE_PROC_FAMILY "ICELAKE "
++#elif defined CONFIG_MCASCADELAKE
++#define MODULE_PROC_FAMILY "CASCADELAKE "
++#elif defined CONFIG_MCOOPERLAKE
++#define MODULE_PROC_FAMILY "COOPERLAKE "
++#elif defined CONFIG_MTIGERLAKE
++#define MODULE_PROC_FAMILY "TIGERLAKE "
++#elif defined CONFIG_MSAPPHIRERAPIDS
++#define MODULE_PROC_FAMILY "SAPPHIRERAPIDS "
++#elif defined CONFIG_ROCKETLAKE
++#define MODULE_PROC_FAMILY "ROCKETLAKE "
++#elif defined CONFIG_MALDERLAKE
++#define MODULE_PROC_FAMILY "ALDERLAKE "
+ #elif defined CONFIG_MATOM
+ #define MODULE_PROC_FAMILY "ATOM "
+ #elif defined CONFIG_M686
+@@ -35,6 +77,30 @@
+ #define MODULE_PROC_FAMILY "K7 "
+ #elif defined CONFIG_MK8
+ #define MODULE_PROC_FAMILY "K8 "
++#elif defined CONFIG_MK8SSE3
++#define MODULE_PROC_FAMILY "K8SSE3 "
++#elif defined CONFIG_MK10
++#define MODULE_PROC_FAMILY "K10 "
++#elif defined CONFIG_MBARCELONA
++#define MODULE_PROC_FAMILY "BARCELONA "
++#elif defined CONFIG_MBOBCAT
++#define MODULE_PROC_FAMILY "BOBCAT "
++#elif defined CONFIG_MBULLDOZER
++#define MODULE_PROC_FAMILY "BULLDOZER "
++#elif defined CONFIG_MPILEDRIVER
++#define MODULE_PROC_FAMILY "PILEDRIVER "
++#elif defined CONFIG_MSTEAMROLLER
++#define MODULE_PROC_FAMILY "STEAMROLLER "
++#elif defined CONFIG_MJAGUAR
++#define MODULE_PROC_FAMILY "JAGUAR "
++#elif defined CONFIG_MEXCAVATOR
++#define MODULE_PROC_FAMILY "EXCAVATOR "
++#elif defined CONFIG_MZEN
++#define MODULE_PROC_FAMILY "ZEN "
++#elif defined CONFIG_MZEN2
++#define MODULE_PROC_FAMILY "ZEN2 "
++#elif defined CONFIG_MZEN3
++#define MODULE_PROC_FAMILY "ZEN3 "
+ #elif defined CONFIG_MELAN
+ #define MODULE_PROC_FAMILY "ELAN "
+ #elif defined CONFIG_MCRUSOE
+-- 
+2.35.1
+


^ permalink raw reply related	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2023-01-12 12:17 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-16 19:56 [gentoo-commits] proj/linux-patches:6.0 commit in: / Mike Pagano
  -- strict thread matches above, loose matches on Subject: below --
2023-01-12 12:17 Mike Pagano
2023-01-07 11:11 Mike Pagano
2023-01-04 11:38 Mike Pagano
2022-12-31 15:29 Mike Pagano
2022-12-21 18:50 Alice Ferrazzi
2022-12-19 12:23 Alice Ferrazzi
2022-12-14 12:51 Mike Pagano
2022-12-14 12:13 Mike Pagano
2022-12-08 11:40 Alice Ferrazzi
2022-12-06 13:46 Mike Pagano
2022-12-06 13:00 Mike Pagano
2022-12-02 17:23 Mike Pagano
2022-11-26 11:55 Mike Pagano
2022-11-16 11:16 Alice Ferrazzi
2022-11-10 18:18 Mike Pagano
2022-11-10 18:10 Mike Pagano
2022-11-09 19:00 Mike Pagano
2022-11-03 15:27 Mike Pagano
2022-11-01 12:46 Mike Pagano
2022-10-29  9:54 Mike Pagano
2022-10-26 11:24 Mike Pagano
2022-10-21 13:14 Mike Pagano
2022-10-15 10:03 Mike Pagano
2022-10-12 11:16 Mike Pagano
2022-10-03  9:31 Mike Pagano
2022-09-11 22:30 Mike Pagano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox