From 155c54f5916de4e291eaeaabf693f3ad86923529 Mon Sep 17 00:00:00 2001 From: Igor Pecovnik Date: Wed, 11 Sep 2024 08:31:22 +0200 Subject: [PATCH] Odroid XU4: remove deprecated patches --- .../odroidxu4-6.6/patch-6.6.44-45.patch | 5821 --------------- .../odroidxu4-6.6/patch-6.6.45-46.patch | 6300 ----------------- .../odroidxu4-6.6/patch-6.6.46-47.patch | 4211 ----------- 3 files changed, 16332 deletions(-) delete mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.44-45.patch delete mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.45-46.patch delete mode 100644 patch/kernel/archive/odroidxu4-6.6/patch-6.6.46-47.patch diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.44-45.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.44-45.patch deleted file mode 100644 index 95da970d54..0000000000 --- a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.44-45.patch +++ /dev/null @@ -1,5821 +0,0 @@ -diff --git a/Makefile b/Makefile -index 2e5d92ce2774d..0bd4bee2128b4 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 6 --SUBLEVEL = 44 -+SUBLEVEL = 45 - EXTRAVERSION = - NAME = Hurr durr I'ma ninja sloth - -diff --git a/arch/arm/kernel/perf_callchain.c b/arch/arm/kernel/perf_callchain.c -index 7147edbe56c67..1d230ac9d0eb5 100644 ---- a/arch/arm/kernel/perf_callchain.c -+++ b/arch/arm/kernel/perf_callchain.c -@@ -85,8 +85,7 @@ static bool - callchain_trace(void *data, unsigned long pc) - { - struct perf_callchain_entry_ctx *entry = data; -- perf_callchain_store(entry, pc); -- return true; -+ return perf_callchain_store(entry, pc) == 0; - } - - void -diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi -index 5effd8180cc41..e5993a365870c 100644 ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi -@@ -641,6 +641,7 @@ dwc_0: usb@8a00000 { - interrupts = ; - phys = <&qusb_phy_0>, <&usb0_ssphy>; - phy-names = "usb2-phy", "usb3-phy"; -+ snps,parkmode-disable-ss-quirk; - snps,is-utmi-l1-suspend; - snps,hird-threshold = /bits/ 8 <0x0>; - snps,dis_u2_susphy_quirk; -@@ -683,6 +684,7 @@ dwc_1: usb@8c00000 { - interrupts = ; - phys = <&qusb_phy_1>, <&usb1_ssphy>; - phy-names = "usb2-phy", "usb3-phy"; -+ snps,parkmode-disable-ss-quirk; - snps,is-utmi-l1-suspend; - snps,hird-threshold = /bits/ 8 <0x0>; - snps,dis_u2_susphy_quirk; -diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi -index 9c072ce197358..7fcc15b6946ae 100644 ---- a/arch/arm64/boot/dts/qcom/msm8998.dtsi -+++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi -@@ -2159,7 +2159,8 @@ usb3_dwc3: usb@a800000 { - interrupts = ; - snps,dis_u2_susphy_quirk; - snps,dis_enblslpm_quirk; -- phys = <&qusb2phy>, <&usb1_ssphy>; -+ snps,parkmode-disable-ss-quirk; -+ phys = <&qusb2phy>, <&usb3phy>; - phy-names = "usb2-phy", "usb3-phy"; - snps,has-lpm-erratum; - snps,hird-threshold = /bits/ 8 <0x10>; -@@ -2168,33 +2169,26 @@ usb3_dwc3: usb@a800000 { - - usb3phy: phy@c010000 { - compatible = "qcom,msm8998-qmp-usb3-phy"; -- reg = <0x0c010000 0x18c>; -- status = "disabled"; -- #address-cells = <1>; -- #size-cells = <1>; -- ranges; -+ reg = <0x0c010000 0x1000>; - - clocks = <&gcc GCC_USB3_PHY_AUX_CLK>, -+ <&gcc GCC_USB3_CLKREF_CLK>, - <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, -- <&gcc GCC_USB3_CLKREF_CLK>; -- clock-names = "aux", "cfg_ahb", "ref"; -+ <&gcc GCC_USB3_PHY_PIPE_CLK>; -+ clock-names = "aux", -+ "ref", -+ "cfg_ahb", -+ "pipe"; -+ clock-output-names = "usb3_phy_pipe_clk_src"; -+ #clock-cells = <0>; -+ #phy-cells = <0>; - - resets = <&gcc GCC_USB3_PHY_BCR>, - <&gcc GCC_USB3PHY_PHY_BCR>; -- reset-names = "phy", "common"; -+ reset-names = "phy", -+ "phy_phy"; - -- usb1_ssphy: phy@c010200 { -- reg = <0xc010200 0x128>, -- <0xc010400 0x200>, -- <0xc010c00 0x20c>, -- <0xc010600 0x128>, -- <0xc010800 0x200>; -- #phy-cells = <0>; -- #clock-cells = <0>; -- clocks = <&gcc GCC_USB3_PHY_PIPE_CLK>; -- clock-names = "pipe0"; -- clock-output-names = "usb3_phy_pipe_clk_src"; -- }; -+ status = "disabled"; - }; - - qusb2phy: phy@c012000 { -diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi -index f7c528ecb224b..68b1c017a9fd5 100644 ---- a/arch/arm64/boot/dts/qcom/sc7180.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2795,49 +2796,28 @@ usb_1_hsphy: phy@88e3000 { - nvmem-cells = <&qusb2p_hstx_trim>; - }; - -- usb_1_qmpphy: phy-wrapper@88e9000 { -+ usb_1_qmpphy: phy@88e8000 { - compatible = "qcom,sc7180-qmp-usb3-dp-phy"; -- reg = <0 0x088e9000 0 0x18c>, -- <0 0x088e8000 0 0x3c>, -- <0 0x088ea000 0 0x18c>; -+ reg = <0 0x088e8000 0 0x3000>; - status = "disabled"; -- #address-cells = <2>; -- #size-cells = <2>; -- ranges; - - clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>, -- <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, - <&gcc GCC_USB3_PRIM_CLKREF_CLK>, -- <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>; -- clock-names = "aux", "cfg_ahb", "ref", "com_aux"; -+ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>, -+ <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>, -+ <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>; -+ clock-names = "aux", -+ "ref", -+ "com_aux", -+ "usb3_pipe", -+ "cfg_ahb"; - - resets = <&gcc GCC_USB3_PHY_PRIM_BCR>, - <&gcc GCC_USB3_DP_PHY_PRIM_BCR>; - reset-names = "phy", "common"; - -- usb_1_ssphy: usb3-phy@88e9200 { -- reg = <0 0x088e9200 0 0x128>, -- <0 0x088e9400 0 0x200>, -- <0 0x088e9c00 0 0x218>, -- <0 0x088e9600 0 0x128>, -- <0 0x088e9800 0 0x200>, -- <0 0x088e9a00 0 0x18>; -- #clock-cells = <0>; -- #phy-cells = <0>; -- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; -- clock-names = "pipe0"; -- clock-output-names = "usb3_phy_pipe_clk_src"; -- }; -- -- dp_phy: dp-phy@88ea200 { -- reg = <0 0x088ea200 0 0x200>, -- <0 0x088ea400 0 0x200>, -- <0 0x088eaa00 0 0x200>, -- <0 0x088ea600 0 0x200>, -- <0 0x088ea800 0 0x200>; -- #clock-cells = <1>; -- #phy-cells = <0>; -- }; -+ #clock-cells = <1>; -+ #phy-cells = <1>; - }; - - pmu@90b6300 { -@@ -3001,7 +2981,8 @@ usb_1_dwc3: usb@a600000 { - iommus = <&apps_smmu 0x540 0>; - snps,dis_u2_susphy_quirk; - snps,dis_enblslpm_quirk; -- phys = <&usb_1_hsphy>, <&usb_1_ssphy>; -+ snps,parkmode-disable-ss-quirk; -+ phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>; - phy-names = "usb2-phy", "usb3-phy"; - maximum-speed = "super-speed"; - }; -@@ -3307,8 +3288,9 @@ mdss_dp: displayport-controller@ae90000 { - "ctrl_link_iface", "stream_pixel"; - assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>, - <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>; -- assigned-clock-parents = <&dp_phy 0>, <&dp_phy 1>; -- phys = <&dp_phy>; -+ assigned-clock-parents = <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>, -+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>; -+ phys = <&usb_1_qmpphy QMP_USB43DP_DP_PHY>; - phy-names = "dp"; - - operating-points-v2 = <&dp_opp_table>; -@@ -3365,8 +3347,8 @@ dispcc: clock-controller@af00000 { - <&gcc GCC_DISP_GPLL0_CLK_SRC>, - <&mdss_dsi0_phy 0>, - <&mdss_dsi0_phy 1>, -- <&dp_phy 0>, -- <&dp_phy 1>; -+ <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>, -+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>; - clock-names = "bi_tcxo", - "gcc_disp_gpll0_clk_src", - "dsi0_phy_pll_out_byteclk", -diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi -index b75de7caaa7e5..149c7962f2cbb 100644 ---- a/arch/arm64/boot/dts/qcom/sc7280.dtsi -+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -858,7 +859,7 @@ gcc: clock-controller@100000 { - <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>, - <0>, <&pcie1_lane>, - <0>, <0>, <0>, -- <&usb_1_ssphy>; -+ <&usb_1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>; - clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", - "pcie_0_pipe_clk", "pcie_1_pipe_clk", - "ufs_phy_rx_symbol_0_clk", "ufs_phy_rx_symbol_1_clk", -@@ -3351,49 +3352,26 @@ usb_2_hsphy: phy@88e4000 { - resets = <&gcc GCC_QUSB2PHY_SEC_BCR>; - }; - -- usb_1_qmpphy: phy-wrapper@88e9000 { -- compatible = "qcom,sc7280-qmp-usb3-dp-phy", -- "qcom,sm8250-qmp-usb3-dp-phy"; -- reg = <0 0x088e9000 0 0x200>, -- <0 0x088e8000 0 0x40>, -- <0 0x088ea000 0 0x200>; -+ usb_1_qmpphy: phy@88e8000 { -+ compatible = "qcom,sc7280-qmp-usb3-dp-phy"; -+ reg = <0 0x088e8000 0 0x3000>; - status = "disabled"; -- #address-cells = <2>; -- #size-cells = <2>; -- ranges; - - clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>, - <&rpmhcc RPMH_CXO_CLK>, -- <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>; -- clock-names = "aux", "ref_clk_src", "com_aux"; -+ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>, -+ <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; -+ clock-names = "aux", -+ "ref", -+ "com_aux", -+ "usb3_pipe"; - - resets = <&gcc GCC_USB3_DP_PHY_PRIM_BCR>, - <&gcc GCC_USB3_PHY_PRIM_BCR>; - reset-names = "phy", "common"; - -- usb_1_ssphy: usb3-phy@88e9200 { -- reg = <0 0x088e9200 0 0x200>, -- <0 0x088e9400 0 0x200>, -- <0 0x088e9c00 0 0x400>, -- <0 0x088e9600 0 0x200>, -- <0 0x088e9800 0 0x200>, -- <0 0x088e9a00 0 0x100>; -- #clock-cells = <0>; -- #phy-cells = <0>; -- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; -- clock-names = "pipe0"; -- clock-output-names = "usb3_phy_pipe_clk_src"; -- }; -- -- dp_phy: dp-phy@88ea200 { -- reg = <0 0x088ea200 0 0x200>, -- <0 0x088ea400 0 0x200>, -- <0 0x088eaa00 0 0x200>, -- <0 0x088ea600 0 0x200>, -- <0 0x088ea800 0 0x200>; -- #phy-cells = <0>; -- #clock-cells = <1>; -- }; -+ #clock-cells = <1>; -+ #phy-cells = <1>; - }; - - usb_2: usb@8cf8800 { -@@ -3702,7 +3680,8 @@ usb_1_dwc3: usb@a600000 { - iommus = <&apps_smmu 0xe0 0x0>; - snps,dis_u2_susphy_quirk; - snps,dis_enblslpm_quirk; -- phys = <&usb_1_hsphy>, <&usb_1_ssphy>; -+ snps,parkmode-disable-ss-quirk; -+ phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>; - phy-names = "usb2-phy", "usb3-phy"; - maximum-speed = "super-speed"; - }; -@@ -3807,8 +3786,8 @@ dispcc: clock-controller@af00000 { - <&gcc GCC_DISP_GPLL0_CLK_SRC>, - <&mdss_dsi_phy 0>, - <&mdss_dsi_phy 1>, -- <&dp_phy 0>, -- <&dp_phy 1>, -+ <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>, -+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>, - <&mdss_edp_phy 0>, - <&mdss_edp_phy 1>; - clock-names = "bi_tcxo", -@@ -4144,8 +4123,9 @@ mdss_dp: displayport-controller@ae90000 { - "stream_pixel"; - assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>, - <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>; -- assigned-clock-parents = <&dp_phy 0>, <&dp_phy 1>; -- phys = <&dp_phy>; -+ assigned-clock-parents = <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>, -+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>; -+ phys = <&usb_1_qmpphy QMP_USB43DP_DP_PHY>; - phy-names = "dp"; - - operating-points-v2 = <&dp_opp_table>; -diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi -index 9d9b378c07e14..dcdc8a0cd1819 100644 ---- a/arch/arm64/boot/dts/qcom/sdm845.dtsi -+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -3983,80 +3984,54 @@ usb_2_hsphy: phy@88e3000 { - nvmem-cells = <&qusb2s_hstx_trim>; - }; - -- usb_1_qmpphy: phy@88e9000 { -+ usb_1_qmpphy: phy@88e8000 { - compatible = "qcom,sdm845-qmp-usb3-dp-phy"; -- reg = <0 0x088e9000 0 0x18c>, -- <0 0x088e8000 0 0x38>, -- <0 0x088ea000 0 0x40>; -+ reg = <0 0x088e8000 0 0x3000>; - status = "disabled"; -- #address-cells = <2>; -- #size-cells = <2>; -- ranges; - - clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>, -- <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, - <&gcc GCC_USB3_PRIM_CLKREF_CLK>, -- <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>; -- clock-names = "aux", "cfg_ahb", "ref", "com_aux"; -+ <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>, -+ <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>, -+ <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>; -+ clock-names = "aux", -+ "ref", -+ "com_aux", -+ "usb3_pipe", -+ "cfg_ahb"; - - resets = <&gcc GCC_USB3_PHY_PRIM_BCR>, - <&gcc GCC_USB3_DP_PHY_PRIM_BCR>; - reset-names = "phy", "common"; - -- usb_1_ssphy: usb3-phy@88e9200 { -- reg = <0 0x088e9200 0 0x128>, -- <0 0x088e9400 0 0x200>, -- <0 0x088e9c00 0 0x218>, -- <0 0x088e9600 0 0x128>, -- <0 0x088e9800 0 0x200>, -- <0 0x088e9a00 0 0x100>; -- #clock-cells = <0>; -- #phy-cells = <0>; -- clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; -- clock-names = "pipe0"; -- clock-output-names = "usb3_phy_pipe_clk_src"; -- }; -- -- dp_phy: dp-phy@88ea200 { -- reg = <0 0x088ea200 0 0x200>, -- <0 0x088ea400 0 0x200>, -- <0 0x088eaa00 0 0x200>, -- <0 0x088ea600 0 0x200>, -- <0 0x088ea800 0 0x200>; -- #clock-cells = <1>; -- #phy-cells = <0>; -- }; -+ #clock-cells = <1>; -+ #phy-cells = <1>; - }; - - usb_2_qmpphy: phy@88eb000 { - compatible = "qcom,sdm845-qmp-usb3-uni-phy"; -- reg = <0 0x088eb000 0 0x18c>; -- status = "disabled"; -- #address-cells = <2>; -- #size-cells = <2>; -- ranges; -+ reg = <0 0x088eb000 0 0x1000>; - - clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>, - <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, - <&gcc GCC_USB3_SEC_CLKREF_CLK>, -- <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>; -- clock-names = "aux", "cfg_ahb", "ref", "com_aux"; -+ <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>, -+ <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; -+ clock-names = "aux", -+ "cfg_ahb", -+ "ref", -+ "com_aux", -+ "pipe"; -+ clock-output-names = "usb3_uni_phy_pipe_clk_src"; -+ #clock-cells = <0>; -+ #phy-cells = <0>; - -- resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR>, -- <&gcc GCC_USB3_PHY_SEC_BCR>; -- reset-names = "phy", "common"; -+ resets = <&gcc GCC_USB3_PHY_SEC_BCR>, -+ <&gcc GCC_USB3PHY_PHY_SEC_BCR>; -+ reset-names = "phy", -+ "phy_phy"; - -- usb_2_ssphy: phy@88eb200 { -- reg = <0 0x088eb200 0 0x128>, -- <0 0x088eb400 0 0x1fc>, -- <0 0x088eb800 0 0x218>, -- <0 0x088eb600 0 0x70>; -- #clock-cells = <0>; -- #phy-cells = <0>; -- clocks = <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; -- clock-names = "pipe0"; -- clock-output-names = "usb3_uni_phy_pipe_clk_src"; -- }; -+ status = "disabled"; - }; - - usb_1: usb@a6f8800 { -@@ -4105,7 +4080,8 @@ usb_1_dwc3: usb@a600000 { - iommus = <&apps_smmu 0x740 0>; - snps,dis_u2_susphy_quirk; - snps,dis_enblslpm_quirk; -- phys = <&usb_1_hsphy>, <&usb_1_ssphy>; -+ snps,parkmode-disable-ss-quirk; -+ phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>; - phy-names = "usb2-phy", "usb3-phy"; - }; - }; -@@ -4156,7 +4132,8 @@ usb_2_dwc3: usb@a800000 { - iommus = <&apps_smmu 0x760 0>; - snps,dis_u2_susphy_quirk; - snps,dis_enblslpm_quirk; -- phys = <&usb_2_hsphy>, <&usb_2_ssphy>; -+ snps,parkmode-disable-ss-quirk; -+ phys = <&usb_2_hsphy>, <&usb_2_qmpphy>; - phy-names = "usb2-phy", "usb3-phy"; - }; - }; -@@ -4573,8 +4550,9 @@ mdss_dp: displayport-controller@ae90000 { - "ctrl_link_iface", "stream_pixel"; - assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>, - <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>; -- assigned-clock-parents = <&dp_phy 0>, <&dp_phy 1>; -- phys = <&dp_phy>; -+ assigned-clock-parents = <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>, -+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>; -+ phys = <&usb_1_qmpphy QMP_USB43DP_DP_PHY>; - phy-names = "dp"; - - operating-points-v2 = <&dp_opp_table>; -@@ -4912,8 +4890,8 @@ dispcc: clock-controller@af00000 { - <&mdss_dsi0_phy 1>, - <&mdss_dsi1_phy 0>, - <&mdss_dsi1_phy 1>, -- <&dp_phy 0>, -- <&dp_phy 1>; -+ <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>, -+ <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>; - clock-names = "bi_tcxo", - "gcc_disp_gpll0_clk_src", - "gcc_disp_gpll0_div_clk_src", -diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h -index 6aafbb7899916..4b99159150829 100644 ---- a/arch/arm64/include/asm/jump_label.h -+++ b/arch/arm64/include/asm/jump_label.h -@@ -13,6 +13,7 @@ - #include - #include - -+#define HAVE_JUMP_LABEL_BATCH - #define JUMP_LABEL_NOP_SIZE AARCH64_INSN_SIZE - - static __always_inline bool arch_static_branch(struct static_key * const key, -diff --git a/arch/arm64/kernel/jump_label.c b/arch/arm64/kernel/jump_label.c -index faf88ec9c48e8..f63ea915d6ad2 100644 ---- a/arch/arm64/kernel/jump_label.c -+++ b/arch/arm64/kernel/jump_label.c -@@ -7,11 +7,12 @@ - */ - #include - #include -+#include - #include - #include - --void arch_jump_label_transform(struct jump_entry *entry, -- enum jump_label_type type) -+bool arch_jump_label_transform_queue(struct jump_entry *entry, -+ enum jump_label_type type) - { - void *addr = (void *)jump_entry_code(entry); - u32 insn; -@@ -25,4 +26,10 @@ void arch_jump_label_transform(struct jump_entry *entry, - } - - aarch64_insn_patch_text_nosync(addr, insn); -+ return true; -+} -+ -+void arch_jump_label_transform_apply(void) -+{ -+ kick_all_cpus_sync(); - } -diff --git a/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi b/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi -index c0be84a6e81fd..cc7747c5f21f3 100644 ---- a/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi -+++ b/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi -@@ -99,8 +99,8 @@ liointc1: interrupt-controller@1fe11440 { - rtc0: rtc@1fe07800 { - compatible = "loongson,ls2k1000-rtc"; - reg = <0 0x1fe07800 0 0x78>; -- interrupt-parent = <&liointc0>; -- interrupts = <60 IRQ_TYPE_LEVEL_LOW>; -+ interrupt-parent = <&liointc1>; -+ interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; - }; - - uart0: serial@1fe00000 { -@@ -108,7 +108,7 @@ uart0: serial@1fe00000 { - reg = <0 0x1fe00000 0 0x8>; - clock-frequency = <125000000>; - interrupt-parent = <&liointc0>; -- interrupts = <0 IRQ_TYPE_LEVEL_LOW>; -+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; - no-loopback-test; - }; - -@@ -117,7 +117,6 @@ pci@1a000000 { - device_type = "pci"; - #address-cells = <3>; - #size-cells = <2>; -- #interrupt-cells = <2>; - - reg = <0 0x1a000000 0 0x02000000>, - <0xfe 0x00000000 0 0x20000000>; -@@ -132,8 +131,8 @@ gmac@3,0 { - "pciclass0c03"; - - reg = <0x1800 0x0 0x0 0x0 0x0>; -- interrupts = <12 IRQ_TYPE_LEVEL_LOW>, -- <13 IRQ_TYPE_LEVEL_LOW>; -+ interrupts = <12 IRQ_TYPE_LEVEL_HIGH>, -+ <13 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "macirq", "eth_lpi"; - interrupt-parent = <&liointc0>; - phy-mode = "rgmii-id"; -@@ -156,8 +155,8 @@ gmac@3,1 { - "loongson, pci-gmac"; - - reg = <0x1900 0x0 0x0 0x0 0x0>; -- interrupts = <14 IRQ_TYPE_LEVEL_LOW>, -- <15 IRQ_TYPE_LEVEL_LOW>; -+ interrupts = <14 IRQ_TYPE_LEVEL_HIGH>, -+ <15 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "macirq", "eth_lpi"; - interrupt-parent = <&liointc0>; - phy-mode = "rgmii-id"; -@@ -179,7 +178,7 @@ ehci@4,1 { - "pciclass0c03"; - - reg = <0x2100 0x0 0x0 0x0 0x0>; -- interrupts = <18 IRQ_TYPE_LEVEL_LOW>; -+ interrupts = <18 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&liointc1>; - }; - -@@ -190,7 +189,7 @@ ohci@4,2 { - "pciclass0c03"; - - reg = <0x2200 0x0 0x0 0x0 0x0>; -- interrupts = <19 IRQ_TYPE_LEVEL_LOW>; -+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&liointc1>; - }; - -@@ -201,97 +200,121 @@ sata@8,0 { - "pciclass0106"; - - reg = <0x4000 0x0 0x0 0x0 0x0>; -- interrupts = <19 IRQ_TYPE_LEVEL_LOW>; -+ interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&liointc0>; - }; - -- pci_bridge@9,0 { -+ pcie@9,0 { - compatible = "pci0014,7a19.0", - "pci0014,7a19", - "pciclass060400", - "pciclass0604"; - - reg = <0x4800 0x0 0x0 0x0 0x0>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; - #interrupt-cells = <1>; -- interrupts = <0 IRQ_TYPE_LEVEL_LOW>; -+ interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&liointc1>; - interrupt-map-mask = <0 0 0 0>; -- interrupt-map = <0 0 0 0 &liointc1 0 IRQ_TYPE_LEVEL_LOW>; -+ interrupt-map = <0 0 0 0 &liointc1 0 IRQ_TYPE_LEVEL_HIGH>; -+ ranges; - external-facing; - }; - -- pci_bridge@a,0 { -+ pcie@a,0 { - compatible = "pci0014,7a09.0", - "pci0014,7a09", - "pciclass060400", - "pciclass0604"; - - reg = <0x5000 0x0 0x0 0x0 0x0>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; - #interrupt-cells = <1>; -- interrupts = <1 IRQ_TYPE_LEVEL_LOW>; -+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&liointc1>; - interrupt-map-mask = <0 0 0 0>; -- interrupt-map = <0 0 0 0 &liointc1 1 IRQ_TYPE_LEVEL_LOW>; -+ interrupt-map = <0 0 0 0 &liointc1 1 IRQ_TYPE_LEVEL_HIGH>; -+ ranges; - external-facing; - }; - -- pci_bridge@b,0 { -+ pcie@b,0 { - compatible = "pci0014,7a09.0", - "pci0014,7a09", - "pciclass060400", - "pciclass0604"; - - reg = <0x5800 0x0 0x0 0x0 0x0>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; - #interrupt-cells = <1>; -- interrupts = <2 IRQ_TYPE_LEVEL_LOW>; -+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&liointc1>; - interrupt-map-mask = <0 0 0 0>; -- interrupt-map = <0 0 0 0 &liointc1 2 IRQ_TYPE_LEVEL_LOW>; -+ interrupt-map = <0 0 0 0 &liointc1 2 IRQ_TYPE_LEVEL_HIGH>; -+ ranges; - external-facing; - }; - -- pci_bridge@c,0 { -+ pcie@c,0 { - compatible = "pci0014,7a09.0", - "pci0014,7a09", - "pciclass060400", - "pciclass0604"; - - reg = <0x6000 0x0 0x0 0x0 0x0>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; - #interrupt-cells = <1>; -- interrupts = <3 IRQ_TYPE_LEVEL_LOW>; -+ interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&liointc1>; - interrupt-map-mask = <0 0 0 0>; -- interrupt-map = <0 0 0 0 &liointc1 3 IRQ_TYPE_LEVEL_LOW>; -+ interrupt-map = <0 0 0 0 &liointc1 3 IRQ_TYPE_LEVEL_HIGH>; -+ ranges; - external-facing; - }; - -- pci_bridge@d,0 { -+ pcie@d,0 { - compatible = "pci0014,7a19.0", - "pci0014,7a19", - "pciclass060400", - "pciclass0604"; - - reg = <0x6800 0x0 0x0 0x0 0x0>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; - #interrupt-cells = <1>; -- interrupts = <4 IRQ_TYPE_LEVEL_LOW>; -+ interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&liointc1>; - interrupt-map-mask = <0 0 0 0>; -- interrupt-map = <0 0 0 0 &liointc1 4 IRQ_TYPE_LEVEL_LOW>; -+ interrupt-map = <0 0 0 0 &liointc1 4 IRQ_TYPE_LEVEL_HIGH>; -+ ranges; - external-facing; - }; - -- pci_bridge@e,0 { -+ pcie@e,0 { - compatible = "pci0014,7a09.0", - "pci0014,7a09", - "pciclass060400", - "pciclass0604"; - - reg = <0x7000 0x0 0x0 0x0 0x0>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; - #interrupt-cells = <1>; -- interrupts = <5 IRQ_TYPE_LEVEL_LOW>; -+ interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&liointc1>; - interrupt-map-mask = <0 0 0 0>; -- interrupt-map = <0 0 0 0 &liointc1 5 IRQ_TYPE_LEVEL_LOW>; -+ interrupt-map = <0 0 0 0 &liointc1 5 IRQ_TYPE_LEVEL_HIGH>; -+ ranges; - external-facing; - }; - -diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c -index 5348d842c7453..e867fe465164e 100644 ---- a/arch/riscv/kernel/traps_misaligned.c -+++ b/arch/riscv/kernel/traps_misaligned.c -@@ -151,51 +151,19 @@ - #define PRECISION_S 0 - #define PRECISION_D 1 - --#define DECLARE_UNPRIVILEGED_LOAD_FUNCTION(type, insn) \ --static inline type load_##type(const type *addr) \ --{ \ -- type val; \ -- asm (#insn " %0, %1" \ -- : "=&r" (val) : "m" (*addr)); \ -- return val; \ --} -+static inline u8 load_u8(const u8 *addr) -+{ -+ u8 val; - --#define DECLARE_UNPRIVILEGED_STORE_FUNCTION(type, insn) \ --static inline void store_##type(type *addr, type val) \ --{ \ -- asm volatile (#insn " %0, %1\n" \ -- : : "r" (val), "m" (*addr)); \ --} -+ asm volatile("lbu %0, %1" : "=&r" (val) : "m" (*addr)); - --DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u8, lbu) --DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u16, lhu) --DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s8, lb) --DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s16, lh) --DECLARE_UNPRIVILEGED_LOAD_FUNCTION(s32, lw) --DECLARE_UNPRIVILEGED_STORE_FUNCTION(u8, sb) --DECLARE_UNPRIVILEGED_STORE_FUNCTION(u16, sh) --DECLARE_UNPRIVILEGED_STORE_FUNCTION(u32, sw) --#if defined(CONFIG_64BIT) --DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u32, lwu) --DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u64, ld) --DECLARE_UNPRIVILEGED_STORE_FUNCTION(u64, sd) --DECLARE_UNPRIVILEGED_LOAD_FUNCTION(ulong, ld) --#else --DECLARE_UNPRIVILEGED_LOAD_FUNCTION(u32, lw) --DECLARE_UNPRIVILEGED_LOAD_FUNCTION(ulong, lw) -- --static inline u64 load_u64(const u64 *addr) --{ -- return load_u32((u32 *)addr) -- + ((u64)load_u32((u32 *)addr + 1) << 32); -+ return val; - } - --static inline void store_u64(u64 *addr, u64 val) -+static inline void store_u8(u8 *addr, u8 val) - { -- store_u32((u32 *)addr, val); -- store_u32((u32 *)addr + 1, val >> 32); -+ asm volatile ("sb %0, %1\n" : : "r" (val), "m" (*addr)); - } --#endif - - static inline ulong get_insn(ulong mepc) - { -diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c -index 90d4ba36d1d06..655b2b1bb529f 100644 ---- a/arch/riscv/mm/fault.c -+++ b/arch/riscv/mm/fault.c -@@ -61,26 +61,27 @@ static inline void no_context(struct pt_regs *regs, unsigned long addr) - - static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_fault_t fault) - { -+ if (!user_mode(regs)) { -+ no_context(regs, addr); -+ return; -+ } -+ - if (fault & VM_FAULT_OOM) { - /* - * We ran out of memory, call the OOM killer, and return the userspace - * (which will retry the fault, or kill us if we got oom-killed). - */ -- if (!user_mode(regs)) { -- no_context(regs, addr); -- return; -- } - pagefault_out_of_memory(); - return; - } else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE)) { - /* Kernel mode? Handle exceptions or die */ -- if (!user_mode(regs)) { -- no_context(regs, addr); -- return; -- } - do_trap(regs, SIGBUS, BUS_ADRERR, addr); - return; -+ } else if (fault & VM_FAULT_SIGSEGV) { -+ do_trap(regs, SIGSEGV, SEGV_MAPERR, addr); -+ return; - } -+ - BUG(); - } - -diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c -index 8adcb9419ad50..9b10e9655df8c 100644 ---- a/arch/riscv/mm/init.c -+++ b/arch/riscv/mm/init.c -@@ -217,8 +217,6 @@ static void __init setup_bootmem(void) - */ - memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); - -- phys_ram_end = memblock_end_of_DRAM(); -- - /* - * Make sure we align the start of the memory on a PMD boundary so that - * at worst, we map the linear mapping with PMD mappings. -@@ -233,6 +231,16 @@ static void __init setup_bootmem(void) - if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU)) - kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base; - -+ /* -+ * The size of the linear page mapping may restrict the amount of -+ * usable RAM. -+ */ -+ if (IS_ENABLED(CONFIG_64BIT)) { -+ max_mapped_addr = __pa(PAGE_OFFSET) + KERN_VIRT_SIZE; -+ memblock_cap_memory_range(phys_ram_base, -+ max_mapped_addr - phys_ram_base); -+ } -+ - /* - * Reserve physical address space that would be mapped to virtual - * addresses greater than (void *)(-PAGE_SIZE) because: -@@ -249,6 +257,7 @@ static void __init setup_bootmem(void) - memblock_reserve(max_mapped_addr, (phys_addr_t)-max_mapped_addr); - } - -+ phys_ram_end = memblock_end_of_DRAM(); - min_low_pfn = PFN_UP(phys_ram_base); - max_low_pfn = max_pfn = PFN_DOWN(phys_ram_end); - high_memory = (void *)(__va(PFN_PHYS(max_low_pfn))); -@@ -1269,8 +1278,6 @@ static void __init create_linear_mapping_page_table(void) - if (start <= __pa(PAGE_OFFSET) && - __pa(PAGE_OFFSET) < end) - start = __pa(PAGE_OFFSET); -- if (end >= __pa(PAGE_OFFSET) + memory_limit) -- end = __pa(PAGE_OFFSET) + memory_limit; - - create_linear_mapping_range(start, end, 0); - } -diff --git a/arch/x86/include/asm/posted_intr.h b/arch/x86/include/asm/posted_intr.h -new file mode 100644 -index 0000000000000..f0324c56f7af5 ---- /dev/null -+++ b/arch/x86/include/asm/posted_intr.h -@@ -0,0 +1,88 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef _X86_POSTED_INTR_H -+#define _X86_POSTED_INTR_H -+ -+#define POSTED_INTR_ON 0 -+#define POSTED_INTR_SN 1 -+ -+#define PID_TABLE_ENTRY_VALID 1 -+ -+/* Posted-Interrupt Descriptor */ -+struct pi_desc { -+ u32 pir[8]; /* Posted interrupt requested */ -+ union { -+ struct { -+ /* bit 256 - Outstanding Notification */ -+ u16 on : 1, -+ /* bit 257 - Suppress Notification */ -+ sn : 1, -+ /* bit 271:258 - Reserved */ -+ rsvd_1 : 14; -+ /* bit 279:272 - Notification Vector */ -+ u8 nv; -+ /* bit 287:280 - Reserved */ -+ u8 rsvd_2; -+ /* bit 319:288 - Notification Destination */ -+ u32 ndst; -+ }; -+ u64 control; -+ }; -+ u32 rsvd[6]; -+} __aligned(64); -+ -+static inline bool pi_test_and_set_on(struct pi_desc *pi_desc) -+{ -+ return test_and_set_bit(POSTED_INTR_ON, (unsigned long *)&pi_desc->control); -+} -+ -+static inline bool pi_test_and_clear_on(struct pi_desc *pi_desc) -+{ -+ return test_and_clear_bit(POSTED_INTR_ON, (unsigned long *)&pi_desc->control); -+} -+ -+static inline bool pi_test_and_clear_sn(struct pi_desc *pi_desc) -+{ -+ return test_and_clear_bit(POSTED_INTR_SN, (unsigned long *)&pi_desc->control); -+} -+ -+static inline bool pi_test_and_set_pir(int vector, struct pi_desc *pi_desc) -+{ -+ return test_and_set_bit(vector, (unsigned long *)pi_desc->pir); -+} -+ -+static inline bool pi_is_pir_empty(struct pi_desc *pi_desc) -+{ -+ return bitmap_empty((unsigned long *)pi_desc->pir, NR_VECTORS); -+} -+ -+static inline void pi_set_sn(struct pi_desc *pi_desc) -+{ -+ set_bit(POSTED_INTR_SN, (unsigned long *)&pi_desc->control); -+} -+ -+static inline void pi_set_on(struct pi_desc *pi_desc) -+{ -+ set_bit(POSTED_INTR_ON, (unsigned long *)&pi_desc->control); -+} -+ -+static inline void pi_clear_on(struct pi_desc *pi_desc) -+{ -+ clear_bit(POSTED_INTR_ON, (unsigned long *)&pi_desc->control); -+} -+ -+static inline void pi_clear_sn(struct pi_desc *pi_desc) -+{ -+ clear_bit(POSTED_INTR_SN, (unsigned long *)&pi_desc->control); -+} -+ -+static inline bool pi_test_on(struct pi_desc *pi_desc) -+{ -+ return test_bit(POSTED_INTR_ON, (unsigned long *)&pi_desc->control); -+} -+ -+static inline bool pi_test_sn(struct pi_desc *pi_desc) -+{ -+ return test_bit(POSTED_INTR_SN, (unsigned long *)&pi_desc->control); -+} -+ -+#endif /* _X86_POSTED_INTR_H */ -diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile -index 80e3fe184d17e..a99ffc3f3a3fd 100644 ---- a/arch/x86/kvm/Makefile -+++ b/arch/x86/kvm/Makefile -@@ -26,6 +26,10 @@ kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o \ - vmx/hyperv.o vmx/nested.o vmx/posted_intr.o - kvm-intel-$(CONFIG_X86_SGX_KVM) += vmx/sgx.o - -+ifdef CONFIG_HYPERV -+kvm-intel-y += vmx/vmx_onhyperv.o -+endif -+ - kvm-amd-y += svm/svm.o svm/vmenter.o svm/pmu.o svm/nested.o svm/avic.o \ - svm/sev.o svm/hyperv.o - -diff --git a/arch/x86/kvm/vmx/hyperv.c b/arch/x86/kvm/vmx/hyperv.c -index 313b8bb5b8a7c..de13dc14fe1d2 100644 ---- a/arch/x86/kvm/vmx/hyperv.c -+++ b/arch/x86/kvm/vmx/hyperv.c -@@ -13,111 +13,6 @@ - - #define CC KVM_NESTED_VMENTER_CONSISTENCY_CHECK - --/* -- * Enlightened VMCSv1 doesn't support these: -- * -- * POSTED_INTR_NV = 0x00000002, -- * GUEST_INTR_STATUS = 0x00000810, -- * APIC_ACCESS_ADDR = 0x00002014, -- * POSTED_INTR_DESC_ADDR = 0x00002016, -- * EOI_EXIT_BITMAP0 = 0x0000201c, -- * EOI_EXIT_BITMAP1 = 0x0000201e, -- * EOI_EXIT_BITMAP2 = 0x00002020, -- * EOI_EXIT_BITMAP3 = 0x00002022, -- * GUEST_PML_INDEX = 0x00000812, -- * PML_ADDRESS = 0x0000200e, -- * VM_FUNCTION_CONTROL = 0x00002018, -- * EPTP_LIST_ADDRESS = 0x00002024, -- * VMREAD_BITMAP = 0x00002026, -- * VMWRITE_BITMAP = 0x00002028, -- * -- * TSC_MULTIPLIER = 0x00002032, -- * PLE_GAP = 0x00004020, -- * PLE_WINDOW = 0x00004022, -- * VMX_PREEMPTION_TIMER_VALUE = 0x0000482E, -- * -- * Currently unsupported in KVM: -- * GUEST_IA32_RTIT_CTL = 0x00002814, -- */ --#define EVMCS1_SUPPORTED_PINCTRL \ -- (PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR | \ -- PIN_BASED_EXT_INTR_MASK | \ -- PIN_BASED_NMI_EXITING | \ -- PIN_BASED_VIRTUAL_NMIS) -- --#define EVMCS1_SUPPORTED_EXEC_CTRL \ -- (CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR | \ -- CPU_BASED_HLT_EXITING | \ -- CPU_BASED_CR3_LOAD_EXITING | \ -- CPU_BASED_CR3_STORE_EXITING | \ -- CPU_BASED_UNCOND_IO_EXITING | \ -- CPU_BASED_MOV_DR_EXITING | \ -- CPU_BASED_USE_TSC_OFFSETTING | \ -- CPU_BASED_MWAIT_EXITING | \ -- CPU_BASED_MONITOR_EXITING | \ -- CPU_BASED_INVLPG_EXITING | \ -- CPU_BASED_RDPMC_EXITING | \ -- CPU_BASED_INTR_WINDOW_EXITING | \ -- CPU_BASED_CR8_LOAD_EXITING | \ -- CPU_BASED_CR8_STORE_EXITING | \ -- CPU_BASED_RDTSC_EXITING | \ -- CPU_BASED_TPR_SHADOW | \ -- CPU_BASED_USE_IO_BITMAPS | \ -- CPU_BASED_MONITOR_TRAP_FLAG | \ -- CPU_BASED_USE_MSR_BITMAPS | \ -- CPU_BASED_NMI_WINDOW_EXITING | \ -- CPU_BASED_PAUSE_EXITING | \ -- CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) -- --#define EVMCS1_SUPPORTED_2NDEXEC \ -- (SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | \ -- SECONDARY_EXEC_WBINVD_EXITING | \ -- SECONDARY_EXEC_ENABLE_VPID | \ -- SECONDARY_EXEC_ENABLE_EPT | \ -- SECONDARY_EXEC_UNRESTRICTED_GUEST | \ -- SECONDARY_EXEC_DESC | \ -- SECONDARY_EXEC_ENABLE_RDTSCP | \ -- SECONDARY_EXEC_ENABLE_INVPCID | \ -- SECONDARY_EXEC_ENABLE_XSAVES | \ -- SECONDARY_EXEC_RDSEED_EXITING | \ -- SECONDARY_EXEC_RDRAND_EXITING | \ -- SECONDARY_EXEC_TSC_SCALING | \ -- SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | \ -- SECONDARY_EXEC_PT_USE_GPA | \ -- SECONDARY_EXEC_PT_CONCEAL_VMX | \ -- SECONDARY_EXEC_BUS_LOCK_DETECTION | \ -- SECONDARY_EXEC_NOTIFY_VM_EXITING | \ -- SECONDARY_EXEC_ENCLS_EXITING) -- --#define EVMCS1_SUPPORTED_3RDEXEC (0ULL) -- --#define EVMCS1_SUPPORTED_VMEXIT_CTRL \ -- (VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | \ -- VM_EXIT_SAVE_DEBUG_CONTROLS | \ -- VM_EXIT_ACK_INTR_ON_EXIT | \ -- VM_EXIT_HOST_ADDR_SPACE_SIZE | \ -- VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | \ -- VM_EXIT_SAVE_IA32_PAT | \ -- VM_EXIT_LOAD_IA32_PAT | \ -- VM_EXIT_SAVE_IA32_EFER | \ -- VM_EXIT_LOAD_IA32_EFER | \ -- VM_EXIT_CLEAR_BNDCFGS | \ -- VM_EXIT_PT_CONCEAL_PIP | \ -- VM_EXIT_CLEAR_IA32_RTIT_CTL) -- --#define EVMCS1_SUPPORTED_VMENTRY_CTRL \ -- (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | \ -- VM_ENTRY_LOAD_DEBUG_CONTROLS | \ -- VM_ENTRY_IA32E_MODE | \ -- VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | \ -- VM_ENTRY_LOAD_IA32_PAT | \ -- VM_ENTRY_LOAD_IA32_EFER | \ -- VM_ENTRY_LOAD_BNDCFGS | \ -- VM_ENTRY_PT_CONCEAL_PIP | \ -- VM_ENTRY_LOAD_IA32_RTIT_CTL) -- --#define EVMCS1_SUPPORTED_VMFUNC (0) -- - #define EVMCS1_OFFSET(x) offsetof(struct hv_enlightened_vmcs, x) - #define EVMCS1_FIELD(number, name, clean_field)[ROL16(number, 6)] = \ - {EVMCS1_OFFSET(name), clean_field} -@@ -608,40 +503,6 @@ int nested_evmcs_check_controls(struct vmcs12 *vmcs12) - return 0; - } - --#if IS_ENABLED(CONFIG_HYPERV) --DEFINE_STATIC_KEY_FALSE(__kvm_is_using_evmcs); -- --/* -- * KVM on Hyper-V always uses the latest known eVMCSv1 revision, the assumption -- * is: in case a feature has corresponding fields in eVMCS described and it was -- * exposed in VMX feature MSRs, KVM is free to use it. Warn if KVM meets a -- * feature which has no corresponding eVMCS field, this likely means that KVM -- * needs to be updated. -- */ --#define evmcs_check_vmcs_conf(field, ctrl) \ -- do { \ -- typeof(vmcs_conf->field) unsupported; \ -- \ -- unsupported = vmcs_conf->field & ~EVMCS1_SUPPORTED_ ## ctrl; \ -- if (unsupported) { \ -- pr_warn_once(#field " unsupported with eVMCS: 0x%llx\n",\ -- (u64)unsupported); \ -- vmcs_conf->field &= EVMCS1_SUPPORTED_ ## ctrl; \ -- } \ -- } \ -- while (0) -- --void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf) --{ -- evmcs_check_vmcs_conf(cpu_based_exec_ctrl, EXEC_CTRL); -- evmcs_check_vmcs_conf(pin_based_exec_ctrl, PINCTRL); -- evmcs_check_vmcs_conf(cpu_based_2nd_exec_ctrl, 2NDEXEC); -- evmcs_check_vmcs_conf(cpu_based_3rd_exec_ctrl, 3RDEXEC); -- evmcs_check_vmcs_conf(vmentry_ctrl, VMENTRY_CTRL); -- evmcs_check_vmcs_conf(vmexit_ctrl, VMEXIT_CTRL); --} --#endif -- - int nested_enable_evmcs(struct kvm_vcpu *vcpu, - uint16_t *vmcs_version) - { -diff --git a/arch/x86/kvm/vmx/hyperv.h b/arch/x86/kvm/vmx/hyperv.h -index 9623fe1651c48..9401dbfaea7ce 100644 ---- a/arch/x86/kvm/vmx/hyperv.h -+++ b/arch/x86/kvm/vmx/hyperv.h -@@ -14,12 +14,113 @@ - #include "vmcs.h" - #include "vmcs12.h" - --struct vmcs_config; -- --#define current_evmcs ((struct hv_enlightened_vmcs *)this_cpu_read(current_vmcs)) -- - #define KVM_EVMCS_VERSION 1 - -+/* -+ * Enlightened VMCSv1 doesn't support these: -+ * -+ * POSTED_INTR_NV = 0x00000002, -+ * GUEST_INTR_STATUS = 0x00000810, -+ * APIC_ACCESS_ADDR = 0x00002014, -+ * POSTED_INTR_DESC_ADDR = 0x00002016, -+ * EOI_EXIT_BITMAP0 = 0x0000201c, -+ * EOI_EXIT_BITMAP1 = 0x0000201e, -+ * EOI_EXIT_BITMAP2 = 0x00002020, -+ * EOI_EXIT_BITMAP3 = 0x00002022, -+ * GUEST_PML_INDEX = 0x00000812, -+ * PML_ADDRESS = 0x0000200e, -+ * VM_FUNCTION_CONTROL = 0x00002018, -+ * EPTP_LIST_ADDRESS = 0x00002024, -+ * VMREAD_BITMAP = 0x00002026, -+ * VMWRITE_BITMAP = 0x00002028, -+ * -+ * TSC_MULTIPLIER = 0x00002032, -+ * PLE_GAP = 0x00004020, -+ * PLE_WINDOW = 0x00004022, -+ * VMX_PREEMPTION_TIMER_VALUE = 0x0000482E, -+ * -+ * Currently unsupported in KVM: -+ * GUEST_IA32_RTIT_CTL = 0x00002814, -+ */ -+#define EVMCS1_SUPPORTED_PINCTRL \ -+ (PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR | \ -+ PIN_BASED_EXT_INTR_MASK | \ -+ PIN_BASED_NMI_EXITING | \ -+ PIN_BASED_VIRTUAL_NMIS) -+ -+#define EVMCS1_SUPPORTED_EXEC_CTRL \ -+ (CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR | \ -+ CPU_BASED_HLT_EXITING | \ -+ CPU_BASED_CR3_LOAD_EXITING | \ -+ CPU_BASED_CR3_STORE_EXITING | \ -+ CPU_BASED_UNCOND_IO_EXITING | \ -+ CPU_BASED_MOV_DR_EXITING | \ -+ CPU_BASED_USE_TSC_OFFSETTING | \ -+ CPU_BASED_MWAIT_EXITING | \ -+ CPU_BASED_MONITOR_EXITING | \ -+ CPU_BASED_INVLPG_EXITING | \ -+ CPU_BASED_RDPMC_EXITING | \ -+ CPU_BASED_INTR_WINDOW_EXITING | \ -+ CPU_BASED_CR8_LOAD_EXITING | \ -+ CPU_BASED_CR8_STORE_EXITING | \ -+ CPU_BASED_RDTSC_EXITING | \ -+ CPU_BASED_TPR_SHADOW | \ -+ CPU_BASED_USE_IO_BITMAPS | \ -+ CPU_BASED_MONITOR_TRAP_FLAG | \ -+ CPU_BASED_USE_MSR_BITMAPS | \ -+ CPU_BASED_NMI_WINDOW_EXITING | \ -+ CPU_BASED_PAUSE_EXITING | \ -+ CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) -+ -+#define EVMCS1_SUPPORTED_2NDEXEC \ -+ (SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | \ -+ SECONDARY_EXEC_WBINVD_EXITING | \ -+ SECONDARY_EXEC_ENABLE_VPID | \ -+ SECONDARY_EXEC_ENABLE_EPT | \ -+ SECONDARY_EXEC_UNRESTRICTED_GUEST | \ -+ SECONDARY_EXEC_DESC | \ -+ SECONDARY_EXEC_ENABLE_RDTSCP | \ -+ SECONDARY_EXEC_ENABLE_INVPCID | \ -+ SECONDARY_EXEC_ENABLE_XSAVES | \ -+ SECONDARY_EXEC_RDSEED_EXITING | \ -+ SECONDARY_EXEC_RDRAND_EXITING | \ -+ SECONDARY_EXEC_TSC_SCALING | \ -+ SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | \ -+ SECONDARY_EXEC_PT_USE_GPA | \ -+ SECONDARY_EXEC_PT_CONCEAL_VMX | \ -+ SECONDARY_EXEC_BUS_LOCK_DETECTION | \ -+ SECONDARY_EXEC_NOTIFY_VM_EXITING | \ -+ SECONDARY_EXEC_ENCLS_EXITING) -+ -+#define EVMCS1_SUPPORTED_3RDEXEC (0ULL) -+ -+#define EVMCS1_SUPPORTED_VMEXIT_CTRL \ -+ (VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | \ -+ VM_EXIT_SAVE_DEBUG_CONTROLS | \ -+ VM_EXIT_ACK_INTR_ON_EXIT | \ -+ VM_EXIT_HOST_ADDR_SPACE_SIZE | \ -+ VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | \ -+ VM_EXIT_SAVE_IA32_PAT | \ -+ VM_EXIT_LOAD_IA32_PAT | \ -+ VM_EXIT_SAVE_IA32_EFER | \ -+ VM_EXIT_LOAD_IA32_EFER | \ -+ VM_EXIT_CLEAR_BNDCFGS | \ -+ VM_EXIT_PT_CONCEAL_PIP | \ -+ VM_EXIT_CLEAR_IA32_RTIT_CTL) -+ -+#define EVMCS1_SUPPORTED_VMENTRY_CTRL \ -+ (VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR | \ -+ VM_ENTRY_LOAD_DEBUG_CONTROLS | \ -+ VM_ENTRY_IA32E_MODE | \ -+ VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | \ -+ VM_ENTRY_LOAD_IA32_PAT | \ -+ VM_ENTRY_LOAD_IA32_EFER | \ -+ VM_ENTRY_LOAD_BNDCFGS | \ -+ VM_ENTRY_PT_CONCEAL_PIP | \ -+ VM_ENTRY_LOAD_IA32_RTIT_CTL) -+ -+#define EVMCS1_SUPPORTED_VMFUNC (0) -+ - struct evmcs_field { - u16 offset; - u16 clean_field; -@@ -65,114 +166,6 @@ static inline u64 evmcs_read_any(struct hv_enlightened_vmcs *evmcs, - return vmcs12_read_any((void *)evmcs, field, offset); - } - --#if IS_ENABLED(CONFIG_HYPERV) -- --DECLARE_STATIC_KEY_FALSE(__kvm_is_using_evmcs); -- --static __always_inline bool kvm_is_using_evmcs(void) --{ -- return static_branch_unlikely(&__kvm_is_using_evmcs); --} -- --static __always_inline int get_evmcs_offset(unsigned long field, -- u16 *clean_field) --{ -- int offset = evmcs_field_offset(field, clean_field); -- -- WARN_ONCE(offset < 0, "accessing unsupported EVMCS field %lx\n", field); -- return offset; --} -- --static __always_inline void evmcs_write64(unsigned long field, u64 value) --{ -- u16 clean_field; -- int offset = get_evmcs_offset(field, &clean_field); -- -- if (offset < 0) -- return; -- -- *(u64 *)((char *)current_evmcs + offset) = value; -- -- current_evmcs->hv_clean_fields &= ~clean_field; --} -- --static __always_inline void evmcs_write32(unsigned long field, u32 value) --{ -- u16 clean_field; -- int offset = get_evmcs_offset(field, &clean_field); -- -- if (offset < 0) -- return; -- -- *(u32 *)((char *)current_evmcs + offset) = value; -- current_evmcs->hv_clean_fields &= ~clean_field; --} -- --static __always_inline void evmcs_write16(unsigned long field, u16 value) --{ -- u16 clean_field; -- int offset = get_evmcs_offset(field, &clean_field); -- -- if (offset < 0) -- return; -- -- *(u16 *)((char *)current_evmcs + offset) = value; -- current_evmcs->hv_clean_fields &= ~clean_field; --} -- --static __always_inline u64 evmcs_read64(unsigned long field) --{ -- int offset = get_evmcs_offset(field, NULL); -- -- if (offset < 0) -- return 0; -- -- return *(u64 *)((char *)current_evmcs + offset); --} -- --static __always_inline u32 evmcs_read32(unsigned long field) --{ -- int offset = get_evmcs_offset(field, NULL); -- -- if (offset < 0) -- return 0; -- -- return *(u32 *)((char *)current_evmcs + offset); --} -- --static __always_inline u16 evmcs_read16(unsigned long field) --{ -- int offset = get_evmcs_offset(field, NULL); -- -- if (offset < 0) -- return 0; -- -- return *(u16 *)((char *)current_evmcs + offset); --} -- --static inline void evmcs_load(u64 phys_addr) --{ -- struct hv_vp_assist_page *vp_ap = -- hv_get_vp_assist_page(smp_processor_id()); -- -- if (current_evmcs->hv_enlightenments_control.nested_flush_hypercall) -- vp_ap->nested_control.features.directhypercall = 1; -- vp_ap->current_nested_vmcs = phys_addr; -- vp_ap->enlighten_vmentry = 1; --} -- --void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf); --#else /* !IS_ENABLED(CONFIG_HYPERV) */ --static __always_inline bool kvm_is_using_evmcs(void) { return false; } --static __always_inline void evmcs_write64(unsigned long field, u64 value) {} --static __always_inline void evmcs_write32(unsigned long field, u32 value) {} --static __always_inline void evmcs_write16(unsigned long field, u16 value) {} --static __always_inline u64 evmcs_read64(unsigned long field) { return 0; } --static __always_inline u32 evmcs_read32(unsigned long field) { return 0; } --static __always_inline u16 evmcs_read16(unsigned long field) { return 0; } --static inline void evmcs_load(u64 phys_addr) {} --#endif /* IS_ENABLED(CONFIG_HYPERV) */ -- - #define EVMPTR_INVALID (-1ULL) - #define EVMPTR_MAP_PENDING (-2ULL) - -diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c -index d1b4a85def0a6..0ad66b9207e85 100644 ---- a/arch/x86/kvm/vmx/nested.c -+++ b/arch/x86/kvm/vmx/nested.c -@@ -12,6 +12,7 @@ - #include "mmu.h" - #include "nested.h" - #include "pmu.h" -+#include "posted_intr.h" - #include "sgx.h" - #include "trace.h" - #include "vmx.h" -@@ -3830,8 +3831,8 @@ static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) - if (!pi_test_and_clear_on(vmx->nested.pi_desc)) - return 0; - -- max_irr = find_last_bit((unsigned long *)vmx->nested.pi_desc->pir, 256); -- if (max_irr != 256) { -+ max_irr = pi_find_highest_vector(vmx->nested.pi_desc); -+ if (max_irr > 0) { - vapic_page = vmx->nested.virtual_apic_map.hva; - if (!vapic_page) - goto mmio_needed; -@@ -3964,8 +3965,40 @@ static bool nested_vmx_preemption_timer_pending(struct kvm_vcpu *vcpu) - - static bool vmx_has_nested_events(struct kvm_vcpu *vcpu, bool for_injection) - { -- return nested_vmx_preemption_timer_pending(vcpu) || -- to_vmx(vcpu)->nested.mtf_pending; -+ struct vcpu_vmx *vmx = to_vmx(vcpu); -+ void *vapic = vmx->nested.virtual_apic_map.hva; -+ int max_irr, vppr; -+ -+ if (nested_vmx_preemption_timer_pending(vcpu) || -+ vmx->nested.mtf_pending) -+ return true; -+ -+ /* -+ * Virtual Interrupt Delivery doesn't require manual injection. Either -+ * the interrupt is already in GUEST_RVI and will be recognized by CPU -+ * at VM-Entry, or there is a KVM_REQ_EVENT pending and KVM will move -+ * the interrupt from the PIR to RVI prior to entering the guest. -+ */ -+ if (for_injection) -+ return false; -+ -+ if (!nested_cpu_has_vid(get_vmcs12(vcpu)) || -+ __vmx_interrupt_blocked(vcpu)) -+ return false; -+ -+ if (!vapic) -+ return false; -+ -+ vppr = *((u32 *)(vapic + APIC_PROCPRI)); -+ -+ if (vmx->nested.pi_pending && vmx->nested.pi_desc && -+ pi_test_on(vmx->nested.pi_desc)) { -+ max_irr = pi_find_highest_vector(vmx->nested.pi_desc); -+ if (max_irr > 0 && (max_irr & 0xf0) > (vppr & 0xf0)) -+ return true; -+ } -+ -+ return false; - } - - /* -diff --git a/arch/x86/kvm/vmx/posted_intr.h b/arch/x86/kvm/vmx/posted_intr.h -index 26992076552ef..1715d2ab07be5 100644 ---- a/arch/x86/kvm/vmx/posted_intr.h -+++ b/arch/x86/kvm/vmx/posted_intr.h -@@ -2,97 +2,8 @@ - #ifndef __KVM_X86_VMX_POSTED_INTR_H - #define __KVM_X86_VMX_POSTED_INTR_H - --#define POSTED_INTR_ON 0 --#define POSTED_INTR_SN 1 -- --#define PID_TABLE_ENTRY_VALID 1 -- --/* Posted-Interrupt Descriptor */ --struct pi_desc { -- u32 pir[8]; /* Posted interrupt requested */ -- union { -- struct { -- /* bit 256 - Outstanding Notification */ -- u16 on : 1, -- /* bit 257 - Suppress Notification */ -- sn : 1, -- /* bit 271:258 - Reserved */ -- rsvd_1 : 14; -- /* bit 279:272 - Notification Vector */ -- u8 nv; -- /* bit 287:280 - Reserved */ -- u8 rsvd_2; -- /* bit 319:288 - Notification Destination */ -- u32 ndst; -- }; -- u64 control; -- }; -- u32 rsvd[6]; --} __aligned(64); -- --static inline bool pi_test_and_set_on(struct pi_desc *pi_desc) --{ -- return test_and_set_bit(POSTED_INTR_ON, -- (unsigned long *)&pi_desc->control); --} -- --static inline bool pi_test_and_clear_on(struct pi_desc *pi_desc) --{ -- return test_and_clear_bit(POSTED_INTR_ON, -- (unsigned long *)&pi_desc->control); --} -- --static inline bool pi_test_and_clear_sn(struct pi_desc *pi_desc) --{ -- return test_and_clear_bit(POSTED_INTR_SN, -- (unsigned long *)&pi_desc->control); --} -- --static inline bool pi_test_and_set_pir(int vector, struct pi_desc *pi_desc) --{ -- return test_and_set_bit(vector, (unsigned long *)pi_desc->pir); --} -- --static inline bool pi_is_pir_empty(struct pi_desc *pi_desc) --{ -- return bitmap_empty((unsigned long *)pi_desc->pir, NR_VECTORS); --} -- --static inline void pi_set_sn(struct pi_desc *pi_desc) --{ -- set_bit(POSTED_INTR_SN, -- (unsigned long *)&pi_desc->control); --} -- --static inline void pi_set_on(struct pi_desc *pi_desc) --{ -- set_bit(POSTED_INTR_ON, -- (unsigned long *)&pi_desc->control); --} -- --static inline void pi_clear_on(struct pi_desc *pi_desc) --{ -- clear_bit(POSTED_INTR_ON, -- (unsigned long *)&pi_desc->control); --} -- --static inline void pi_clear_sn(struct pi_desc *pi_desc) --{ -- clear_bit(POSTED_INTR_SN, -- (unsigned long *)&pi_desc->control); --} -- --static inline bool pi_test_on(struct pi_desc *pi_desc) --{ -- return test_bit(POSTED_INTR_ON, -- (unsigned long *)&pi_desc->control); --} -- --static inline bool pi_test_sn(struct pi_desc *pi_desc) --{ -- return test_bit(POSTED_INTR_SN, -- (unsigned long *)&pi_desc->control); --} -+#include -+#include - - void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu); - void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu); -@@ -103,4 +14,12 @@ int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq, - uint32_t guest_irq, bool set); - void vmx_pi_start_assignment(struct kvm *kvm); - -+static inline int pi_find_highest_vector(struct pi_desc *pi_desc) -+{ -+ int vec; -+ -+ vec = find_last_bit((unsigned long *)pi_desc->pir, 256); -+ return vec < 256 ? vec : -1; -+} -+ - #endif /* __KVM_X86_VMX_POSTED_INTR_H */ -diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c -index f5f652a546bf2..2e0106d9d371c 100644 ---- a/arch/x86/kvm/vmx/vmx.c -+++ b/arch/x86/kvm/vmx/vmx.c -@@ -66,6 +66,8 @@ - #include "vmx.h" - #include "x86.h" - #include "smm.h" -+#include "vmx_onhyperv.h" -+#include "posted_intr.h" - - MODULE_AUTHOR("Qumranet"); - MODULE_LICENSE("GPL"); -diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h -index 912b0c4697429..6be1627d888e5 100644 ---- a/arch/x86/kvm/vmx/vmx.h -+++ b/arch/x86/kvm/vmx/vmx.h -@@ -7,10 +7,10 @@ - #include - #include - #include -+#include - - #include "capabilities.h" - #include "../kvm_cache_regs.h" --#include "posted_intr.h" - #include "vmcs.h" - #include "vmx_ops.h" - #include "../cpuid.h" -diff --git a/arch/x86/kvm/vmx/vmx_onhyperv.c b/arch/x86/kvm/vmx/vmx_onhyperv.c -new file mode 100644 -index 0000000000000..b9a8b91166d02 ---- /dev/null -+++ b/arch/x86/kvm/vmx/vmx_onhyperv.c -@@ -0,0 +1,36 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+ -+#include "capabilities.h" -+#include "vmx_onhyperv.h" -+ -+DEFINE_STATIC_KEY_FALSE(__kvm_is_using_evmcs); -+ -+/* -+ * KVM on Hyper-V always uses the latest known eVMCSv1 revision, the assumption -+ * is: in case a feature has corresponding fields in eVMCS described and it was -+ * exposed in VMX feature MSRs, KVM is free to use it. Warn if KVM meets a -+ * feature which has no corresponding eVMCS field, this likely means that KVM -+ * needs to be updated. -+ */ -+#define evmcs_check_vmcs_conf(field, ctrl) \ -+ do { \ -+ typeof(vmcs_conf->field) unsupported; \ -+ \ -+ unsupported = vmcs_conf->field & ~EVMCS1_SUPPORTED_ ## ctrl; \ -+ if (unsupported) { \ -+ pr_warn_once(#field " unsupported with eVMCS: 0x%llx\n",\ -+ (u64)unsupported); \ -+ vmcs_conf->field &= EVMCS1_SUPPORTED_ ## ctrl; \ -+ } \ -+ } \ -+ while (0) -+ -+void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf) -+{ -+ evmcs_check_vmcs_conf(cpu_based_exec_ctrl, EXEC_CTRL); -+ evmcs_check_vmcs_conf(pin_based_exec_ctrl, PINCTRL); -+ evmcs_check_vmcs_conf(cpu_based_2nd_exec_ctrl, 2NDEXEC); -+ evmcs_check_vmcs_conf(cpu_based_3rd_exec_ctrl, 3RDEXEC); -+ evmcs_check_vmcs_conf(vmentry_ctrl, VMENTRY_CTRL); -+ evmcs_check_vmcs_conf(vmexit_ctrl, VMEXIT_CTRL); -+} -diff --git a/arch/x86/kvm/vmx/vmx_onhyperv.h b/arch/x86/kvm/vmx/vmx_onhyperv.h -new file mode 100644 -index 0000000000000..11541d272dbd8 ---- /dev/null -+++ b/arch/x86/kvm/vmx/vmx_onhyperv.h -@@ -0,0 +1,124 @@ -+/* SPDX-License-Identifier: GPL-2.0-only */ -+ -+#ifndef __ARCH_X86_KVM_VMX_ONHYPERV_H__ -+#define __ARCH_X86_KVM_VMX_ONHYPERV_H__ -+ -+#include -+ -+#include -+ -+#include "capabilities.h" -+#include "hyperv.h" -+#include "vmcs12.h" -+ -+#define current_evmcs ((struct hv_enlightened_vmcs *)this_cpu_read(current_vmcs)) -+ -+#if IS_ENABLED(CONFIG_HYPERV) -+ -+DECLARE_STATIC_KEY_FALSE(__kvm_is_using_evmcs); -+ -+static __always_inline bool kvm_is_using_evmcs(void) -+{ -+ return static_branch_unlikely(&__kvm_is_using_evmcs); -+} -+ -+static __always_inline int get_evmcs_offset(unsigned long field, -+ u16 *clean_field) -+{ -+ int offset = evmcs_field_offset(field, clean_field); -+ -+ WARN_ONCE(offset < 0, "accessing unsupported EVMCS field %lx\n", field); -+ return offset; -+} -+ -+static __always_inline void evmcs_write64(unsigned long field, u64 value) -+{ -+ u16 clean_field; -+ int offset = get_evmcs_offset(field, &clean_field); -+ -+ if (offset < 0) -+ return; -+ -+ *(u64 *)((char *)current_evmcs + offset) = value; -+ -+ current_evmcs->hv_clean_fields &= ~clean_field; -+} -+ -+static __always_inline void evmcs_write32(unsigned long field, u32 value) -+{ -+ u16 clean_field; -+ int offset = get_evmcs_offset(field, &clean_field); -+ -+ if (offset < 0) -+ return; -+ -+ *(u32 *)((char *)current_evmcs + offset) = value; -+ current_evmcs->hv_clean_fields &= ~clean_field; -+} -+ -+static __always_inline void evmcs_write16(unsigned long field, u16 value) -+{ -+ u16 clean_field; -+ int offset = get_evmcs_offset(field, &clean_field); -+ -+ if (offset < 0) -+ return; -+ -+ *(u16 *)((char *)current_evmcs + offset) = value; -+ current_evmcs->hv_clean_fields &= ~clean_field; -+} -+ -+static __always_inline u64 evmcs_read64(unsigned long field) -+{ -+ int offset = get_evmcs_offset(field, NULL); -+ -+ if (offset < 0) -+ return 0; -+ -+ return *(u64 *)((char *)current_evmcs + offset); -+} -+ -+static __always_inline u32 evmcs_read32(unsigned long field) -+{ -+ int offset = get_evmcs_offset(field, NULL); -+ -+ if (offset < 0) -+ return 0; -+ -+ return *(u32 *)((char *)current_evmcs + offset); -+} -+ -+static __always_inline u16 evmcs_read16(unsigned long field) -+{ -+ int offset = get_evmcs_offset(field, NULL); -+ -+ if (offset < 0) -+ return 0; -+ -+ return *(u16 *)((char *)current_evmcs + offset); -+} -+ -+static inline void evmcs_load(u64 phys_addr) -+{ -+ struct hv_vp_assist_page *vp_ap = -+ hv_get_vp_assist_page(smp_processor_id()); -+ -+ if (current_evmcs->hv_enlightenments_control.nested_flush_hypercall) -+ vp_ap->nested_control.features.directhypercall = 1; -+ vp_ap->current_nested_vmcs = phys_addr; -+ vp_ap->enlighten_vmentry = 1; -+} -+ -+void evmcs_sanitize_exec_ctrls(struct vmcs_config *vmcs_conf); -+#else /* !IS_ENABLED(CONFIG_HYPERV) */ -+static __always_inline bool kvm_is_using_evmcs(void) { return false; } -+static __always_inline void evmcs_write64(unsigned long field, u64 value) {} -+static __always_inline void evmcs_write32(unsigned long field, u32 value) {} -+static __always_inline void evmcs_write16(unsigned long field, u16 value) {} -+static __always_inline u64 evmcs_read64(unsigned long field) { return 0; } -+static __always_inline u32 evmcs_read32(unsigned long field) { return 0; } -+static __always_inline u16 evmcs_read16(unsigned long field) { return 0; } -+static inline void evmcs_load(u64 phys_addr) {} -+#endif /* IS_ENABLED(CONFIG_HYPERV) */ -+ -+#endif /* __ARCH_X86_KVM_VMX_ONHYPERV_H__ */ -diff --git a/arch/x86/kvm/vmx/vmx_ops.h b/arch/x86/kvm/vmx/vmx_ops.h -index 6a0c6e81f7f3e..8060e5fc6dbd8 100644 ---- a/arch/x86/kvm/vmx/vmx_ops.h -+++ b/arch/x86/kvm/vmx/vmx_ops.h -@@ -6,7 +6,7 @@ - - #include - --#include "hyperv.h" -+#include "vmx_onhyperv.h" - #include "vmcs.h" - #include "../x86.h" - -diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c -index 3da3c266a66f3..a936219aebb81 100644 ---- a/drivers/bluetooth/btintel.c -+++ b/drivers/bluetooth/btintel.c -@@ -2845,6 +2845,9 @@ static int btintel_setup_combined(struct hci_dev *hdev) - btintel_set_dsm_reset_method(hdev, &ver_tlv); - - err = btintel_bootloader_setup_tlv(hdev, &ver_tlv); -+ if (err) -+ goto exit_error; -+ - btintel_register_devcoredump_support(hdev); - break; - default: -diff --git a/drivers/cpufreq/qcom-cpufreq-nvmem.c b/drivers/cpufreq/qcom-cpufreq-nvmem.c -index 84d7033e5efe8..ef51dfb39baa9 100644 ---- a/drivers/cpufreq/qcom-cpufreq-nvmem.c -+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c -@@ -40,10 +40,14 @@ struct qcom_cpufreq_match_data { - const char **genpd_names; - }; - -+struct qcom_cpufreq_drv_cpu { -+ int opp_token; -+}; -+ - struct qcom_cpufreq_drv { -- int *opp_tokens; - u32 versions; - const struct qcom_cpufreq_match_data *data; -+ struct qcom_cpufreq_drv_cpu cpus[]; - }; - - static struct platform_device *cpufreq_dt_pdev, *cpufreq_pdev; -@@ -243,42 +247,39 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) - return -ENOENT; - } - -- drv = kzalloc(sizeof(*drv), GFP_KERNEL); -- if (!drv) -+ drv = devm_kzalloc(&pdev->dev, struct_size(drv, cpus, num_possible_cpus()), -+ GFP_KERNEL); -+ if (!drv) { -+ of_node_put(np); - return -ENOMEM; -+ } - - match = pdev->dev.platform_data; - drv->data = match->data; - if (!drv->data) { -- ret = -ENODEV; -- goto free_drv; -+ of_node_put(np); -+ return -ENODEV; - } - - if (drv->data->get_version) { - speedbin_nvmem = of_nvmem_cell_get(np, NULL); - if (IS_ERR(speedbin_nvmem)) { -- ret = dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem), -- "Could not get nvmem cell\n"); -- goto free_drv; -+ of_node_put(np); -+ return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem), -+ "Could not get nvmem cell\n"); - } - - ret = drv->data->get_version(cpu_dev, - speedbin_nvmem, &pvs_name, drv); - if (ret) { -+ of_node_put(np); - nvmem_cell_put(speedbin_nvmem); -- goto free_drv; -+ return ret; - } - nvmem_cell_put(speedbin_nvmem); - } - of_node_put(np); - -- drv->opp_tokens = kcalloc(num_possible_cpus(), sizeof(*drv->opp_tokens), -- GFP_KERNEL); -- if (!drv->opp_tokens) { -- ret = -ENOMEM; -- goto free_drv; -- } -- - for_each_possible_cpu(cpu) { - struct dev_pm_opp_config config = { - .supported_hw = NULL, -@@ -304,9 +305,9 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) - } - - if (config.supported_hw || config.genpd_names) { -- drv->opp_tokens[cpu] = dev_pm_opp_set_config(cpu_dev, &config); -- if (drv->opp_tokens[cpu] < 0) { -- ret = drv->opp_tokens[cpu]; -+ drv->cpus[cpu].opp_token = dev_pm_opp_set_config(cpu_dev, &config); -+ if (drv->cpus[cpu].opp_token < 0) { -+ ret = drv->cpus[cpu].opp_token; - dev_err(cpu_dev, "Failed to set OPP config\n"); - goto free_opp; - } -@@ -325,11 +326,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) - - free_opp: - for_each_possible_cpu(cpu) -- dev_pm_opp_clear_config(drv->opp_tokens[cpu]); -- kfree(drv->opp_tokens); --free_drv: -- kfree(drv); -- -+ dev_pm_opp_clear_config(drv->cpus[cpu].opp_token); - return ret; - } - -@@ -341,10 +338,7 @@ static void qcom_cpufreq_remove(struct platform_device *pdev) - platform_device_unregister(cpufreq_dt_pdev); - - for_each_possible_cpu(cpu) -- dev_pm_opp_clear_config(drv->opp_tokens[cpu]); -- -- kfree(drv->opp_tokens); -- kfree(drv); -+ dev_pm_opp_clear_config(drv->cpus[cpu].opp_token); - } - - static struct platform_driver qcom_cpufreq_driver = { -diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c -index 793f1a7ad5e34..53fdfd32a7e77 100644 ---- a/drivers/dma/fsl-edma-common.c -+++ b/drivers/dma/fsl-edma-common.c -@@ -3,6 +3,7 @@ - // Copyright (c) 2013-2014 Freescale Semiconductor, Inc - // Copyright (c) 2017 Sysam, Angelo Dureghello - -+#include - #include - #include - #include -@@ -74,18 +75,10 @@ static void fsl_edma3_enable_request(struct fsl_edma_chan *fsl_chan) - - flags = fsl_edma_drvflags(fsl_chan); - val = edma_readl_chreg(fsl_chan, ch_sbr); -- /* Remote/local swapped wrongly on iMX8 QM Audio edma */ -- if (flags & FSL_EDMA_DRV_QUIRK_SWAPPED) { -- if (!fsl_chan->is_rxchan) -- val |= EDMA_V3_CH_SBR_RD; -- else -- val |= EDMA_V3_CH_SBR_WR; -- } else { -- if (fsl_chan->is_rxchan) -- val |= EDMA_V3_CH_SBR_RD; -- else -- val |= EDMA_V3_CH_SBR_WR; -- } -+ if (fsl_chan->is_rxchan) -+ val |= EDMA_V3_CH_SBR_RD; -+ else -+ val |= EDMA_V3_CH_SBR_WR; - - if (fsl_chan->is_remote) - val &= ~(EDMA_V3_CH_SBR_RD | EDMA_V3_CH_SBR_WR); -@@ -97,8 +90,8 @@ static void fsl_edma3_enable_request(struct fsl_edma_chan *fsl_chan) - * ch_mux: With the exception of 0, attempts to write a value - * already in use will be forced to 0. - */ -- if (!edma_readl_chreg(fsl_chan, ch_mux)) -- edma_writel_chreg(fsl_chan, fsl_chan->srcid, ch_mux); -+ if (!edma_readl(fsl_chan->edma, fsl_chan->mux_addr)) -+ edma_writel(fsl_chan->edma, fsl_chan->srcid, fsl_chan->mux_addr); - } - - val = edma_readl_chreg(fsl_chan, ch_csr); -@@ -134,7 +127,7 @@ static void fsl_edma3_disable_request(struct fsl_edma_chan *fsl_chan) - flags = fsl_edma_drvflags(fsl_chan); - - if (flags & FSL_EDMA_DRV_HAS_CHMUX) -- edma_writel_chreg(fsl_chan, 0, ch_mux); -+ edma_writel(fsl_chan->edma, 0, fsl_chan->mux_addr); - - val &= ~EDMA_V3_CH_CSR_ERQ; - edma_writel_chreg(fsl_chan, val, ch_csr); -@@ -754,6 +747,8 @@ struct dma_async_tx_descriptor *fsl_edma_prep_memcpy(struct dma_chan *chan, - fsl_desc->iscyclic = false; - - fsl_chan->is_sw = true; -+ if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_MEM_REMOTE) -+ fsl_chan->is_remote = true; - - /* To match with copy_align and max_seg_size so 1 tcd is enough */ - fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[0].vtcd, dma_src, dma_dst, -@@ -802,6 +797,9 @@ int fsl_edma_alloc_chan_resources(struct dma_chan *chan) - { - struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); - -+ if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_HAS_CHCLK) -+ clk_prepare_enable(fsl_chan->clk); -+ - fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev, - sizeof(struct fsl_edma_hw_tcd), - 32, 0); -@@ -829,6 +827,9 @@ void fsl_edma_free_chan_resources(struct dma_chan *chan) - fsl_chan->tcd_pool = NULL; - fsl_chan->is_sw = false; - fsl_chan->srcid = 0; -+ fsl_chan->is_remote = false; -+ if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_HAS_CHCLK) -+ clk_disable_unprepare(fsl_chan->clk); - } - - void fsl_edma_cleanup_vchan(struct dma_device *dmadev) -diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h -index 92fe53faa53b1..6028389de408b 100644 ---- a/drivers/dma/fsl-edma-common.h -+++ b/drivers/dma/fsl-edma-common.h -@@ -146,6 +146,7 @@ struct fsl_edma_chan { - enum dma_data_direction dma_dir; - char chan_name[32]; - struct fsl_edma_hw_tcd __iomem *tcd; -+ void __iomem *mux_addr; - u32 real_count; - struct work_struct issue_worker; - struct platform_device *pdev; -@@ -177,8 +178,7 @@ struct fsl_edma_desc { - #define FSL_EDMA_DRV_HAS_PD BIT(5) - #define FSL_EDMA_DRV_HAS_CHCLK BIT(6) - #define FSL_EDMA_DRV_HAS_CHMUX BIT(7) --/* imx8 QM audio edma remote local swapped */ --#define FSL_EDMA_DRV_QUIRK_SWAPPED BIT(8) -+#define FSL_EDMA_DRV_MEM_REMOTE BIT(8) - /* control and status register is in tcd address space, edma3 reg layout */ - #define FSL_EDMA_DRV_SPLIT_REG BIT(9) - #define FSL_EDMA_DRV_BUS_8BYTE BIT(10) -@@ -207,6 +207,8 @@ struct fsl_edma_drvdata { - u32 chreg_off; - u32 chreg_space_sz; - u32 flags; -+ u32 mux_off; /* channel mux register offset */ -+ u32 mux_skip; /* how much skip for each channel */ - int (*setup_irq)(struct platform_device *pdev, - struct fsl_edma_engine *fsl_edma); - }; -diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c -index 42a338cbe6143..8a0ae90548997 100644 ---- a/drivers/dma/fsl-edma-main.c -+++ b/drivers/dma/fsl-edma-main.c -@@ -340,16 +340,19 @@ static struct fsl_edma_drvdata imx7ulp_data = { - }; - - static struct fsl_edma_drvdata imx8qm_data = { -- .flags = FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3, -+ .flags = FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3 | FSL_EDMA_DRV_MEM_REMOTE, - .chreg_space_sz = 0x10000, - .chreg_off = 0x10000, - .setup_irq = fsl_edma3_irq_init, - }; - --static struct fsl_edma_drvdata imx8qm_audio_data = { -- .flags = FSL_EDMA_DRV_QUIRK_SWAPPED | FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3, -+static struct fsl_edma_drvdata imx8ulp_data = { -+ .flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_CHCLK | FSL_EDMA_DRV_HAS_DMACLK | -+ FSL_EDMA_DRV_EDMA3, - .chreg_space_sz = 0x10000, - .chreg_off = 0x10000, -+ .mux_off = 0x10000 + offsetof(struct fsl_edma3_ch_reg, ch_mux), -+ .mux_skip = 0x10000, - .setup_irq = fsl_edma3_irq_init, - }; - -@@ -364,6 +367,8 @@ static struct fsl_edma_drvdata imx93_data4 = { - .flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4, - .chreg_space_sz = 0x8000, - .chreg_off = 0x10000, -+ .mux_off = 0x10000 + offsetof(struct fsl_edma3_ch_reg, ch_mux), -+ .mux_skip = 0x8000, - .setup_irq = fsl_edma3_irq_init, - }; - -@@ -372,7 +377,7 @@ static const struct of_device_id fsl_edma_dt_ids[] = { - { .compatible = "fsl,ls1028a-edma", .data = &ls1028a_data}, - { .compatible = "fsl,imx7ulp-edma", .data = &imx7ulp_data}, - { .compatible = "fsl,imx8qm-edma", .data = &imx8qm_data}, -- { .compatible = "fsl,imx8qm-adma", .data = &imx8qm_audio_data}, -+ { .compatible = "fsl,imx8ulp-edma", .data = &imx8ulp_data}, - { .compatible = "fsl,imx93-edma3", .data = &imx93_data3}, - { .compatible = "fsl,imx93-edma4", .data = &imx93_data4}, - { /* sentinel */ } -@@ -427,6 +432,7 @@ static int fsl_edma_probe(struct platform_device *pdev) - struct fsl_edma_engine *fsl_edma; - const struct fsl_edma_drvdata *drvdata = NULL; - u32 chan_mask[2] = {0, 0}; -+ char clk_name[36]; - struct edma_regs *regs; - int chans; - int ret, i; -@@ -540,12 +546,23 @@ static int fsl_edma_probe(struct platform_device *pdev) - offsetof(struct fsl_edma3_ch_reg, tcd) : 0; - fsl_chan->tcd = fsl_edma->membase - + i * drvdata->chreg_space_sz + drvdata->chreg_off + len; -+ fsl_chan->mux_addr = fsl_edma->membase + drvdata->mux_off + i * drvdata->mux_skip; - -+ if (drvdata->flags & FSL_EDMA_DRV_HAS_CHCLK) { -+ snprintf(clk_name, sizeof(clk_name), "ch%02d", i); -+ fsl_chan->clk = devm_clk_get_enabled(&pdev->dev, -+ (const char *)clk_name); -+ -+ if (IS_ERR(fsl_chan->clk)) -+ return PTR_ERR(fsl_chan->clk); -+ } - fsl_chan->pdev = pdev; - vchan_init(&fsl_chan->vchan, &fsl_edma->dma_dev); - - edma_write_tcdreg(fsl_chan, 0, csr); - fsl_edma_chan_mux(fsl_chan, 0, false); -+ if (fsl_chan->edma->drvdata->flags & FSL_EDMA_DRV_HAS_CHCLK) -+ clk_disable_unprepare(fsl_chan->clk); - } - - ret = fsl_edma->drvdata->setup_irq(pdev, fsl_edma); -diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig -index b59e3041fd627..f0e9f250669e2 100644 ---- a/drivers/firmware/Kconfig -+++ b/drivers/firmware/Kconfig -@@ -229,6 +229,7 @@ config QCOM_SCM_DOWNLOAD_MODE_DEFAULT - config SYSFB - bool - select BOOT_VESA_SUPPORT -+ select SCREEN_INFO - - config SYSFB_SIMPLEFB - bool "Mark VGA/VBE/EFI FB as generic system framebuffer" -diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c -index 3c197db42c9d9..defd7a36cb08a 100644 ---- a/drivers/firmware/sysfb.c -+++ b/drivers/firmware/sysfb.c -@@ -77,6 +77,8 @@ static __init int sysfb_init(void) - bool compatible; - int ret = 0; - -+ screen_info_apply_fixups(); -+ - mutex_lock(&disable_lock); - if (disabled) - goto unlock_mutex; -diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c -index d0255ea98348d..247e7d675e2b9 100644 ---- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c -+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c -@@ -1556,7 +1556,7 @@ static void skl_wrpll_params_populate(struct skl_wrpll_params *params, - } - - static int --skl_ddi_calculate_wrpll(int clock /* in Hz */, -+skl_ddi_calculate_wrpll(int clock, - int ref_clock, - struct skl_wrpll_params *wrpll_params) - { -@@ -1581,7 +1581,7 @@ skl_ddi_calculate_wrpll(int clock /* in Hz */, - }; - unsigned int dco, d, i; - unsigned int p0, p1, p2; -- u64 afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */ -+ u64 afe_clock = (u64)clock * 1000 * 5; /* AFE Clock is 5x Pixel clock, in Hz */ - - for (d = 0; d < ARRAY_SIZE(dividers); d++) { - for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) { -@@ -1713,7 +1713,7 @@ static int skl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state) - - ctrl1 |= DPLL_CTRL1_HDMI_MODE(0); - -- ret = skl_ddi_calculate_wrpll(crtc_state->port_clock * 1000, -+ ret = skl_ddi_calculate_wrpll(crtc_state->port_clock, - i915->display.dpll.ref_clks.nssc, &wrpll_params); - if (ret) - return ret; -diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_regs.h b/drivers/gpu/drm/i915/display/intel_hdcp_regs.h -index 8023c85c7fa0e..74059384892af 100644 ---- a/drivers/gpu/drm/i915/display/intel_hdcp_regs.h -+++ b/drivers/gpu/drm/i915/display/intel_hdcp_regs.h -@@ -249,7 +249,7 @@ - #define HDCP2_STREAM_STATUS(dev_priv, trans, port) \ - (GRAPHICS_VER(dev_priv) >= 12 ? \ - TRANS_HDCP2_STREAM_STATUS(trans) : \ -- PIPE_HDCP2_STREAM_STATUS(pipe)) -+ PIPE_HDCP2_STREAM_STATUS(port)) - - #define _PORTA_HDCP2_AUTH_STREAM 0x66F00 - #define _PORTB_HDCP2_AUTH_STREAM 0x66F04 -diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c -index 3f90403d86cb4..0808b54d3c518 100644 ---- a/drivers/gpu/drm/i915/i915_perf.c -+++ b/drivers/gpu/drm/i915/i915_perf.c -@@ -2781,26 +2781,6 @@ oa_configure_all_contexts(struct i915_perf_stream *stream, - return 0; - } - --static int --gen12_configure_all_contexts(struct i915_perf_stream *stream, -- const struct i915_oa_config *oa_config, -- struct i915_active *active) --{ -- struct flex regs[] = { -- { -- GEN8_R_PWR_CLK_STATE(RENDER_RING_BASE), -- CTX_R_PWR_CLK_STATE, -- }, -- }; -- -- if (stream->engine->class != RENDER_CLASS) -- return 0; -- -- return oa_configure_all_contexts(stream, -- regs, ARRAY_SIZE(regs), -- active); --} -- - static int - lrc_configure_all_contexts(struct i915_perf_stream *stream, - const struct i915_oa_config *oa_config, -@@ -2907,7 +2887,6 @@ gen12_enable_metric_set(struct i915_perf_stream *stream, - { - struct drm_i915_private *i915 = stream->perf->i915; - struct intel_uncore *uncore = stream->uncore; -- struct i915_oa_config *oa_config = stream->oa_config; - bool periodic = stream->periodic; - u32 period_exponent = stream->period_exponent; - u32 sqcnt1; -@@ -2951,15 +2930,6 @@ gen12_enable_metric_set(struct i915_perf_stream *stream, - - intel_uncore_rmw(uncore, GEN12_SQCNT1, 0, sqcnt1); - -- /* -- * Update all contexts prior writing the mux configurations as we need -- * to make sure all slices/subslices are ON before writing to NOA -- * registers. -- */ -- ret = gen12_configure_all_contexts(stream, oa_config, active); -- if (ret) -- return ret; -- - /* - * For Gen12, performance counters are context - * saved/restored. Only enable it for the context that -@@ -3014,9 +2984,6 @@ static void gen12_disable_metric_set(struct i915_perf_stream *stream) - _MASKED_BIT_DISABLE(GEN12_DISABLE_DOP_GATING)); - } - -- /* Reset all contexts' slices/subslices configurations. */ -- gen12_configure_all_contexts(stream, NULL, NULL); -- - /* disable the context save/restore or OAR counters */ - if (stream->ctx) - gen12_configure_oar_context(stream, NULL); -diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c -index 1b2ff0c40fc1c..6c599a9f49ee4 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_prime.c -+++ b/drivers/gpu/drm/nouveau/nouveau_prime.c -@@ -64,7 +64,8 @@ struct drm_gem_object *nouveau_gem_prime_import_sg_table(struct drm_device *dev, - * to the caller, instead of a normal nouveau_bo ttm reference. */ - ret = drm_gem_object_init(dev, &nvbo->bo.base, size); - if (ret) { -- nouveau_bo_ref(NULL, &nvbo); -+ drm_gem_object_release(&nvbo->bo.base); -+ kfree(nvbo); - obj = ERR_PTR(-ENOMEM); - goto unlock; - } -diff --git a/drivers/gpu/drm/virtio/virtgpu_submit.c b/drivers/gpu/drm/virtio/virtgpu_submit.c -index 5c514946bbad9..d530c058f53e2 100644 ---- a/drivers/gpu/drm/virtio/virtgpu_submit.c -+++ b/drivers/gpu/drm/virtio/virtgpu_submit.c -@@ -48,7 +48,7 @@ struct virtio_gpu_submit { - static int virtio_gpu_do_fence_wait(struct virtio_gpu_submit *submit, - struct dma_fence *in_fence) - { -- u32 context = submit->fence_ctx + submit->ring_idx; -+ u64 context = submit->fence_ctx + submit->ring_idx; - - if (dma_fence_match_context(in_fence, context)) - return 0; -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c -index 5efc6a766f64e..588d50ababf60 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c -@@ -32,7 +32,6 @@ - #define VMW_FENCE_WRAP (1 << 31) - - struct vmw_fence_manager { -- int num_fence_objects; - struct vmw_private *dev_priv; - spinlock_t lock; - struct list_head fence_list; -@@ -124,13 +123,13 @@ static void vmw_fence_obj_destroy(struct dma_fence *f) - { - struct vmw_fence_obj *fence = - container_of(f, struct vmw_fence_obj, base); -- - struct vmw_fence_manager *fman = fman_from_fence(fence); - -- spin_lock(&fman->lock); -- list_del_init(&fence->head); -- --fman->num_fence_objects; -- spin_unlock(&fman->lock); -+ if (!list_empty(&fence->head)) { -+ spin_lock(&fman->lock); -+ list_del_init(&fence->head); -+ spin_unlock(&fman->lock); -+ } - fence->destroy(fence); - } - -@@ -257,7 +256,6 @@ static const struct dma_fence_ops vmw_fence_ops = { - .release = vmw_fence_obj_destroy, - }; - -- - /* - * Execute signal actions on fences recently signaled. - * This is done from a workqueue so we don't have to execute -@@ -355,7 +353,6 @@ static int vmw_fence_obj_init(struct vmw_fence_manager *fman, - goto out_unlock; - } - list_add_tail(&fence->head, &fman->fence_list); -- ++fman->num_fence_objects; - - out_unlock: - spin_unlock(&fman->lock); -@@ -403,7 +400,7 @@ static bool vmw_fence_goal_new_locked(struct vmw_fence_manager *fman, - u32 passed_seqno) - { - u32 goal_seqno; -- struct vmw_fence_obj *fence; -+ struct vmw_fence_obj *fence, *next_fence; - - if (likely(!fman->seqno_valid)) - return false; -@@ -413,7 +410,7 @@ static bool vmw_fence_goal_new_locked(struct vmw_fence_manager *fman, - return false; - - fman->seqno_valid = false; -- list_for_each_entry(fence, &fman->fence_list, head) { -+ list_for_each_entry_safe(fence, next_fence, &fman->fence_list, head) { - if (!list_empty(&fence->seq_passed_actions)) { - fman->seqno_valid = true; - vmw_fence_goal_write(fman->dev_priv, -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c -index c45b4724e4141..e20f64b67b266 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c -@@ -92,7 +92,7 @@ static int vmw_overlay_send_put(struct vmw_private *dev_priv, - { - struct vmw_escape_video_flush *flush; - size_t fifo_size; -- bool have_so = (dev_priv->active_display_unit == vmw_du_screen_object); -+ bool have_so = (dev_priv->active_display_unit != vmw_du_legacy); - int i, num_items; - SVGAGuestPtr ptr; - -diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c -index 4ccab07faff08..cb03c589ab226 100644 ---- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c -+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c -@@ -868,6 +868,32 @@ vmw_stdu_connector_mode_valid(struct drm_connector *connector, - return MODE_OK; - } - -+/* -+ * Trigger a modeset if the X,Y position of the Screen Target changes. -+ * This is needed when multi-mon is cycled. The original Screen Target will have -+ * the same mode but its relative X,Y position in the topology will change. -+ */ -+static int vmw_stdu_connector_atomic_check(struct drm_connector *conn, -+ struct drm_atomic_state *state) -+{ -+ struct drm_connector_state *conn_state; -+ struct vmw_screen_target_display_unit *du; -+ struct drm_crtc_state *new_crtc_state; -+ -+ conn_state = drm_atomic_get_connector_state(state, conn); -+ du = vmw_connector_to_stdu(conn); -+ -+ if (!conn_state->crtc) -+ return 0; -+ -+ new_crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); -+ if (du->base.gui_x != du->base.set_gui_x || -+ du->base.gui_y != du->base.set_gui_y) -+ new_crtc_state->mode_changed = true; -+ -+ return 0; -+} -+ - static const struct drm_connector_funcs vmw_stdu_connector_funcs = { - .dpms = vmw_du_connector_dpms, - .detect = vmw_du_connector_detect, -@@ -882,7 +908,8 @@ static const struct drm_connector_funcs vmw_stdu_connector_funcs = { - static const struct - drm_connector_helper_funcs vmw_stdu_connector_helper_funcs = { - .get_modes = vmw_connector_get_modes, -- .mode_valid = vmw_stdu_connector_mode_valid -+ .mode_valid = vmw_stdu_connector_mode_valid, -+ .atomic_check = vmw_stdu_connector_atomic_check, - }; - - -diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c -index bdb578e0899f5..4b59687ff5d82 100644 ---- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c -+++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c -@@ -288,12 +288,22 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) - mp2_ops->start(privdata, info); - cl_data->sensor_sts[i] = amd_sfh_wait_for_response - (privdata, cl_data->sensor_idx[i], SENSOR_ENABLED); -+ -+ if (cl_data->sensor_sts[i] == SENSOR_ENABLED) -+ cl_data->is_any_sensor_enabled = true; -+ } -+ -+ if (!cl_data->is_any_sensor_enabled || -+ (mp2_ops->discovery_status && mp2_ops->discovery_status(privdata) == 0)) { -+ dev_warn(dev, "Failed to discover, sensors not enabled is %d\n", -+ cl_data->is_any_sensor_enabled); -+ rc = -EOPNOTSUPP; -+ goto cleanup; - } - - for (i = 0; i < cl_data->num_hid_devices; i++) { - cl_data->cur_hid_dev = i; - if (cl_data->sensor_sts[i] == SENSOR_ENABLED) { -- cl_data->is_any_sensor_enabled = true; - rc = amdtp_hid_probe(i, cl_data); - if (rc) - goto cleanup; -@@ -305,12 +315,6 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) - cl_data->sensor_sts[i]); - } - -- if (!cl_data->is_any_sensor_enabled || -- (mp2_ops->discovery_status && mp2_ops->discovery_status(privdata) == 0)) { -- dev_warn(dev, "Failed to discover, sensors not enabled is %d\n", cl_data->is_any_sensor_enabled); -- rc = -EOPNOTSUPP; -- goto cleanup; -- } - schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP)); - return 0; - -diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c -index 002cbaa16bd16..d2fe14ce423e2 100644 ---- a/drivers/hid/wacom_wac.c -+++ b/drivers/hid/wacom_wac.c -@@ -714,13 +714,12 @@ static int wacom_intuos_get_tool_type(int tool_id) - case 0x8e2: /* IntuosHT2 pen */ - case 0x022: - case 0x200: /* Pro Pen 3 */ -- case 0x04200: /* Pro Pen 3 */ - case 0x10842: /* MobileStudio Pro Pro Pen slim */ - case 0x14802: /* Intuos4/5 13HD/24HD Classic Pen */ - case 0x16802: /* Cintiq 13HD Pro Pen */ - case 0x18802: /* DTH2242 Pen */ - case 0x10802: /* Intuos4/5 13HD/24HD General Pen */ -- case 0x80842: /* Intuos Pro and Cintiq Pro 3D Pen */ -+ case 0x8842: /* Intuos Pro and Cintiq Pro 3D Pen */ - tool_type = BTN_TOOL_PEN; - break; - -diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c -index 4f5829b726a75..72fd2fe8f6fe8 100644 ---- a/drivers/leds/led-triggers.c -+++ b/drivers/leds/led-triggers.c -@@ -194,11 +194,24 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) - spin_unlock(&trig->leddev_list_lock); - led_cdev->trigger = trig; - -+ /* -+ * Some activate() calls use led_trigger_event() to initialize -+ * the brightness of the LED for which the trigger is being set. -+ * Ensure the led_cdev is visible on trig->led_cdevs for this. -+ */ -+ synchronize_rcu(); -+ -+ /* -+ * If "set brightness to 0" is pending in workqueue, -+ * we don't want that to be reordered after ->activate() -+ */ -+ flush_work(&led_cdev->set_brightness_work); -+ -+ ret = 0; - if (trig->activate) - ret = trig->activate(led_cdev); - else -- ret = 0; -- -+ led_set_brightness(led_cdev, trig->brightness); - if (ret) - goto err_activate; - -@@ -269,19 +282,6 @@ void led_trigger_set_default(struct led_classdev *led_cdev) - } - EXPORT_SYMBOL_GPL(led_trigger_set_default); - --void led_trigger_rename_static(const char *name, struct led_trigger *trig) --{ -- /* new name must be on a temporary string to prevent races */ -- BUG_ON(name == trig->name); -- -- down_write(&triggers_list_lock); -- /* this assumes that trig->name was originaly allocated to -- * non constant storage */ -- strcpy((char *)trig->name, name); -- up_write(&triggers_list_lock); --} --EXPORT_SYMBOL_GPL(led_trigger_rename_static); -- - /* LED Trigger Interface */ - - int led_trigger_register(struct led_trigger *trig) -@@ -386,6 +386,8 @@ void led_trigger_event(struct led_trigger *trig, - if (!trig) - return; - -+ trig->brightness = brightness; -+ - rcu_read_lock(); - list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list) - led_set_brightness(led_cdev, brightness); -diff --git a/drivers/leds/trigger/ledtrig-timer.c b/drivers/leds/trigger/ledtrig-timer.c -index b4688d1d9d2b2..1d213c999d40a 100644 ---- a/drivers/leds/trigger/ledtrig-timer.c -+++ b/drivers/leds/trigger/ledtrig-timer.c -@@ -110,11 +110,6 @@ static int timer_trig_activate(struct led_classdev *led_cdev) - led_cdev->flags &= ~LED_INIT_DEFAULT_TRIGGER; - } - -- /* -- * If "set brightness to 0" is pending in workqueue, we don't -- * want that to be reordered after blink_set() -- */ -- flush_work(&led_cdev->set_brightness_work); - led_blink_set(led_cdev, &led_cdev->blink_delay_on, - &led_cdev->blink_delay_off); - -diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c -index 24c914015973e..49b1fa9651161 100644 ---- a/drivers/net/ethernet/intel/ice/ice_txrx.c -+++ b/drivers/net/ethernet/intel/ice/ice_txrx.c -@@ -456,7 +456,7 @@ void ice_free_rx_ring(struct ice_rx_ring *rx_ring) - if (rx_ring->vsi->type == ICE_VSI_PF) - if (xdp_rxq_info_is_reg(&rx_ring->xdp_rxq)) - xdp_rxq_info_unreg(&rx_ring->xdp_rxq); -- rx_ring->xdp_prog = NULL; -+ WRITE_ONCE(rx_ring->xdp_prog, NULL); - if (rx_ring->xsk_pool) { - kfree(rx_ring->xdp_buf); - rx_ring->xdp_buf = NULL; -diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c -index f53566cb6bfbd..67511153081ae 100644 ---- a/drivers/net/ethernet/intel/ice/ice_xsk.c -+++ b/drivers/net/ethernet/intel/ice/ice_xsk.c -@@ -52,10 +52,8 @@ static void ice_qp_reset_stats(struct ice_vsi *vsi, u16 q_idx) - static void ice_qp_clean_rings(struct ice_vsi *vsi, u16 q_idx) - { - ice_clean_tx_ring(vsi->tx_rings[q_idx]); -- if (ice_is_xdp_ena_vsi(vsi)) { -- synchronize_rcu(); -+ if (ice_is_xdp_ena_vsi(vsi)) - ice_clean_tx_ring(vsi->xdp_rings[q_idx]); -- } - ice_clean_rx_ring(vsi->rx_rings[q_idx]); - } - -@@ -180,11 +178,12 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx) - usleep_range(1000, 2000); - } - -+ synchronize_net(); -+ netif_tx_stop_queue(netdev_get_tx_queue(vsi->netdev, q_idx)); -+ - ice_qvec_dis_irq(vsi, rx_ring, q_vector); - ice_qvec_toggle_napi(vsi, q_vector, false); - -- netif_tx_stop_queue(netdev_get_tx_queue(vsi->netdev, q_idx)); -- - ice_fill_txq_meta(vsi, tx_ring, &txq_meta); - err = ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, 0, tx_ring, &txq_meta); - if (err) -@@ -199,10 +198,8 @@ static int ice_qp_dis(struct ice_vsi *vsi, u16 q_idx) - if (err) - return err; - } -- err = ice_vsi_ctrl_one_rx_ring(vsi, false, q_idx, true); -- if (err) -- return err; - -+ ice_vsi_ctrl_one_rx_ring(vsi, false, q_idx, false); - ice_qp_clean_rings(vsi, q_idx); - ice_qp_reset_stats(vsi, q_idx); - -@@ -1068,6 +1065,10 @@ bool ice_xmit_zc(struct ice_tx_ring *xdp_ring) - - ice_clean_xdp_irq_zc(xdp_ring); - -+ if (!netif_carrier_ok(xdp_ring->vsi->netdev) || -+ !netif_running(xdp_ring->vsi->netdev)) -+ return true; -+ - budget = ICE_DESC_UNUSED(xdp_ring); - budget = min_t(u16, budget, ICE_RING_QUARTER(xdp_ring)); - -@@ -1111,7 +1112,7 @@ ice_xsk_wakeup(struct net_device *netdev, u32 queue_id, - struct ice_vsi *vsi = np->vsi; - struct ice_tx_ring *ring; - -- if (test_bit(ICE_VSI_DOWN, vsi->state)) -+ if (test_bit(ICE_VSI_DOWN, vsi->state) || !netif_carrier_ok(netdev)) - return -ENETDOWN; - - if (!ice_is_xdp_ena_vsi(vsi)) -diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c -index e83700ad7e622..d80bbcdeb93ed 100644 ---- a/drivers/net/ethernet/intel/igc/igc_main.c -+++ b/drivers/net/ethernet/intel/igc/igc_main.c -@@ -6208,21 +6208,6 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter, - size_t n; - int i; - -- switch (qopt->cmd) { -- case TAPRIO_CMD_REPLACE: -- break; -- case TAPRIO_CMD_DESTROY: -- return igc_tsn_clear_schedule(adapter); -- case TAPRIO_CMD_STATS: -- igc_taprio_stats(adapter->netdev, &qopt->stats); -- return 0; -- case TAPRIO_CMD_QUEUE_STATS: -- igc_taprio_queue_stats(adapter->netdev, &qopt->queue_stats); -- return 0; -- default: -- return -EOPNOTSUPP; -- } -- - if (qopt->base_time < 0) - return -ERANGE; - -@@ -6331,7 +6316,23 @@ static int igc_tsn_enable_qbv_scheduling(struct igc_adapter *adapter, - if (hw->mac.type != igc_i225) - return -EOPNOTSUPP; - -- err = igc_save_qbv_schedule(adapter, qopt); -+ switch (qopt->cmd) { -+ case TAPRIO_CMD_REPLACE: -+ err = igc_save_qbv_schedule(adapter, qopt); -+ break; -+ case TAPRIO_CMD_DESTROY: -+ err = igc_tsn_clear_schedule(adapter); -+ break; -+ case TAPRIO_CMD_STATS: -+ igc_taprio_stats(adapter->netdev, &qopt->stats); -+ return 0; -+ case TAPRIO_CMD_QUEUE_STATS: -+ igc_taprio_queue_stats(adapter->netdev, &qopt->queue_stats); -+ return 0; -+ default: -+ return -EOPNOTSUPP; -+ } -+ - if (err) - return err; - -diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -index 05f4aa11b95c3..34051c9abd97d 100644 ---- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c -@@ -953,13 +953,13 @@ static void mvpp2_bm_pool_update_fc(struct mvpp2_port *port, - static void mvpp2_bm_pool_update_priv_fc(struct mvpp2 *priv, bool en) - { - struct mvpp2_port *port; -- int i; -+ int i, j; - - for (i = 0; i < priv->port_count; i++) { - port = priv->port_list[i]; - if (port->priv->percpu_pools) { -- for (i = 0; i < port->nrxqs; i++) -- mvpp2_bm_pool_update_fc(port, &port->priv->bm_pools[i], -+ for (j = 0; j < port->nrxqs; j++) -+ mvpp2_bm_pool_update_fc(port, &port->priv->bm_pools[j], - port->tx_fc & en); - } else { - mvpp2_bm_pool_update_fc(port, port->pool_long, port->tx_fc & en); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c -index fadfa8b50bebe..8c4e3ecef5901 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c -@@ -920,6 +920,7 @@ mlx5_tc_ct_entry_replace_rule(struct mlx5_tc_ct_priv *ct_priv, - mlx5_tc_ct_entry_destroy_mod_hdr(ct_priv, zone_rule->attr, mh); - mlx5_put_label_mapping(ct_priv, attr->ct_attr.ct_labels_id); - err_mod_hdr: -+ *attr = *old_attr; - kfree(old_attr); - err_attr: - kvfree(spec); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c -index ce29e31721208..de83567aae791 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c -@@ -50,9 +50,10 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev) - MLX5_CAP_FLOWTABLE_NIC_RX(mdev, decap)) - caps |= MLX5_IPSEC_CAP_PACKET_OFFLOAD; - -- if ((MLX5_CAP_FLOWTABLE_NIC_TX(mdev, ignore_flow_level) && -- MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ignore_flow_level)) || -- MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, ignore_flow_level)) -+ if (IS_ENABLED(CONFIG_MLX5_CLS_ACT) && -+ ((MLX5_CAP_FLOWTABLE_NIC_TX(mdev, ignore_flow_level) && -+ MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ignore_flow_level)) || -+ MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, ignore_flow_level))) - caps |= MLX5_IPSEC_CAP_PRIO; - - if (MLX5_CAP_FLOWTABLE_NIC_TX(mdev, -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c -index 38263d5c98b34..50db127e6371b 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c -@@ -1223,7 +1223,12 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, - if (!an_changes && link_modes == eproto.admin) - goto out; - -- mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext); -+ err = mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext); -+ if (err) { -+ netdev_err(priv->netdev, "%s: failed to set ptys reg: %d\n", __func__, err); -+ goto out; -+ } -+ - mlx5_toggle_port_link(mdev); - - out: -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c -index 3a9cdf79403ae..6b17346aa4cef 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c -@@ -206,6 +206,7 @@ int mlx5_fw_reset_set_live_patch(struct mlx5_core_dev *dev) - static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unloaded) - { - struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; -+ struct devlink *devlink = priv_to_devlink(dev); - - /* if this is the driver that initiated the fw reset, devlink completed the reload */ - if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) { -@@ -217,9 +218,11 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unload - mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n"); - else - mlx5_load_one(dev, true); -- devlink_remote_reload_actions_performed(priv_to_devlink(dev), 0, -+ devl_lock(devlink); -+ devlink_remote_reload_actions_performed(devlink, 0, - BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) | - BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE)); -+ devl_unlock(devlink); - } - } - -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c b/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c -index 612e666ec2635..e2230c8f18152 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c -@@ -48,6 +48,7 @@ static struct mlx5_irq * - irq_pool_request_irq(struct mlx5_irq_pool *pool, struct irq_affinity_desc *af_desc) - { - struct irq_affinity_desc auto_desc = {}; -+ struct mlx5_irq *irq; - u32 irq_index; - int err; - -@@ -64,9 +65,12 @@ irq_pool_request_irq(struct mlx5_irq_pool *pool, struct irq_affinity_desc *af_de - else - cpu_get(pool, cpumask_first(&af_desc->mask)); - } -- return mlx5_irq_alloc(pool, irq_index, -- cpumask_empty(&auto_desc.mask) ? af_desc : &auto_desc, -- NULL); -+ irq = mlx5_irq_alloc(pool, irq_index, -+ cpumask_empty(&auto_desc.mask) ? af_desc : &auto_desc, -+ NULL); -+ if (IS_ERR(irq)) -+ xa_erase(&pool->irqs, irq_index); -+ return irq; - } - - /* Looking for the IRQ with the smallest refcount that fits req_mask. -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c -index dfc2ba6f780a2..18cf756bad8cc 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c -@@ -1512,7 +1512,7 @@ u8 mlx5_lag_get_slave_port(struct mlx5_core_dev *dev, - goto unlock; - - for (i = 0; i < ldev->ports; i++) { -- if (ldev->pf[MLX5_LAG_P1].netdev == slave) { -+ if (ldev->pf[i].netdev == slave) { - port = i; - break; - } -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c -index 2237b3d01e0e5..11f11248feb8b 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/main.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c -@@ -2130,7 +2130,6 @@ static int mlx5_try_fast_unload(struct mlx5_core_dev *dev) - /* Panic tear down fw command will stop the PCI bus communication - * with the HCA, so the health poll is no longer needed. - */ -- mlx5_drain_health_wq(dev); - mlx5_stop_health_poll(dev, false); - - ret = mlx5_cmd_fast_teardown_hca(dev); -@@ -2165,6 +2164,7 @@ static void shutdown(struct pci_dev *pdev) - - mlx5_core_info(dev, "Shutdown was called\n"); - set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state); -+ mlx5_drain_health_wq(dev); - err = mlx5_try_fast_unload(dev); - if (err) - mlx5_unload_one(dev, false); -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c -index 30218f37d5285..2028acbe85ca2 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c -@@ -90,6 +90,7 @@ static void mlx5_sf_dev_shutdown(struct auxiliary_device *adev) - struct mlx5_core_dev *mdev = sf_dev->mdev; - - set_bit(MLX5_BREAK_FW_WAIT, &mdev->intf_state); -+ mlx5_drain_health_wq(mdev); - mlx5_unload_one(mdev, false); - } - -diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c -index d759f3373b175..8a732edac15a0 100644 ---- a/drivers/net/ethernet/realtek/r8169_main.c -+++ b/drivers/net/ethernet/realtek/r8169_main.c -@@ -4256,7 +4256,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, - if (unlikely(!rtl_tx_slots_avail(tp))) { - if (net_ratelimit()) - netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); -- goto err_stop_0; -+ netif_stop_queue(dev); -+ return NETDEV_TX_BUSY; - } - - opts[1] = rtl8169_tx_vlan_tag(skb); -@@ -4312,11 +4313,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, - dev_kfree_skb_any(skb); - dev->stats.tx_dropped++; - return NETDEV_TX_OK; -- --err_stop_0: -- netif_stop_queue(dev); -- dev->stats.tx_dropped++; -- return NETDEV_TX_BUSY; - } - - static unsigned int rtl_last_frag_len(struct sk_buff *skb) -diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c -index 3297aff969c80..11e08cb8d3c3e 100644 ---- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c -+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c -@@ -1826,9 +1826,9 @@ static void axienet_dma_err_handler(struct work_struct *work) - ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); - axienet_set_mac_address(ndev, NULL); - axienet_set_multicast_list(ndev); -- axienet_setoptions(ndev, lp->options); - napi_enable(&lp->napi_rx); - napi_enable(&lp->napi_tx); -+ axienet_setoptions(ndev, lp->options); - } - - /** -diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c -index 029c82f88ee38..9a0432145645f 100644 ---- a/drivers/net/phy/micrel.c -+++ b/drivers/net/phy/micrel.c -@@ -1293,6 +1293,8 @@ static int ksz9131_config_init(struct phy_device *phydev) - const struct device *dev_walker; - int ret; - -+ phydev->mdix_ctrl = ETH_TP_MDI_AUTO; -+ - dev_walker = &phydev->mdio.dev; - do { - of_node = dev_walker->of_node; -@@ -1342,28 +1344,30 @@ static int ksz9131_config_init(struct phy_device *phydev) - #define MII_KSZ9131_AUTO_MDIX 0x1C - #define MII_KSZ9131_AUTO_MDI_SET BIT(7) - #define MII_KSZ9131_AUTO_MDIX_SWAP_OFF BIT(6) -+#define MII_KSZ9131_DIG_AXAN_STS 0x14 -+#define MII_KSZ9131_DIG_AXAN_STS_LINK_DET BIT(14) -+#define MII_KSZ9131_DIG_AXAN_STS_A_SELECT BIT(12) - - static int ksz9131_mdix_update(struct phy_device *phydev) - { - int ret; - -- ret = phy_read(phydev, MII_KSZ9131_AUTO_MDIX); -- if (ret < 0) -- return ret; -- -- if (ret & MII_KSZ9131_AUTO_MDIX_SWAP_OFF) { -- if (ret & MII_KSZ9131_AUTO_MDI_SET) -- phydev->mdix_ctrl = ETH_TP_MDI; -- else -- phydev->mdix_ctrl = ETH_TP_MDI_X; -+ if (phydev->mdix_ctrl != ETH_TP_MDI_AUTO) { -+ phydev->mdix = phydev->mdix_ctrl; - } else { -- phydev->mdix_ctrl = ETH_TP_MDI_AUTO; -- } -+ ret = phy_read(phydev, MII_KSZ9131_DIG_AXAN_STS); -+ if (ret < 0) -+ return ret; - -- if (ret & MII_KSZ9131_AUTO_MDI_SET) -- phydev->mdix = ETH_TP_MDI; -- else -- phydev->mdix = ETH_TP_MDI_X; -+ if (ret & MII_KSZ9131_DIG_AXAN_STS_LINK_DET) { -+ if (ret & MII_KSZ9131_DIG_AXAN_STS_A_SELECT) -+ phydev->mdix = ETH_TP_MDI; -+ else -+ phydev->mdix = ETH_TP_MDI_X; -+ } else { -+ phydev->mdix = ETH_TP_MDI_INVALID; -+ } -+ } - - return 0; - } -diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c -index 337899c69738e..2604d9663a5b2 100644 ---- a/drivers/net/phy/realtek.c -+++ b/drivers/net/phy/realtek.c -@@ -1083,6 +1083,13 @@ static struct phy_driver realtek_drvs[] = { - .handle_interrupt = genphy_handle_interrupt_no_ack, - .suspend = genphy_suspend, - .resume = genphy_resume, -+ }, { -+ PHY_ID_MATCH_EXACT(0x001cc960), -+ .name = "RTL8366S Gigabit Ethernet", -+ .suspend = genphy_suspend, -+ .resume = genphy_resume, -+ .read_mmd = genphy_read_mmd_unsupported, -+ .write_mmd = genphy_write_mmd_unsupported, - }, - }; - -diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c -index 0a662e42ed965..cb7d2f798fb43 100644 ---- a/drivers/net/usb/sr9700.c -+++ b/drivers/net/usb/sr9700.c -@@ -179,6 +179,7 @@ static int sr_mdio_read(struct net_device *netdev, int phy_id, int loc) - struct usbnet *dev = netdev_priv(netdev); - __le16 res; - int rc = 0; -+ int err; - - if (phy_id) { - netdev_dbg(netdev, "Only internal phy supported\n"); -@@ -189,11 +190,17 @@ static int sr_mdio_read(struct net_device *netdev, int phy_id, int loc) - if (loc == MII_BMSR) { - u8 value; - -- sr_read_reg(dev, SR_NSR, &value); -+ err = sr_read_reg(dev, SR_NSR, &value); -+ if (err < 0) -+ return err; -+ - if (value & NSR_LINKST) - rc = 1; - } -- sr_share_read_word(dev, 1, loc, &res); -+ err = sr_share_read_word(dev, 1, loc, &res); -+ if (err < 0) -+ return err; -+ - if (rc == 1) - res = le16_to_cpu(res) | BMSR_LSTATUS; - else -diff --git a/drivers/pci/search.c b/drivers/pci/search.c -index b4c138a6ec025..53840634fbfc2 100644 ---- a/drivers/pci/search.c -+++ b/drivers/pci/search.c -@@ -363,6 +363,37 @@ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) - } - EXPORT_SYMBOL(pci_get_class); - -+/** -+ * pci_get_base_class - searching for a PCI device by matching against the base class code only -+ * @class: search for a PCI device with this base class code -+ * @from: Previous PCI device found in search, or %NULL for new search. -+ * -+ * Iterates through the list of known PCI devices. If a PCI device is found -+ * with a matching base class code, the reference count to the device is -+ * incremented. See pci_match_one_device() to figure out how does this works. -+ * A new search is initiated by passing %NULL as the @from argument. -+ * Otherwise if @from is not %NULL, searches continue from next device on the -+ * global list. The reference count for @from is always decremented if it is -+ * not %NULL. -+ * -+ * Returns: -+ * A pointer to a matched PCI device, %NULL Otherwise. -+ */ -+struct pci_dev *pci_get_base_class(unsigned int class, struct pci_dev *from) -+{ -+ struct pci_device_id id = { -+ .vendor = PCI_ANY_ID, -+ .device = PCI_ANY_ID, -+ .subvendor = PCI_ANY_ID, -+ .subdevice = PCI_ANY_ID, -+ .class_mask = 0xFF0000, -+ .class = class << 16, -+ }; -+ -+ return pci_get_dev_by_id(&id, from); -+} -+EXPORT_SYMBOL(pci_get_base_class); -+ - /** - * pci_dev_present - Returns 1 if device matching the device list is present, 0 if not. - * @ids: A pointer to a null terminated list of struct pci_device_id structures -diff --git a/drivers/perf/fsl_imx9_ddr_perf.c b/drivers/perf/fsl_imx9_ddr_perf.c -index 5cf770a1bc312..4f6eade522024 100644 ---- a/drivers/perf/fsl_imx9_ddr_perf.c -+++ b/drivers/perf/fsl_imx9_ddr_perf.c -@@ -476,12 +476,12 @@ static int ddr_perf_event_add(struct perf_event *event, int flags) - hwc->idx = counter; - hwc->state |= PERF_HES_STOPPED; - -- if (flags & PERF_EF_START) -- ddr_perf_event_start(event, flags); -- - /* read trans, write trans, read beat */ - ddr_perf_monitor_config(pmu, cfg, cfg1, cfg2); - -+ if (flags & PERF_EF_START) -+ ddr_perf_event_start(event, flags); -+ - return 0; - } - -diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c -index ae16ecb15f2d9..901da688ea3f8 100644 ---- a/drivers/perf/riscv_pmu_sbi.c -+++ b/drivers/perf/riscv_pmu_sbi.c -@@ -355,7 +355,7 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event) - * but not in the user access mode as we want to use the other counters - * that support sampling/filtering. - */ -- if (hwc->flags & PERF_EVENT_FLAG_LEGACY) { -+ if ((hwc->flags & PERF_EVENT_FLAG_LEGACY) && (event->attr.type == PERF_TYPE_HARDWARE)) { - if (event->attr.config == PERF_COUNT_HW_CPU_CYCLES) { - cflags |= SBI_PMU_CFG_FLAG_SKIP_MATCH; - cmask = 1; -diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c -index 475a6dd72db6b..809fabef3b44a 100644 ---- a/drivers/platform/chrome/cros_ec_proto.c -+++ b/drivers/platform/chrome/cros_ec_proto.c -@@ -805,9 +805,11 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev, - if (ret == -ENOPROTOOPT) { - dev_dbg(ec_dev->dev, - "GET_NEXT_EVENT returned invalid version error.\n"); -+ mutex_lock(&ec_dev->lock); - ret = cros_ec_get_host_command_version_mask(ec_dev, - EC_CMD_GET_NEXT_EVENT, - &ver_mask); -+ mutex_unlock(&ec_dev->lock); - if (ret < 0 || ver_mask == 0) - /* - * Do not change the MKBP supported version if we can't -diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c -index 3acc9288b3105..3b1030fc4fbfe 100644 ---- a/drivers/thermal/broadcom/bcm2835_thermal.c -+++ b/drivers/thermal/broadcom/bcm2835_thermal.c -@@ -185,7 +185,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) - return err; - } - -- data->clk = devm_clk_get(&pdev->dev, NULL); -+ data->clk = devm_clk_get_enabled(&pdev->dev, NULL); - if (IS_ERR(data->clk)) { - err = PTR_ERR(data->clk); - if (err != -EPROBE_DEFER) -@@ -193,10 +193,6 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) - return err; - } - -- err = clk_prepare_enable(data->clk); -- if (err) -- return err; -- - rate = clk_get_rate(data->clk); - if ((rate < 1920000) || (rate > 5000000)) - dev_warn(&pdev->dev, -@@ -211,7 +207,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) - dev_err(&pdev->dev, - "Failed to register the thermal device: %d\n", - err); -- goto err_clk; -+ return err; - } - - /* -@@ -236,7 +232,7 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) - dev_err(&pdev->dev, - "Not able to read trip_temp: %d\n", - err); -- goto err_tz; -+ return err; - } - - /* set bandgap reference voltage and enable voltage regulator */ -@@ -269,32 +265,23 @@ static int bcm2835_thermal_probe(struct platform_device *pdev) - */ - err = thermal_add_hwmon_sysfs(tz); - if (err) -- goto err_tz; -+ return err; - - bcm2835_thermal_debugfs(pdev); - - return 0; --err_tz: -- devm_thermal_of_zone_unregister(&pdev->dev, tz); --err_clk: -- clk_disable_unprepare(data->clk); -- -- return err; - } - --static int bcm2835_thermal_remove(struct platform_device *pdev) -+static void bcm2835_thermal_remove(struct platform_device *pdev) - { - struct bcm2835_thermal_data *data = platform_get_drvdata(pdev); - - debugfs_remove_recursive(data->debugfsdir); -- clk_disable_unprepare(data->clk); -- -- return 0; - } - - static struct platform_driver bcm2835_thermal_driver = { - .probe = bcm2835_thermal_probe, -- .remove = bcm2835_thermal_remove, -+ .remove_new = bcm2835_thermal_remove, - .driver = { - .name = "bcm2835_thermal", - .of_match_table = bcm2835_thermal_of_match_table, -diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig -index b694d7669d320..1eb755a94940a 100644 ---- a/drivers/video/Kconfig -+++ b/drivers/video/Kconfig -@@ -11,6 +11,10 @@ config APERTURE_HELPERS - Support tracking and hand-over of aperture ownership. Required - by graphics drivers for firmware-provided framebuffers. - -+config SCREEN_INFO -+ bool -+ default n -+ - config STI_CORE - bool - depends on PARISC -diff --git a/drivers/video/Makefile b/drivers/video/Makefile -index 6bbc039508995..6bbf87c1b579e 100644 ---- a/drivers/video/Makefile -+++ b/drivers/video/Makefile -@@ -1,12 +1,16 @@ - # SPDX-License-Identifier: GPL-2.0 - - obj-$(CONFIG_APERTURE_HELPERS) += aperture.o -+obj-$(CONFIG_SCREEN_INFO) += screen_info.o - obj-$(CONFIG_STI_CORE) += sticore.o - obj-$(CONFIG_VGASTATE) += vgastate.o - obj-$(CONFIG_VIDEO_CMDLINE) += cmdline.o - obj-$(CONFIG_VIDEO_NOMODESET) += nomodeset.o - obj-$(CONFIG_HDMI) += hdmi.o - -+screen_info-y := screen_info_generic.o -+screen_info-$(CONFIG_PCI) += screen_info_pci.o -+ - obj-$(CONFIG_VT) += console/ - obj-$(CONFIG_FB_STI) += console/ - obj-$(CONFIG_LOGO) += logo/ -diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c -index c0edceea0a793..a21581b40256c 100644 ---- a/drivers/video/fbdev/vesafb.c -+++ b/drivers/video/fbdev/vesafb.c -@@ -243,6 +243,7 @@ static int vesafb_setup(char *options) - - static int vesafb_probe(struct platform_device *dev) - { -+ struct screen_info *si = &screen_info; - struct fb_info *info; - struct vesafb_par *par; - int i, err; -@@ -255,17 +256,17 @@ static int vesafb_probe(struct platform_device *dev) - fb_get_options("vesafb", &option); - vesafb_setup(option); - -- if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) -+ if (si->orig_video_isVGA != VIDEO_TYPE_VLFB) - return -ENODEV; - -- vga_compat = (screen_info.capabilities & 2) ? 0 : 1; -- vesafb_fix.smem_start = screen_info.lfb_base; -- vesafb_defined.bits_per_pixel = screen_info.lfb_depth; -+ vga_compat = !__screen_info_vbe_mode_nonvga(si); -+ vesafb_fix.smem_start = si->lfb_base; -+ vesafb_defined.bits_per_pixel = si->lfb_depth; - if (15 == vesafb_defined.bits_per_pixel) - vesafb_defined.bits_per_pixel = 16; -- vesafb_defined.xres = screen_info.lfb_width; -- vesafb_defined.yres = screen_info.lfb_height; -- vesafb_fix.line_length = screen_info.lfb_linelength; -+ vesafb_defined.xres = si->lfb_width; -+ vesafb_defined.yres = si->lfb_height; -+ vesafb_fix.line_length = si->lfb_linelength; - vesafb_fix.visual = (vesafb_defined.bits_per_pixel == 8) ? - FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; - -@@ -277,7 +278,7 @@ static int vesafb_probe(struct platform_device *dev) - /* size_total -- all video memory we have. Used for mtrr - * entries, resource allocation and bounds - * checking. */ -- size_total = screen_info.lfb_size * 65536; -+ size_total = si->lfb_size * 65536; - if (vram_total) - size_total = vram_total * 1024 * 1024; - if (size_total < size_vmode) -@@ -297,7 +298,7 @@ static int vesafb_probe(struct platform_device *dev) - vesafb_fix.smem_len = size_remap; - - #ifndef __i386__ -- screen_info.vesapm_seg = 0; -+ si->vesapm_seg = 0; - #endif - - if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) { -@@ -317,23 +318,26 @@ static int vesafb_probe(struct platform_device *dev) - par = info->par; - info->pseudo_palette = par->pseudo_palette; - -- par->base = screen_info.lfb_base; -+ par->base = si->lfb_base; - par->size = size_total; - - printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", -- vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages); -+ vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, -+ vesafb_fix.line_length, si->pages); - -- if (screen_info.vesapm_seg) { -+ if (si->vesapm_seg) { - printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n", -- screen_info.vesapm_seg,screen_info.vesapm_off); -+ si->vesapm_seg, si->vesapm_off); - } - -- if (screen_info.vesapm_seg < 0xc000) -+ if (si->vesapm_seg < 0xc000) - ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */ - - if (ypan || pmi_setpal) { -+ unsigned long pmi_phys; - unsigned short *pmi_base; -- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); -+ pmi_phys = ((unsigned long)si->vesapm_seg << 4) + si->vesapm_off; -+ pmi_base = (unsigned short *)phys_to_virt(pmi_phys); - pmi_start = (void*)((char*)pmi_base + pmi_base[1]); - pmi_pal = (void*)((char*)pmi_base + pmi_base[2]); - printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal); -@@ -377,14 +381,14 @@ static int vesafb_probe(struct platform_device *dev) - vesafb_defined.left_margin = (vesafb_defined.xres / 8) & 0xf8; - vesafb_defined.hsync_len = (vesafb_defined.xres / 8) & 0xf8; - -- vesafb_defined.red.offset = screen_info.red_pos; -- vesafb_defined.red.length = screen_info.red_size; -- vesafb_defined.green.offset = screen_info.green_pos; -- vesafb_defined.green.length = screen_info.green_size; -- vesafb_defined.blue.offset = screen_info.blue_pos; -- vesafb_defined.blue.length = screen_info.blue_size; -- vesafb_defined.transp.offset = screen_info.rsvd_pos; -- vesafb_defined.transp.length = screen_info.rsvd_size; -+ vesafb_defined.red.offset = si->red_pos; -+ vesafb_defined.red.length = si->red_size; -+ vesafb_defined.green.offset = si->green_pos; -+ vesafb_defined.green.length = si->green_size; -+ vesafb_defined.blue.offset = si->blue_pos; -+ vesafb_defined.blue.length = si->blue_size; -+ vesafb_defined.transp.offset = si->rsvd_pos; -+ vesafb_defined.transp.length = si->rsvd_size; - - if (vesafb_defined.bits_per_pixel <= 8) { - depth = vesafb_defined.green.length; -@@ -399,14 +403,14 @@ static int vesafb_probe(struct platform_device *dev) - (vesafb_defined.bits_per_pixel > 8) ? - "Truecolor" : (vga_compat || pmi_setpal) ? - "Pseudocolor" : "Static Pseudocolor", -- screen_info.rsvd_size, -- screen_info.red_size, -- screen_info.green_size, -- screen_info.blue_size, -- screen_info.rsvd_pos, -- screen_info.red_pos, -- screen_info.green_pos, -- screen_info.blue_pos); -+ si->rsvd_size, -+ si->red_size, -+ si->green_size, -+ si->blue_size, -+ si->rsvd_pos, -+ si->red_pos, -+ si->green_pos, -+ si->blue_pos); - - vesafb_fix.ypanstep = ypan ? 1 : 0; - vesafb_fix.ywrapstep = (ypan>1) ? 1 : 0; -diff --git a/drivers/video/screen_info_generic.c b/drivers/video/screen_info_generic.c -new file mode 100644 -index 0000000000000..64117c6367abb ---- /dev/null -+++ b/drivers/video/screen_info_generic.c -@@ -0,0 +1,146 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+#include -+ -+static void resource_init_named(struct resource *r, -+ resource_size_t start, resource_size_t size, -+ const char *name, unsigned int flags) -+{ -+ memset(r, 0, sizeof(*r)); -+ -+ r->start = start; -+ r->end = start + size - 1; -+ r->name = name; -+ r->flags = flags; -+} -+ -+static void resource_init_io_named(struct resource *r, -+ resource_size_t start, resource_size_t size, -+ const char *name) -+{ -+ resource_init_named(r, start, size, name, IORESOURCE_IO); -+} -+ -+static void resource_init_mem_named(struct resource *r, -+ resource_size_t start, resource_size_t size, -+ const char *name) -+{ -+ resource_init_named(r, start, size, name, IORESOURCE_MEM); -+} -+ -+static inline bool __screen_info_has_ega_gfx(unsigned int mode) -+{ -+ switch (mode) { -+ case 0x0d: /* 320x200-4 */ -+ case 0x0e: /* 640x200-4 */ -+ case 0x0f: /* 640x350-1 */ -+ case 0x10: /* 640x350-4 */ -+ return true; -+ default: -+ return false; -+ } -+} -+ -+static inline bool __screen_info_has_vga_gfx(unsigned int mode) -+{ -+ switch (mode) { -+ case 0x10: /* 640x480-1 */ -+ case 0x12: /* 640x480-4 */ -+ case 0x13: /* 320-200-8 */ -+ case 0x6a: /* 800x600-4 (VESA) */ -+ return true; -+ default: -+ return __screen_info_has_ega_gfx(mode); -+ } -+} -+ -+/** -+ * screen_info_resources() - Get resources from screen_info structure -+ * @si: the screen_info -+ * @r: pointer to an array of resource structures -+ * @num: number of elements in @r: -+ * -+ * Returns: -+ * The number of resources stored in @r on success, or a negative errno code otherwise. -+ * -+ * A call to screen_info_resources() returns the resources consumed by the -+ * screen_info's device or framebuffer. The result is stored in the caller-supplied -+ * array @r with up to @num elements. The function returns the number of -+ * initialized elements. -+ */ -+ssize_t screen_info_resources(const struct screen_info *si, struct resource *r, size_t num) -+{ -+ struct resource *pos = r; -+ unsigned int type = screen_info_video_type(si); -+ u64 base, size; -+ -+ switch (type) { -+ case VIDEO_TYPE_MDA: -+ if (num > 0) -+ resource_init_io_named(pos++, 0x3b0, 12, "mda"); -+ if (num > 1) -+ resource_init_io_named(pos++, 0x3bf, 0x01, "mda"); -+ if (num > 2) -+ resource_init_mem_named(pos++, 0xb0000, 0x2000, "mda"); -+ break; -+ case VIDEO_TYPE_CGA: -+ if (num > 0) -+ resource_init_io_named(pos++, 0x3d4, 0x02, "cga"); -+ if (num > 1) -+ resource_init_mem_named(pos++, 0xb8000, 0x2000, "cga"); -+ break; -+ case VIDEO_TYPE_EGAM: -+ if (num > 0) -+ resource_init_io_named(pos++, 0x3bf, 0x10, "ega"); -+ if (num > 1) -+ resource_init_mem_named(pos++, 0xb0000, 0x8000, "ega"); -+ break; -+ case VIDEO_TYPE_EGAC: -+ if (num > 0) -+ resource_init_io_named(pos++, 0x3c0, 0x20, "ega"); -+ if (num > 1) { -+ if (__screen_info_has_ega_gfx(si->orig_video_mode)) -+ resource_init_mem_named(pos++, 0xa0000, 0x10000, "ega"); -+ else -+ resource_init_mem_named(pos++, 0xb8000, 0x8000, "ega"); -+ } -+ break; -+ case VIDEO_TYPE_VGAC: -+ if (num > 0) -+ resource_init_io_named(pos++, 0x3c0, 0x20, "vga+"); -+ if (num > 1) { -+ if (__screen_info_has_vga_gfx(si->orig_video_mode)) -+ resource_init_mem_named(pos++, 0xa0000, 0x10000, "vga+"); -+ else -+ resource_init_mem_named(pos++, 0xb8000, 0x8000, "vga+"); -+ } -+ break; -+ case VIDEO_TYPE_VLFB: -+ case VIDEO_TYPE_EFI: -+ base = __screen_info_lfb_base(si); -+ if (!base) -+ break; -+ size = __screen_info_lfb_size(si, type); -+ if (!size) -+ break; -+ if (num > 0) -+ resource_init_mem_named(pos++, base, size, "lfb"); -+ break; -+ case VIDEO_TYPE_PICA_S3: -+ case VIDEO_TYPE_MIPS_G364: -+ case VIDEO_TYPE_SGI: -+ case VIDEO_TYPE_TGAC: -+ case VIDEO_TYPE_SUN: -+ case VIDEO_TYPE_SUNPCI: -+ case VIDEO_TYPE_PMAC: -+ default: -+ /* not supported */ -+ return -EINVAL; -+ } -+ -+ return pos - r; -+} -+EXPORT_SYMBOL(screen_info_resources); -diff --git a/drivers/video/screen_info_pci.c b/drivers/video/screen_info_pci.c -new file mode 100644 -index 0000000000000..6c58335171410 ---- /dev/null -+++ b/drivers/video/screen_info_pci.c -@@ -0,0 +1,136 @@ -+// SPDX-License-Identifier: GPL-2.0 -+ -+#include -+#include -+#include -+#include -+ -+static struct pci_dev *screen_info_lfb_pdev; -+static size_t screen_info_lfb_bar; -+static resource_size_t screen_info_lfb_offset; -+static struct resource screen_info_lfb_res = DEFINE_RES_MEM(0, 0); -+ -+static bool __screen_info_relocation_is_valid(const struct screen_info *si, struct resource *pr) -+{ -+ u64 size = __screen_info_lfb_size(si, screen_info_video_type(si)); -+ -+ if (screen_info_lfb_offset > resource_size(pr)) -+ return false; -+ if (size > resource_size(pr)) -+ return false; -+ if (resource_size(pr) - size < screen_info_lfb_offset) -+ return false; -+ -+ return true; -+} -+ -+void screen_info_apply_fixups(void) -+{ -+ struct screen_info *si = &screen_info; -+ -+ if (screen_info_lfb_pdev) { -+ struct resource *pr = &screen_info_lfb_pdev->resource[screen_info_lfb_bar]; -+ -+ if (pr->start != screen_info_lfb_res.start) { -+ if (__screen_info_relocation_is_valid(si, pr)) { -+ /* -+ * Only update base if we have an actual -+ * relocation to a valid I/O range. -+ */ -+ __screen_info_set_lfb_base(si, pr->start + screen_info_lfb_offset); -+ pr_info("Relocating firmware framebuffer to offset %pa[d] within %pr\n", -+ &screen_info_lfb_offset, pr); -+ } else { -+ pr_warn("Invalid relocating, disabling firmware framebuffer\n"); -+ } -+ } -+ } -+} -+ -+static void screen_info_fixup_lfb(struct pci_dev *pdev) -+{ -+ unsigned int type; -+ struct resource res[SCREEN_INFO_MAX_RESOURCES]; -+ size_t i, numres; -+ int ret; -+ const struct screen_info *si = &screen_info; -+ -+ if (screen_info_lfb_pdev) -+ return; // already found -+ -+ type = screen_info_video_type(si); -+ if (type != VIDEO_TYPE_EFI) -+ return; // only applies to EFI -+ -+ ret = screen_info_resources(si, res, ARRAY_SIZE(res)); -+ if (ret < 0) -+ return; -+ numres = ret; -+ -+ for (i = 0; i < numres; ++i) { -+ struct resource *r = &res[i]; -+ const struct resource *pr; -+ -+ if (!(r->flags & IORESOURCE_MEM)) -+ continue; -+ pr = pci_find_resource(pdev, r); -+ if (!pr) -+ continue; -+ -+ /* -+ * We've found a PCI device with the framebuffer -+ * resource. Store away the parameters to track -+ * relocation of the framebuffer aperture. -+ */ -+ screen_info_lfb_pdev = pdev; -+ screen_info_lfb_bar = pr - pdev->resource; -+ screen_info_lfb_offset = r->start - pr->start; -+ memcpy(&screen_info_lfb_res, r, sizeof(screen_info_lfb_res)); -+ } -+} -+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY, 16, -+ screen_info_fixup_lfb); -+ -+static struct pci_dev *__screen_info_pci_dev(struct resource *res) -+{ -+ struct pci_dev *pdev = NULL; -+ const struct resource *r = NULL; -+ -+ if (!(res->flags & IORESOURCE_MEM)) -+ return NULL; -+ -+ while (!r && (pdev = pci_get_base_class(PCI_BASE_CLASS_DISPLAY, pdev))) { -+ r = pci_find_resource(pdev, res); -+ } -+ -+ return pdev; -+} -+ -+/** -+ * screen_info_pci_dev() - Return PCI parent device that contains screen_info's framebuffer -+ * @si: the screen_info -+ * -+ * Returns: -+ * The screen_info's parent device or NULL on success, or a pointer-encoded -+ * errno value otherwise. The value NULL is not an error. It signals that no -+ * PCI device has been found. -+ */ -+struct pci_dev *screen_info_pci_dev(const struct screen_info *si) -+{ -+ struct resource res[SCREEN_INFO_MAX_RESOURCES]; -+ ssize_t i, numres; -+ -+ numres = screen_info_resources(si, res, ARRAY_SIZE(res)); -+ if (numres < 0) -+ return ERR_PTR(numres); -+ -+ for (i = 0; i < numres; ++i) { -+ struct pci_dev *pdev = __screen_info_pci_dev(&res[i]); -+ -+ if (pdev) -+ return pdev; -+ } -+ -+ return NULL; -+} -+EXPORT_SYMBOL(screen_info_pci_dev); -diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c -index dd065349fae3a..4e999e1c14075 100644 ---- a/fs/btrfs/block-group.c -+++ b/fs/btrfs/block-group.c -@@ -1214,8 +1214,8 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, - block_group->space_info->total_bytes -= block_group->length; - block_group->space_info->bytes_readonly -= - (block_group->length - block_group->zone_unusable); -- block_group->space_info->bytes_zone_unusable -= -- block_group->zone_unusable; -+ btrfs_space_info_update_bytes_zone_unusable(fs_info, block_group->space_info, -+ -block_group->zone_unusable); - block_group->space_info->disk_total -= block_group->length * factor; - - spin_unlock(&block_group->space_info->lock); -@@ -1399,7 +1399,8 @@ static int inc_block_group_ro(struct btrfs_block_group *cache, int force) - if (btrfs_is_zoned(cache->fs_info)) { - /* Migrate zone_unusable bytes to readonly */ - sinfo->bytes_readonly += cache->zone_unusable; -- sinfo->bytes_zone_unusable -= cache->zone_unusable; -+ btrfs_space_info_update_bytes_zone_unusable(cache->fs_info, sinfo, -+ -cache->zone_unusable); - cache->zone_unusable = 0; - } - cache->ro++; -@@ -3023,9 +3024,11 @@ void btrfs_dec_block_group_ro(struct btrfs_block_group *cache) - if (btrfs_is_zoned(cache->fs_info)) { - /* Migrate zone_unusable bytes back */ - cache->zone_unusable = -- (cache->alloc_offset - cache->used) + -+ (cache->alloc_offset - cache->used - cache->pinned - -+ cache->reserved) + - (cache->length - cache->zone_capacity); -- sinfo->bytes_zone_unusable += cache->zone_unusable; -+ btrfs_space_info_update_bytes_zone_unusable(cache->fs_info, sinfo, -+ cache->zone_unusable); - sinfo->bytes_readonly -= cache->zone_unusable; - } - num_bytes = cache->length - cache->reserved - -diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c -index b89b558b15926..c6ecfd05e1db9 100644 ---- a/fs/btrfs/extent-tree.c -+++ b/fs/btrfs/extent-tree.c -@@ -2749,7 +2749,8 @@ static int unpin_extent_range(struct btrfs_fs_info *fs_info, - readonly = true; - } else if (btrfs_is_zoned(fs_info)) { - /* Need reset before reusing in a zoned block group */ -- space_info->bytes_zone_unusable += len; -+ btrfs_space_info_update_bytes_zone_unusable(fs_info, space_info, -+ len); - readonly = true; - } - spin_unlock(&cache->lock); -diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c -index dcfc0425115e9..f59e599766662 100644 ---- a/fs/btrfs/free-space-cache.c -+++ b/fs/btrfs/free-space-cache.c -@@ -2721,8 +2721,10 @@ static int __btrfs_add_free_space_zoned(struct btrfs_block_group *block_group, - * If the block group is read-only, we should account freed space into - * bytes_readonly. - */ -- if (!block_group->ro) -+ if (!block_group->ro) { - block_group->zone_unusable += to_unusable; -+ WARN_ON(block_group->zone_unusable > block_group->length); -+ } - spin_unlock(&ctl->tree_lock); - if (!used) { - spin_lock(&block_group->lock); -diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c -index 3f7a9605e2d3a..581bdd709ee0d 100644 ---- a/fs/btrfs/space-info.c -+++ b/fs/btrfs/space-info.c -@@ -312,7 +312,7 @@ void btrfs_add_bg_to_space_info(struct btrfs_fs_info *info, - found->bytes_used += block_group->used; - found->disk_used += block_group->used * factor; - found->bytes_readonly += block_group->bytes_super; -- found->bytes_zone_unusable += block_group->zone_unusable; -+ btrfs_space_info_update_bytes_zone_unusable(info, found, block_group->zone_unusable); - if (block_group->length > 0) - found->full = 0; - btrfs_try_granting_tickets(info, found); -@@ -524,8 +524,7 @@ void btrfs_dump_space_info(struct btrfs_fs_info *fs_info, - - spin_lock(&cache->lock); - avail = cache->length - cache->used - cache->pinned - -- cache->reserved - cache->delalloc_bytes - -- cache->bytes_super - cache->zone_unusable; -+ cache->reserved - cache->bytes_super - cache->zone_unusable; - btrfs_info(fs_info, - "block group %llu has %llu bytes, %llu used %llu pinned %llu reserved %llu delalloc %llu super %llu zone_unusable (%llu bytes available) %s", - cache->start, cache->length, cache->used, cache->pinned, -diff --git a/fs/btrfs/space-info.h b/fs/btrfs/space-info.h -index 0bb9d14e60a82..08a3bd10addcf 100644 ---- a/fs/btrfs/space-info.h -+++ b/fs/btrfs/space-info.h -@@ -197,6 +197,7 @@ btrfs_space_info_update_##name(struct btrfs_fs_info *fs_info, \ - - DECLARE_SPACE_INFO_UPDATE(bytes_may_use, "space_info"); - DECLARE_SPACE_INFO_UPDATE(bytes_pinned, "pinned"); -+DECLARE_SPACE_INFO_UPDATE(bytes_zone_unusable, "zone_unusable"); - - int btrfs_init_space_info(struct btrfs_fs_info *fs_info); - void btrfs_add_bg_to_space_info(struct btrfs_fs_info *info, -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index d5eb8d44c6c81..cef119a2476bb 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -453,6 +453,35 @@ static void ext4_map_blocks_es_recheck(handle_t *handle, - } - #endif /* ES_AGGRESSIVE_TEST */ - -+static int ext4_map_query_blocks(handle_t *handle, struct inode *inode, -+ struct ext4_map_blocks *map) -+{ -+ unsigned int status; -+ int retval; -+ -+ if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) -+ retval = ext4_ext_map_blocks(handle, inode, map, 0); -+ else -+ retval = ext4_ind_map_blocks(handle, inode, map, 0); -+ -+ if (retval <= 0) -+ return retval; -+ -+ if (unlikely(retval != map->m_len)) { -+ ext4_warning(inode->i_sb, -+ "ES len assertion failed for inode " -+ "%lu: retval %d != map->m_len %d", -+ inode->i_ino, retval, map->m_len); -+ WARN_ON(1); -+ } -+ -+ status = map->m_flags & EXT4_MAP_UNWRITTEN ? -+ EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; -+ ext4_es_insert_extent(inode, map->m_lblk, map->m_len, -+ map->m_pblk, status); -+ return retval; -+} -+ - /* - * The ext4_map_blocks() function tries to look up the requested blocks, - * and returns if the blocks are already mapped. -@@ -1705,12 +1734,10 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, - - /* Lookup extent status tree firstly */ - if (ext4_es_lookup_extent(inode, iblock, NULL, &es)) { -- if (ext4_es_is_hole(&es)) { -- retval = 0; -- down_read(&EXT4_I(inode)->i_data_sem); -+ if (ext4_es_is_hole(&es)) - goto add_delayed; -- } - -+found: - /* - * Delayed extent could be allocated by fallocate. - * So we need to check it. -@@ -1747,49 +1774,42 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, - down_read(&EXT4_I(inode)->i_data_sem); - if (ext4_has_inline_data(inode)) - retval = 0; -- else if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) -- retval = ext4_ext_map_blocks(NULL, inode, map, 0); - else -- retval = ext4_ind_map_blocks(NULL, inode, map, 0); -+ retval = ext4_map_query_blocks(NULL, inode, map); -+ up_read(&EXT4_I(inode)->i_data_sem); -+ if (retval) -+ return retval; - - add_delayed: -- if (retval == 0) { -- int ret; -- -- /* -- * XXX: __block_prepare_write() unmaps passed block, -- * is it OK? -- */ -- -- ret = ext4_insert_delayed_block(inode, map->m_lblk); -- if (ret != 0) { -- retval = ret; -- goto out_unlock; -+ down_write(&EXT4_I(inode)->i_data_sem); -+ /* -+ * Page fault path (ext4_page_mkwrite does not take i_rwsem) -+ * and fallocate path (no folio lock) can race. Make sure we -+ * lookup the extent status tree here again while i_data_sem -+ * is held in write mode, before inserting a new da entry in -+ * the extent status tree. -+ */ -+ if (ext4_es_lookup_extent(inode, iblock, NULL, &es)) { -+ if (!ext4_es_is_hole(&es)) { -+ up_write(&EXT4_I(inode)->i_data_sem); -+ goto found; - } -- -- map_bh(bh, inode->i_sb, invalid_block); -- set_buffer_new(bh); -- set_buffer_delay(bh); -- } else if (retval > 0) { -- unsigned int status; -- -- if (unlikely(retval != map->m_len)) { -- ext4_warning(inode->i_sb, -- "ES len assertion failed for inode " -- "%lu: retval %d != map->m_len %d", -- inode->i_ino, retval, map->m_len); -- WARN_ON(1); -+ } else if (!ext4_has_inline_data(inode)) { -+ retval = ext4_map_query_blocks(NULL, inode, map); -+ if (retval) { -+ up_write(&EXT4_I(inode)->i_data_sem); -+ return retval; - } -- -- status = map->m_flags & EXT4_MAP_UNWRITTEN ? -- EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; -- ext4_es_insert_extent(inode, map->m_lblk, map->m_len, -- map->m_pblk, status); - } - --out_unlock: -- up_read((&EXT4_I(inode)->i_data_sem)); -+ retval = ext4_insert_delayed_block(inode, map->m_lblk); -+ up_write(&EXT4_I(inode)->i_data_sem); -+ if (retval) -+ return retval; - -+ map_bh(bh, inode->i_sb, invalid_block); -+ set_buffer_new(bh); -+ set_buffer_delay(bh); - return retval; - } - -diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c -index 22080606b8769..804958c6de34c 100644 ---- a/fs/f2fs/segment.c -+++ b/fs/f2fs/segment.c -@@ -3350,7 +3350,9 @@ static int __get_segment_type_6(struct f2fs_io_info *fio) - if (page_private_gcing(fio->page)) { - if (fio->sbi->am.atgc_enabled && - (fio->io_type == FS_DATA_IO) && -- (fio->sbi->gc_mode != GC_URGENT_HIGH)) -+ (fio->sbi->gc_mode != GC_URGENT_HIGH) && -+ __is_valid_data_blkaddr(fio->old_blkaddr) && -+ !is_inode_flag_set(inode, FI_OPU_WRITE)) - return CURSEG_ALL_DATA_ATGC; - else - return CURSEG_COLD_DATA; -diff --git a/fs/file.c b/fs/file.c -index a815f6eddc511..b64a84137c00f 100644 ---- a/fs/file.c -+++ b/fs/file.c -@@ -1124,6 +1124,7 @@ __releases(&files->file_lock) - * tables and this condition does not arise without those. - */ - fdt = files_fdtable(files); -+ fd = array_index_nospec(fd, fdt->max_fds); - tofree = fdt->fd[fd]; - if (!tofree && fd_is_open(fd, fdt)) - goto Ebusy; -diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c -index 5b5cdc747cef3..071a71eb1a2d4 100644 ---- a/fs/proc/proc_sysctl.c -+++ b/fs/proc/proc_sysctl.c -@@ -480,12 +480,10 @@ static struct inode *proc_sys_make_inode(struct super_block *sb, - make_empty_dir_inode(inode); - } - -+ inode->i_uid = GLOBAL_ROOT_UID; -+ inode->i_gid = GLOBAL_ROOT_GID; - if (root->set_ownership) -- root->set_ownership(head, table, &inode->i_uid, &inode->i_gid); -- else { -- inode->i_uid = GLOBAL_ROOT_UID; -- inode->i_gid = GLOBAL_ROOT_GID; -- } -+ root->set_ownership(head, &inode->i_uid, &inode->i_gid); - - return inode; - } -diff --git a/include/linux/leds.h b/include/linux/leds.h -index aa16dc2a8230f..d3056bc6f0a1a 100644 ---- a/include/linux/leds.h -+++ b/include/linux/leds.h -@@ -474,6 +474,9 @@ struct led_trigger { - int (*activate)(struct led_classdev *led_cdev); - void (*deactivate)(struct led_classdev *led_cdev); - -+ /* Brightness set by led_trigger_event */ -+ enum led_brightness brightness; -+ - /* LED-private triggers have this set */ - struct led_hw_trigger_type *trigger_type; - -@@ -527,22 +530,11 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev) - return led_cdev->trigger_data; - } - --/** -- * led_trigger_rename_static - rename a trigger -- * @name: the new trigger name -- * @trig: the LED trigger to rename -- * -- * Change a LED trigger name by copying the string passed in -- * name into current trigger name, which MUST be large -- * enough for the new string. -- * -- * Note that name must NOT point to the same string used -- * during LED registration, as that could lead to races. -- * -- * This is meant to be used on triggers with statically -- * allocated name. -- */ --void led_trigger_rename_static(const char *name, struct led_trigger *trig); -+static inline enum led_brightness -+led_trigger_get_brightness(const struct led_trigger *trigger) -+{ -+ return trigger ? trigger->brightness : LED_OFF; -+} - - #define module_led_trigger(__led_trigger) \ - module_driver(__led_trigger, led_trigger_register, \ -@@ -580,6 +572,12 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev) - return NULL; - } - -+static inline enum led_brightness -+led_trigger_get_brightness(const struct led_trigger *trigger) -+{ -+ return LED_OFF; -+} -+ - #endif /* CONFIG_LEDS_TRIGGERS */ - - /* Trigger specific enum */ -diff --git a/include/linux/pci.h b/include/linux/pci.h -index f141300116219..7b18a4b3efb0e 100644 ---- a/include/linux/pci.h -+++ b/include/linux/pci.h -@@ -1182,6 +1182,8 @@ struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn); - struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus, - unsigned int devfn); - struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from); -+struct pci_dev *pci_get_base_class(unsigned int class, struct pci_dev *from); -+ - int pci_dev_present(const struct pci_device_id *ids); - - int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, -@@ -1958,6 +1960,9 @@ static inline struct pci_dev *pci_get_class(unsigned int class, - struct pci_dev *from) - { return NULL; } - -+static inline struct pci_dev *pci_get_base_class(unsigned int class, -+ struct pci_dev *from) -+{ return NULL; } - - static inline int pci_dev_present(const struct pci_device_id *ids) - { return 0; } -diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h -index eab7081392d50..6a4a3cec4638b 100644 ---- a/include/linux/screen_info.h -+++ b/include/linux/screen_info.h -@@ -4,6 +4,142 @@ - - #include - -+#include -+ -+/** -+ * SCREEN_INFO_MAX_RESOURCES - maximum number of resources per screen_info -+ */ -+#define SCREEN_INFO_MAX_RESOURCES 3 -+ -+struct pci_dev; -+struct resource; -+ -+static inline bool __screen_info_has_lfb(unsigned int type) -+{ -+ return (type == VIDEO_TYPE_VLFB) || (type == VIDEO_TYPE_EFI); -+} -+ -+static inline u64 __screen_info_lfb_base(const struct screen_info *si) -+{ -+ u64 lfb_base = si->lfb_base; -+ -+ if (si->capabilities & VIDEO_CAPABILITY_64BIT_BASE) -+ lfb_base |= (u64)si->ext_lfb_base << 32; -+ -+ return lfb_base; -+} -+ -+static inline void __screen_info_set_lfb_base(struct screen_info *si, u64 lfb_base) -+{ -+ si->lfb_base = lfb_base & GENMASK_ULL(31, 0); -+ si->ext_lfb_base = (lfb_base & GENMASK_ULL(63, 32)) >> 32; -+ -+ if (si->ext_lfb_base) -+ si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE; -+ else -+ si->capabilities &= ~VIDEO_CAPABILITY_64BIT_BASE; -+} -+ -+static inline u64 __screen_info_lfb_size(const struct screen_info *si, unsigned int type) -+{ -+ u64 lfb_size = si->lfb_size; -+ -+ if (type == VIDEO_TYPE_VLFB) -+ lfb_size <<= 16; -+ return lfb_size; -+} -+ -+static inline bool __screen_info_vbe_mode_nonvga(const struct screen_info *si) -+{ -+ /* -+ * VESA modes typically run on VGA hardware. Set bit 5 signals that this -+ * is not the case. Drivers can then not make use of VGA resources. See -+ * Sec 4.4 of the VBE 2.0 spec. -+ */ -+ return si->vesa_attributes & BIT(5); -+} -+ -+static inline unsigned int __screen_info_video_type(unsigned int type) -+{ -+ switch (type) { -+ case VIDEO_TYPE_MDA: -+ case VIDEO_TYPE_CGA: -+ case VIDEO_TYPE_EGAM: -+ case VIDEO_TYPE_EGAC: -+ case VIDEO_TYPE_VGAC: -+ case VIDEO_TYPE_VLFB: -+ case VIDEO_TYPE_PICA_S3: -+ case VIDEO_TYPE_MIPS_G364: -+ case VIDEO_TYPE_SGI: -+ case VIDEO_TYPE_TGAC: -+ case VIDEO_TYPE_SUN: -+ case VIDEO_TYPE_SUNPCI: -+ case VIDEO_TYPE_PMAC: -+ case VIDEO_TYPE_EFI: -+ return type; -+ default: -+ return 0; -+ } -+} -+ -+/** -+ * screen_info_video_type() - Decodes the video type from struct screen_info -+ * @si: an instance of struct screen_info -+ * -+ * Returns: -+ * A VIDEO_TYPE_ constant representing si's type of video display, or 0 otherwise. -+ */ -+static inline unsigned int screen_info_video_type(const struct screen_info *si) -+{ -+ unsigned int type; -+ -+ // check if display output is on -+ if (!si->orig_video_isVGA) -+ return 0; -+ -+ // check for a known VIDEO_TYPE_ constant -+ type = __screen_info_video_type(si->orig_video_isVGA); -+ if (type) -+ return si->orig_video_isVGA; -+ -+ // check if text mode has been initialized -+ if (!si->orig_video_lines || !si->orig_video_cols) -+ return 0; -+ -+ // 80x25 text, mono -+ if (si->orig_video_mode == 0x07) { -+ if ((si->orig_video_ega_bx & 0xff) != 0x10) -+ return VIDEO_TYPE_EGAM; -+ else -+ return VIDEO_TYPE_MDA; -+ } -+ -+ // EGA/VGA, 16 colors -+ if ((si->orig_video_ega_bx & 0xff) != 0x10) { -+ if (si->orig_video_isVGA) -+ return VIDEO_TYPE_VGAC; -+ else -+ return VIDEO_TYPE_EGAC; -+ } -+ -+ // the rest... -+ return VIDEO_TYPE_CGA; -+} -+ -+ssize_t screen_info_resources(const struct screen_info *si, struct resource *r, size_t num); -+ -+#if defined(CONFIG_PCI) -+void screen_info_apply_fixups(void); -+struct pci_dev *screen_info_pci_dev(const struct screen_info *si); -+#else -+static inline void screen_info_apply_fixups(void) -+{ } -+static inline struct pci_dev *screen_info_pci_dev(const struct screen_info *si) -+{ -+ return NULL; -+} -+#endif -+ - extern struct screen_info screen_info; - - #endif /* _SCREEN_INFO_H */ -diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h -index 61b40ea81f4d3..698a71422a14b 100644 ---- a/include/linux/sysctl.h -+++ b/include/linux/sysctl.h -@@ -205,7 +205,6 @@ struct ctl_table_root { - struct ctl_table_set default_set; - struct ctl_table_set *(*lookup)(struct ctl_table_root *root); - void (*set_ownership)(struct ctl_table_header *head, -- struct ctl_table *table, - kuid_t *uid, kgid_t *gid); - int (*permissions)(struct ctl_table_header *head, struct ctl_table *table); - }; -diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h -index b2db2c2f1c577..3c4d5ef6d4463 100644 ---- a/include/trace/events/btrfs.h -+++ b/include/trace/events/btrfs.h -@@ -2430,6 +2430,14 @@ DEFINE_EVENT(btrfs__space_info_update, update_bytes_pinned, - TP_ARGS(fs_info, sinfo, old, diff) - ); - -+DEFINE_EVENT(btrfs__space_info_update, update_bytes_zone_unusable, -+ -+ TP_PROTO(const struct btrfs_fs_info *fs_info, -+ const struct btrfs_space_info *sinfo, u64 old, s64 diff), -+ -+ TP_ARGS(fs_info, sinfo, old, diff) -+); -+ - DECLARE_EVENT_CLASS(btrfs_raid56_bio, - - TP_PROTO(const struct btrfs_raid_bio *rbio, -diff --git a/include/trace/events/mptcp.h b/include/trace/events/mptcp.h -index 563e48617374d..54e8fb5a229cd 100644 ---- a/include/trace/events/mptcp.h -+++ b/include/trace/events/mptcp.h -@@ -34,7 +34,7 @@ TRACE_EVENT(mptcp_subflow_get_send, - struct sock *ssk; - - __entry->active = mptcp_subflow_active(subflow); -- __entry->backup = subflow->backup; -+ __entry->backup = subflow->backup || subflow->request_bkup; - - if (subflow->tcp_sock && sk_fullsock(subflow->tcp_sock)) - __entry->free = sk_stream_memory_free(subflow->tcp_sock); -diff --git a/init/Kconfig b/init/Kconfig -index e403a29256357..e173364abd6c0 100644 ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -1898,6 +1898,7 @@ config RUST - depends on !MODVERSIONS - depends on !GCC_PLUGINS - depends on !RANDSTRUCT -+ depends on !SHADOW_CALL_STACK - depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE - help - Enables Rust support in the kernel. -diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c -index 8c62e443f78b3..b2f39a86f4734 100644 ---- a/ipc/ipc_sysctl.c -+++ b/ipc/ipc_sysctl.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include "util.h" - - static int proc_ipc_dointvec_minmax_orphans(struct ctl_table *table, int write, -@@ -190,25 +191,56 @@ static int set_is_seen(struct ctl_table_set *set) - return ¤t->nsproxy->ipc_ns->ipc_set == set; - } - -+static void ipc_set_ownership(struct ctl_table_header *head, -+ kuid_t *uid, kgid_t *gid) -+{ -+ struct ipc_namespace *ns = -+ container_of(head->set, struct ipc_namespace, ipc_set); -+ -+ kuid_t ns_root_uid = make_kuid(ns->user_ns, 0); -+ kgid_t ns_root_gid = make_kgid(ns->user_ns, 0); -+ -+ *uid = uid_valid(ns_root_uid) ? ns_root_uid : GLOBAL_ROOT_UID; -+ *gid = gid_valid(ns_root_gid) ? ns_root_gid : GLOBAL_ROOT_GID; -+} -+ - static int ipc_permissions(struct ctl_table_header *head, struct ctl_table *table) - { - int mode = table->mode; - - #ifdef CONFIG_CHECKPOINT_RESTORE -- struct ipc_namespace *ns = current->nsproxy->ipc_ns; -+ struct ipc_namespace *ns = -+ container_of(head->set, struct ipc_namespace, ipc_set); - - if (((table->data == &ns->ids[IPC_SEM_IDS].next_id) || - (table->data == &ns->ids[IPC_MSG_IDS].next_id) || - (table->data == &ns->ids[IPC_SHM_IDS].next_id)) && - checkpoint_restore_ns_capable(ns->user_ns)) - mode = 0666; -+ else - #endif -- return mode; -+ { -+ kuid_t ns_root_uid; -+ kgid_t ns_root_gid; -+ -+ ipc_set_ownership(head, &ns_root_uid, &ns_root_gid); -+ -+ if (uid_eq(current_euid(), ns_root_uid)) -+ mode >>= 6; -+ -+ else if (in_egroup_p(ns_root_gid)) -+ mode >>= 3; -+ } -+ -+ mode &= 7; -+ -+ return (mode << 6) | (mode << 3) | mode; - } - - static struct ctl_table_root set_root = { - .lookup = set_lookup, - .permissions = ipc_permissions, -+ .set_ownership = ipc_set_ownership, - }; - - bool setup_ipc_sysctls(struct ipc_namespace *ns) -diff --git a/ipc/mq_sysctl.c b/ipc/mq_sysctl.c -index ebb5ed81c151a..6bb1c5397c69b 100644 ---- a/ipc/mq_sysctl.c -+++ b/ipc/mq_sysctl.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - - static int msg_max_limit_min = MIN_MSGMAX; - static int msg_max_limit_max = HARD_MSGMAX; -@@ -76,8 +77,42 @@ static int set_is_seen(struct ctl_table_set *set) - return ¤t->nsproxy->ipc_ns->mq_set == set; - } - -+static void mq_set_ownership(struct ctl_table_header *head, -+ kuid_t *uid, kgid_t *gid) -+{ -+ struct ipc_namespace *ns = -+ container_of(head->set, struct ipc_namespace, mq_set); -+ -+ kuid_t ns_root_uid = make_kuid(ns->user_ns, 0); -+ kgid_t ns_root_gid = make_kgid(ns->user_ns, 0); -+ -+ *uid = uid_valid(ns_root_uid) ? ns_root_uid : GLOBAL_ROOT_UID; -+ *gid = gid_valid(ns_root_gid) ? ns_root_gid : GLOBAL_ROOT_GID; -+} -+ -+static int mq_permissions(struct ctl_table_header *head, struct ctl_table *table) -+{ -+ int mode = table->mode; -+ kuid_t ns_root_uid; -+ kgid_t ns_root_gid; -+ -+ mq_set_ownership(head, &ns_root_uid, &ns_root_gid); -+ -+ if (uid_eq(current_euid(), ns_root_uid)) -+ mode >>= 6; -+ -+ else if (in_egroup_p(ns_root_gid)) -+ mode >>= 3; -+ -+ mode &= 7; -+ -+ return (mode << 6) | (mode << 3) | mode; -+} -+ - static struct ctl_table_root set_root = { - .lookup = set_lookup, -+ .permissions = mq_permissions, -+ .set_ownership = mq_set_ownership, - }; - - bool setup_mq_sysctls(struct ipc_namespace *ns) -diff --git a/mm/Kconfig b/mm/Kconfig -index 264a2df5ecf5b..ece4f2847e2b4 100644 ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -704,6 +704,17 @@ config HUGETLB_PAGE_SIZE_VARIABLE - config CONTIG_ALLOC - def_bool (MEMORY_ISOLATION && COMPACTION) || CMA - -+config PCP_BATCH_SCALE_MAX -+ int "Maximum scale factor of PCP (Per-CPU pageset) batch allocate/free" -+ default 5 -+ range 0 6 -+ help -+ In page allocator, PCP (Per-CPU pageset) is refilled and drained in -+ batches. The batch number is scaled automatically to improve page -+ allocation/free throughput. But too large scale factor may hurt -+ latency. This option sets the upper limit of scale factor to limit -+ the maximum latency. -+ - config PHYS_ADDR_T_64BIT - def_bool 64BIT - -diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index e99d3223f0fc2..39bdbfb5313fb 100644 ---- a/mm/page_alloc.c -+++ b/mm/page_alloc.c -@@ -2185,14 +2185,21 @@ void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp) - */ - static void drain_pages_zone(unsigned int cpu, struct zone *zone) - { -- struct per_cpu_pages *pcp; -+ struct per_cpu_pages *pcp = per_cpu_ptr(zone->per_cpu_pageset, cpu); -+ int count; - -- pcp = per_cpu_ptr(zone->per_cpu_pageset, cpu); -- if (pcp->count) { -+ do { - spin_lock(&pcp->lock); -- free_pcppages_bulk(zone, pcp->count, pcp, 0); -+ count = pcp->count; -+ if (count) { -+ int to_drain = min(count, -+ pcp->batch << CONFIG_PCP_BATCH_SCALE_MAX); -+ -+ free_pcppages_bulk(zone, to_drain, pcp, 0); -+ count -= to_drain; -+ } - spin_unlock(&pcp->lock); -- } -+ } while (count); - } - - /* -@@ -2343,7 +2350,7 @@ static int nr_pcp_free(struct per_cpu_pages *pcp, int high, bool free_high) - * freeing of pages without any allocation. - */ - batch <<= pcp->free_factor; -- if (batch < max_nr_free) -+ if (batch < max_nr_free && pcp->free_factor < CONFIG_PCP_BATCH_SCALE_MAX) - pcp->free_factor++; - batch = clamp(batch, min_nr_free, max_nr_free); - -diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c -index b3f5714dab342..6dab0c99c82c7 100644 ---- a/net/bluetooth/hci_sync.c -+++ b/net/bluetooth/hci_sync.c -@@ -2862,6 +2862,27 @@ static int hci_passive_scan_sync(struct hci_dev *hdev) - */ - filter_policy = hci_update_accept_list_sync(hdev); - -+ /* If suspended and filter_policy set to 0x00 (no acceptlist) then -+ * passive scanning cannot be started since that would require the host -+ * to be woken up to process the reports. -+ */ -+ if (hdev->suspended && !filter_policy) { -+ /* Check if accept list is empty then there is no need to scan -+ * while suspended. -+ */ -+ if (list_empty(&hdev->le_accept_list)) -+ return 0; -+ -+ /* If there are devices is the accept_list that means some -+ * devices could not be programmed which in non-suspended case -+ * means filter_policy needs to be set to 0x00 so the host needs -+ * to filter, but since this is treating suspended case we -+ * can ignore device needing host to filter to allow devices in -+ * the acceptlist to be able to wakeup the system. -+ */ -+ filter_policy = 0x01; -+ } -+ - /* When the controller is using random resolvable addresses and - * with that having LE privacy enabled, then controllers with - * Extended Scanner Filter Policies support can now enable support -diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 7ea66de1442cc..8573dad6d8171 100644 ---- a/net/core/rtnetlink.c -+++ b/net/core/rtnetlink.c -@@ -3263,7 +3263,7 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, - if (ifm->ifi_index > 0) - dev = __dev_get_by_index(tgt_net, ifm->ifi_index); - else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) -- dev = rtnl_dev_get(net, tb); -+ dev = rtnl_dev_get(tgt_net, tb); - else if (tb[IFLA_GROUP]) - err = rtnl_group_dellink(tgt_net, nla_get_u32(tb[IFLA_GROUP])); - else -diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c -index 56f6ecc43451e..12ca666d6e2c1 100644 ---- a/net/ipv4/netfilter/iptable_nat.c -+++ b/net/ipv4/netfilter/iptable_nat.c -@@ -145,25 +145,27 @@ static struct pernet_operations iptable_nat_net_ops = { - - static int __init iptable_nat_init(void) - { -- int ret = xt_register_template(&nf_nat_ipv4_table, -- iptable_nat_table_init); -+ int ret; - -+ /* net->gen->ptr[iptable_nat_net_id] must be allocated -+ * before calling iptable_nat_table_init(). -+ */ -+ ret = register_pernet_subsys(&iptable_nat_net_ops); - if (ret < 0) - return ret; - -- ret = register_pernet_subsys(&iptable_nat_net_ops); -- if (ret < 0) { -- xt_unregister_template(&nf_nat_ipv4_table); -- return ret; -- } -+ ret = xt_register_template(&nf_nat_ipv4_table, -+ iptable_nat_table_init); -+ if (ret < 0) -+ unregister_pernet_subsys(&iptable_nat_net_ops); - - return ret; - } - - static void __exit iptable_nat_exit(void) - { -- unregister_pernet_subsys(&iptable_nat_net_ops); - xt_unregister_template(&nf_nat_ipv4_table); -+ unregister_pernet_subsys(&iptable_nat_net_ops); - } - - module_init(iptable_nat_init); -diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c -index 3b4dafefb4b03..e143562077958 100644 ---- a/net/ipv4/syncookies.c -+++ b/net/ipv4/syncookies.c -@@ -424,7 +424,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb) - } - - /* Try to redo what tcp_v4_send_synack did. */ -- req->rsk_window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW); -+ req->rsk_window_clamp = READ_ONCE(tp->window_clamp) ? : -+ dst_metric(&rt->dst, RTAX_WINDOW); - /* limit the window selection if the user enforce a smaller rx buffer */ - full_space = tcp_full_space(sk); - if (sk->sk_userlocks & SOCK_RCVBUF_LOCK && -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index 91c3d8264059d..1e3202f2b7a87 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -1723,7 +1723,7 @@ int tcp_set_rcvlowat(struct sock *sk, int val) - space = tcp_space_from_win(sk, val); - if (space > sk->sk_rcvbuf) { - WRITE_ONCE(sk->sk_rcvbuf, space); -- tcp_sk(sk)->window_clamp = val; -+ WRITE_ONCE(tcp_sk(sk)->window_clamp, val); - } - return 0; - } -@@ -3386,7 +3386,7 @@ int tcp_set_window_clamp(struct sock *sk, int val) - if (!val) { - if (sk->sk_state != TCP_CLOSE) - return -EINVAL; -- tp->window_clamp = 0; -+ WRITE_ONCE(tp->window_clamp, 0); - } else { - u32 new_rcv_ssthresh, old_window_clamp = tp->window_clamp; - u32 new_window_clamp = val < SOCK_MIN_RCVBUF / 2 ? -@@ -3395,7 +3395,7 @@ int tcp_set_window_clamp(struct sock *sk, int val) - if (new_window_clamp == old_window_clamp) - return 0; - -- tp->window_clamp = new_window_clamp; -+ WRITE_ONCE(tp->window_clamp, new_window_clamp); - if (new_window_clamp < old_window_clamp) { - /* need to apply the reserved mem provisioning only - * when shrinking the window clamp -@@ -4020,7 +4020,7 @@ int do_tcp_getsockopt(struct sock *sk, int level, - TCP_RTO_MAX / HZ); - break; - case TCP_WINDOW_CLAMP: -- val = tp->window_clamp; -+ val = READ_ONCE(tp->window_clamp); - break; - case TCP_INFO: { - struct tcp_info info; -diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c -index c2e4dac42453b..d0364cff65c9f 100644 ---- a/net/ipv4/tcp_input.c -+++ b/net/ipv4/tcp_input.c -@@ -570,19 +570,20 @@ static void tcp_init_buffer_space(struct sock *sk) - maxwin = tcp_full_space(sk); - - if (tp->window_clamp >= maxwin) { -- tp->window_clamp = maxwin; -+ WRITE_ONCE(tp->window_clamp, maxwin); - - if (tcp_app_win && maxwin > 4 * tp->advmss) -- tp->window_clamp = max(maxwin - -- (maxwin >> tcp_app_win), -- 4 * tp->advmss); -+ WRITE_ONCE(tp->window_clamp, -+ max(maxwin - (maxwin >> tcp_app_win), -+ 4 * tp->advmss)); - } - - /* Force reservation of one segment. */ - if (tcp_app_win && - tp->window_clamp > 2 * tp->advmss && - tp->window_clamp + tp->advmss > maxwin) -- tp->window_clamp = max(2 * tp->advmss, maxwin - tp->advmss); -+ WRITE_ONCE(tp->window_clamp, -+ max(2 * tp->advmss, maxwin - tp->advmss)); - - tp->rcv_ssthresh = min(tp->rcv_ssthresh, tp->window_clamp); - tp->snd_cwnd_stamp = tcp_jiffies32; -@@ -747,8 +748,7 @@ void tcp_rcv_space_adjust(struct sock *sk) - * - */ - -- if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_moderate_rcvbuf) && -- !(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) { -+ if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_moderate_rcvbuf)) { - u64 rcvwin, grow; - int rcvbuf; - -@@ -764,11 +764,22 @@ void tcp_rcv_space_adjust(struct sock *sk) - - rcvbuf = min_t(u64, tcp_space_from_win(sk, rcvwin), - READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2])); -- if (rcvbuf > sk->sk_rcvbuf) { -- WRITE_ONCE(sk->sk_rcvbuf, rcvbuf); -+ if (!(sk->sk_userlocks & SOCK_RCVBUF_LOCK)) { -+ if (rcvbuf > sk->sk_rcvbuf) { -+ WRITE_ONCE(sk->sk_rcvbuf, rcvbuf); - -- /* Make the window clamp follow along. */ -- tp->window_clamp = tcp_win_from_space(sk, rcvbuf); -+ /* Make the window clamp follow along. */ -+ WRITE_ONCE(tp->window_clamp, -+ tcp_win_from_space(sk, rcvbuf)); -+ } -+ } else { -+ /* Make the window clamp follow along while being bounded -+ * by SO_RCVBUF. -+ */ -+ int clamp = tcp_win_from_space(sk, min(rcvbuf, sk->sk_rcvbuf)); -+ -+ if (clamp > tp->window_clamp) -+ WRITE_ONCE(tp->window_clamp, clamp); - } - } - tp->rcvq_space.space = copied; -@@ -6347,7 +6358,8 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, - - if (!tp->rx_opt.wscale_ok) { - tp->rx_opt.snd_wscale = tp->rx_opt.rcv_wscale = 0; -- tp->window_clamp = min(tp->window_clamp, 65535U); -+ WRITE_ONCE(tp->window_clamp, -+ min(tp->window_clamp, 65535U)); - } - - if (tp->rx_opt.saw_tstamp) { -diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c -index 5631041ae12cb..15c49d559db53 100644 ---- a/net/ipv4/tcp_output.c -+++ b/net/ipv4/tcp_output.c -@@ -203,16 +203,17 @@ static inline void tcp_event_ack_sent(struct sock *sk, u32 rcv_nxt) - * This MUST be enforced by all callers. - */ - void tcp_select_initial_window(const struct sock *sk, int __space, __u32 mss, -- __u32 *rcv_wnd, __u32 *window_clamp, -+ __u32 *rcv_wnd, __u32 *__window_clamp, - int wscale_ok, __u8 *rcv_wscale, - __u32 init_rcv_wnd) - { - unsigned int space = (__space < 0 ? 0 : __space); -+ u32 window_clamp = READ_ONCE(*__window_clamp); - - /* If no clamp set the clamp to the max possible scaled window */ -- if (*window_clamp == 0) -- (*window_clamp) = (U16_MAX << TCP_MAX_WSCALE); -- space = min(*window_clamp, space); -+ if (window_clamp == 0) -+ window_clamp = (U16_MAX << TCP_MAX_WSCALE); -+ space = min(window_clamp, space); - - /* Quantize space offering to a multiple of mss if possible. */ - if (space > mss) -@@ -239,12 +240,13 @@ void tcp_select_initial_window(const struct sock *sk, int __space, __u32 mss, - /* Set window scaling on max possible window */ - space = max_t(u32, space, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2])); - space = max_t(u32, space, READ_ONCE(sysctl_rmem_max)); -- space = min_t(u32, space, *window_clamp); -+ space = min_t(u32, space, window_clamp); - *rcv_wscale = clamp_t(int, ilog2(space) - 15, - 0, TCP_MAX_WSCALE); - } - /* Set the clamp no higher than max representable value */ -- (*window_clamp) = min_t(__u32, U16_MAX << (*rcv_wscale), *window_clamp); -+ WRITE_ONCE(*__window_clamp, -+ min_t(__u32, U16_MAX << (*rcv_wscale), window_clamp)); - } - EXPORT_SYMBOL(tcp_select_initial_window); - -@@ -3787,7 +3789,7 @@ static void tcp_connect_init(struct sock *sk) - tcp_ca_dst_init(sk, dst); - - if (!tp->window_clamp) -- tp->window_clamp = dst_metric(dst, RTAX_WINDOW); -+ WRITE_ONCE(tp->window_clamp, dst_metric(dst, RTAX_WINDOW)); - tp->advmss = tcp_mss_clamp(tp, dst_metric_advmss(dst)); - - tcp_initialize_rcv_mss(sk); -@@ -3795,7 +3797,7 @@ static void tcp_connect_init(struct sock *sk) - /* limit the window selection if the user enforce a smaller rx buffer */ - if (sk->sk_userlocks & SOCK_RCVBUF_LOCK && - (tp->window_clamp > tcp_full_space(sk) || tp->window_clamp == 0)) -- tp->window_clamp = tcp_full_space(sk); -+ WRITE_ONCE(tp->window_clamp, tcp_full_space(sk)); - - rcv_wnd = tcp_rwnd_init_bpf(sk); - if (rcv_wnd == 0) -diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c -index 68debc78189c2..2062ab94721e3 100644 ---- a/net/ipv6/ndisc.c -+++ b/net/ipv6/ndisc.c -@@ -227,6 +227,7 @@ struct ndisc_options *ndisc_parse_options(const struct net_device *dev, - return NULL; - memset(ndopts, 0, sizeof(*ndopts)); - while (opt_len) { -+ bool unknown = false; - int l; - if (opt_len < sizeof(struct nd_opt_hdr)) - return NULL; -@@ -262,22 +263,23 @@ struct ndisc_options *ndisc_parse_options(const struct net_device *dev, - break; - #endif - default: -- if (ndisc_is_useropt(dev, nd_opt)) { -- ndopts->nd_useropts_end = nd_opt; -- if (!ndopts->nd_useropts) -- ndopts->nd_useropts = nd_opt; -- } else { -- /* -- * Unknown options must be silently ignored, -- * to accommodate future extension to the -- * protocol. -- */ -- ND_PRINTK(2, notice, -- "%s: ignored unsupported option; type=%d, len=%d\n", -- __func__, -- nd_opt->nd_opt_type, -- nd_opt->nd_opt_len); -- } -+ unknown = true; -+ } -+ if (ndisc_is_useropt(dev, nd_opt)) { -+ ndopts->nd_useropts_end = nd_opt; -+ if (!ndopts->nd_useropts) -+ ndopts->nd_useropts = nd_opt; -+ } else if (unknown) { -+ /* -+ * Unknown options must be silently ignored, -+ * to accommodate future extension to the -+ * protocol. -+ */ -+ ND_PRINTK(2, notice, -+ "%s: ignored unsupported option; type=%d, len=%d\n", -+ __func__, -+ nd_opt->nd_opt_type, -+ nd_opt->nd_opt_len); - } - next_opt: - opt_len -= l; -diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c -index bf3cb3a13600c..52d597b16b658 100644 ---- a/net/ipv6/netfilter/ip6table_nat.c -+++ b/net/ipv6/netfilter/ip6table_nat.c -@@ -147,23 +147,27 @@ static struct pernet_operations ip6table_nat_net_ops = { - - static int __init ip6table_nat_init(void) - { -- int ret = xt_register_template(&nf_nat_ipv6_table, -- ip6table_nat_table_init); -+ int ret; - -+ /* net->gen->ptr[ip6table_nat_net_id] must be allocated -+ * before calling ip6t_nat_register_lookups(). -+ */ -+ ret = register_pernet_subsys(&ip6table_nat_net_ops); - if (ret < 0) - return ret; - -- ret = register_pernet_subsys(&ip6table_nat_net_ops); -+ ret = xt_register_template(&nf_nat_ipv6_table, -+ ip6table_nat_table_init); - if (ret) -- xt_unregister_template(&nf_nat_ipv6_table); -+ unregister_pernet_subsys(&ip6table_nat_net_ops); - - return ret; - } - - static void __exit ip6table_nat_exit(void) - { -- unregister_pernet_subsys(&ip6table_nat_net_ops); - xt_unregister_template(&nf_nat_ipv6_table); -+ unregister_pernet_subsys(&ip6table_nat_net_ops); - } - - module_init(ip6table_nat_init); -diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c -index 8698b49dfc8de..593ead8a45d79 100644 ---- a/net/ipv6/syncookies.c -+++ b/net/ipv6/syncookies.c -@@ -243,7 +243,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) - goto out_free; - } - -- req->rsk_window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); -+ req->rsk_window_clamp = READ_ONCE(tp->window_clamp) ? :dst_metric(dst, RTAX_WINDOW); - /* limit the window selection if the user enforce a smaller rx buffer */ - full_space = tcp_full_space(sk); - if (sk->sk_userlocks & SOCK_RCVBUF_LOCK && -diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c -index 498a0c35b7bb2..815b1df0b2d19 100644 ---- a/net/iucv/af_iucv.c -+++ b/net/iucv/af_iucv.c -@@ -335,8 +335,8 @@ static void iucv_sever_path(struct sock *sk, int with_user_data) - struct iucv_sock *iucv = iucv_sk(sk); - struct iucv_path *path = iucv->path; - -- if (iucv->path) { -- iucv->path = NULL; -+ /* Whoever resets the path pointer, must sever and free it. */ -+ if (xchg(&iucv->path, NULL)) { - if (with_user_data) { - low_nmcpy(user_data, iucv->src_name); - high_nmcpy(user_data, iucv->dst_name); -diff --git a/net/mptcp/mib.c b/net/mptcp/mib.c -index c30405e768337..7884217f33eb2 100644 ---- a/net/mptcp/mib.c -+++ b/net/mptcp/mib.c -@@ -19,7 +19,9 @@ static const struct snmp_mib mptcp_snmp_list[] = { - SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS), - SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN), - SNMP_MIB_ITEM("MPJoinSynRx", MPTCP_MIB_JOINSYNRX), -+ SNMP_MIB_ITEM("MPJoinSynBackupRx", MPTCP_MIB_JOINSYNBACKUPRX), - SNMP_MIB_ITEM("MPJoinSynAckRx", MPTCP_MIB_JOINSYNACKRX), -+ SNMP_MIB_ITEM("MPJoinSynAckBackupRx", MPTCP_MIB_JOINSYNACKBACKUPRX), - SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC), - SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX), - SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC), -diff --git a/net/mptcp/mib.h b/net/mptcp/mib.h -index dd7fd1f246b5f..443604462ace8 100644 ---- a/net/mptcp/mib.h -+++ b/net/mptcp/mib.h -@@ -12,7 +12,9 @@ enum linux_mptcp_mib_field { - MPTCP_MIB_RETRANSSEGS, /* Segments retransmitted at the MPTCP-level */ - MPTCP_MIB_JOINNOTOKEN, /* Received MP_JOIN but the token was not found */ - MPTCP_MIB_JOINSYNRX, /* Received a SYN + MP_JOIN */ -+ MPTCP_MIB_JOINSYNBACKUPRX, /* Received a SYN + MP_JOIN + backup flag */ - MPTCP_MIB_JOINSYNACKRX, /* Received a SYN/ACK + MP_JOIN */ -+ MPTCP_MIB_JOINSYNACKBACKUPRX, /* Received a SYN/ACK + MP_JOIN + backup flag */ - MPTCP_MIB_JOINSYNACKMAC, /* HMAC was wrong on SYN/ACK + MP_JOIN */ - MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */ - MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */ -diff --git a/net/mptcp/options.c b/net/mptcp/options.c -index 63fc0758c22d4..85aafa94cc8ab 100644 ---- a/net/mptcp/options.c -+++ b/net/mptcp/options.c -@@ -909,7 +909,7 @@ bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, - return true; - } else if (subflow_req->mp_join) { - opts->suboptions = OPTION_MPTCP_MPJ_SYNACK; -- opts->backup = subflow_req->backup; -+ opts->backup = subflow_req->request_bkup; - opts->join_id = subflow_req->local_id; - opts->thmac = subflow_req->thmac; - opts->nonce = subflow_req->local_nonce; -diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c -index f58bf77d76b81..db621933b2035 100644 ---- a/net/mptcp/pm_netlink.c -+++ b/net/mptcp/pm_netlink.c -@@ -476,7 +476,6 @@ static void __mptcp_pm_send_ack(struct mptcp_sock *msk, struct mptcp_subflow_con - slow = lock_sock_fast(ssk); - if (prio) { - subflow->send_mp_prio = 1; -- subflow->backup = backup; - subflow->request_bkup = backup; - } - -@@ -1432,6 +1431,7 @@ static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk, - ret = remove_anno_list_by_saddr(msk, addr); - if (ret || force) { - spin_lock_bh(&msk->pm.lock); -+ msk->pm.add_addr_signaled -= ret; - mptcp_pm_remove_addr(msk, &list); - spin_unlock_bh(&msk->pm.lock); - } -@@ -1565,16 +1565,25 @@ void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list) - { - struct mptcp_rm_list alist = { .nr = 0 }; - struct mptcp_pm_addr_entry *entry; -+ int anno_nr = 0; - - list_for_each_entry(entry, rm_list, list) { -- if ((remove_anno_list_by_saddr(msk, &entry->addr) || -- lookup_subflow_by_saddr(&msk->conn_list, &entry->addr)) && -- alist.nr < MPTCP_RM_IDS_MAX) -- alist.ids[alist.nr++] = entry->addr.id; -+ if (alist.nr >= MPTCP_RM_IDS_MAX) -+ break; -+ -+ /* only delete if either announced or matching a subflow */ -+ if (remove_anno_list_by_saddr(msk, &entry->addr)) -+ anno_nr++; -+ else if (!lookup_subflow_by_saddr(&msk->conn_list, -+ &entry->addr)) -+ continue; -+ -+ alist.ids[alist.nr++] = entry->addr.id; - } - - if (alist.nr) { - spin_lock_bh(&msk->pm.lock); -+ msk->pm.add_addr_signaled -= anno_nr; - mptcp_pm_remove_addr(msk, &alist); - spin_unlock_bh(&msk->pm.lock); - } -@@ -1587,17 +1596,18 @@ void mptcp_pm_remove_addrs_and_subflows(struct mptcp_sock *msk, - struct mptcp_pm_addr_entry *entry; - - list_for_each_entry(entry, rm_list, list) { -- if (lookup_subflow_by_saddr(&msk->conn_list, &entry->addr) && -- slist.nr < MPTCP_RM_IDS_MAX) -+ if (slist.nr < MPTCP_RM_IDS_MAX && -+ lookup_subflow_by_saddr(&msk->conn_list, &entry->addr)) - slist.ids[slist.nr++] = entry->addr.id; - -- if (remove_anno_list_by_saddr(msk, &entry->addr) && -- alist.nr < MPTCP_RM_IDS_MAX) -+ if (alist.nr < MPTCP_RM_IDS_MAX && -+ remove_anno_list_by_saddr(msk, &entry->addr)) - alist.ids[alist.nr++] = entry->addr.id; - } - - if (alist.nr) { - spin_lock_bh(&msk->pm.lock); -+ msk->pm.add_addr_signaled -= alist.nr; - mptcp_pm_remove_addr(msk, &alist); - spin_unlock_bh(&msk->pm.lock); - } -diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c -index fbf2b26760731..c1d652a3f7a9b 100644 ---- a/net/mptcp/protocol.c -+++ b/net/mptcp/protocol.c -@@ -352,8 +352,10 @@ static bool __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk, - skb_orphan(skb); - - /* try to fetch required memory from subflow */ -- if (!mptcp_rmem_schedule(sk, ssk, skb->truesize)) -+ if (!mptcp_rmem_schedule(sk, ssk, skb->truesize)) { -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RCVPRUNED); - goto drop; -+ } - - has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp; - -@@ -842,16 +844,13 @@ void mptcp_data_ready(struct sock *sk, struct sock *ssk) - sk_rbuf = ssk_rbuf; - - /* over limit? can't append more skbs to msk, Also, no need to wake-up*/ -- if (__mptcp_rmem(sk) > sk_rbuf) { -- MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RCVPRUNED); -+ if (__mptcp_rmem(sk) > sk_rbuf) - return; -- } - - /* Wake-up the reader only for in-sequence data */ - mptcp_data_lock(sk); -- if (move_skbs_to_msk(msk, ssk)) -+ if (move_skbs_to_msk(msk, ssk) && mptcp_epollin_ready(sk)) - sk->sk_data_ready(sk); -- - mptcp_data_unlock(sk); - } - -@@ -1418,13 +1417,15 @@ struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk) - } - - mptcp_for_each_subflow(msk, subflow) { -+ bool backup = subflow->backup || subflow->request_bkup; -+ - trace_mptcp_subflow_get_send(subflow); - ssk = mptcp_subflow_tcp_sock(subflow); - if (!mptcp_subflow_active(subflow)) - continue; - - tout = max(tout, mptcp_timeout_from_subflow(subflow)); -- nr_active += !subflow->backup; -+ nr_active += !backup; - pace = subflow->avg_pacing_rate; - if (unlikely(!pace)) { - /* init pacing rate from socket */ -@@ -1435,9 +1436,9 @@ struct sock *mptcp_subflow_get_send(struct mptcp_sock *msk) - } - - linger_time = div_u64((u64)READ_ONCE(ssk->sk_wmem_queued) << 32, pace); -- if (linger_time < send_info[subflow->backup].linger_time) { -- send_info[subflow->backup].ssk = ssk; -- send_info[subflow->backup].linger_time = linger_time; -+ if (linger_time < send_info[backup].linger_time) { -+ send_info[backup].ssk = ssk; -+ send_info[backup].linger_time = linger_time; - } - } - __mptcp_set_timeout(sk, tout); -@@ -1918,6 +1919,7 @@ static int __mptcp_recvmsg_mskq(struct mptcp_sock *msk, - if (!(flags & MSG_PEEK)) { - MPTCP_SKB_CB(skb)->offset += count; - MPTCP_SKB_CB(skb)->map_seq += count; -+ msk->bytes_consumed += count; - } - break; - } -@@ -1928,6 +1930,7 @@ static int __mptcp_recvmsg_mskq(struct mptcp_sock *msk, - WRITE_ONCE(msk->rmem_released, msk->rmem_released + skb->truesize); - __skb_unlink(skb, &msk->receive_queue); - __kfree_skb(skb); -+ msk->bytes_consumed += count; - } - - if (copied >= len) -@@ -2023,7 +2026,7 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied) - ssk = mptcp_subflow_tcp_sock(subflow); - slow = lock_sock_fast(ssk); - WRITE_ONCE(ssk->sk_rcvbuf, rcvbuf); -- tcp_sk(ssk)->window_clamp = window_clamp; -+ WRITE_ONCE(tcp_sk(ssk)->window_clamp, window_clamp); - tcp_cleanup_rbuf(ssk, 1); - unlock_sock_fast(ssk, slow); - } -@@ -2752,6 +2755,7 @@ static void __mptcp_init_sock(struct sock *sk) - msk->rmem_fwd_alloc = 0; - WRITE_ONCE(msk->rmem_released, 0); - msk->timer_ival = TCP_RTO_MIN; -+ msk->scaling_ratio = TCP_DEFAULT_SCALING_RATIO; - - WRITE_ONCE(msk->first, NULL); - inet_csk(sk)->icsk_sync_mss = mptcp_sync_mss; -@@ -2984,16 +2988,9 @@ void __mptcp_unaccepted_force_close(struct sock *sk) - __mptcp_destroy_sock(sk); - } - --static __poll_t mptcp_check_readable(struct mptcp_sock *msk) -+static __poll_t mptcp_check_readable(struct sock *sk) - { -- /* Concurrent splices from sk_receive_queue into receive_queue will -- * always show at least one non-empty queue when checked in this order. -- */ -- if (skb_queue_empty_lockless(&((struct sock *)msk)->sk_receive_queue) && -- skb_queue_empty_lockless(&msk->receive_queue)) -- return 0; -- -- return EPOLLIN | EPOLLRDNORM; -+ return mptcp_epollin_ready(sk) ? EPOLLIN | EPOLLRDNORM : 0; - } - - static void mptcp_check_listen_stop(struct sock *sk) -@@ -3031,7 +3028,7 @@ bool __mptcp_close(struct sock *sk, long timeout) - goto cleanup; - } - -- if (mptcp_check_readable(msk) || timeout < 0) { -+ if (mptcp_data_avail(msk) || timeout < 0) { - /* If the msk has read data, or the caller explicitly ask it, - * do the MPTCP equivalent of TCP reset, aka MPTCP fastclose - */ -@@ -3157,6 +3154,7 @@ static int mptcp_disconnect(struct sock *sk, int flags) - msk->snd_data_fin_enable = false; - msk->rcv_fastclose = false; - msk->use_64bit_ack = false; -+ msk->bytes_consumed = 0; - WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk))); - mptcp_pm_data_reset(msk); - mptcp_ca_reset(sk); -@@ -3983,7 +3981,7 @@ static __poll_t mptcp_poll(struct file *file, struct socket *sock, - mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP; - - if (state != TCP_SYN_SENT && state != TCP_SYN_RECV) { -- mask |= mptcp_check_readable(msk); -+ mask |= mptcp_check_readable(sk); - if (shutdown & SEND_SHUTDOWN) - mask |= EPOLLOUT | EPOLLWRNORM; - else -@@ -4021,6 +4019,7 @@ static const struct proto_ops mptcp_stream_ops = { - .sendmsg = inet_sendmsg, - .recvmsg = inet_recvmsg, - .mmap = sock_no_mmap, -+ .set_rcvlowat = mptcp_set_rcvlowat, - }; - - static struct inet_protosw mptcp_protosw = { -@@ -4122,6 +4121,7 @@ static const struct proto_ops mptcp_v6_stream_ops = { - #ifdef CONFIG_COMPAT - .compat_ioctl = inet6_compat_ioctl, - #endif -+ .set_rcvlowat = mptcp_set_rcvlowat, - }; - - static struct proto mptcp_v6_prot; -diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h -index 93ba48f4ae386..c28ac5dfd0b58 100644 ---- a/net/mptcp/protocol.h -+++ b/net/mptcp/protocol.h -@@ -268,6 +268,7 @@ struct mptcp_sock { - atomic64_t rcv_wnd_sent; - u64 rcv_data_fin_seq; - u64 bytes_retrans; -+ u64 bytes_consumed; - int rmem_fwd_alloc; - int snd_burst; - int old_wspace; -@@ -418,6 +419,7 @@ struct mptcp_subflow_request_sock { - u16 mp_capable : 1, - mp_join : 1, - backup : 1, -+ request_bkup : 1, - csum_reqd : 1, - allow_join_id0 : 1; - u8 local_id; -@@ -674,6 +676,24 @@ struct sock *mptcp_subflow_get_retrans(struct mptcp_sock *msk); - int mptcp_sched_get_send(struct mptcp_sock *msk); - int mptcp_sched_get_retrans(struct mptcp_sock *msk); - -+static inline u64 mptcp_data_avail(const struct mptcp_sock *msk) -+{ -+ return READ_ONCE(msk->bytes_received) - READ_ONCE(msk->bytes_consumed); -+} -+ -+static inline bool mptcp_epollin_ready(const struct sock *sk) -+{ -+ /* mptcp doesn't have to deal with small skbs in the receive queue, -+ * at it can always coalesce them -+ */ -+ return (mptcp_data_avail(mptcp_sk(sk)) >= sk->sk_rcvlowat) || -+ (mem_cgroup_sockets_enabled && sk->sk_memcg && -+ mem_cgroup_under_socket_pressure(sk->sk_memcg)) || -+ READ_ONCE(tcp_memory_pressure); -+} -+ -+int mptcp_set_rcvlowat(struct sock *sk, int val); -+ - static inline bool __tcp_can_send(const struct sock *ssk) - { - /* only send if our side has not closed yet */ -@@ -748,6 +768,7 @@ static inline bool mptcp_is_fully_established(struct sock *sk) - return inet_sk_state_load(sk) == TCP_ESTABLISHED && - READ_ONCE(mptcp_sk(sk)->fully_established); - } -+ - void mptcp_rcv_space_init(struct mptcp_sock *msk, const struct sock *ssk); - void mptcp_data_ready(struct sock *sk, struct sock *ssk); - bool mptcp_finish_join(struct sock *sk); -diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c -index cc04b5e29dd35..bdfeecea814f3 100644 ---- a/net/mptcp/sockopt.c -+++ b/net/mptcp/sockopt.c -@@ -1521,9 +1521,55 @@ void mptcp_sockopt_sync_locked(struct mptcp_sock *msk, struct sock *ssk) - - msk_owned_by_me(msk); - -+ ssk->sk_rcvlowat = 0; -+ - if (READ_ONCE(subflow->setsockopt_seq) != msk->setsockopt_seq) { - sync_socket_options(msk, ssk); - - subflow->setsockopt_seq = msk->setsockopt_seq; - } - } -+ -+/* unfortunately this is different enough from the tcp version so -+ * that we can't factor it out -+ */ -+int mptcp_set_rcvlowat(struct sock *sk, int val) -+{ -+ struct mptcp_subflow_context *subflow; -+ int space, cap; -+ -+ /* bpf can land here with a wrong sk type */ -+ if (sk->sk_protocol == IPPROTO_TCP) -+ return -EINVAL; -+ -+ if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) -+ cap = sk->sk_rcvbuf >> 1; -+ else -+ cap = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2]) >> 1; -+ val = min(val, cap); -+ WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); -+ -+ /* Check if we need to signal EPOLLIN right now */ -+ if (mptcp_epollin_ready(sk)) -+ sk->sk_data_ready(sk); -+ -+ if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) -+ return 0; -+ -+ space = __tcp_space_from_win(mptcp_sk(sk)->scaling_ratio, val); -+ if (space <= sk->sk_rcvbuf) -+ return 0; -+ -+ /* propagate the rcvbuf changes to all the subflows */ -+ WRITE_ONCE(sk->sk_rcvbuf, space); -+ mptcp_for_each_subflow(mptcp_sk(sk), subflow) { -+ struct sock *ssk = mptcp_subflow_tcp_sock(subflow); -+ bool slow; -+ -+ slow = lock_sock_fast(ssk); -+ WRITE_ONCE(ssk->sk_rcvbuf, space); -+ WRITE_ONCE(tcp_sk(ssk)->window_clamp, val); -+ unlock_sock_fast(ssk, slow); -+ } -+ return 0; -+} -diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c -index 23ee96c6abcbf..bc1efc1787720 100644 ---- a/net/mptcp/subflow.c -+++ b/net/mptcp/subflow.c -@@ -166,6 +166,9 @@ static int subflow_check_req(struct request_sock *req, - return 0; - } else if (opt_mp_join) { - SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINSYNRX); -+ -+ if (mp_opt.backup) -+ SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINSYNBACKUPRX); - } - - if (opt_mp_capable && listener->request_mptcp) { -@@ -558,6 +561,9 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb) - subflow->mp_join = 1; - MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKRX); - -+ if (subflow->backup) -+ MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_JOINSYNACKBACKUPRX); -+ - if (subflow_use_different_dport(msk, sk)) { - pr_debug("synack inet_dport=%d %d", - ntohs(inet_sk(sk)->inet_dport), -@@ -1192,14 +1198,22 @@ static void mptcp_subflow_discard_data(struct sock *ssk, struct sk_buff *skb, - { - struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); - bool fin = TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN; -- u32 incr; -+ struct tcp_sock *tp = tcp_sk(ssk); -+ u32 offset, incr, avail_len; -+ -+ offset = tp->copied_seq - TCP_SKB_CB(skb)->seq; -+ if (WARN_ON_ONCE(offset > skb->len)) -+ goto out; - -- incr = limit >= skb->len ? skb->len + fin : limit; -+ avail_len = skb->len - offset; -+ incr = limit >= avail_len ? avail_len + fin : limit; - -- pr_debug("discarding=%d len=%d seq=%d", incr, skb->len, -- subflow->map_subflow_seq); -+ pr_debug("discarding=%d len=%d offset=%d seq=%d", incr, skb->len, -+ offset, subflow->map_subflow_seq); - MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DUPDATA); - tcp_sk(ssk)->copied_seq += incr; -+ -+out: - if (!before(tcp_sk(ssk)->copied_seq, TCP_SKB_CB(skb)->end_seq)) - sk_eat_skb(ssk, skb); - if (mptcp_subflow_get_map_offset(subflow) >= subflow->map_data_len) -@@ -1432,10 +1446,18 @@ static void subflow_data_ready(struct sock *sk) - WARN_ON_ONCE(!__mptcp_check_fallback(msk) && !subflow->mp_capable && - !subflow->mp_join && !(state & TCPF_CLOSE)); - -- if (mptcp_subflow_data_available(sk)) -+ if (mptcp_subflow_data_available(sk)) { - mptcp_data_ready(parent, sk); -- else if (unlikely(sk->sk_err)) -+ -+ /* subflow-level lowat test are not relevant. -+ * respect the msk-level threshold eventually mandating an immediate ack -+ */ -+ if (mptcp_data_avail(msk) < parent->sk_rcvlowat && -+ (tcp_sk(sk)->rcv_nxt - tcp_sk(sk)->rcv_wup) > inet_csk(sk)->icsk_ack.rcv_mss) -+ inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW; -+ } else if (unlikely(sk->sk_err)) { - subflow_error_report(sk); -+ } - } - - static void subflow_write_space(struct sock *ssk) -@@ -1968,6 +1990,7 @@ static void subflow_ulp_clone(const struct request_sock *req, - new_ctx->fully_established = 1; - new_ctx->remote_key_valid = 1; - new_ctx->backup = subflow_req->backup; -+ new_ctx->request_bkup = subflow_req->request_bkup; - WRITE_ONCE(new_ctx->remote_id, subflow_req->remote_id); - new_ctx->token = subflow_req->token; - new_ctx->thmac = subflow_req->thmac; -diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c -index 3ac19516ed803..50d24e240e8fb 100644 ---- a/net/sched/act_ct.c -+++ b/net/sched/act_ct.c -@@ -44,6 +44,8 @@ static DEFINE_MUTEX(zones_mutex); - struct zones_ht_key { - struct net *net; - u16 zone; -+ /* Note : pad[] must be the last field. */ -+ u8 pad[]; - }; - - struct tcf_ct_flow_table { -@@ -60,7 +62,7 @@ struct tcf_ct_flow_table { - static const struct rhashtable_params zones_params = { - .head_offset = offsetof(struct tcf_ct_flow_table, node), - .key_offset = offsetof(struct tcf_ct_flow_table, key), -- .key_len = sizeof_field(struct tcf_ct_flow_table, key), -+ .key_len = offsetof(struct zones_ht_key, pad), - .automatic_shrinking = true, - }; - -diff --git a/net/sysctl_net.c b/net/sysctl_net.c -index 051ed5f6fc937..a0a7a79991f9f 100644 ---- a/net/sysctl_net.c -+++ b/net/sysctl_net.c -@@ -54,7 +54,6 @@ static int net_ctl_permissions(struct ctl_table_header *head, - } - - static void net_ctl_set_ownership(struct ctl_table_header *head, -- struct ctl_table *table, - kuid_t *uid, kgid_t *gid) - { - struct net *net = container_of(head->set, struct net, sysctls); -diff --git a/net/wireless/sme.c b/net/wireless/sme.c -index 9bba233b5a6ec..72d78dbc55ffd 100644 ---- a/net/wireless/sme.c -+++ b/net/wireless/sme.c -@@ -1057,6 +1057,7 @@ void cfg80211_connect_done(struct net_device *dev, - cfg80211_hold_bss( - bss_from_pub(params->links[link].bss)); - ev->cr.links[link].bss = params->links[link].bss; -+ ev->cr.links[link].status = params->links[link].status; - - if (params->links[link].addr) { - ev->cr.links[link].addr = next; -diff --git a/sound/core/seq/seq_ump_convert.c b/sound/core/seq/seq_ump_convert.c -index e90b27a135e6f..d9dacfbe4a9ae 100644 ---- a/sound/core/seq/seq_ump_convert.c -+++ b/sound/core/seq/seq_ump_convert.c -@@ -1192,44 +1192,53 @@ static int cvt_sysex_to_ump(struct snd_seq_client *dest, - { - struct snd_seq_ump_event ev_cvt; - unsigned char status; -- u8 buf[6], *xbuf; -+ u8 buf[8], *xbuf; - int offset = 0; - int len, err; -+ bool finished = false; - - if (!snd_seq_ev_is_variable(event)) - return 0; - - setup_ump_event(&ev_cvt, event); -- for (;;) { -+ while (!finished) { - len = snd_seq_expand_var_event_at(event, sizeof(buf), buf, offset); - if (len <= 0) - break; -- if (WARN_ON(len > 6)) -+ if (WARN_ON(len > sizeof(buf))) - break; -- offset += len; -+ - xbuf = buf; -+ status = UMP_SYSEX_STATUS_CONTINUE; -+ /* truncate the sysex start-marker */ - if (*xbuf == UMP_MIDI1_MSG_SYSEX_START) { - status = UMP_SYSEX_STATUS_START; -- xbuf++; - len--; -- if (len > 0 && xbuf[len - 1] == UMP_MIDI1_MSG_SYSEX_END) { -+ offset++; -+ xbuf++; -+ } -+ -+ /* if the last of this packet or the 1st byte of the next packet -+ * is the end-marker, finish the transfer with this packet -+ */ -+ if (len > 0 && len < 8 && -+ xbuf[len - 1] == UMP_MIDI1_MSG_SYSEX_END) { -+ if (status == UMP_SYSEX_STATUS_START) - status = UMP_SYSEX_STATUS_SINGLE; -- len--; -- } -- } else { -- if (xbuf[len - 1] == UMP_MIDI1_MSG_SYSEX_END) { -+ else - status = UMP_SYSEX_STATUS_END; -- len--; -- } else { -- status = UMP_SYSEX_STATUS_CONTINUE; -- } -+ len--; -+ finished = true; - } -+ -+ len = min(len, 6); - fill_sysex7_ump(dest_port, ev_cvt.ump, status, xbuf, len); - err = __snd_seq_deliver_single_event(dest, dest_port, - (struct snd_seq_event *)&ev_cvt, - atomic, hop); - if (err < 0) - return err; -+ offset += len; - } - return 0; - } -diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c -index c9f153f85ae6b..5f0f8d9c08d1e 100644 ---- a/sound/firewire/amdtp-stream.c -+++ b/sound/firewire/amdtp-stream.c -@@ -77,6 +77,8 @@ - // overrun. Actual device can skip more, then this module stops the packet streaming. - #define IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES 5 - -+static void pcm_period_work(struct work_struct *work); -+ - /** - * amdtp_stream_init - initialize an AMDTP stream structure - * @s: the AMDTP stream to initialize -@@ -105,6 +107,7 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, - s->flags = flags; - s->context = ERR_PTR(-1); - mutex_init(&s->mutex); -+ INIT_WORK(&s->period_work, pcm_period_work); - s->packet_index = 0; - - init_waitqueue_head(&s->ready_wait); -@@ -347,6 +350,7 @@ EXPORT_SYMBOL(amdtp_stream_get_max_payload); - */ - void amdtp_stream_pcm_prepare(struct amdtp_stream *s) - { -+ cancel_work_sync(&s->period_work); - s->pcm_buffer_pointer = 0; - s->pcm_period_pointer = 0; - } -@@ -611,19 +615,21 @@ static void update_pcm_pointers(struct amdtp_stream *s, - // The program in user process should periodically check the status of intermediate - // buffer associated to PCM substream to process PCM frames in the buffer, instead - // of receiving notification of period elapsed by poll wait. -- if (!pcm->runtime->no_period_wakeup) { -- if (in_softirq()) { -- // In software IRQ context for 1394 OHCI. -- snd_pcm_period_elapsed(pcm); -- } else { -- // In process context of ALSA PCM application under acquired lock of -- // PCM substream. -- snd_pcm_period_elapsed_under_stream_lock(pcm); -- } -- } -+ if (!pcm->runtime->no_period_wakeup) -+ queue_work(system_highpri_wq, &s->period_work); - } - } - -+static void pcm_period_work(struct work_struct *work) -+{ -+ struct amdtp_stream *s = container_of(work, struct amdtp_stream, -+ period_work); -+ struct snd_pcm_substream *pcm = READ_ONCE(s->pcm); -+ -+ if (pcm) -+ snd_pcm_period_elapsed(pcm); -+} -+ - static int queue_packet(struct amdtp_stream *s, struct fw_iso_packet *params, - bool sched_irq) - { -@@ -1852,11 +1858,14 @@ unsigned long amdtp_domain_stream_pcm_pointer(struct amdtp_domain *d, - { - struct amdtp_stream *irq_target = d->irq_target; - -- // Process isochronous packets queued till recent isochronous cycle to handle PCM frames. - if (irq_target && amdtp_stream_running(irq_target)) { -- // In software IRQ context, the call causes dead-lock to disable the tasklet -- // synchronously. -- if (!in_softirq()) -+ // use wq to prevent AB/BA deadlock competition for -+ // substream lock: -+ // fw_iso_context_flush_completions() acquires -+ // lock by ohci_flush_iso_completions(), -+ // amdtp-stream process_rx_packets() attempts to -+ // acquire same lock by snd_pcm_elapsed() -+ if (current_work() != &s->period_work) - fw_iso_context_flush_completions(irq_target->context); - } - -@@ -1912,6 +1921,7 @@ static void amdtp_stream_stop(struct amdtp_stream *s) - return; - } - -+ cancel_work_sync(&s->period_work); - fw_iso_context_stop(s->context); - fw_iso_context_destroy(s->context); - s->context = ERR_PTR(-1); -diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h -index a1ed2e80f91a7..775db3fc4959f 100644 ---- a/sound/firewire/amdtp-stream.h -+++ b/sound/firewire/amdtp-stream.h -@@ -191,6 +191,7 @@ struct amdtp_stream { - - /* For a PCM substream processing. */ - struct snd_pcm_substream *pcm; -+ struct work_struct period_work; - snd_pcm_uframes_t pcm_buffer_pointer; - unsigned int pcm_period_pointer; - unsigned int pcm_frame_multiplier; -diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h -index 8556031bcd68e..f31cb31d46362 100644 ---- a/sound/pci/hda/hda_controller.h -+++ b/sound/pci/hda/hda_controller.h -@@ -28,7 +28,7 @@ - #else - #define AZX_DCAPS_I915_COMPONENT 0 /* NOP */ - #endif --/* 14 unused */ -+#define AZX_DCAPS_AMD_ALLOC_FIX (1 << 14) /* AMD allocation workaround */ - #define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ - #define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */ - #define AZX_DCAPS_AMD_WORKAROUND (1 << 17) /* AMD-specific workaround */ -diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c -index a6a9d353fe635..d5c9f113e477a 100644 ---- a/sound/pci/hda/hda_intel.c -+++ b/sound/pci/hda/hda_intel.c -@@ -40,6 +40,7 @@ - - #ifdef CONFIG_X86 - /* for snoop control */ -+#include - #include - #include - #endif -@@ -301,7 +302,7 @@ enum { - - /* quirks for ATI HDMI with snoop off */ - #define AZX_DCAPS_PRESET_ATI_HDMI_NS \ -- (AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_SNOOP_OFF) -+ (AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_AMD_ALLOC_FIX) - - /* quirks for AMD SB */ - #define AZX_DCAPS_PRESET_AMD_SB \ -@@ -1715,6 +1716,13 @@ static void azx_check_snoop_available(struct azx *chip) - if (chip->driver_caps & AZX_DCAPS_SNOOP_OFF) - snoop = false; - -+#ifdef CONFIG_X86 -+ /* check the presence of DMA ops (i.e. IOMMU), disable snoop conditionally */ -+ if ((chip->driver_caps & AZX_DCAPS_AMD_ALLOC_FIX) && -+ !get_dma_ops(chip->card->dev)) -+ snoop = false; -+#endif -+ - chip->snoop = snoop; - if (!snoop) { - dev_info(chip->card->dev, "Force to non-snoop mode\n"); -diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c -index e8209178d87bb..af921364195e4 100644 ---- a/sound/pci/hda/patch_conexant.c -+++ b/sound/pci/hda/patch_conexant.c -@@ -21,12 +21,6 @@ - #include "hda_jack.h" - #include "hda_generic.h" - --enum { -- CX_HEADSET_NOPRESENT = 0, -- CX_HEADSET_PARTPRESENT, -- CX_HEADSET_ALLPRESENT, --}; -- - struct conexant_spec { - struct hda_gen_spec gen; - -@@ -48,7 +42,6 @@ struct conexant_spec { - unsigned int gpio_led; - unsigned int gpio_mute_led_mask; - unsigned int gpio_mic_led_mask; -- unsigned int headset_present_flag; - bool is_cx8070_sn6140; - }; - -@@ -250,48 +243,19 @@ static void cx_process_headset_plugin(struct hda_codec *codec) - } - } - --static void cx_update_headset_mic_vref(struct hda_codec *codec, unsigned int res) -+static void cx_update_headset_mic_vref(struct hda_codec *codec, struct hda_jack_callback *event) - { -- unsigned int phone_present, mic_persent, phone_tag, mic_tag; -- struct conexant_spec *spec = codec->spec; -+ unsigned int mic_present; - - /* In cx8070 and sn6140, the node 16 can only be config to headphone or disabled, - * the node 19 can only be config to microphone or disabled. - * Check hp&mic tag to process headset pulgin&plugout. - */ -- phone_tag = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0); -- mic_tag = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_UNSOLICITED_RESPONSE, 0x0); -- if ((phone_tag & (res >> AC_UNSOL_RES_TAG_SHIFT)) || -- (mic_tag & (res >> AC_UNSOL_RES_TAG_SHIFT))) { -- phone_present = snd_hda_codec_read(codec, 0x16, 0, AC_VERB_GET_PIN_SENSE, 0x0); -- if (!(phone_present & AC_PINSENSE_PRESENCE)) {/* headphone plugout */ -- spec->headset_present_flag = CX_HEADSET_NOPRESENT; -- snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20); -- return; -- } -- if (spec->headset_present_flag == CX_HEADSET_NOPRESENT) { -- spec->headset_present_flag = CX_HEADSET_PARTPRESENT; -- } else if (spec->headset_present_flag == CX_HEADSET_PARTPRESENT) { -- mic_persent = snd_hda_codec_read(codec, 0x19, 0, -- AC_VERB_GET_PIN_SENSE, 0x0); -- /* headset is present */ -- if ((phone_present & AC_PINSENSE_PRESENCE) && -- (mic_persent & AC_PINSENSE_PRESENCE)) { -- cx_process_headset_plugin(codec); -- spec->headset_present_flag = CX_HEADSET_ALLPRESENT; -- } -- } -- } --} -- --static void cx_jack_unsol_event(struct hda_codec *codec, unsigned int res) --{ -- struct conexant_spec *spec = codec->spec; -- -- if (spec->is_cx8070_sn6140) -- cx_update_headset_mic_vref(codec, res); -- -- snd_hda_jack_unsol_event(codec, res); -+ mic_present = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0x0); -+ if (!(mic_present & AC_PINSENSE_PRESENCE)) /* mic plugout */ -+ snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20); -+ else -+ cx_process_headset_plugin(codec); - } - - #ifdef CONFIG_PM -@@ -307,7 +271,7 @@ static const struct hda_codec_ops cx_auto_patch_ops = { - .build_pcms = snd_hda_gen_build_pcms, - .init = cx_auto_init, - .free = cx_auto_free, -- .unsol_event = cx_jack_unsol_event, -+ .unsol_event = snd_hda_jack_unsol_event, - #ifdef CONFIG_PM - .suspend = cx_auto_suspend, - .check_power_status = snd_hda_gen_check_power_status, -@@ -1167,7 +1131,7 @@ static int patch_conexant_auto(struct hda_codec *codec) - case 0x14f11f86: - case 0x14f11f87: - spec->is_cx8070_sn6140 = true; -- spec->headset_present_flag = CX_HEADSET_NOPRESENT; -+ snd_hda_jack_detect_enable_callback(codec, 0x19, cx_update_headset_mic_vref); - break; - } - -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index f3aca1c38b77d..0b33a00771450 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -9639,6 +9639,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS), - SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC), - SND_PCI_QUIRK(0x1025, 0x0840, "Acer Aspire E1", ALC269VB_FIXUP_ASPIRE_E1_COEF), -+ SND_PCI_QUIRK(0x1025, 0x100c, "Acer Aspire E5-574G", ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST), - SND_PCI_QUIRK(0x1025, 0x101c, "Acer Veriton N2510G", ALC269_FIXUP_LIFEBOOK), - SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0x1025, 0x1065, "Acer Aspire C20-820", ALC269VC_FIXUP_ACER_HEADSET_MIC), -diff --git a/sound/usb/stream.c b/sound/usb/stream.c -index d5409f3879455..e14c725acebf2 100644 ---- a/sound/usb/stream.c -+++ b/sound/usb/stream.c -@@ -244,8 +244,8 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits, - SNDRV_CHMAP_FR, /* right front */ - SNDRV_CHMAP_FC, /* center front */ - SNDRV_CHMAP_LFE, /* LFE */ -- SNDRV_CHMAP_SL, /* left surround */ -- SNDRV_CHMAP_SR, /* right surround */ -+ SNDRV_CHMAP_RL, /* left surround */ -+ SNDRV_CHMAP_RR, /* right surround */ - SNDRV_CHMAP_FLC, /* left of center */ - SNDRV_CHMAP_FRC, /* right of center */ - SNDRV_CHMAP_RC, /* surround */ -diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c -index aee937d14fbbf..09e6b4e1401c9 100644 ---- a/tools/perf/util/callchain.c -+++ b/tools/perf/util/callchain.c -@@ -1126,7 +1126,7 @@ int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *samp - int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *node, - bool hide_unresolved) - { -- struct machine *machine = maps__machine(node->ms.maps); -+ struct machine *machine = node->ms.maps ? maps__machine(node->ms.maps) : NULL; - - maps__put(al->maps); - al->maps = maps__get(node->ms.maps); -diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c -index d2043ec3bf6d6..4209b95690394 100644 ---- a/tools/testing/selftests/net/mptcp/mptcp_connect.c -+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c -@@ -1115,11 +1115,11 @@ int main_loop_s(int listensock) - return 1; - } - -- if (--cfg_repeat > 0) { -- if (cfg_input) -- close(fd); -+ if (cfg_input) -+ close(fd); -+ -+ if (--cfg_repeat > 0) - goto again; -- } - - return 0; - } -diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh -index 231a95a8de9ee..a2dae2a3a93e0 100755 ---- a/tools/testing/selftests/net/mptcp/mptcp_join.sh -+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh -@@ -1778,6 +1778,8 @@ chk_prio_nr() - { - local mp_prio_nr_tx=$1 - local mp_prio_nr_rx=$2 -+ local mpj_syn=$3 -+ local mpj_syn_ack=$4 - local count - - print_check "ptx" -@@ -1799,6 +1801,26 @@ chk_prio_nr() - else - print_ok - fi -+ -+ print_check "syn backup" -+ count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinSynBackupRx") -+ if [ -z "$count" ]; then -+ print_skip -+ elif [ "$count" != "$mpj_syn" ]; then -+ fail_test "got $count JOIN[s] syn with Backup expected $mpj_syn" -+ else -+ print_ok -+ fi -+ -+ print_check "synack backup" -+ count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinSynAckBackupRx") -+ if [ -z "$count" ]; then -+ print_skip -+ elif [ "$count" != "$mpj_syn_ack" ]; then -+ fail_test "got $count JOIN[s] synack with Backup expected $mpj_syn_ack" -+ else -+ print_ok -+ fi - } - - chk_subflow_nr() -@@ -2751,11 +2773,24 @@ backup_tests() - sflags=nobackup speed=slow \ - run_tests $ns1 $ns2 10.0.1.1 - chk_join_nr 1 1 1 -- chk_prio_nr 0 1 -+ chk_prio_nr 0 1 1 0 - fi - - # single address, backup - if reset "single address, backup" && -+ continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then -+ pm_nl_set_limits $ns1 0 1 -+ pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup -+ pm_nl_set_limits $ns2 1 1 -+ sflags=nobackup speed=slow \ -+ run_tests $ns1 $ns2 10.0.1.1 -+ chk_join_nr 1 1 1 -+ chk_add_nr 1 1 -+ chk_prio_nr 1 0 0 1 -+ fi -+ -+ # single address, switch to backup -+ if reset "single address, switch to backup" && - continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then - pm_nl_set_limits $ns1 0 1 - pm_nl_add_endpoint $ns1 10.0.2.1 flags signal -@@ -2764,20 +2799,20 @@ backup_tests() - run_tests $ns1 $ns2 10.0.1.1 - chk_join_nr 1 1 1 - chk_add_nr 1 1 -- chk_prio_nr 1 1 -+ chk_prio_nr 1 1 0 0 - fi - - # single address with port, backup - if reset "single address with port, backup" && - continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then - pm_nl_set_limits $ns1 0 1 -- pm_nl_add_endpoint $ns1 10.0.2.1 flags signal port 10100 -+ pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,backup port 10100 - pm_nl_set_limits $ns2 1 1 -- sflags=backup speed=slow \ -+ sflags=nobackup speed=slow \ - run_tests $ns1 $ns2 10.0.1.1 - chk_join_nr 1 1 1 - chk_add_nr 1 1 -- chk_prio_nr 1 1 -+ chk_prio_nr 1 0 0 1 - fi - - if reset "mpc backup" && -@@ -2786,17 +2821,26 @@ backup_tests() - speed=slow \ - run_tests $ns1 $ns2 10.0.1.1 - chk_join_nr 0 0 0 -- chk_prio_nr 0 1 -+ chk_prio_nr 0 1 0 0 - fi - - if reset "mpc backup both sides" && - continue_if mptcp_lib_kallsyms_doesnt_have "T mptcp_subflow_send_ack$"; then -- pm_nl_add_endpoint $ns1 10.0.1.1 flags subflow,backup -+ pm_nl_set_limits $ns1 0 2 -+ pm_nl_set_limits $ns2 1 2 -+ pm_nl_add_endpoint $ns1 10.0.1.1 flags signal,backup - pm_nl_add_endpoint $ns2 10.0.1.2 flags subflow,backup -+ -+ # 10.0.2.2 (non-backup) -> 10.0.1.1 (backup) -+ pm_nl_add_endpoint $ns2 10.0.2.2 flags subflow -+ # 10.0.1.2 (backup) -> 10.0.2.1 (non-backup) -+ pm_nl_add_endpoint $ns1 10.0.2.1 flags signal -+ ip -net "$ns2" route add 10.0.2.1 via 10.0.1.1 dev ns2eth1 # force this path -+ - speed=slow \ - run_tests $ns1 $ns2 10.0.1.1 -- chk_join_nr 0 0 0 -- chk_prio_nr 1 1 -+ chk_join_nr 2 2 2 -+ chk_prio_nr 1 1 1 1 - fi - - if reset "mpc switch to backup" && -@@ -2805,7 +2849,7 @@ backup_tests() - sflags=backup speed=slow \ - run_tests $ns1 $ns2 10.0.1.1 - chk_join_nr 0 0 0 -- chk_prio_nr 0 1 -+ chk_prio_nr 0 1 0 0 - fi - - if reset "mpc switch to backup both sides" && -@@ -2815,7 +2859,7 @@ backup_tests() - sflags=backup speed=slow \ - run_tests $ns1 $ns2 10.0.1.1 - chk_join_nr 0 0 0 -- chk_prio_nr 1 1 -+ chk_prio_nr 1 1 0 0 - fi - } - -@@ -3215,7 +3259,7 @@ fullmesh_tests() - addr_nr_ns2=1 sflags=backup,fullmesh speed=slow \ - run_tests $ns1 $ns2 10.0.1.1 - chk_join_nr 2 2 2 -- chk_prio_nr 0 1 -+ chk_prio_nr 0 1 1 0 - chk_rm_nr 0 1 - fi - -@@ -3228,7 +3272,7 @@ fullmesh_tests() - sflags=nobackup,nofullmesh speed=slow \ - run_tests $ns1 $ns2 10.0.1.1 - chk_join_nr 2 2 2 -- chk_prio_nr 0 1 -+ chk_prio_nr 0 1 1 0 - chk_rm_nr 0 1 - fi - } -@@ -3407,7 +3451,7 @@ userspace_tests() - sflags=backup speed=slow \ - run_tests $ns1 $ns2 10.0.1.1 - chk_join_nr 1 1 0 -- chk_prio_nr 0 0 -+ chk_prio_nr 0 0 0 0 - fi - - # userspace pm type prevents rm_addr diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.45-46.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.45-46.patch deleted file mode 100644 index 359d52eccf..0000000000 --- a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.45-46.patch +++ /dev/null @@ -1,6300 +0,0 @@ -diff --git a/Documentation/admin-guide/cifs/usage.rst b/Documentation/admin-guide/cifs/usage.rst -index 20aba92dfc5f5..3de599cf0779a 100644 ---- a/Documentation/admin-guide/cifs/usage.rst -+++ b/Documentation/admin-guide/cifs/usage.rst -@@ -741,7 +741,7 @@ SecurityFlags Flags which control security negotiation and - may use NTLMSSP 0x00080 - must use NTLMSSP 0x80080 - seal (packet encryption) 0x00040 -- must seal (not implemented yet) 0x40040 -+ must seal 0x40040 - - cifsFYI If set to non-zero value, additional debug information - will be logged to the system error log. This field -diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt -index 8d2f9ed3f1076..a7fe113897361 100644 ---- a/Documentation/admin-guide/kernel-parameters.txt -+++ b/Documentation/admin-guide/kernel-parameters.txt -@@ -664,12 +664,6 @@ - loops can be debugged more effectively on production - systems. - -- clocksource.max_cswd_read_retries= [KNL] -- Number of clocksource_watchdog() retries due to -- external delays before the clock will be marked -- unstable. Defaults to two retries, that is, -- three attempts to read the clock under test. -- - clocksource.verify_n_cpus= [KNL] - Limit the number of CPUs checked for clocksources - marked with CLOCK_SOURCE_VERIFY_PERCPU that -@@ -4655,11 +4649,9 @@ - - profile= [KNL] Enable kernel profiling via /proc/profile - Format: [,] -- Param: : "schedule", "sleep", or "kvm" -+ Param: : "schedule" or "kvm" - [defaults to kernel profiling] - Param: "schedule" - profile schedule points. -- Param: "sleep" - profile D-state sleeping (millisecs). -- Requires CONFIG_SCHEDSTATS - Param: "kvm" - profile VM exits. - Param: - step/bucket size as a power of 2 for - statistical time based profiling. -diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst -index 29fd5213eeb2b..357d6cb98161f 100644 ---- a/Documentation/arch/arm64/silicon-errata.rst -+++ b/Documentation/arch/arm64/silicon-errata.rst -@@ -119,32 +119,68 @@ stable kernels. - +----------------+-----------------+-----------------+-----------------------------+ - | ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 | - +----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-A76 | #3324349 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ - | ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 | - +----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-A77 | #3324348 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-A78C | #3324346,3324347| ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ - | ARM | Cortex-A710 | #2119858 | ARM64_ERRATUM_2119858 | - +----------------+-----------------+-----------------+-----------------------------+ - | ARM | Cortex-A710 | #2054223 | ARM64_ERRATUM_2054223 | - +----------------+-----------------+-----------------+-----------------------------+ - | ARM | Cortex-A710 | #2224489 | ARM64_ERRATUM_2224489 | - +----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ - | ARM | Cortex-A715 | #2645198 | ARM64_ERRATUM_2645198 | - +----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-X1C | #3324346 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ - | ARM | Cortex-X2 | #2119858 | ARM64_ERRATUM_2119858 | - +----------------+-----------------+-----------------+-----------------------------+ - | ARM | Cortex-X2 | #2224489 | ARM64_ERRATUM_2224489 | - +----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-X2 | #3324338 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-X3 | #3324335 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Cortex-X925 | #3324334 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ - | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | - +----------------+-----------------+-----------------+-----------------------------+ - | ARM | Neoverse-N1 | #1349291 | N/A | - +----------------+-----------------+-----------------+-----------------------------+ - | ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 | - +----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ - | ARM | Neoverse-N2 | #2139208 | ARM64_ERRATUM_2139208 | - +----------------+-----------------+-----------------+-----------------------------+ - | ARM | Neoverse-N2 | #2067961 | ARM64_ERRATUM_2067961 | - +----------------+-----------------+-----------------+-----------------------------+ - | ARM | Neoverse-N2 | #2253138 | ARM64_ERRATUM_2253138 | - +----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ -+| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 | -++----------------+-----------------+-----------------+-----------------------------+ - | ARM | MMU-500 | #841119,826419 | N/A | - +----------------+-----------------+-----------------+-----------------------------+ - | ARM | MMU-600 | #1076982,1209401| N/A | -diff --git a/Documentation/hwmon/corsair-psu.rst b/Documentation/hwmon/corsair-psu.rst -index 16db34d464dd6..7ed794087f848 100644 ---- a/Documentation/hwmon/corsair-psu.rst -+++ b/Documentation/hwmon/corsair-psu.rst -@@ -15,11 +15,11 @@ Supported devices: - - Corsair HX850i - -- Corsair HX1000i (Series 2022 and 2023) -+ Corsair HX1000i (Legacy and Series 2023) - -- Corsair HX1200i -+ Corsair HX1200i (Legacy and Series 2023) - -- Corsair HX1500i (Series 2022 and 2023) -+ Corsair HX1500i (Legacy and Series 2023) - - Corsair RM550i - -diff --git a/Makefile b/Makefile -index 0bd4bee2128b4..77de99984c2f1 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 6 --SUBLEVEL = 45 -+SUBLEVEL = 46 - EXTRAVERSION = - NAME = Hurr durr I'ma ninja sloth - -diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index f9777ce2ccb2d..9e0c1ac3d13ee 100644 ---- a/arch/arm64/Kconfig -+++ b/arch/arm64/Kconfig -@@ -1068,6 +1068,44 @@ config ARM64_ERRATUM_3117295 - - If unsure, say Y. - -+config ARM64_ERRATUM_3194386 -+ bool "Cortex-*/Neoverse-*: workaround for MSR SSBS not self-synchronizing" -+ default y -+ help -+ This option adds the workaround for the following errata: -+ -+ * ARM Cortex-A76 erratum 3324349 -+ * ARM Cortex-A77 erratum 3324348 -+ * ARM Cortex-A78 erratum 3324344 -+ * ARM Cortex-A78C erratum 3324346 -+ * ARM Cortex-A78C erratum 3324347 -+ * ARM Cortex-A710 erratam 3324338 -+ * ARM Cortex-A720 erratum 3456091 -+ * ARM Cortex-A725 erratum 3456106 -+ * ARM Cortex-X1 erratum 3324344 -+ * ARM Cortex-X1C erratum 3324346 -+ * ARM Cortex-X2 erratum 3324338 -+ * ARM Cortex-X3 erratum 3324335 -+ * ARM Cortex-X4 erratum 3194386 -+ * ARM Cortex-X925 erratum 3324334 -+ * ARM Neoverse-N1 erratum 3324349 -+ * ARM Neoverse N2 erratum 3324339 -+ * ARM Neoverse-V1 erratum 3324341 -+ * ARM Neoverse V2 erratum 3324336 -+ * ARM Neoverse-V3 erratum 3312417 -+ -+ On affected cores "MSR SSBS, #0" instructions may not affect -+ subsequent speculative instructions, which may permit unexepected -+ speculative store bypassing. -+ -+ Work around this problem by placing a Speculation Barrier (SB) or -+ Instruction Synchronization Barrier (ISB) after kernel changes to -+ SSBS. The presence of the SSBS special-purpose register is hidden -+ from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such that userspace -+ will use the PR_SPEC_STORE_BYPASS prctl to change SSBS. -+ -+ If unsure, say Y. -+ - config CAVIUM_ERRATUM_22375 - bool "Cavium erratum 22375, 24313" - default y -diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h -index cf2987464c186..1ca947d5c9396 100644 ---- a/arch/arm64/include/asm/barrier.h -+++ b/arch/arm64/include/asm/barrier.h -@@ -40,6 +40,10 @@ - */ - #define dgh() asm volatile("hint #6" : : : "memory") - -+#define spec_bar() asm volatile(ALTERNATIVE("dsb nsh\nisb\n", \ -+ SB_BARRIER_INSN"nop\n", \ -+ ARM64_HAS_SB)) -+ - #ifdef CONFIG_ARM64_PSEUDO_NMI - #define pmr_sync() \ - do { \ -diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h -index 52f076afeb960..5fd7caea44193 100644 ---- a/arch/arm64/include/asm/cputype.h -+++ b/arch/arm64/include/asm/cputype.h -@@ -86,6 +86,14 @@ - #define ARM_CPU_PART_CORTEX_X2 0xD48 - #define ARM_CPU_PART_NEOVERSE_N2 0xD49 - #define ARM_CPU_PART_CORTEX_A78C 0xD4B -+#define ARM_CPU_PART_CORTEX_X1C 0xD4C -+#define ARM_CPU_PART_CORTEX_X3 0xD4E -+#define ARM_CPU_PART_NEOVERSE_V2 0xD4F -+#define ARM_CPU_PART_CORTEX_A720 0xD81 -+#define ARM_CPU_PART_CORTEX_X4 0xD82 -+#define ARM_CPU_PART_NEOVERSE_V3 0xD84 -+#define ARM_CPU_PART_CORTEX_X925 0xD85 -+#define ARM_CPU_PART_CORTEX_A725 0xD87 - - #define APM_CPU_PART_XGENE 0x000 - #define APM_CPU_VAR_POTENZA 0x00 -@@ -159,6 +167,14 @@ - #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) - #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) - #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) -+#define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C) -+#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3) -+#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2) -+#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720) -+#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4) -+#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) -+#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925) -+#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725) - #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) - #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) - #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) -diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c -index 7bba831f62c33..57b1d6a68256b 100644 ---- a/arch/arm64/kernel/cpu_errata.c -+++ b/arch/arm64/kernel/cpu_errata.c -@@ -448,6 +448,30 @@ static const struct midr_range erratum_spec_unpriv_load_list[] = { - }; - #endif - -+#ifdef CONFIG_ARM64_ERRATUM_3194386 -+static const struct midr_range erratum_spec_ssbs_list[] = { -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A76), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A77), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_A725), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X2), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X4), -+ MIDR_ALL_VERSIONS(MIDR_CORTEX_X925), -+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), -+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), -+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), -+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), -+ MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3), -+ {} -+}; -+#endif -+ - const struct arm64_cpu_capabilities arm64_errata[] = { - #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE - { -@@ -746,6 +770,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = { - .cpu_enable = cpu_clear_bf16_from_user_emulation, - }, - #endif -+#ifdef CONFIG_ARM64_ERRATUM_3194386 -+ { -+ .desc = "SSBS not fully self-synchronizing", -+ .capability = ARM64_WORKAROUND_SPECULATIVE_SSBS, -+ ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list), -+ }, -+#endif - #ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD - { - .desc = "ARM errata 2966298, 3117295", -diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c -index 444a73c2e6385..7e96604559004 100644 ---- a/arch/arm64/kernel/cpufeature.c -+++ b/arch/arm64/kernel/cpufeature.c -@@ -2190,6 +2190,17 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) - } - #endif /* CONFIG_ARM64_MTE */ - -+static void user_feature_fixup(void) -+{ -+ if (cpus_have_cap(ARM64_WORKAROUND_SPECULATIVE_SSBS)) { -+ struct arm64_ftr_reg *regp; -+ -+ regp = get_arm64_ftr_reg(SYS_ID_AA64PFR1_EL1); -+ if (regp) -+ regp->user_mask &= ~ID_AA64PFR1_EL1_SSBS_MASK; -+ } -+} -+ - static void elf_hwcap_fixup(void) - { - #ifdef CONFIG_ARM64_ERRATUM_1742098 -@@ -3345,6 +3356,7 @@ void __init setup_cpu_features(void) - u32 cwg; - - setup_system_capabilities(); -+ user_feature_fixup(); - setup_elf_hwcaps(arm64_elf_hwcaps); - - if (system_supports_32bit_el0()) { -diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c -index 05f40c4e18fda..57503dc4b22fa 100644 ---- a/arch/arm64/kernel/proton-pack.c -+++ b/arch/arm64/kernel/proton-pack.c -@@ -558,6 +558,18 @@ static enum mitigation_state spectre_v4_enable_hw_mitigation(void) - - /* SCTLR_EL1.DSSBS was initialised to 0 during boot */ - set_pstate_ssbs(0); -+ -+ /* -+ * SSBS is self-synchronizing and is intended to affect subsequent -+ * speculative instructions, but some CPUs can speculate with a stale -+ * value of SSBS. -+ * -+ * Mitigate this with an unconditional speculation barrier, as CPUs -+ * could mis-speculate branches and bypass a conditional barrier. -+ */ -+ if (IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386)) -+ spec_bar(); -+ - return SPECTRE_MITIGATED; - } - -diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps -index 5511bee15603a..c251ef3caae56 100644 ---- a/arch/arm64/tools/cpucaps -+++ b/arch/arm64/tools/cpucaps -@@ -99,4 +99,5 @@ WORKAROUND_NVIDIA_CARMEL_CNP - WORKAROUND_QCOM_FALKOR_E1003 - WORKAROUND_REPEAT_TLBI - WORKAROUND_SPECULATIVE_AT -+WORKAROUND_SPECULATIVE_SSBS - WORKAROUND_SPECULATIVE_UNPRIV_LOAD -diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c -index 9fc10cea21e10..de4f3def4af0b 100644 ---- a/arch/loongarch/kernel/efi.c -+++ b/arch/loongarch/kernel/efi.c -@@ -66,6 +66,12 @@ void __init efi_runtime_init(void) - set_bit(EFI_RUNTIME_SERVICES, &efi.flags); - } - -+bool efi_poweroff_required(void) -+{ -+ return efi_enabled(EFI_RUNTIME_SERVICES) && -+ (acpi_gbl_reduced_hardware || acpi_no_s5); -+} -+ - unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; - - static void __init init_screen_info(void) -diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig -index 2834a64064970..a077e6bf9475f 100644 ---- a/arch/parisc/Kconfig -+++ b/arch/parisc/Kconfig -@@ -18,6 +18,7 @@ config PARISC - select ARCH_SUPPORTS_HUGETLBFS if PA20 - select ARCH_SUPPORTS_MEMORY_FAILURE - select ARCH_STACKWALK -+ select ARCH_HAS_CACHE_LINE_SIZE - select ARCH_HAS_DEBUG_VM_PGTABLE - select HAVE_RELIABLE_STACKTRACE - select DMA_OPS -diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h -index 2a60d7a72f1fa..a3f0f100f2194 100644 ---- a/arch/parisc/include/asm/cache.h -+++ b/arch/parisc/include/asm/cache.h -@@ -20,7 +20,16 @@ - - #define SMP_CACHE_BYTES L1_CACHE_BYTES - --#define ARCH_DMA_MINALIGN L1_CACHE_BYTES -+#ifdef CONFIG_PA20 -+#define ARCH_DMA_MINALIGN 128 -+#else -+#define ARCH_DMA_MINALIGN 32 -+#endif -+#define ARCH_KMALLOC_MINALIGN 16 /* ldcw requires 16-byte alignment */ -+ -+#define arch_slab_minalign() ((unsigned)dcache_stride) -+#define cache_line_size() dcache_stride -+#define dma_get_cache_alignment cache_line_size - - #define __read_mostly __section(".data..read_mostly") - -diff --git a/arch/parisc/net/bpf_jit_core.c b/arch/parisc/net/bpf_jit_core.c -index d6ee2fd455503..7b9cb3cda27ee 100644 ---- a/arch/parisc/net/bpf_jit_core.c -+++ b/arch/parisc/net/bpf_jit_core.c -@@ -114,7 +114,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) - jit_data->header = - bpf_jit_binary_alloc(prog_size + extable_size, - &jit_data->image, -- sizeof(u32), -+ sizeof(long), - bpf_fill_ill_insns); - if (!jit_data->header) { - prog = orig_prog; -diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h -index 621bac6b74011..24b7bd255e983 100644 ---- a/arch/x86/include/asm/msr-index.h -+++ b/arch/x86/include/asm/msr-index.h -@@ -237,6 +237,7 @@ - #define MSR_INTEGRITY_CAPS_ARRAY_BIST BIT(MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT) - #define MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT 4 - #define MSR_INTEGRITY_CAPS_PERIODIC_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT) -+#define MSR_INTEGRITY_CAPS_SAF_GEN_MASK GENMASK_ULL(10, 9) - - #define MSR_LBR_NHM_FROM 0x00000680 - #define MSR_LBR_NHM_TO 0x000006c0 -diff --git a/arch/x86/include/asm/qspinlock.h b/arch/x86/include/asm/qspinlock.h -index cde8357bb226d..e897046c5d2c6 100644 ---- a/arch/x86/include/asm/qspinlock.h -+++ b/arch/x86/include/asm/qspinlock.h -@@ -66,13 +66,15 @@ static inline bool vcpu_is_preempted(long cpu) - - #ifdef CONFIG_PARAVIRT - /* -- * virt_spin_lock_key - enables (by default) the virt_spin_lock() hijack. -+ * virt_spin_lock_key - disables by default the virt_spin_lock() hijack. - * -- * Native (and PV wanting native due to vCPU pinning) should disable this key. -- * It is done in this backwards fashion to only have a single direction change, -- * which removes ordering between native_pv_spin_init() and HV setup. -+ * Native (and PV wanting native due to vCPU pinning) should keep this key -+ * disabled. Native does not touch the key. -+ * -+ * When in a guest then native_pv_lock_init() enables the key first and -+ * KVM/XEN might conditionally disable it later in the boot process again. - */ --DECLARE_STATIC_KEY_TRUE(virt_spin_lock_key); -+DECLARE_STATIC_KEY_FALSE(virt_spin_lock_key); - - /* - * Shortcut for the queued_spin_lock_slowpath() function that allows -diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c -index 767bf1c71aadd..2a2fc14955cd3 100644 ---- a/arch/x86/kernel/cpu/mtrr/mtrr.c -+++ b/arch/x86/kernel/cpu/mtrr/mtrr.c -@@ -609,7 +609,7 @@ void mtrr_save_state(void) - { - int first_cpu; - -- if (!mtrr_enabled()) -+ if (!mtrr_enabled() || !mtrr_state.have_fixed) - return; - - first_cpu = cpumask_first(cpu_online_mask); -diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c -index 97f1436c1a203..8d51c86caa415 100644 ---- a/arch/x86/kernel/paravirt.c -+++ b/arch/x86/kernel/paravirt.c -@@ -71,13 +71,12 @@ DEFINE_PARAVIRT_ASM(pv_native_irq_enable, "sti", .noinstr.text); - DEFINE_PARAVIRT_ASM(pv_native_read_cr2, "mov %cr2, %rax", .noinstr.text); - #endif - --DEFINE_STATIC_KEY_TRUE(virt_spin_lock_key); -+DEFINE_STATIC_KEY_FALSE(virt_spin_lock_key); - - void __init native_pv_lock_init(void) - { -- if (IS_ENABLED(CONFIG_PARAVIRT_SPINLOCKS) && -- !boot_cpu_has(X86_FEATURE_HYPERVISOR)) -- static_branch_disable(&virt_spin_lock_key); -+ if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) -+ static_branch_enable(&virt_spin_lock_key); - } - - static void native_tlb_remove_table(struct mmu_gather *tlb, void *table) -diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c -index 51b6b78e6b175..41d8c8f475a7c 100644 ---- a/arch/x86/mm/pti.c -+++ b/arch/x86/mm/pti.c -@@ -374,14 +374,14 @@ pti_clone_pgtable(unsigned long start, unsigned long end, - */ - *target_pmd = *pmd; - -- addr += PMD_SIZE; -+ addr = round_up(addr + 1, PMD_SIZE); - - } else if (level == PTI_CLONE_PTE) { - - /* Walk the page-table down to the pte level */ - pte = pte_offset_kernel(pmd, addr); - if (pte_none(*pte)) { -- addr += PAGE_SIZE; -+ addr = round_up(addr + 1, PAGE_SIZE); - continue; - } - -@@ -401,7 +401,7 @@ pti_clone_pgtable(unsigned long start, unsigned long end, - /* Clone the PTE */ - *target_pte = *pte; - -- addr += PAGE_SIZE; -+ addr = round_up(addr + 1, PAGE_SIZE); - - } else { - BUG(); -@@ -496,7 +496,7 @@ static void pti_clone_entry_text(void) - { - pti_clone_pgtable((unsigned long) __entry_text_start, - (unsigned long) __entry_text_end, -- PTI_CLONE_PMD); -+ PTI_LEVEL_KERNEL_IMAGE); - } - - /* -diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c -index 969bf81e8d546..7f7ad94f22b91 100644 ---- a/drivers/acpi/battery.c -+++ b/drivers/acpi/battery.c -@@ -678,12 +678,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, - return count; - } - --static const struct device_attribute alarm_attr = { -+static struct device_attribute alarm_attr = { - .attr = {.name = "alarm", .mode = 0644}, - .show = acpi_battery_alarm_show, - .store = acpi_battery_alarm_store, - }; - -+static struct attribute *acpi_battery_attrs[] = { -+ &alarm_attr.attr, -+ NULL -+}; -+ATTRIBUTE_GROUPS(acpi_battery); -+ - /* - * The Battery Hooking API - * -@@ -823,7 +829,10 @@ static void __exit battery_hook_exit(void) - - static int sysfs_add_battery(struct acpi_battery *battery) - { -- struct power_supply_config psy_cfg = { .drv_data = battery, }; -+ struct power_supply_config psy_cfg = { -+ .drv_data = battery, -+ .attr_grp = acpi_battery_groups, -+ }; - bool full_cap_broken = false; - - if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && -@@ -868,7 +877,7 @@ static int sysfs_add_battery(struct acpi_battery *battery) - return result; - } - battery_hook_add_battery(battery); -- return device_create_file(&battery->bat->dev, &alarm_attr); -+ return 0; - } - - static void sysfs_remove_battery(struct acpi_battery *battery) -@@ -879,7 +888,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery) - return; - } - battery_hook_remove_battery(battery); -- device_remove_file(&battery->bat->dev, &alarm_attr); - power_supply_unregister(battery->bat); - battery->bat = NULL; - mutex_unlock(&battery->sysfs_lock); -diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c -index 94e3c000df2e1..fdeb46ed21d69 100644 ---- a/drivers/acpi/sbs.c -+++ b/drivers/acpi/sbs.c -@@ -77,7 +77,6 @@ struct acpi_battery { - u16 spec; - u8 id; - u8 present:1; -- u8 have_sysfs_alarm:1; - }; - - #define to_acpi_battery(x) power_supply_get_drvdata(x) -@@ -462,12 +461,18 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, - return count; - } - --static const struct device_attribute alarm_attr = { -+static struct device_attribute alarm_attr = { - .attr = {.name = "alarm", .mode = 0644}, - .show = acpi_battery_alarm_show, - .store = acpi_battery_alarm_store, - }; - -+static struct attribute *acpi_battery_attrs[] = { -+ &alarm_attr.attr, -+ NULL -+}; -+ATTRIBUTE_GROUPS(acpi_battery); -+ - /* -------------------------------------------------------------------------- - Driver Interface - -------------------------------------------------------------------------- */ -@@ -518,7 +523,10 @@ static int acpi_battery_read(struct acpi_battery *battery) - static int acpi_battery_add(struct acpi_sbs *sbs, int id) - { - struct acpi_battery *battery = &sbs->battery[id]; -- struct power_supply_config psy_cfg = { .drv_data = battery, }; -+ struct power_supply_config psy_cfg = { -+ .drv_data = battery, -+ .attr_grp = acpi_battery_groups, -+ }; - int result; - - battery->id = id; -@@ -548,10 +556,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) - goto end; - } - -- result = device_create_file(&battery->bat->dev, &alarm_attr); -- if (result) -- goto end; -- battery->have_sysfs_alarm = 1; - end: - pr_info("%s [%s]: Battery Slot [%s] (battery %s)\n", - ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), -@@ -563,11 +567,8 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id) - { - struct acpi_battery *battery = &sbs->battery[id]; - -- if (battery->bat) { -- if (battery->have_sysfs_alarm) -- device_remove_file(&battery->bat->dev, &alarm_attr); -+ if (battery->bat) - power_supply_unregister(battery->bat); -- } - } - - static int acpi_charger_add(struct acpi_sbs *sbs) -diff --git a/drivers/base/core.c b/drivers/base/core.c -index aeb4644817d57..cb323700e952f 100644 ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2565,6 +2566,7 @@ static const char *dev_uevent_name(const struct kobject *kobj) - static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) - { - const struct device *dev = kobj_to_dev(kobj); -+ struct device_driver *driver; - int retval = 0; - - /* add device node properties if present */ -@@ -2593,8 +2595,12 @@ static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) - if (dev->type && dev->type->name) - add_uevent_var(env, "DEVTYPE=%s", dev->type->name); - -- if (dev->driver) -- add_uevent_var(env, "DRIVER=%s", dev->driver->name); -+ /* Synchronize with module_remove_driver() */ -+ rcu_read_lock(); -+ driver = READ_ONCE(dev->driver); -+ if (driver) -+ add_uevent_var(env, "DRIVER=%s", driver->name); -+ rcu_read_unlock(); - - /* Add common DT information about the device */ - of_device_uevent(dev, env); -@@ -2664,11 +2670,8 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, - if (!env) - return -ENOMEM; - -- /* Synchronize with really_probe() */ -- device_lock(dev); - /* let the kset specific function add its keys */ - retval = kset->uevent_ops->uevent(&dev->kobj, env); -- device_unlock(dev); - if (retval) - goto out; - -diff --git a/drivers/base/module.c b/drivers/base/module.c -index a1b55da07127d..b0b79b9c189d4 100644 ---- a/drivers/base/module.c -+++ b/drivers/base/module.c -@@ -7,6 +7,7 @@ - #include - #include - #include -+#include - #include "base.h" - - static char *make_driver_name(struct device_driver *drv) -@@ -97,6 +98,9 @@ void module_remove_driver(struct device_driver *drv) - if (!drv) - return; - -+ /* Synchronize with dev_uevent() */ -+ synchronize_rcu(); -+ - sysfs_remove_link(&drv->p->kobj, "module"); - - if (drv->owner) -diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c -index 83e8e27a5ecec..b5d40e0e05f31 100644 ---- a/drivers/bluetooth/btnxpuart.c -+++ b/drivers/bluetooth/btnxpuart.c -@@ -340,7 +340,7 @@ static void ps_cancel_timer(struct btnxpuart_dev *nxpdev) - struct ps_data *psdata = &nxpdev->psdata; - - flush_work(&psdata->work); -- del_timer_sync(&psdata->ps_timer); -+ timer_shutdown_sync(&psdata->ps_timer); - } - - static void ps_control(struct hci_dev *hdev, u8 ps_state) -diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c -index 26919556ef5f0..b72b36e0abed8 100644 ---- a/drivers/clocksource/sh_cmt.c -+++ b/drivers/clocksource/sh_cmt.c -@@ -528,6 +528,7 @@ static void sh_cmt_set_next(struct sh_cmt_channel *ch, unsigned long delta) - static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) - { - struct sh_cmt_channel *ch = dev_id; -+ unsigned long flags; - - /* clear flags */ - sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & -@@ -558,6 +559,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) - - ch->flags &= ~FLAG_SKIPEVENT; - -+ raw_spin_lock_irqsave(&ch->lock, flags); -+ - if (ch->flags & FLAG_REPROGRAM) { - ch->flags &= ~FLAG_REPROGRAM; - sh_cmt_clock_event_program_verify(ch, 1); -@@ -570,6 +573,8 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) - - ch->flags &= ~FLAG_IRQCONTEXT; - -+ raw_spin_unlock_irqrestore(&ch->lock, flags); -+ - return IRQ_HANDLED; - } - -@@ -780,12 +785,18 @@ static int sh_cmt_clock_event_next(unsigned long delta, - struct clock_event_device *ced) - { - struct sh_cmt_channel *ch = ced_to_sh_cmt(ced); -+ unsigned long flags; - - BUG_ON(!clockevent_state_oneshot(ced)); -+ -+ raw_spin_lock_irqsave(&ch->lock, flags); -+ - if (likely(ch->flags & FLAG_IRQCONTEXT)) - ch->next_match_value = delta - 1; - else -- sh_cmt_set_next(ch, delta - 1); -+ __sh_cmt_set_next(ch, delta - 1); -+ -+ raw_spin_unlock_irqrestore(&ch->lock, flags); - - return 0; - } -diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c -index 1c512ed3fa6d9..5c0016c77d2ab 100644 ---- a/drivers/gpio/gpiolib.c -+++ b/drivers/gpio/gpiolib.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -164,7 +165,7 @@ struct gpio_desc *gpiochip_get_desc(struct gpio_chip *gc, - if (hwnum >= gdev->ngpio) - return ERR_PTR(-EINVAL); - -- return &gdev->descs[hwnum]; -+ return &gdev->descs[array_index_nospec(hwnum, gdev->ngpio)]; - } - EXPORT_SYMBOL_GPL(gpiochip_get_desc); - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -index ea1bce13db941..eb663eb811563 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c -@@ -3561,6 +3561,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, - mutex_init(&adev->grbm_idx_mutex); - mutex_init(&adev->mn_lock); - mutex_init(&adev->virt.vf_errors.lock); -+ mutex_init(&adev->virt.rlcg_reg_lock); - hash_init(adev->mn_hash); - mutex_init(&adev->psp.mutex); - mutex_init(&adev->notifier_lock); -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c -index de9d7f3dc2336..99dd86337e841 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c -@@ -258,9 +258,8 @@ amdgpu_job_prepare_job(struct drm_sched_job *sched_job, - struct dma_fence *fence = NULL; - int r; - -- /* Ignore soft recovered fences here */ - r = drm_sched_entity_error(s_entity); -- if (r && r != -ENODATA) -+ if (r) - goto error; - - if (!fence && job->gang_submit) -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c -index ca5c86e5f7cd6..8e8afbd237bcd 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c -@@ -334,7 +334,7 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size - - set_ta_context_funcs(psp, ta_type, &context); - -- if (!context->initialized) { -+ if (!context || !context->initialized) { - dev_err(adev->dev, "TA is not initialized\n"); - ret = -EINVAL; - goto err_free_shared_buf; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c -index 67b75ff0f7c37..7cba98f8bbdca 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c -@@ -1780,12 +1780,15 @@ static void amdgpu_ras_interrupt_process_handler(struct work_struct *work) - int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev, - struct ras_dispatch_if *info) - { -- struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head); -- struct ras_ih_data *data = &obj->ih_data; -+ struct ras_manager *obj; -+ struct ras_ih_data *data; - -+ obj = amdgpu_ras_find_obj(adev, &info->head); - if (!obj) - return -EINVAL; - -+ data = &obj->ih_data; -+ - if (data->inuse == 0) - return 0; - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c -index 96857ae7fb5bc..ff4f52e07cc0d 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c -@@ -1003,6 +1003,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v - scratch_reg1 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg1; - scratch_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2; - scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3; -+ -+ mutex_lock(&adev->virt.rlcg_reg_lock); -+ - if (reg_access_ctrl->spare_int) - spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int; - -@@ -1058,6 +1061,9 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v - } - - ret = readl(scratch_reg0); -+ -+ mutex_unlock(&adev->virt.rlcg_reg_lock); -+ - return ret; - } - -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h -index fabb83e9d9aec..23b6efa9d25df 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h -@@ -263,6 +263,8 @@ struct amdgpu_virt { - - /* the ucode id to signal the autoload */ - uint32_t autoload_ucode_id; -+ -+ struct mutex rlcg_reg_lock; - }; - - struct amdgpu_video_codec_info; -diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c -index 349416e176a12..1cf1498204678 100644 ---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c -+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c -@@ -102,6 +102,11 @@ static int amdgpu_vm_sdma_prepare(struct amdgpu_vm_update_params *p, - if (!r) - r = amdgpu_sync_push_to_job(&sync, p->job); - amdgpu_sync_free(&sync); -+ -+ if (r) { -+ p->num_dw_left = 0; -+ amdgpu_job_free(p->job); -+ } - return r; - } - -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -index 60db3800666ec..94059aef762be 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c -@@ -2628,7 +2628,8 @@ static int dm_suspend(void *handle) - - dm->cached_dc_state = dc_copy_state(dm->dc->current_state); - -- dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false); -+ if (dm->cached_dc_state) -+ dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false); - - amdgpu_dm_commit_zero_streams(dm->dc); - -@@ -6483,7 +6484,8 @@ static void create_eml_sink(struct amdgpu_dm_connector *aconnector) - aconnector->dc_sink = aconnector->dc_link->local_sink ? - aconnector->dc_link->local_sink : - aconnector->dc_em_sink; -- dc_sink_retain(aconnector->dc_sink); -+ if (aconnector->dc_sink) -+ dc_sink_retain(aconnector->dc_sink); - } - } - -@@ -7296,7 +7298,8 @@ static int amdgpu_dm_connector_get_modes(struct drm_connector *connector) - drm_add_modes_noedid(connector, 1920, 1080); - } else { - amdgpu_dm_connector_ddc_get_modes(connector, edid); -- amdgpu_dm_connector_add_common_modes(encoder, connector); -+ if (encoder) -+ amdgpu_dm_connector_add_common_modes(encoder, connector); - amdgpu_dm_connector_add_freesync_modes(connector, edid); - } - amdgpu_dm_fbc_init(connector); -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c -index 2104511f3b863..3880ddf1c820f 100644 ---- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c -+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c -@@ -1266,6 +1266,9 @@ static bool is_dsc_need_re_compute( - } - } - -+ if (new_stream_on_link_num == 0) -+ return false; -+ - /* check current_state if there stream on link but it is not in - * new request state - */ -diff --git a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c -index b621b97711b61..a7f5b0f6272ce 100644 ---- a/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c -+++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c -@@ -162,7 +162,12 @@ static void set_hpo_fixed_vs_pe_retimer_dp_link_test_pattern(struct dc_link *lin - link_res->hpo_dp_link_enc->funcs->set_link_test_pattern( - link_res->hpo_dp_link_enc, tp_params); - } -+ - link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN); -+ -+ // Give retimer extra time to lock before updating DP_TRAINING_PATTERN_SET to TPS1 -+ if (tp_params->dp_phy_pattern == DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE) -+ msleep(30); - } - - static void set_hpo_fixed_vs_pe_retimer_dp_lane_settings(struct dc_link *link, -diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c -index 9e4f8a4104a34..7bf46e4974f88 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c -@@ -927,7 +927,7 @@ static int pp_dpm_switch_power_profile(void *handle, - enum PP_SMC_POWER_PROFILE type, bool en) - { - struct pp_hwmgr *hwmgr = handle; -- long workload; -+ long workload[1]; - uint32_t index; - - if (!hwmgr || !hwmgr->pm_en) -@@ -945,12 +945,12 @@ static int pp_dpm_switch_power_profile(void *handle, - hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]); - index = fls(hwmgr->workload_mask); - index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; -- workload = hwmgr->workload_setting[index]; -+ workload[0] = hwmgr->workload_setting[index]; - } else { - hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]); - index = fls(hwmgr->workload_mask); - index = index <= Workload_Policy_Max ? index - 1 : 0; -- workload = hwmgr->workload_setting[index]; -+ workload[0] = hwmgr->workload_setting[index]; - } - - if (type == PP_SMC_POWER_PROFILE_COMPUTE && -@@ -960,7 +960,7 @@ static int pp_dpm_switch_power_profile(void *handle, - } - - if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) -- hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); -+ hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0); - - return 0; - } -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c -index 1d829402cd2e2..f4bd8e9357e22 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c -@@ -269,7 +269,7 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set - struct pp_power_state *new_ps) - { - uint32_t index; -- long workload; -+ long workload[1]; - - if (hwmgr->not_vf) { - if (!skip_display_settings) -@@ -294,10 +294,10 @@ int psm_adjust_power_state_dynamic(struct pp_hwmgr *hwmgr, bool skip_display_set - if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) { - index = fls(hwmgr->workload_mask); - index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0; -- workload = hwmgr->workload_setting[index]; -+ workload[0] = hwmgr->workload_setting[index]; - -- if (hwmgr->power_profile_mode != workload && hwmgr->hwmgr_func->set_power_profile_mode) -- hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0); -+ if (hwmgr->power_profile_mode != workload[0] && hwmgr->hwmgr_func->set_power_profile_mode) -+ hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0); - } - - return 0; -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c -index aa91730e4eaff..163864bd51c34 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c -@@ -2957,6 +2957,7 @@ static int smu7_update_edc_leakage_table(struct pp_hwmgr *hwmgr) - - static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) - { -+ struct amdgpu_device *adev = hwmgr->adev; - struct smu7_hwmgr *data; - int result = 0; - -@@ -2993,40 +2994,37 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) - /* Initalize Dynamic State Adjustment Rule Settings */ - result = phm_initializa_dynamic_state_adjustment_rule_settings(hwmgr); - -- if (0 == result) { -- struct amdgpu_device *adev = hwmgr->adev; -+ if (result) -+ goto fail; - -- data->is_tlu_enabled = false; -+ data->is_tlu_enabled = false; - -- hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = -+ hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = - SMU7_MAX_HARDWARE_POWERLEVELS; -- hwmgr->platform_descriptor.hardwarePerformanceLevels = 2; -- hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; -+ hwmgr->platform_descriptor.hardwarePerformanceLevels = 2; -+ hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; - -- data->pcie_gen_cap = adev->pm.pcie_gen_mask; -- if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) -- data->pcie_spc_cap = 20; -- else -- data->pcie_spc_cap = 16; -- data->pcie_lane_cap = adev->pm.pcie_mlw_mask; -- -- hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */ --/* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */ -- hwmgr->platform_descriptor.clockStep.engineClock = 500; -- hwmgr->platform_descriptor.clockStep.memoryClock = 500; -- smu7_thermal_parameter_init(hwmgr); -- } else { -- /* Ignore return value in here, we are cleaning up a mess. */ -- smu7_hwmgr_backend_fini(hwmgr); -- } -+ data->pcie_gen_cap = adev->pm.pcie_gen_mask; -+ if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) -+ data->pcie_spc_cap = 20; -+ else -+ data->pcie_spc_cap = 16; -+ data->pcie_lane_cap = adev->pm.pcie_mlw_mask; -+ -+ hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */ -+ /* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */ -+ hwmgr->platform_descriptor.clockStep.engineClock = 500; -+ hwmgr->platform_descriptor.clockStep.memoryClock = 500; -+ smu7_thermal_parameter_init(hwmgr); - - result = smu7_update_edc_leakage_table(hwmgr); -- if (result) { -- smu7_hwmgr_backend_fini(hwmgr); -- return result; -- } -+ if (result) -+ goto fail; - - return 0; -+fail: -+ smu7_hwmgr_backend_fini(hwmgr); -+ return result; - } - - static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr) -@@ -3316,8 +3314,7 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, - const struct pp_power_state *current_ps) - { - struct amdgpu_device *adev = hwmgr->adev; -- struct smu7_power_state *smu7_ps = -- cast_phw_smu7_power_state(&request_ps->hardware); -+ struct smu7_power_state *smu7_ps; - uint32_t sclk; - uint32_t mclk; - struct PP_Clocks minimum_clocks = {0}; -@@ -3334,6 +3331,10 @@ static int smu7_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, - uint32_t latency; - bool latency_allowed = false; - -+ smu7_ps = cast_phw_smu7_power_state(&request_ps->hardware); -+ if (!smu7_ps) -+ return -EINVAL; -+ - data->battery_state = (PP_StateUILabel_Battery == - request_ps->classification.ui_label); - data->mclk_ignore_signal = false; -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c -index b015a601b385a..eb744401e0567 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c -@@ -1065,16 +1065,18 @@ static int smu8_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, - struct pp_power_state *prequest_ps, - const struct pp_power_state *pcurrent_ps) - { -- struct smu8_power_state *smu8_ps = -- cast_smu8_power_state(&prequest_ps->hardware); -- -- const struct smu8_power_state *smu8_current_ps = -- cast_const_smu8_power_state(&pcurrent_ps->hardware); -- -+ struct smu8_power_state *smu8_ps; -+ const struct smu8_power_state *smu8_current_ps; - struct smu8_hwmgr *data = hwmgr->backend; - struct PP_Clocks clocks = {0, 0, 0, 0}; - bool force_high; - -+ smu8_ps = cast_smu8_power_state(&prequest_ps->hardware); -+ smu8_current_ps = cast_const_smu8_power_state(&pcurrent_ps->hardware); -+ -+ if (!smu8_ps || !smu8_current_ps) -+ return -EINVAL; -+ - smu8_ps->need_dfs_bypass = true; - - data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label); -diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c -index 6d6bc6a380b36..d43a530aba0e3 100644 ---- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c -+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c -@@ -3259,8 +3259,7 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, - const struct pp_power_state *current_ps) - { - struct amdgpu_device *adev = hwmgr->adev; -- struct vega10_power_state *vega10_ps = -- cast_phw_vega10_power_state(&request_ps->hardware); -+ struct vega10_power_state *vega10_ps; - uint32_t sclk; - uint32_t mclk; - struct PP_Clocks minimum_clocks = {0}; -@@ -3278,6 +3277,10 @@ static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, - uint32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0; - uint32_t latency; - -+ vega10_ps = cast_phw_vega10_power_state(&request_ps->hardware); -+ if (!vega10_ps) -+ return -EINVAL; -+ - data->battery_state = (PP_StateUILabel_Battery == - request_ps->classification.ui_label); - -@@ -3415,13 +3418,17 @@ static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, co - const struct vega10_power_state *vega10_ps = - cast_const_phw_vega10_power_state(states->pnew_state); - struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table); -- uint32_t sclk = vega10_ps->performance_levels -- [vega10_ps->performance_level_count - 1].gfx_clock; - struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table); -- uint32_t mclk = vega10_ps->performance_levels -- [vega10_ps->performance_level_count - 1].mem_clock; -+ uint32_t sclk, mclk; - uint32_t i; - -+ if (vega10_ps == NULL) -+ return -EINVAL; -+ sclk = vega10_ps->performance_levels -+ [vega10_ps->performance_level_count - 1].gfx_clock; -+ mclk = vega10_ps->performance_levels -+ [vega10_ps->performance_level_count - 1].mem_clock; -+ - for (i = 0; i < sclk_table->count; i++) { - if (sclk == sclk_table->dpm_levels[i].value) - break; -@@ -3728,6 +3735,9 @@ static int vega10_generate_dpm_level_enable_mask( - cast_const_phw_vega10_power_state(states->pnew_state); - int i; - -+ if (vega10_ps == NULL) -+ return -EINVAL; -+ - PP_ASSERT_WITH_CODE(!vega10_trim_dpm_states(hwmgr, vega10_ps), - "Attempt to Trim DPM States Failed!", - return -1); -@@ -4995,6 +5005,8 @@ static int vega10_check_states_equal(struct pp_hwmgr *hwmgr, - - vega10_psa = cast_const_phw_vega10_power_state(pstate1); - vega10_psb = cast_const_phw_vega10_power_state(pstate2); -+ if (vega10_psa == NULL || vega10_psb == NULL) -+ return -EINVAL; - - /* If the two states don't even have the same number of performance levels - * they cannot be the same state. -@@ -5128,6 +5140,8 @@ static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value) - return -EINVAL; - - vega10_ps = cast_phw_vega10_power_state(&ps->hardware); -+ if (vega10_ps == NULL) -+ return -EINVAL; - - vega10_ps->performance_levels - [vega10_ps->performance_level_count - 1].gfx_clock = -@@ -5179,6 +5193,8 @@ static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value) - return -EINVAL; - - vega10_ps = cast_phw_vega10_power_state(&ps->hardware); -+ if (vega10_ps == NULL) -+ return -EINVAL; - - vega10_ps->performance_levels - [vega10_ps->performance_level_count - 1].mem_clock = -@@ -5420,6 +5436,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr) - return; - - vega10_ps = cast_phw_vega10_power_state(&ps->hardware); -+ if (vega10_ps == NULL) -+ return; -+ - max_level = vega10_ps->performance_level_count - 1; - - if (vega10_ps->performance_levels[max_level].gfx_clock != -@@ -5442,6 +5461,9 @@ static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr) - - ps = (struct pp_power_state *)((unsigned long)(hwmgr->ps) + hwmgr->ps_size * (hwmgr->num_ps - 1)); - vega10_ps = cast_phw_vega10_power_state(&ps->hardware); -+ if (vega10_ps == NULL) -+ return; -+ - max_level = vega10_ps->performance_level_count - 1; - - if (vega10_ps->performance_levels[max_level].gfx_clock != -@@ -5632,6 +5654,8 @@ static int vega10_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_ - return -EINVAL; - - vega10_ps = cast_const_phw_vega10_power_state(state); -+ if (vega10_ps == NULL) -+ return -EINVAL; - - i = index > vega10_ps->performance_level_count - 1 ? - vega10_ps->performance_level_count - 1 : index; -diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -index 56e4c312cb7a9..1402e468aa90f 100644 ---- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -+++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c -@@ -1846,7 +1846,7 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, - { - int ret = 0; - int index = 0; -- long workload; -+ long workload[1]; - struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); - - if (!skip_display_settings) { -@@ -1886,10 +1886,10 @@ static int smu_adjust_power_state_dynamic(struct smu_context *smu, - smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) { - index = fls(smu->workload_mask); - index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; -- workload = smu->workload_setting[index]; -+ workload[0] = smu->workload_setting[index]; - -- if (smu->power_profile_mode != workload) -- smu_bump_power_profile_mode(smu, &workload, 0); -+ if (smu->power_profile_mode != workload[0]) -+ smu_bump_power_profile_mode(smu, workload, 0); - } - - return ret; -@@ -1939,7 +1939,7 @@ static int smu_switch_power_profile(void *handle, - { - struct smu_context *smu = handle; - struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm); -- long workload; -+ long workload[1]; - uint32_t index; - - if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled) -@@ -1952,17 +1952,17 @@ static int smu_switch_power_profile(void *handle, - smu->workload_mask &= ~(1 << smu->workload_prority[type]); - index = fls(smu->workload_mask); - index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; -- workload = smu->workload_setting[index]; -+ workload[0] = smu->workload_setting[index]; - } else { - smu->workload_mask |= (1 << smu->workload_prority[type]); - index = fls(smu->workload_mask); - index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0; -- workload = smu->workload_setting[index]; -+ workload[0] = smu->workload_setting[index]; - } - - if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL && - smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) -- smu_bump_power_profile_mode(smu, &workload, 0); -+ smu_bump_power_profile_mode(smu, workload, 0); - - return 0; - } -diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c -index 6a4f20fccf841..7b0bc9704eacb 100644 ---- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c -+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c -@@ -1027,7 +1027,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, - u32 status_reg; - u8 *buffer = msg->buffer; - unsigned int i; -- int num_transferred = 0; - int ret; - - /* Buffer size of AUX CH is 16 bytes */ -@@ -1079,7 +1078,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, - reg = buffer[i]; - writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 + - 4 * i); -- num_transferred++; - } - } - -@@ -1127,7 +1125,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, - reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 + - 4 * i); - buffer[i] = (unsigned char)reg; -- num_transferred++; - } - } - -@@ -1144,7 +1141,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, - (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) - msg->reply = DP_AUX_NATIVE_REPLY_ACK; - -- return num_transferred > 0 ? num_transferred : -EBUSY; -+ return msg->size; - - aux_error: - /* if aux err happen, reset aux */ -diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c -index 9023c0216a8a4..6ead31701e79e 100644 ---- a/drivers/gpu/drm/display/drm_dp_mst_topology.c -+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c -@@ -4024,6 +4024,7 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) - if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) { - const struct drm_dp_connection_status_notify *conn_stat = - &up_req->msg.u.conn_stat; -+ bool handle_csn; - - drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n", - conn_stat->port_number, -@@ -4032,6 +4033,16 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) - conn_stat->message_capability_status, - conn_stat->input_port, - conn_stat->peer_device_type); -+ -+ mutex_lock(&mgr->probe_lock); -+ handle_csn = mgr->mst_primary->link_address_sent; -+ mutex_unlock(&mgr->probe_lock); -+ -+ if (!handle_csn) { -+ drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it."); -+ kfree(up_req); -+ goto out; -+ } - } else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) { - const struct drm_dp_resource_status_notify *res_stat = - &up_req->msg.u.resource_stat; -diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c -index 0683a129b3628..51df7244de718 100644 ---- a/drivers/gpu/drm/drm_client_modeset.c -+++ b/drivers/gpu/drm/drm_client_modeset.c -@@ -869,6 +869,11 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, - - kfree(modeset->mode); - modeset->mode = drm_mode_duplicate(dev, mode); -+ if (!modeset->mode) { -+ ret = -ENOMEM; -+ break; -+ } -+ - drm_connector_get(connector); - modeset->connectors[modeset->num_connectors++] = connector; - modeset->x = offset->x; -diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c -index 310654542b42c..a59c17ec7fa36 100644 ---- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c -+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c -@@ -290,6 +290,41 @@ static vm_fault_t vm_fault_cpu(struct vm_fault *vmf) - return i915_error_to_vmf_fault(err); - } - -+static void set_address_limits(struct vm_area_struct *area, -+ struct i915_vma *vma, -+ unsigned long obj_offset, -+ unsigned long *start_vaddr, -+ unsigned long *end_vaddr) -+{ -+ unsigned long vm_start, vm_end, vma_size; /* user's memory parameters */ -+ long start, end; /* memory boundaries */ -+ -+ /* -+ * Let's move into the ">> PAGE_SHIFT" -+ * domain to be sure not to lose bits -+ */ -+ vm_start = area->vm_start >> PAGE_SHIFT; -+ vm_end = area->vm_end >> PAGE_SHIFT; -+ vma_size = vma->size >> PAGE_SHIFT; -+ -+ /* -+ * Calculate the memory boundaries by considering the offset -+ * provided by the user during memory mapping and the offset -+ * provided for the partial mapping. -+ */ -+ start = vm_start; -+ start -= obj_offset; -+ start += vma->gtt_view.partial.offset; -+ end = start + vma_size; -+ -+ start = max_t(long, start, vm_start); -+ end = min_t(long, end, vm_end); -+ -+ /* Let's move back into the "<< PAGE_SHIFT" domain */ -+ *start_vaddr = (unsigned long)start << PAGE_SHIFT; -+ *end_vaddr = (unsigned long)end << PAGE_SHIFT; -+} -+ - static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) - { - #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT) -@@ -302,14 +337,18 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) - struct i915_ggtt *ggtt = to_gt(i915)->ggtt; - bool write = area->vm_flags & VM_WRITE; - struct i915_gem_ww_ctx ww; -+ unsigned long obj_offset; -+ unsigned long start, end; /* memory boundaries */ - intel_wakeref_t wakeref; - struct i915_vma *vma; - pgoff_t page_offset; -+ unsigned long pfn; - int srcu; - int ret; - -- /* We don't use vmf->pgoff since that has the fake offset */ -+ obj_offset = area->vm_pgoff - drm_vma_node_start(&mmo->vma_node); - page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT; -+ page_offset += obj_offset; - - trace_i915_gem_object_fault(obj, page_offset, true, write); - -@@ -402,12 +441,14 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) - if (ret) - goto err_unpin; - -+ set_address_limits(area, vma, obj_offset, &start, &end); -+ -+ pfn = (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT; -+ pfn += (start - area->vm_start) >> PAGE_SHIFT; -+ pfn += obj_offset - vma->gtt_view.partial.offset; -+ - /* Finally, remap it using the new GTT offset */ -- ret = remap_io_mapping(area, -- area->vm_start + (vma->gtt_view.partial.offset << PAGE_SHIFT), -- (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT, -- min_t(u64, vma->size, area->vm_end - area->vm_start), -- &ggtt->iomap); -+ ret = remap_io_mapping(area, start, pfn, end - start, &ggtt->iomap); - if (ret) - goto err_fence; - -@@ -1088,6 +1129,8 @@ int i915_gem_fb_mmap(struct drm_i915_gem_object *obj, struct vm_area_struct *vma - mmo = mmap_offset_attach(obj, mmap_type, NULL); - if (IS_ERR(mmo)) - return PTR_ERR(mmo); -+ -+ vma->vm_pgoff += drm_vma_node_start(&mmo->vma_node); - } - - /* -diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c -index 10fd9154cc465..8c9b656eeb59d 100644 ---- a/drivers/gpu/drm/lima/lima_drv.c -+++ b/drivers/gpu/drm/lima/lima_drv.c -@@ -486,3 +486,4 @@ module_platform_driver(lima_platform_driver); - MODULE_AUTHOR("Lima Project Developers"); - MODULE_DESCRIPTION("Lima DRM Driver"); - MODULE_LICENSE("GPL v2"); -+MODULE_SOFTDEP("pre: governor_simpleondemand"); -diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c -index 0c48bdf3e7f80..f5c5d06d0d4bb 100644 ---- a/drivers/gpu/drm/mgag200/mgag200_i2c.c -+++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c -@@ -31,6 +31,8 @@ - #include - #include - -+#include -+ - #include "mgag200_drv.h" - - static int mga_i2c_read_gpio(struct mga_device *mdev) -@@ -86,7 +88,7 @@ static int mga_gpio_getscl(void *data) - return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0; - } - --static void mgag200_i2c_release(void *res) -+static void mgag200_i2c_release(struct drm_device *dev, void *res) - { - struct mga_i2c_chan *i2c = res; - -@@ -115,7 +117,7 @@ int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c) - i2c->adapter.algo_data = &i2c->bit; - - i2c->bit.udelay = 10; -- i2c->bit.timeout = 2; -+ i2c->bit.timeout = usecs_to_jiffies(2200); - i2c->bit.data = i2c; - i2c->bit.setsda = mga_gpio_setsda; - i2c->bit.setscl = mga_gpio_setscl; -@@ -126,5 +128,5 @@ int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c) - if (ret) - return ret; - -- return devm_add_action_or_reset(dev->dev, mgag200_i2c_release, i2c); -+ return drmm_add_action_or_reset(dev, mgag200_i2c_release, i2c); - } -diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c b/drivers/gpu/drm/nouveau/nouveau_uvmm.c -index 2bbcdc649e862..3d41e590d4712 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c -+++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c -@@ -1320,6 +1320,7 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job) - - drm_gpuva_for_each_op(va_op, op->ops) { - struct drm_gem_object *obj = op_gem_obj(va_op); -+ struct nouveau_bo *nvbo; - - if (unlikely(!obj)) - continue; -@@ -1330,8 +1331,9 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job) - if (unlikely(va_op->op == DRM_GPUVA_OP_UNMAP)) - continue; - -- ret = nouveau_bo_validate(nouveau_gem_object(obj), -- true, false); -+ nvbo = nouveau_gem_object(obj); -+ nouveau_bo_placement_set(nvbo, nvbo->valid_domains, 0); -+ ret = nouveau_bo_validate(nvbo, true, false); - if (ret) { - op = list_last_op(&bind_job->ops); - goto unwind; -diff --git a/drivers/gpu/drm/radeon/pptable.h b/drivers/gpu/drm/radeon/pptable.h -index 844f0490bf31f..ce8832916704f 100644 ---- a/drivers/gpu/drm/radeon/pptable.h -+++ b/drivers/gpu/drm/radeon/pptable.h -@@ -439,7 +439,7 @@ typedef struct _StateArray{ - //how many states we have - UCHAR ucNumEntries; - -- ATOM_PPLIB_STATE_V2 states[] __counted_by(ucNumEntries); -+ ATOM_PPLIB_STATE_V2 states[] /* __counted_by(ucNumEntries) */; - }StateArray; - - -diff --git a/drivers/hwmon/corsair-psu.c b/drivers/hwmon/corsair-psu.c -index 2c7c92272fe39..f8f22b8a67cdf 100644 ---- a/drivers/hwmon/corsair-psu.c -+++ b/drivers/hwmon/corsair-psu.c -@@ -875,15 +875,16 @@ static const struct hid_device_id corsairpsu_idtable[] = { - { HID_USB_DEVICE(0x1b1c, 0x1c04) }, /* Corsair HX650i */ - { HID_USB_DEVICE(0x1b1c, 0x1c05) }, /* Corsair HX750i */ - { HID_USB_DEVICE(0x1b1c, 0x1c06) }, /* Corsair HX850i */ -- { HID_USB_DEVICE(0x1b1c, 0x1c07) }, /* Corsair HX1000i Series 2022 */ -- { HID_USB_DEVICE(0x1b1c, 0x1c08) }, /* Corsair HX1200i */ -+ { HID_USB_DEVICE(0x1b1c, 0x1c07) }, /* Corsair HX1000i Legacy */ -+ { HID_USB_DEVICE(0x1b1c, 0x1c08) }, /* Corsair HX1200i Legacy */ - { HID_USB_DEVICE(0x1b1c, 0x1c09) }, /* Corsair RM550i */ - { HID_USB_DEVICE(0x1b1c, 0x1c0a) }, /* Corsair RM650i */ - { HID_USB_DEVICE(0x1b1c, 0x1c0b) }, /* Corsair RM750i */ - { HID_USB_DEVICE(0x1b1c, 0x1c0c) }, /* Corsair RM850i */ - { HID_USB_DEVICE(0x1b1c, 0x1c0d) }, /* Corsair RM1000i */ - { HID_USB_DEVICE(0x1b1c, 0x1c1e) }, /* Corsair HX1000i Series 2023 */ -- { HID_USB_DEVICE(0x1b1c, 0x1c1f) }, /* Corsair HX1500i Series 2022 and 2023 */ -+ { HID_USB_DEVICE(0x1b1c, 0x1c1f) }, /* Corsair HX1500i Legacy and Series 2023 */ -+ { HID_USB_DEVICE(0x1b1c, 0x1c23) }, /* Corsair HX1200i Series 2023 */ - { }, - }; - MODULE_DEVICE_TABLE(hid, corsairpsu_idtable); -diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c -index 5cc32a465f12e..b17411e97be68 100644 ---- a/drivers/i2c/busses/i2c-qcom-geni.c -+++ b/drivers/i2c/busses/i2c-qcom-geni.c -@@ -991,8 +991,11 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev) - return ret; - - ret = geni_se_resources_on(&gi2c->se); -- if (ret) -+ if (ret) { -+ clk_disable_unprepare(gi2c->core_clk); -+ geni_icc_disable(&gi2c->se); - return ret; -+ } - - enable_irq(gi2c->irq); - gi2c->suspended = 0; -diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c -index 138c3f5e0093a..6520e09743912 100644 ---- a/drivers/i2c/i2c-smbus.c -+++ b/drivers/i2c/i2c-smbus.c -@@ -34,6 +34,7 @@ static int smbus_do_alert(struct device *dev, void *addrp) - struct i2c_client *client = i2c_verify_client(dev); - struct alert_data *data = addrp; - struct i2c_driver *driver; -+ int ret; - - if (!client || client->addr != data->addr) - return 0; -@@ -47,16 +48,47 @@ static int smbus_do_alert(struct device *dev, void *addrp) - device_lock(dev); - if (client->dev.driver) { - driver = to_i2c_driver(client->dev.driver); -- if (driver->alert) -+ if (driver->alert) { -+ /* Stop iterating after we find the device */ - driver->alert(client, data->type, data->data); -- else -+ ret = -EBUSY; -+ } else { - dev_warn(&client->dev, "no driver alert()!\n"); -- } else -+ ret = -EOPNOTSUPP; -+ } -+ } else { - dev_dbg(&client->dev, "alert with no driver\n"); -+ ret = -ENODEV; -+ } -+ device_unlock(dev); -+ -+ return ret; -+} -+ -+/* Same as above, but call back all drivers with alert handler */ -+ -+static int smbus_do_alert_force(struct device *dev, void *addrp) -+{ -+ struct i2c_client *client = i2c_verify_client(dev); -+ struct alert_data *data = addrp; -+ struct i2c_driver *driver; -+ -+ if (!client || (client->flags & I2C_CLIENT_TEN)) -+ return 0; -+ -+ /* -+ * Drivers should either disable alerts, or provide at least -+ * a minimal handler. Lock so the driver won't change. -+ */ -+ device_lock(dev); -+ if (client->dev.driver) { -+ driver = to_i2c_driver(client->dev.driver); -+ if (driver->alert) -+ driver->alert(client, data->type, data->data); -+ } - device_unlock(dev); - -- /* Stop iterating after we find the device */ -- return -EBUSY; -+ return 0; - } - - /* -@@ -67,6 +99,7 @@ static irqreturn_t smbus_alert(int irq, void *d) - { - struct i2c_smbus_alert *alert = d; - struct i2c_client *ara; -+ unsigned short prev_addr = I2C_CLIENT_END; /* Not a valid address */ - - ara = alert->ara; - -@@ -94,8 +127,25 @@ static irqreturn_t smbus_alert(int irq, void *d) - data.addr, data.data); - - /* Notify driver for the device which issued the alert */ -- device_for_each_child(&ara->adapter->dev, &data, -- smbus_do_alert); -+ status = device_for_each_child(&ara->adapter->dev, &data, -+ smbus_do_alert); -+ /* -+ * If we read the same address more than once, and the alert -+ * was not handled by a driver, it won't do any good to repeat -+ * the loop because it will never terminate. Try again, this -+ * time calling the alert handlers of all devices connected to -+ * the bus, and abort the loop afterwards. If this helps, we -+ * are all set. If it doesn't, there is nothing else we can do, -+ * so we might as well abort the loop. -+ * Note: This assumes that a driver with alert handler handles -+ * the alert properly and clears it if necessary. -+ */ -+ if (data.addr == prev_addr && status != -EBUSY) { -+ device_for_each_child(&ara->adapter->dev, &data, -+ smbus_do_alert_force); -+ break; -+ } -+ prev_addr = data.addr; - } - - return IRQ_HANDLED; -diff --git a/drivers/irqchip/irq-loongarch-cpu.c b/drivers/irqchip/irq-loongarch-cpu.c -index 9d8f2c4060431..b35903a06902f 100644 ---- a/drivers/irqchip/irq-loongarch-cpu.c -+++ b/drivers/irqchip/irq-loongarch-cpu.c -@@ -18,11 +18,13 @@ struct fwnode_handle *cpuintc_handle; - - static u32 lpic_gsi_to_irq(u32 gsi) - { -+ int irq = 0; -+ - /* Only pch irqdomain transferring is required for LoongArch. */ - if (gsi >= GSI_MIN_PCH_IRQ && gsi <= GSI_MAX_PCH_IRQ) -- return acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH); -+ irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH); - -- return 0; -+ return (irq > 0) ? irq : 0; - } - - static struct fwnode_handle *lpic_get_gsi_domain_id(u32 gsi) -diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c -index 58881d3139792..244a8d489cac6 100644 ---- a/drivers/irqchip/irq-mbigen.c -+++ b/drivers/irqchip/irq-mbigen.c -@@ -64,6 +64,20 @@ struct mbigen_device { - void __iomem *base; - }; - -+static inline unsigned int get_mbigen_node_offset(unsigned int nid) -+{ -+ unsigned int offset = nid * MBIGEN_NODE_OFFSET; -+ -+ /* -+ * To avoid touched clear register in unexpected way, we need to directly -+ * skip clear register when access to more than 10 mbigen nodes. -+ */ -+ if (nid >= (REG_MBIGEN_CLEAR_OFFSET / MBIGEN_NODE_OFFSET)) -+ offset += MBIGEN_NODE_OFFSET; -+ -+ return offset; -+} -+ - static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq) - { - unsigned int nid, pin; -@@ -72,8 +86,7 @@ static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq) - nid = hwirq / IRQS_PER_MBIGEN_NODE + 1; - pin = hwirq % IRQS_PER_MBIGEN_NODE; - -- return pin * 4 + nid * MBIGEN_NODE_OFFSET -- + REG_MBIGEN_VEC_OFFSET; -+ return pin * 4 + get_mbigen_node_offset(nid) + REG_MBIGEN_VEC_OFFSET; - } - - static inline void get_mbigen_type_reg(irq_hw_number_t hwirq, -@@ -88,8 +101,7 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq, - *mask = 1 << (irq_ofst % 32); - ofst = irq_ofst / 32 * 4; - -- *addr = ofst + nid * MBIGEN_NODE_OFFSET -- + REG_MBIGEN_TYPE_OFFSET; -+ *addr = ofst + get_mbigen_node_offset(nid) + REG_MBIGEN_TYPE_OFFSET; - } - - static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq, -diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c -index f88df39f41291..471e04eaf3230 100644 ---- a/drivers/irqchip/irq-meson-gpio.c -+++ b/drivers/irqchip/irq-meson-gpio.c -@@ -173,7 +173,7 @@ struct meson_gpio_irq_controller { - void __iomem *base; - u32 channel_irqs[MAX_NUM_CHANNEL]; - DECLARE_BITMAP(channel_map, MAX_NUM_CHANNEL); -- spinlock_t lock; -+ raw_spinlock_t lock; - }; - - static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl, -@@ -182,14 +182,14 @@ static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl, - unsigned long flags; - u32 tmp; - -- spin_lock_irqsave(&ctl->lock, flags); -+ raw_spin_lock_irqsave(&ctl->lock, flags); - - tmp = readl_relaxed(ctl->base + reg); - tmp &= ~mask; - tmp |= val; - writel_relaxed(tmp, ctl->base + reg); - -- spin_unlock_irqrestore(&ctl->lock, flags); -+ raw_spin_unlock_irqrestore(&ctl->lock, flags); - } - - static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl) -@@ -239,12 +239,12 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl, - unsigned long flags; - unsigned int idx; - -- spin_lock_irqsave(&ctl->lock, flags); -+ raw_spin_lock_irqsave(&ctl->lock, flags); - - /* Find a free channel */ - idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels); - if (idx >= ctl->params->nr_channels) { -- spin_unlock_irqrestore(&ctl->lock, flags); -+ raw_spin_unlock_irqrestore(&ctl->lock, flags); - pr_err("No channel available\n"); - return -ENOSPC; - } -@@ -252,7 +252,7 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl, - /* Mark the channel as used */ - set_bit(idx, ctl->channel_map); - -- spin_unlock_irqrestore(&ctl->lock, flags); -+ raw_spin_unlock_irqrestore(&ctl->lock, flags); - - /* - * Setup the mux of the channel to route the signal of the pad -@@ -562,7 +562,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node * - if (!ctl) - return -ENOMEM; - -- spin_lock_init(&ctl->lock); -+ raw_spin_lock_init(&ctl->lock); - - ctl->base = of_iomap(node, 0); - if (!ctl->base) { -diff --git a/drivers/irqchip/irq-xilinx-intc.c b/drivers/irqchip/irq-xilinx-intc.c -index 238d3d3449496..7e08714d507f4 100644 ---- a/drivers/irqchip/irq-xilinx-intc.c -+++ b/drivers/irqchip/irq-xilinx-intc.c -@@ -189,7 +189,7 @@ static int __init xilinx_intc_of_init(struct device_node *intc, - irqc->intr_mask = 0; - } - -- if (irqc->intr_mask >> irqc->nr_irq) -+ if ((u64)irqc->intr_mask >> irqc->nr_irq) - pr_warn("irq-xilinx: mismatch in kind-of-intr param\n"); - - pr_info("irq-xilinx: %pOF: num_irq=%d, edge=0x%x\n", -diff --git a/drivers/md/md.c b/drivers/md/md.c -index b5dea664f946d..35b003b83ef1b 100644 ---- a/drivers/md/md.c -+++ b/drivers/md/md.c -@@ -456,7 +456,6 @@ void mddev_suspend(struct mddev *mddev) - clear_bit_unlock(MD_ALLOW_SB_UPDATE, &mddev->flags); - wait_event(mddev->sb_wait, !test_bit(MD_UPDATING_SB, &mddev->flags)); - -- del_timer_sync(&mddev->safemode_timer); - /* restrict memory reclaim I/O during raid array is suspend */ - mddev->noio_flag = memalloc_noio_save(); - } -diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c -index 1507540a9cb4e..2c7f11e576673 100644 ---- a/drivers/md/raid5.c -+++ b/drivers/md/raid5.c -@@ -6326,7 +6326,9 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk - safepos = conf->reshape_safe; - sector_div(safepos, data_disks); - if (mddev->reshape_backwards) { -- BUG_ON(writepos < reshape_sectors); -+ if (WARN_ON(writepos < reshape_sectors)) -+ return MaxSector; -+ - writepos -= reshape_sectors; - readpos += reshape_sectors; - safepos += reshape_sectors; -@@ -6344,14 +6346,18 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *sk - * to set 'stripe_addr' which is where we will write to. - */ - if (mddev->reshape_backwards) { -- BUG_ON(conf->reshape_progress == 0); -+ if (WARN_ON(conf->reshape_progress == 0)) -+ return MaxSector; -+ - stripe_addr = writepos; -- BUG_ON((mddev->dev_sectors & -- ~((sector_t)reshape_sectors - 1)) -- - reshape_sectors - stripe_addr -- != sector_nr); -+ if (WARN_ON((mddev->dev_sectors & -+ ~((sector_t)reshape_sectors - 1)) - -+ reshape_sectors - stripe_addr != sector_nr)) -+ return MaxSector; - } else { -- BUG_ON(writepos != sector_nr + reshape_sectors); -+ if (WARN_ON(writepos != sector_nr + reshape_sectors)) -+ return MaxSector; -+ - stripe_addr = sector_nr; - } - -diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c -index 133d77d1ea0c3..4f438eaa7d385 100644 ---- a/drivers/media/platform/amphion/vdec.c -+++ b/drivers/media/platform/amphion/vdec.c -@@ -195,7 +195,6 @@ static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) - struct vdec_t *vdec = inst->priv; - int ret = 0; - -- vpu_inst_lock(inst); - switch (ctrl->id) { - case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: - vdec->params.display_delay_enable = ctrl->val; -@@ -207,7 +206,6 @@ static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) - ret = -EINVAL; - break; - } -- vpu_inst_unlock(inst); - - return ret; - } -diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c -index 4eb57d793a9c0..16ed4d21519cd 100644 ---- a/drivers/media/platform/amphion/venc.c -+++ b/drivers/media/platform/amphion/venc.c -@@ -518,7 +518,6 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl) - struct venc_t *venc = inst->priv; - int ret = 0; - -- vpu_inst_lock(inst); - switch (ctrl->id) { - case V4L2_CID_MPEG_VIDEO_H264_PROFILE: - venc->params.profile = ctrl->val; -@@ -579,7 +578,6 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl) - ret = -EINVAL; - break; - } -- vpu_inst_unlock(inst); - - return ret; - } -diff --git a/drivers/media/tuners/xc2028.c b/drivers/media/tuners/xc2028.c -index 5a967edceca93..352b8a3679b72 100644 ---- a/drivers/media/tuners/xc2028.c -+++ b/drivers/media/tuners/xc2028.c -@@ -1361,9 +1361,16 @@ static void load_firmware_cb(const struct firmware *fw, - void *context) - { - struct dvb_frontend *fe = context; -- struct xc2028_data *priv = fe->tuner_priv; -+ struct xc2028_data *priv; - int rc; - -+ if (!fe) { -+ pr_warn("xc2028: No frontend in %s\n", __func__); -+ return; -+ } -+ -+ priv = fe->tuner_priv; -+ - tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error"); - if (!fw) { - tuner_err("Could not load firmware %s.\n", priv->fname); -diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c -index 5eef560bc8cd8..91c350b254126 100644 ---- a/drivers/media/usb/uvc/uvc_video.c -+++ b/drivers/media/usb/uvc/uvc_video.c -@@ -214,13 +214,13 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, - * Compute a bandwidth estimation by multiplying the frame - * size by the number of video frames per second, divide the - * result by the number of USB frames (or micro-frames for -- * high-speed devices) per second and add the UVC header size -- * (assumed to be 12 bytes long). -+ * high- and super-speed devices) per second and add the UVC -+ * header size (assumed to be 12 bytes long). - */ - bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp; - bandwidth *= 10000000 / interval + 1; - bandwidth /= 1000; -- if (stream->dev->udev->speed == USB_SPEED_HIGH) -+ if (stream->dev->udev->speed >= USB_SPEED_HIGH) - bandwidth /= 8; - bandwidth += 12; - -@@ -478,6 +478,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, - ktime_t time; - u16 host_sof; - u16 dev_sof; -+ u32 dev_stc; - - switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) { - case UVC_STREAM_PTS | UVC_STREAM_SCR: -@@ -526,6 +527,34 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, - if (dev_sof == stream->clock.last_sof) - return; - -+ dev_stc = get_unaligned_le32(&data[header_size - 6]); -+ -+ /* -+ * STC (Source Time Clock) is the clock used by the camera. The UVC 1.5 -+ * standard states that it "must be captured when the first video data -+ * of a video frame is put on the USB bus". This is generally understood -+ * as requiring devices to clear the payload header's SCR bit before -+ * the first packet containing video data. -+ * -+ * Most vendors follow that interpretation, but some (namely SunplusIT -+ * on some devices) always set the `UVC_STREAM_SCR` bit, fill the SCR -+ * field with 0's,and expect that the driver only processes the SCR if -+ * there is data in the packet. -+ * -+ * Ignore all the hardware timestamp information if we haven't received -+ * any data for this frame yet, the packet contains no data, and both -+ * STC and SOF are zero. This heuristics should be safe on compliant -+ * devices. This should be safe with compliant devices, as in the very -+ * unlikely case where a UVC 1.1 device would send timing information -+ * only before the first packet containing data, and both STC and SOF -+ * happen to be zero for a particular frame, we would only miss one -+ * clock sample from many and the clock recovery algorithm wouldn't -+ * suffer from this condition. -+ */ -+ if (buf && buf->bytesused == 0 && len == header_size && -+ dev_stc == 0 && dev_sof == 0) -+ return; -+ - stream->clock.last_sof = dev_sof; - - host_sof = usb_get_current_frame_number(stream->dev->udev); -@@ -575,7 +604,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, - spin_lock_irqsave(&stream->clock.lock, flags); - - sample = &stream->clock.samples[stream->clock.head]; -- sample->dev_stc = get_unaligned_le32(&data[header_size - 6]); -+ sample->dev_stc = dev_stc; - sample->dev_sof = dev_sof; - sample->host_sof = host_sof; - sample->host_time = time; -diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c -index bfe4caa0c99d4..4cb79a4f24612 100644 ---- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c -+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c -@@ -485,6 +485,8 @@ int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv) - clear_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags); - } - -+ tx_ring->obj_num_shift_to_u8 = BITS_PER_TYPE(tx_ring->obj_num) - -+ ilog2(tx_ring->obj_num); - tx_ring->obj_size = tx_obj_size; - - rem = priv->rx_obj_num; -diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c -index e5bd57b65aafe..5b0c7890d4b44 100644 ---- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c -+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c -@@ -2,7 +2,7 @@ - // - // mcp251xfd - Microchip MCP251xFD Family CAN controller driver - // --// Copyright (c) 2019, 2020, 2021 Pengutronix, -+// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, - // Marc Kleine-Budde - // - // Based on: -@@ -16,6 +16,11 @@ - - #include "mcp251xfd.h" - -+static inline bool mcp251xfd_tx_fifo_sta_full(u32 fifo_sta) -+{ -+ return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF); -+} -+ - static inline int - mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv, - u8 *tef_tail) -@@ -55,56 +60,39 @@ static int mcp251xfd_check_tef_tail(const struct mcp251xfd_priv *priv) - return 0; - } - --static int --mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq) --{ -- const struct mcp251xfd_tx_ring *tx_ring = priv->tx; -- u32 tef_sta; -- int err; -- -- err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFSTA, &tef_sta); -- if (err) -- return err; -- -- if (tef_sta & MCP251XFD_REG_TEFSTA_TEFOVIF) { -- netdev_err(priv->ndev, -- "Transmit Event FIFO buffer overflow.\n"); -- return -ENOBUFS; -- } -- -- netdev_info(priv->ndev, -- "Transmit Event FIFO buffer %s. (seq=0x%08x, tef_tail=0x%08x, tef_head=0x%08x, tx_head=0x%08x).\n", -- tef_sta & MCP251XFD_REG_TEFSTA_TEFFIF ? -- "full" : tef_sta & MCP251XFD_REG_TEFSTA_TEFNEIF ? -- "not empty" : "empty", -- seq, priv->tef->tail, priv->tef->head, tx_ring->head); -- -- /* The Sequence Number in the TEF doesn't match our tef_tail. */ -- return -EAGAIN; --} -- - static int - mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, - const struct mcp251xfd_hw_tef_obj *hw_tef_obj, - unsigned int *frame_len_ptr) - { - struct net_device_stats *stats = &priv->ndev->stats; -+ u32 seq, tef_tail_masked, tef_tail; - struct sk_buff *skb; -- u32 seq, seq_masked, tef_tail_masked, tef_tail; - -- seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK, -+ /* Use the MCP2517FD mask on the MCP2518FD, too. We only -+ * compare 7 bits, this is enough to detect old TEF objects. -+ */ -+ seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK, - hw_tef_obj->flags); -- -- /* Use the MCP2517FD mask on the MCP2518FD, too. We only -- * compare 7 bits, this should be enough to detect -- * net-yet-completed, i.e. old TEF objects. -- */ -- seq_masked = seq & -- field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); - tef_tail_masked = priv->tef->tail & - field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK); -- if (seq_masked != tef_tail_masked) -- return mcp251xfd_handle_tefif_recover(priv, seq); -+ -+ /* According to mcp2518fd erratum DS80000789E 6. the FIFOCI -+ * bits of a FIFOSTA register, here the TX FIFO tail index -+ * might be corrupted and we might process past the TEF FIFO's -+ * head into old CAN frames. -+ * -+ * Compare the sequence number of the currently processed CAN -+ * frame with the expected sequence number. Abort with -+ * -EBADMSG if an old CAN frame is detected. -+ */ -+ if (seq != tef_tail_masked) { -+ netdev_dbg(priv->ndev, "%s: chip=0x%02x ring=0x%02x\n", __func__, -+ seq, tef_tail_masked); -+ stats->tx_fifo_errors++; -+ -+ return -EBADMSG; -+ } - - tef_tail = mcp251xfd_get_tef_tail(priv); - skb = priv->can.echo_skb[tef_tail]; -@@ -120,28 +108,44 @@ mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv, - return 0; - } - --static int mcp251xfd_tef_ring_update(struct mcp251xfd_priv *priv) -+static int -+mcp251xfd_get_tef_len(struct mcp251xfd_priv *priv, u8 *len_p) - { - const struct mcp251xfd_tx_ring *tx_ring = priv->tx; -- unsigned int new_head; -- u8 chip_tx_tail; -+ const u8 shift = tx_ring->obj_num_shift_to_u8; -+ u8 chip_tx_tail, tail, len; -+ u32 fifo_sta; - int err; - -- err = mcp251xfd_tx_tail_get_from_chip(priv, &chip_tx_tail); -+ err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(priv->tx->fifo_nr), -+ &fifo_sta); - if (err) - return err; - -- /* chip_tx_tail, is the next TX-Object send by the HW. -- * The new TEF head must be >= the old head, ... -+ if (mcp251xfd_tx_fifo_sta_full(fifo_sta)) { -+ *len_p = tx_ring->obj_num; -+ return 0; -+ } -+ -+ chip_tx_tail = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); -+ -+ err = mcp251xfd_check_tef_tail(priv); -+ if (err) -+ return err; -+ tail = mcp251xfd_get_tef_tail(priv); -+ -+ /* First shift to full u8. The subtraction works on signed -+ * values, that keeps the difference steady around the u8 -+ * overflow. The right shift acts on len, which is an u8. - */ -- new_head = round_down(priv->tef->head, tx_ring->obj_num) + chip_tx_tail; -- if (new_head <= priv->tef->head) -- new_head += tx_ring->obj_num; -+ BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(chip_tx_tail)); -+ BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(tail)); -+ BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(len)); - -- /* ... but it cannot exceed the TX head. */ -- priv->tef->head = min(new_head, tx_ring->head); -+ len = (chip_tx_tail << shift) - (tail << shift); -+ *len_p = len >> shift; - -- return mcp251xfd_check_tef_tail(priv); -+ return 0; - } - - static inline int -@@ -182,13 +186,12 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) - u8 tef_tail, len, l; - int err, i; - -- err = mcp251xfd_tef_ring_update(priv); -+ err = mcp251xfd_get_tef_len(priv, &len); - if (err) - return err; - - tef_tail = mcp251xfd_get_tef_tail(priv); -- len = mcp251xfd_get_tef_len(priv); -- l = mcp251xfd_get_tef_linear_len(priv); -+ l = mcp251xfd_get_tef_linear_len(priv, len); - err = mcp251xfd_tef_obj_read(priv, hw_tef_obj, tef_tail, l); - if (err) - return err; -@@ -203,12 +206,12 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) - unsigned int frame_len = 0; - - err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len); -- /* -EAGAIN means the Sequence Number in the TEF -- * doesn't match our tef_tail. This can happen if we -- * read the TEF objects too early. Leave loop let the -- * interrupt handler call us again. -+ /* -EBADMSG means we're affected by mcp2518fd erratum -+ * DS80000789E 6., i.e. the Sequence Number in the TEF -+ * doesn't match our tef_tail. Don't process any -+ * further and mark processed frames as good. - */ -- if (err == -EAGAIN) -+ if (err == -EBADMSG) - goto out_netif_wake_queue; - if (err) - return err; -@@ -223,6 +226,8 @@ int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv) - struct mcp251xfd_tx_ring *tx_ring = priv->tx; - int offset; - -+ ring->head += len; -+ - /* Increment the TEF FIFO tail pointer 'len' times in - * a single SPI message. - * -diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h -index b35bfebd23f29..4628bf847bc9b 100644 ---- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h -+++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h -@@ -524,6 +524,7 @@ struct mcp251xfd_tef_ring { - - /* u8 obj_num equals tx_ring->obj_num */ - /* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */ -+ /* u8 obj_num_shift_to_u8 equals tx_ring->obj_num_shift_to_u8 */ - - union mcp251xfd_write_reg_buf irq_enable_buf; - struct spi_transfer irq_enable_xfer; -@@ -542,6 +543,7 @@ struct mcp251xfd_tx_ring { - u8 nr; - u8 fifo_nr; - u8 obj_num; -+ u8 obj_num_shift_to_u8; - u8 obj_size; - - struct mcp251xfd_tx_obj obj[MCP251XFD_TX_OBJ_NUM_MAX]; -@@ -861,17 +863,8 @@ static inline u8 mcp251xfd_get_tef_tail(const struct mcp251xfd_priv *priv) - return priv->tef->tail & (priv->tx->obj_num - 1); - } - --static inline u8 mcp251xfd_get_tef_len(const struct mcp251xfd_priv *priv) -+static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv, u8 len) - { -- return priv->tef->head - priv->tef->tail; --} -- --static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv) --{ -- u8 len; -- -- len = mcp251xfd_get_tef_len(priv); -- - return min_t(u8, len, priv->tx->obj_num - mcp251xfd_get_tef_tail(priv)); - } - -diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c -index cd1f240c90f39..257df16768750 100644 ---- a/drivers/net/dsa/bcm_sf2.c -+++ b/drivers/net/dsa/bcm_sf2.c -@@ -678,8 +678,10 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) - of_remove_property(child, prop); - - phydev = of_phy_find_device(child); -- if (phydev) -+ if (phydev) { - phy_device_remove(phydev); -+ phy_device_free(phydev); -+ } - } - - err = mdiobus_register(priv->slave_mii_bus); -diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c -index 1248792d7fd4d..0715ea5bf13ed 100644 ---- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c -+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c -@@ -42,19 +42,15 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) - struct bcmgenet_priv *priv = netdev_priv(dev); - struct device *kdev = &priv->pdev->dev; - -- if (dev->phydev) { -+ if (dev->phydev) - phy_ethtool_get_wol(dev->phydev, wol); -- if (wol->supported) -- return; -- } - -- if (!device_can_wakeup(kdev)) { -- wol->supported = 0; -- wol->wolopts = 0; -+ /* MAC is not wake-up capable, return what the PHY does */ -+ if (!device_can_wakeup(kdev)) - return; -- } - -- wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER; -+ /* Overlay MAC capabilities with that of the PHY queried before */ -+ wol->supported |= WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER; - wol->wolopts = priv->wolopts; - memset(wol->sopass, 0, sizeof(wol->sopass)); - -diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c -index e32f6724f5681..2e4f3e1782a25 100644 ---- a/drivers/net/ethernet/freescale/fec_ptp.c -+++ b/drivers/net/ethernet/freescale/fec_ptp.c -@@ -775,6 +775,9 @@ void fec_ptp_stop(struct platform_device *pdev) - struct net_device *ndev = platform_get_drvdata(pdev); - struct fec_enet_private *fep = netdev_priv(ndev); - -+ if (fep->pps_enable) -+ fec_ptp_enable_pps(fep, 0); -+ - cancel_delayed_work_sync(&fep->time_keep); - hrtimer_cancel(&fep->perout_timer); - if (fep->ptp_clock) -diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c -index 600a2f5370875..b168a37a5dfff 100644 ---- a/drivers/net/ethernet/intel/ice/ice_main.c -+++ b/drivers/net/ethernet/intel/ice/ice_main.c -@@ -557,6 +557,8 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type) - if (test_bit(ICE_PREPARED_FOR_RESET, pf->state)) - return; - -+ synchronize_irq(pf->oicr_irq.virq); -+ - ice_unplug_aux_dev(pf); - - /* Notify VFs of impending reset */ -diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c -index 8d9743a5e42c7..79ec6fcc9e259 100644 ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c -@@ -2374,6 +2374,9 @@ static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cq - if (likely(wi->consumed_strides < rq->mpwqe.num_strides)) - return; - -+ if (unlikely(!cstrides)) -+ return; -+ - wq = &rq->mpwqe.wq; - wqe = mlx5_wq_ll_get_wqe(wq, wqe_id); - mlx5_wq_ll_pop(wq, cqe->wqe_id, &wqe->next.next_wqe_index); -diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c -index d5d2a4c776c1c..ded1bbda5266f 100644 ---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c -@@ -21,6 +21,7 @@ - #define RGMII_IO_MACRO_CONFIG2 0x1C - #define RGMII_IO_MACRO_DEBUG1 0x20 - #define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28 -+#define EMAC_WRAPPER_SGMII_PHY_CNTRL1 0xf4 - - /* RGMII_IO_MACRO_CONFIG fields */ - #define RGMII_CONFIG_FUNC_CLK_EN BIT(30) -@@ -79,6 +80,9 @@ - #define ETHQOS_MAC_CTRL_SPEED_MODE BIT(14) - #define ETHQOS_MAC_CTRL_PORT_SEL BIT(15) - -+/* EMAC_WRAPPER_SGMII_PHY_CNTRL1 bits */ -+#define SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN BIT(3) -+ - #define SGMII_10M_RX_CLK_DVDR 0x31 - - struct ethqos_emac_por { -@@ -95,6 +99,7 @@ struct ethqos_emac_driver_data { - bool has_integrated_pcs; - u32 dma_addr_width; - struct dwmac4_addrs dwmac4_addrs; -+ bool needs_sgmii_loopback; - }; - - struct qcom_ethqos { -@@ -113,6 +118,7 @@ struct qcom_ethqos { - unsigned int num_por; - bool rgmii_config_loopback_en; - bool has_emac_ge_3; -+ bool needs_sgmii_loopback; - }; - - static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset) -@@ -187,8 +193,22 @@ ethqos_update_link_clk(struct qcom_ethqos *ethqos, unsigned int speed) - clk_set_rate(ethqos->link_clk, ethqos->link_clk_rate); - } - -+static void -+qcom_ethqos_set_sgmii_loopback(struct qcom_ethqos *ethqos, bool enable) -+{ -+ if (!ethqos->needs_sgmii_loopback || -+ ethqos->phy_mode != PHY_INTERFACE_MODE_2500BASEX) -+ return; -+ -+ rgmii_updatel(ethqos, -+ SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN, -+ enable ? SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN : 0, -+ EMAC_WRAPPER_SGMII_PHY_CNTRL1); -+} -+ - static void ethqos_set_func_clk_en(struct qcom_ethqos *ethqos) - { -+ qcom_ethqos_set_sgmii_loopback(ethqos, true); - rgmii_updatel(ethqos, RGMII_CONFIG_FUNC_CLK_EN, - RGMII_CONFIG_FUNC_CLK_EN, RGMII_IO_MACRO_CONFIG); - } -@@ -273,6 +293,7 @@ static const struct ethqos_emac_driver_data emac_v4_0_0_data = { - .has_emac_ge_3 = true, - .link_clk_name = "phyaux", - .has_integrated_pcs = true, -+ .needs_sgmii_loopback = true, - .dma_addr_width = 36, - .dwmac4_addrs = { - .dma_chan = 0x00008100, -@@ -646,6 +667,7 @@ static void ethqos_fix_mac_speed(void *priv, unsigned int speed, unsigned int mo - { - struct qcom_ethqos *ethqos = priv; - -+ qcom_ethqos_set_sgmii_loopback(ethqos, false); - ethqos->speed = speed; - ethqos_update_link_clk(ethqos, speed); - ethqos_configure(ethqos); -@@ -781,6 +803,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) - ethqos->num_por = data->num_por; - ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en; - ethqos->has_emac_ge_3 = data->has_emac_ge_3; -+ ethqos->needs_sgmii_loopback = data->needs_sgmii_loopback; - - ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii"); - if (IS_ERR(ethqos->link_clk)) -diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c -index befbca01bfe37..b1380cf1b13ab 100644 ---- a/drivers/net/usb/qmi_wwan.c -+++ b/drivers/net/usb/qmi_wwan.c -@@ -201,6 +201,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) - break; - default: - /* not ip - do not know what to do */ -+ kfree_skb(skbn); - goto skip; - } - -diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h -index c926952c956ef..33f4706af880d 100644 ---- a/drivers/net/wireless/ath/ath12k/core.h -+++ b/drivers/net/wireless/ath/ath12k/core.h -@@ -181,6 +181,8 @@ enum ath12k_dev_flags { - ATH12K_FLAG_REGISTERED, - ATH12K_FLAG_QMI_FAIL, - ATH12K_FLAG_HTC_SUSPEND_COMPLETE, -+ ATH12K_FLAG_CE_IRQ_ENABLED, -+ ATH12K_FLAG_EXT_IRQ_ENABLED, - }; - - enum ath12k_monitor_flags { -diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c -index 2c17b1e7681a5..d9bc07844fb71 100644 ---- a/drivers/net/wireless/ath/ath12k/dp_rx.c -+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c -@@ -2759,6 +2759,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev - peer = ath12k_peer_find(ab, vdev_id, peer_mac); - if (!peer) { - spin_unlock_bh(&ab->base_lock); -+ crypto_free_shash(tfm); - ath12k_warn(ab, "failed to find the peer to set up fragment info\n"); - return -ENOENT; - } -diff --git a/drivers/net/wireless/ath/ath12k/hif.h b/drivers/net/wireless/ath/ath12k/hif.h -index 4cbf9b5c04b9c..c653ca1f59b22 100644 ---- a/drivers/net/wireless/ath/ath12k/hif.h -+++ b/drivers/net/wireless/ath/ath12k/hif.h -@@ -10,17 +10,17 @@ - #include "core.h" - - struct ath12k_hif_ops { -- u32 (*read32)(struct ath12k_base *sc, u32 address); -- void (*write32)(struct ath12k_base *sc, u32 address, u32 data); -- void (*irq_enable)(struct ath12k_base *sc); -- void (*irq_disable)(struct ath12k_base *sc); -- int (*start)(struct ath12k_base *sc); -- void (*stop)(struct ath12k_base *sc); -- int (*power_up)(struct ath12k_base *sc); -- void (*power_down)(struct ath12k_base *sc); -+ u32 (*read32)(struct ath12k_base *ab, u32 address); -+ void (*write32)(struct ath12k_base *ab, u32 address, u32 data); -+ void (*irq_enable)(struct ath12k_base *ab); -+ void (*irq_disable)(struct ath12k_base *ab); -+ int (*start)(struct ath12k_base *ab); -+ void (*stop)(struct ath12k_base *ab); -+ int (*power_up)(struct ath12k_base *ab); -+ void (*power_down)(struct ath12k_base *ab); - int (*suspend)(struct ath12k_base *ab); - int (*resume)(struct ath12k_base *ab); -- int (*map_service_to_pipe)(struct ath12k_base *sc, u16 service_id, -+ int (*map_service_to_pipe)(struct ath12k_base *ab, u16 service_id, - u8 *ul_pipe, u8 *dl_pipe); - int (*get_user_msi_vector)(struct ath12k_base *ab, char *user_name, - int *num_vectors, u32 *user_base_data, -diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c -index 58cd678555964..041a9602f0e15 100644 ---- a/drivers/net/wireless/ath/ath12k/pci.c -+++ b/drivers/net/wireless/ath/ath12k/pci.c -@@ -373,6 +373,8 @@ static void ath12k_pci_ce_irqs_disable(struct ath12k_base *ab) - { - int i; - -+ clear_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags); -+ - for (i = 0; i < ab->hw_params->ce_count; i++) { - if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) - continue; -@@ -406,6 +408,10 @@ static void ath12k_pci_ce_tasklet(struct tasklet_struct *t) - static irqreturn_t ath12k_pci_ce_interrupt_handler(int irq, void *arg) - { - struct ath12k_ce_pipe *ce_pipe = arg; -+ struct ath12k_base *ab = ce_pipe->ab; -+ -+ if (!test_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags)) -+ return IRQ_HANDLED; - - /* last interrupt received for this CE */ - ce_pipe->timestamp = jiffies; -@@ -424,12 +430,15 @@ static void ath12k_pci_ext_grp_disable(struct ath12k_ext_irq_grp *irq_grp) - disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]); - } - --static void __ath12k_pci_ext_irq_disable(struct ath12k_base *sc) -+static void __ath12k_pci_ext_irq_disable(struct ath12k_base *ab) - { - int i; - -+ if (!test_and_clear_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags)) -+ return; -+ - for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { -- struct ath12k_ext_irq_grp *irq_grp = &sc->ext_irq_grp[i]; -+ struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; - - ath12k_pci_ext_grp_disable(irq_grp); - -@@ -483,6 +492,10 @@ static int ath12k_pci_ext_grp_napi_poll(struct napi_struct *napi, int budget) - static irqreturn_t ath12k_pci_ext_interrupt_handler(int irq, void *arg) - { - struct ath12k_ext_irq_grp *irq_grp = arg; -+ struct ath12k_base *ab = irq_grp->ab; -+ -+ if (!test_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags)) -+ return IRQ_HANDLED; - - ath12k_dbg(irq_grp->ab, ATH12K_DBG_PCI, "ext irq:%d\n", irq); - -@@ -626,6 +639,8 @@ static void ath12k_pci_ce_irqs_enable(struct ath12k_base *ab) - { - int i; - -+ set_bit(ATH12K_FLAG_CE_IRQ_ENABLED, &ab->dev_flags); -+ - for (i = 0; i < ab->hw_params->ce_count; i++) { - if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR) - continue; -@@ -956,6 +971,8 @@ void ath12k_pci_ext_irq_enable(struct ath12k_base *ab) - { - int i; - -+ set_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); -+ - for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) { - struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; - -diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c -index 796c2a00fea4a..0fc7aa78b2e5b 100644 ---- a/drivers/nvme/host/pci.c -+++ b/drivers/nvme/host/pci.c -@@ -826,9 +826,9 @@ static blk_status_t nvme_map_metadata(struct nvme_dev *dev, struct request *req, - struct nvme_command *cmnd) - { - struct nvme_iod *iod = blk_mq_rq_to_pdu(req); -+ struct bio_vec bv = rq_integrity_vec(req); - -- iod->meta_dma = dma_map_bvec(dev->dev, rq_integrity_vec(req), -- rq_dma_dir(req), 0); -+ iod->meta_dma = dma_map_bvec(dev->dev, &bv, rq_dma_dir(req), 0); - if (dma_mapping_error(dev->dev, iod->meta_dma)) - return BLK_STS_IOERR; - cmnd->rw.metadata = cpu_to_le64(iod->meta_dma); -@@ -969,7 +969,7 @@ static __always_inline void nvme_pci_unmap_rq(struct request *req) - struct nvme_iod *iod = blk_mq_rq_to_pdu(req); - - dma_unmap_page(dev->dev, iod->meta_dma, -- rq_integrity_vec(req)->bv_len, rq_dma_dir(req)); -+ rq_integrity_vec(req).bv_len, rq_dma_dir(req)); - } - - if (blk_rq_nr_phys_segments(req)) -diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c -index 306f886b52d20..4ff2aa4b484bc 100644 ---- a/drivers/platform/x86/intel/ifs/core.c -+++ b/drivers/platform/x86/intel/ifs/core.c -@@ -1,6 +1,7 @@ - // SPDX-License-Identifier: GPL-2.0-only - /* Copyright(c) 2022 Intel Corporation. */ - -+#include - #include - #include - #include -@@ -94,6 +95,8 @@ static int __init ifs_init(void) - for (i = 0; i < IFS_NUMTESTS; i++) { - if (!(msrval & BIT(ifs_devices[i].test_caps->integrity_cap_bit))) - continue; -+ ifs_devices[i].rw_data.generation = FIELD_GET(MSR_INTEGRITY_CAPS_SAF_GEN_MASK, -+ msrval); - ret = misc_register(&ifs_devices[i].misc); - if (ret) - goto err_exit; -diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h -index 93191855890f2..6bc63ab705175 100644 ---- a/drivers/platform/x86/intel/ifs/ifs.h -+++ b/drivers/platform/x86/intel/ifs/ifs.h -@@ -174,9 +174,17 @@ union ifs_chunks_auth_status { - union ifs_scan { - u64 data; - struct { -- u32 start :8; -- u32 stop :8; -- u32 rsvd :16; -+ union { -+ struct { -+ u8 start; -+ u8 stop; -+ u16 rsvd; -+ } gen0; -+ struct { -+ u16 start; -+ u16 stop; -+ } gen2; -+ }; - u32 delay :31; - u32 sigmce :1; - }; -@@ -186,9 +194,17 @@ union ifs_scan { - union ifs_status { - u64 data; - struct { -- u32 chunk_num :8; -- u32 chunk_stop_index :8; -- u32 rsvd1 :16; -+ union { -+ struct { -+ u8 chunk_num; -+ u8 chunk_stop_index; -+ u16 rsvd1; -+ } gen0; -+ struct { -+ u16 chunk_num; -+ u16 chunk_stop_index; -+ } gen2; -+ }; - u32 error_code :8; - u32 rsvd2 :22; - u32 control_error :1; -@@ -229,6 +245,7 @@ struct ifs_test_caps { - * @status: it holds simple status pass/fail/untested - * @scan_details: opaque scan status code from h/w - * @cur_batch: number indicating the currently loaded test file -+ * @generation: IFS test generation enumerated by hardware - */ - struct ifs_data { - int loaded_version; -@@ -238,6 +255,7 @@ struct ifs_data { - int status; - u64 scan_details; - u32 cur_batch; -+ u32 generation; - }; - - struct ifs_work { -diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c -index 43c864add778f..c7a5bf24bef35 100644 ---- a/drivers/platform/x86/intel/ifs/runtest.c -+++ b/drivers/platform/x86/intel/ifs/runtest.c -@@ -167,25 +167,35 @@ static int doscan(void *data) - */ - static void ifs_test_core(int cpu, struct device *dev) - { -+ union ifs_status status = {}; - union ifs_scan activate; -- union ifs_status status; - unsigned long timeout; - struct ifs_data *ifsd; -+ int to_start, to_stop; -+ int status_chunk; - u64 msrvals[2]; - int retries; - - ifsd = ifs_get_data(dev); - -- activate.rsvd = 0; -+ activate.gen0.rsvd = 0; - activate.delay = IFS_THREAD_WAIT; - activate.sigmce = 0; -- activate.start = 0; -- activate.stop = ifsd->valid_chunks - 1; -+ to_start = 0; -+ to_stop = ifsd->valid_chunks - 1; -+ -+ if (ifsd->generation) { -+ activate.gen2.start = to_start; -+ activate.gen2.stop = to_stop; -+ } else { -+ activate.gen0.start = to_start; -+ activate.gen0.stop = to_stop; -+ } - - timeout = jiffies + HZ / 2; - retries = MAX_IFS_RETRIES; - -- while (activate.start <= activate.stop) { -+ while (to_start <= to_stop) { - if (time_after(jiffies, timeout)) { - status.error_code = IFS_SW_TIMEOUT; - break; -@@ -196,13 +206,14 @@ static void ifs_test_core(int cpu, struct device *dev) - - status.data = msrvals[1]; - -- trace_ifs_status(cpu, activate, status); -+ trace_ifs_status(cpu, to_start, to_stop, status.data); - - /* Some cases can be retried, give up for others */ - if (!can_restart(status)) - break; - -- if (status.chunk_num == activate.start) { -+ status_chunk = ifsd->generation ? status.gen2.chunk_num : status.gen0.chunk_num; -+ if (status_chunk == to_start) { - /* Check for forward progress */ - if (--retries == 0) { - if (status.error_code == IFS_NO_ERROR) -@@ -211,7 +222,11 @@ static void ifs_test_core(int cpu, struct device *dev) - } - } else { - retries = MAX_IFS_RETRIES; -- activate.start = status.chunk_num; -+ if (ifsd->generation) -+ activate.gen2.start = status_chunk; -+ else -+ activate.gen0.start = status_chunk; -+ to_start = status_chunk; - } - } - -diff --git a/drivers/power/supply/axp288_charger.c b/drivers/power/supply/axp288_charger.c -index b5903193e2f96..ac05942e4e6ac 100644 ---- a/drivers/power/supply/axp288_charger.c -+++ b/drivers/power/supply/axp288_charger.c -@@ -178,18 +178,18 @@ static inline int axp288_charger_set_cv(struct axp288_chrg_info *info, int cv) - u8 reg_val; - int ret; - -- if (cv <= CV_4100MV) { -- reg_val = CHRG_CCCV_CV_4100MV; -- cv = CV_4100MV; -- } else if (cv <= CV_4150MV) { -- reg_val = CHRG_CCCV_CV_4150MV; -- cv = CV_4150MV; -- } else if (cv <= CV_4200MV) { -+ if (cv >= CV_4350MV) { -+ reg_val = CHRG_CCCV_CV_4350MV; -+ cv = CV_4350MV; -+ } else if (cv >= CV_4200MV) { - reg_val = CHRG_CCCV_CV_4200MV; - cv = CV_4200MV; -+ } else if (cv >= CV_4150MV) { -+ reg_val = CHRG_CCCV_CV_4150MV; -+ cv = CV_4150MV; - } else { -- reg_val = CHRG_CCCV_CV_4350MV; -- cv = CV_4350MV; -+ reg_val = CHRG_CCCV_CV_4100MV; -+ cv = CV_4100MV; - } - - reg_val = reg_val << CHRG_CCCV_CV_BIT_POS; -@@ -337,8 +337,8 @@ static int axp288_charger_usb_set_property(struct power_supply *psy, - } - break; - case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: -- scaled_val = min(val->intval, info->max_cv); -- scaled_val = DIV_ROUND_CLOSEST(scaled_val, 1000); -+ scaled_val = DIV_ROUND_CLOSEST(val->intval, 1000); -+ scaled_val = min(scaled_val, info->max_cv); - ret = axp288_charger_set_cv(info, scaled_val); - if (ret < 0) { - dev_warn(&info->pdev->dev, "set charge voltage failed\n"); -diff --git a/drivers/power/supply/qcom_battmgr.c b/drivers/power/supply/qcom_battmgr.c -index ec163d1bcd189..44c6301f5f174 100644 ---- a/drivers/power/supply/qcom_battmgr.c -+++ b/drivers/power/supply/qcom_battmgr.c -@@ -486,7 +486,7 @@ static int qcom_battmgr_bat_get_property(struct power_supply *psy, - int ret; - - if (!battmgr->service_up) -- return -ENODEV; -+ return -EAGAIN; - - if (battmgr->variant == QCOM_BATTMGR_SC8280XP) - ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp); -@@ -683,7 +683,7 @@ static int qcom_battmgr_ac_get_property(struct power_supply *psy, - int ret; - - if (!battmgr->service_up) -- return -ENODEV; -+ return -EAGAIN; - - ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp); - if (ret) -@@ -748,7 +748,7 @@ static int qcom_battmgr_usb_get_property(struct power_supply *psy, - int ret; - - if (!battmgr->service_up) -- return -ENODEV; -+ return -EAGAIN; - - if (battmgr->variant == QCOM_BATTMGR_SC8280XP) - ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp); -@@ -867,7 +867,7 @@ static int qcom_battmgr_wls_get_property(struct power_supply *psy, - int ret; - - if (!battmgr->service_up) -- return -ENODEV; -+ return -EAGAIN; - - if (battmgr->variant == QCOM_BATTMGR_SC8280XP) - ret = qcom_battmgr_bat_sc8280xp_update(battmgr, psp); -diff --git a/drivers/s390/char/sclp_sd.c b/drivers/s390/char/sclp_sd.c -index f9e164be7568f..944e75beb160c 100644 ---- a/drivers/s390/char/sclp_sd.c -+++ b/drivers/s390/char/sclp_sd.c -@@ -320,8 +320,14 @@ static int sclp_sd_store_data(struct sclp_sd_data *result, u8 di) - &esize); - if (rc) { - /* Cancel running request if interrupted */ -- if (rc == -ERESTARTSYS) -- sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL); -+ if (rc == -ERESTARTSYS) { -+ if (sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL)) { -+ pr_warn("Could not stop Store Data request - leaking at least %zu bytes\n", -+ (size_t)dsize * PAGE_SIZE); -+ data = NULL; -+ asce = 0; -+ } -+ } - vfree(data); - goto out; - } -diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c -index 80d71041086e1..7f32619234696 100644 ---- a/drivers/scsi/mpi3mr/mpi3mr_os.c -+++ b/drivers/scsi/mpi3mr/mpi3mr_os.c -@@ -3447,6 +3447,17 @@ static int mpi3mr_prepare_sg_scmd(struct mpi3mr_ioc *mrioc, - scmd->sc_data_direction); - priv->meta_sg_valid = 1; /* To unmap meta sg DMA */ - } else { -+ /* -+ * Some firmware versions byte-swap the REPORT ZONES command -+ * reply from ATA-ZAC devices by directly accessing in the host -+ * buffer. This does not respect the default command DMA -+ * direction and causes IOMMU page faults on some architectures -+ * with an IOMMU enforcing write mappings (e.g. AMD hosts). -+ * Avoid such issue by making the REPORT ZONES buffer mapping -+ * bi-directional. -+ */ -+ if (scmd->cmnd[0] == ZBC_IN && scmd->cmnd[1] == ZI_REPORT_ZONES) -+ scmd->sc_data_direction = DMA_BIDIRECTIONAL; - sg_scmd = scsi_sglist(scmd); - sges_left = scsi_dma_map(scmd); - } -diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c -index 04116e02ffe8c..8acf586dc8b2e 100644 ---- a/drivers/scsi/mpt3sas/mpt3sas_base.c -+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c -@@ -2671,6 +2671,22 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr) - _base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1); - } - -+static inline int _base_scsi_dma_map(struct scsi_cmnd *cmd) -+{ -+ /* -+ * Some firmware versions byte-swap the REPORT ZONES command reply from -+ * ATA-ZAC devices by directly accessing in the host buffer. This does -+ * not respect the default command DMA direction and causes IOMMU page -+ * faults on some architectures with an IOMMU enforcing write mappings -+ * (e.g. AMD hosts). Avoid such issue by making the report zones buffer -+ * mapping bi-directional. -+ */ -+ if (cmd->cmnd[0] == ZBC_IN && cmd->cmnd[1] == ZI_REPORT_ZONES) -+ cmd->sc_data_direction = DMA_BIDIRECTIONAL; -+ -+ return scsi_dma_map(cmd); -+} -+ - /** - * _base_build_sg_scmd - main sg creation routine - * pcie_device is unused here! -@@ -2717,7 +2733,7 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc, - sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; - - sg_scmd = scsi_sglist(scmd); -- sges_left = scsi_dma_map(scmd); -+ sges_left = _base_scsi_dma_map(scmd); - if (sges_left < 0) - return -ENOMEM; - -@@ -2861,7 +2877,7 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc, - } - - sg_scmd = scsi_sglist(scmd); -- sges_left = scsi_dma_map(scmd); -+ sges_left = _base_scsi_dma_map(scmd); - if (sges_left < 0) - return -ENOMEM; - -diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c -index 079035db7dd85..3c0f7dc9614d1 100644 ---- a/drivers/spi/spi-fsl-lpspi.c -+++ b/drivers/spi/spi-fsl-lpspi.c -@@ -296,7 +296,7 @@ static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi) - static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) - { - struct lpspi_config config = fsl_lpspi->config; -- unsigned int perclk_rate, scldiv; -+ unsigned int perclk_rate, scldiv, div; - u8 prescale; - - perclk_rate = clk_get_rate(fsl_lpspi->clk_per); -@@ -313,8 +313,10 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) - return -EINVAL; - } - -+ div = DIV_ROUND_UP(perclk_rate, config.speed_hz); -+ - for (prescale = 0; prescale < 8; prescale++) { -- scldiv = perclk_rate / config.speed_hz / (1 << prescale) - 2; -+ scldiv = div / (1 << prescale) - 2; - if (scldiv < 256) { - fsl_lpspi->config.prescale = prescale; - break; -diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c -index 1a8dd10012448..b97206d47ec6d 100644 ---- a/drivers/spi/spidev.c -+++ b/drivers/spi/spidev.c -@@ -704,6 +704,7 @@ static const struct file_operations spidev_fops = { - static struct class *spidev_class; - - static const struct spi_device_id spidev_spi_ids[] = { -+ { .name = "bh2228fv" }, - { .name = "dh2228fv" }, - { .name = "ltc2488" }, - { .name = "sx1301" }, -diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c -index 2eceef54e0b30..ed8798fdf522a 100644 ---- a/drivers/tty/serial/serial_core.c -+++ b/drivers/tty/serial/serial_core.c -@@ -876,6 +876,14 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, - new_flags = (__force upf_t)new_info->flags; - old_custom_divisor = uport->custom_divisor; - -+ if (!(uport->flags & UPF_FIXED_PORT)) { -+ unsigned int uartclk = new_info->baud_base * 16; -+ /* check needs to be done here before other settings made */ -+ if (uartclk == 0) { -+ retval = -EINVAL; -+ goto exit; -+ } -+ } - if (!capable(CAP_SYS_ADMIN)) { - retval = -EPERM; - if (change_irq || change_port || -diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c -index 808979a093505..94edac17b95f8 100644 ---- a/drivers/ufs/core/ufshcd.c -+++ b/drivers/ufs/core/ufshcd.c -@@ -3971,11 +3971,16 @@ static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba) - min_sleep_time_us = - MIN_DELAY_BEFORE_DME_CMDS_US - delta; - else -- return; /* no more delay required */ -+ min_sleep_time_us = 0; /* no more delay required */ - } - -- /* allow sleep for extra 50us if needed */ -- usleep_range(min_sleep_time_us, min_sleep_time_us + 50); -+ if (min_sleep_time_us > 0) { -+ /* allow sleep for extra 50us if needed */ -+ usleep_range(min_sleep_time_us, min_sleep_time_us + 50); -+ } -+ -+ /* update the last_dme_cmd_tstamp */ -+ hba->last_dme_cmd_tstamp = ktime_get(); - } - - /** -@@ -10157,9 +10162,6 @@ int ufshcd_system_restore(struct device *dev) - */ - ufshcd_readl(hba, REG_UTP_TASK_REQ_LIST_BASE_H); - -- /* Resuming from hibernate, assume that link was OFF */ -- ufshcd_set_link_off(hba); -- - return 0; - - } -diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c -index 0e38bb145e8f5..6908fdd4a83f3 100644 ---- a/drivers/usb/gadget/function/f_midi2.c -+++ b/drivers/usb/gadget/function/f_midi2.c -@@ -642,12 +642,21 @@ static void process_ump_stream_msg(struct f_midi2_ep *ep, const u32 *data) - if (format) - return; // invalid - blk = (*data >> 8) & 0xff; -- if (blk >= ep->num_blks) -- return; -- if (*data & UMP_STREAM_MSG_REQUEST_FB_INFO) -- reply_ump_stream_fb_info(ep, blk); -- if (*data & UMP_STREAM_MSG_REQUEST_FB_NAME) -- reply_ump_stream_fb_name(ep, blk); -+ if (blk == 0xff) { -+ /* inquiry for all blocks */ -+ for (blk = 0; blk < ep->num_blks; blk++) { -+ if (*data & UMP_STREAM_MSG_REQUEST_FB_INFO) -+ reply_ump_stream_fb_info(ep, blk); -+ if (*data & UMP_STREAM_MSG_REQUEST_FB_NAME) -+ reply_ump_stream_fb_name(ep, blk); -+ } -+ } else if (blk < ep->num_blks) { -+ /* only the specified block */ -+ if (*data & UMP_STREAM_MSG_REQUEST_FB_INFO) -+ reply_ump_stream_fb_info(ep, blk); -+ if (*data & UMP_STREAM_MSG_REQUEST_FB_NAME) -+ reply_ump_stream_fb_name(ep, blk); -+ } - return; - } - } -diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c -index ec1dceb087293..0be0966973c7f 100644 ---- a/drivers/usb/gadget/function/u_audio.c -+++ b/drivers/usb/gadget/function/u_audio.c -@@ -592,16 +592,25 @@ int u_audio_start_capture(struct g_audio *audio_dev) - struct usb_ep *ep, *ep_fback; - struct uac_rtd_params *prm; - struct uac_params *params = &audio_dev->params; -- int req_len, i; -+ int req_len, i, ret; - - prm = &uac->c_prm; - dev_dbg(dev, "start capture with rate %d\n", prm->srate); - ep = audio_dev->out_ep; -- config_ep_by_speed(gadget, &audio_dev->func, ep); -+ ret = config_ep_by_speed(gadget, &audio_dev->func, ep); -+ if (ret < 0) { -+ dev_err(dev, "config_ep_by_speed for out_ep failed (%d)\n", ret); -+ return ret; -+ } -+ - req_len = ep->maxpacket; - - prm->ep_enabled = true; -- usb_ep_enable(ep); -+ ret = usb_ep_enable(ep); -+ if (ret < 0) { -+ dev_err(dev, "usb_ep_enable failed for out_ep (%d)\n", ret); -+ return ret; -+ } - - for (i = 0; i < params->req_number; i++) { - if (!prm->reqs[i]) { -@@ -629,9 +638,18 @@ int u_audio_start_capture(struct g_audio *audio_dev) - return 0; - - /* Setup feedback endpoint */ -- config_ep_by_speed(gadget, &audio_dev->func, ep_fback); -+ ret = config_ep_by_speed(gadget, &audio_dev->func, ep_fback); -+ if (ret < 0) { -+ dev_err(dev, "config_ep_by_speed in_ep_fback failed (%d)\n", ret); -+ return ret; // TODO: Clean up out_ep -+ } -+ - prm->fb_ep_enabled = true; -- usb_ep_enable(ep_fback); -+ ret = usb_ep_enable(ep_fback); -+ if (ret < 0) { -+ dev_err(dev, "usb_ep_enable failed for in_ep_fback (%d)\n", ret); -+ return ret; // TODO: Clean up out_ep -+ } - req_len = ep_fback->maxpacket; - - req_fback = usb_ep_alloc_request(ep_fback, GFP_ATOMIC); -@@ -687,13 +705,17 @@ int u_audio_start_playback(struct g_audio *audio_dev) - struct uac_params *params = &audio_dev->params; - unsigned int factor; - const struct usb_endpoint_descriptor *ep_desc; -- int req_len, i; -+ int req_len, i, ret; - unsigned int p_pktsize; - - prm = &uac->p_prm; - dev_dbg(dev, "start playback with rate %d\n", prm->srate); - ep = audio_dev->in_ep; -- config_ep_by_speed(gadget, &audio_dev->func, ep); -+ ret = config_ep_by_speed(gadget, &audio_dev->func, ep); -+ if (ret < 0) { -+ dev_err(dev, "config_ep_by_speed for in_ep failed (%d)\n", ret); -+ return ret; -+ } - - ep_desc = ep->desc; - /* -@@ -720,7 +742,11 @@ int u_audio_start_playback(struct g_audio *audio_dev) - uac->p_residue_mil = 0; - - prm->ep_enabled = true; -- usb_ep_enable(ep); -+ ret = usb_ep_enable(ep); -+ if (ret < 0) { -+ dev_err(dev, "usb_ep_enable failed for in_ep (%d)\n", ret); -+ return ret; -+ } - - for (i = 0; i < params->req_number; i++) { - if (!prm->reqs[i]) { -diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c -index a92eb6d909768..8962f96ae7294 100644 ---- a/drivers/usb/gadget/function/u_serial.c -+++ b/drivers/usb/gadget/function/u_serial.c -@@ -1441,6 +1441,7 @@ void gserial_suspend(struct gserial *gser) - spin_lock(&port->port_lock); - spin_unlock(&serial_port_lock); - port->suspended = true; -+ port->start_delayed = true; - spin_unlock_irqrestore(&port->port_lock, flags); - } - EXPORT_SYMBOL_GPL(gserial_suspend); -diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c -index 358394fc3db93..9886e1cb13985 100644 ---- a/drivers/usb/gadget/udc/core.c -+++ b/drivers/usb/gadget/udc/core.c -@@ -118,12 +118,10 @@ int usb_ep_enable(struct usb_ep *ep) - goto out; - - /* UDC drivers can't handle endpoints with maxpacket size 0 */ -- if (usb_endpoint_maxp(ep->desc) == 0) { -- /* -- * We should log an error message here, but we can't call -- * dev_err() because there's no way to find the gadget -- * given only ep. -- */ -+ if (!ep->desc || usb_endpoint_maxp(ep->desc) == 0) { -+ WARN_ONCE(1, "%s: ep%d (%s) has %s\n", __func__, ep->address, ep->name, -+ (!ep->desc) ? "NULL descriptor" : "maxpacket 0"); -+ - ret = -EINVAL; - goto out; - } -diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c -index 6934970f180d7..5a8869cd95d52 100644 ---- a/drivers/usb/serial/usb_debug.c -+++ b/drivers/usb/serial/usb_debug.c -@@ -76,6 +76,11 @@ static void usb_debug_process_read_urb(struct urb *urb) - usb_serial_generic_process_read_urb(urb); - } - -+static void usb_debug_init_termios(struct tty_struct *tty) -+{ -+ tty->termios.c_lflag &= ~(ECHO | ECHONL); -+} -+ - static struct usb_serial_driver debug_device = { - .driver = { - .owner = THIS_MODULE, -@@ -85,6 +90,7 @@ static struct usb_serial_driver debug_device = { - .num_ports = 1, - .bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE, - .break_ctl = usb_debug_break_ctl, -+ .init_termios = usb_debug_init_termios, - .process_read_urb = usb_debug_process_read_urb, - }; - -@@ -96,6 +102,7 @@ static struct usb_serial_driver dbc_device = { - .id_table = dbc_id_table, - .num_ports = 1, - .break_ctl = usb_debug_break_ctl, -+ .init_termios = usb_debug_init_termios, - .process_read_urb = usb_debug_process_read_urb, - }; - -diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c -index 37d1fc34e8a56..14a5f55f24fc8 100644 ---- a/drivers/usb/usbip/vhci_hcd.c -+++ b/drivers/usb/usbip/vhci_hcd.c -@@ -745,6 +745,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag - * - */ - if (usb_pipedevice(urb->pipe) == 0) { -+ struct usb_device *old; - __u8 type = usb_pipetype(urb->pipe); - struct usb_ctrlrequest *ctrlreq = - (struct usb_ctrlrequest *) urb->setup_packet; -@@ -755,14 +756,15 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag - goto no_need_xmit; - } - -+ old = vdev->udev; - switch (ctrlreq->bRequest) { - case USB_REQ_SET_ADDRESS: - /* set_address may come when a device is reset */ - dev_info(dev, "SetAddress Request (%d) to port %d\n", - ctrlreq->wValue, vdev->rhport); - -- usb_put_dev(vdev->udev); - vdev->udev = usb_get_dev(urb->dev); -+ usb_put_dev(old); - - spin_lock(&vdev->ud.lock); - vdev->ud.status = VDEV_ST_USED; -@@ -781,8 +783,8 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag - usbip_dbg_vhci_hc( - "Not yet?:Get_Descriptor to device 0 (get max pipe size)\n"); - -- usb_put_dev(vdev->udev); - vdev->udev = usb_get_dev(urb->dev); -+ usb_put_dev(old); - goto out; - - default: -@@ -1067,6 +1069,7 @@ static void vhci_shutdown_connection(struct usbip_device *ud) - static void vhci_device_reset(struct usbip_device *ud) - { - struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); -+ struct usb_device *old = vdev->udev; - unsigned long flags; - - spin_lock_irqsave(&ud->lock, flags); -@@ -1074,8 +1077,8 @@ static void vhci_device_reset(struct usbip_device *ud) - vdev->speed = 0; - vdev->devid = 0; - -- usb_put_dev(vdev->udev); - vdev->udev = NULL; -+ usb_put_dev(old); - - if (ud->tcp_socket) { - sockfd_put(ud->tcp_socket); -diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c -index fb590e346e43d..da2c31ccc1380 100644 ---- a/drivers/vhost/vdpa.c -+++ b/drivers/vhost/vdpa.c -@@ -1378,13 +1378,7 @@ static vm_fault_t vhost_vdpa_fault(struct vm_fault *vmf) - - notify = ops->get_vq_notification(vdpa, index); - -- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -- if (remap_pfn_range(vma, vmf->address & PAGE_MASK, -- PFN_DOWN(notify.addr), PAGE_SIZE, -- vma->vm_page_prot)) -- return VM_FAULT_SIGBUS; -- -- return VM_FAULT_NOPAGE; -+ return vmf_insert_pfn(vma, vmf->address & PAGE_MASK, PFN_DOWN(notify.addr)); - } - - static const struct vm_operations_struct vhost_vdpa_vm_ops = { -diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c -index da88173bac432..923f064c7e3e9 100644 ---- a/drivers/xen/privcmd.c -+++ b/drivers/xen/privcmd.c -@@ -841,7 +841,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file, - #ifdef CONFIG_XEN_PRIVCMD_IRQFD - /* Irqfd support */ - static struct workqueue_struct *irqfd_cleanup_wq; --static DEFINE_MUTEX(irqfds_lock); -+static DEFINE_SPINLOCK(irqfds_lock); - static LIST_HEAD(irqfds_list); - - struct privcmd_kernel_irqfd { -@@ -905,9 +905,11 @@ irqfd_wakeup(wait_queue_entry_t *wait, unsigned int mode, int sync, void *key) - irqfd_inject(kirqfd); - - if (flags & EPOLLHUP) { -- mutex_lock(&irqfds_lock); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&irqfds_lock, flags); - irqfd_deactivate(kirqfd); -- mutex_unlock(&irqfds_lock); -+ spin_unlock_irqrestore(&irqfds_lock, flags); - } - - return 0; -@@ -925,6 +927,7 @@ irqfd_poll_func(struct file *file, wait_queue_head_t *wqh, poll_table *pt) - static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) - { - struct privcmd_kernel_irqfd *kirqfd, *tmp; -+ unsigned long flags; - __poll_t events; - struct fd f; - void *dm_op; -@@ -964,18 +967,18 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd) - init_waitqueue_func_entry(&kirqfd->wait, irqfd_wakeup); - init_poll_funcptr(&kirqfd->pt, irqfd_poll_func); - -- mutex_lock(&irqfds_lock); -+ spin_lock_irqsave(&irqfds_lock, flags); - - list_for_each_entry(tmp, &irqfds_list, list) { - if (kirqfd->eventfd == tmp->eventfd) { - ret = -EBUSY; -- mutex_unlock(&irqfds_lock); -+ spin_unlock_irqrestore(&irqfds_lock, flags); - goto error_eventfd; - } - } - - list_add_tail(&kirqfd->list, &irqfds_list); -- mutex_unlock(&irqfds_lock); -+ spin_unlock_irqrestore(&irqfds_lock, flags); - - /* - * Check if there was an event already pending on the eventfd before we -@@ -1007,12 +1010,13 @@ static int privcmd_irqfd_deassign(struct privcmd_irqfd *irqfd) - { - struct privcmd_kernel_irqfd *kirqfd; - struct eventfd_ctx *eventfd; -+ unsigned long flags; - - eventfd = eventfd_ctx_fdget(irqfd->fd); - if (IS_ERR(eventfd)) - return PTR_ERR(eventfd); - -- mutex_lock(&irqfds_lock); -+ spin_lock_irqsave(&irqfds_lock, flags); - - list_for_each_entry(kirqfd, &irqfds_list, list) { - if (kirqfd->eventfd == eventfd) { -@@ -1021,7 +1025,7 @@ static int privcmd_irqfd_deassign(struct privcmd_irqfd *irqfd) - } - } - -- mutex_unlock(&irqfds_lock); -+ spin_unlock_irqrestore(&irqfds_lock, flags); - - eventfd_ctx_put(eventfd); - -@@ -1069,13 +1073,14 @@ static int privcmd_irqfd_init(void) - static void privcmd_irqfd_exit(void) - { - struct privcmd_kernel_irqfd *kirqfd, *tmp; -+ unsigned long flags; - -- mutex_lock(&irqfds_lock); -+ spin_lock_irqsave(&irqfds_lock, flags); - - list_for_each_entry_safe(kirqfd, tmp, &irqfds_list, list) - irqfd_deactivate(kirqfd); - -- mutex_unlock(&irqfds_lock); -+ spin_unlock_irqrestore(&irqfds_lock, flags); - - destroy_workqueue(irqfd_cleanup_wq); - } -diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h -index 06333a74d6c4c..86c7f8ce1715e 100644 ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -445,6 +445,7 @@ struct btrfs_file_private { - void *filldir_buf; - u64 last_index; - struct extent_state *llseek_cached_state; -+ bool fsync_skip_inode_lock; - }; - - static inline u32 BTRFS_LEAF_DATA_SIZE(const struct btrfs_fs_info *info) -diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c -index 9fbffd84b16c5..c6a95dfa59c81 100644 ---- a/fs/btrfs/extent_io.c -+++ b/fs/btrfs/extent_io.c -@@ -2172,10 +2172,8 @@ void extent_write_locked_range(struct inode *inode, struct page *locked_page, - - page = find_get_page(mapping, cur >> PAGE_SHIFT); - ASSERT(PageLocked(page)); -- if (pages_dirty && page != locked_page) { -+ if (pages_dirty && page != locked_page) - ASSERT(PageDirty(page)); -- clear_page_dirty_for_io(page); -- } - - ret = __extent_writepage_io(BTRFS_I(inode), page, &bio_ctrl, - i_size, &nr); -diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c -index c997b790568fa..952cf145c6295 100644 ---- a/fs/btrfs/file.c -+++ b/fs/btrfs/file.c -@@ -1535,21 +1535,37 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from) - * 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; - 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(BTRFS_I(inode), ilock_flags); -- -- if (IS_ERR_OR_NULL(dio)) -+ if (IS_ERR_OR_NULL(dio)) { - err = PTR_ERR_OR_ZERO(dio); -- else -+ } else { -+ struct btrfs_file_private stack_private = { 0 }; -+ struct btrfs_file_private *private; -+ const bool have_private = (file->private_data != NULL); -+ -+ if (!have_private) -+ file->private_data = &stack_private; -+ -+ /* -+ * If we have a synchoronous write, we must make sure the fsync -+ * triggered by the iomap_dio_complete() call below doesn't -+ * deadlock on the inode lock - we are already holding it and we -+ * can't call it after unlocking because we may need to complete -+ * partial writes due to the input buffer (or parts of it) not -+ * being already faulted in. -+ */ -+ private = file->private_data; -+ private->fsync_skip_inode_lock = true; - err = iomap_dio_complete(dio); -+ private->fsync_skip_inode_lock = false; -+ -+ if (!have_private) -+ file->private_data = NULL; -+ } - - /* No increment (+=) because iomap returns a cumulative value. */ - if (err > 0) -@@ -1576,10 +1592,12 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from) - } else { - fault_in_iov_iter_readable(from, left); - prev_left = left; -- goto relock; -+ goto again; - } - } - -+ btrfs_inode_unlock(BTRFS_I(inode), ilock_flags); -+ - /* - * If 'err' is -ENOTBLK or we have not written all data, then it means - * we must fallback to buffered IO. -@@ -1778,6 +1796,7 @@ static inline bool skip_inode_logging(const struct btrfs_log_ctx *ctx) - */ - int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) - { -+ struct btrfs_file_private *private = file->private_data; - struct dentry *dentry = file_dentry(file); - struct inode *inode = d_inode(dentry); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); -@@ -1787,6 +1806,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) - int ret = 0, err; - u64 len; - bool full_sync; -+ const bool skip_ilock = (private ? private->fsync_skip_inode_lock : false); - - trace_btrfs_sync_file(file, datasync); - -@@ -1814,7 +1834,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) - if (ret) - goto out; - -- btrfs_inode_lock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); -+ if (skip_ilock) -+ down_write(&BTRFS_I(inode)->i_mmap_lock); -+ else -+ btrfs_inode_lock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); - - atomic_inc(&root->log_batch); - -@@ -1838,7 +1861,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) - */ - ret = start_ordered_ops(inode, start, end); - if (ret) { -- btrfs_inode_unlock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); -+ if (skip_ilock) -+ up_write(&BTRFS_I(inode)->i_mmap_lock); -+ else -+ btrfs_inode_unlock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); - goto out; - } - -@@ -1941,7 +1967,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) - * file again, but that will end up using the synchronization - * inside btrfs_sync_log to keep things safe. - */ -- btrfs_inode_unlock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); -+ if (skip_ilock) -+ up_write(&BTRFS_I(inode)->i_mmap_lock); -+ else -+ btrfs_inode_unlock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); - - if (ret == BTRFS_NO_LOG_SYNC) { - ret = btrfs_end_transaction(trans); -@@ -2009,7 +2038,10 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) - - out_release_extents: - btrfs_release_log_ctx_extents(&ctx); -- btrfs_inode_unlock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); -+ if (skip_ilock) -+ up_write(&BTRFS_I(inode)->i_mmap_lock); -+ else -+ btrfs_inode_unlock(BTRFS_I(inode), BTRFS_ILOCK_MMAP); - goto out; - } - -diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c -index f59e599766662..3e141c4dd2630 100644 ---- a/fs/btrfs/free-space-cache.c -+++ b/fs/btrfs/free-space-cache.c -@@ -855,6 +855,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, - spin_unlock(&ctl->tree_lock); - btrfs_err(fs_info, - "Duplicate entries in free space cache, dumping"); -+ kmem_cache_free(btrfs_free_space_bitmap_cachep, e->bitmap); - kmem_cache_free(btrfs_free_space_cachep, e); - goto free_cache; - } -diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c -index 0c93439e929fb..815a5fc3ff9d8 100644 ---- a/fs/btrfs/print-tree.c -+++ b/fs/btrfs/print-tree.c -@@ -12,7 +12,7 @@ - - struct root_name_map { - u64 id; -- char name[16]; -+ const char *name; - }; - - static const struct root_name_map root_map[] = { -diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c -index 012d9259ff532..a604aa1d23aed 100644 ---- a/fs/ext4/inline.c -+++ b/fs/ext4/inline.c -@@ -1411,7 +1411,11 @@ int ext4_inlinedir_to_tree(struct file *dir_file, - hinfo->hash = EXT4_DIRENT_HASH(de); - hinfo->minor_hash = EXT4_DIRENT_MINOR_HASH(de); - } else { -- ext4fs_dirhash(dir, de->name, de->name_len, hinfo); -+ err = ext4fs_dirhash(dir, de->name, de->name_len, hinfo); -+ if (err) { -+ ret = err; -+ goto out; -+ } - } - if ((hinfo->hash < start_hash) || - ((hinfo->hash == start_hash) && -diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c -index 0168d28427077..57264eb4d9da3 100644 ---- a/fs/jbd2/journal.c -+++ b/fs/jbd2/journal.c -@@ -399,6 +399,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, - tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS); - if (!tmp) { - brelse(new_bh); -+ free_buffer_head(new_bh); - return -ENOMEM; - } - spin_lock(&jh_in->b_state_lock); -diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c -index c71ae5c043060..4a20e92474b23 100644 ---- a/fs/smb/client/cifs_debug.c -+++ b/fs/smb/client/cifs_debug.c -@@ -1072,7 +1072,7 @@ static int cifs_security_flags_proc_open(struct inode *inode, struct file *file) - static void - cifs_security_flags_handle_must_flags(unsigned int *flags) - { -- unsigned int signflags = *flags & CIFSSEC_MUST_SIGN; -+ unsigned int signflags = *flags & (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL); - - if ((*flags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) - *flags = CIFSSEC_MUST_KRB5; -diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h -index 53e00255d96b6..54a84003950a4 100644 ---- a/fs/smb/client/cifsglob.h -+++ b/fs/smb/client/cifsglob.h -@@ -1922,7 +1922,7 @@ static inline bool is_replayable_error(int error) - #define CIFSSEC_MAY_SIGN 0x00001 - #define CIFSSEC_MAY_NTLMV2 0x00004 - #define CIFSSEC_MAY_KRB5 0x00008 --#define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */ -+#define CIFSSEC_MAY_SEAL 0x00040 - #define CIFSSEC_MAY_NTLMSSP 0x00080 /* raw ntlmssp with ntlmv2 */ - - #define CIFSSEC_MUST_SIGN 0x01001 -@@ -1932,11 +1932,11 @@ require use of the stronger protocol */ - #define CIFSSEC_MUST_NTLMV2 0x04004 - #define CIFSSEC_MUST_KRB5 0x08008 - #ifdef CONFIG_CIFS_UPCALL --#define CIFSSEC_MASK 0x8F08F /* flags supported if no weak allowed */ -+#define CIFSSEC_MASK 0xCF0CF /* flags supported if no weak allowed */ - #else --#define CIFSSEC_MASK 0x87087 /* flags supported if no weak allowed */ -+#define CIFSSEC_MASK 0xC70C7 /* flags supported if no weak allowed */ - #endif /* UPCALL */ --#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ -+#define CIFSSEC_MUST_SEAL 0x40040 - #define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */ - - #define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_NTLMSSP | CIFSSEC_MAY_SEAL) -diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c -index 9cdbc3ccc1d14..e74ba047902d8 100644 ---- a/fs/smb/client/inode.c -+++ b/fs/smb/client/inode.c -@@ -1023,13 +1023,26 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data, - } - - rc = -EOPNOTSUPP; -- switch ((data->reparse.tag = tag)) { -- case 0: /* SMB1 symlink */ -+ data->reparse.tag = tag; -+ if (!data->reparse.tag) { - if (server->ops->query_symlink) { - rc = server->ops->query_symlink(xid, tcon, - cifs_sb, full_path, - &data->symlink_target); - } -+ if (rc == -EOPNOTSUPP) -+ data->reparse.tag = IO_REPARSE_TAG_INTERNAL; -+ } -+ -+ switch (data->reparse.tag) { -+ case 0: /* SMB1 symlink */ -+ break; -+ case IO_REPARSE_TAG_INTERNAL: -+ rc = 0; -+ if (le32_to_cpu(data->fi.Attributes) & ATTR_DIRECTORY) { -+ cifs_create_junction_fattr(fattr, sb); -+ goto out; -+ } - break; - case IO_REPARSE_TAG_MOUNT_POINT: - cifs_create_junction_fattr(fattr, sb); -diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c -index 07c468ddb88a8..65d4b72b4d51a 100644 ---- a/fs/smb/client/misc.c -+++ b/fs/smb/client/misc.c -@@ -1288,6 +1288,7 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid, - const char *full_path, - bool *islink) - { -+ struct TCP_Server_Info *server = tcon->ses->server; - struct cifs_ses *ses = tcon->ses; - size_t len; - char *path; -@@ -1304,12 +1305,12 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid, - !is_tcon_dfs(tcon)) - return 0; - -- spin_lock(&tcon->tc_lock); -- if (!tcon->origin_fullpath) { -- spin_unlock(&tcon->tc_lock); -+ spin_lock(&server->srv_lock); -+ if (!server->leaf_fullpath) { -+ spin_unlock(&server->srv_lock); - return 0; - } -- spin_unlock(&tcon->tc_lock); -+ spin_unlock(&server->srv_lock); - - /* - * Slow path - tcon is DFS and @full_path has prefix path, so attempt -diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c -index a0ffbda907331..689d8a506d459 100644 ---- a/fs/smb/client/reparse.c -+++ b/fs/smb/client/reparse.c -@@ -505,6 +505,10 @@ bool cifs_reparse_point_to_fattr(struct cifs_sb_info *cifs_sb, - } - - switch (tag) { -+ case IO_REPARSE_TAG_INTERNAL: -+ if (!(fattr->cf_cifsattrs & ATTR_DIRECTORY)) -+ return false; -+ fallthrough; - case IO_REPARSE_TAG_DFS: - case IO_REPARSE_TAG_DFSR: - case IO_REPARSE_TAG_MOUNT_POINT: -diff --git a/fs/smb/client/reparse.h b/fs/smb/client/reparse.h -index 6b55d1df9e2f8..2c0644bc4e65a 100644 ---- a/fs/smb/client/reparse.h -+++ b/fs/smb/client/reparse.h -@@ -12,6 +12,12 @@ - #include "fs_context.h" - #include "cifsglob.h" - -+/* -+ * Used only by cifs.ko to ignore reparse points from files when client or -+ * server doesn't support FSCTL_GET_REPARSE_POINT. -+ */ -+#define IO_REPARSE_TAG_INTERNAL ((__u32)~0U) -+ - static inline dev_t reparse_nfs_mkdev(struct reparse_posix_data *buf) - { - u64 v = le64_to_cpu(*(__le64 *)buf->DataBuffer); -@@ -78,10 +84,19 @@ static inline u32 reparse_mode_wsl_tag(mode_t mode) - static inline bool reparse_inode_match(struct inode *inode, - struct cifs_fattr *fattr) - { -+ struct cifsInodeInfo *cinode = CIFS_I(inode); - struct timespec64 ctime = inode_get_ctime(inode); - -- return (CIFS_I(inode)->cifsAttrs & ATTR_REPARSE) && -- CIFS_I(inode)->reparse_tag == fattr->cf_cifstag && -+ /* -+ * Do not match reparse tags when client or server doesn't support -+ * FSCTL_GET_REPARSE_POINT. @fattr->cf_cifstag should contain correct -+ * reparse tag from query dir response but the client won't be able to -+ * read the reparse point data anyway. This spares us a revalidation. -+ */ -+ if (cinode->reparse_tag != IO_REPARSE_TAG_INTERNAL && -+ cinode->reparse_tag != fattr->cf_cifstag) -+ return false; -+ return (cinode->cifsAttrs & ATTR_REPARSE) && - timespec64_equal(&ctime, &fattr->cf_ctime); - } - -diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c -index 86f8c81791374..28031c7ba6b19 100644 ---- a/fs/smb/client/smb2inode.c -+++ b/fs/smb/client/smb2inode.c -@@ -930,6 +930,8 @@ int smb2_query_path_info(const unsigned int xid, - - switch (rc) { - case 0: -+ rc = parse_create_response(data, cifs_sb, &out_iov[0]); -+ break; - case -EOPNOTSUPP: - /* - * BB TODO: When support for special files added to Samba -diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c -index a5efce03cb58e..61df8a5c68242 100644 ---- a/fs/smb/client/smb2pdu.c -+++ b/fs/smb/client/smb2pdu.c -@@ -80,6 +80,9 @@ int smb3_encryption_required(const struct cifs_tcon *tcon) - if (tcon->seal && - (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) - return 1; -+ if (((global_secflags & CIFSSEC_MUST_SEAL) == CIFSSEC_MUST_SEAL) && -+ (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) -+ return 1; - return 0; - } - -diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c -index b406bb3430f3d..aa54be1ce1242 100644 ---- a/fs/tracefs/event_inode.c -+++ b/fs/tracefs/event_inode.c -@@ -113,7 +113,7 @@ static void release_ei(struct kref *ref) - entry->release(entry->name, ei->data); - } - -- call_rcu(&ei->rcu, free_ei_rcu); -+ call_srcu(&eventfs_srcu, &ei->rcu, free_ei_rcu); - } - - static inline void put_ei(struct eventfs_inode *ei) -@@ -806,7 +806,7 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode - /* Was the parent freed? */ - if (list_empty(&ei->list)) { - cleanup_ei(ei); -- ei = NULL; -+ ei = ERR_PTR(-EBUSY); - } - return ei; - } -diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c -index 4ea11d1f72ace..7d389dd5ed519 100644 ---- a/fs/tracefs/inode.c -+++ b/fs/tracefs/inode.c -@@ -42,7 +42,7 @@ static struct inode *tracefs_alloc_inode(struct super_block *sb) - struct tracefs_inode *ti; - unsigned long flags; - -- ti = kmem_cache_alloc(tracefs_inode_cachep, GFP_KERNEL); -+ ti = alloc_inode_sb(sb, tracefs_inode_cachep, GFP_KERNEL); - if (!ti) - return NULL; - -@@ -53,15 +53,14 @@ static struct inode *tracefs_alloc_inode(struct super_block *sb) - return &ti->vfs_inode; - } - --static void tracefs_free_inode_rcu(struct rcu_head *rcu) -+static void tracefs_free_inode(struct inode *inode) - { -- struct tracefs_inode *ti; -+ struct tracefs_inode *ti = get_tracefs(inode); - -- ti = container_of(rcu, struct tracefs_inode, rcu); - kmem_cache_free(tracefs_inode_cachep, ti); - } - --static void tracefs_free_inode(struct inode *inode) -+static void tracefs_destroy_inode(struct inode *inode) - { - struct tracefs_inode *ti = get_tracefs(inode); - unsigned long flags; -@@ -69,8 +68,6 @@ static void tracefs_free_inode(struct inode *inode) - spin_lock_irqsave(&tracefs_inode_lock, flags); - list_del_rcu(&ti->list); - spin_unlock_irqrestore(&tracefs_inode_lock, flags); -- -- call_rcu(&ti->rcu, tracefs_free_inode_rcu); - } - - static ssize_t default_read_file(struct file *file, char __user *buf, -@@ -458,6 +455,7 @@ static int tracefs_drop_inode(struct inode *inode) - static const struct super_operations tracefs_super_operations = { - .alloc_inode = tracefs_alloc_inode, - .free_inode = tracefs_free_inode, -+ .destroy_inode = tracefs_destroy_inode, - .drop_inode = tracefs_drop_inode, - .statfs = simple_statfs, - .remount_fs = tracefs_remount, -diff --git a/fs/tracefs/internal.h b/fs/tracefs/internal.h -index f704d8348357e..d83c2a25f288e 100644 ---- a/fs/tracefs/internal.h -+++ b/fs/tracefs/internal.h -@@ -10,10 +10,7 @@ enum { - }; - - struct tracefs_inode { -- union { -- struct inode vfs_inode; -- struct rcu_head rcu; -- }; -+ struct inode vfs_inode; - /* The below gets initialized with memset_after(ti, 0, vfs_inode) */ - struct list_head list; - unsigned long flags; -diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c -index 558ad046972ad..bb471ec364046 100644 ---- a/fs/udf/balloc.c -+++ b/fs/udf/balloc.c -@@ -18,6 +18,7 @@ - #include "udfdecl.h" - - #include -+#include - - #include "udf_i.h" - #include "udf_sb.h" -@@ -140,7 +141,6 @@ static void udf_bitmap_free_blocks(struct super_block *sb, - { - struct udf_sb_info *sbi = UDF_SB(sb); - struct buffer_head *bh = NULL; -- struct udf_part_map *partmap; - unsigned long block; - unsigned long block_group; - unsigned long bit; -@@ -149,19 +149,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb, - unsigned long overflow; - - mutex_lock(&sbi->s_alloc_mutex); -- partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; -- if (bloc->logicalBlockNum + count < count || -- (bloc->logicalBlockNum + count) > partmap->s_partition_len) { -- udf_debug("%u < %d || %u + %u > %u\n", -- bloc->logicalBlockNum, 0, -- bloc->logicalBlockNum, count, -- partmap->s_partition_len); -- goto error_return; -- } -- -+ /* We make sure this cannot overflow when mounting the filesystem */ - block = bloc->logicalBlockNum + offset + - (sizeof(struct spaceBitmapDesc) << 3); -- - do { - overflow = 0; - block_group = block >> (sb->s_blocksize_bits + 3); -@@ -391,7 +381,6 @@ static void udf_table_free_blocks(struct super_block *sb, - uint32_t count) - { - struct udf_sb_info *sbi = UDF_SB(sb); -- struct udf_part_map *partmap; - uint32_t start, end; - uint32_t elen; - struct kernel_lb_addr eloc; -@@ -400,16 +389,6 @@ static void udf_table_free_blocks(struct super_block *sb, - struct udf_inode_info *iinfo; - - mutex_lock(&sbi->s_alloc_mutex); -- partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; -- if (bloc->logicalBlockNum + count < count || -- (bloc->logicalBlockNum + count) > partmap->s_partition_len) { -- udf_debug("%u < %d || %u + %u > %u\n", -- bloc->logicalBlockNum, 0, -- bloc->logicalBlockNum, count, -- partmap->s_partition_len); -- goto error_return; -- } -- - iinfo = UDF_I(table); - udf_add_free_space(sb, sbi->s_partition, count); - -@@ -684,6 +663,17 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode, - { - uint16_t partition = bloc->partitionReferenceNum; - struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; -+ uint32_t blk; -+ -+ if (check_add_overflow(bloc->logicalBlockNum, offset, &blk) || -+ check_add_overflow(blk, count, &blk) || -+ bloc->logicalBlockNum + count > map->s_partition_len) { -+ udf_debug("Invalid request to free blocks: (%d, %u), off %u, " -+ "len %u, partition len %u\n", -+ partition, bloc->logicalBlockNum, offset, count, -+ map->s_partition_len); -+ return; -+ } - - if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { - udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap, -diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c -index 57f366c3d3554..9f9d3abad2cf3 100644 ---- a/fs/xfs/xfs_log_recover.c -+++ b/fs/xfs/xfs_log_recover.c -@@ -2965,7 +2965,7 @@ xlog_do_recovery_pass( - int error = 0, h_size, h_len; - int error2 = 0; - int bblks, split_bblks; -- int hblks, split_hblks, wrapped_hblks; -+ int hblks = 1, split_hblks, wrapped_hblks; - int i; - struct hlist_head rhash[XLOG_RHASH_SIZE]; - LIST_HEAD (buffer_list); -@@ -3021,14 +3021,22 @@ xlog_do_recovery_pass( - if (error) - goto bread_err1; - -- hblks = xlog_logrec_hblks(log, rhead); -- if (hblks != 1) { -- kmem_free(hbp); -- hbp = xlog_alloc_buffer(log, hblks); -+ /* -+ * This open codes xlog_logrec_hblks so that we can reuse the -+ * fixed up h_size value calculated above. Without that we'd -+ * still allocate the buffer based on the incorrect on-disk -+ * size. -+ */ -+ if (h_size > XLOG_HEADER_CYCLE_SIZE && -+ (rhead->h_version & cpu_to_be32(XLOG_VERSION_2))) { -+ hblks = DIV_ROUND_UP(h_size, XLOG_HEADER_CYCLE_SIZE); -+ if (hblks > 1) { -+ kmem_free(hbp); -+ hbp = xlog_alloc_buffer(log, hblks); -+ } - } - } else { - ASSERT(log->l_sectBBsize == 1); -- hblks = 1; - hbp = xlog_alloc_buffer(log, 1); - h_size = XLOG_BIG_RECORD_BSIZE; - } -diff --git a/include/linux/blk-integrity.h b/include/linux/blk-integrity.h -index 378b2459efe2d..f7cc8080672cc 100644 ---- a/include/linux/blk-integrity.h -+++ b/include/linux/blk-integrity.h -@@ -105,14 +105,13 @@ static inline bool blk_integrity_rq(struct request *rq) - } - - /* -- * Return the first bvec that contains integrity data. Only drivers that are -- * limited to a single integrity segment should use this helper. -+ * Return the current bvec that contains the integrity data. bip_iter may be -+ * advanced to iterate over the integrity data. - */ --static inline struct bio_vec *rq_integrity_vec(struct request *rq) -+static inline struct bio_vec rq_integrity_vec(struct request *rq) - { -- if (WARN_ON_ONCE(queue_max_integrity_segments(rq->q) > 1)) -- return NULL; -- return rq->bio->bi_integrity->bip_vec; -+ return mp_bvec_iter_bvec(rq->bio->bi_integrity->bip_vec, -+ rq->bio->bi_integrity->bip_iter); - } - #else /* CONFIG_BLK_DEV_INTEGRITY */ - static inline int blk_rq_count_integrity_sg(struct request_queue *q, -@@ -176,9 +175,10 @@ static inline int blk_integrity_rq(struct request *rq) - return 0; - } - --static inline struct bio_vec *rq_integrity_vec(struct request *rq) -+static inline struct bio_vec rq_integrity_vec(struct request *rq) - { -- return NULL; -+ /* the optimizer will remove all calls to this function */ -+ return (struct bio_vec){ }; - } - #endif /* CONFIG_BLK_DEV_INTEGRITY */ - #endif /* _LINUX_BLK_INTEGRITY_H */ -diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h -index 1d42d4b173271..0ad8b550bb4b4 100644 ---- a/include/linux/clocksource.h -+++ b/include/linux/clocksource.h -@@ -291,7 +291,19 @@ static inline void timer_probe(void) {} - #define TIMER_ACPI_DECLARE(name, table_id, fn) \ - ACPI_DECLARE_PROBE_ENTRY(timer, name, table_id, 0, NULL, 0, fn) - --extern ulong max_cswd_read_retries; -+static inline unsigned int clocksource_get_max_watchdog_retry(void) -+{ -+ /* -+ * When system is in the boot phase or under heavy workload, there -+ * can be random big latencies during the clocksource/watchdog -+ * read, so allow retries to filter the noise latency. As the -+ * latency's frequency and maximum value goes up with the number of -+ * CPUs, scale the number of retries with the number of online -+ * CPUs. -+ */ -+ return (ilog2(num_online_cpus()) / 2) + 1; -+} -+ - void clocksource_verify_percpu(struct clocksource *cs); - - #endif /* _LINUX_CLOCKSOURCE_H */ -diff --git a/include/linux/fs.h b/include/linux/fs.h -index ee5efad0d7801..56dce38c47862 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -642,6 +642,7 @@ struct inode { - umode_t i_mode; - unsigned short i_opflags; - kuid_t i_uid; -+ struct list_head i_lru; /* inode LRU list */ - kgid_t i_gid; - unsigned int i_flags; - -@@ -703,7 +704,6 @@ struct inode { - u16 i_wb_frn_avg_time; - u16 i_wb_frn_history; - #endif -- struct list_head i_lru; /* inode LRU list */ - struct list_head i_sb_list; - struct list_head i_wb_list; /* backing dev writeback list */ - union { -diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h -index 0a85ff5c8db3c..abff4e3b6a58b 100644 ---- a/include/linux/pci_ids.h -+++ b/include/linux/pci_ids.h -@@ -2124,6 +2124,8 @@ - - #define PCI_VENDOR_ID_CHELSIO 0x1425 - -+#define PCI_VENDOR_ID_EDIMAX 0x1432 -+ - #define PCI_VENDOR_ID_ADLINK 0x144a - - #define PCI_VENDOR_ID_SAMSUNG 0x144d -diff --git a/include/linux/profile.h b/include/linux/profile.h -index 11db1ec516e27..12da750a88a04 100644 ---- a/include/linux/profile.h -+++ b/include/linux/profile.h -@@ -11,7 +11,6 @@ - - #define CPU_PROFILING 1 - #define SCHED_PROFILING 2 --#define SLEEP_PROFILING 3 - #define KVM_PROFILING 4 - - struct proc_dir_entry; -diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h -index 696f8dc4aa53c..cb8bd759e8005 100644 ---- a/include/linux/trace_events.h -+++ b/include/linux/trace_events.h -@@ -869,7 +869,6 @@ do { \ - struct perf_event; - - DECLARE_PER_CPU(struct pt_regs, perf_trace_regs); --DECLARE_PER_CPU(int, bpf_kprobe_override); - - extern int perf_trace_init(struct perf_event *event); - extern void perf_trace_destroy(struct perf_event *event); -diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h -index d1d7825318c32..6c395a2600e8d 100644 ---- a/include/linux/virtio_net.h -+++ b/include/linux/virtio_net.h -@@ -56,7 +56,6 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, - unsigned int thlen = 0; - unsigned int p_off = 0; - unsigned int ip_proto; -- u64 ret, remainder, gso_size; - - if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { - switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { -@@ -99,16 +98,6 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, - u32 off = __virtio16_to_cpu(little_endian, hdr->csum_offset); - u32 needed = start + max_t(u32, thlen, off + sizeof(__sum16)); - -- if (hdr->gso_size) { -- gso_size = __virtio16_to_cpu(little_endian, hdr->gso_size); -- ret = div64_u64_rem(skb->len, gso_size, &remainder); -- if (!(ret && (hdr->gso_size > needed) && -- ((remainder > needed) || (remainder == 0)))) { -- return -EINVAL; -- } -- skb_shinfo(skb)->tx_flags |= SKBFL_SHARED_FRAG; -- } -- - if (!pskb_may_pull(skb, needed)) - return -EINVAL; - -@@ -182,6 +171,11 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, - if (gso_type != SKB_GSO_UDP_L4) - return -EINVAL; - break; -+ case SKB_GSO_TCPV4: -+ case SKB_GSO_TCPV6: -+ if (skb->csum_offset != offsetof(struct tcphdr, check)) -+ return -EINVAL; -+ break; - } - - /* Kernel has a special handling for GSO_BY_FRAGS. */ -diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h -index b32539bb0fb05..61cfc8891f820 100644 ---- a/include/net/ip6_route.h -+++ b/include/net/ip6_route.h -@@ -128,18 +128,26 @@ void rt6_age_exceptions(struct fib6_info *f6i, struct fib6_gc_args *gc_args, - - static inline int ip6_route_get_saddr(struct net *net, struct fib6_info *f6i, - const struct in6_addr *daddr, -- unsigned int prefs, -+ unsigned int prefs, int l3mdev_index, - struct in6_addr *saddr) - { -+ struct net_device *l3mdev; -+ struct net_device *dev; -+ bool same_vrf; - int err = 0; - -- if (f6i && f6i->fib6_prefsrc.plen) { -+ rcu_read_lock(); -+ -+ l3mdev = dev_get_by_index_rcu(net, l3mdev_index); -+ if (!f6i || !f6i->fib6_prefsrc.plen || l3mdev) -+ dev = f6i ? fib6_info_nh_dev(f6i) : NULL; -+ same_vrf = !l3mdev || l3mdev_master_dev_rcu(dev) == l3mdev; -+ if (f6i && f6i->fib6_prefsrc.plen && same_vrf) - *saddr = f6i->fib6_prefsrc.addr; -- } else { -- struct net_device *dev = f6i ? fib6_info_nh_dev(f6i) : NULL; -+ else -+ err = ipv6_dev_get_saddr(net, same_vrf ? dev : l3mdev, daddr, prefs, saddr); - -- err = ipv6_dev_get_saddr(net, dev, daddr, prefs, saddr); -- } -+ rcu_read_unlock(); - - return err; - } -diff --git a/include/trace/events/intel_ifs.h b/include/trace/events/intel_ifs.h -index d7353024016cc..af0af3f1d9b7c 100644 ---- a/include/trace/events/intel_ifs.h -+++ b/include/trace/events/intel_ifs.h -@@ -10,25 +10,25 @@ - - TRACE_EVENT(ifs_status, - -- TP_PROTO(int cpu, union ifs_scan activate, union ifs_status status), -+ TP_PROTO(int cpu, int start, int stop, u64 status), - -- TP_ARGS(cpu, activate, status), -+ TP_ARGS(cpu, start, stop, status), - - TP_STRUCT__entry( - __field( u64, status ) - __field( int, cpu ) -- __field( u8, start ) -- __field( u8, stop ) -+ __field( u16, start ) -+ __field( u16, stop ) - ), - - TP_fast_assign( - __entry->cpu = cpu; -- __entry->start = activate.start; -- __entry->stop = activate.stop; -- __entry->status = status.data; -+ __entry->start = start; -+ __entry->stop = stop; -+ __entry->status = status; - ), - -- TP_printk("cpu: %d, start: %.2x, stop: %.2x, status: %llx", -+ TP_printk("cpu: %d, start: %.4x, stop: %.4x, status: %.16llx", - __entry->cpu, - __entry->start, - __entry->stop, -diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c -index 5c9888901ef44..46094f0c9fcda 100644 ---- a/kernel/irq/irqdesc.c -+++ b/kernel/irq/irqdesc.c -@@ -517,6 +517,7 @@ static int alloc_descs(unsigned int start, unsigned int cnt, int node, - flags = IRQD_AFFINITY_MANAGED | - IRQD_MANAGED_SHUTDOWN; - } -+ flags |= IRQD_AFFINITY_SET; - mask = &affinity->mask; - node = cpu_to_node(cpumask_first(mask)); - affinity++; -diff --git a/kernel/jump_label.c b/kernel/jump_label.c -index eec802175ccc6..1ed269b2c4035 100644 ---- a/kernel/jump_label.c -+++ b/kernel/jump_label.c -@@ -231,7 +231,7 @@ void static_key_disable_cpuslocked(struct static_key *key) - } - - jump_label_lock(); -- if (atomic_cmpxchg(&key->enabled, 1, 0)) -+ if (atomic_cmpxchg(&key->enabled, 1, 0) == 1) - jump_label_update(key); - jump_label_unlock(); - } -@@ -284,7 +284,7 @@ static void __static_key_slow_dec_cpuslocked(struct static_key *key) - return; - - guard(mutex)(&jump_label_mutex); -- if (atomic_cmpxchg(&key->enabled, 1, 0)) -+ if (atomic_cmpxchg(&key->enabled, 1, 0) == 1) - jump_label_update(key); - else - WARN_ON_ONCE(!static_key_slow_try_dec(key)); -diff --git a/kernel/kcov.c b/kernel/kcov.c -index 9f4affae4fad4..72d9aa6fb50c3 100644 ---- a/kernel/kcov.c -+++ b/kernel/kcov.c -@@ -161,6 +161,15 @@ static void kcov_remote_area_put(struct kcov_remote_area *area, - kmsan_unpoison_memory(&area->list, sizeof(area->list)); - } - -+/* -+ * Unlike in_serving_softirq(), this function returns false when called during -+ * a hardirq or an NMI that happened in the softirq context. -+ */ -+static inline bool in_softirq_really(void) -+{ -+ return in_serving_softirq() && !in_hardirq() && !in_nmi(); -+} -+ - static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t) - { - unsigned int mode; -@@ -170,7 +179,7 @@ static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_stru - * so we ignore code executed in interrupts, unless we are in a remote - * coverage collection section in a softirq. - */ -- if (!in_task() && !(in_serving_softirq() && t->kcov_softirq)) -+ if (!in_task() && !(in_softirq_really() && t->kcov_softirq)) - return false; - mode = READ_ONCE(t->kcov_mode); - /* -@@ -848,7 +857,7 @@ void kcov_remote_start(u64 handle) - - if (WARN_ON(!kcov_check_handle(handle, true, true, true))) - return; -- if (!in_task() && !in_serving_softirq()) -+ if (!in_task() && !in_softirq_really()) - return; - - local_lock_irqsave(&kcov_percpu_data.lock, flags); -@@ -990,7 +999,7 @@ void kcov_remote_stop(void) - int sequence; - unsigned long flags; - -- if (!in_task() && !in_serving_softirq()) -+ if (!in_task() && !in_softirq_really()) - return; - - local_lock_irqsave(&kcov_percpu_data.lock, flags); -diff --git a/kernel/kprobes.c b/kernel/kprobes.c -index add63428c0b40..c10954bd84448 100644 ---- a/kernel/kprobes.c -+++ b/kernel/kprobes.c -@@ -1558,8 +1558,8 @@ static bool is_cfi_preamble_symbol(unsigned long addr) - if (lookup_symbol_name(addr, symbuf)) - return false; - -- return str_has_prefix("__cfi_", symbuf) || -- str_has_prefix("__pfx_", symbuf); -+ return str_has_prefix(symbuf, "__cfi_") || -+ str_has_prefix(symbuf, "__pfx_"); - } - - static int check_kprobe_address_safe(struct kprobe *p, -diff --git a/kernel/module/main.c b/kernel/module/main.c -index 34d9e718c2c7d..b00e31721a73e 100644 ---- a/kernel/module/main.c -+++ b/kernel/module/main.c -@@ -3081,7 +3081,7 @@ static bool idempotent(struct idempotent *u, const void *cookie) - struct idempotent *existing; - bool first; - -- u->ret = 0; -+ u->ret = -EINTR; - u->cookie = cookie; - init_completion(&u->complete); - -@@ -3117,7 +3117,7 @@ static int idempotent_complete(struct idempotent *u, int ret) - hlist_for_each_entry_safe(pos, next, head, entry) { - if (pos->cookie != cookie) - continue; -- hlist_del(&pos->entry); -+ hlist_del_init(&pos->entry); - pos->ret = ret; - complete(&pos->complete); - } -@@ -3125,6 +3125,28 @@ static int idempotent_complete(struct idempotent *u, int ret) - return ret; - } - -+/* -+ * Wait for the idempotent worker. -+ * -+ * If we get interrupted, we need to remove ourselves from the -+ * the idempotent list, and the completion may still come in. -+ * -+ * The 'idem_lock' protects against the race, and 'idem.ret' was -+ * initialized to -EINTR and is thus always the right return -+ * value even if the idempotent work then completes between -+ * the wait_for_completion and the cleanup. -+ */ -+static int idempotent_wait_for_completion(struct idempotent *u) -+{ -+ if (wait_for_completion_interruptible(&u->complete)) { -+ spin_lock(&idem_lock); -+ if (!hlist_unhashed(&u->entry)) -+ hlist_del(&u->entry); -+ spin_unlock(&idem_lock); -+ } -+ return u->ret; -+} -+ - static int init_module_from_file(struct file *f, const char __user * uargs, int flags) - { - struct load_info info = { }; -@@ -3160,15 +3182,16 @@ static int idempotent_init_module(struct file *f, const char __user * uargs, int - if (!f || !(f->f_mode & FMODE_READ)) - return -EBADF; - -- /* See if somebody else is doing the operation? */ -- if (idempotent(&idem, file_inode(f))) { -- wait_for_completion(&idem.complete); -- return idem.ret; -+ /* Are we the winners of the race and get to do this? */ -+ if (!idempotent(&idem, file_inode(f))) { -+ int ret = init_module_from_file(f, uargs, flags); -+ return idempotent_complete(&idem, ret); - } - -- /* Otherwise, we'll do it and complete others */ -- return idempotent_complete(&idem, -- init_module_from_file(f, uargs, flags)); -+ /* -+ * Somebody else won the race and is loading the module. -+ */ -+ return idempotent_wait_for_completion(&idem); - } - - SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags) -diff --git a/kernel/padata.c b/kernel/padata.c -index c974568f65f5d..29545dd6dd53d 100644 ---- a/kernel/padata.c -+++ b/kernel/padata.c -@@ -516,6 +516,13 @@ void __init padata_do_multithreaded(struct padata_mt_job *job) - ps.chunk_size = max(ps.chunk_size, job->min_chunk); - ps.chunk_size = roundup(ps.chunk_size, job->align); - -+ /* -+ * chunk_size can be 0 if the caller sets min_chunk to 0. So force it -+ * to at least 1 to prevent divide-by-0 panic in padata_mt_helper().` -+ */ -+ if (!ps.chunk_size) -+ ps.chunk_size = 1U; -+ - list_for_each_entry(pw, &works, pw_list) - queue_work(system_unbound_wq, &pw->pw_work); - -diff --git a/kernel/profile.c b/kernel/profile.c -index 8a77769bc4b4c..984f819b701c9 100644 ---- a/kernel/profile.c -+++ b/kernel/profile.c -@@ -57,20 +57,11 @@ static DEFINE_MUTEX(profile_flip_mutex); - int profile_setup(char *str) - { - static const char schedstr[] = "schedule"; -- static const char sleepstr[] = "sleep"; - static const char kvmstr[] = "kvm"; - const char *select = NULL; - int par; - -- if (!strncmp(str, sleepstr, strlen(sleepstr))) { --#ifdef CONFIG_SCHEDSTATS -- force_schedstat_enabled(); -- prof_on = SLEEP_PROFILING; -- select = sleepstr; --#else -- pr_warn("kernel sleep profiling requires CONFIG_SCHEDSTATS\n"); --#endif /* CONFIG_SCHEDSTATS */ -- } else if (!strncmp(str, schedstr, strlen(schedstr))) { -+ if (!strncmp(str, schedstr, strlen(schedstr))) { - prof_on = SCHED_PROFILING; - select = schedstr; - } else if (!strncmp(str, kvmstr, strlen(kvmstr))) { -diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c -index 781146600aa49..46612fb15fc6d 100644 ---- a/kernel/rcu/rcutorture.c -+++ b/kernel/rcu/rcutorture.c -@@ -2592,7 +2592,7 @@ static void rcu_torture_fwd_cb_cr(struct rcu_head *rhp) - spin_lock_irqsave(&rfp->rcu_fwd_lock, flags); - rfcpp = rfp->rcu_fwd_cb_tail; - rfp->rcu_fwd_cb_tail = &rfcp->rfc_next; -- WRITE_ONCE(*rfcpp, rfcp); -+ smp_store_release(rfcpp, rfcp); - WRITE_ONCE(rfp->n_launders_cb, rfp->n_launders_cb + 1); - i = ((jiffies - rfp->rcu_fwd_startat) / (HZ / FWD_CBS_HIST_DIV)); - if (i >= ARRAY_SIZE(rfp->n_launders_hist)) -diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c -index 8cf6a6fef7965..583cc29080764 100644 ---- a/kernel/rcu/tree.c -+++ b/kernel/rcu/tree.c -@@ -4595,11 +4595,15 @@ void rcutree_migrate_callbacks(int cpu) - struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu); - bool needwake; - -- if (rcu_rdp_is_offloaded(rdp) || -- rcu_segcblist_empty(&rdp->cblist)) -- return; /* No callbacks to migrate. */ -+ if (rcu_rdp_is_offloaded(rdp)) -+ return; - - raw_spin_lock_irqsave(&rcu_state.barrier_lock, flags); -+ if (rcu_segcblist_empty(&rdp->cblist)) { -+ raw_spin_unlock_irqrestore(&rcu_state.barrier_lock, flags); -+ return; /* No callbacks to migrate. */ -+ } -+ - WARN_ON_ONCE(rcu_rdp_cpu_online(rdp)); - rcu_barrier_entrain(rdp); - my_rdp = this_cpu_ptr(&rcu_data); -diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 92e4afeb71add..97571d390f184 100644 ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -9596,6 +9596,30 @@ void set_rq_offline(struct rq *rq) - } - } - -+static inline void sched_set_rq_online(struct rq *rq, int cpu) -+{ -+ struct rq_flags rf; -+ -+ rq_lock_irqsave(rq, &rf); -+ if (rq->rd) { -+ BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span)); -+ set_rq_online(rq); -+ } -+ rq_unlock_irqrestore(rq, &rf); -+} -+ -+static inline void sched_set_rq_offline(struct rq *rq, int cpu) -+{ -+ struct rq_flags rf; -+ -+ rq_lock_irqsave(rq, &rf); -+ if (rq->rd) { -+ BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span)); -+ set_rq_offline(rq); -+ } -+ rq_unlock_irqrestore(rq, &rf); -+} -+ - /* - * used to mark begin/end of suspend/resume: - */ -@@ -9646,10 +9670,25 @@ static int cpuset_cpu_inactive(unsigned int cpu) - return 0; - } - -+static inline void sched_smt_present_inc(int cpu) -+{ -+#ifdef CONFIG_SCHED_SMT -+ if (cpumask_weight(cpu_smt_mask(cpu)) == 2) -+ static_branch_inc_cpuslocked(&sched_smt_present); -+#endif -+} -+ -+static inline void sched_smt_present_dec(int cpu) -+{ -+#ifdef CONFIG_SCHED_SMT -+ if (cpumask_weight(cpu_smt_mask(cpu)) == 2) -+ static_branch_dec_cpuslocked(&sched_smt_present); -+#endif -+} -+ - int sched_cpu_activate(unsigned int cpu) - { - struct rq *rq = cpu_rq(cpu); -- struct rq_flags rf; - - /* - * Clear the balance_push callback and prepare to schedule -@@ -9657,13 +9696,10 @@ int sched_cpu_activate(unsigned int cpu) - */ - balance_push_set(cpu, false); - --#ifdef CONFIG_SCHED_SMT - /* - * When going up, increment the number of cores with SMT present. - */ -- if (cpumask_weight(cpu_smt_mask(cpu)) == 2) -- static_branch_inc_cpuslocked(&sched_smt_present); --#endif -+ sched_smt_present_inc(cpu); - set_cpu_active(cpu, true); - - if (sched_smp_initialized) { -@@ -9681,12 +9717,7 @@ int sched_cpu_activate(unsigned int cpu) - * 2) At runtime, if cpuset_cpu_active() fails to rebuild the - * domains. - */ -- rq_lock_irqsave(rq, &rf); -- if (rq->rd) { -- BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span)); -- set_rq_online(rq); -- } -- rq_unlock_irqrestore(rq, &rf); -+ sched_set_rq_online(rq, cpu); - - return 0; - } -@@ -9694,7 +9725,6 @@ int sched_cpu_activate(unsigned int cpu) - int sched_cpu_deactivate(unsigned int cpu) - { - struct rq *rq = cpu_rq(cpu); -- struct rq_flags rf; - int ret; - - /* -@@ -9725,20 +9755,14 @@ int sched_cpu_deactivate(unsigned int cpu) - */ - synchronize_rcu(); - -- rq_lock_irqsave(rq, &rf); -- if (rq->rd) { -- BUG_ON(!cpumask_test_cpu(cpu, rq->rd->span)); -- set_rq_offline(rq); -- } -- rq_unlock_irqrestore(rq, &rf); -+ sched_set_rq_offline(rq, cpu); - --#ifdef CONFIG_SCHED_SMT - /* - * When going down, decrement the number of cores with SMT present. - */ -- if (cpumask_weight(cpu_smt_mask(cpu)) == 2) -- static_branch_dec_cpuslocked(&sched_smt_present); -+ sched_smt_present_dec(cpu); - -+#ifdef CONFIG_SCHED_SMT - sched_core_cpu_deactivate(cpu); - #endif - -@@ -9748,6 +9772,8 @@ int sched_cpu_deactivate(unsigned int cpu) - sched_update_numa(cpu, false); - ret = cpuset_cpu_inactive(cpu); - if (ret) { -+ sched_smt_present_inc(cpu); -+ sched_set_rq_online(rq, cpu); - balance_push_set(cpu, false); - set_cpu_active(cpu, true); - sched_update_numa(cpu, true); -diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c -index af7952f12e6cf..b453f8a6a7c76 100644 ---- a/kernel/sched/cputime.c -+++ b/kernel/sched/cputime.c -@@ -595,6 +595,12 @@ void cputime_adjust(struct task_cputime *curr, struct prev_cputime *prev, - } - - stime = mul_u64_u64_div_u64(stime, rtime, stime + utime); -+ /* -+ * Because mul_u64_u64_div_u64() can approximate on some -+ * achitectures; enforce the constraint that: a*b/(b+c) <= a. -+ */ -+ if (unlikely(stime > rtime)) -+ stime = rtime; - - update: - /* -diff --git a/kernel/sched/stats.c b/kernel/sched/stats.c -index 857f837f52cbe..966f4eacfe51d 100644 ---- a/kernel/sched/stats.c -+++ b/kernel/sched/stats.c -@@ -92,16 +92,6 @@ void __update_stats_enqueue_sleeper(struct rq *rq, struct task_struct *p, - - trace_sched_stat_blocked(p, delta); - -- /* -- * Blocking time is in units of nanosecs, so shift by -- * 20 to get a milliseconds-range estimation of the -- * amount of time that the task spent sleeping: -- */ -- if (unlikely(prof_on == SLEEP_PROFILING)) { -- profile_hits(SLEEP_PROFILING, -- (void *)get_wchan(p), -- delta >> 20); -- } - account_scheduler_latency(p, delta >> 10, 0); - } - } -diff --git a/kernel/time/clocksource-wdtest.c b/kernel/time/clocksource-wdtest.c -index df922f49d171b..d06185e054ea2 100644 ---- a/kernel/time/clocksource-wdtest.c -+++ b/kernel/time/clocksource-wdtest.c -@@ -104,8 +104,8 @@ static void wdtest_ktime_clocksource_reset(void) - static int wdtest_func(void *arg) - { - unsigned long j1, j2; -+ int i, max_retries; - char *s; -- int i; - - schedule_timeout_uninterruptible(holdoff * HZ); - -@@ -139,18 +139,19 @@ static int wdtest_func(void *arg) - WARN_ON_ONCE(time_before(j2, j1 + NSEC_PER_USEC)); - - /* Verify tsc-like stability with various numbers of errors injected. */ -- for (i = 0; i <= max_cswd_read_retries + 1; i++) { -- if (i <= 1 && i < max_cswd_read_retries) -+ max_retries = clocksource_get_max_watchdog_retry(); -+ for (i = 0; i <= max_retries + 1; i++) { -+ if (i <= 1 && i < max_retries) - s = ""; -- else if (i <= max_cswd_read_retries) -+ else if (i <= max_retries) - s = ", expect message"; - else - s = ", expect clock skew"; -- pr_info("--- Watchdog with %dx error injection, %lu retries%s.\n", i, max_cswd_read_retries, s); -+ pr_info("--- Watchdog with %dx error injection, %d retries%s.\n", i, max_retries, s); - WRITE_ONCE(wdtest_ktime_read_ndelays, i); - schedule_timeout_uninterruptible(2 * HZ); - WARN_ON_ONCE(READ_ONCE(wdtest_ktime_read_ndelays)); -- WARN_ON_ONCE((i <= max_cswd_read_retries) != -+ WARN_ON_ONCE((i <= max_retries) != - !(clocksource_wdtest_ktime.flags & CLOCK_SOURCE_UNSTABLE)); - wdtest_ktime_clocksource_reset(); - } -diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c -index 3052b1f1168e2..3260bbe98894b 100644 ---- a/kernel/time/clocksource.c -+++ b/kernel/time/clocksource.c -@@ -210,9 +210,6 @@ void clocksource_mark_unstable(struct clocksource *cs) - spin_unlock_irqrestore(&watchdog_lock, flags); - } - --ulong max_cswd_read_retries = 2; --module_param(max_cswd_read_retries, ulong, 0644); --EXPORT_SYMBOL_GPL(max_cswd_read_retries); - static int verify_n_cpus = 8; - module_param(verify_n_cpus, int, 0644); - -@@ -224,11 +221,12 @@ enum wd_read_status { - - static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow) - { -- unsigned int nretries; -+ unsigned int nretries, max_retries; - u64 wd_end, wd_end2, wd_delta; - int64_t wd_delay, wd_seq_delay; - -- for (nretries = 0; nretries <= max_cswd_read_retries; nretries++) { -+ max_retries = clocksource_get_max_watchdog_retry(); -+ for (nretries = 0; nretries <= max_retries; nretries++) { - local_irq_disable(); - *wdnow = watchdog->read(watchdog); - *csnow = cs->read(cs); -@@ -240,7 +238,7 @@ static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, - wd_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, - watchdog->shift); - if (wd_delay <= WATCHDOG_MAX_SKEW) { -- if (nretries > 1 || nretries >= max_cswd_read_retries) { -+ if (nretries > 1 && nretries >= max_retries) { - pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n", - smp_processor_id(), watchdog->name, nretries); - } -diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c -index 406dccb79c2b6..8d2dd214ec682 100644 ---- a/kernel/time/ntp.c -+++ b/kernel/time/ntp.c -@@ -727,17 +727,16 @@ static inline void process_adjtimex_modes(const struct __kernel_timex *txc, - } - - if (txc->modes & ADJ_MAXERROR) -- time_maxerror = txc->maxerror; -+ time_maxerror = clamp(txc->maxerror, 0, NTP_PHASE_LIMIT); - - if (txc->modes & ADJ_ESTERROR) -- time_esterror = txc->esterror; -+ time_esterror = clamp(txc->esterror, 0, NTP_PHASE_LIMIT); - - if (txc->modes & ADJ_TIMECONST) { -- time_constant = txc->constant; -+ time_constant = clamp(txc->constant, 0, MAXTC); - if (!(time_status & STA_NANO)) - time_constant += 4; -- time_constant = min(time_constant, (long)MAXTC); -- time_constant = max(time_constant, 0l); -+ time_constant = clamp(time_constant, 0, MAXTC); - } - - if (txc->modes & ADJ_TAI && -diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c -index b4843099a8da7..ed58eebb4e8f4 100644 ---- a/kernel/time/tick-broadcast.c -+++ b/kernel/time/tick-broadcast.c -@@ -1141,7 +1141,6 @@ void tick_broadcast_switch_to_oneshot(void) - #ifdef CONFIG_HOTPLUG_CPU - void hotplug_cpu__broadcast_tick_pull(int deadcpu) - { -- struct tick_device *td = this_cpu_ptr(&tick_cpu_device); - struct clock_event_device *bc; - unsigned long flags; - -@@ -1167,6 +1166,8 @@ void hotplug_cpu__broadcast_tick_pull(int deadcpu) - * device to avoid the starvation. - */ - if (tick_check_broadcast_expired()) { -+ struct tick_device *td = this_cpu_ptr(&tick_cpu_device); -+ - cpumask_clear_cpu(smp_processor_id(), tick_broadcast_force_mask); - tick_program_event(td->evtdev->next_event, 1); - } -diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c -index 8aab7ed414907..11b7000d5e1d4 100644 ---- a/kernel/time/timekeeping.c -+++ b/kernel/time/timekeeping.c -@@ -2476,7 +2476,7 @@ int do_adjtimex(struct __kernel_timex *txc) - clock_set |= timekeeping_advance(TK_ADV_FREQ); - - if (clock_set) -- clock_was_set(CLOCK_REALTIME); -+ clock_was_set(CLOCK_SET_WALL); - - ntp_notify_cmos_timer(); - -diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c -index a4dcf0f243521..3a56e7c8aa4f6 100644 ---- a/kernel/trace/tracing_map.c -+++ b/kernel/trace/tracing_map.c -@@ -454,7 +454,7 @@ static struct tracing_map_elt *get_free_elt(struct tracing_map *map) - struct tracing_map_elt *elt = NULL; - int idx; - -- idx = atomic_inc_return(&map->next_elt); -+ idx = atomic_fetch_add_unless(&map->next_elt, 1, map->max_elts); - if (idx < map->max_elts) { - elt = *(TRACING_MAP_ELT(map->elts, idx)); - if (map->ops && map->ops->elt_init) -@@ -699,7 +699,7 @@ void tracing_map_clear(struct tracing_map *map) - { - unsigned int i; - -- atomic_set(&map->next_elt, -1); -+ atomic_set(&map->next_elt, 0); - atomic64_set(&map->hits, 0); - atomic64_set(&map->drops, 0); - -@@ -783,7 +783,7 @@ struct tracing_map *tracing_map_create(unsigned int map_bits, - - map->map_bits = map_bits; - map->max_elts = (1 << map_bits); -- atomic_set(&map->next_elt, -1); -+ atomic_set(&map->next_elt, 0); - - map->map_size = (1 << (map_bits + 1)); - map->ops = ops; -diff --git a/mm/huge_memory.c b/mm/huge_memory.c -index 79fbd6ddec49f..7ac2877e76629 100644 ---- a/mm/huge_memory.c -+++ b/mm/huge_memory.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -601,6 +602,9 @@ static unsigned long __thp_get_unmapped_area(struct file *filp, - loff_t off_align = round_up(off, size); - unsigned long len_pad, ret; - -+ if (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall()) -+ return 0; -+ - if (off_end <= off_align || (off_end - off_align) < size) - return 0; - -diff --git a/mm/hugetlb.c b/mm/hugetlb.c -index a480affd475bf..fb7a531fce717 100644 ---- a/mm/hugetlb.c -+++ b/mm/hugetlb.c -@@ -1769,13 +1769,6 @@ static void __update_and_free_hugetlb_folio(struct hstate *h, - return; - } - -- /* -- * Move PageHWPoison flag from head page to the raw error pages, -- * which makes any healthy subpages reusable. -- */ -- if (unlikely(folio_test_hwpoison(folio))) -- folio_clear_hugetlb_hwpoison(folio); -- - /* - * If vmemmap pages were allocated above, then we need to clear the - * hugetlb destructor under the hugetlb lock. -@@ -1786,6 +1779,13 @@ static void __update_and_free_hugetlb_folio(struct hstate *h, - spin_unlock_irq(&hugetlb_lock); - } - -+ /* -+ * Move PageHWPoison flag from head page to the raw error pages, -+ * which makes any healthy subpages reusable. -+ */ -+ if (unlikely(folio_test_hwpoison(folio))) -+ folio_clear_hugetlb_hwpoison(folio); -+ - /* - * Non-gigantic pages demoted from CMA allocated gigantic pages - * need to be given back to CMA in free_gigantic_folio. -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index dd854cc65fd9d..fd1b707f5de40 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -5167,11 +5167,28 @@ static struct cftype mem_cgroup_legacy_files[] = { - - #define MEM_CGROUP_ID_MAX ((1UL << MEM_CGROUP_ID_SHIFT) - 1) - static DEFINE_IDR(mem_cgroup_idr); -+static DEFINE_SPINLOCK(memcg_idr_lock); -+ -+static int mem_cgroup_alloc_id(void) -+{ -+ int ret; -+ -+ idr_preload(GFP_KERNEL); -+ spin_lock(&memcg_idr_lock); -+ ret = idr_alloc(&mem_cgroup_idr, NULL, 1, MEM_CGROUP_ID_MAX + 1, -+ GFP_NOWAIT); -+ spin_unlock(&memcg_idr_lock); -+ idr_preload_end(); -+ return ret; -+} - - static void mem_cgroup_id_remove(struct mem_cgroup *memcg) - { - if (memcg->id.id > 0) { -+ spin_lock(&memcg_idr_lock); - idr_remove(&mem_cgroup_idr, memcg->id.id); -+ spin_unlock(&memcg_idr_lock); -+ - memcg->id.id = 0; - } - } -@@ -5294,8 +5311,7 @@ static struct mem_cgroup *mem_cgroup_alloc(void) - if (!memcg) - return ERR_PTR(error); - -- memcg->id.id = idr_alloc(&mem_cgroup_idr, NULL, -- 1, MEM_CGROUP_ID_MAX + 1, GFP_KERNEL); -+ memcg->id.id = mem_cgroup_alloc_id(); - if (memcg->id.id < 0) { - error = memcg->id.id; - goto fail; -@@ -5430,7 +5446,9 @@ static int mem_cgroup_css_online(struct cgroup_subsys_state *css) - * publish it here at the end of onlining. This matches the - * regular ID destruction during offlining. - */ -+ spin_lock(&memcg_idr_lock); - idr_replace(&mem_cgroup_idr, memcg, memcg->id.id); -+ spin_unlock(&memcg_idr_lock); - - return 0; - offline_kmem: -diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c -index 6dab0c99c82c7..38fee34887d8a 100644 ---- a/net/bluetooth/hci_sync.c -+++ b/net/bluetooth/hci_sync.c -@@ -2905,6 +2905,20 @@ static int hci_passive_scan_sync(struct hci_dev *hdev) - } else if (hci_is_adv_monitoring(hdev)) { - window = hdev->le_scan_window_adv_monitor; - interval = hdev->le_scan_int_adv_monitor; -+ -+ /* Disable duplicates filter when scanning for advertisement -+ * monitor for the following reasons. -+ * -+ * For HW pattern filtering (ex. MSFT), Realtek and Qualcomm -+ * controllers ignore RSSI_Sampling_Period when the duplicates -+ * filter is enabled. -+ * -+ * For SW pattern filtering, when we're not doing interleaved -+ * scanning, it is necessary to disable duplicates filter, -+ * otherwise hosts can only receive one advertisement and it's -+ * impossible to know if a peer is still in range. -+ */ -+ filter_dups = LE_SCAN_FILTER_DUP_DISABLE; - } else { - window = hdev->le_scan_window; - interval = hdev->le_scan_interval; -diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c -index 1164c6d927281..2651cc2d5c283 100644 ---- a/net/bluetooth/l2cap_core.c -+++ b/net/bluetooth/l2cap_core.c -@@ -6775,6 +6775,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, - bt_cb(skb)->l2cap.psm = psm; - - if (!chan->ops->recv(chan, skb)) { -+ l2cap_chan_unlock(chan); - l2cap_chan_put(chan); - return; - } -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 38373b4fb7ddf..c38244d60ff86 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -2044,16 +2044,14 @@ void br_multicast_del_port(struct net_bridge_port *port) - { - struct net_bridge *br = port->br; - struct net_bridge_port_group *pg; -- HLIST_HEAD(deleted_head); - struct hlist_node *n; - - /* Take care of the remaining groups, only perm ones should be left */ - spin_lock_bh(&br->multicast_lock); - hlist_for_each_entry_safe(pg, n, &port->mglist, mglist) - br_multicast_find_del_pg(br, pg); -- hlist_move_list(&br->mcast_gc_list, &deleted_head); - spin_unlock_bh(&br->multicast_lock); -- br_multicast_gc(&deleted_head); -+ flush_work(&br->mcast_gc_work); - br_multicast_port_ctx_deinit(&port->multicast_ctx); - free_percpu(port->mcast_stats); - } -diff --git a/net/core/link_watch.c b/net/core/link_watch.c -index cb43f5aebfbcc..cf867f6e38bf1 100644 ---- a/net/core/link_watch.c -+++ b/net/core/link_watch.c -@@ -153,9 +153,9 @@ static void linkwatch_schedule_work(int urgent) - * override the existing timer. - */ - if (test_bit(LW_URGENT, &linkwatch_flags)) -- mod_delayed_work(system_wq, &linkwatch_work, 0); -+ mod_delayed_work(system_unbound_wq, &linkwatch_work, 0); - else -- schedule_delayed_work(&linkwatch_work, delay); -+ queue_delayed_work(system_unbound_wq, &linkwatch_work, delay); - } - - -diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c -index 8311c38267b55..69e6012ae82fb 100644 ---- a/net/ipv4/tcp_offload.c -+++ b/net/ipv4/tcp_offload.c -@@ -73,6 +73,9 @@ struct sk_buff *tcp_gso_segment(struct sk_buff *skb, - if (thlen < sizeof(*th)) - goto out; - -+ if (unlikely(skb_checksum_start(skb) != skb_transport_header(skb))) -+ goto out; -+ - if (!pskb_may_pull(skb, thlen)) - goto out; - -diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c -index e5971890d637d..9cb13a50011ef 100644 ---- a/net/ipv4/udp_offload.c -+++ b/net/ipv4/udp_offload.c -@@ -278,6 +278,10 @@ struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb, - if (gso_skb->len <= sizeof(*uh) + mss) - return ERR_PTR(-EINVAL); - -+ if (unlikely(skb_checksum_start(gso_skb) != -+ skb_transport_header(gso_skb))) -+ return ERR_PTR(-EINVAL); -+ - if (skb_gso_ok(gso_skb, features | NETIF_F_GSO_ROBUST)) { - /* Packet is from an untrusted source, reset gso_segs. */ - skb_shinfo(gso_skb)->gso_segs = DIV_ROUND_UP(gso_skb->len - sizeof(*uh), -diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c -index f97cb368e5a81..db8d0e1bf69ff 100644 ---- a/net/ipv6/ip6_output.c -+++ b/net/ipv6/ip6_output.c -@@ -1122,6 +1122,7 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk, - from = rt ? rcu_dereference(rt->from) : NULL; - err = ip6_route_get_saddr(net, from, &fl6->daddr, - sk ? inet6_sk(sk)->srcprefs : 0, -+ fl6->flowi6_l3mdev, - &fl6->saddr); - rcu_read_unlock(); - -diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index eb3afaee62e8f..49ef5623c55e2 100644 ---- a/net/ipv6/route.c -+++ b/net/ipv6/route.c -@@ -5678,7 +5678,7 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb, - goto nla_put_failure; - } else if (dest) { - struct in6_addr saddr_buf; -- if (ip6_route_get_saddr(net, rt, dest, 0, &saddr_buf) == 0 && -+ if (ip6_route_get_saddr(net, rt, dest, 0, 0, &saddr_buf) == 0 && - nla_put_in6_addr(skb, RTA_PREFSRC, &saddr_buf)) - goto nla_put_failure; - } -diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c -index 8d21ff25f1602..70da78ab95202 100644 ---- a/net/l2tp/l2tp_core.c -+++ b/net/l2tp/l2tp_core.c -@@ -88,6 +88,11 @@ - /* Default trace flags */ - #define L2TP_DEFAULT_DEBUG_FLAGS 0 - -+#define L2TP_DEPTH_NESTING 2 -+#if L2TP_DEPTH_NESTING == SINGLE_DEPTH_NESTING -+#error "L2TP requires its own lockdep subclass" -+#endif -+ - /* Private data stored for received packets in the skb. - */ - struct l2tp_skb_cb { -@@ -1041,7 +1046,13 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns - IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED); - nf_reset_ct(skb); - -- bh_lock_sock_nested(sk); -+ /* L2TP uses its own lockdep subclass to avoid lockdep splats caused by -+ * nested socket calls on the same lockdep socket class. This can -+ * happen when data from a user socket is routed over l2tp, which uses -+ * another userspace socket. -+ */ -+ spin_lock_nested(&sk->sk_lock.slock, L2TP_DEPTH_NESTING); -+ - if (sock_owned_by_user(sk)) { - kfree_skb(skb); - ret = NET_XMIT_DROP; -@@ -1093,7 +1104,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns - ret = l2tp_xmit_queue(tunnel, skb, &inet->cork.fl); - - out_unlock: -- bh_unlock_sock(sk); -+ spin_unlock(&sk->sk_lock.slock); - - return ret; - } -diff --git a/net/mptcp/options.c b/net/mptcp/options.c -index 85aafa94cc8ab..604724cca887f 100644 ---- a/net/mptcp/options.c -+++ b/net/mptcp/options.c -@@ -958,7 +958,8 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk, - - if (subflow->remote_key_valid && - (((mp_opt->suboptions & OPTION_MPTCP_DSS) && mp_opt->use_ack) || -- ((mp_opt->suboptions & OPTION_MPTCP_ADD_ADDR) && !mp_opt->echo))) { -+ ((mp_opt->suboptions & OPTION_MPTCP_ADD_ADDR) && -+ (!mp_opt->echo || subflow->mp_join)))) { - /* subflows are fully established as soon as we get any - * additional ack, including ADD_ADDR. - */ -diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c -index d8da5374d9e13..cf70a376398be 100644 ---- a/net/mptcp/pm.c -+++ b/net/mptcp/pm.c -@@ -427,6 +427,18 @@ int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc) - return mptcp_pm_nl_get_local_id(msk, &skc_local); - } - -+bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc) -+{ -+ struct mptcp_addr_info skc_local; -+ -+ mptcp_local_address((struct sock_common *)skc, &skc_local); -+ -+ if (mptcp_pm_is_userspace(msk)) -+ return mptcp_userspace_pm_is_backup(msk, &skc_local); -+ -+ return mptcp_pm_nl_is_backup(msk, &skc_local); -+} -+ - int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id, - u8 *flags, int *ifindex) - { -diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c -index db621933b2035..2c49182c674f3 100644 ---- a/net/mptcp/pm_netlink.c -+++ b/net/mptcp/pm_netlink.c -@@ -353,7 +353,7 @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk, - add_entry = mptcp_lookup_anno_list_by_saddr(msk, addr); - - if (add_entry) { -- if (mptcp_pm_is_kernel(msk)) -+ if (WARN_ON_ONCE(mptcp_pm_is_kernel(msk))) - return false; - - sk_reset_timer(sk, &add_entry->add_timer, -@@ -520,8 +520,8 @@ __lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info, - - static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) - { -+ struct mptcp_pm_addr_entry *local, *signal_and_subflow = NULL; - struct sock *sk = (struct sock *)msk; -- struct mptcp_pm_addr_entry *local; - unsigned int add_addr_signal_max; - unsigned int local_addr_max; - struct pm_nl_pernet *pernet; -@@ -563,8 +563,6 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) - - /* check first for announce */ - if (msk->pm.add_addr_signaled < add_addr_signal_max) { -- local = select_signal_address(pernet, msk); -- - /* due to racing events on both ends we can reach here while - * previous add address is still running: if we invoke now - * mptcp_pm_announce_addr(), that will fail and the -@@ -575,16 +573,26 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) - if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) - return; - -- if (local) { -- if (mptcp_pm_alloc_anno_list(msk, &local->addr)) { -- __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); -- msk->pm.add_addr_signaled++; -- mptcp_pm_announce_addr(msk, &local->addr, false); -- mptcp_pm_nl_addr_send_ack(msk); -- } -- } -+ local = select_signal_address(pernet, msk); -+ if (!local) -+ goto subflow; -+ -+ /* If the alloc fails, we are on memory pressure, not worth -+ * continuing, and trying to create subflows. -+ */ -+ if (!mptcp_pm_alloc_anno_list(msk, &local->addr)) -+ return; -+ -+ __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); -+ msk->pm.add_addr_signaled++; -+ mptcp_pm_announce_addr(msk, &local->addr, false); -+ mptcp_pm_nl_addr_send_ack(msk); -+ -+ if (local->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) -+ signal_and_subflow = local; - } - -+subflow: - /* check if should create a new subflow */ - while (msk->pm.local_addr_used < local_addr_max && - msk->pm.subflows < subflows_max) { -@@ -592,9 +600,14 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) - bool fullmesh; - int i, nr; - -- local = select_local_address(pernet, msk); -- if (!local) -- break; -+ if (signal_and_subflow) { -+ local = signal_and_subflow; -+ signal_and_subflow = NULL; -+ } else { -+ local = select_local_address(pernet, msk); -+ if (!local) -+ break; -+ } - - fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH); - -@@ -1109,6 +1122,24 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc - return ret; - } - -+bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc) -+{ -+ struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk); -+ struct mptcp_pm_addr_entry *entry; -+ bool backup = false; -+ -+ rcu_read_lock(); -+ list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) { -+ if (mptcp_addresses_equal(&entry->addr, skc, entry->addr.port)) { -+ backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP); -+ break; -+ } -+ } -+ rcu_read_unlock(); -+ -+ return backup; -+} -+ - #define MPTCP_PM_CMD_GRP_OFFSET 0 - #define MPTCP_PM_EV_GRP_OFFSET 1 - -@@ -1341,8 +1372,8 @@ static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info) - if (ret < 0) - return ret; - -- if (addr.addr.port && !(addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) { -- GENL_SET_ERR_MSG(info, "flags must have signal when using port"); -+ if (addr.addr.port && !address_use_port(&addr)) { -+ GENL_SET_ERR_MSG(info, "flags must have signal and not subflow when using port"); - return -EINVAL; - } - -diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c -index f36f87a62dd0d..6738bad048cec 100644 ---- a/net/mptcp/pm_userspace.c -+++ b/net/mptcp/pm_userspace.c -@@ -157,6 +157,24 @@ int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, - return mptcp_userspace_pm_append_new_local_addr(msk, &new_entry, true); - } - -+bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, -+ struct mptcp_addr_info *skc) -+{ -+ struct mptcp_pm_addr_entry *entry; -+ bool backup = false; -+ -+ spin_lock_bh(&msk->pm.lock); -+ list_for_each_entry(entry, &msk->pm.userspace_pm_local_addr_list, list) { -+ if (mptcp_addresses_equal(&entry->addr, skc, false)) { -+ backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP); -+ break; -+ } -+ } -+ spin_unlock_bh(&msk->pm.lock); -+ -+ return backup; -+} -+ - int mptcp_nl_cmd_announce(struct sk_buff *skb, struct genl_info *info) - { - struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN]; -diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h -index c28ac5dfd0b58..0201b1004a3b9 100644 ---- a/net/mptcp/protocol.h -+++ b/net/mptcp/protocol.h -@@ -1032,6 +1032,9 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, - int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); - int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc); - int mptcp_userspace_pm_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc); -+bool mptcp_pm_is_backup(struct mptcp_sock *msk, struct sock_common *skc); -+bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc); -+bool mptcp_userspace_pm_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc); - - static inline u8 subflow_get_local_id(const struct mptcp_subflow_context *subflow) - { -diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c -index bc1efc1787720..927c2d5997dc7 100644 ---- a/net/mptcp/subflow.c -+++ b/net/mptcp/subflow.c -@@ -100,6 +100,7 @@ static struct mptcp_sock *subflow_token_join_request(struct request_sock *req) - return NULL; - } - subflow_req->local_id = local_id; -+ subflow_req->request_bkup = mptcp_pm_is_backup(msk, (struct sock_common *)req); - - return msk; - } -@@ -601,6 +602,8 @@ static int subflow_chk_local_id(struct sock *sk) - return err; - - subflow_set_local_id(subflow, err); -+ subflow->request_bkup = mptcp_pm_is_backup(msk, (struct sock_common *)sk); -+ - return 0; - } - -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index dd044a47c8723..ea139fca74cb9 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -3743,6 +3743,15 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r - nf_tables_rule_destroy(ctx, rule); - } - -+/** nft_chain_validate - loop detection and hook validation -+ * -+ * @ctx: context containing call depth and base chain -+ * @chain: chain to validate -+ * -+ * Walk through the rules of the given chain and chase all jumps/gotos -+ * and set lookups until either the jump limit is hit or all reachable -+ * chains have been validated. -+ */ - int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) - { - struct nft_expr *expr, *last; -@@ -3764,6 +3773,9 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) - if (!expr->ops->validate) - continue; - -+ /* This may call nft_chain_validate() recursively, -+ * callers that do so must increment ctx->level. -+ */ - err = expr->ops->validate(ctx, expr, &data); - if (err < 0) - return err; -@@ -10621,146 +10633,6 @@ int nft_chain_validate_hooks(const struct nft_chain *chain, - } - EXPORT_SYMBOL_GPL(nft_chain_validate_hooks); - --/* -- * Loop detection - walk through the ruleset beginning at the destination chain -- * of a new jump until either the source chain is reached (loop) or all -- * reachable chains have been traversed. -- * -- * The loop check is performed whenever a new jump verdict is added to an -- * expression or verdict map or a verdict map is bound to a new chain. -- */ -- --static int nf_tables_check_loops(const struct nft_ctx *ctx, -- const struct nft_chain *chain); -- --static int nft_check_loops(const struct nft_ctx *ctx, -- const struct nft_set_ext *ext) --{ -- const struct nft_data *data; -- int ret; -- -- data = nft_set_ext_data(ext); -- switch (data->verdict.code) { -- case NFT_JUMP: -- case NFT_GOTO: -- ret = nf_tables_check_loops(ctx, data->verdict.chain); -- break; -- default: -- ret = 0; -- break; -- } -- -- return ret; --} -- --static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx, -- struct nft_set *set, -- const struct nft_set_iter *iter, -- struct nft_set_elem *elem) --{ -- const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); -- -- if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) && -- *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END) -- return 0; -- -- return nft_check_loops(ctx, ext); --} -- --static int nft_set_catchall_loops(const struct nft_ctx *ctx, -- struct nft_set *set) --{ -- u8 genmask = nft_genmask_next(ctx->net); -- struct nft_set_elem_catchall *catchall; -- struct nft_set_ext *ext; -- int ret = 0; -- -- list_for_each_entry_rcu(catchall, &set->catchall_list, list) { -- ext = nft_set_elem_ext(set, catchall->elem); -- if (!nft_set_elem_active(ext, genmask)) -- continue; -- -- ret = nft_check_loops(ctx, ext); -- if (ret < 0) -- return ret; -- } -- -- return ret; --} -- --static int nf_tables_check_loops(const struct nft_ctx *ctx, -- const struct nft_chain *chain) --{ -- const struct nft_rule *rule; -- const struct nft_expr *expr, *last; -- struct nft_set *set; -- struct nft_set_binding *binding; -- struct nft_set_iter iter; -- -- if (ctx->chain == chain) -- return -ELOOP; -- -- if (fatal_signal_pending(current)) -- return -EINTR; -- -- list_for_each_entry(rule, &chain->rules, list) { -- nft_rule_for_each_expr(expr, last, rule) { -- struct nft_immediate_expr *priv; -- const struct nft_data *data; -- int err; -- -- if (strcmp(expr->ops->type->name, "immediate")) -- continue; -- -- priv = nft_expr_priv(expr); -- if (priv->dreg != NFT_REG_VERDICT) -- continue; -- -- data = &priv->data; -- switch (data->verdict.code) { -- case NFT_JUMP: -- case NFT_GOTO: -- err = nf_tables_check_loops(ctx, -- data->verdict.chain); -- if (err < 0) -- return err; -- break; -- default: -- break; -- } -- } -- } -- -- list_for_each_entry(set, &ctx->table->sets, list) { -- if (!nft_is_active_next(ctx->net, set)) -- continue; -- if (!(set->flags & NFT_SET_MAP) || -- set->dtype != NFT_DATA_VERDICT) -- continue; -- -- list_for_each_entry(binding, &set->bindings, list) { -- if (!(binding->flags & NFT_SET_MAP) || -- binding->chain != chain) -- continue; -- -- iter.genmask = nft_genmask_next(ctx->net); -- iter.skip = 0; -- iter.count = 0; -- iter.err = 0; -- iter.fn = nf_tables_loop_check_setelem; -- -- set->ops->walk(ctx, set, &iter); -- if (!iter.err) -- iter.err = nft_set_catchall_loops(ctx, set); -- -- if (iter.err < 0) -- return iter.err; -- } -- } -- -- return 0; --} -- - /** - * nft_parse_u32_check - fetch u32 attribute and check for maximum value - * -@@ -10873,7 +10745,7 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, - if (data != NULL && - (data->verdict.code == NFT_GOTO || - data->verdict.code == NFT_JUMP)) { -- err = nf_tables_check_loops(ctx, data->verdict.chain); -+ err = nft_chain_validate(ctx, data->verdict.chain); - if (err < 0) - return err; - } -diff --git a/net/sctp/input.c b/net/sctp/input.c -index 17fcaa9b0df94..a8a254a5008e5 100644 ---- a/net/sctp/input.c -+++ b/net/sctp/input.c -@@ -735,15 +735,19 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep) - struct sock *sk = ep->base.sk; - struct net *net = sock_net(sk); - struct sctp_hashbucket *head; -+ int err = 0; - - ep->hashent = sctp_ep_hashfn(net, ep->base.bind_addr.port); - head = &sctp_ep_hashtable[ep->hashent]; - -+ write_lock(&head->lock); - if (sk->sk_reuseport) { - bool any = sctp_is_ep_boundall(sk); - struct sctp_endpoint *ep2; - struct list_head *list; -- int cnt = 0, err = 1; -+ int cnt = 0; -+ -+ err = 1; - - list_for_each(list, &ep->base.bind_addr.address_list) - cnt++; -@@ -761,24 +765,24 @@ static int __sctp_hash_endpoint(struct sctp_endpoint *ep) - if (!err) { - err = reuseport_add_sock(sk, sk2, any); - if (err) -- return err; -+ goto out; - break; - } else if (err < 0) { -- return err; -+ goto out; - } - } - - if (err) { - err = reuseport_alloc(sk, any); - if (err) -- return err; -+ goto out; - } - } - -- write_lock(&head->lock); - hlist_add_head(&ep->node, &head->chain); -+out: - write_unlock(&head->lock); -- return 0; -+ return err; - } - - /* Add an endpoint to the hash. Local BH-safe. */ -@@ -803,10 +807,9 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) - - head = &sctp_ep_hashtable[ep->hashent]; - -+ write_lock(&head->lock); - if (rcu_access_pointer(sk->sk_reuseport_cb)) - reuseport_detach_sock(sk); -- -- write_lock(&head->lock); - hlist_del_init(&ep->node); - write_unlock(&head->lock); - } -diff --git a/net/smc/smc_stats.h b/net/smc/smc_stats.h -index 9d32058db2b5d..e19177ce40923 100644 ---- a/net/smc/smc_stats.h -+++ b/net/smc/smc_stats.h -@@ -19,7 +19,7 @@ - - #include "smc_clc.h" - --#define SMC_MAX_FBACK_RSN_CNT 30 -+#define SMC_MAX_FBACK_RSN_CNT 36 - - enum { - SMC_BUF_8K, -diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c -index 6debf4fd42d4e..cef623ea15060 100644 ---- a/net/sunrpc/sched.c -+++ b/net/sunrpc/sched.c -@@ -369,8 +369,10 @@ static void rpc_make_runnable(struct workqueue_struct *wq, - if (RPC_IS_ASYNC(task)) { - INIT_WORK(&task->u.tk_work, rpc_async_schedule); - queue_work(wq, &task->u.tk_work); -- } else -+ } else { -+ smp_mb__after_atomic(); - wake_up_bit(&task->tk_runstate, RPC_TASK_QUEUED); -+ } - } - - /* -diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c -index a551be47cb6c6..b7f62442d8268 100644 ---- a/net/unix/af_unix.c -+++ b/net/unix/af_unix.c -@@ -1483,6 +1483,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, - struct unix_sock *u = unix_sk(sk), *newu, *otheru; - struct net *net = sock_net(sk); - struct sk_buff *skb = NULL; -+ unsigned char state; - long timeo; - int err; - -@@ -1529,7 +1530,6 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, - goto out; - } - -- /* Latch state of peer */ - unix_state_lock(other); - - /* Apparently VFS overslept socket death. Retry. */ -@@ -1559,37 +1559,21 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, - goto restart; - } - -- /* Latch our state. -- -- It is tricky place. We need to grab our state lock and cannot -- drop lock on peer. It is dangerous because deadlock is -- possible. Connect to self case and simultaneous -- attempt to connect are eliminated by checking socket -- state. other is TCP_LISTEN, if sk is TCP_LISTEN we -- check this before attempt to grab lock. -- -- Well, and we have to recheck the state after socket locked. -+ /* self connect and simultaneous connect are eliminated -+ * by rejecting TCP_LISTEN socket to avoid deadlock. - */ -- switch (READ_ONCE(sk->sk_state)) { -- case TCP_CLOSE: -- /* This is ok... continue with connect */ -- break; -- case TCP_ESTABLISHED: -- /* Socket is already connected */ -- err = -EISCONN; -- goto out_unlock; -- default: -- err = -EINVAL; -+ state = READ_ONCE(sk->sk_state); -+ if (unlikely(state != TCP_CLOSE)) { -+ err = state == TCP_ESTABLISHED ? -EISCONN : -EINVAL; - goto out_unlock; - } - - unix_state_lock_nested(sk, U_LOCK_SECOND); - -- if (sk->sk_state != TCP_CLOSE) { -+ if (unlikely(sk->sk_state != TCP_CLOSE)) { -+ err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EINVAL; - unix_state_unlock(sk); -- unix_state_unlock(other); -- sock_put(other); -- goto restart; -+ goto out_unlock; - } - - err = security_unix_stream_connect(sk, other, newsk); -diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c -index 8f8f077e6cd40..be5c42d6ffbea 100644 ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -3398,6 +3398,33 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, - if (chandef.chan != cur_chan) - return -EBUSY; - -+ /* only allow this for regular channel widths */ -+ switch (wdev->links[link_id].ap.chandef.width) { -+ case NL80211_CHAN_WIDTH_20_NOHT: -+ case NL80211_CHAN_WIDTH_20: -+ case NL80211_CHAN_WIDTH_40: -+ case NL80211_CHAN_WIDTH_80: -+ case NL80211_CHAN_WIDTH_80P80: -+ case NL80211_CHAN_WIDTH_160: -+ case NL80211_CHAN_WIDTH_320: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ switch (chandef.width) { -+ case NL80211_CHAN_WIDTH_20_NOHT: -+ case NL80211_CHAN_WIDTH_20: -+ case NL80211_CHAN_WIDTH_40: -+ case NL80211_CHAN_WIDTH_80: -+ case NL80211_CHAN_WIDTH_80P80: -+ case NL80211_CHAN_WIDTH_160: -+ case NL80211_CHAN_WIDTH_320: -+ break; -+ default: -+ return -EINVAL; -+ } -+ - result = rdev_set_ap_chanwidth(rdev, dev, link_id, - &chandef); - if (result) -@@ -4446,10 +4473,7 @@ static void get_key_callback(void *c, struct key_params *params) - struct nlattr *key; - struct get_key_cookie *cookie = c; - -- if ((params->key && -- nla_put(cookie->msg, NL80211_ATTR_KEY_DATA, -- params->key_len, params->key)) || -- (params->seq && -+ if ((params->seq && - nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ, - params->seq_len, params->seq)) || - (params->cipher && -@@ -4461,10 +4485,7 @@ static void get_key_callback(void *c, struct key_params *params) - if (!key) - goto nla_put_failure; - -- if ((params->key && -- nla_put(cookie->msg, NL80211_KEY_DATA, -- params->key_len, params->key)) || -- (params->seq && -+ if ((params->seq && - nla_put(cookie->msg, NL80211_KEY_SEQ, - params->seq_len, params->seq)) || - (params->cipher && -diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c -index 038db8902c9ed..82c0d3a3327ab 100644 ---- a/sound/pci/hda/patch_hdmi.c -+++ b/sound/pci/hda/patch_hdmi.c -@@ -1989,6 +1989,8 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) - } - - static const struct snd_pci_quirk force_connect_list[] = { -+ SND_PCI_QUIRK(0x103c, 0x83e2, "HP EliteDesk 800 G4", 1), -+ SND_PCI_QUIRK(0x103c, 0x83ef, "HP MP9 G4 Retail System AMS", 1), - SND_PCI_QUIRK(0x103c, 0x870f, "HP", 1), - SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1), - SND_PCI_QUIRK(0x103c, 0x8711, "HP", 1), -diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index 0b33a00771450..82dcea2b78000 100644 ---- a/sound/pci/hda/patch_realtek.c -+++ b/sound/pci/hda/patch_realtek.c -@@ -10360,6 +10360,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x8086, 0x3038, "Intel NUC 13", ALC295_FIXUP_CHROME_BOOK), - SND_PCI_QUIRK(0xf111, 0x0001, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), - SND_PCI_QUIRK(0xf111, 0x0006, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), -+ SND_PCI_QUIRK(0xf111, 0x0009, "Framework Laptop", ALC295_FIXUP_FRAMEWORK_LAPTOP_MIC_NO_PRESENCE), - - #if 0 - /* Below is a quirk table taken from the old code. -diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c -index 36dddf230c2c4..d597e59863ee3 100644 ---- a/sound/soc/amd/yc/acp6x-mach.c -+++ b/sound/soc/amd/yc/acp6x-mach.c -@@ -409,6 +409,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { - DMI_MATCH(DMI_BOARD_NAME, "8A43"), - } - }, -+ { -+ .driver_data = &acp6x_card, -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"), -+ DMI_MATCH(DMI_BOARD_NAME, "8A44"), -+ } -+ }, - { - .driver_data = &acp6x_card, - .matches = { -diff --git a/sound/soc/codecs/wcd938x-sdw.c b/sound/soc/codecs/wcd938x-sdw.c -index a1f04010da95f..132c1d24f8f6e 100644 ---- a/sound/soc/codecs/wcd938x-sdw.c -+++ b/sound/soc/codecs/wcd938x-sdw.c -@@ -1252,12 +1252,12 @@ static int wcd9380_probe(struct sdw_slave *pdev, - pdev->prop.lane_control_support = true; - pdev->prop.simple_clk_stop_capable = true; - if (wcd->is_tx) { -- pdev->prop.source_ports = GENMASK(WCD938X_MAX_SWR_PORTS, 0); -+ pdev->prop.source_ports = GENMASK(WCD938X_MAX_SWR_PORTS - 1, 0); - pdev->prop.src_dpn_prop = wcd938x_dpn_prop; - wcd->ch_info = &wcd938x_sdw_tx_ch_info[0]; - pdev->prop.wake_capable = true; - } else { -- pdev->prop.sink_ports = GENMASK(WCD938X_MAX_SWR_PORTS, 0); -+ pdev->prop.sink_ports = GENMASK(WCD938X_MAX_SWR_PORTS - 1, 0); - pdev->prop.sink_dpn_prop = wcd938x_dpn_prop; - wcd->ch_info = &wcd938x_sdw_rx_ch_info[0]; - } -diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c -index 1253695bebd86..53b828f681020 100644 ---- a/sound/soc/codecs/wsa881x.c -+++ b/sound/soc/codecs/wsa881x.c -@@ -1152,7 +1152,7 @@ static int wsa881x_probe(struct sdw_slave *pdev, - wsa881x->sconfig.frame_rate = 48000; - wsa881x->sconfig.direction = SDW_DATA_DIR_RX; - wsa881x->sconfig.type = SDW_STREAM_PDM; -- pdev->prop.sink_ports = GENMASK(WSA881X_MAX_SWR_PORTS, 0); -+ pdev->prop.sink_ports = GENMASK(WSA881X_MAX_SWR_PORTS - 1, 0); - pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop; - pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; - pdev->prop.clk_stop_mode1 = true; -diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c -index a2e86ef7d18f5..2169d93989841 100644 ---- a/sound/soc/codecs/wsa883x.c -+++ b/sound/soc/codecs/wsa883x.c -@@ -1399,7 +1399,15 @@ static int wsa883x_probe(struct sdw_slave *pdev, - wsa883x->sconfig.direction = SDW_DATA_DIR_RX; - wsa883x->sconfig.type = SDW_STREAM_PDM; - -- pdev->prop.sink_ports = GENMASK(WSA883X_MAX_SWR_PORTS, 0); -+ /** -+ * Port map index starts with 0, however the data port for this codec -+ * are from index 1 -+ */ -+ if (of_property_read_u32_array(dev->of_node, "qcom,port-mapping", &pdev->m_port_map[1], -+ WSA883X_MAX_SWR_PORTS)) -+ dev_dbg(dev, "Static Port mapping not specified\n"); -+ -+ pdev->prop.sink_ports = GENMASK(WSA883X_MAX_SWR_PORTS - 1, 0); - pdev->prop.simple_clk_stop_capable = true; - pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop; - pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; -diff --git a/sound/soc/codecs/wsa884x.c b/sound/soc/codecs/wsa884x.c -index 993d76b18b536..1cd52fab7b40d 100644 ---- a/sound/soc/codecs/wsa884x.c -+++ b/sound/soc/codecs/wsa884x.c -@@ -1858,7 +1858,15 @@ static int wsa884x_probe(struct sdw_slave *pdev, - wsa884x->sconfig.direction = SDW_DATA_DIR_RX; - wsa884x->sconfig.type = SDW_STREAM_PDM; - -- pdev->prop.sink_ports = GENMASK(WSA884X_MAX_SWR_PORTS, 0); -+ /** -+ * Port map index starts with 0, however the data port for this codec -+ * are from index 1 -+ */ -+ if (of_property_read_u32_array(dev->of_node, "qcom,port-mapping", &pdev->m_port_map[1], -+ WSA884X_MAX_SWR_PORTS)) -+ dev_dbg(dev, "Static Port mapping not specified\n"); -+ -+ pdev->prop.sink_ports = GENMASK(WSA884X_MAX_SWR_PORTS - 1, 0); - pdev->prop.simple_clk_stop_capable = true; - pdev->prop.sink_dpn_prop = wsa884x_sink_dpn_prop; - pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; -diff --git a/sound/soc/meson/axg-fifo.c b/sound/soc/meson/axg-fifo.c -index 94b169a5493b5..5218e40aeb1bb 100644 ---- a/sound/soc/meson/axg-fifo.c -+++ b/sound/soc/meson/axg-fifo.c -@@ -207,25 +207,18 @@ static irqreturn_t axg_fifo_pcm_irq_block(int irq, void *dev_id) - status = FIELD_GET(STATUS1_INT_STS, status); - axg_fifo_ack_irq(fifo, status); - -- /* Use the thread to call period elapsed on nonatomic links */ -- if (status & FIFO_INT_COUNT_REPEAT) -- return IRQ_WAKE_THREAD; -+ if (status & ~FIFO_INT_COUNT_REPEAT) -+ dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n", -+ status); - -- dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n", -- status); -+ if (status & FIFO_INT_COUNT_REPEAT) { -+ snd_pcm_period_elapsed(ss); -+ return IRQ_HANDLED; -+ } - - return IRQ_NONE; - } - --static irqreturn_t axg_fifo_pcm_irq_block_thread(int irq, void *dev_id) --{ -- struct snd_pcm_substream *ss = dev_id; -- -- snd_pcm_period_elapsed(ss); -- -- return IRQ_HANDLED; --} -- - int axg_fifo_pcm_open(struct snd_soc_component *component, - struct snd_pcm_substream *ss) - { -@@ -251,8 +244,9 @@ int axg_fifo_pcm_open(struct snd_soc_component *component, - if (ret) - return ret; - -- ret = request_threaded_irq(fifo->irq, axg_fifo_pcm_irq_block, -- axg_fifo_pcm_irq_block_thread, -+ /* Use the threaded irq handler only with non-atomic links */ -+ ret = request_threaded_irq(fifo->irq, NULL, -+ axg_fifo_pcm_irq_block, - IRQF_ONESHOT, dev_name(dev), ss); - if (ret) - return ret; -diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c -index 7d6a568556ea4..b5b4ea854da4b 100644 ---- a/sound/soc/sof/mediatek/mt8195/mt8195.c -+++ b/sound/soc/sof/mediatek/mt8195/mt8195.c -@@ -624,7 +624,7 @@ static struct snd_sof_dsp_ops sof_mt8195_ops = { - static struct snd_sof_of_mach sof_mt8195_machs[] = { - { - .compatible = "google,tomato", -- .sof_tplg_filename = "sof-mt8195-mt6359-rt1019-rt5682-dts.tplg" -+ .sof_tplg_filename = "sof-mt8195-mt6359-rt1019-rt5682.tplg" - }, { - .compatible = "mediatek,mt8195", - .sof_tplg_filename = "sof-mt8195.tplg" -diff --git a/sound/soc/sti/sti_uniperif.c b/sound/soc/sti/sti_uniperif.c -index 2c21a86421e66..cc9a8122b9bc2 100644 ---- a/sound/soc/sti/sti_uniperif.c -+++ b/sound/soc/sti/sti_uniperif.c -@@ -352,7 +352,7 @@ static int sti_uniperiph_resume(struct snd_soc_component *component) - return ret; - } - --static int sti_uniperiph_dai_probe(struct snd_soc_dai *dai) -+int sti_uniperiph_dai_probe(struct snd_soc_dai *dai) - { - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct sti_uniperiph_dai *dai_data = &priv->dai_data; -diff --git a/sound/soc/sti/uniperif.h b/sound/soc/sti/uniperif.h -index 2a5de328501c1..74e51f0ff85c8 100644 ---- a/sound/soc/sti/uniperif.h -+++ b/sound/soc/sti/uniperif.h -@@ -1380,6 +1380,7 @@ int uni_reader_init(struct platform_device *pdev, - struct uniperif *reader); - - /* common */ -+int sti_uniperiph_dai_probe(struct snd_soc_dai *dai); - int sti_uniperiph_dai_set_fmt(struct snd_soc_dai *dai, - unsigned int fmt); - -diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c -index dd9013c476649..6d1ce030963c6 100644 ---- a/sound/soc/sti/uniperif_player.c -+++ b/sound/soc/sti/uniperif_player.c -@@ -1038,6 +1038,7 @@ static const struct snd_soc_dai_ops uni_player_dai_ops = { - .startup = uni_player_startup, - .shutdown = uni_player_shutdown, - .prepare = uni_player_prepare, -+ .probe = sti_uniperiph_dai_probe, - .trigger = uni_player_trigger, - .hw_params = sti_uniperiph_dai_hw_params, - .set_fmt = sti_uniperiph_dai_set_fmt, -diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c -index 065c5f0d1f5f0..05ea2b794eb92 100644 ---- a/sound/soc/sti/uniperif_reader.c -+++ b/sound/soc/sti/uniperif_reader.c -@@ -401,6 +401,7 @@ static const struct snd_soc_dai_ops uni_reader_dai_ops = { - .startup = uni_reader_startup, - .shutdown = uni_reader_shutdown, - .prepare = uni_reader_prepare, -+ .probe = sti_uniperiph_dai_probe, - .trigger = uni_reader_trigger, - .hw_params = sti_uniperiph_dai_hw_params, - .set_fmt = sti_uniperiph_dai_set_fmt, -diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c -index f4437015d43a7..9df49a880b750 100644 ---- a/sound/usb/line6/driver.c -+++ b/sound/usb/line6/driver.c -@@ -286,12 +286,14 @@ static void line6_data_received(struct urb *urb) - { - struct usb_line6 *line6 = (struct usb_line6 *)urb->context; - struct midi_buffer *mb = &line6->line6midi->midibuf_in; -+ unsigned long flags; - int done; - - if (urb->status == -ESHUTDOWN) - return; - - if (line6->properties->capabilities & LINE6_CAP_CONTROL_MIDI) { -+ spin_lock_irqsave(&line6->line6midi->lock, flags); - done = - line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length); - -@@ -300,12 +302,15 @@ static void line6_data_received(struct urb *urb) - dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n", - done, urb->actual_length); - } -+ spin_unlock_irqrestore(&line6->line6midi->lock, flags); - - for (;;) { -+ spin_lock_irqsave(&line6->line6midi->lock, flags); - done = - line6_midibuf_read(mb, line6->buffer_message, - LINE6_MIDI_MESSAGE_MAXLEN, - LINE6_MIDIBUF_READ_RX); -+ spin_unlock_irqrestore(&line6->line6midi->lock, flags); - - if (done <= 0) - break; -diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h -index 5d72dc8441cbb..af1b8cf5a9883 100644 ---- a/sound/usb/quirks-table.h -+++ b/sound/usb/quirks-table.h -@@ -2594,6 +2594,10 @@ YAMAHA_DEVICE(0x7010, "UB99"), - } - }, - -+/* Stanton ScratchAmp */ -+{ USB_DEVICE(0x103d, 0x0100) }, -+{ USB_DEVICE(0x103d, 0x0101) }, -+ - /* Novation EMS devices */ - { - USB_DEVICE_VENDOR_SPEC(0x1235, 0x0001), -diff --git a/tools/arch/arm64/include/asm/cputype.h b/tools/arch/arm64/include/asm/cputype.h -index 5f6f84837a490..329d41f8c9237 100644 ---- a/tools/arch/arm64/include/asm/cputype.h -+++ b/tools/arch/arm64/include/asm/cputype.h -@@ -84,6 +84,9 @@ - #define ARM_CPU_PART_CORTEX_X2 0xD48 - #define ARM_CPU_PART_NEOVERSE_N2 0xD49 - #define ARM_CPU_PART_CORTEX_A78C 0xD4B -+#define ARM_CPU_PART_NEOVERSE_V2 0xD4F -+#define ARM_CPU_PART_CORTEX_X4 0xD82 -+#define ARM_CPU_PART_NEOVERSE_V3 0xD84 - - #define APM_CPU_PART_POTENZA 0x000 - -@@ -153,6 +156,9 @@ - #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) - #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) - #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) -+#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2) -+#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4) -+#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) - #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) - #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) - #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) -diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c -index b15b343ebb6b1..9adcda7f1fedc 100644 ---- a/tools/testing/selftests/bpf/prog_tests/send_signal.c -+++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c -@@ -156,7 +156,8 @@ static void test_send_signal_tracepoint(bool signal_thread) - static void test_send_signal_perf(bool signal_thread) - { - struct perf_event_attr attr = { -- .sample_period = 1, -+ .freq = 1, -+ .sample_freq = 1000, - .type = PERF_TYPE_SOFTWARE, - .config = PERF_COUNT_SW_CPU_CLOCK, - }; -diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile -index 292359a542429..8b2b9bb8bad10 100644 ---- a/tools/testing/selftests/mm/Makefile -+++ b/tools/testing/selftests/mm/Makefile -@@ -101,7 +101,7 @@ endif - - endif - --ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64)) -+ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64 s390)) - TEST_GEN_FILES += va_high_addr_switch - TEST_GEN_FILES += virtual_address_range - TEST_GEN_FILES += write_to_hugetlbfs -diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh -index a2dae2a3a93e0..b16b8278c4cea 100755 ---- a/tools/testing/selftests/net/mptcp/mptcp_join.sh -+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh -@@ -812,7 +812,7 @@ pm_nl_check_endpoint() - done - - if [ -z "$id" ]; then -- test_fail "bad test - missing endpoint id" -+ fail_test "bad test - missing endpoint id" - return - fi - -@@ -1559,18 +1559,28 @@ chk_add_nr() - local add_nr=$1 - local echo_nr=$2 - local port_nr=${3:-0} -- local syn_nr=${4:-$port_nr} -- local syn_ack_nr=${5:-$port_nr} -- local ack_nr=${6:-$port_nr} -- local mis_syn_nr=${7:-0} -- local mis_ack_nr=${8:-0} -+ local ns_invert=${4:-""} -+ local syn_nr=$port_nr -+ local syn_ack_nr=$port_nr -+ local ack_nr=$port_nr -+ local mis_syn_nr=0 -+ local mis_ack_nr=0 -+ local ns_tx=$ns1 -+ local ns_rx=$ns2 -+ local extra_msg="" - local count - local timeout - -- timeout=$(ip netns exec $ns1 sysctl -n net.mptcp.add_addr_timeout) -+ if [[ $ns_invert = "invert" ]]; then -+ ns_tx=$ns2 -+ ns_rx=$ns1 -+ extra_msg="invert" -+ fi -+ -+ timeout=$(ip netns exec ${ns_tx} sysctl -n net.mptcp.add_addr_timeout) - - print_check "add" -- count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtAddAddr") -+ count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtAddAddr") - if [ -z "$count" ]; then - print_skip - # if the test configured a short timeout tolerate greater then expected -@@ -1582,7 +1592,7 @@ chk_add_nr() - fi - - print_check "echo" -- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtEchoAdd") -+ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtEchoAdd") - if [ -z "$count" ]; then - print_skip - elif [ "$count" != "$echo_nr" ]; then -@@ -1593,7 +1603,7 @@ chk_add_nr() - - if [ $port_nr -gt 0 ]; then - print_check "pt" -- count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtPortAdd") -+ count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtPortAdd") - if [ -z "$count" ]; then - print_skip - elif [ "$count" != "$port_nr" ]; then -@@ -1603,7 +1613,7 @@ chk_add_nr() - fi - - print_check "syn" -- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinPortSynRx") -+ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPJoinPortSynRx") - if [ -z "$count" ]; then - print_skip - elif [ "$count" != "$syn_nr" ]; then -@@ -1614,7 +1624,7 @@ chk_add_nr() - fi - - print_check "synack" -- count=$(mptcp_lib_get_counter ${ns2} "MPTcpExtMPJoinPortSynAckRx") -+ count=$(mptcp_lib_get_counter ${ns_rx} "MPTcpExtMPJoinPortSynAckRx") - if [ -z "$count" ]; then - print_skip - elif [ "$count" != "$syn_ack_nr" ]; then -@@ -1625,7 +1635,7 @@ chk_add_nr() - fi - - print_check "ack" -- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMPJoinPortAckRx") -+ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMPJoinPortAckRx") - if [ -z "$count" ]; then - print_skip - elif [ "$count" != "$ack_nr" ]; then -@@ -1636,7 +1646,7 @@ chk_add_nr() - fi - - print_check "syn" -- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMismatchPortSynRx") -+ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMismatchPortSynRx") - if [ -z "$count" ]; then - print_skip - elif [ "$count" != "$mis_syn_nr" ]; then -@@ -1647,7 +1657,7 @@ chk_add_nr() - fi - - print_check "ack" -- count=$(mptcp_lib_get_counter ${ns1} "MPTcpExtMismatchPortAckRx") -+ count=$(mptcp_lib_get_counter ${ns_tx} "MPTcpExtMismatchPortAckRx") - if [ -z "$count" ]; then - print_skip - elif [ "$count" != "$mis_ack_nr" ]; then -@@ -1657,6 +1667,8 @@ chk_add_nr() - print_ok - fi - fi -+ -+ print_info "$extra_msg" - } - - chk_add_tx_nr() -@@ -2121,6 +2133,21 @@ signal_address_tests() - chk_add_nr 1 1 - fi - -+ # uncommon: subflow and signal flags on the same endpoint -+ # or because the user wrongly picked both, but still expects the client -+ # to create additional subflows -+ if reset "subflow and signal together"; then -+ pm_nl_set_limits $ns1 0 2 -+ pm_nl_set_limits $ns2 0 2 -+ pm_nl_add_endpoint $ns2 10.0.3.2 flags signal,subflow -+ run_tests $ns1 $ns2 10.0.1.1 -+ chk_join_nr 1 1 1 -+ chk_add_nr 1 1 0 invert # only initiated by ns2 -+ chk_add_nr 0 0 0 # none initiated by ns1 -+ chk_rst_nr 0 0 invert # no RST sent by the client -+ chk_rst_nr 0 0 # no RST sent by the server -+ fi -+ - # accept and use add_addr with additional subflows - if reset "multiple subflows and signal"; then - pm_nl_set_limits $ns1 0 3 -diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh -index be97a7ed09503..f24bd2bf08311 100755 ---- a/tools/testing/selftests/net/mptcp/simult_flows.sh -+++ b/tools/testing/selftests/net/mptcp/simult_flows.sh -@@ -262,7 +262,7 @@ run_test() - do_transfer $small $large $time - lret=$? - mptcp_lib_result_code "${lret}" "${msg}" -- if [ $lret -ne 0 ] && ! mptcp_lib_subtest_is_flaky; then -+ if [ $lret -ne 0 ]; then - ret=$lret - [ $bail -eq 0 ] || exit $ret - fi -@@ -272,7 +272,7 @@ run_test() - do_transfer $large $small $time - lret=$? - mptcp_lib_result_code "${lret}" "${msg}" -- if [ $lret -ne 0 ] && ! mptcp_lib_subtest_is_flaky; then -+ if [ $lret -ne 0 ]; then - ret=$lret - [ $bail -eq 0 ] || exit $ret - fi -@@ -305,7 +305,7 @@ run_test 10 10 0 0 "balanced bwidth" - run_test 10 10 1 25 "balanced bwidth with unbalanced delay" - - # we still need some additional infrastructure to pass the following test-cases --MPTCP_LIB_SUBTEST_FLAKY=1 run_test 10 3 0 0 "unbalanced bwidth" -+run_test 10 3 0 0 "unbalanced bwidth" - run_test 10 3 1 25 "unbalanced bwidth with unbalanced delay" - run_test 10 3 25 1 "unbalanced bwidth with opposed, unbalanced delay" - -diff --git a/tools/testing/selftests/rcutorture/bin/torture.sh b/tools/testing/selftests/rcutorture/bin/torture.sh -index 12b50a4a881ac..89a82f6f140ef 100755 ---- a/tools/testing/selftests/rcutorture/bin/torture.sh -+++ b/tools/testing/selftests/rcutorture/bin/torture.sh -@@ -567,7 +567,7 @@ then - torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 tsc=watchdog" - torture_set "clocksourcewd-1" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --kconfig "CONFIG_TEST_CLOCKSOURCE_WATCHDOG=y" --trust-make - -- torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 clocksource.max_cswd_read_retries=1 tsc=watchdog" -+ torture_bootargs="rcupdate.rcu_cpu_stall_suppress_at_boot=1 torture.disable_onoff_at_boot rcupdate.rcu_task_stall_timeout=30000 tsc=watchdog" - torture_set "clocksourcewd-2" tools/testing/selftests/rcutorture/bin/kvm.sh --allcpus --duration 45s --configs TREE03 --kconfig "CONFIG_TEST_CLOCKSOURCE_WATCHDOG=y" --trust-make - - # In case our work is already done... diff --git a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.46-47.patch b/patch/kernel/archive/odroidxu4-6.6/patch-6.6.46-47.patch deleted file mode 100644 index 830bd4b9a0..0000000000 --- a/patch/kernel/archive/odroidxu4-6.6/patch-6.6.46-47.patch +++ /dev/null @@ -1,4211 +0,0 @@ -diff --git a/Documentation/bpf/map_lpm_trie.rst b/Documentation/bpf/map_lpm_trie.rst -index 74d64a30f50073..f9cd579496c9ce 100644 ---- a/Documentation/bpf/map_lpm_trie.rst -+++ b/Documentation/bpf/map_lpm_trie.rst -@@ -17,7 +17,7 @@ significant byte. - - LPM tries may be created with a maximum prefix length that is a multiple - of 8, in the range from 8 to 2048. The key used for lookup and update --operations is a ``struct bpf_lpm_trie_key``, extended by -+operations is a ``struct bpf_lpm_trie_key_u8``, extended by - ``max_prefixlen/8`` bytes. - - - For IPv4 addresses the data length is 4 bytes -diff --git a/Documentation/mm/page_table_check.rst b/Documentation/mm/page_table_check.rst -index c12838ce6b8de2..c59f22eb6a0f9a 100644 ---- a/Documentation/mm/page_table_check.rst -+++ b/Documentation/mm/page_table_check.rst -@@ -14,7 +14,7 @@ Page table check performs extra verifications at the time when new pages become - accessible from the userspace by getting their page table entries (PTEs PMDs - etc.) added into the table. - --In case of detected corruption, the kernel is crashed. There is a small -+In case of most detected corruption, the kernel is crashed. There is a small - performance and memory overhead associated with the page table check. Therefore, - it is disabled by default, but can be optionally enabled on systems where the - extra hardening outweighs the performance costs. Also, because page table check -@@ -22,6 +22,13 @@ is synchronous, it can help with debugging double map memory corruption issues, - by crashing kernel at the time wrong mapping occurs instead of later which is - often the case with memory corruptions bugs. - -+It can also be used to do page table entry checks over various flags, dump -+warnings when illegal combinations of entry flags are detected. Currently, -+userfaultfd is the only user of such to sanity check wr-protect bit against -+any writable flags. Illegal flag combinations will not directly cause data -+corruption in this case immediately, but that will cause read-only data to -+be writable, leading to corrupt when the page content is later modified. -+ - Double mapping detection logic - ============================== - -diff --git a/Makefile b/Makefile -index 77de99984c2f18..6b967e135c80f0 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - VERSION = 6 - PATCHLEVEL = 6 --SUBLEVEL = 46 -+SUBLEVEL = 47 - EXTRAVERSION = - NAME = Hurr durr I'ma ninja sloth - -diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c -index 15aa9bad1c280b..ca0bf0b92ca09e 100644 ---- a/arch/arm64/kvm/hyp/pgtable.c -+++ b/arch/arm64/kvm/hyp/pgtable.c -@@ -523,7 +523,7 @@ static int hyp_unmap_walker(const struct kvm_pgtable_visit_ctx *ctx, - - kvm_clear_pte(ctx->ptep); - dsb(ishst); -- __tlbi_level(vae2is, __TLBI_VADDR(ctx->addr, 0), ctx->level); -+ __tlbi_level(vae2is, __TLBI_VADDR(ctx->addr, 0), 0); - } else { - if (ctx->end - ctx->addr < granule) - return -EINVAL; -@@ -861,9 +861,13 @@ static void stage2_unmap_put_pte(const struct kvm_pgtable_visit_ctx *ctx, - if (kvm_pte_valid(ctx->old)) { - kvm_clear_pte(ctx->ptep); - -- if (!stage2_unmap_defer_tlb_flush(pgt)) -- kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu, -- ctx->addr, ctx->level); -+ if (kvm_pte_table(ctx->old, ctx->level)) { -+ kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu, ctx->addr, -+ 0); -+ } else if (!stage2_unmap_defer_tlb_flush(pgt)) { -+ kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu, ctx->addr, -+ ctx->level); -+ } - } - - mm_ops->put_page(ctx->ptep); -diff --git a/arch/loongarch/include/uapi/asm/unistd.h b/arch/loongarch/include/uapi/asm/unistd.h -index fcb668984f0336..b344b1f917153b 100644 ---- a/arch/loongarch/include/uapi/asm/unistd.h -+++ b/arch/loongarch/include/uapi/asm/unistd.h -@@ -1,4 +1,5 @@ - /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+#define __ARCH_WANT_NEW_STAT - #define __ARCH_WANT_SYS_CLONE - #define __ARCH_WANT_SYS_CLONE3 - -diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h -index e02b179ec65989..d03fe4fb41f43c 100644 ---- a/arch/x86/include/asm/pgtable.h -+++ b/arch/x86/include/asm/pgtable.h -@@ -387,23 +387,7 @@ static inline pte_t pte_wrprotect(pte_t pte) - #ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP - static inline int pte_uffd_wp(pte_t pte) - { -- bool wp = pte_flags(pte) & _PAGE_UFFD_WP; -- --#ifdef CONFIG_DEBUG_VM -- /* -- * Having write bit for wr-protect-marked present ptes is fatal, -- * because it means the uffd-wp bit will be ignored and write will -- * just go through. -- * -- * Use any chance of pgtable walking to verify this (e.g., when -- * page swapped out or being migrated for all purposes). It means -- * something is already wrong. Tell the admin even before the -- * process crashes. We also nail it with wrong pgtable setup. -- */ -- WARN_ON_ONCE(wp && pte_write(pte)); --#endif -- -- return wp; -+ return pte_flags(pte) & _PAGE_UFFD_WP; - } - - static inline pte_t pte_mkuffd_wp(pte_t pte) -diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c -index 77dbd516a05463..277bf0e8ed0918 100644 ---- a/drivers/ata/libata-scsi.c -+++ b/drivers/ata/libata-scsi.c -@@ -941,8 +941,19 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) - &sense_key, &asc, &ascq); - ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq); - } else { -- /* ATA PASS-THROUGH INFORMATION AVAILABLE */ -- ata_scsi_set_sense(qc->dev, cmd, RECOVERED_ERROR, 0, 0x1D); -+ /* -+ * ATA PASS-THROUGH INFORMATION AVAILABLE -+ * -+ * Note: we are supposed to call ata_scsi_set_sense(), which -+ * respects the D_SENSE bit, instead of unconditionally -+ * generating the sense data in descriptor format. However, -+ * because hdparm, hddtemp, and udisks incorrectly assume sense -+ * data in descriptor format, without even looking at the -+ * RESPONSE CODE field in the returned sense data (to see which -+ * format the returned sense data is in), we are stuck with -+ * being bug compatible with older kernels. -+ */ -+ scsi_build_sense(cmd, 1, RECOVERED_ERROR, 0, 0x1D); - } - } - -diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c -index 2776ca5fc33f39..b215b28cad7b76 100644 ---- a/drivers/isdn/mISDN/socket.c -+++ b/drivers/isdn/mISDN/socket.c -@@ -401,23 +401,23 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) - } - - static int data_sock_setsockopt(struct socket *sock, int level, int optname, -- sockptr_t optval, unsigned int len) -+ sockptr_t optval, unsigned int optlen) - { - struct sock *sk = sock->sk; - int err = 0, opt = 0; - - if (*debug & DEBUG_SOCKET) - printk(KERN_DEBUG "%s(%p, %d, %x, optval, %d)\n", __func__, sock, -- level, optname, len); -+ level, optname, optlen); - - lock_sock(sk); - - switch (optname) { - case MISDN_TIME_STAMP: -- if (copy_from_sockptr(&opt, optval, sizeof(int))) { -- err = -EFAULT; -+ err = copy_safe_from_sockptr(&opt, sizeof(opt), -+ optval, optlen); -+ if (err) - break; -- } - - if (opt) - _pms(sk)->cmask |= MISDN_TIME_STAMP; -diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c -index 22d83ac18eb735..fbf58012becdf2 100644 ---- a/drivers/media/usb/dvb-usb/dvb-usb-init.c -+++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c -@@ -23,40 +23,11 @@ static int dvb_usb_force_pid_filter_usage; - module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444); - MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0)."); - --static int dvb_usb_check_bulk_endpoint(struct dvb_usb_device *d, u8 endpoint) --{ -- if (endpoint) { -- int ret; -- -- ret = usb_pipe_type_check(d->udev, usb_sndbulkpipe(d->udev, endpoint)); -- if (ret) -- return ret; -- ret = usb_pipe_type_check(d->udev, usb_rcvbulkpipe(d->udev, endpoint)); -- if (ret) -- return ret; -- } -- return 0; --} -- --static void dvb_usb_clear_halt(struct dvb_usb_device *d, u8 endpoint) --{ -- if (endpoint) { -- usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, endpoint)); -- usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, endpoint)); -- } --} -- - static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) - { - struct dvb_usb_adapter *adap; - int ret, n, o; - -- ret = dvb_usb_check_bulk_endpoint(d, d->props.generic_bulk_ctrl_endpoint); -- if (ret) -- return ret; -- ret = dvb_usb_check_bulk_endpoint(d, d->props.generic_bulk_ctrl_endpoint_response); -- if (ret) -- return ret; - for (n = 0; n < d->props.num_adapters; n++) { - adap = &d->adapter[n]; - adap->dev = d; -@@ -132,8 +103,10 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) - * when reloading the driver w/o replugging the device - * sometimes a timeout occurs, this helps - */ -- dvb_usb_clear_halt(d, d->props.generic_bulk_ctrl_endpoint); -- dvb_usb_clear_halt(d, d->props.generic_bulk_ctrl_endpoint_response); -+ if (d->props.generic_bulk_ctrl_endpoint != 0) { -+ usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); -+ usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); -+ } - - return 0; - -diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c -index ba8b6bd8233cad..96cca4ee470a4b 100644 ---- a/drivers/net/ppp/pppoe.c -+++ b/drivers/net/ppp/pppoe.c -@@ -1007,26 +1007,21 @@ static int pppoe_recvmsg(struct socket *sock, struct msghdr *m, - struct sk_buff *skb; - int error = 0; - -- if (sk->sk_state & PPPOX_BOUND) { -- error = -EIO; -- goto end; -- } -+ if (sk->sk_state & PPPOX_BOUND) -+ return -EIO; - - skb = skb_recv_datagram(sk, flags, &error); -- if (error < 0) -- goto end; -+ if (!skb) -+ return error; - -- if (skb) { -- total_len = min_t(size_t, total_len, skb->len); -- error = skb_copy_datagram_msg(skb, 0, m, total_len); -- if (error == 0) { -- consume_skb(skb); -- return total_len; -- } -+ total_len = min_t(size_t, total_len, skb->len); -+ error = skb_copy_datagram_msg(skb, 0, m, total_len); -+ if (error == 0) { -+ consume_skb(skb); -+ return total_len; - } - - kfree_skb(skb); --end: - return error; - } - -diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c -index 0fc7aa78b2e5b9..2c3f55877a1134 100644 ---- a/drivers/nvme/host/pci.c -+++ b/drivers/nvme/host/pci.c -@@ -2931,6 +2931,13 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) - return NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND; - } - -+ /* -+ * NVMe SSD drops off the PCIe bus after system idle -+ * for 10 hours on a Lenovo N60z board. -+ */ -+ if (dmi_match(DMI_BOARD_NAME, "LXKT-ZXEG-N6")) -+ return NVME_QUIRK_NO_APST; -+ - return 0; - } - -diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c -index c26545d71d39a3..cd6d5bbb4b9df5 100644 ---- a/fs/binfmt_flat.c -+++ b/fs/binfmt_flat.c -@@ -72,8 +72,10 @@ - - #ifdef CONFIG_BINFMT_FLAT_NO_DATA_START_OFFSET - #define DATA_START_OFFSET_WORDS (0) -+#define MAX_SHARED_LIBS_UPDATE (0) - #else - #define DATA_START_OFFSET_WORDS (MAX_SHARED_LIBS) -+#define MAX_SHARED_LIBS_UPDATE (MAX_SHARED_LIBS) - #endif - - struct lib_info { -@@ -880,7 +882,7 @@ static int load_flat_binary(struct linux_binprm *bprm) - return res; - - /* Update data segment pointers for all libraries */ -- for (i = 0; i < MAX_SHARED_LIBS; i++) { -+ for (i = 0; i < MAX_SHARED_LIBS_UPDATE; i++) { - if (!libinfo.lib_list[i].loaded) - continue; - for (j = 0; j < MAX_SHARED_LIBS; j++) { -diff --git a/fs/buffer.c b/fs/buffer.c -index 12e9a71c693d74..ecd8b47507ff80 100644 ---- a/fs/buffer.c -+++ b/fs/buffer.c -@@ -2179,6 +2179,8 @@ static void __block_commit_write(struct folio *folio, size_t from, size_t to) - struct buffer_head *bh, *head; - - bh = head = folio_buffers(folio); -+ if (!bh) -+ return; - blocksize = bh->b_size; - - block_start = 0; -diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c -index 5ee7d7bbb361ce..2fbf97077ce910 100644 ---- a/fs/cramfs/inode.c -+++ b/fs/cramfs/inode.c -@@ -495,7 +495,7 @@ static void cramfs_kill_sb(struct super_block *sb) - sb->s_mtd = NULL; - } else if (IS_ENABLED(CONFIG_CRAMFS_BLOCKDEV) && sb->s_bdev) { - sync_blockdev(sb->s_bdev); -- blkdev_put(sb->s_bdev, sb); -+ bdev_release(sb->s_bdev_handle); - } - kfree(sbi); - } -diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c -index d36b3963c0bf3c..aa59788a61e6e4 100644 ---- a/fs/erofs/decompressor.c -+++ b/fs/erofs/decompressor.c -@@ -248,15 +248,9 @@ static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx, - if (ret != rq->outputsize) { - erofs_err(rq->sb, "failed to decompress %d in[%u, %u] out[%u]", - ret, rq->inputsize, inputmargin, rq->outputsize); -- -- print_hex_dump(KERN_DEBUG, "[ in]: ", DUMP_PREFIX_OFFSET, -- 16, 1, src + inputmargin, rq->inputsize, true); -- print_hex_dump(KERN_DEBUG, "[out]: ", DUMP_PREFIX_OFFSET, -- 16, 1, out, rq->outputsize, true); -- - if (ret >= 0) - memset(out + ret, 0, rq->outputsize - ret); -- ret = -EIO; -+ ret = -EFSCORRUPTED; - } else { - ret = 0; - } -diff --git a/fs/exec.c b/fs/exec.c -index 89a9017af7e86f..1cbbef281f8cfe 100644 ---- a/fs/exec.c -+++ b/fs/exec.c -@@ -1609,6 +1609,7 @@ static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file) - unsigned int mode; - vfsuid_t vfsuid; - vfsgid_t vfsgid; -+ int err; - - if (!mnt_may_suid(file->f_path.mnt)) - return; -@@ -1625,12 +1626,17 @@ static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file) - /* Be careful if suid/sgid is set */ - inode_lock(inode); - -- /* reload atomically mode/uid/gid now that lock held */ -+ /* Atomically reload and check mode/uid/gid now that lock held. */ - mode = inode->i_mode; - vfsuid = i_uid_into_vfsuid(idmap, inode); - vfsgid = i_gid_into_vfsgid(idmap, inode); -+ err = inode_permission(idmap, inode, MAY_EXEC); - inode_unlock(inode); - -+ /* Did the exec bit vanish out from under us? Give up. */ -+ if (err) -+ return; -+ - /* We ignore suid/sgid if there are no mappings for them in the ns */ - if (!vfsuid_has_mapping(bprm->cred->user_ns, vfsuid) || - !vfsgid_has_mapping(bprm->cred->user_ns, vfsgid)) -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index cef119a2476bb4..a4ffd1acac6514 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -2966,23 +2966,29 @@ static int ext4_da_should_update_i_disksize(struct folio *folio, - - static int ext4_da_do_write_end(struct address_space *mapping, - loff_t pos, unsigned len, unsigned copied, -- struct page *page) -+ struct folio *folio) - { - struct inode *inode = mapping->host; - loff_t old_size = inode->i_size; - bool disksize_changed = false; - loff_t new_i_size; - -+ if (unlikely(!folio_buffers(folio))) { -+ folio_unlock(folio); -+ folio_put(folio); -+ return -EIO; -+ } - /* - * block_write_end() will mark the inode as dirty with I_DIRTY_PAGES - * flag, which all that's needed to trigger page writeback. - */ -- copied = block_write_end(NULL, mapping, pos, len, copied, page, NULL); -+ copied = block_write_end(NULL, mapping, pos, len, copied, -+ &folio->page, NULL); - new_i_size = pos + copied; - - /* -- * It's important to update i_size while still holding page lock, -- * because page writeout could otherwise come in and zero beyond -+ * It's important to update i_size while still holding folio lock, -+ * because folio writeout could otherwise come in and zero beyond - * i_size. - * - * Since we are holding inode lock, we are sure i_disksize <= -@@ -3000,14 +3006,14 @@ static int ext4_da_do_write_end(struct address_space *mapping, - - i_size_write(inode, new_i_size); - end = (new_i_size - 1) & (PAGE_SIZE - 1); -- if (copied && ext4_da_should_update_i_disksize(page_folio(page), end)) { -+ if (copied && ext4_da_should_update_i_disksize(folio, end)) { - ext4_update_i_disksize(inode, new_i_size); - disksize_changed = true; - } - } - -- unlock_page(page); -- put_page(page); -+ folio_unlock(folio); -+ folio_put(folio); - - if (old_size < pos) - pagecache_isize_extended(inode, old_size, pos); -@@ -3046,10 +3052,10 @@ static int ext4_da_write_end(struct file *file, - return ext4_write_inline_data_end(inode, pos, len, copied, - folio); - -- if (unlikely(copied < len) && !PageUptodate(page)) -+ if (unlikely(copied < len) && !folio_test_uptodate(folio)) - copied = 0; - -- return ext4_da_do_write_end(mapping, pos, len, copied, &folio->page); -+ return ext4_da_do_write_end(mapping, pos, len, copied, folio); - } - - /* -diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c -index c58cbe9f7809c1..c368ff671d7739 100644 ---- a/fs/ext4/xattr.c -+++ b/fs/ext4/xattr.c -@@ -1571,46 +1571,49 @@ ext4_xattr_inode_cache_find(struct inode *inode, const void *value, - /* - * Add value of the EA in an inode. - */ --static int ext4_xattr_inode_lookup_create(handle_t *handle, struct inode *inode, -- const void *value, size_t value_len, -- struct inode **ret_inode) -+static struct inode *ext4_xattr_inode_lookup_create(handle_t *handle, -+ struct inode *inode, const void *value, size_t value_len) - { - struct inode *ea_inode; - u32 hash; - int err; - -+ /* Account inode & space to quota even if sharing... */ -+ err = ext4_xattr_inode_alloc_quota(inode, value_len); -+ if (err) -+ return ERR_PTR(err); -+ - hash = ext4_xattr_inode_hash(EXT4_SB(inode->i_sb), value, value_len); - ea_inode = ext4_xattr_inode_cache_find(inode, value, value_len, hash); - if (ea_inode) { - err = ext4_xattr_inode_inc_ref(handle, ea_inode); -- if (err) { -- iput(ea_inode); -- return err; -- } -- -- *ret_inode = ea_inode; -- return 0; -+ if (err) -+ goto out_err; -+ return ea_inode; - } - - /* Create an inode for the EA value */ - ea_inode = ext4_xattr_inode_create(handle, inode, hash); -- if (IS_ERR(ea_inode)) -- return PTR_ERR(ea_inode); -+ if (IS_ERR(ea_inode)) { -+ ext4_xattr_inode_free_quota(inode, NULL, value_len); -+ return ea_inode; -+ } - - err = ext4_xattr_inode_write(handle, ea_inode, value, value_len); - if (err) { - if (ext4_xattr_inode_dec_ref(handle, ea_inode)) - ext4_warning_inode(ea_inode, "cleanup dec ref error %d", err); -- iput(ea_inode); -- return err; -+ goto out_err; - } - - if (EA_INODE_CACHE(inode)) - mb_cache_entry_create(EA_INODE_CACHE(inode), GFP_NOFS, hash, - ea_inode->i_ino, true /* reusable */); -- -- *ret_inode = ea_inode; -- return 0; -+ return ea_inode; -+out_err: -+ iput(ea_inode); -+ ext4_xattr_inode_free_quota(inode, NULL, value_len); -+ return ERR_PTR(err); - } - - /* -@@ -1622,6 +1625,7 @@ static int ext4_xattr_inode_lookup_create(handle_t *handle, struct inode *inode, - static int ext4_xattr_set_entry(struct ext4_xattr_info *i, - struct ext4_xattr_search *s, - handle_t *handle, struct inode *inode, -+ struct inode *new_ea_inode, - bool is_block) - { - struct ext4_xattr_entry *last, *next; -@@ -1629,7 +1633,6 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, - size_t min_offs = s->end - s->base, name_len = strlen(i->name); - int in_inode = i->in_inode; - struct inode *old_ea_inode = NULL; -- struct inode *new_ea_inode = NULL; - size_t old_size, new_size; - int ret; - -@@ -1714,43 +1717,11 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, - old_ea_inode = NULL; - goto out; - } -- } -- if (i->value && in_inode) { -- WARN_ON_ONCE(!i->value_len); -- -- ret = ext4_xattr_inode_alloc_quota(inode, i->value_len); -- if (ret) -- goto out; -- -- ret = ext4_xattr_inode_lookup_create(handle, inode, i->value, -- i->value_len, -- &new_ea_inode); -- if (ret) { -- new_ea_inode = NULL; -- ext4_xattr_inode_free_quota(inode, NULL, i->value_len); -- goto out; -- } -- } - -- if (old_ea_inode) { - /* We are ready to release ref count on the old_ea_inode. */ - ret = ext4_xattr_inode_dec_ref(handle, old_ea_inode); -- if (ret) { -- /* Release newly required ref count on new_ea_inode. */ -- if (new_ea_inode) { -- int err; -- -- err = ext4_xattr_inode_dec_ref(handle, -- new_ea_inode); -- if (err) -- ext4_warning_inode(new_ea_inode, -- "dec ref new_ea_inode err=%d", -- err); -- ext4_xattr_inode_free_quota(inode, new_ea_inode, -- i->value_len); -- } -+ if (ret) - goto out; -- } - - ext4_xattr_inode_free_quota(inode, old_ea_inode, - le32_to_cpu(here->e_value_size)); -@@ -1874,7 +1845,6 @@ static int ext4_xattr_set_entry(struct ext4_xattr_info *i, - ret = 0; - out: - iput(old_ea_inode); -- iput(new_ea_inode); - return ret; - } - -@@ -1937,9 +1907,21 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, - size_t old_ea_inode_quota = 0; - unsigned int ea_ino; - -- - #define header(x) ((struct ext4_xattr_header *)(x)) - -+ /* If we need EA inode, prepare it before locking the buffer */ -+ if (i->value && i->in_inode) { -+ WARN_ON_ONCE(!i->value_len); -+ -+ ea_inode = ext4_xattr_inode_lookup_create(handle, inode, -+ i->value, i->value_len); -+ if (IS_ERR(ea_inode)) { -+ error = PTR_ERR(ea_inode); -+ ea_inode = NULL; -+ goto cleanup; -+ } -+ } -+ - if (s->base) { - int offset = (char *)s->here - bs->bh->b_data; - -@@ -1948,6 +1930,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, - EXT4_JTR_NONE); - if (error) - goto cleanup; -+ - lock_buffer(bs->bh); - - if (header(s->base)->h_refcount == cpu_to_le32(1)) { -@@ -1974,7 +1957,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, - } - ea_bdebug(bs->bh, "modifying in-place"); - error = ext4_xattr_set_entry(i, s, handle, inode, -- true /* is_block */); -+ ea_inode, true /* is_block */); - ext4_xattr_block_csum_set(inode, bs->bh); - unlock_buffer(bs->bh); - if (error == -EFSCORRUPTED) -@@ -2042,29 +2025,13 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, - s->end = s->base + sb->s_blocksize; - } - -- error = ext4_xattr_set_entry(i, s, handle, inode, true /* is_block */); -+ error = ext4_xattr_set_entry(i, s, handle, inode, ea_inode, -+ true /* is_block */); - if (error == -EFSCORRUPTED) - goto bad_block; - if (error) - goto cleanup; - -- if (i->value && s->here->e_value_inum) { -- /* -- * A ref count on ea_inode has been taken as part of the call to -- * ext4_xattr_set_entry() above. We would like to drop this -- * extra ref but we have to wait until the xattr block is -- * initialized and has its own ref count on the ea_inode. -- */ -- ea_ino = le32_to_cpu(s->here->e_value_inum); -- error = ext4_xattr_inode_iget(inode, ea_ino, -- le32_to_cpu(s->here->e_hash), -- &ea_inode); -- if (error) { -- ea_inode = NULL; -- goto cleanup; -- } -- } -- - inserted: - if (!IS_LAST_ENTRY(s->first)) { - new_bh = ext4_xattr_block_cache_find(inode, header(s->base), -@@ -2217,17 +2184,16 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, - - cleanup: - if (ea_inode) { -- int error2; -- -- error2 = ext4_xattr_inode_dec_ref(handle, ea_inode); -- if (error2) -- ext4_warning_inode(ea_inode, "dec ref error=%d", -- error2); -+ if (error) { -+ int error2; - -- /* If there was an error, revert the quota charge. */ -- if (error) -+ error2 = ext4_xattr_inode_dec_ref(handle, ea_inode); -+ if (error2) -+ ext4_warning_inode(ea_inode, "dec ref error=%d", -+ error2); - ext4_xattr_inode_free_quota(inode, ea_inode, - i_size_read(ea_inode)); -+ } - iput(ea_inode); - } - if (ce) -@@ -2285,14 +2251,38 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode, - { - struct ext4_xattr_ibody_header *header; - struct ext4_xattr_search *s = &is->s; -+ struct inode *ea_inode = NULL; - int error; - - if (!EXT4_INODE_HAS_XATTR_SPACE(inode)) - return -ENOSPC; - -- error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */); -- if (error) -+ /* If we need EA inode, prepare it before locking the buffer */ -+ if (i->value && i->in_inode) { -+ WARN_ON_ONCE(!i->value_len); -+ -+ ea_inode = ext4_xattr_inode_lookup_create(handle, inode, -+ i->value, i->value_len); -+ if (IS_ERR(ea_inode)) -+ return PTR_ERR(ea_inode); -+ } -+ error = ext4_xattr_set_entry(i, s, handle, inode, ea_inode, -+ false /* is_block */); -+ if (error) { -+ if (ea_inode) { -+ int error2; -+ -+ error2 = ext4_xattr_inode_dec_ref(handle, ea_inode); -+ if (error2) -+ ext4_warning_inode(ea_inode, "dec ref error=%d", -+ error2); -+ -+ ext4_xattr_inode_free_quota(inode, ea_inode, -+ i_size_read(ea_inode)); -+ iput(ea_inode); -+ } - return error; -+ } - header = IHDR(inode, ext4_raw_inode(&is->iloc)); - if (!IS_LAST_ENTRY(s->first)) { - header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC); -@@ -2301,6 +2291,7 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode, - header->h_magic = cpu_to_le32(0); - ext4_clear_inode_state(inode, EXT4_STATE_XATTR); - } -+ iput(ea_inode); - return 0; - } - -diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c -index ad8dfac73bd446..6a9a470345bfc7 100644 ---- a/fs/f2fs/extent_cache.c -+++ b/fs/f2fs/extent_cache.c -@@ -19,34 +19,24 @@ - #include "node.h" - #include - --bool sanity_check_extent_cache(struct inode *inode) -+bool sanity_check_extent_cache(struct inode *inode, struct page *ipage) - { - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); -- struct f2fs_inode_info *fi = F2FS_I(inode); -- struct extent_tree *et = fi->extent_tree[EX_READ]; -- struct extent_info *ei; -- -- if (!et) -- return true; -+ struct f2fs_extent *i_ext = &F2FS_INODE(ipage)->i_ext; -+ struct extent_info ei; - -- ei = &et->largest; -- if (!ei->len) -- return true; -+ get_read_extent_info(&ei, i_ext); - -- /* Let's drop, if checkpoint got corrupted. */ -- if (is_set_ckpt_flags(sbi, CP_ERROR_FLAG)) { -- ei->len = 0; -- et->largest_updated = true; -+ if (!ei.len) - return true; -- } - -- if (!f2fs_is_valid_blkaddr(sbi, ei->blk, DATA_GENERIC_ENHANCE) || -- !f2fs_is_valid_blkaddr(sbi, ei->blk + ei->len - 1, -+ if (!f2fs_is_valid_blkaddr(sbi, ei.blk, DATA_GENERIC_ENHANCE) || -+ !f2fs_is_valid_blkaddr(sbi, ei.blk + ei.len - 1, - DATA_GENERIC_ENHANCE)) { - set_sbi_flag(sbi, SBI_NEED_FSCK); - f2fs_warn(sbi, "%s: inode (ino=%lx) extent info [%u, %u, %u] is incorrect, run fsck to fix", - __func__, inode->i_ino, -- ei->blk, ei->fofs, ei->len); -+ ei.blk, ei.fofs, ei.len); - return false; - } - return true; -@@ -395,24 +385,22 @@ void f2fs_init_read_extent_tree(struct inode *inode, struct page *ipage) - - if (!__may_extent_tree(inode, EX_READ)) { - /* drop largest read extent */ -- if (i_ext && i_ext->len) { -+ if (i_ext->len) { - f2fs_wait_on_page_writeback(ipage, NODE, true, true); - i_ext->len = 0; - set_page_dirty(ipage); - } -- goto out; -+ set_inode_flag(inode, FI_NO_EXTENT); -+ return; - } - - et = __grab_extent_tree(inode, EX_READ); - -- if (!i_ext || !i_ext->len) -- goto out; -- - get_read_extent_info(&ei, i_ext); - - write_lock(&et->lock); -- if (atomic_read(&et->node_cnt)) -- goto unlock_out; -+ if (atomic_read(&et->node_cnt) || !ei.len) -+ goto skip; - - en = __attach_extent_node(sbi, et, &ei, NULL, - &et->root.rb_root.rb_node, true); -@@ -424,11 +412,13 @@ void f2fs_init_read_extent_tree(struct inode *inode, struct page *ipage) - list_add_tail(&en->list, &eti->extent_list); - spin_unlock(&eti->extent_lock); - } --unlock_out: -+skip: -+ /* Let's drop, if checkpoint got corrupted. */ -+ if (f2fs_cp_error(sbi)) { -+ et->largest.len = 0; -+ et->largest_updated = true; -+ } - write_unlock(&et->lock); --out: -- if (!F2FS_I(inode)->extent_tree[EX_READ]) -- set_inode_flag(inode, FI_NO_EXTENT); - } - - void f2fs_init_age_extent_tree(struct inode *inode) -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index 19490dd8321943..00eff023cd9d63 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -4189,7 +4189,7 @@ void f2fs_leave_shrinker(struct f2fs_sb_info *sbi); - /* - * extent_cache.c - */ --bool sanity_check_extent_cache(struct inode *inode); -+bool sanity_check_extent_cache(struct inode *inode, struct page *ipage); - void f2fs_init_extent_tree(struct inode *inode); - void f2fs_drop_extent_tree(struct inode *inode); - void f2fs_destroy_extent_node(struct inode *inode); -diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c -index afb7c88ba06b2c..888c301ffe8f4c 100644 ---- a/fs/f2fs/gc.c -+++ b/fs/f2fs/gc.c -@@ -1563,6 +1563,16 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, - continue; - } - -+ if (f2fs_has_inline_data(inode)) { -+ iput(inode); -+ set_sbi_flag(sbi, SBI_NEED_FSCK); -+ f2fs_err_ratelimited(sbi, -+ "inode %lx has both inline_data flag and " -+ "data block, nid=%u, ofs_in_node=%u", -+ inode->i_ino, dni.nid, ofs_in_node); -+ continue; -+ } -+ - err = f2fs_gc_pinned_control(inode, gc_type, segno); - if (err == -EAGAIN) { - iput(inode); -diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c -index 0172f4e503061d..26e857fee631d9 100644 ---- a/fs/f2fs/inode.c -+++ b/fs/f2fs/inode.c -@@ -511,16 +511,16 @@ static int do_read_inode(struct inode *inode) - - init_idisk_time(inode); - -- /* Need all the flag bits */ -- f2fs_init_read_extent_tree(inode, node_page); -- f2fs_init_age_extent_tree(inode); -- -- if (!sanity_check_extent_cache(inode)) { -+ if (!sanity_check_extent_cache(inode, node_page)) { - f2fs_put_page(node_page, 1); - f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); - return -EFSCORRUPTED; - } - -+ /* Need all the flag bits */ -+ f2fs_init_read_extent_tree(inode, node_page); -+ f2fs_init_age_extent_tree(inode); -+ - f2fs_put_page(node_page, 1); - - stat_inc_inline_xattr(inode); -diff --git a/fs/fhandle.c b/fs/fhandle.c -index 99dcf07cfecfe1..c361d7ff1b88dd 100644 ---- a/fs/fhandle.c -+++ b/fs/fhandle.c -@@ -40,7 +40,7 @@ static long do_sys_name_to_handle(const struct path *path, - if (f_handle.handle_bytes > MAX_HANDLE_SZ) - return -EINVAL; - -- handle = kzalloc(sizeof(struct file_handle) + f_handle.handle_bytes, -+ handle = kzalloc(struct_size(handle, f_handle, f_handle.handle_bytes), - GFP_KERNEL); - if (!handle) - return -ENOMEM; -@@ -75,7 +75,7 @@ static long do_sys_name_to_handle(const struct path *path, - /* copy the mount id */ - if (put_user(real_mount(path->mnt)->mnt_id, mnt_id) || - copy_to_user(ufh, handle, -- sizeof(struct file_handle) + handle_bytes)) -+ struct_size(handle, f_handle, handle_bytes))) - retval = -EFAULT; - kfree(handle); - return retval; -@@ -196,7 +196,7 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh, - retval = -EINVAL; - goto out_err; - } -- handle = kmalloc(sizeof(struct file_handle) + f_handle.handle_bytes, -+ handle = kmalloc(struct_size(handle, f_handle, f_handle.handle_bytes), - GFP_KERNEL); - if (!handle) { - retval = -ENOMEM; -diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c -index cb3cda1390adb1..5713994328cbcb 100644 ---- a/fs/jfs/jfs_dmap.c -+++ b/fs/jfs/jfs_dmap.c -@@ -1626,6 +1626,8 @@ s64 dbDiscardAG(struct inode *ip, int agno, s64 minlen) - } else if (rc == -ENOSPC) { - /* search for next smaller log2 block */ - l2nb = BLKSTOL2(nblocks) - 1; -+ if (unlikely(l2nb < 0)) -+ break; - nblocks = 1LL << l2nb; - } else { - /* Trim any already allocated blocks */ -diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c -index 031d8f570f581f..5d3127ca68a42d 100644 ---- a/fs/jfs/jfs_dtree.c -+++ b/fs/jfs/jfs_dtree.c -@@ -834,6 +834,8 @@ int dtInsert(tid_t tid, struct inode *ip, - * the full page. - */ - DT_GETSEARCH(ip, btstack->top, bn, mp, p, index); -+ if (p->header.freelist == 0) -+ return -EINVAL; - - /* - * insert entry for new key -diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c -index e855b8fde76ce1..cb6d1fda66a702 100644 ---- a/fs/jfs/jfs_logmgr.c -+++ b/fs/jfs/jfs_logmgr.c -@@ -1058,7 +1058,7 @@ void jfs_syncpt(struct jfs_log *log, int hard_sync) - int lmLogOpen(struct super_block *sb) - { - int rc; -- struct block_device *bdev; -+ struct bdev_handle *bdev_handle; - struct jfs_log *log; - struct jfs_sb_info *sbi = JFS_SBI(sb); - -@@ -1070,7 +1070,7 @@ int lmLogOpen(struct super_block *sb) - - mutex_lock(&jfs_log_mutex); - list_for_each_entry(log, &jfs_external_logs, journal_list) { -- if (log->bdev->bd_dev == sbi->logdev) { -+ if (log->bdev_handle->bdev->bd_dev == sbi->logdev) { - if (!uuid_equal(&log->uuid, &sbi->loguuid)) { - jfs_warn("wrong uuid on JFS journal"); - mutex_unlock(&jfs_log_mutex); -@@ -1100,14 +1100,14 @@ int lmLogOpen(struct super_block *sb) - * file systems to log may have n-to-1 relationship; - */ - -- bdev = blkdev_get_by_dev(sbi->logdev, BLK_OPEN_READ | BLK_OPEN_WRITE, -- log, NULL); -- if (IS_ERR(bdev)) { -- rc = PTR_ERR(bdev); -+ bdev_handle = bdev_open_by_dev(sbi->logdev, -+ BLK_OPEN_READ | BLK_OPEN_WRITE, log, NULL); -+ if (IS_ERR(bdev_handle)) { -+ rc = PTR_ERR(bdev_handle); - goto free; - } - -- log->bdev = bdev; -+ log->bdev_handle = bdev_handle; - uuid_copy(&log->uuid, &sbi->loguuid); - - /* -@@ -1141,7 +1141,7 @@ int lmLogOpen(struct super_block *sb) - lbmLogShutdown(log); - - close: /* close external log device */ -- blkdev_put(bdev, log); -+ bdev_release(bdev_handle); - - free: /* free log descriptor */ - mutex_unlock(&jfs_log_mutex); -@@ -1162,7 +1162,7 @@ static int open_inline_log(struct super_block *sb) - init_waitqueue_head(&log->syncwait); - - set_bit(log_INLINELOG, &log->flag); -- log->bdev = sb->s_bdev; -+ log->bdev_handle = sb->s_bdev_handle; - log->base = addressPXD(&JFS_SBI(sb)->logpxd); - log->size = lengthPXD(&JFS_SBI(sb)->logpxd) >> - (L2LOGPSIZE - sb->s_blocksize_bits); -@@ -1436,7 +1436,7 @@ int lmLogClose(struct super_block *sb) - { - struct jfs_sb_info *sbi = JFS_SBI(sb); - struct jfs_log *log = sbi->log; -- struct block_device *bdev; -+ struct bdev_handle *bdev_handle; - int rc = 0; - - jfs_info("lmLogClose: log:0x%p", log); -@@ -1482,10 +1482,10 @@ int lmLogClose(struct super_block *sb) - * external log as separate logical volume - */ - list_del(&log->journal_list); -- bdev = log->bdev; -+ bdev_handle = log->bdev_handle; - rc = lmLogShutdown(log); - -- blkdev_put(bdev, log); -+ bdev_release(bdev_handle); - - kfree(log); - -@@ -1972,7 +1972,7 @@ static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp) - - bp->l_flag |= lbmREAD; - -- bio = bio_alloc(log->bdev, 1, REQ_OP_READ, GFP_NOFS); -+ bio = bio_alloc(log->bdev_handle->bdev, 1, REQ_OP_READ, GFP_NOFS); - bio->bi_iter.bi_sector = bp->l_blkno << (log->l2bsize - 9); - __bio_add_page(bio, bp->l_page, LOGPSIZE, bp->l_offset); - BUG_ON(bio->bi_iter.bi_size != LOGPSIZE); -@@ -2110,10 +2110,15 @@ static void lbmStartIO(struct lbuf * bp) - { - struct bio *bio; - struct jfs_log *log = bp->l_log; -+ struct block_device *bdev = NULL; - - jfs_info("lbmStartIO"); - -- bio = bio_alloc(log->bdev, 1, REQ_OP_WRITE | REQ_SYNC, GFP_NOFS); -+ if (!log->no_integrity) -+ bdev = log->bdev_handle->bdev; -+ -+ bio = bio_alloc(bdev, 1, REQ_OP_WRITE | REQ_SYNC, -+ GFP_NOFS); - bio->bi_iter.bi_sector = bp->l_blkno << (log->l2bsize - 9); - __bio_add_page(bio, bp->l_page, LOGPSIZE, bp->l_offset); - BUG_ON(bio->bi_iter.bi_size != LOGPSIZE); -diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h -index 805877ce502044..84aa2d25390743 100644 ---- a/fs/jfs/jfs_logmgr.h -+++ b/fs/jfs/jfs_logmgr.h -@@ -356,7 +356,7 @@ struct jfs_log { - * before writing syncpt. - */ - struct list_head journal_list; /* Global list */ -- struct block_device *bdev; /* 4: log lv pointer */ -+ struct bdev_handle *bdev_handle; /* 4: log lv pointer */ - int serial; /* 4: log mount serial number */ - - s64 base; /* @8: log extent address (inline log ) */ -diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c -index 631b8bd3e43849..9b5c6a20b30c83 100644 ---- a/fs/jfs/jfs_mount.c -+++ b/fs/jfs/jfs_mount.c -@@ -430,7 +430,8 @@ int updateSuper(struct super_block *sb, uint state) - - if (state == FM_MOUNT) { - /* record log's dev_t and mount serial number */ -- j_sb->s_logdev = cpu_to_le32(new_encode_dev(sbi->log->bdev->bd_dev)); -+ j_sb->s_logdev = cpu_to_le32( -+ new_encode_dev(sbi->log->bdev_handle->bdev->bd_dev)); - j_sb->s_logserial = cpu_to_le32(sbi->log->serial); - } else if (state == FM_CLEAN) { - /* -diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c -index 6579948070a482..a62331487ebf16 100644 ---- a/fs/lockd/svc.c -+++ b/fs/lockd/svc.c -@@ -712,8 +712,6 @@ static const struct svc_version *nlmsvc_version[] = { - #endif - }; - --static struct svc_stat nlmsvc_stats; -- - #define NLM_NRVERS ARRAY_SIZE(nlmsvc_version) - static struct svc_program nlmsvc_program = { - .pg_prog = NLM_PROGRAM, /* program number */ -@@ -721,7 +719,6 @@ static struct svc_program nlmsvc_program = { - .pg_vers = nlmsvc_version, /* version table */ - .pg_name = "lockd", /* service name */ - .pg_class = "nfsd", /* share authentication with nfsd */ -- .pg_stats = &nlmsvc_stats, /* stats table */ - .pg_authenticate = &lockd_authenticate, /* export authentication */ - .pg_init_request = svc_generic_init_request, - .pg_rpcbind_set = svc_generic_rpcbind_set, -diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c -index 466ebf1d41b2b7..869c88978899c0 100644 ---- a/fs/nfs/callback.c -+++ b/fs/nfs/callback.c -@@ -399,15 +399,12 @@ static const struct svc_version *nfs4_callback_version[] = { - [4] = &nfs4_callback_version4, - }; - --static struct svc_stat nfs4_callback_stats; -- - static struct svc_program nfs4_callback_program = { - .pg_prog = NFS4_CALLBACK, /* RPC service number */ - .pg_nvers = ARRAY_SIZE(nfs4_callback_version), /* Number of entries */ - .pg_vers = nfs4_callback_version, /* version table */ - .pg_name = "NFSv4 callback", /* service name */ - .pg_class = "nfs", /* authentication class */ -- .pg_stats = &nfs4_callback_stats, - .pg_authenticate = nfs_callback_authenticate, - .pg_init_request = svc_generic_init_request, - .pg_rpcbind_set = svc_generic_rpcbind_set, -diff --git a/fs/nfsd/cache.h b/fs/nfsd/cache.h -index 4cbe0434cbb8ce..66a05fefae98ea 100644 ---- a/fs/nfsd/cache.h -+++ b/fs/nfsd/cache.h -@@ -80,8 +80,6 @@ enum { - - int nfsd_drc_slab_create(void); - void nfsd_drc_slab_free(void); --int nfsd_net_reply_cache_init(struct nfsd_net *nn); --void nfsd_net_reply_cache_destroy(struct nfsd_net *nn); - int nfsd_reply_cache_init(struct nfsd_net *); - void nfsd_reply_cache_shutdown(struct nfsd_net *); - int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, -diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c -index 11a0eaa2f91407..b7da17e530077e 100644 ---- a/fs/nfsd/export.c -+++ b/fs/nfsd/export.c -@@ -339,12 +339,16 @@ static int export_stats_init(struct export_stats *stats) - - static void export_stats_reset(struct export_stats *stats) - { -- nfsd_percpu_counters_reset(stats->counter, EXP_STATS_COUNTERS_NUM); -+ if (stats) -+ nfsd_percpu_counters_reset(stats->counter, -+ EXP_STATS_COUNTERS_NUM); - } - - static void export_stats_destroy(struct export_stats *stats) - { -- nfsd_percpu_counters_destroy(stats->counter, EXP_STATS_COUNTERS_NUM); -+ if (stats) -+ nfsd_percpu_counters_destroy(stats->counter, -+ EXP_STATS_COUNTERS_NUM); - } - - static void svc_export_put(struct kref *ref) -@@ -353,7 +357,8 @@ static void svc_export_put(struct kref *ref) - path_put(&exp->ex_path); - auth_domain_put(exp->ex_client); - nfsd4_fslocs_free(&exp->ex_fslocs); -- export_stats_destroy(&exp->ex_stats); -+ export_stats_destroy(exp->ex_stats); -+ kfree(exp->ex_stats); - kfree(exp->ex_uuid); - kfree_rcu(exp, ex_rcu); - } -@@ -767,13 +772,15 @@ static int svc_export_show(struct seq_file *m, - seq_putc(m, '\t'); - seq_escape(m, exp->ex_client->name, " \t\n\\"); - if (export_stats) { -- seq_printf(m, "\t%lld\n", exp->ex_stats.start_time); -+ struct percpu_counter *counter = exp->ex_stats->counter; -+ -+ seq_printf(m, "\t%lld\n", exp->ex_stats->start_time); - seq_printf(m, "\tfh_stale: %lld\n", -- percpu_counter_sum_positive(&exp->ex_stats.counter[EXP_STATS_FH_STALE])); -+ percpu_counter_sum_positive(&counter[EXP_STATS_FH_STALE])); - seq_printf(m, "\tio_read: %lld\n", -- percpu_counter_sum_positive(&exp->ex_stats.counter[EXP_STATS_IO_READ])); -+ percpu_counter_sum_positive(&counter[EXP_STATS_IO_READ])); - seq_printf(m, "\tio_write: %lld\n", -- percpu_counter_sum_positive(&exp->ex_stats.counter[EXP_STATS_IO_WRITE])); -+ percpu_counter_sum_positive(&counter[EXP_STATS_IO_WRITE])); - seq_putc(m, '\n'); - return 0; - } -@@ -819,7 +826,7 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem) - new->ex_layout_types = 0; - new->ex_uuid = NULL; - new->cd = item->cd; -- export_stats_reset(&new->ex_stats); -+ export_stats_reset(new->ex_stats); - } - - static void export_update(struct cache_head *cnew, struct cache_head *citem) -@@ -856,7 +863,14 @@ static struct cache_head *svc_export_alloc(void) - if (!i) - return NULL; - -- if (export_stats_init(&i->ex_stats)) { -+ i->ex_stats = kmalloc(sizeof(*(i->ex_stats)), GFP_KERNEL); -+ if (!i->ex_stats) { -+ kfree(i); -+ return NULL; -+ } -+ -+ if (export_stats_init(i->ex_stats)) { -+ kfree(i->ex_stats); - kfree(i); - return NULL; - } -diff --git a/fs/nfsd/export.h b/fs/nfsd/export.h -index 2df8ae25aad302..ca9dc230ae3d0b 100644 ---- a/fs/nfsd/export.h -+++ b/fs/nfsd/export.h -@@ -64,10 +64,10 @@ struct svc_export { - struct cache_head h; - struct auth_domain * ex_client; - int ex_flags; -+ int ex_fsid; - struct path ex_path; - kuid_t ex_anon_uid; - kgid_t ex_anon_gid; -- int ex_fsid; - unsigned char * ex_uuid; /* 16 byte fsid */ - struct nfsd4_fs_locations ex_fslocs; - uint32_t ex_nflavors; -@@ -76,8 +76,8 @@ struct svc_export { - struct nfsd4_deviceid_map *ex_devid_map; - struct cache_detail *cd; - struct rcu_head ex_rcu; -- struct export_stats ex_stats; - unsigned long ex_xprtsec_modes; -+ struct export_stats *ex_stats; - }; - - /* an "export key" (expkey) maps a filehandlefragement to an -diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h -index ec49b200b79762..9bfca3dda63d33 100644 ---- a/fs/nfsd/netns.h -+++ b/fs/nfsd/netns.h -@@ -11,8 +11,10 @@ - #include - #include - #include -+#include - #include - #include -+#include - - /* Hash tables for nfs4_clientid state */ - #define CLIENT_HASH_BITS 4 -@@ -26,10 +28,22 @@ struct nfsd4_client_tracking_ops; - - enum { - /* cache misses due only to checksum comparison failures */ -- NFSD_NET_PAYLOAD_MISSES, -+ NFSD_STATS_PAYLOAD_MISSES, - /* amount of memory (in bytes) currently consumed by the DRC */ -- NFSD_NET_DRC_MEM_USAGE, -- NFSD_NET_COUNTERS_NUM -+ NFSD_STATS_DRC_MEM_USAGE, -+ NFSD_STATS_RC_HITS, /* repcache hits */ -+ NFSD_STATS_RC_MISSES, /* repcache misses */ -+ NFSD_STATS_RC_NOCACHE, /* uncached reqs */ -+ NFSD_STATS_FH_STALE, /* FH stale error */ -+ NFSD_STATS_IO_READ, /* bytes returned to read requests */ -+ NFSD_STATS_IO_WRITE, /* bytes passed in write requests */ -+#ifdef CONFIG_NFSD_V4 -+ NFSD_STATS_FIRST_NFS4_OP, /* count of individual nfsv4 operations */ -+ NFSD_STATS_LAST_NFS4_OP = NFSD_STATS_FIRST_NFS4_OP + LAST_NFS4_OP, -+#define NFSD_STATS_NFS4_OP(op) (NFSD_STATS_FIRST_NFS4_OP + (op)) -+ NFSD_STATS_WDELEG_GETATTR, /* count of getattr conflict with wdeleg */ -+#endif -+ NFSD_STATS_COUNTERS_NUM - }; - - /* -@@ -169,7 +183,10 @@ struct nfsd_net { - atomic_t num_drc_entries; - - /* Per-netns stats counters */ -- struct percpu_counter counter[NFSD_NET_COUNTERS_NUM]; -+ struct percpu_counter counter[NFSD_STATS_COUNTERS_NUM]; -+ -+ /* sunrpc svc stats */ -+ struct svc_stat nfsd_svcstats; - - /* longest hash chain seen */ - unsigned int longest_chain; -diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c -index 451026f9986b61..ae0057c54ef4ed 100644 ---- a/fs/nfsd/nfs4proc.c -+++ b/fs/nfsd/nfs4proc.c -@@ -2478,10 +2478,10 @@ nfsd4_proc_null(struct svc_rqst *rqstp) - return rpc_success; - } - --static inline void nfsd4_increment_op_stats(u32 opnum) -+static inline void nfsd4_increment_op_stats(struct nfsd_net *nn, u32 opnum) - { - if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP) -- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_NFS4_OP(opnum)]); -+ percpu_counter_inc(&nn->counter[NFSD_STATS_NFS4_OP(opnum)]); - } - - static const struct nfsd4_operation nfsd4_ops[]; -@@ -2756,7 +2756,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp) - status, nfsd4_op_name(op->opnum)); - - nfsd4_cstate_clear_replay(cstate); -- nfsd4_increment_op_stats(op->opnum); -+ nfsd4_increment_op_stats(nn, op->opnum); - } - - fh_put(current_fh); -diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c -index c7e52d980cd75f..cdad1eaa4a3180 100644 ---- a/fs/nfsd/nfs4state.c -+++ b/fs/nfsd/nfs4state.c -@@ -8422,6 +8422,7 @@ __be32 - nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct inode *inode) - { - __be32 status; -+ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); - struct file_lock_context *ctx; - struct file_lock *fl; - struct nfs4_delegation *dp; -@@ -8451,7 +8452,7 @@ nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct inode *inode) - } - break_lease: - spin_unlock(&ctx->flc_lock); -- nfsd_stats_wdeleg_getattr_inc(); -+ nfsd_stats_wdeleg_getattr_inc(nn); - status = nfserrno(nfsd_open_break_lease(inode, NFSD_MAY_READ)); - if (status != nfserr_jukebox || - !nfsd_wait_for_delegreturn(rqstp, inode)) -diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c -index 6cd36af2f97e10..c52132ecb339d5 100644 ---- a/fs/nfsd/nfscache.c -+++ b/fs/nfsd/nfscache.c -@@ -176,27 +176,6 @@ void nfsd_drc_slab_free(void) - kmem_cache_destroy(drc_slab); - } - --/** -- * nfsd_net_reply_cache_init - per net namespace reply cache set-up -- * @nn: nfsd_net being initialized -- * -- * Returns zero on succes; otherwise a negative errno is returned. -- */ --int nfsd_net_reply_cache_init(struct nfsd_net *nn) --{ -- return nfsd_percpu_counters_init(nn->counter, NFSD_NET_COUNTERS_NUM); --} -- --/** -- * nfsd_net_reply_cache_destroy - per net namespace reply cache tear-down -- * @nn: nfsd_net being freed -- * -- */ --void nfsd_net_reply_cache_destroy(struct nfsd_net *nn) --{ -- nfsd_percpu_counters_destroy(nn->counter, NFSD_NET_COUNTERS_NUM); --} -- - int nfsd_reply_cache_init(struct nfsd_net *nn) - { - unsigned int hashsize; -@@ -502,7 +481,7 @@ nfsd_cache_insert(struct nfsd_drc_bucket *b, struct nfsd_cacherep *key, - int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, - unsigned int len, struct nfsd_cacherep **cacherep) - { -- struct nfsd_net *nn; -+ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); - struct nfsd_cacherep *rp, *found; - __wsum csum; - struct nfsd_drc_bucket *b; -@@ -512,7 +491,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, - int rtn = RC_DOIT; - - if (type == RC_NOCACHE) { -- nfsd_stats_rc_nocache_inc(); -+ nfsd_stats_rc_nocache_inc(nn); - goto out; - } - -@@ -522,7 +501,6 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, - * Since the common case is a cache miss followed by an insert, - * preallocate an entry. - */ -- nn = net_generic(SVC_NET(rqstp), nfsd_net_id); - rp = nfsd_cacherep_alloc(rqstp, csum, nn); - if (!rp) - goto out; -@@ -540,7 +518,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, - freed = nfsd_cacherep_dispose(&dispose); - trace_nfsd_drc_gc(nn, freed); - -- nfsd_stats_rc_misses_inc(); -+ nfsd_stats_rc_misses_inc(nn); - atomic_inc(&nn->num_drc_entries); - nfsd_stats_drc_mem_usage_add(nn, sizeof(*rp)); - goto out; -@@ -548,7 +526,7 @@ int nfsd_cache_lookup(struct svc_rqst *rqstp, unsigned int start, - found_entry: - /* We found a matching entry which is either in progress or done. */ - nfsd_reply_cache_free_locked(NULL, rp, nn); -- nfsd_stats_rc_hits_inc(); -+ nfsd_stats_rc_hits_inc(nn); - rtn = RC_DROPIT; - rp = found; - -@@ -690,15 +668,15 @@ int nfsd_reply_cache_stats_show(struct seq_file *m, void *v) - atomic_read(&nn->num_drc_entries)); - seq_printf(m, "hash buckets: %u\n", 1 << nn->maskbits); - seq_printf(m, "mem usage: %lld\n", -- percpu_counter_sum_positive(&nn->counter[NFSD_NET_DRC_MEM_USAGE])); -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_DRC_MEM_USAGE])); - seq_printf(m, "cache hits: %lld\n", -- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_HITS])); -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_HITS])); - seq_printf(m, "cache misses: %lld\n", -- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_MISSES])); -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_MISSES])); - seq_printf(m, "not cached: %lld\n", -- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE])); -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_NOCACHE])); - seq_printf(m, "payload misses: %lld\n", -- percpu_counter_sum_positive(&nn->counter[NFSD_NET_PAYLOAD_MISSES])); -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_PAYLOAD_MISSES])); - seq_printf(m, "longest chain len: %u\n", nn->longest_chain); - seq_printf(m, "cachesize at longest: %u\n", nn->longest_chain_cachesize); - return 0; -diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c -index a13e81e450718a..887035b7446763 100644 ---- a/fs/nfsd/nfsctl.c -+++ b/fs/nfsd/nfsctl.c -@@ -1524,14 +1524,17 @@ static __net_init int nfsd_net_init(struct net *net) - retval = nfsd_idmap_init(net); - if (retval) - goto out_idmap_error; -- retval = nfsd_net_reply_cache_init(nn); -+ retval = nfsd_stat_counters_init(nn); - if (retval) - goto out_repcache_error; -+ memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats)); -+ nn->nfsd_svcstats.program = &nfsd_program; - nn->nfsd_versions = NULL; - nn->nfsd4_minorversions = NULL; - nfsd4_init_leases_net(nn); - get_random_bytes(&nn->siphash_key, sizeof(nn->siphash_key)); - seqlock_init(&nn->writeverf_lock); -+ nfsd_proc_stat_init(net); - - return 0; - -@@ -1552,7 +1555,8 @@ static __net_exit void nfsd_net_exit(struct net *net) - { - struct nfsd_net *nn = net_generic(net, nfsd_net_id); - -- nfsd_net_reply_cache_destroy(nn); -+ nfsd_proc_stat_shutdown(net); -+ nfsd_stat_counters_destroy(nn); - nfsd_idmap_shutdown(net); - nfsd_export_shutdown(net); - nfsd_netns_free_versions(nn); -@@ -1575,12 +1579,9 @@ static int __init init_nfsd(void) - retval = nfsd4_init_pnfs(); - if (retval) - goto out_free_slabs; -- retval = nfsd_stat_init(); /* Statistics */ -- if (retval) -- goto out_free_pnfs; - retval = nfsd_drc_slab_create(); - if (retval) -- goto out_free_stat; -+ goto out_free_pnfs; - nfsd_lockd_init(); /* lockd->nfsd callbacks */ - retval = create_proc_exports_entry(); - if (retval) -@@ -1610,8 +1611,6 @@ static int __init init_nfsd(void) - out_free_lockd: - nfsd_lockd_shutdown(); - nfsd_drc_slab_free(); --out_free_stat: -- nfsd_stat_shutdown(); - out_free_pnfs: - nfsd4_exit_pnfs(); - out_free_slabs: -@@ -1628,7 +1627,6 @@ static void __exit exit_nfsd(void) - nfsd_drc_slab_free(); - remove_proc_entry("fs/nfs/exports", NULL); - remove_proc_entry("fs/nfs", NULL); -- nfsd_stat_shutdown(); - nfsd_lockd_shutdown(); - nfsd4_free_slabs(); - nfsd4_exit_pnfs(); -diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h -index fe846a360ae18d..d05bd2b811f377 100644 ---- a/fs/nfsd/nfsd.h -+++ b/fs/nfsd/nfsd.h -@@ -69,6 +69,7 @@ extern struct mutex nfsd_mutex; - extern spinlock_t nfsd_drc_lock; - extern unsigned long nfsd_drc_max_mem; - extern unsigned long nfsd_drc_mem_used; -+extern atomic_t nfsd_th_cnt; /* number of available threads */ - - extern const struct seq_operations nfs_exports_op; - -diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c -index 937be276bb6b48..c2495d98c18928 100644 ---- a/fs/nfsd/nfsfh.c -+++ b/fs/nfsd/nfsfh.c -@@ -327,6 +327,7 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) - __be32 - fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) - { -+ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); - struct svc_export *exp = NULL; - struct dentry *dentry; - __be32 error; -@@ -395,7 +396,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) - out: - trace_nfsd_fh_verify_err(rqstp, fhp, type, access, error); - if (error == nfserr_stale) -- nfsd_stats_fh_stale_inc(exp); -+ nfsd_stats_fh_stale_inc(nn, exp); - return error; - } - -diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c -index 7ef6af908faacb..7911c4b3b5d355 100644 ---- a/fs/nfsd/nfssvc.c -+++ b/fs/nfsd/nfssvc.c -@@ -34,6 +34,7 @@ - - #define NFSDDBG_FACILITY NFSDDBG_SVC - -+atomic_t nfsd_th_cnt = ATOMIC_INIT(0); - extern struct svc_program nfsd_program; - static int nfsd(void *vrqstp); - #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) -@@ -89,7 +90,6 @@ unsigned long nfsd_drc_max_mem; - unsigned long nfsd_drc_mem_used; - - #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) --static struct svc_stat nfsd_acl_svcstats; - static const struct svc_version *nfsd_acl_version[] = { - # if defined(CONFIG_NFSD_V2_ACL) - [2] = &nfsd_acl_version2, -@@ -108,15 +108,11 @@ static struct svc_program nfsd_acl_program = { - .pg_vers = nfsd_acl_version, - .pg_name = "nfsacl", - .pg_class = "nfsd", -- .pg_stats = &nfsd_acl_svcstats, - .pg_authenticate = &svc_set_client, - .pg_init_request = nfsd_acl_init_request, - .pg_rpcbind_set = nfsd_acl_rpcbind_set, - }; - --static struct svc_stat nfsd_acl_svcstats = { -- .program = &nfsd_acl_program, --}; - #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ - - static const struct svc_version *nfsd_version[] = { -@@ -141,7 +137,6 @@ struct svc_program nfsd_program = { - .pg_vers = nfsd_version, /* version table */ - .pg_name = "nfsd", /* program name */ - .pg_class = "nfsd", /* authentication class */ -- .pg_stats = &nfsd_svcstats, /* version table */ - .pg_authenticate = &svc_set_client, /* export authentication */ - .pg_init_request = nfsd_init_request, - .pg_rpcbind_set = nfsd_rpcbind_set, -@@ -675,7 +670,8 @@ int nfsd_create_serv(struct net *net) - if (nfsd_max_blksize == 0) - nfsd_max_blksize = nfsd_get_default_max_blksize(); - nfsd_reset_versions(nn); -- serv = svc_create_pooled(&nfsd_program, nfsd_max_blksize, nfsd); -+ serv = svc_create_pooled(&nfsd_program, &nn->nfsd_svcstats, -+ nfsd_max_blksize, nfsd); - if (serv == NULL) - return -ENOMEM; - -@@ -950,7 +946,7 @@ nfsd(void *vrqstp) - - current->fs->umask = 0; - -- atomic_inc(&nfsdstats.th_cnt); -+ atomic_inc(&nfsd_th_cnt); - - set_freezable(); - -@@ -964,7 +960,7 @@ nfsd(void *vrqstp) - svc_recv(rqstp); - } - -- atomic_dec(&nfsdstats.th_cnt); -+ atomic_dec(&nfsd_th_cnt); - - out: - /* Release the thread */ -diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c -index 63797635e1c328..9f606fa08bd4b8 100644 ---- a/fs/nfsd/stats.c -+++ b/fs/nfsd/stats.c -@@ -27,25 +27,22 @@ - - #include "nfsd.h" - --struct nfsd_stats nfsdstats; --struct svc_stat nfsd_svcstats = { -- .program = &nfsd_program, --}; -- - static int nfsd_show(struct seq_file *seq, void *v) - { -+ struct net *net = pde_data(file_inode(seq->file)); -+ struct nfsd_net *nn = net_generic(net, nfsd_net_id); - int i; - - seq_printf(seq, "rc %lld %lld %lld\nfh %lld 0 0 0 0\nio %lld %lld\n", -- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_HITS]), -- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_MISSES]), -- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE]), -- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_FH_STALE]), -- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_IO_READ]), -- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_IO_WRITE])); -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_HITS]), -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_MISSES]), -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_RC_NOCACHE]), -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_FH_STALE]), -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_IO_READ]), -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_IO_WRITE])); - - /* thread usage: */ -- seq_printf(seq, "th %u 0", atomic_read(&nfsdstats.th_cnt)); -+ seq_printf(seq, "th %u 0", atomic_read(&nfsd_th_cnt)); - - /* deprecated thread usage histogram stats */ - for (i = 0; i < 10; i++) -@@ -55,7 +52,7 @@ static int nfsd_show(struct seq_file *seq, void *v) - seq_puts(seq, "\nra 0 0 0 0 0 0 0 0 0 0 0 0\n"); - - /* show my rpc info */ -- svc_seq_show(seq, &nfsd_svcstats); -+ svc_seq_show(seq, &nn->nfsd_svcstats); - - #ifdef CONFIG_NFSD_V4 - /* Show count for individual nfsv4 operations */ -@@ -63,10 +60,10 @@ static int nfsd_show(struct seq_file *seq, void *v) - seq_printf(seq,"proc4ops %u", LAST_NFS4_OP + 1); - for (i = 0; i <= LAST_NFS4_OP; i++) { - seq_printf(seq, " %lld", -- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_NFS4_OP(i)])); -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_NFS4_OP(i)])); - } - seq_printf(seq, "\nwdeleg_getattr %lld", -- percpu_counter_sum_positive(&nfsdstats.counter[NFSD_STATS_WDELEG_GETATTR])); -+ percpu_counter_sum_positive(&nn->counter[NFSD_STATS_WDELEG_GETATTR])); - - seq_putc(seq, '\n'); - #endif -@@ -76,7 +73,7 @@ static int nfsd_show(struct seq_file *seq, void *v) - - DEFINE_PROC_SHOW_ATTRIBUTE(nfsd); - --int nfsd_percpu_counters_init(struct percpu_counter counters[], int num) -+int nfsd_percpu_counters_init(struct percpu_counter *counters, int num) - { - int i, err = 0; - -@@ -108,31 +105,24 @@ void nfsd_percpu_counters_destroy(struct percpu_counter counters[], int num) - percpu_counter_destroy(&counters[i]); - } - --static int nfsd_stat_counters_init(void) -+int nfsd_stat_counters_init(struct nfsd_net *nn) - { -- return nfsd_percpu_counters_init(nfsdstats.counter, NFSD_STATS_COUNTERS_NUM); -+ return nfsd_percpu_counters_init(nn->counter, NFSD_STATS_COUNTERS_NUM); - } - --static void nfsd_stat_counters_destroy(void) -+void nfsd_stat_counters_destroy(struct nfsd_net *nn) - { -- nfsd_percpu_counters_destroy(nfsdstats.counter, NFSD_STATS_COUNTERS_NUM); -+ nfsd_percpu_counters_destroy(nn->counter, NFSD_STATS_COUNTERS_NUM); - } - --int nfsd_stat_init(void) -+void nfsd_proc_stat_init(struct net *net) - { -- int err; -- -- err = nfsd_stat_counters_init(); -- if (err) -- return err; -+ struct nfsd_net *nn = net_generic(net, nfsd_net_id); - -- svc_proc_register(&init_net, &nfsd_svcstats, &nfsd_proc_ops); -- -- return 0; -+ svc_proc_register(net, &nn->nfsd_svcstats, &nfsd_proc_ops); - } - --void nfsd_stat_shutdown(void) -+void nfsd_proc_stat_shutdown(struct net *net) - { -- nfsd_stat_counters_destroy(); -- svc_proc_unregister(&init_net, "nfsd"); -+ svc_proc_unregister(net, "nfsd"); - } -diff --git a/fs/nfsd/stats.h b/fs/nfsd/stats.h -index cf5524e7ca0623..d2753e975dfd34 100644 ---- a/fs/nfsd/stats.h -+++ b/fs/nfsd/stats.h -@@ -10,94 +10,72 @@ - #include - #include - -- --enum { -- NFSD_STATS_RC_HITS, /* repcache hits */ -- NFSD_STATS_RC_MISSES, /* repcache misses */ -- NFSD_STATS_RC_NOCACHE, /* uncached reqs */ -- NFSD_STATS_FH_STALE, /* FH stale error */ -- NFSD_STATS_IO_READ, /* bytes returned to read requests */ -- NFSD_STATS_IO_WRITE, /* bytes passed in write requests */ --#ifdef CONFIG_NFSD_V4 -- NFSD_STATS_FIRST_NFS4_OP, /* count of individual nfsv4 operations */ -- NFSD_STATS_LAST_NFS4_OP = NFSD_STATS_FIRST_NFS4_OP + LAST_NFS4_OP, --#define NFSD_STATS_NFS4_OP(op) (NFSD_STATS_FIRST_NFS4_OP + (op)) -- NFSD_STATS_WDELEG_GETATTR, /* count of getattr conflict with wdeleg */ --#endif -- NFSD_STATS_COUNTERS_NUM --}; -- --struct nfsd_stats { -- struct percpu_counter counter[NFSD_STATS_COUNTERS_NUM]; -- -- atomic_t th_cnt; /* number of available threads */ --}; -- --extern struct nfsd_stats nfsdstats; -- --extern struct svc_stat nfsd_svcstats; -- --int nfsd_percpu_counters_init(struct percpu_counter counters[], int num); --void nfsd_percpu_counters_reset(struct percpu_counter counters[], int num); --void nfsd_percpu_counters_destroy(struct percpu_counter counters[], int num); --int nfsd_stat_init(void); --void nfsd_stat_shutdown(void); -- --static inline void nfsd_stats_rc_hits_inc(void) -+int nfsd_percpu_counters_init(struct percpu_counter *counters, int num); -+void nfsd_percpu_counters_reset(struct percpu_counter *counters, int num); -+void nfsd_percpu_counters_destroy(struct percpu_counter *counters, int num); -+int nfsd_stat_counters_init(struct nfsd_net *nn); -+void nfsd_stat_counters_destroy(struct nfsd_net *nn); -+void nfsd_proc_stat_init(struct net *net); -+void nfsd_proc_stat_shutdown(struct net *net); -+ -+static inline void nfsd_stats_rc_hits_inc(struct nfsd_net *nn) - { -- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_RC_HITS]); -+ percpu_counter_inc(&nn->counter[NFSD_STATS_RC_HITS]); - } - --static inline void nfsd_stats_rc_misses_inc(void) -+static inline void nfsd_stats_rc_misses_inc(struct nfsd_net *nn) - { -- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_RC_MISSES]); -+ percpu_counter_inc(&nn->counter[NFSD_STATS_RC_MISSES]); - } - --static inline void nfsd_stats_rc_nocache_inc(void) -+static inline void nfsd_stats_rc_nocache_inc(struct nfsd_net *nn) - { -- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_RC_NOCACHE]); -+ percpu_counter_inc(&nn->counter[NFSD_STATS_RC_NOCACHE]); - } - --static inline void nfsd_stats_fh_stale_inc(struct svc_export *exp) -+static inline void nfsd_stats_fh_stale_inc(struct nfsd_net *nn, -+ struct svc_export *exp) - { -- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_FH_STALE]); -- if (exp) -- percpu_counter_inc(&exp->ex_stats.counter[EXP_STATS_FH_STALE]); -+ percpu_counter_inc(&nn->counter[NFSD_STATS_FH_STALE]); -+ if (exp && exp->ex_stats) -+ percpu_counter_inc(&exp->ex_stats->counter[EXP_STATS_FH_STALE]); - } - --static inline void nfsd_stats_io_read_add(struct svc_export *exp, s64 amount) -+static inline void nfsd_stats_io_read_add(struct nfsd_net *nn, -+ struct svc_export *exp, s64 amount) - { -- percpu_counter_add(&nfsdstats.counter[NFSD_STATS_IO_READ], amount); -- if (exp) -- percpu_counter_add(&exp->ex_stats.counter[EXP_STATS_IO_READ], amount); -+ percpu_counter_add(&nn->counter[NFSD_STATS_IO_READ], amount); -+ if (exp && exp->ex_stats) -+ percpu_counter_add(&exp->ex_stats->counter[EXP_STATS_IO_READ], amount); - } - --static inline void nfsd_stats_io_write_add(struct svc_export *exp, s64 amount) -+static inline void nfsd_stats_io_write_add(struct nfsd_net *nn, -+ struct svc_export *exp, s64 amount) - { -- percpu_counter_add(&nfsdstats.counter[NFSD_STATS_IO_WRITE], amount); -- if (exp) -- percpu_counter_add(&exp->ex_stats.counter[EXP_STATS_IO_WRITE], amount); -+ percpu_counter_add(&nn->counter[NFSD_STATS_IO_WRITE], amount); -+ if (exp && exp->ex_stats) -+ percpu_counter_add(&exp->ex_stats->counter[EXP_STATS_IO_WRITE], amount); - } - - static inline void nfsd_stats_payload_misses_inc(struct nfsd_net *nn) - { -- percpu_counter_inc(&nn->counter[NFSD_NET_PAYLOAD_MISSES]); -+ percpu_counter_inc(&nn->counter[NFSD_STATS_PAYLOAD_MISSES]); - } - - static inline void nfsd_stats_drc_mem_usage_add(struct nfsd_net *nn, s64 amount) - { -- percpu_counter_add(&nn->counter[NFSD_NET_DRC_MEM_USAGE], amount); -+ percpu_counter_add(&nn->counter[NFSD_STATS_DRC_MEM_USAGE], amount); - } - - static inline void nfsd_stats_drc_mem_usage_sub(struct nfsd_net *nn, s64 amount) - { -- percpu_counter_sub(&nn->counter[NFSD_NET_DRC_MEM_USAGE], amount); -+ percpu_counter_sub(&nn->counter[NFSD_STATS_DRC_MEM_USAGE], amount); - } - - #ifdef CONFIG_NFSD_V4 --static inline void nfsd_stats_wdeleg_getattr_inc(void) -+static inline void nfsd_stats_wdeleg_getattr_inc(struct nfsd_net *nn) - { -- percpu_counter_inc(&nfsdstats.counter[NFSD_STATS_WDELEG_GETATTR]); -+ percpu_counter_inc(&nn->counter[NFSD_STATS_WDELEG_GETATTR]); - } - #endif - #endif /* _NFSD_STATS_H */ -diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c -index d0fdf70ab20d36..1f2a5b22b6498e 100644 ---- a/fs/nfsd/vfs.c -+++ b/fs/nfsd/vfs.c -@@ -985,7 +985,9 @@ static __be32 nfsd_finish_read(struct svc_rqst *rqstp, struct svc_fh *fhp, - unsigned long *count, u32 *eof, ssize_t host_err) - { - if (host_err >= 0) { -- nfsd_stats_io_read_add(fhp->fh_export, host_err); -+ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); -+ -+ nfsd_stats_io_read_add(nn, fhp->fh_export, host_err); - *eof = nfsd_eof_on_read(file, offset, host_err, *count); - *count = host_err; - fsnotify_access(file); -@@ -1168,7 +1170,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, - goto out_nfserr; - } - *cnt = host_err; -- nfsd_stats_io_write_add(exp, *cnt); -+ nfsd_stats_io_write_add(nn, exp, *cnt); - fsnotify_modify(file); - host_err = filemap_check_wb_err(file->f_mapping, since); - if (host_err < 0) -diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c -index 424865dfca74ba..45b687aff700be 100644 ---- a/fs/ntfs3/frecord.c -+++ b/fs/ntfs3/frecord.c -@@ -1896,6 +1896,47 @@ enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr, - return REPARSE_LINK; - } - -+/* -+ * fiemap_fill_next_extent_k - a copy of fiemap_fill_next_extent -+ * but it accepts kernel address for fi_extents_start -+ */ -+static int fiemap_fill_next_extent_k(struct fiemap_extent_info *fieinfo, -+ u64 logical, u64 phys, u64 len, u32 flags) -+{ -+ struct fiemap_extent extent; -+ struct fiemap_extent __user *dest = fieinfo->fi_extents_start; -+ -+ /* only count the extents */ -+ if (fieinfo->fi_extents_max == 0) { -+ fieinfo->fi_extents_mapped++; -+ return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0; -+ } -+ -+ if (fieinfo->fi_extents_mapped >= fieinfo->fi_extents_max) -+ return 1; -+ -+ if (flags & FIEMAP_EXTENT_DELALLOC) -+ flags |= FIEMAP_EXTENT_UNKNOWN; -+ if (flags & FIEMAP_EXTENT_DATA_ENCRYPTED) -+ flags |= FIEMAP_EXTENT_ENCODED; -+ if (flags & (FIEMAP_EXTENT_DATA_TAIL | FIEMAP_EXTENT_DATA_INLINE)) -+ flags |= FIEMAP_EXTENT_NOT_ALIGNED; -+ -+ memset(&extent, 0, sizeof(extent)); -+ extent.fe_logical = logical; -+ extent.fe_physical = phys; -+ extent.fe_length = len; -+ extent.fe_flags = flags; -+ -+ dest += fieinfo->fi_extents_mapped; -+ memcpy(dest, &extent, sizeof(extent)); -+ -+ fieinfo->fi_extents_mapped++; -+ if (fieinfo->fi_extents_mapped == fieinfo->fi_extents_max) -+ return 1; -+ return (flags & FIEMAP_EXTENT_LAST) ? 1 : 0; -+} -+ - /* - * ni_fiemap - Helper for file_fiemap(). - * -@@ -1906,6 +1947,8 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, - __u64 vbo, __u64 len) - { - int err = 0; -+ struct fiemap_extent __user *fe_u = fieinfo->fi_extents_start; -+ struct fiemap_extent *fe_k = NULL; - struct ntfs_sb_info *sbi = ni->mi.sbi; - u8 cluster_bits = sbi->cluster_bits; - struct runs_tree *run; -@@ -1953,6 +1996,18 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, - goto out; - } - -+ /* -+ * To avoid lock problems replace pointer to user memory by pointer to kernel memory. -+ */ -+ fe_k = kmalloc_array(fieinfo->fi_extents_max, -+ sizeof(struct fiemap_extent), -+ GFP_NOFS | __GFP_ZERO); -+ if (!fe_k) { -+ err = -ENOMEM; -+ goto out; -+ } -+ fieinfo->fi_extents_start = fe_k; -+ - end = vbo + len; - alloc_size = le64_to_cpu(attr->nres.alloc_size); - if (end > alloc_size) -@@ -2041,8 +2096,9 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, - if (vbo + dlen >= end) - flags |= FIEMAP_EXTENT_LAST; - -- err = fiemap_fill_next_extent(fieinfo, vbo, lbo, dlen, -- flags); -+ err = fiemap_fill_next_extent_k(fieinfo, vbo, lbo, dlen, -+ flags); -+ - if (err < 0) - break; - if (err == 1) { -@@ -2062,7 +2118,8 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, - if (vbo + bytes >= end) - flags |= FIEMAP_EXTENT_LAST; - -- err = fiemap_fill_next_extent(fieinfo, vbo, lbo, bytes, flags); -+ err = fiemap_fill_next_extent_k(fieinfo, vbo, lbo, bytes, -+ flags); - if (err < 0) - break; - if (err == 1) { -@@ -2075,7 +2132,19 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, - - up_read(run_lock); - -+ /* -+ * Copy to user memory out of lock -+ */ -+ if (copy_to_user(fe_u, fe_k, -+ fieinfo->fi_extents_max * -+ sizeof(struct fiemap_extent))) { -+ err = -EFAULT; -+ } -+ - out: -+ /* Restore original pointer. */ -+ fieinfo->fi_extents_start = fe_u; -+ kfree(fe_k); - return err; - } - -diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c -index 0f1493e0f6d059..254f6359b287fa 100644 ---- a/fs/quota/quota_tree.c -+++ b/fs/quota/quota_tree.c -@@ -21,6 +21,12 @@ MODULE_AUTHOR("Jan Kara"); - MODULE_DESCRIPTION("Quota trie support"); - MODULE_LICENSE("GPL"); - -+/* -+ * Maximum quota tree depth we support. Only to limit recursion when working -+ * with the tree. -+ */ -+#define MAX_QTREE_DEPTH 6 -+ - #define __QUOTA_QT_PARANOIA - - static int __get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth) -@@ -327,27 +333,36 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, - - /* Insert reference to structure into the trie */ - static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, -- uint *treeblk, int depth) -+ uint *blks, int depth) - { - char *buf = kmalloc(info->dqi_usable_bs, GFP_NOFS); - int ret = 0, newson = 0, newact = 0; - __le32 *ref; - uint newblk; -+ int i; - - if (!buf) - return -ENOMEM; -- if (!*treeblk) { -+ if (!blks[depth]) { - ret = get_free_dqblk(info); - if (ret < 0) - goto out_buf; -- *treeblk = ret; -+ for (i = 0; i < depth; i++) -+ if (ret == blks[i]) { -+ quota_error(dquot->dq_sb, -+ "Free block already used in tree: block %u", -+ ret); -+ ret = -EIO; -+ goto out_buf; -+ } -+ blks[depth] = ret; - memset(buf, 0, info->dqi_usable_bs); - newact = 1; - } else { -- ret = read_blk(info, *treeblk, buf); -+ ret = read_blk(info, blks[depth], buf); - if (ret < 0) { - quota_error(dquot->dq_sb, "Can't read tree quota " -- "block %u", *treeblk); -+ "block %u", blks[depth]); - goto out_buf; - } - } -@@ -357,8 +372,20 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, - info->dqi_blocks - 1); - if (ret) - goto out_buf; -- if (!newblk) -+ if (!newblk) { - newson = 1; -+ } else { -+ for (i = 0; i <= depth; i++) -+ if (newblk == blks[i]) { -+ quota_error(dquot->dq_sb, -+ "Cycle in quota tree detected: block %u index %u", -+ blks[depth], -+ get_index(info, dquot->dq_id, depth)); -+ ret = -EIO; -+ goto out_buf; -+ } -+ } -+ blks[depth + 1] = newblk; - if (depth == info->dqi_qtree_depth - 1) { - #ifdef __QUOTA_QT_PARANOIA - if (newblk) { -@@ -370,16 +397,16 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, - goto out_buf; - } - #endif -- newblk = find_free_dqentry(info, dquot, &ret); -+ blks[depth + 1] = find_free_dqentry(info, dquot, &ret); - } else { -- ret = do_insert_tree(info, dquot, &newblk, depth+1); -+ ret = do_insert_tree(info, dquot, blks, depth + 1); - } - if (newson && ret >= 0) { - ref[get_index(info, dquot->dq_id, depth)] = -- cpu_to_le32(newblk); -- ret = write_blk(info, *treeblk, buf); -+ cpu_to_le32(blks[depth + 1]); -+ ret = write_blk(info, blks[depth], buf); - } else if (newact && ret < 0) { -- put_free_dqblk(info, buf, *treeblk); -+ put_free_dqblk(info, buf, blks[depth]); - } - out_buf: - kfree(buf); -@@ -390,7 +417,7 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, - static inline int dq_insert_tree(struct qtree_mem_dqinfo *info, - struct dquot *dquot) - { -- int tmp = QT_TREEOFF; -+ uint blks[MAX_QTREE_DEPTH] = { QT_TREEOFF }; - - #ifdef __QUOTA_QT_PARANOIA - if (info->dqi_blocks <= QT_TREEOFF) { -@@ -398,7 +425,11 @@ static inline int dq_insert_tree(struct qtree_mem_dqinfo *info, - return -EIO; - } - #endif -- return do_insert_tree(info, dquot, &tmp, 0); -+ if (info->dqi_qtree_depth >= MAX_QTREE_DEPTH) { -+ quota_error(dquot->dq_sb, "Quota tree depth too big!"); -+ return -EIO; -+ } -+ return do_insert_tree(info, dquot, blks, 0); - } - - /* -@@ -511,19 +542,20 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, - - /* Remove reference to dquot from tree */ - static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, -- uint *blk, int depth) -+ uint *blks, int depth) - { - char *buf = kmalloc(info->dqi_usable_bs, GFP_NOFS); - int ret = 0; - uint newblk; - __le32 *ref = (__le32 *)buf; -+ int i; - - if (!buf) - return -ENOMEM; -- ret = read_blk(info, *blk, buf); -+ ret = read_blk(info, blks[depth], buf); - if (ret < 0) { - quota_error(dquot->dq_sb, "Can't read quota data block %u", -- *blk); -+ blks[depth]); - goto out_buf; - } - newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); -@@ -532,29 +564,38 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, - if (ret) - goto out_buf; - -+ for (i = 0; i <= depth; i++) -+ if (newblk == blks[i]) { -+ quota_error(dquot->dq_sb, -+ "Cycle in quota tree detected: block %u index %u", -+ blks[depth], -+ get_index(info, dquot->dq_id, depth)); -+ ret = -EIO; -+ goto out_buf; -+ } - if (depth == info->dqi_qtree_depth - 1) { - ret = free_dqentry(info, dquot, newblk); -- newblk = 0; -+ blks[depth + 1] = 0; - } else { -- ret = remove_tree(info, dquot, &newblk, depth+1); -+ blks[depth + 1] = newblk; -+ ret = remove_tree(info, dquot, blks, depth + 1); - } -- if (ret >= 0 && !newblk) { -- int i; -+ if (ret >= 0 && !blks[depth + 1]) { - ref[get_index(info, dquot->dq_id, depth)] = cpu_to_le32(0); - /* Block got empty? */ - for (i = 0; i < (info->dqi_usable_bs >> 2) && !ref[i]; i++) - ; - /* Don't put the root block into the free block list */ - if (i == (info->dqi_usable_bs >> 2) -- && *blk != QT_TREEOFF) { -- put_free_dqblk(info, buf, *blk); -- *blk = 0; -+ && blks[depth] != QT_TREEOFF) { -+ put_free_dqblk(info, buf, blks[depth]); -+ blks[depth] = 0; - } else { -- ret = write_blk(info, *blk, buf); -+ ret = write_blk(info, blks[depth], buf); - if (ret < 0) - quota_error(dquot->dq_sb, - "Can't write quota tree block %u", -- *blk); -+ blks[depth]); - } - } - out_buf: -@@ -565,11 +606,15 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, - /* Delete dquot from tree */ - int qtree_delete_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) - { -- uint tmp = QT_TREEOFF; -+ uint blks[MAX_QTREE_DEPTH] = { QT_TREEOFF }; - - if (!dquot->dq_off) /* Even not allocated? */ - return 0; -- return remove_tree(info, dquot, &tmp, 0); -+ if (info->dqi_qtree_depth >= MAX_QTREE_DEPTH) { -+ quota_error(dquot->dq_sb, "Quota tree depth too big!"); -+ return -EIO; -+ } -+ return remove_tree(info, dquot, blks, 0); - } - EXPORT_SYMBOL(qtree_delete_dquot); - -@@ -613,18 +658,20 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, - - /* Find entry for given id in the tree */ - static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info, -- struct dquot *dquot, uint blk, int depth) -+ struct dquot *dquot, uint *blks, int depth) - { - char *buf = kmalloc(info->dqi_usable_bs, GFP_NOFS); - loff_t ret = 0; - __le32 *ref = (__le32 *)buf; -+ uint blk; -+ int i; - - if (!buf) - return -ENOMEM; -- ret = read_blk(info, blk, buf); -+ ret = read_blk(info, blks[depth], buf); - if (ret < 0) { - quota_error(dquot->dq_sb, "Can't read quota tree block %u", -- blk); -+ blks[depth]); - goto out_buf; - } - ret = 0; -@@ -636,8 +683,19 @@ static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info, - if (ret) - goto out_buf; - -+ /* Check for cycles in the tree */ -+ for (i = 0; i <= depth; i++) -+ if (blk == blks[i]) { -+ quota_error(dquot->dq_sb, -+ "Cycle in quota tree detected: block %u index %u", -+ blks[depth], -+ get_index(info, dquot->dq_id, depth)); -+ ret = -EIO; -+ goto out_buf; -+ } -+ blks[depth + 1] = blk; - if (depth < info->dqi_qtree_depth - 1) -- ret = find_tree_dqentry(info, dquot, blk, depth+1); -+ ret = find_tree_dqentry(info, dquot, blks, depth + 1); - else - ret = find_block_dqentry(info, dquot, blk); - out_buf: -@@ -649,7 +707,13 @@ static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info, - static inline loff_t find_dqentry(struct qtree_mem_dqinfo *info, - struct dquot *dquot) - { -- return find_tree_dqentry(info, dquot, QT_TREEOFF, 0); -+ uint blks[MAX_QTREE_DEPTH] = { QT_TREEOFF }; -+ -+ if (info->dqi_qtree_depth >= MAX_QTREE_DEPTH) { -+ quota_error(dquot->dq_sb, "Quota tree depth too big!"); -+ return -EIO; -+ } -+ return find_tree_dqentry(info, dquot, blks, 0); - } - - int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) -diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c -index ae99e7b88205b2..7978ab671e0c6a 100644 ---- a/fs/quota/quota_v2.c -+++ b/fs/quota/quota_v2.c -@@ -166,14 +166,17 @@ static int v2_read_file_info(struct super_block *sb, int type) - i_size_read(sb_dqopt(sb)->files[type])); - goto out_free; - } -- if (qinfo->dqi_free_blk >= qinfo->dqi_blocks) { -- quota_error(sb, "Free block number too big (%u >= %u).", -- qinfo->dqi_free_blk, qinfo->dqi_blocks); -+ if (qinfo->dqi_free_blk && (qinfo->dqi_free_blk <= QT_TREEOFF || -+ qinfo->dqi_free_blk >= qinfo->dqi_blocks)) { -+ quota_error(sb, "Free block number %u out of range (%u, %u).", -+ qinfo->dqi_free_blk, QT_TREEOFF, qinfo->dqi_blocks); - goto out_free; - } -- if (qinfo->dqi_free_entry >= qinfo->dqi_blocks) { -- quota_error(sb, "Block with free entry too big (%u >= %u).", -- qinfo->dqi_free_entry, qinfo->dqi_blocks); -+ if (qinfo->dqi_free_entry && (qinfo->dqi_free_entry <= QT_TREEOFF || -+ qinfo->dqi_free_entry >= qinfo->dqi_blocks)) { -+ quota_error(sb, "Block with free entry %u out of range (%u, %u).", -+ qinfo->dqi_free_entry, QT_TREEOFF, -+ qinfo->dqi_blocks); - goto out_free; - } - ret = 0; -diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c -index 3676e02a0232a4..4ab8cab6ea6147 100644 ---- a/fs/reiserfs/stree.c -+++ b/fs/reiserfs/stree.c -@@ -1407,7 +1407,7 @@ void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th, - INITIALIZE_PATH(path); - int item_len = 0; - int tb_init = 0; -- struct cpu_key cpu_key; -+ struct cpu_key cpu_key = {}; - int retval; - int quota_cut_bytes = 0; - -diff --git a/fs/romfs/super.c b/fs/romfs/super.c -index 5c35f6c760377e..b1bdfbc211c3c0 100644 ---- a/fs/romfs/super.c -+++ b/fs/romfs/super.c -@@ -593,7 +593,7 @@ static void romfs_kill_sb(struct super_block *sb) - #ifdef CONFIG_ROMFS_ON_BLOCK - if (sb->s_bdev) { - sync_blockdev(sb->s_bdev); -- blkdev_put(sb->s_bdev, sb); -+ bdev_release(sb->s_bdev_handle); - } - #endif - } -diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c -index 581ce951933901..2dc730800f448d 100644 ---- a/fs/squashfs/block.c -+++ b/fs/squashfs/block.c -@@ -321,7 +321,7 @@ int squashfs_read_data(struct super_block *sb, u64 index, int length, - TRACE("Block @ 0x%llx, %scompressed size %d\n", index - 2, - compressed ? "" : "un", length); - } -- if (length < 0 || length > output->length || -+ if (length <= 0 || length > output->length || - (index + length) > msblk->bytes_used) { - res = -EIO; - goto out; -diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c -index 8ba8c4c5077078..e8df6430444b01 100644 ---- a/fs/squashfs/file.c -+++ b/fs/squashfs/file.c -@@ -544,7 +544,8 @@ static void squashfs_readahead(struct readahead_control *ractl) - struct squashfs_page_actor *actor; - unsigned int nr_pages = 0; - struct page **pages; -- int i, file_end = i_size_read(inode) >> msblk->block_log; -+ int i; -+ loff_t file_end = i_size_read(inode) >> msblk->block_log; - unsigned int max_pages = 1UL << shift; - - readahead_expand(ractl, start, (len | mask) + 1); -diff --git a/fs/squashfs/file_direct.c b/fs/squashfs/file_direct.c -index f1ccad519e28cc..763a3f7a75f6dd 100644 ---- a/fs/squashfs/file_direct.c -+++ b/fs/squashfs/file_direct.c -@@ -26,10 +26,10 @@ int squashfs_readpage_block(struct page *target_page, u64 block, int bsize, - struct inode *inode = target_page->mapping->host; - struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; - -- int file_end = (i_size_read(inode) - 1) >> PAGE_SHIFT; -+ loff_t file_end = (i_size_read(inode) - 1) >> PAGE_SHIFT; - int mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1; -- int start_index = target_page->index & ~mask; -- int end_index = start_index | mask; -+ loff_t start_index = target_page->index & ~mask; -+ loff_t end_index = start_index | mask; - int i, n, pages, bytes, res = -ENOMEM; - struct page **page; - struct squashfs_page_actor *actor; -diff --git a/fs/super.c b/fs/super.c -index 576abb1ff0403d..b142e71eb8dfdd 100644 ---- a/fs/super.c -+++ b/fs/super.c -@@ -1490,14 +1490,16 @@ int setup_bdev_super(struct super_block *sb, int sb_flags, - struct fs_context *fc) - { - blk_mode_t mode = sb_open_mode(sb_flags); -+ struct bdev_handle *bdev_handle; - struct block_device *bdev; - -- bdev = blkdev_get_by_dev(sb->s_dev, mode, sb, &fs_holder_ops); -- if (IS_ERR(bdev)) { -+ bdev_handle = bdev_open_by_dev(sb->s_dev, mode, sb, &fs_holder_ops); -+ if (IS_ERR(bdev_handle)) { - if (fc) - errorf(fc, "%s: Can't open blockdev", fc->source); -- return PTR_ERR(bdev); -+ return PTR_ERR(bdev_handle); - } -+ bdev = bdev_handle->bdev; - - /* - * This really should be in blkdev_get_by_dev, but right now can't due -@@ -1505,7 +1507,7 @@ int setup_bdev_super(struct super_block *sb, int sb_flags, - * writable from userspace even for a read-only block device. - */ - if ((mode & BLK_OPEN_WRITE) && bdev_read_only(bdev)) { -- blkdev_put(bdev, sb); -+ bdev_release(bdev_handle); - return -EACCES; - } - -@@ -1521,10 +1523,11 @@ int setup_bdev_super(struct super_block *sb, int sb_flags, - mutex_unlock(&bdev->bd_fsfreeze_mutex); - if (fc) - warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev); -- blkdev_put(bdev, sb); -+ bdev_release(bdev_handle); - return -EBUSY; - } - spin_lock(&sb_lock); -+ sb->s_bdev_handle = bdev_handle; - sb->s_bdev = bdev; - sb->s_bdi = bdi_get(bdev->bd_disk->bdi); - if (bdev_stable_writes(bdev)) -@@ -1657,7 +1660,7 @@ void kill_block_super(struct super_block *sb) - generic_shutdown_super(sb); - if (bdev) { - sync_blockdev(bdev); -- blkdev_put(bdev, sb); -+ bdev_release(sb->s_bdev_handle); - } - } - -diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h -index 265da00a1a8b1b..6eefe5153a6ff7 100644 ---- a/include/linux/cgroup-defs.h -+++ b/include/linux/cgroup-defs.h -@@ -543,6 +543,10 @@ struct cgroup_root { - /* Unique id for this hierarchy. */ - int hierarchy_id; - -+ /* A list running through the active hierarchies */ -+ struct list_head root_list; -+ struct rcu_head rcu; /* Must be near the top */ -+ - /* - * The root cgroup. The containing cgroup_root will be destroyed on its - * release. cgrp->ancestors[0] will be used overflowing into the -@@ -556,9 +560,6 @@ struct cgroup_root { - /* Number of cgroups in the hierarchy, used only for /proc/cgroups */ - atomic_t nr_cgrps; - -- /* A list running through the active hierarchies */ -- struct list_head root_list; -- - /* Hierarchy-specific flags */ - unsigned int flags; - -diff --git a/include/linux/fs.h b/include/linux/fs.h -index 56dce38c478627..43e640fb4a7f77 100644 ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1036,7 +1036,7 @@ struct file_handle { - __u32 handle_bytes; - int handle_type; - /* file identifier */ -- unsigned char f_handle[]; -+ unsigned char f_handle[] __counted_by(handle_bytes); - }; - - static inline struct file *get_file(struct file *f) -@@ -1223,6 +1223,7 @@ struct super_block { - struct hlist_bl_head s_roots; /* alternate root dentries for NFS */ - struct list_head s_mounts; /* list of mounts; _not_ for fs use */ - struct block_device *s_bdev; -+ struct bdev_handle *s_bdev_handle; - struct backing_dev_info *s_bdi; - struct mtd_info *s_mtd; - struct hlist_node s_instances; -diff --git a/include/linux/sockptr.h b/include/linux/sockptr.h -index bae5e2369b4f7a..1c1a5d926b1713 100644 ---- a/include/linux/sockptr.h -+++ b/include/linux/sockptr.h -@@ -50,11 +50,36 @@ static inline int copy_from_sockptr_offset(void *dst, sockptr_t src, - return 0; - } - -+/* Deprecated. -+ * This is unsafe, unless caller checked user provided optlen. -+ * Prefer copy_safe_from_sockptr() instead. -+ */ - static inline int copy_from_sockptr(void *dst, sockptr_t src, size_t size) - { - return copy_from_sockptr_offset(dst, src, 0, size); - } - -+/** -+ * copy_safe_from_sockptr: copy a struct from sockptr -+ * @dst: Destination address, in kernel space. This buffer must be @ksize -+ * bytes long. -+ * @ksize: Size of @dst struct. -+ * @optval: Source address. (in user or kernel space) -+ * @optlen: Size of @optval data. -+ * -+ * Returns: -+ * * -EINVAL: @optlen < @ksize -+ * * -EFAULT: access to userspace failed. -+ * * 0 : @ksize bytes were copied -+ */ -+static inline int copy_safe_from_sockptr(void *dst, size_t ksize, -+ sockptr_t optval, unsigned int optlen) -+{ -+ if (optlen < ksize) -+ return -EINVAL; -+ return copy_from_sockptr(dst, optval, ksize); -+} -+ - static inline int copy_to_sockptr_offset(sockptr_t dst, size_t offset, - const void *src, size_t size) - { -diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h -index dbf5b21feafe48..3d8b215f32d5b0 100644 ---- a/include/linux/sunrpc/svc.h -+++ b/include/linux/sunrpc/svc.h -@@ -336,7 +336,6 @@ struct svc_program { - const struct svc_version **pg_vers; /* version array */ - char * pg_name; /* service name */ - char * pg_class; /* class name: services sharing authentication */ -- struct svc_stat * pg_stats; /* rpc statistics */ - enum svc_auth_status (*pg_authenticate)(struct svc_rqst *rqstp); - __be32 (*pg_init_request)(struct svc_rqst *, - const struct svc_program *, -@@ -408,7 +407,9 @@ bool svc_rqst_replace_page(struct svc_rqst *rqstp, - void svc_rqst_release_pages(struct svc_rqst *rqstp); - void svc_rqst_free(struct svc_rqst *); - void svc_exit_thread(struct svc_rqst *); --struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int, -+struct svc_serv * svc_create_pooled(struct svc_program *prog, -+ struct svc_stat *stats, -+ unsigned int bufsize, - int (*threadfn)(void *data)); - int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int); - int svc_pool_stats_open(struct svc_serv *serv, struct file *file); -diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h -index fb09fd1767f289..ba6e346c8d669a 100644 ---- a/include/uapi/linux/bpf.h -+++ b/include/uapi/linux/bpf.h -@@ -77,12 +77,29 @@ struct bpf_insn { - __s32 imm; /* signed immediate constant */ - }; - --/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */ -+/* Deprecated: use struct bpf_lpm_trie_key_u8 (when the "data" member is needed for -+ * byte access) or struct bpf_lpm_trie_key_hdr (when using an alternative type for -+ * the trailing flexible array member) instead. -+ */ - struct bpf_lpm_trie_key { - __u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */ - __u8 data[0]; /* Arbitrary size */ - }; - -+/* Header for bpf_lpm_trie_key structs */ -+struct bpf_lpm_trie_key_hdr { -+ __u32 prefixlen; -+}; -+ -+/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry, with trailing byte array. */ -+struct bpf_lpm_trie_key_u8 { -+ union { -+ struct bpf_lpm_trie_key_hdr hdr; -+ __u32 prefixlen; -+ }; -+ __u8 data[]; /* Arbitrary size */ -+}; -+ - struct bpf_cgroup_storage_key { - __u64 cgroup_inode_id; /* cgroup inode id */ - __u32 attach_type; /* program attach type (enum bpf_attach_type) */ -diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c -index b32be680da6cdc..d0febf07051edf 100644 ---- a/kernel/bpf/lpm_trie.c -+++ b/kernel/bpf/lpm_trie.c -@@ -164,13 +164,13 @@ static inline int extract_bit(const u8 *data, size_t index) - */ - static size_t longest_prefix_match(const struct lpm_trie *trie, - const struct lpm_trie_node *node, -- const struct bpf_lpm_trie_key *key) -+ const struct bpf_lpm_trie_key_u8 *key) - { - u32 limit = min(node->prefixlen, key->prefixlen); - u32 prefixlen = 0, i = 0; - - BUILD_BUG_ON(offsetof(struct lpm_trie_node, data) % sizeof(u32)); -- BUILD_BUG_ON(offsetof(struct bpf_lpm_trie_key, data) % sizeof(u32)); -+ BUILD_BUG_ON(offsetof(struct bpf_lpm_trie_key_u8, data) % sizeof(u32)); - - #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && defined(CONFIG_64BIT) - -@@ -229,7 +229,7 @@ static void *trie_lookup_elem(struct bpf_map *map, void *_key) - { - struct lpm_trie *trie = container_of(map, struct lpm_trie, map); - struct lpm_trie_node *node, *found = NULL; -- struct bpf_lpm_trie_key *key = _key; -+ struct bpf_lpm_trie_key_u8 *key = _key; - - if (key->prefixlen > trie->max_prefixlen) - return NULL; -@@ -308,8 +308,9 @@ static long trie_update_elem(struct bpf_map *map, - { - struct lpm_trie *trie = container_of(map, struct lpm_trie, map); - struct lpm_trie_node *node, *im_node = NULL, *new_node = NULL; -+ struct lpm_trie_node *free_node = NULL; - struct lpm_trie_node __rcu **slot; -- struct bpf_lpm_trie_key *key = _key; -+ struct bpf_lpm_trie_key_u8 *key = _key; - unsigned long irq_flags; - unsigned int next_bit; - size_t matchlen = 0; -@@ -382,7 +383,7 @@ static long trie_update_elem(struct bpf_map *map, - trie->n_entries--; - - rcu_assign_pointer(*slot, new_node); -- kfree_rcu(node, rcu); -+ free_node = node; - - goto out; - } -@@ -429,6 +430,7 @@ static long trie_update_elem(struct bpf_map *map, - } - - spin_unlock_irqrestore(&trie->lock, irq_flags); -+ kfree_rcu(free_node, rcu); - - return ret; - } -@@ -437,7 +439,8 @@ static long trie_update_elem(struct bpf_map *map, - static long trie_delete_elem(struct bpf_map *map, void *_key) - { - struct lpm_trie *trie = container_of(map, struct lpm_trie, map); -- struct bpf_lpm_trie_key *key = _key; -+ struct lpm_trie_node *free_node = NULL, *free_parent = NULL; -+ struct bpf_lpm_trie_key_u8 *key = _key; - struct lpm_trie_node __rcu **trim, **trim2; - struct lpm_trie_node *node, *parent; - unsigned long irq_flags; -@@ -506,8 +509,8 @@ static long trie_delete_elem(struct bpf_map *map, void *_key) - else - rcu_assign_pointer( - *trim2, rcu_access_pointer(parent->child[0])); -- kfree_rcu(parent, rcu); -- kfree_rcu(node, rcu); -+ free_parent = parent; -+ free_node = node; - goto out; - } - -@@ -521,10 +524,12 @@ static long trie_delete_elem(struct bpf_map *map, void *_key) - rcu_assign_pointer(*trim, rcu_access_pointer(node->child[1])); - else - RCU_INIT_POINTER(*trim, NULL); -- kfree_rcu(node, rcu); -+ free_node = node; - - out: - spin_unlock_irqrestore(&trie->lock, irq_flags); -+ kfree_rcu(free_parent, rcu); -+ kfree_rcu(free_node, rcu); - - return ret; - } -@@ -536,7 +541,7 @@ static long trie_delete_elem(struct bpf_map *map, void *_key) - sizeof(struct lpm_trie_node)) - #define LPM_VAL_SIZE_MIN 1 - --#define LPM_KEY_SIZE(X) (sizeof(struct bpf_lpm_trie_key) + (X)) -+#define LPM_KEY_SIZE(X) (sizeof(struct bpf_lpm_trie_key_u8) + (X)) - #define LPM_KEY_SIZE_MAX LPM_KEY_SIZE(LPM_DATA_SIZE_MAX) - #define LPM_KEY_SIZE_MIN LPM_KEY_SIZE(LPM_DATA_SIZE_MIN) - -@@ -565,7 +570,7 @@ static struct bpf_map *trie_alloc(union bpf_attr *attr) - /* copy mandatory map attributes */ - bpf_map_init_from_attr(&trie->map, attr); - trie->data_size = attr->key_size - -- offsetof(struct bpf_lpm_trie_key, data); -+ offsetof(struct bpf_lpm_trie_key_u8, data); - trie->max_prefixlen = trie->data_size * 8; - - spin_lock_init(&trie->lock); -@@ -616,7 +621,7 @@ static int trie_get_next_key(struct bpf_map *map, void *_key, void *_next_key) - { - struct lpm_trie_node *node, *next_node = NULL, *parent, *search_root; - struct lpm_trie *trie = container_of(map, struct lpm_trie, map); -- struct bpf_lpm_trie_key *key = _key, *next_key = _next_key; -+ struct bpf_lpm_trie_key_u8 *key = _key, *next_key = _next_key; - struct lpm_trie_node **node_stack = NULL; - int err = 0, stack_ptr = -1; - unsigned int next_bit; -@@ -703,7 +708,7 @@ static int trie_get_next_key(struct bpf_map *map, void *_key, void *_next_key) - } - do_copy: - next_key->prefixlen = next_node->prefixlen; -- memcpy((void *)next_key + offsetof(struct bpf_lpm_trie_key, data), -+ memcpy((void *)next_key + offsetof(struct bpf_lpm_trie_key_u8, data), - next_node->data, trie->data_size); - free_stack: - kfree(node_stack); -@@ -715,7 +720,7 @@ static int trie_check_btf(const struct bpf_map *map, - const struct btf_type *key_type, - const struct btf_type *value_type) - { -- /* Keys must have struct bpf_lpm_trie_key embedded. */ -+ /* Keys must have struct bpf_lpm_trie_key_u8 embedded. */ - return BTF_INFO_KIND(key_type->info) != BTF_KIND_STRUCT ? - -EINVAL : 0; - } -diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h -index c56071f150f2ae..5e17f01ced9fd2 100644 ---- a/kernel/cgroup/cgroup-internal.h -+++ b/kernel/cgroup/cgroup-internal.h -@@ -170,7 +170,8 @@ extern struct list_head cgroup_roots; - - /* iterate across the hierarchies */ - #define for_each_root(root) \ -- list_for_each_entry((root), &cgroup_roots, root_list) -+ list_for_each_entry_rcu((root), &cgroup_roots, root_list, \ -+ lockdep_is_held(&cgroup_mutex)) - - /** - * for_each_subsys - iterate all enabled cgroup subsystems -diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c -index 094f513319259d..d872fff901073f 100644 ---- a/kernel/cgroup/cgroup.c -+++ b/kernel/cgroup/cgroup.c -@@ -1313,7 +1313,7 @@ static void cgroup_exit_root_id(struct cgroup_root *root) - - void cgroup_free_root(struct cgroup_root *root) - { -- kfree(root); -+ kfree_rcu(root, rcu); - } - - static void cgroup_destroy_root(struct cgroup_root *root) -@@ -1346,7 +1346,7 @@ static void cgroup_destroy_root(struct cgroup_root *root) - spin_unlock_irq(&css_set_lock); - - if (!list_empty(&root->root_list)) { -- list_del(&root->root_list); -+ list_del_rcu(&root->root_list); - cgroup_root_count--; - } - -@@ -1386,7 +1386,15 @@ static inline struct cgroup *__cset_cgroup_from_root(struct css_set *cset, - } - } - -- BUG_ON(!res_cgroup); -+ /* -+ * If cgroup_mutex is not held, the cgrp_cset_link will be freed -+ * before we remove the cgroup root from the root_list. Consequently, -+ * when accessing a cgroup root, the cset_link may have already been -+ * freed, resulting in a NULL res_cgroup. However, by holding the -+ * cgroup_mutex, we ensure that res_cgroup can't be NULL. -+ * If we don't hold cgroup_mutex in the caller, we must do the NULL -+ * check. -+ */ - return res_cgroup; - } - -@@ -1445,7 +1453,6 @@ static struct cgroup *current_cgns_cgroup_dfl(void) - static struct cgroup *cset_cgroup_from_root(struct css_set *cset, - struct cgroup_root *root) - { -- lockdep_assert_held(&cgroup_mutex); - lockdep_assert_held(&css_set_lock); - - return __cset_cgroup_from_root(cset, root); -@@ -1453,7 +1460,9 @@ static struct cgroup *cset_cgroup_from_root(struct css_set *cset, - - /* - * Return the cgroup for "task" from the given hierarchy. Must be -- * called with cgroup_mutex and css_set_lock held. -+ * called with css_set_lock held to prevent task's groups from being modified. -+ * Must be called with either cgroup_mutex or rcu read lock to prevent the -+ * cgroup root from being destroyed. - */ - struct cgroup *task_cgroup_from_root(struct task_struct *task, - struct cgroup_root *root) -@@ -2014,7 +2023,7 @@ void init_cgroup_root(struct cgroup_fs_context *ctx) - struct cgroup_root *root = ctx->root; - struct cgroup *cgrp = &root->cgrp; - -- INIT_LIST_HEAD(&root->root_list); -+ INIT_LIST_HEAD_RCU(&root->root_list); - atomic_set(&root->nr_cgrps, 1); - cgrp->root = root; - init_cgroup_housekeeping(cgrp); -@@ -2097,7 +2106,7 @@ int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask) - * care of subsystems' refcounts, which are explicitly dropped in - * the failure exit path. - */ -- list_add(&root->root_list, &cgroup_roots); -+ list_add_rcu(&root->root_list, &cgroup_roots); - cgroup_root_count++; - - /* -diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c -index 5ecd072a34fe72..eb86283901565b 100644 ---- a/kernel/irq/cpuhotplug.c -+++ b/kernel/irq/cpuhotplug.c -@@ -130,6 +130,22 @@ static bool migrate_one_irq(struct irq_desc *desc) - * CPU. - */ - err = irq_do_set_affinity(d, affinity, false); -+ -+ /* -+ * If there are online CPUs in the affinity mask, but they have no -+ * vectors left to make the migration work, try to break the -+ * affinity by migrating to any online CPU. -+ */ -+ if (err == -ENOSPC && !irqd_affinity_is_managed(d) && affinity != cpu_online_mask) { -+ pr_debug("IRQ%u: set affinity failed for %*pbl, re-try with online CPUs\n", -+ d->irq, cpumask_pr_args(affinity)); -+ -+ affinity = cpu_online_mask; -+ brokeaff = true; -+ -+ err = irq_do_set_affinity(d, affinity, false); -+ } -+ - if (err) { - pr_warn_ratelimited("IRQ%u: set affinity failed(%d).\n", - d->irq, err); -@@ -195,10 +211,15 @@ static void irq_restore_affinity_of_irq(struct irq_desc *desc, unsigned int cpu) - !irq_data_get_irq_chip(data) || !cpumask_test_cpu(cpu, affinity)) - return; - -- if (irqd_is_managed_and_shutdown(data)) { -- irq_startup(desc, IRQ_RESEND, IRQ_START_COND); -+ /* -+ * Don't restore suspended interrupts here when a system comes back -+ * from S3. They are reenabled via resume_device_irqs(). -+ */ -+ if (desc->istate & IRQS_SUSPENDED) - return; -- } -+ -+ if (irqd_is_managed_and_shutdown(data)) -+ irq_startup(desc, IRQ_RESEND, IRQ_START_COND); - - /* - * If the interrupt can only be directed to a single target -diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c -index a054cd5ec08bce..8a936c1ffad390 100644 ---- a/kernel/irq/manage.c -+++ b/kernel/irq/manage.c -@@ -796,10 +796,14 @@ void __enable_irq(struct irq_desc *desc) - irq_settings_set_noprobe(desc); - /* - * Call irq_startup() not irq_enable() here because the -- * interrupt might be marked NOAUTOEN. So irq_startup() -- * needs to be invoked when it gets enabled the first -- * time. If it was already started up, then irq_startup() -- * will invoke irq_enable() under the hood. -+ * interrupt might be marked NOAUTOEN so irq_startup() -+ * needs to be invoked when it gets enabled the first time. -+ * This is also required when __enable_irq() is invoked for -+ * a managed and shutdown interrupt from the S3 resume -+ * path. -+ * -+ * If it was already started up, then irq_startup() will -+ * invoke irq_enable() under the hood. - */ - irq_startup(desc, IRQ_RESEND, IRQ_START_FORCE); - break; -diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c -index 13f0d11927074a..68af76ca8bc992 100644 ---- a/mm/debug_vm_pgtable.c -+++ b/mm/debug_vm_pgtable.c -@@ -39,22 +39,7 @@ - * Please refer Documentation/mm/arch_pgtable_helpers.rst for the semantics - * expectations that are being validated here. All future changes in here - * or the documentation need to be in sync. -- * -- * On s390 platform, the lower 4 bits are used to identify given page table -- * entry type. But these bits might affect the ability to clear entries with -- * pxx_clear() because of how dynamic page table folding works on s390. So -- * while loading up the entries do not change the lower 4 bits. It does not -- * have affect any other platform. Also avoid the 62nd bit on ppc64 that is -- * used to mark a pte entry. - */ --#define S390_SKIP_MASK GENMASK(3, 0) --#if __BITS_PER_LONG == 64 --#define PPC64_SKIP_MASK GENMASK(62, 62) --#else --#define PPC64_SKIP_MASK 0x0 --#endif --#define ARCH_SKIP_MASK (S390_SKIP_MASK | PPC64_SKIP_MASK) --#define RANDOM_ORVALUE (GENMASK(BITS_PER_LONG - 1, 0) & ~ARCH_SKIP_MASK) - #define RANDOM_NZVALUE GENMASK(7, 0) - - struct pgtable_debug_args { -@@ -510,8 +495,7 @@ static void __init pud_clear_tests(struct pgtable_debug_args *args) - return; - - pr_debug("Validating PUD clear\n"); -- pud = __pud(pud_val(pud) | RANDOM_ORVALUE); -- WRITE_ONCE(*args->pudp, pud); -+ WARN_ON(pud_none(pud)); - pud_clear(args->pudp); - pud = READ_ONCE(*args->pudp); - WARN_ON(!pud_none(pud)); -@@ -547,8 +531,7 @@ static void __init p4d_clear_tests(struct pgtable_debug_args *args) - return; - - pr_debug("Validating P4D clear\n"); -- p4d = __p4d(p4d_val(p4d) | RANDOM_ORVALUE); -- WRITE_ONCE(*args->p4dp, p4d); -+ WARN_ON(p4d_none(p4d)); - p4d_clear(args->p4dp); - p4d = READ_ONCE(*args->p4dp); - WARN_ON(!p4d_none(p4d)); -@@ -581,8 +564,7 @@ static void __init pgd_clear_tests(struct pgtable_debug_args *args) - return; - - pr_debug("Validating PGD clear\n"); -- pgd = __pgd(pgd_val(pgd) | RANDOM_ORVALUE); -- WRITE_ONCE(*args->pgdp, pgd); -+ WARN_ON(pgd_none(pgd)); - pgd_clear(args->pgdp); - pgd = READ_ONCE(*args->pgdp); - WARN_ON(!pgd_none(pgd)); -@@ -633,10 +615,8 @@ static void __init pte_clear_tests(struct pgtable_debug_args *args) - if (WARN_ON(!args->ptep)) - return; - --#ifndef CONFIG_RISCV -- pte = __pte(pte_val(pte) | RANDOM_ORVALUE); --#endif - set_pte_at(args->mm, args->vaddr, args->ptep, pte); -+ WARN_ON(pte_none(pte)); - flush_dcache_page(page); - barrier(); - ptep_clear(args->mm, args->vaddr, args->ptep); -@@ -649,8 +629,7 @@ static void __init pmd_clear_tests(struct pgtable_debug_args *args) - pmd_t pmd = READ_ONCE(*args->pmdp); - - pr_debug("Validating PMD clear\n"); -- pmd = __pmd(pmd_val(pmd) | RANDOM_ORVALUE); -- WRITE_ONCE(*args->pmdp, pmd); -+ WARN_ON(pmd_none(pmd)); - pmd_clear(args->pmdp); - pmd = READ_ONCE(*args->pmdp); - WARN_ON(!pmd_none(pmd)); -diff --git a/mm/gup.c b/mm/gup.c -index f50fe2219a13b6..fdd75384160d8d 100644 ---- a/mm/gup.c -+++ b/mm/gup.c -@@ -97,95 +97,6 @@ static inline struct folio *try_get_folio(struct page *page, int refs) - return folio; - } - --/** -- * try_grab_folio() - Attempt to get or pin a folio. -- * @page: pointer to page to be grabbed -- * @refs: the value to (effectively) add to the folio's refcount -- * @flags: gup flags: these are the FOLL_* flag values. -- * -- * "grab" names in this file mean, "look at flags to decide whether to use -- * FOLL_PIN or FOLL_GET behavior, when incrementing the folio's refcount. -- * -- * Either FOLL_PIN or FOLL_GET (or neither) must be set, but not both at the -- * same time. (That's true throughout the get_user_pages*() and -- * pin_user_pages*() APIs.) Cases: -- * -- * FOLL_GET: folio's refcount will be incremented by @refs. -- * -- * FOLL_PIN on large folios: folio's refcount will be incremented by -- * @refs, and its pincount will be incremented by @refs. -- * -- * FOLL_PIN on single-page folios: folio's refcount will be incremented by -- * @refs * GUP_PIN_COUNTING_BIAS. -- * -- * Return: The folio containing @page (with refcount appropriately -- * incremented) for success, or NULL upon failure. If neither FOLL_GET -- * nor FOLL_PIN was set, that's considered failure, and furthermore, -- * a likely bug in the caller, so a warning is also emitted. -- */ --struct folio *try_grab_folio(struct page *page, int refs, unsigned int flags) --{ -- struct folio *folio; -- -- if (WARN_ON_ONCE((flags & (FOLL_GET | FOLL_PIN)) == 0)) -- return NULL; -- -- if (unlikely(!(flags & FOLL_PCI_P2PDMA) && is_pci_p2pdma_page(page))) -- return NULL; -- -- if (flags & FOLL_GET) -- return try_get_folio(page, refs); -- -- /* FOLL_PIN is set */ -- -- /* -- * Don't take a pin on the zero page - it's not going anywhere -- * and it is used in a *lot* of places. -- */ -- if (is_zero_page(page)) -- return page_folio(page); -- -- folio = try_get_folio(page, refs); -- if (!folio) -- return NULL; -- -- /* -- * Can't do FOLL_LONGTERM + FOLL_PIN gup fast path if not in a -- * right zone, so fail and let the caller fall back to the slow -- * path. -- */ -- if (unlikely((flags & FOLL_LONGTERM) && -- !folio_is_longterm_pinnable(folio))) { -- if (!put_devmap_managed_page_refs(&folio->page, refs)) -- folio_put_refs(folio, refs); -- return NULL; -- } -- -- /* -- * When pinning a large folio, use an exact count to track it. -- * -- * However, be sure to *also* increment the normal folio -- * refcount field at least once, so that the folio really -- * is pinned. That's why the refcount from the earlier -- * try_get_folio() is left intact. -- */ -- if (folio_test_large(folio)) -- atomic_add(refs, &folio->_pincount); -- else -- folio_ref_add(folio, -- refs * (GUP_PIN_COUNTING_BIAS - 1)); -- /* -- * Adjust the pincount before re-checking the PTE for changes. -- * This is essentially a smp_mb() and is paired with a memory -- * barrier in page_try_share_anon_rmap(). -- */ -- smp_mb__after_atomic(); -- -- node_stat_mod_folio(folio, NR_FOLL_PIN_ACQUIRED, refs); -- -- return folio; --} -- - static void gup_put_folio(struct folio *folio, int refs, unsigned int flags) - { - if (flags & FOLL_PIN) { -@@ -203,58 +114,59 @@ static void gup_put_folio(struct folio *folio, int refs, unsigned int flags) - } - - /** -- * try_grab_page() - elevate a page's refcount by a flag-dependent amount -- * @page: pointer to page to be grabbed -- * @flags: gup flags: these are the FOLL_* flag values. -+ * try_grab_folio() - add a folio's refcount by a flag-dependent amount -+ * @folio: pointer to folio to be grabbed -+ * @refs: the value to (effectively) add to the folio's refcount -+ * @flags: gup flags: these are the FOLL_* flag values - * - * This might not do anything at all, depending on the flags argument. - * - * "grab" names in this file mean, "look at flags to decide whether to use -- * FOLL_PIN or FOLL_GET behavior, when incrementing the page's refcount. -+ * FOLL_PIN or FOLL_GET behavior, when incrementing the folio's refcount. - * - * Either FOLL_PIN or FOLL_GET (or neither) may be set, but not both at the same -- * time. Cases: please see the try_grab_folio() documentation, with -- * "refs=1". -+ * time. - * - * Return: 0 for success, or if no action was required (if neither FOLL_PIN - * nor FOLL_GET was set, nothing is done). A negative error code for failure: - * -- * -ENOMEM FOLL_GET or FOLL_PIN was set, but the page could not -+ * -ENOMEM FOLL_GET or FOLL_PIN was set, but the folio could not - * be grabbed. -+ * -+ * It is called when we have a stable reference for the folio, typically in -+ * GUP slow path. - */ --int __must_check try_grab_page(struct page *page, unsigned int flags) -+int __must_check try_grab_folio(struct folio *folio, int refs, -+ unsigned int flags) - { -- struct folio *folio = page_folio(page); -- - if (WARN_ON_ONCE(folio_ref_count(folio) <= 0)) - return -ENOMEM; - -- if (unlikely(!(flags & FOLL_PCI_P2PDMA) && is_pci_p2pdma_page(page))) -+ if (unlikely(!(flags & FOLL_PCI_P2PDMA) && is_pci_p2pdma_page(&folio->page))) - return -EREMOTEIO; - - if (flags & FOLL_GET) -- folio_ref_inc(folio); -+ folio_ref_add(folio, refs); - else if (flags & FOLL_PIN) { - /* - * Don't take a pin on the zero page - it's not going anywhere - * and it is used in a *lot* of places. - */ -- if (is_zero_page(page)) -+ if (is_zero_folio(folio)) - return 0; - - /* -- * Similar to try_grab_folio(): be sure to *also* -- * increment the normal page refcount field at least once, -+ * Increment the normal page refcount field at least once, - * so that the page really is pinned. - */ - if (folio_test_large(folio)) { -- folio_ref_add(folio, 1); -- atomic_add(1, &folio->_pincount); -+ folio_ref_add(folio, refs); -+ atomic_add(refs, &folio->_pincount); - } else { -- folio_ref_add(folio, GUP_PIN_COUNTING_BIAS); -+ folio_ref_add(folio, refs * GUP_PIN_COUNTING_BIAS); - } - -- node_stat_mod_folio(folio, NR_FOLL_PIN_ACQUIRED, 1); -+ node_stat_mod_folio(folio, NR_FOLL_PIN_ACQUIRED, refs); - } - - return 0; -@@ -647,8 +559,8 @@ static struct page *follow_page_pte(struct vm_area_struct *vma, - VM_BUG_ON_PAGE((flags & FOLL_PIN) && PageAnon(page) && - !PageAnonExclusive(page), page); - -- /* try_grab_page() does nothing unless FOLL_GET or FOLL_PIN is set. */ -- ret = try_grab_page(page, flags); -+ /* try_grab_folio() does nothing unless FOLL_GET or FOLL_PIN is set. */ -+ ret = try_grab_folio(page_folio(page), 1, flags); - if (unlikely(ret)) { - page = ERR_PTR(ret); - goto out; -@@ -899,7 +811,7 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address, - goto unmap; - *page = pte_page(entry); - } -- ret = try_grab_page(*page, gup_flags); -+ ret = try_grab_folio(page_folio(*page), 1, gup_flags); - if (unlikely(ret)) - goto unmap; - out: -@@ -1302,20 +1214,19 @@ static long __get_user_pages(struct mm_struct *mm, - * pages. - */ - if (page_increm > 1) { -- struct folio *folio; -+ struct folio *folio = page_folio(page); - - /* - * Since we already hold refcount on the - * large folio, this should never fail. - */ -- folio = try_grab_folio(page, page_increm - 1, -- foll_flags); -- if (WARN_ON_ONCE(!folio)) { -+ if (try_grab_folio(folio, page_increm - 1, -+ foll_flags)) { - /* - * Release the 1st page ref if the - * folio is problematic, fail hard. - */ -- gup_put_folio(page_folio(page), 1, -+ gup_put_folio(folio, 1, - foll_flags); - ret = -EFAULT; - goto out; -@@ -2541,6 +2452,102 @@ static void __maybe_unused undo_dev_pagemap(int *nr, int nr_start, - } - } - -+/** -+ * try_grab_folio_fast() - Attempt to get or pin a folio in fast path. -+ * @page: pointer to page to be grabbed -+ * @refs: the value to (effectively) add to the folio's refcount -+ * @flags: gup flags: these are the FOLL_* flag values. -+ * -+ * "grab" names in this file mean, "look at flags to decide whether to use -+ * FOLL_PIN or FOLL_GET behavior, when incrementing the folio's refcount. -+ * -+ * Either FOLL_PIN or FOLL_GET (or neither) must be set, but not both at the -+ * same time. (That's true throughout the get_user_pages*() and -+ * pin_user_pages*() APIs.) Cases: -+ * -+ * FOLL_GET: folio's refcount will be incremented by @refs. -+ * -+ * FOLL_PIN on large folios: folio's refcount will be incremented by -+ * @refs, and its pincount will be incremented by @refs. -+ * -+ * FOLL_PIN on single-page folios: folio's refcount will be incremented by -+ * @refs * GUP_PIN_COUNTING_BIAS. -+ * -+ * Return: The folio containing @page (with refcount appropriately -+ * incremented) for success, or NULL upon failure. If neither FOLL_GET -+ * nor FOLL_PIN was set, that's considered failure, and furthermore, -+ * a likely bug in the caller, so a warning is also emitted. -+ * -+ * It uses add ref unless zero to elevate the folio refcount and must be called -+ * in fast path only. -+ */ -+static struct folio *try_grab_folio_fast(struct page *page, int refs, -+ unsigned int flags) -+{ -+ struct folio *folio; -+ -+ /* Raise warn if it is not called in fast GUP */ -+ VM_WARN_ON_ONCE(!irqs_disabled()); -+ -+ if (WARN_ON_ONCE((flags & (FOLL_GET | FOLL_PIN)) == 0)) -+ return NULL; -+ -+ if (unlikely(!(flags & FOLL_PCI_P2PDMA) && is_pci_p2pdma_page(page))) -+ return NULL; -+ -+ if (flags & FOLL_GET) -+ return try_get_folio(page, refs); -+ -+ /* FOLL_PIN is set */ -+ -+ /* -+ * Don't take a pin on the zero page - it's not going anywhere -+ * and it is used in a *lot* of places. -+ */ -+ if (is_zero_page(page)) -+ return page_folio(page); -+ -+ folio = try_get_folio(page, refs); -+ if (!folio) -+ return NULL; -+ -+ /* -+ * Can't do FOLL_LONGTERM + FOLL_PIN gup fast path if not in a -+ * right zone, so fail and let the caller fall back to the slow -+ * path. -+ */ -+ if (unlikely((flags & FOLL_LONGTERM) && -+ !folio_is_longterm_pinnable(folio))) { -+ if (!put_devmap_managed_page_refs(&folio->page, refs)) -+ folio_put_refs(folio, refs); -+ return NULL; -+ } -+ -+ /* -+ * When pinning a large folio, use an exact count to track it. -+ * -+ * However, be sure to *also* increment the normal folio -+ * refcount field at least once, so that the folio really -+ * is pinned. That's why the refcount from the earlier -+ * try_get_folio() is left intact. -+ */ -+ if (folio_test_large(folio)) -+ atomic_add(refs, &folio->_pincount); -+ else -+ folio_ref_add(folio, -+ refs * (GUP_PIN_COUNTING_BIAS - 1)); -+ /* -+ * Adjust the pincount before re-checking the PTE for changes. -+ * This is essentially a smp_mb() and is paired with a memory -+ * barrier in folio_try_share_anon_rmap_*(). -+ */ -+ smp_mb__after_atomic(); -+ -+ node_stat_mod_folio(folio, NR_FOLL_PIN_ACQUIRED, refs); -+ -+ return folio; -+} -+ - #ifdef CONFIG_ARCH_HAS_PTE_SPECIAL - /* - * Fast-gup relies on pte change detection to avoid concurrent pgtable -@@ -2605,7 +2612,7 @@ static int gup_pte_range(pmd_t pmd, pmd_t *pmdp, unsigned long addr, - VM_BUG_ON(!pfn_valid(pte_pfn(pte))); - page = pte_page(pte); - -- folio = try_grab_folio(page, 1, flags); -+ folio = try_grab_folio_fast(page, 1, flags); - if (!folio) - goto pte_unmap; - -@@ -2699,7 +2706,7 @@ static int __gup_device_huge(unsigned long pfn, unsigned long addr, - - SetPageReferenced(page); - pages[*nr] = page; -- if (unlikely(try_grab_page(page, flags))) { -+ if (unlikely(try_grab_folio(page_folio(page), 1, flags))) { - undo_dev_pagemap(nr, nr_start, flags, pages); - break; - } -@@ -2808,7 +2815,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, - page = nth_page(pte_page(pte), (addr & (sz - 1)) >> PAGE_SHIFT); - refs = record_subpages(page, addr, end, pages + *nr); - -- folio = try_grab_folio(page, refs, flags); -+ folio = try_grab_folio_fast(page, refs, flags); - if (!folio) - return 0; - -@@ -2879,7 +2886,7 @@ static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr, - page = nth_page(pmd_page(orig), (addr & ~PMD_MASK) >> PAGE_SHIFT); - refs = record_subpages(page, addr, end, pages + *nr); - -- folio = try_grab_folio(page, refs, flags); -+ folio = try_grab_folio_fast(page, refs, flags); - if (!folio) - return 0; - -@@ -2923,7 +2930,7 @@ static int gup_huge_pud(pud_t orig, pud_t *pudp, unsigned long addr, - page = nth_page(pud_page(orig), (addr & ~PUD_MASK) >> PAGE_SHIFT); - refs = record_subpages(page, addr, end, pages + *nr); - -- folio = try_grab_folio(page, refs, flags); -+ folio = try_grab_folio_fast(page, refs, flags); - if (!folio) - return 0; - -@@ -2963,7 +2970,7 @@ static int gup_huge_pgd(pgd_t orig, pgd_t *pgdp, unsigned long addr, - page = nth_page(pgd_page(orig), (addr & ~PGDIR_MASK) >> PAGE_SHIFT); - refs = record_subpages(page, addr, end, pages + *nr); - -- folio = try_grab_folio(page, refs, flags); -+ folio = try_grab_folio_fast(page, refs, flags); - if (!folio) - return 0; - -diff --git a/mm/huge_memory.c b/mm/huge_memory.c -index 7ac2877e76629b..f2816c9a1f3ec8 100644 ---- a/mm/huge_memory.c -+++ b/mm/huge_memory.c -@@ -1056,7 +1056,7 @@ struct page *follow_devmap_pmd(struct vm_area_struct *vma, unsigned long addr, - if (!*pgmap) - return ERR_PTR(-EFAULT); - page = pfn_to_page(pfn); -- ret = try_grab_page(page, flags); -+ ret = try_grab_folio(page_folio(page), 1, flags); - if (ret) - page = ERR_PTR(ret); - -@@ -1214,7 +1214,7 @@ struct page *follow_devmap_pud(struct vm_area_struct *vma, unsigned long addr, - return ERR_PTR(-EFAULT); - page = pfn_to_page(pfn); - -- ret = try_grab_page(page, flags); -+ ret = try_grab_folio(page_folio(page), 1, flags); - if (ret) - page = ERR_PTR(ret); - -@@ -1475,7 +1475,7 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, - VM_BUG_ON_PAGE((flags & FOLL_PIN) && PageAnon(page) && - !PageAnonExclusive(page), page); - -- ret = try_grab_page(page, flags); -+ ret = try_grab_folio(page_folio(page), 1, flags); - if (ret) - return ERR_PTR(ret); - -diff --git a/mm/hugetlb.c b/mm/hugetlb.c -index fb7a531fce7174..0acb04c3e95291 100644 ---- a/mm/hugetlb.c -+++ b/mm/hugetlb.c -@@ -6532,7 +6532,7 @@ struct page *hugetlb_follow_page_mask(struct vm_area_struct *vma, - * try_grab_page() should always be able to get the page here, - * because we hold the ptl lock and have verified pte_present(). - */ -- ret = try_grab_page(page, flags); -+ ret = try_grab_folio(page_folio(page), 1, flags); - - if (WARN_ON_ONCE(ret)) { - page = ERR_PTR(ret); -diff --git a/mm/internal.h b/mm/internal.h -index abed947f784b7b..ef8d787a510c5c 100644 ---- a/mm/internal.h -+++ b/mm/internal.h -@@ -938,8 +938,8 @@ int migrate_device_coherent_page(struct page *page); - /* - * mm/gup.c - */ --struct folio *try_grab_folio(struct page *page, int refs, unsigned int flags); --int __must_check try_grab_page(struct page *page, unsigned int flags); -+int __must_check try_grab_folio(struct folio *folio, int refs, -+ unsigned int flags); - - /* - * mm/huge_memory.c -diff --git a/mm/page_table_check.c b/mm/page_table_check.c -index 6363f93a47c691..509c6ef8de400e 100644 ---- a/mm/page_table_check.c -+++ b/mm/page_table_check.c -@@ -7,6 +7,8 @@ - #include - #include - #include -+#include -+#include - - #undef pr_fmt - #define pr_fmt(fmt) "page_table_check: " fmt -@@ -191,6 +193,22 @@ void __page_table_check_pud_clear(struct mm_struct *mm, pud_t pud) - } - EXPORT_SYMBOL(__page_table_check_pud_clear); - -+/* Whether the swap entry cached writable information */ -+static inline bool swap_cached_writable(swp_entry_t entry) -+{ -+ return is_writable_device_exclusive_entry(entry) || -+ is_writable_device_private_entry(entry) || -+ is_writable_migration_entry(entry); -+} -+ -+static inline void page_table_check_pte_flags(pte_t pte) -+{ -+ if (pte_present(pte) && pte_uffd_wp(pte)) -+ WARN_ON_ONCE(pte_write(pte)); -+ else if (is_swap_pte(pte) && pte_swp_uffd_wp(pte)) -+ WARN_ON_ONCE(swap_cached_writable(pte_to_swp_entry(pte))); -+} -+ - void __page_table_check_ptes_set(struct mm_struct *mm, pte_t *ptep, pte_t pte, - unsigned int nr) - { -@@ -199,6 +217,8 @@ void __page_table_check_ptes_set(struct mm_struct *mm, pte_t *ptep, pte_t pte, - if (&init_mm == mm) - return; - -+ page_table_check_pte_flags(pte); -+ - for (i = 0; i < nr; i++) - __page_table_check_pte_clear(mm, ptep_get(ptep + i)); - if (pte_user_accessible_page(pte)) -@@ -206,11 +226,21 @@ void __page_table_check_ptes_set(struct mm_struct *mm, pte_t *ptep, pte_t pte, - } - EXPORT_SYMBOL(__page_table_check_ptes_set); - -+static inline void page_table_check_pmd_flags(pmd_t pmd) -+{ -+ if (pmd_present(pmd) && pmd_uffd_wp(pmd)) -+ WARN_ON_ONCE(pmd_write(pmd)); -+ else if (is_swap_pmd(pmd) && pmd_swp_uffd_wp(pmd)) -+ WARN_ON_ONCE(swap_cached_writable(pmd_to_swp_entry(pmd))); -+} -+ - void __page_table_check_pmd_set(struct mm_struct *mm, pmd_t *pmdp, pmd_t pmd) - { - if (&init_mm == mm) - return; - -+ page_table_check_pmd_flags(pmd); -+ - __page_table_check_pmd_clear(mm, *pmdp); - if (pmd_user_accessible_page(pmd)) { - page_table_check_set(pmd_pfn(pmd), PMD_SIZE >> PAGE_SHIFT, -diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c -index b54e8a530f55a1..29aa07e9db9d71 100644 ---- a/net/bluetooth/rfcomm/sock.c -+++ b/net/bluetooth/rfcomm/sock.c -@@ -629,7 +629,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, - - switch (optname) { - case RFCOMM_LM: -- if (copy_from_sockptr(&opt, optval, sizeof(u32))) { -+ if (bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen)) { - err = -EFAULT; - break; - } -@@ -664,7 +664,6 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, - struct sock *sk = sock->sk; - struct bt_security sec; - int err = 0; -- size_t len; - u32 opt; - - BT_DBG("sk %p", sk); -@@ -686,11 +685,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, - - sec.level = BT_SECURITY_LOW; - -- len = min_t(unsigned int, sizeof(sec), optlen); -- if (copy_from_sockptr(&sec, optval, len)) { -- err = -EFAULT; -+ err = bt_copy_from_sockptr(&sec, sizeof(sec), optval, optlen); -+ if (err) - break; -- } - - if (sec.level > BT_SECURITY_HIGH) { - err = -EINVAL; -@@ -706,10 +703,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, - break; - } - -- if (copy_from_sockptr(&opt, optval, sizeof(u32))) { -- err = -EFAULT; -+ err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen); -+ if (err) - break; -- } - - if (opt) - set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); -diff --git a/net/core/filter.c b/net/core/filter.c -index 8cb44cd29967bb..be313928d272c6 100644 ---- a/net/core/filter.c -+++ b/net/core/filter.c -@@ -2271,12 +2271,12 @@ static int __bpf_redirect_neigh_v6(struct sk_buff *skb, struct net_device *dev, - - err = bpf_out_neigh_v6(net, skb, dev, nh); - if (unlikely(net_xmit_eval(err))) -- dev->stats.tx_errors++; -+ DEV_STATS_INC(dev, tx_errors); - else - ret = NET_XMIT_SUCCESS; - goto out_xmit; - out_drop: -- dev->stats.tx_errors++; -+ DEV_STATS_INC(dev, tx_errors); - kfree_skb(skb); - out_xmit: - return ret; -@@ -2378,12 +2378,12 @@ static int __bpf_redirect_neigh_v4(struct sk_buff *skb, struct net_device *dev, - - err = bpf_out_neigh_v4(net, skb, dev, nh); - if (unlikely(net_xmit_eval(err))) -- dev->stats.tx_errors++; -+ DEV_STATS_INC(dev, tx_errors); - else - ret = NET_XMIT_SUCCESS; - goto out_xmit; - out_drop: -- dev->stats.tx_errors++; -+ DEV_STATS_INC(dev, tx_errors); - kfree_skb(skb); - out_xmit: - return ret; -diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c -index 0c41076e31edad..b38b82ae903de0 100644 ---- a/net/ipv4/fou_core.c -+++ b/net/ipv4/fou_core.c -@@ -433,7 +433,7 @@ static struct sk_buff *gue_gro_receive(struct sock *sk, - - offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; - ops = rcu_dereference(offloads[proto]); -- if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive)) -+ if (!ops || !ops->callbacks.gro_receive) - goto out; - - pp = call_gro_receive(ops->callbacks.gro_receive, head, skb); -diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c -index b71f94a5932ac0..e0883ba709b0bf 100644 ---- a/net/ipv4/tcp_metrics.c -+++ b/net/ipv4/tcp_metrics.c -@@ -899,11 +899,13 @@ static void tcp_metrics_flush_all(struct net *net) - unsigned int row; - - for (row = 0; row < max_rows; row++, hb++) { -- struct tcp_metrics_block __rcu **pp; -+ struct tcp_metrics_block __rcu **pp = &hb->chain; - bool match; - -+ if (!rcu_access_pointer(*pp)) -+ continue; -+ - spin_lock_bh(&tcp_metrics_lock); -- pp = &hb->chain; - for (tm = deref_locked(*pp); tm; tm = deref_locked(*pp)) { - match = net ? net_eq(tm_net(tm), net) : - !refcount_read(&tm_net(tm)->ns.count); -@@ -915,6 +917,7 @@ static void tcp_metrics_flush_all(struct net *net) - } - } - spin_unlock_bh(&tcp_metrics_lock); -+ cond_resched(); - } - } - -diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c -index 6e3bfb46af44d3..52b048807feae5 100644 ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -251,9 +251,9 @@ static int ieee80211_can_powered_addr_change(struct ieee80211_sub_if_data *sdata - return ret; - } - --static int ieee80211_change_mac(struct net_device *dev, void *addr) -+static int _ieee80211_change_mac(struct ieee80211_sub_if_data *sdata, -+ void *addr) - { -- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_local *local = sdata->local; - struct sockaddr *sa = addr; - bool check_dup = true; -@@ -278,7 +278,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr) - - if (live) - drv_remove_interface(local, sdata); -- ret = eth_mac_addr(dev, sa); -+ ret = eth_mac_addr(sdata->dev, sa); - - if (ret == 0) { - memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN); -@@ -294,6 +294,27 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr) - return ret; - } - -+static int ieee80211_change_mac(struct net_device *dev, void *addr) -+{ -+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ struct ieee80211_local *local = sdata->local; -+ int ret; -+ -+ /* -+ * This happens during unregistration if there's a bond device -+ * active (maybe other cases?) and we must get removed from it. -+ * But we really don't care anymore if it's not registered now. -+ */ -+ if (!dev->ieee80211_ptr->registered) -+ return 0; -+ -+ wiphy_lock(local->hw.wiphy); -+ ret = _ieee80211_change_mac(sdata, addr); -+ wiphy_unlock(local->hw.wiphy); -+ -+ return ret; -+} -+ - static inline int identical_mac_addr_allowed(int type1, int type2) - { - return type1 == NL80211_IFTYPE_MONITOR || -diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c -index 819157bbb5a2c6..d5344563e525c9 100644 ---- a/net/nfc/llcp_sock.c -+++ b/net/nfc/llcp_sock.c -@@ -252,10 +252,10 @@ static int nfc_llcp_setsockopt(struct socket *sock, int level, int optname, - break; - } - -- if (copy_from_sockptr(&opt, optval, sizeof(u32))) { -- err = -EFAULT; -+ err = copy_safe_from_sockptr(&opt, sizeof(opt), -+ optval, optlen); -+ if (err) - break; -- } - - if (opt > LLCP_MAX_RW) { - err = -EINVAL; -@@ -274,10 +274,10 @@ static int nfc_llcp_setsockopt(struct socket *sock, int level, int optname, - break; - } - -- if (copy_from_sockptr(&opt, optval, sizeof(u32))) { -- err = -EFAULT; -+ err = copy_safe_from_sockptr(&opt, sizeof(opt), -+ optval, optlen); -+ if (err) - break; -- } - - if (opt > LLCP_MAX_MIUX) { - err = -EINVAL; -diff --git a/net/rds/recv.c b/net/rds/recv.c -index c71b923764fd7c..5627f80013f8b1 100644 ---- a/net/rds/recv.c -+++ b/net/rds/recv.c -@@ -425,6 +425,7 @@ static int rds_still_queued(struct rds_sock *rs, struct rds_incoming *inc, - struct sock *sk = rds_rs_to_sk(rs); - int ret = 0; - unsigned long flags; -+ struct rds_incoming *to_drop = NULL; - - write_lock_irqsave(&rs->rs_recv_lock, flags); - if (!list_empty(&inc->i_item)) { -@@ -435,11 +436,14 @@ static int rds_still_queued(struct rds_sock *rs, struct rds_incoming *inc, - -be32_to_cpu(inc->i_hdr.h_len), - inc->i_hdr.h_dport); - list_del_init(&inc->i_item); -- rds_inc_put(inc); -+ to_drop = inc; - } - } - write_unlock_irqrestore(&rs->rs_recv_lock, flags); - -+ if (to_drop) -+ rds_inc_put(to_drop); -+ - rdsdebug("inc %p rs %p still %d dropped %d\n", inc, rs, ret, drop); - return ret; - } -@@ -758,16 +762,21 @@ void rds_clear_recv_queue(struct rds_sock *rs) - struct sock *sk = rds_rs_to_sk(rs); - struct rds_incoming *inc, *tmp; - unsigned long flags; -+ LIST_HEAD(to_drop); - - write_lock_irqsave(&rs->rs_recv_lock, flags); - list_for_each_entry_safe(inc, tmp, &rs->rs_recv_queue, i_item) { - rds_recv_rcvbuf_delta(rs, sk, inc->i_conn->c_lcong, - -be32_to_cpu(inc->i_hdr.h_len), - inc->i_hdr.h_dport); -+ list_move(&inc->i_item, &to_drop); -+ } -+ write_unlock_irqrestore(&rs->rs_recv_lock, flags); -+ -+ list_for_each_entry_safe(inc, tmp, &to_drop, i_item) { - list_del_init(&inc->i_item); - rds_inc_put(inc); - } -- write_unlock_irqrestore(&rs->rs_recv_lock, flags); - } - - /* -diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c -index 4023c955036b12..6ab9359c1706f1 100644 ---- a/net/sched/sch_generic.c -+++ b/net/sched/sch_generic.c -@@ -522,8 +522,9 @@ static void dev_watchdog(struct timer_list *t) - - if (unlikely(timedout_ms)) { - trace_net_dev_xmit_timeout(dev, i); -- WARN_ONCE(1, "NETDEV WATCHDOG: %s (%s): transmit queue %u timed out %u ms\n", -- dev->name, netdev_drivername(dev), i, timedout_ms); -+ netdev_crit(dev, "NETDEV WATCHDOG: CPU: %d: transmit queue %u timed out %u ms\n", -+ raw_smp_processor_id(), -+ i, timedout_ms); - netif_freeze_queues(dev); - dev->netdev_ops->ndo_tx_timeout(dev, i); - netif_unfreeze_queues(dev); -diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c -index 7182c5a450fb5b..5c165218180588 100644 ---- a/net/sctp/inqueue.c -+++ b/net/sctp/inqueue.c -@@ -38,6 +38,14 @@ void sctp_inq_init(struct sctp_inq *queue) - INIT_WORK(&queue->immediate, NULL); - } - -+/* Properly release the chunk which is being worked on. */ -+static inline void sctp_inq_chunk_free(struct sctp_chunk *chunk) -+{ -+ if (chunk->head_skb) -+ chunk->skb = chunk->head_skb; -+ sctp_chunk_free(chunk); -+} -+ - /* Release the memory associated with an SCTP inqueue. */ - void sctp_inq_free(struct sctp_inq *queue) - { -@@ -53,7 +61,7 @@ void sctp_inq_free(struct sctp_inq *queue) - * free it as well. - */ - if (queue->in_progress) { -- sctp_chunk_free(queue->in_progress); -+ sctp_inq_chunk_free(queue->in_progress); - queue->in_progress = NULL; - } - } -@@ -130,9 +138,7 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue) - goto new_skb; - } - -- if (chunk->head_skb) -- chunk->skb = chunk->head_skb; -- sctp_chunk_free(chunk); -+ sctp_inq_chunk_free(chunk); - chunk = queue->in_progress = NULL; - } else { - /* Nothing to do. Next chunk in the packet, please. */ -diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c -index 65fc1297c6dfa4..383860cb1d5b0f 100644 ---- a/net/sunrpc/stats.c -+++ b/net/sunrpc/stats.c -@@ -314,7 +314,7 @@ EXPORT_SYMBOL_GPL(rpc_proc_unregister); - struct proc_dir_entry * - svc_proc_register(struct net *net, struct svc_stat *statp, const struct proc_ops *proc_ops) - { -- return do_register(net, statp->program->pg_name, statp, proc_ops); -+ return do_register(net, statp->program->pg_name, net, proc_ops); - } - EXPORT_SYMBOL_GPL(svc_proc_register); - -diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c -index 691499d1d2315c..029c49065016ac 100644 ---- a/net/sunrpc/svc.c -+++ b/net/sunrpc/svc.c -@@ -453,8 +453,8 @@ __svc_init_bc(struct svc_serv *serv) - * Create an RPC service - */ - static struct svc_serv * --__svc_create(struct svc_program *prog, unsigned int bufsize, int npools, -- int (*threadfn)(void *data)) -+__svc_create(struct svc_program *prog, struct svc_stat *stats, -+ unsigned int bufsize, int npools, int (*threadfn)(void *data)) - { - struct svc_serv *serv; - unsigned int vers; -@@ -466,7 +466,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, - serv->sv_name = prog->pg_name; - serv->sv_program = prog; - kref_init(&serv->sv_refcnt); -- serv->sv_stats = prog->pg_stats; -+ serv->sv_stats = stats; - if (bufsize > RPCSVC_MAXPAYLOAD) - bufsize = RPCSVC_MAXPAYLOAD; - serv->sv_max_payload = bufsize? bufsize : 4096; -@@ -532,26 +532,28 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, - struct svc_serv *svc_create(struct svc_program *prog, unsigned int bufsize, - int (*threadfn)(void *data)) - { -- return __svc_create(prog, bufsize, 1, threadfn); -+ return __svc_create(prog, NULL, bufsize, 1, threadfn); - } - EXPORT_SYMBOL_GPL(svc_create); - - /** - * svc_create_pooled - Create an RPC service with pooled threads - * @prog: the RPC program the new service will handle -+ * @stats: the stats struct if desired - * @bufsize: maximum message size for @prog - * @threadfn: a function to service RPC requests for @prog - * - * Returns an instantiated struct svc_serv object or NULL. - */ - struct svc_serv *svc_create_pooled(struct svc_program *prog, -+ struct svc_stat *stats, - unsigned int bufsize, - int (*threadfn)(void *data)) - { - struct svc_serv *serv; - unsigned int npools = svc_pool_map_get(); - -- serv = __svc_create(prog, bufsize, npools, threadfn); -+ serv = __svc_create(prog, stats, bufsize, npools, threadfn); - if (!serv) - goto out_err; - return serv; -@@ -1377,7 +1379,8 @@ svc_process_common(struct svc_rqst *rqstp) - goto err_bad_proc; - - /* Syntactic check complete */ -- serv->sv_stats->rpccnt++; -+ if (serv->sv_stats) -+ serv->sv_stats->rpccnt++; - trace_svc_process(rqstp, progp->pg_name); - - aoffset = xdr_stream_pos(xdr); -@@ -1429,7 +1432,8 @@ svc_process_common(struct svc_rqst *rqstp) - goto close_xprt; - - err_bad_rpc: -- serv->sv_stats->rpcbadfmt++; -+ if (serv->sv_stats) -+ serv->sv_stats->rpcbadfmt++; - xdr_stream_encode_u32(xdr, RPC_MSG_DENIED); - xdr_stream_encode_u32(xdr, RPC_MISMATCH); - /* Only RPCv2 supported */ -@@ -1440,7 +1444,8 @@ svc_process_common(struct svc_rqst *rqstp) - err_bad_auth: - dprintk("svc: authentication failed (%d)\n", - be32_to_cpu(rqstp->rq_auth_stat)); -- serv->sv_stats->rpcbadauth++; -+ if (serv->sv_stats) -+ serv->sv_stats->rpcbadauth++; - /* Restore write pointer to location of reply status: */ - xdr_truncate_encode(xdr, XDR_UNIT * 2); - xdr_stream_encode_u32(xdr, RPC_MSG_DENIED); -@@ -1450,7 +1455,8 @@ svc_process_common(struct svc_rqst *rqstp) - - err_bad_prog: - dprintk("svc: unknown program %d\n", rqstp->rq_prog); -- serv->sv_stats->rpcbadfmt++; -+ if (serv->sv_stats) -+ serv->sv_stats->rpcbadfmt++; - *rqstp->rq_accept_statp = rpc_prog_unavail; - goto sendit; - -@@ -1458,7 +1464,8 @@ svc_process_common(struct svc_rqst *rqstp) - svc_printk(rqstp, "unknown version (%d for prog %d, %s)\n", - rqstp->rq_vers, rqstp->rq_prog, progp->pg_name); - -- serv->sv_stats->rpcbadfmt++; -+ if (serv->sv_stats) -+ serv->sv_stats->rpcbadfmt++; - *rqstp->rq_accept_statp = rpc_prog_mismatch; - - /* -@@ -1472,19 +1479,22 @@ svc_process_common(struct svc_rqst *rqstp) - err_bad_proc: - svc_printk(rqstp, "unknown procedure (%d)\n", rqstp->rq_proc); - -- serv->sv_stats->rpcbadfmt++; -+ if (serv->sv_stats) -+ serv->sv_stats->rpcbadfmt++; - *rqstp->rq_accept_statp = rpc_proc_unavail; - goto sendit; - - err_garbage_args: - svc_printk(rqstp, "failed to decode RPC header\n"); - -- serv->sv_stats->rpcbadfmt++; -+ if (serv->sv_stats) -+ serv->sv_stats->rpcbadfmt++; - *rqstp->rq_accept_statp = rpc_garbage_args; - goto sendit; - - err_system_err: -- serv->sv_stats->rpcbadfmt++; -+ if (serv->sv_stats) -+ serv->sv_stats->rpcbadfmt++; - *rqstp->rq_accept_statp = rpc_system_err; - goto sendit; - } -@@ -1536,7 +1546,8 @@ void svc_process(struct svc_rqst *rqstp) - out_baddir: - svc_printk(rqstp, "bad direction 0x%08x, dropping request\n", - be32_to_cpu(*p)); -- rqstp->rq_server->sv_stats->rpcbadfmt++; -+ if (rqstp->rq_server->sv_stats) -+ rqstp->rq_server->sv_stats->rpcbadfmt++; - out_drop: - svc_drop(rqstp); - } -diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c -index be5c42d6ffbeab..2b2dc46dc701f9 100644 ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -468,6 +468,10 @@ static struct netlink_range_validation nl80211_punct_bitmap_range = { - .max = 0xffff, - }; - -+static struct netlink_range_validation q_range = { -+ .max = INT_MAX, -+}; -+ - static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { - [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD }, - [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, -@@ -750,7 +754,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { - - [NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 }, - [NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 }, -- [NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 }, -+ [NL80211_ATTR_TXQ_QUANTUM] = NLA_POLICY_FULL_RANGE(NLA_U32, &q_range), - [NL80211_ATTR_HE_CAPABILITY] = - NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_he_capa, - NL80211_HE_MAX_CAPABILITY_LEN), -diff --git a/samples/bpf/map_perf_test_user.c b/samples/bpf/map_perf_test_user.c -index d2fbcf963cdf6d..07ff471ed6aee0 100644 ---- a/samples/bpf/map_perf_test_user.c -+++ b/samples/bpf/map_perf_test_user.c -@@ -370,7 +370,7 @@ static void run_perf_test(int tasks) - - static void fill_lpm_trie(void) - { -- struct bpf_lpm_trie_key *key; -+ struct bpf_lpm_trie_key_u8 *key; - unsigned long value = 0; - unsigned int i; - int r; -diff --git a/samples/bpf/xdp_router_ipv4_user.c b/samples/bpf/xdp_router_ipv4_user.c -index 9d41db09c4800f..266fdd0b025dc6 100644 ---- a/samples/bpf/xdp_router_ipv4_user.c -+++ b/samples/bpf/xdp_router_ipv4_user.c -@@ -91,7 +91,7 @@ static int recv_msg(struct sockaddr_nl sock_addr, int sock) - static void read_route(struct nlmsghdr *nh, int nll) - { - char dsts[24], gws[24], ifs[16], dsts_len[24], metrics[24]; -- struct bpf_lpm_trie_key *prefix_key; -+ struct bpf_lpm_trie_key_u8 *prefix_key; - struct rtattr *rt_attr; - struct rtmsg *rt_msg; - int rtm_family; -diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c -index 8b58a7864703ee..7e8fca0b066280 100644 ---- a/sound/soc/soc-topology.c -+++ b/sound/soc/soc-topology.c -@@ -1021,6 +1021,7 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, - struct snd_soc_tplg_hdr *hdr) - { - struct snd_soc_dapm_context *dapm = &tplg->comp->dapm; -+ const size_t maxlen = SNDRV_CTL_ELEM_ID_NAME_MAXLEN; - struct snd_soc_tplg_dapm_graph_elem *elem; - struct snd_soc_dapm_route *route; - int count, i; -@@ -1044,39 +1045,22 @@ static int soc_tplg_dapm_graph_elems_load(struct soc_tplg *tplg, - tplg->pos += sizeof(struct snd_soc_tplg_dapm_graph_elem); - - /* validate routes */ -- if (strnlen(elem->source, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == -- SNDRV_CTL_ELEM_ID_NAME_MAXLEN) { -- ret = -EINVAL; -- break; -- } -- if (strnlen(elem->sink, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == -- SNDRV_CTL_ELEM_ID_NAME_MAXLEN) { -- ret = -EINVAL; -- break; -- } -- if (strnlen(elem->control, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == -- SNDRV_CTL_ELEM_ID_NAME_MAXLEN) { -+ if ((strnlen(elem->source, maxlen) == maxlen) || -+ (strnlen(elem->sink, maxlen) == maxlen) || -+ (strnlen(elem->control, maxlen) == maxlen)) { - ret = -EINVAL; - break; - } - -- route->source = devm_kmemdup(tplg->dev, elem->source, -- min(strlen(elem->source), -- SNDRV_CTL_ELEM_ID_NAME_MAXLEN), -- GFP_KERNEL); -- route->sink = devm_kmemdup(tplg->dev, elem->sink, -- min(strlen(elem->sink), SNDRV_CTL_ELEM_ID_NAME_MAXLEN), -- GFP_KERNEL); -+ route->source = devm_kstrdup(tplg->dev, elem->source, GFP_KERNEL); -+ route->sink = devm_kstrdup(tplg->dev, elem->sink, GFP_KERNEL); - if (!route->source || !route->sink) { - ret = -ENOMEM; - break; - } - -- if (strnlen(elem->control, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) != 0) { -- route->control = devm_kmemdup(tplg->dev, elem->control, -- min(strlen(elem->control), -- SNDRV_CTL_ELEM_ID_NAME_MAXLEN), -- GFP_KERNEL); -+ if (strnlen(elem->control, maxlen) != 0) { -+ route->control = devm_kstrdup(tplg->dev, elem->control, GFP_KERNEL); - if (!route->control) { - ret = -ENOMEM; - break; -diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c -index d1bdb0b93bda0c..8cc2d4937f3403 100644 ---- a/sound/usb/mixer.c -+++ b/sound/usb/mixer.c -@@ -2021,6 +2021,13 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, - bmaControls = ftr->bmaControls; - } - -+ if (channels > 32) { -+ usb_audio_info(state->chip, -+ "usbmixer: too many channels (%d) in unit %d\n", -+ channels, unitid); -+ return -EINVAL; -+ } -+ - /* parse the source unit */ - err = parse_audio_unit(state, hdr->bSourceID); - if (err < 0) -diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h -index fb09fd1767f289..ba6e346c8d669a 100644 ---- a/tools/include/uapi/linux/bpf.h -+++ b/tools/include/uapi/linux/bpf.h -@@ -77,12 +77,29 @@ struct bpf_insn { - __s32 imm; /* signed immediate constant */ - }; - --/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */ -+/* Deprecated: use struct bpf_lpm_trie_key_u8 (when the "data" member is needed for -+ * byte access) or struct bpf_lpm_trie_key_hdr (when using an alternative type for -+ * the trailing flexible array member) instead. -+ */ - struct bpf_lpm_trie_key { - __u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */ - __u8 data[0]; /* Arbitrary size */ - }; - -+/* Header for bpf_lpm_trie_key structs */ -+struct bpf_lpm_trie_key_hdr { -+ __u32 prefixlen; -+}; -+ -+/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry, with trailing byte array. */ -+struct bpf_lpm_trie_key_u8 { -+ union { -+ struct bpf_lpm_trie_key_hdr hdr; -+ __u32 prefixlen; -+ }; -+ __u8 data[]; /* Arbitrary size */ -+}; -+ - struct bpf_cgroup_storage_key { - __u64 cgroup_inode_id; /* cgroup inode id */ - __u32 attach_type; /* program attach type (enum bpf_attach_type) */ -diff --git a/tools/testing/selftests/bpf/progs/map_ptr_kern.c b/tools/testing/selftests/bpf/progs/map_ptr_kern.c -index 3325da17ec81af..efaf622c28ddec 100644 ---- a/tools/testing/selftests/bpf/progs/map_ptr_kern.c -+++ b/tools/testing/selftests/bpf/progs/map_ptr_kern.c -@@ -316,7 +316,7 @@ struct lpm_trie { - } __attribute__((preserve_access_index)); - - struct lpm_key { -- struct bpf_lpm_trie_key trie_key; -+ struct bpf_lpm_trie_key_hdr trie_key; - __u32 data; - }; - -diff --git a/tools/testing/selftests/bpf/test_lpm_map.c b/tools/testing/selftests/bpf/test_lpm_map.c -index c028d621c744da..d98c72dc563eaf 100644 ---- a/tools/testing/selftests/bpf/test_lpm_map.c -+++ b/tools/testing/selftests/bpf/test_lpm_map.c -@@ -211,7 +211,7 @@ static void test_lpm_map(int keysize) - volatile size_t n_matches, n_matches_after_delete; - size_t i, j, n_nodes, n_lookups; - struct tlpm_node *t, *list = NULL; -- struct bpf_lpm_trie_key *key; -+ struct bpf_lpm_trie_key_u8 *key; - uint8_t *data, *value; - int r, map; - -@@ -331,8 +331,8 @@ static void test_lpm_map(int keysize) - static void test_lpm_ipaddr(void) - { - LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_NO_PREALLOC); -- struct bpf_lpm_trie_key *key_ipv4; -- struct bpf_lpm_trie_key *key_ipv6; -+ struct bpf_lpm_trie_key_u8 *key_ipv4; -+ struct bpf_lpm_trie_key_u8 *key_ipv6; - size_t key_size_ipv4; - size_t key_size_ipv6; - int map_fd_ipv4; -@@ -423,7 +423,7 @@ static void test_lpm_ipaddr(void) - static void test_lpm_delete(void) - { - LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_NO_PREALLOC); -- struct bpf_lpm_trie_key *key; -+ struct bpf_lpm_trie_key_u8 *key; - size_t key_size; - int map_fd; - __u64 value; -@@ -532,7 +532,7 @@ static void test_lpm_delete(void) - static void test_lpm_get_next_key(void) - { - LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_NO_PREALLOC); -- struct bpf_lpm_trie_key *key_p, *next_key_p; -+ struct bpf_lpm_trie_key_u8 *key_p, *next_key_p; - size_t key_size; - __u32 value = 0; - int map_fd; -@@ -693,9 +693,9 @@ static void *lpm_test_command(void *arg) - { - int i, j, ret, iter, key_size; - struct lpm_mt_test_info *info = arg; -- struct bpf_lpm_trie_key *key_p; -+ struct bpf_lpm_trie_key_u8 *key_p; - -- key_size = sizeof(struct bpf_lpm_trie_key) + sizeof(__u32); -+ key_size = sizeof(*key_p) + sizeof(__u32); - key_p = alloca(key_size); - for (iter = 0; iter < info->iter; iter++) - for (i = 0; i < MAX_TEST_KEYS; i++) { -@@ -717,7 +717,7 @@ static void *lpm_test_command(void *arg) - ret = bpf_map_lookup_elem(info->map_fd, key_p, &value); - assert(ret == 0 || errno == ENOENT); - } else { -- struct bpf_lpm_trie_key *next_key_p = alloca(key_size); -+ struct bpf_lpm_trie_key_u8 *next_key_p = alloca(key_size); - ret = bpf_map_get_next_key(info->map_fd, key_p, next_key_p); - assert(ret == 0 || errno == ENOENT || errno == ENOMEM); - } -@@ -752,7 +752,7 @@ static void test_lpm_multi_thread(void) - - /* create a trie */ - value_size = sizeof(__u32); -- key_size = sizeof(struct bpf_lpm_trie_key) + value_size; -+ key_size = sizeof(struct bpf_lpm_trie_key_hdr) + value_size; - map_fd = bpf_map_create(BPF_MAP_TYPE_LPM_TRIE, NULL, key_size, value_size, 100, &opts); - - /* create 4 threads to test update, delete, lookup and get_next_key */ -diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c -index ad993ab3ac1819..bc36c91c4480f5 100644 ---- a/tools/testing/selftests/net/tls.c -+++ b/tools/testing/selftests/net/tls.c -@@ -707,6 +707,20 @@ TEST_F(tls, splice_from_pipe) - EXPECT_EQ(memcmp(mem_send, mem_recv, send_len), 0); - } - -+TEST_F(tls, splice_more) -+{ -+ unsigned int f = SPLICE_F_NONBLOCK | SPLICE_F_MORE | SPLICE_F_GIFT; -+ int send_len = TLS_PAYLOAD_MAX_LEN; -+ char mem_send[TLS_PAYLOAD_MAX_LEN]; -+ int i, send_pipe = 1; -+ int p[2]; -+ -+ ASSERT_GE(pipe(p), 0); -+ EXPECT_GE(write(p[1], mem_send, send_len), 0); -+ for (i = 0; i < 32; i++) -+ EXPECT_EQ(splice(p[0], NULL, self->fd, NULL, send_pipe, f), 1); -+} -+ - TEST_F(tls, splice_from_pipe2) - { - int send_len = 16000;