From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 64710158020 for ; Thu, 10 Nov 2022 18:10:08 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 82884E0A7F; Thu, 10 Nov 2022 18:10:07 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 11C94E0A7F for ; Thu, 10 Nov 2022 18:10:07 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 5C604340CCD for ; Thu, 10 Nov 2022 18:10:05 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 9F4FF6E9 for ; Thu, 10 Nov 2022 18:10:02 +0000 (UTC) From: "Mike Pagano" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Mike Pagano" Message-ID: <1668103787.8b3e419be10860f5c8692b5fb9acaaee189b3279.mpagano@gentoo> Subject: [gentoo-commits] proj/linux-patches:6.0 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1007_linux-6.0.8.patch X-VCS-Directories: / X-VCS-Committer: mpagano X-VCS-Committer-Name: Mike Pagano X-VCS-Revision: 8b3e419be10860f5c8692b5fb9acaaee189b3279 X-VCS-Branch: 6.0 Date: Thu, 10 Nov 2022 18:10:02 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 3b1b8a84-daae-47a2-a0c8-26efd86646c1 X-Archives-Hash: e29de15ddbc4a5a17ede0584ec7f910f commit: 8b3e419be10860f5c8692b5fb9acaaee189b3279 Author: Mike Pagano gentoo org> AuthorDate: Thu Nov 10 18:09:47 2022 +0000 Commit: Mike Pagano gentoo 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 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"; + }; + ++®_pu { ++ regulator-always-on; ++}; ++ + ®_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 = ; + }; + +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 = ; + }; + +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"; + }; + ++®_pu { ++ regulator-always-on; ++}; ++ + ®_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 = ; + 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 = ; + 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 = ; + 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 = ; +- power-domains = <&pgc_hsiomix>; + }; + + pgc_otg2: power-domain@3 { + #power-domain-cells = <0>; + reg = ; +- 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 = ; +- 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 = ; + 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 = ; + 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 = ; + 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 = ; + 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 + #include + #include ++#include + + #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 + + 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 + #include +-#include + + #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 + #include +-#include ++#include ++#include + + #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(¶ms->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 (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 +- + #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 + #include + #include + #include +@@ -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 +-#include + #include + + #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);