public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:6.0 commit in: /
Date: Thu, 10 Nov 2022 18:10:02 +0000 (UTC)	[thread overview]
Message-ID: <1668103787.8b3e419be10860f5c8692b5fb9acaaee189b3279.mpagano@gentoo> (raw)

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);


             reply	other threads:[~2022-11-10 18:10 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-10 18:10 Mike Pagano [this message]
  -- strict thread matches above, loose matches on Subject: below --
2023-01-12 12:17 [gentoo-commits] proj/linux-patches:6.0 commit in: / 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-16 19:56 Mike Pagano
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-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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1668103787.8b3e419be10860f5c8692b5fb9acaaee189b3279.mpagano@gentoo \
    --to=mpagano@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox